From 424dda7a3d279c3970f92f599ce65857911471fa Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans@users.noreply.github.com> Date: Sat, 25 Apr 2026 19:47:10 -0400 Subject: [PATCH 1/5] feat: scope .github to org-wide standards; drop Cribl-specific workflows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Establishes dryvist/.github as the org-wide infrastructure hub: - CLAUDE.md: TypeScript-everywhere policy, tooling baseline (Biome + Vitest + tsc), inheritance chain from JacobPEvans/.github - biome.jsonc: canonical Biome lint + format config (single source of truth for the org; repos copy via Renovate sync) - SECURITY.md: org-wide vulnerability reporting + dependency trust tiers (mirrored from JacobPEvans/.github structure, scoped to dryvist) - renovate.json: extends github>JacobPEvans/.github:renovate-presets - profile/README.md: org profile page at github.com/dryvist - README.md: rewritten as org-standards docs (inheritance, release-please setup, contributing) — no longer Cribl-focused Removed: - .github/workflows/cribl-pack-test.yml — Cribl-specific, wrong repo - .github/workflows/cribl-pack-release.yml — Cribl-specific, wrong repo Cribl workflows will land in dryvist/cc-edge-pack-template/.github/workflows/ in TypeScript form (separate PR). Until then, no consumer pack can resolve the old uses: paths — that's intentional, the in-flight Python pack PRs are being closed alongside this pivot. Inheritance from JacobPEvans/.github: - _release-please.yml (workflow) — direct uses: from each dryvist repo's caller workflow; no wrapper needed in this repo - renovate-presets.json — extended via renovate.json - Trust tier conventions — adapted in SECURITY.md (claude) --- .github/workflows/cribl-pack-release.yml | 55 ------ .github/workflows/cribl-pack-test.yml | 204 ----------------------- CLAUDE.md | 96 +++++++++++ README.md | 122 ++++++++------ SECURITY.md | 51 ++++++ biome.jsonc | 69 ++++++++ profile/README.md | 63 +++++++ renovate.json | 7 + 8 files changed, 358 insertions(+), 309 deletions(-) delete mode 100644 .github/workflows/cribl-pack-release.yml delete mode 100644 .github/workflows/cribl-pack-test.yml create mode 100644 CLAUDE.md create mode 100644 SECURITY.md create mode 100644 biome.jsonc create mode 100644 profile/README.md create mode 100644 renovate.json diff --git a/.github/workflows/cribl-pack-release.yml b/.github/workflows/cribl-pack-release.yml deleted file mode 100644 index ce1049f..0000000 --- a/.github/workflows/cribl-pack-release.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: Cribl Pack Release (reusable) - -on: - workflow_call: - inputs: - additional_files: - description: "Extra files to include in the .crbl tarball, space-separated. Defaults to LICENSE if present." - type: string - default: "" - -permissions: - contents: write - -jobs: - release: - name: Build .crbl and publish GitHub release - runs-on: ubuntu-latest - env: - ADDITIONAL_FILES: ${{ inputs.additional_files }} - REPO_NAME: ${{ github.event.repository.name }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Get GitHub slug info - uses: rlespinasse/github-slug-action@v5 - - - name: Build .crbl tarball - run: | - set -euo pipefail - TAG_SLUG="${GITHUB_REF_SLUG}" - OUT_VERSIONED="/tmp/${REPO_NAME}-${TAG_SLUG}.crbl" - OUT_LATEST="/tmp/${REPO_NAME}.crbl" - - # Standard pack contents (criblpacks convention) - INCLUDE=(data default package.json README.md) - [[ -f LICENSE ]] && INCLUDE+=(LICENSE) - for extra in $ADDITIONAL_FILES; do - [[ -e "$extra" ]] && INCLUDE+=("$extra") - done - - tar -czf "$OUT_VERSIONED" "${INCLUDE[@]}" - cp "$OUT_VERSIONED" "$OUT_LATEST" - ls -lh "$OUT_VERSIONED" "$OUT_LATEST" - echo "OUT_VERSIONED=$OUT_VERSIONED" >> "$GITHUB_ENV" - echo "OUT_LATEST=$OUT_LATEST" >> "$GITHUB_ENV" - - - name: Create GitHub release - uses: softprops/action-gh-release@v2 - with: - prerelease: ${{ contains(github.ref, 'RC') || contains(github.ref, 'TC') }} - generate_release_notes: true - files: | - ${{ env.OUT_VERSIONED }} - ${{ env.OUT_LATEST }} diff --git a/.github/workflows/cribl-pack-test.yml b/.github/workflows/cribl-pack-test.yml deleted file mode 100644 index 63d0a5e..0000000 --- a/.github/workflows/cribl-pack-test.yml +++ /dev/null @@ -1,204 +0,0 @@ -name: Cribl Pack Test (reusable) - -on: - workflow_call: - inputs: - pack_type: - description: "Pack type — 'edge' or 'stream'. Determines validator naming convention." - type: string - required: true - cribl_version: - description: "cribl/cribl Docker image tag. Defaults to 'latest' (Cribl pinning policy: track upstream)." - type: string - default: "latest" - python_version: - description: "Python version for test runner." - type: string - default: "3.12" - -permissions: - contents: read - -jobs: - validate: - name: Validate pack structure - runs-on: ubuntu-latest - env: - PACK_TYPE: ${{ inputs.pack_type }} - steps: - - name: Checkout pack - uses: actions/checkout@v4 - - - name: Install yq - run: | - sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 - sudo chmod +x /usr/local/bin/yq - - - name: Install yamllint - run: pipx install yamllint - - - name: Verify pack_type input - run: | - if [[ "$PACK_TYPE" != "edge" && "$PACK_TYPE" != "stream" ]]; then - echo "::error::pack_type must be 'edge' or 'stream', got '$PACK_TYPE'" - exit 1 - fi - - - name: Verify required pack files exist - run: | - set -euo pipefail - required=(package.json default/pack.yml default/pipelines/route.yml README.md) - missing=0 - for f in "${required[@]}"; do - if [[ ! -f "$f" ]]; then - echo "::error file=$f::Required pack file missing" - missing=$((missing+1)) - fi - done - if [[ $missing -gt 0 ]]; then - exit 1 - fi - echo "All required pack files present." - - - name: Verify package.json shape - run: | - set -euo pipefail - name=$(jq -r .name package.json) - version=$(jq -r .version package.json) - minLogStreamVersion=$(jq -r .minLogStreamVersion package.json) - for v in "$name" "$version" "$minLogStreamVersion"; do - if [[ -z "$v" || "$v" == "null" ]]; then - echo "::error::package.json missing required field" - exit 1 - fi - done - # Pack ID convention from vct-cribl-pack-validator: cc-{edge,stream}--io - if [[ "$PACK_TYPE" == "edge" ]]; then - if [[ ! "$name" =~ ^cc-edge-.*-io$ ]]; then - echo "::warning::Pack name '$name' does not follow 'cc-edge--io' convention" - fi - else - if [[ ! "$name" =~ ^cc-stream-.*-io$ ]]; then - echo "::warning::Pack name '$name' does not follow 'cc-stream--io' convention" - fi - fi - echo "package.json: name=$name version=$version minLogStreamVersion=$minLogStreamVersion" - - - name: Verify routes reference defined pipelines - run: | - set -euo pipefail - # Each route's `pipeline` must correspond to a default/pipelines//conf.yml - mapfile -t pipelines_in_routes < <(yq -r '.routes[].pipeline' default/pipelines/route.yml | sort -u) - missing=0 - for pipeline in "${pipelines_in_routes[@]}"; do - if [[ -z "$pipeline" || "$pipeline" == "null" ]]; then continue; fi - conf="default/pipelines/$pipeline/conf.yml" - if [[ ! -f "$conf" ]]; then - echo "::error::Route references pipeline '$pipeline' but $conf does not exist" - missing=$((missing+1)) - fi - done - if [[ $missing -gt 0 ]]; then exit 1; fi - echo "All route -> pipeline references valid." - - - name: Verify routes use __group output (vct-pack-validator rule) - run: | - set -euo pipefail - # Routes should use output: __group, not input_id (breaks on source rename) - bad=$(yq -r '.routes[] | select(.output != "__group") | .id' default/pipelines/route.yml) - if [[ -n "$bad" ]]; then - echo "::warning::These routes do not use 'output: __group' (validator rule): $bad" - fi - - - name: Verify samples directory non-empty (warn only) - run: | - if [[ -d data/samples ]]; then - count=$(find data/samples -maxdepth 1 -name '*.json' -type f | wc -l | tr -d ' ') - if [[ $count -eq 0 ]]; then - echo "::warning::data/samples/ exists but contains no JSON sample events" - else - echo "Found $count sample event file(s) in data/samples/" - fi - else - echo "::warning::data/samples/ does not exist — pack lacks sample events" - fi - - - name: Lint YAML - run: | - # Permissive config: only fail on errors, not warnings - cat > /tmp/yamllint.yml <<'EOF' - extends: default - rules: - line-length: disable - comments-indentation: disable - comments: disable - truthy: - level: warning - indentation: - level: warning - document-start: disable - EOF - yamllint -c /tmp/yamllint.yml default/ - - test: - name: Test pack pipelines - runs-on: ubuntu-latest - needs: validate - env: - PACK_TYPE: ${{ inputs.pack_type }} - services: - cribl: - image: cribl/cribl:${{ inputs.cribl_version }} - ports: - - 9000:9000 - - 10080:10080 - options: >- - --health-cmd "curl -fsS http://localhost:9000/api/v1/health || exit 1" - --health-interval 10s - --health-timeout 5s - --health-retries 30 - --health-start-period 30s - steps: - - name: Checkout pack - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ inputs.python_version }} - cache: pip - cache-dependency-path: tests/requirements.txt - - - name: Install Python deps - run: pip install -r tests/requirements.txt - - - name: Wait for Cribl to be ready - run: | - set -euo pipefail - for i in $(seq 1 60); do - if curl -fsS http://localhost:9000/api/v1/health >/dev/null 2>&1; then - echo "Cribl is ready (attempt $i)" - exit 0 - fi - sleep 2 - done - echo "::error::Cribl did not become ready in 120s" - docker ps -a - exit 1 - - - name: Run pytest - env: - CRIBL_HOST: localhost - CRIBL_PORT: "9000" - CRIBL_USER: admin - CRIBL_PASS: admin - run: | - cd tests - python -m pytest -v --tb=short --junitxml=/tmp/pytest-results.xml - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: pytest-results - path: /tmp/pytest-results.xml diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..7191934 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,96 @@ +# dryvist org standards (AI assistant policy) + +This file is the canonical AI-assistant guidance for the **dryvist** GitHub +org. It applies to every repo under . Repo-level +`CLAUDE.md` files may extend or specialize, but **MUST NOT** contradict the +rules below. + +## Language policy: TypeScript everywhere + +All code we write is **TypeScript** unless a runtime forces otherwise. +This includes: + +- Test harnesses (Vitest) +- Custom GitHub Actions (`@actions/core` + TypeScript) +- CLIs and tools we author +- Scripts that ship as committed artifacts + +Configs stay in their natural format: YAML for GitHub Actions workflows, +JSONC (`biome.jsonc`) where comments help, plain JSON where the consumer +demands it (e.g. `release-please-config.json`). Cribl pack content +(`default/`, `data/samples/`, `tests/fixtures/`) is JSON/YAML, not code. + +**Rationale:** ecosystem alignment with our GitHub Actions, Cribl pack +expressions (which are JavaScript), and the broader 2026 dev ecosystem. +Python is not used for new dryvist work. + +## Tooling baseline + +| Concern | Tool | Notes | +|---|---|---| +| Runtime | Node.js (current LTS) | `actions/setup-node@v4` in CI | +| Package manager | npm | Universal in CI; lockfile committed | +| Test runner | Vitest | Native ESM/TS; no `ts-jest` dance | +| Lint + format | Biome | Single config (`biome.jsonc`); see `biome.jsonc` in this repo | +| Type check | `tsc --noEmit` | TypeScript strict mode required in `tsconfig.json` | +| Release automation | release-please | Inherited from `JacobPEvans/.github` | +| Dependency updates | Renovate | Extends `JacobPEvans/.github:renovate-presets` | + +The canonical `biome.jsonc` lives in this repo at the root. Repos copy it at +scaffold time; periodic sync is handled by Renovate's custom manager (or +manual update for now — see `renovate.json`). + +## Inheritance from `JacobPEvans/.github` + +We reuse JacobPEvans's reusable workflows directly. Don't fork or wrap them +unless we need behavior they don't provide. + +| Need | Inherited from | Caller pattern | +|---|---|---| +| Release-please (with org-wide major-bump block) | `JacobPEvans/.github/.github/workflows/_release-please.yml@main` | See `release-please.yml` in any dryvist repo | +| Renovate presets | `github>JacobPEvans/.github:renovate-presets` | `extends` in `renovate.json` | +| Security policy structure | `JacobPEvans/.github/SECURITY.md` | Adapted/scoped to dryvist (this repo) | + +**Inheritance chain:** `JacobPEvans/.github` → `dryvist/.github` → individual +dryvist repos. Re-inheritance works through the same mechanisms (workflow +`uses:` + Renovate `extends:`). + +**Prereq for release-please:** the JacobPEvans reusable workflow needs the +GitHub App secrets `GH_ACTION_JACOBPEVANS_APP_ID` + `GH_APP_PRIVATE_KEY` +configured at the org level on `dryvist`. (Owner sets these manually; agent +should not attempt to install the App.) + +## Scope of this repo + +`dryvist/.github` is **org-wide infrastructure only**. It contains: + +- AI assistant policy (this file) +- Org-wide tooling configs (`biome.jsonc`, `renovate.json`) +- Community health files GitHub auto-applies (`SECURITY.md`, `profile/README.md`) +- Caller workflow templates that wire up inherited reusable workflows + +It does **NOT** contain anything vendor- or product-specific. Cribl pack +infrastructure lives in [`dryvist/cc-edge-pack-template`](https://github.com/dryvist/cc-edge-pack-template). +Future vendor packs (if any) get their own template repo — never `.github`. + +## Workflow expectations + +For every change in dryvist: + +1. Refresh the repo and create a worktree before making changes (per the + user's global workflow guidance). +2. Edits go through PRs — no direct commits to `main`. +3. CI must be green before merge. Use `gh pr checks --watch` to confirm. +4. Don't tag versions yourself; the user controls release timing. +5. Conventional commits (`fix:`, `feat:`, `chore:`, etc.) — release-please + uses these to compute bumps. + +## When in doubt + +- Read [`JacobPEvans/.github`](https://github.com/JacobPEvans/.github) for the + upstream patterns we inherit. +- Read this repo's `biome.jsonc` for current lint/format rules. +- Read [`dryvist/cc-edge-pack-template`](https://github.com/dryvist/cc-edge-pack-template) + for Cribl-specific test/build scaffolding. +- For release-please specifics, the inherited workflow's docstring at + `JacobPEvans/.github/.github/workflows/_release-please.yml` is authoritative. diff --git a/README.md b/README.md index deaea1f..dc1571e 100644 --- a/README.md +++ b/README.md @@ -1,85 +1,107 @@ # dryvist/.github -Org-level community defaults and reusable GitHub Actions workflows for the dryvist organization. +Org-wide standards and inheritance hub for the [dryvist](https://github.com/dryvist) +GitHub organization. Contains AI assistant policy, lint/format config, +dependency-management config, security policy, and the org profile page. -## Installation +This repo holds **only** vendor-agnostic org infrastructure. Cribl-specific +test harnesses and reusable workflows live in +[`dryvist/cc-edge-pack-template`](https://github.com/dryvist/cc-edge-pack-template). -This repository is not installed — it is referenced from other repositories' workflows. To use a workflow from this repo in your pack repo: +## Installation -1. Ensure your pack repo follows the layout from [`dryvist/cc-edge-pack-template`](https://github.com/dryvist/cc-edge-pack-template) (has `default/`, `data/samples/`, `tests/`, `package.json`). -2. Add a thin caller workflow to your pack repo (see Usage below). -3. No tokens or secrets need to be set — the reusable workflow uses public Docker images and the calling repo's read-only checkout token. +This repo is consumed by reference, not installed. Other dryvist repos +inherit configs and policies via the mechanisms below. -Cross-org calls work as long as this repo (`dryvist/.github`) is **public** or marked **internal** with org-default visibility, and the caller repo's actions settings permit calling reusable workflows from non-organisation repos. +| Inheritance mechanism | Where it shows up | +|---|---| +| GitHub auto-applied org files (`SECURITY.md`, `profile/README.md`) | Visible on every dryvist repo's Security tab + at | +| Renovate `extends` | `renovate.json` in each repo: `extends: github>JacobPEvans/.github:renovate-presets` (this repo's `renovate.json` is the example) | +| Biome config | Each repo carries a copy of `biome.jsonc` scaffolded from this repo; Renovate keeps it in sync | +| AI assistant policy | `CLAUDE.md` — read by Claude Code on every session | ## Usage -### `cribl-pack-test.yml` — validates and tests a Cribl pack +### Add the org standards to a new dryvist repo -Adopts the [criblpacks](https://github.com/criblpacks) test pattern (Python + Docker + Cribl management API) and extends it with auto-discovered fixture-based pipeline assertions and structural validation drawn from the [VisiCore/vct-cribl-pack-validator](https://github.com/VisiCore/vct-cribl-pack-validator) ruleset. +For a new TS-based dryvist repo, copy the canonical configs from this repo: + +```sh +# From the new repo's root: +gh api repos/dryvist/.github/contents/biome.jsonc --jq '.content' | base64 -d > biome.jsonc +gh api repos/dryvist/.github/contents/renovate.json --jq '.content' | base64 -d > renovate.json +``` -Add this to your pack repo at `.github/workflows/test.yml`: +If the repo is a Cribl pack, scaffold from +[`dryvist/cc-edge-pack-template`](https://github.com/dryvist/cc-edge-pack-template) +instead — the template already includes the canonical configs. + +### Wire up release-please in a dryvist repo + +Each repo needs `.release-please-manifest.json` + `release-please-config.json` +plus a thin caller workflow that delegates to the inherited reusable workflow: ```yaml -name: Test +# .github/workflows/release-please.yml +name: release-please on: - pull_request: - paths: - - 'default/**' - - 'data/samples/**' - - 'tests/**' - - 'package.json' push: branches: [main] - +permissions: + contents: write + pull-requests: write jobs: - test: - uses: dryvist/.github/.github/workflows/cribl-pack-test.yml@main - with: - pack_type: edge # or 'stream' + release-please: + uses: JacobPEvans/.github/.github/workflows/_release-please.yml@main + secrets: + GH_ACTION_JACOBPEVANS_APP_ID: ${{ secrets.GH_ACTION_JACOBPEVANS_APP_ID }} + GH_APP_PRIVATE_KEY: ${{ secrets.GH_APP_PRIVATE_KEY }} ``` -Inputs: +Org-level secret prereqs (one-time, owner-handled): -| Input | Required | Default | Description | -|---|---|---|---| -| `pack_type` | yes | — | `edge` or `stream` | -| `cribl_version` | no | `latest` | `cribl/cribl` Docker tag | -| `python_version` | no | `3.12` | Python interpreter | +- `GH_ACTION_JACOBPEVANS_APP_ID` +- `GH_APP_PRIVATE_KEY` -Jobs run by this workflow: +These are the same secrets the upstream JacobPEvans org uses. Set them at +`https://github.com/organizations/dryvist/settings/secrets/actions` after +installing the corresponding GitHub App on the dryvist org. -1. **validate** — Structural checks: required files, routes-reference-pipelines, `package.json` shape, yamllint, vct-cribl-pack-validator rule extraction. -2. **test** — Spins up `cribl/cribl` as a service container, installs the pack via the management API, runs `pytest tests/` against the live instance. +## API -## Contributing +This repo exposes the following inheritance surfaces: -Workflow changes must keep the contract stable for downstream packs. Specifically: do not rename inputs, do not change required input semantics, and bump major versions of any workflow if making breaking changes. +| Path | Purpose | +|---|---| +| `CLAUDE.md` | AI assistant policy (read by Claude Code) | +| `biome.jsonc` | Canonical Biome lint + format config | +| `renovate.json` | Org-default Renovate extending JacobPEvans presets | +| `SECURITY.md` | Org-wide vulnerability reporting policy (auto-applied to every dryvist repo's Security tab) | +| `profile/README.md` | Org profile page at | -To validate a change locally before pushing: +## Contributing -```bash -# Lint the workflow -yamllint .github/workflows/ +Changes here affect every dryvist repo. Tread carefully: -# Test against a real pack -cd ~/git/cc-edge-claude-code-io/main -gh workflow run test.yml --ref my-test-branch -``` +- Bump rules in `biome.jsonc` cautiously — they cascade to every repo on next sync. +- Don't introduce vendor-specific (Cribl, etc.) content. That belongs in the relevant template repo. +- Conventional commits required (`feat:`, `fix:`, `chore:`, `docs:`). -## API - -This repository exposes one public reusable workflow: +To validate locally before pushing: -- `dryvist/.github/.github/workflows/cribl-pack-test.yml@` — see Usage above for inputs. +```sh +# Lint this repo's own files (requires Biome installed locally) +npx -y @biomejs/biome check . +``` ## License -Apache-2.0 (matches the org default). +[Apache-2.0](LICENSE). ## References -- [criblpacks/cribl-palo-alto-networks](https://github.com/criblpacks/cribl-palo-alto-networks) — original test pattern this workflow adopts -- [VisiCore/vct-cribl-pack-validator](https://github.com/VisiCore/vct-cribl-pack-validator) — Claude Code skill for deeper structural validation (developer pre-PR step) -- [Cribl management API](https://docs.cribl.io/api-reference/) -- [GitHub reusable workflows](https://docs.github.com/en/actions/sharing-automations/reusing-workflows) +- [`JacobPEvans/.github`](https://github.com/JacobPEvans/.github) — upstream org we inherit from +- [`dryvist/cc-edge-pack-template`](https://github.com/dryvist/cc-edge-pack-template) — Cribl pack template +- [Biome configuration reference](https://biomejs.dev/reference/configuration/) +- [Renovate `extends` docs](https://docs.renovatebot.com/config-presets/) +- [release-please-action](https://github.com/googleapis/release-please-action) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..def9587 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,51 @@ +# Security Policy + +## Reporting Vulnerabilities + +To report a security vulnerability in any **dryvist** repository, use +[GitHub's private vulnerability reporting](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability) +on the affected repository. Do not open a public issue for security +vulnerabilities. + +For critical vulnerabilities affecting multiple dryvist repositories, report +to this [.github repository](https://github.com/dryvist/.github/security/advisories/new). + +## Dependency Trust + +Automated dependency updates use Renovate via the inherited preset +[`JacobPEvans/.github:renovate-presets`](https://github.com/JacobPEvans/.github/blob/main/renovate-presets.json). +The presets enforce a tiered trust model: + +| Tier | Scope | Stabilization | Auto-merge | +|---|---|---|---| +| **Always Trusted** | `dryvist/**`, `JacobPEvans/**` (self-owned) | 0 days | Yes, CI-gated | +| **Trusted, Wait** | GitHub Actions from established orgs (npm, googleapis, actions, etc.) | 3 days | Minor/patch auto; major manual | +| **Default** | All other external dependencies | 3 days | Manual review | + +GitHub Actions from untrusted orgs are pinned to SHA digests, not tags +(`pinGitHubActionDigests: true` in the inherited preset). Vulnerability +alerts auto-merge without the 3-day wait. + +## Version Pinning + +| Source | Strategy | +|---|---| +| dryvist self-references | `@main` or major version tag — never SHA or minor/patch pins | +| JacobPEvans inherited workflows | `@main` (per the inherited org's policy) | +| Trusted GitHub Actions | Semantic version tags (`@v6`) | +| External/untrusted GitHub Actions | SHA commit hash pins | +| npm packages | Lower-bound (`^x.y.z`) in `package.json`; lockfile committed | + +## Secret Management + +- No production credentials are committed to git. +- Repo-level secrets configured via `gh secret set`. +- Org-level secrets (e.g., the GitHub App token for release-please) configured + via `gh secret set --org dryvist`. + +## Auditable Workflow Boundaries + +Reusable workflows we inherit from `JacobPEvans/.github` are pinned to `@main` +intentionally — the upstream org follows the same security posture as +dryvist. If you need to audit a specific workflow run, the resolved SHA is +logged in the GitHub Actions UI for that run. diff --git a/biome.jsonc b/biome.jsonc new file mode 100644 index 0000000..736a1b5 --- /dev/null +++ b/biome.jsonc @@ -0,0 +1,69 @@ +{ + // dryvist canonical Biome config — single source of truth for the org. + // Repos copy this at scaffold time; Renovate keeps copies in sync. + // Schema: https://biomejs.dev/reference/configuration/ + "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignore": [ + "**/node_modules", + "**/.venv", + "**/dist", + "**/coverage", + "**/.direnv", + // Cribl pack content is YAML/JSON authored by Cribl tooling — leave it alone. + "**/default/**", + "**/data/samples/**", + "**/tests/fixtures/**" + ] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 2, + "lineWidth": 100, + "lineEnding": "lf" + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "style": { + // We keep nullish narrowing explicit — disallow non-null assertions. + "noNonNullAssertion": "error", + // Imports stay grouped + sorted by Biome's organizer (run via `biome check --write`). + "useImportType": "warn" + }, + "suspicious": { + // Console output is fine in test fixtures + scripts; tighten in libraries via per-repo override. + "noConsole": "off" + }, + "correctness": { + "noUnusedImports": "error", + "noUnusedVariables": "error" + } + } + }, + "javascript": { + "formatter": { + "quoteStyle": "single", + "semicolons": "always", + "trailingCommas": "all", + "arrowParentheses": "always" + } + }, + "json": { + "formatter": { + "trailingCommas": "none" + }, + "parser": { + // Allow JSONC syntax for files like this one + tsconfig.json. + "allowComments": true, + "allowTrailingCommas": true + } + } +} diff --git a/profile/README.md b/profile/README.md new file mode 100644 index 0000000..9f31b4f --- /dev/null +++ b/profile/README.md @@ -0,0 +1,63 @@ +# dryvist + +Cribl pack development under [dryvist](https://github.com/dryvist) — open +infrastructure for AI-coding-tool observability. + +## Active repositories + +| Repo | Purpose | +|---|---| +| [`cc-edge-pack-template`](https://github.com/dryvist/cc-edge-pack-template) | Template for new Cribl Edge / Stream packs | +| [`cc-edge-claude-code-io`](https://github.com/dryvist/cc-edge-claude-code-io) | Claude Code session-logs + OpenTelemetry pack | +| [`.github`](https://github.com/dryvist/.github) | Org-wide standards: AI policy, Biome config, security policy, renovate inheritance | + +## Installation + +To start a new dryvist Cribl pack, scaffold from the template: + +```sh +gh repo create dryvist/cc-edge--io --public --template dryvist/cc-edge-pack-template +gh repo clone dryvist/cc-edge--io +cd cc-edge--io +npm install +``` + +To install one of our published packs into a Cribl deployment, download the +`.crbl` artifact from the repo's GitHub Releases and import via the Cribl UI +(Manage → Packs → Add Pack → Upload). + +## Usage + +Each pack repo carries its own development tooling — see the per-repo +README for `make` / `npm` targets specific to that pack. + +Org-wide tooling and conventions live in +[`.github`](https://github.com/dryvist/.github): + +- [`CLAUDE.md`](https://github.com/dryvist/.github/blob/main/CLAUDE.md) — AI assistant policy + inheritance chain +- [`biome.jsonc`](https://github.com/dryvist/.github/blob/main/biome.jsonc) — canonical Biome lint + format rules +- [`SECURITY.md`](https://github.com/dryvist/.github/blob/main/SECURITY.md) — vulnerability reporting + dependency trust tiers +- [`renovate.json`](https://github.com/dryvist/.github/blob/main/renovate.json) — extends `JacobPEvans/.github:renovate-presets` + +## Standards + +- **Language:** TypeScript everywhere we write code (test harnesses, custom GitHub Actions, tooling) +- **Lint + format:** [Biome](https://biomejs.dev) (canonical config in `.github/biome.jsonc`) +- **Test runner:** [Vitest](https://vitest.dev) +- **Releases:** [release-please](https://github.com/googleapis/release-please) inherited from [`JacobPEvans/.github`](https://github.com/JacobPEvans/.github) +- **Dependency updates:** Renovate inherited via `extends: github>JacobPEvans/.github:renovate-presets` + +## Contributing + +Issues and pull requests are welcome on any of the active repositories above. +For changes that affect multiple packs (e.g., updates to the test harness or +shared workflows), open the PR against +[`cc-edge-pack-template`](https://github.com/dryvist/cc-edge-pack-template) +or [`.github`](https://github.com/dryvist/.github) as appropriate, and we'll +sweep the change across consumer packs. + +## License + +All dryvist repositories are licensed under +[Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) unless individual +repos state otherwise. diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..e78c3ce --- /dev/null +++ b/renovate.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended", + "github>JacobPEvans/.github:renovate-presets" + ] +} From 16df53b48517a9112e2889a635327bd23c232022 Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans@users.noreply.github.com> Date: Sat, 25 Apr 2026 20:23:11 -0400 Subject: [PATCH 2/5] fix(biome): migrate config to schema 2.3.6 (`includes` instead of `ignore`) Biome 2.x renamed the `ignore` array to `includes` (with `!` prefix for negative patterns). The 2.0.0 schema this PR originally shipped is rejected by Biome 2.3.6. Migrated via `biome migrate --write` and reviewed. Verified by running biome check + tsc against the same config in dryvist/cc-edge-pack-template (PR #3). (claude) --- biome.jsonc | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/biome.jsonc b/biome.jsonc index 736a1b5..be4126b 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -1,24 +1,24 @@ { // dryvist canonical Biome config — single source of truth for the org. - // Repos copy this at scaffold time; Renovate keeps copies in sync. + // Pack repos copy this at scaffold time; Renovate keeps copies in sync. // Schema: https://biomejs.dev/reference/configuration/ - "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json", + "$schema": "https://biomejs.dev/schemas/2.3.6/schema.json", "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true }, "files": { - "ignore": [ - "**/node_modules", - "**/.venv", - "**/dist", - "**/coverage", - "**/.direnv", - // Cribl pack content is YAML/JSON authored by Cribl tooling — leave it alone. - "**/default/**", - "**/data/samples/**", - "**/tests/fixtures/**" + "includes": [ + "**", + "!**/node_modules", + "!**/.venv", + "!**/dist", + "!**/coverage", + "!**/.direnv", + "!**/default", + "!**/data/samples", + "!**/tests/fixtures" ] }, "formatter": { @@ -33,13 +33,10 @@ "rules": { "recommended": true, "style": { - // We keep nullish narrowing explicit — disallow non-null assertions. "noNonNullAssertion": "error", - // Imports stay grouped + sorted by Biome's organizer (run via `biome check --write`). "useImportType": "warn" }, "suspicious": { - // Console output is fine in test fixtures + scripts; tighten in libraries via per-repo override. "noConsole": "off" }, "correctness": { @@ -61,7 +58,6 @@ "trailingCommas": "none" }, "parser": { - // Allow JSONC syntax for files like this one + tsconfig.json. "allowComments": true, "allowTrailingCommas": true } From e9c22da75e3a0260b425cd587910a6362f8eb366 Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans@users.noreply.github.com> Date: Sat, 25 Apr 2026 21:12:51 -0400 Subject: [PATCH 3/5] docs: rename dryvist-side release-please secret to generic GH_APP_ID Documents the wrap pattern: dryvist exposes only generic GH_APP_ID + GH_APP_PRIVATE_KEY at the org level. Caller workflows forward them to whatever input the inherited workflow expects. Adds owner-facing setup steps for the GitHub App install + secret configuration. (claude) --- CLAUDE.md | 18 ++++++++++++++---- README.md | 33 +++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 7191934..0631eb1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -55,10 +55,20 @@ unless we need behavior they don't provide. dryvist repos. Re-inheritance works through the same mechanisms (workflow `uses:` + Renovate `extends:`). -**Prereq for release-please:** the JacobPEvans reusable workflow needs the -GitHub App secrets `GH_ACTION_JACOBPEVANS_APP_ID` + `GH_APP_PRIVATE_KEY` -configured at the org level on `dryvist`. (Owner sets these manually; agent -should not attempt to install the App.) +**Prereq for release-please:** the inherited workflow needs a GitHub App +token at runtime. dryvist exposes two generic org-level secrets — caller +workflows in each dryvist repo forward them to the inherited workflow at the +boundary (the inherited workflow's input is JACOBPEVANS-named for historical +reasons; dryvist consumers see only the generic names): + +| dryvist org secret | Forwards to inherited input | +|---|---| +| `GH_APP_ID` | `GH_ACTION_JACOBPEVANS_APP_ID` | +| `GH_APP_PRIVATE_KEY` | `GH_APP_PRIVATE_KEY` | + +(Owner sets these manually after installing the App on the dryvist org; +agent should not attempt to install the App. See `README.md` for setup +steps.) ## Scope of this repo diff --git a/README.md b/README.md index dc1571e..c84dafb 100644 --- a/README.md +++ b/README.md @@ -53,19 +53,40 @@ permissions: jobs: release-please: uses: JacobPEvans/.github/.github/workflows/_release-please.yml@main + # The inherited workflow's input is named GH_ACTION_JACOBPEVANS_APP_ID for + # historical reasons. dryvist exposes a generic GH_APP_ID org secret and + # forwards it here at the boundary — repo readers only see the generic name. secrets: - GH_ACTION_JACOBPEVANS_APP_ID: ${{ secrets.GH_ACTION_JACOBPEVANS_APP_ID }} + GH_ACTION_JACOBPEVANS_APP_ID: ${{ secrets.GH_APP_ID }} GH_APP_PRIVATE_KEY: ${{ secrets.GH_APP_PRIVATE_KEY }} ``` Org-level secret prereqs (one-time, owner-handled): -- `GH_ACTION_JACOBPEVANS_APP_ID` -- `GH_APP_PRIVATE_KEY` +- `GH_APP_ID` — App ID (numeric) +- `GH_APP_PRIVATE_KEY` — App private key PEM -These are the same secrets the upstream JacobPEvans org uses. Set them at -`https://github.com/organizations/dryvist/settings/secrets/actions` after -installing the corresponding GitHub App on the dryvist org. +Generic names so any future App swap or org-internal rebrand is a one-line +secret update — no caller-workflow churn. + +### One-time GitHub App setup (owner-handled) + +1. Locate the App owned by JacobPEvans (`https://github.com/settings/apps` or + `https://github.com/organizations/JacobPEvans/settings/apps`). +2. Verify "Where can this GitHub App be installed?" is set to "Any account" + (change + save if currently "Only on this account"). +3. Visit the App's public install URL (`https://github.com/apps//installations/new`) + and install on the **dryvist** org with access to "All repositories". +4. Back in the App settings: copy the App ID; generate + download a private + key `.pem` (cannot be re-downloaded). +5. Set the dryvist org secrets: + + ```sh + gh secret set GH_APP_ID --org dryvist --visibility all + gh secret set GH_APP_PRIVATE_KEY --org dryvist --visibility all < /path/to/private-key.pem + ``` + + Or via UI at . ## API From 95a5f1ccab52e64210a5bc807aadb53db42a1174 Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans@users.noreply.github.com> Date: Wed, 27 May 2026 10:37:33 -0400 Subject: [PATCH 4/5] refactor(biome): delegate formatting to .editorconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add .editorconfig as the single source of truth for whitespace rules (indent style/size, EOL, trailing whitespace, final newline). - Set formatter.useEditorconfig: true in biome.jsonc and drop the redundant formatter indent/width/lineEnding block. - Drop per-language overrides (javascript quote/semicolons, json trailingCommas) — defaults now come from .editorconfig. - Reduce linter to enabled-only; revisit custom rule set separately. - Trim unused !**/.venv and !**/coverage from includes (no matching artifacts in this repo). Assisted-by: Claude --- .editorconfig | 12 ++++++++++++ biome.jsonc | 40 ++-------------------------------------- 2 files changed, 14 insertions(+), 38 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8c52ff9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false diff --git a/biome.jsonc b/biome.jsonc index be4126b..d030f1c 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -1,7 +1,6 @@ { // dryvist canonical Biome config — single source of truth for the org. // Pack repos copy this at scaffold time; Renovate keeps copies in sync. - // Schema: https://biomejs.dev/reference/configuration/ "$schema": "https://biomejs.dev/schemas/2.3.6/schema.json", "vcs": { "enabled": true, @@ -12,51 +11,16 @@ "includes": [ "**", "!**/node_modules", - "!**/.venv", "!**/dist", - "!**/coverage", "!**/.direnv", "!**/default", "!**/data/samples", "!**/tests/fixtures" ] }, - "formatter": { - "enabled": true, - "indentStyle": "space", - "indentWidth": 2, - "lineWidth": 100, - "lineEnding": "lf" - }, - "linter": { - "enabled": true, - "rules": { - "recommended": true, - "style": { - "noNonNullAssertion": "error", - "useImportType": "warn" - }, - "suspicious": { - "noConsole": "off" - }, - "correctness": { - "noUnusedImports": "error", - "noUnusedVariables": "error" - } - } - }, - "javascript": { - "formatter": { - "quoteStyle": "single", - "semicolons": "always", - "trailingCommas": "all", - "arrowParentheses": "always" - } - }, + "formatter": { "enabled": true, "useEditorconfig": true }, + "linter": { "enabled": true }, "json": { - "formatter": { - "trailingCommas": "none" - }, "parser": { "allowComments": true, "allowTrailingCommas": true From edc37cf238176c5fba3a7bde2bae558a482ca724 Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans-personal@users.noreply.github.com> Date: Fri, 29 May 2026 08:42:43 -0400 Subject: [PATCH 5/5] chore(biome): set lineWidth to 120 Assisted-by: Claude --- biome.jsonc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biome.jsonc b/biome.jsonc index 37bcc3f..65c8edc 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -24,7 +24,7 @@ "formatter": { "enabled": true, "useEditorconfig": true, - "lineWidth": 100 + "lineWidth": 120 }, "linter": { "enabled": true,