docs(audit): opencode system audit — documentation polish, run records, and config hardening#17
Conversation
…bpaths (AUD-P0-001, AUD-P0-002) Replace blanket '.opencode' EXCLUDE_DIRS with targeted subpath excludes (.opencode/agents, commands, skills, documentation, benchmarks), leaving .opencode/run-logs/ scannable by the secret scanner. Also replace legacy .chatgpt-context-pack* excludes with .context-pack/.
…ke test (AUD-P0-003, AUD-P1-001) AUD-P0-003: Create canonical context-pack generator (scripts/dev/generate-context-pack.sh) - Uses git ls-files to respect .gitignore (root cause fix) - Purges .opencode/run-logs/* before every generation (pre-export hook) - Replaces two external unsafe generators with one source-controlled script - Updated .gitignore: /.chatgpt-context-pack* -> /.context-pack/ AUD-P1-001: Build ADR-0008 smoke test (scripts/security/check-opencode-config.sh) - 11 assertions against opencode.jsonc, all passing - Wired into CI (check-all.sh) and pre-push hook - ADR-0008 updated: default_agent plan->delivery (post-decision annotation)
…P2-004) AUD-P2-003: Create docs/workflows/repository-audit-workflow.md - Documents the repo-auditor -> AGENT_HANDOFF.md -> repo-repair cycle - Mirrors the documentation workflow doc structure AUD-P2-004: Extract generic audit template - templates/repo-audits/opencode-system-audit-template.md from repo-auditor.md - All 11 schema sections preserved - repo-auditor.md updated with canonical template reference - Audit report filed under audits/ as first worked example
…scan (AUD-P2-001, P2-005, P2-006, P1-002, P3-001)
AUD-P2-001: Add /quality-check slash command for git-quality agent
AUD-P2-005: Create .opencode/REGISTRY.md (25 agents, 28 commands, 12 skills)
CI assertion validates counts vs. REGISTRY.md and README.md
AUD-P2-006: Permission-block regression test across 7 agents
(check-agent-permissions.sh verifies 12 secret-path deny patterns)
AUD-P1-002: Dev-dependency advisory scan added to check-dependencies.sh
(informational only, non-blocking per user decision)
AUD-P3-001: Bash deny-list asymmetry documented in REGISTRY.md §Notes
README.md: 27->28 commands (new /quality-check)
…ll phases) Phase A: Stop the bleeding (AUD-P0-001, AUD-P0-002) Phase B: Close structural gap (AUD-P0-003, AUD-P1-001) Phase C: Fill documented gap (AUD-P2-003, AUD-P2-004) Phase D: Polish (AUD-P2-001/005/006, P1-002, P3-001) Includes AGENT_HANDOFF_OPENCODE_SYSTEM.md delivery handoff and Phase B execution plan with pre-execution discoveries.
…on and run records - Align table formatting in REGISTRY.md, AGENT_HANDOFF, audit report, workflow doc - Add spacing/readability improvements across all Phase A-D run records - Consistent italic formatting and structural cleanup in PHASE-B execution plan - No functional or code changes
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cf1a8f4280
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| # ── Check 10: Destructive and publishing commands denied ── | ||
| echo -n "10. Destructive commands denied ... " | ||
| DESTRUCTIVE=("git push*" "git reset*" "git clean*" "git restore*" "rm -rf *" "sudo *" "npm publish*" "pnpm publish*") |
There was a problem hiding this comment.
Align the git-push smoke test with the ask policy
With this commit, opencode.jsonc now sets permission.bash["git push*"] to ask, and both scripts/ci/check-all.sh and the pre-push hook run this smoke test. However check 10 still treats git push* as a command that must equal deny, so bash scripts/security/check-opencode-config.sh fails on the current checkout with FAILED — 1 commands not denied, which in turn blocks pnpm ci:check and installed pushes to main until the assertion or the config is made consistent.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
Bundles the OpenCode system audit follow-up work: adds/updates audit documentation and run records, hardens security/CI checks to prevent config and registry drift, and tweaks OpenCode command permissions (notably git push from deny → ask) to require explicit prompts instead of hard-blocking.
Changes:
- Hardened security/CI automation: OpenCode config smoke test, registry count checks, and agent-permission consistency checks wired into
check-all.shand pre-push. - Replaced legacy context-pack conventions with a canonical, gitignored
.context-pack/output and a source-controlled generator script. - Added audit workflow documentation/template + audit artifacts/run records from the 2026-06-20 system audit.
Reviewed changes
Copilot reviewed 24 out of 25 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| templates/repo-audits/opencode-system-audit-template.md | Adds a canonical audit handoff template derived from repo-auditor schema. |
| scripts/security/check-secrets.sh | Narrows secret-scan excludes (scans .opencode/run-logs/ again) and excludes .context-pack/. |
| scripts/security/check-opencode-config.sh | Adds ADR-0008 “effective configuration” smoke test for opencode.jsonc. |
| scripts/security/check-dependencies.sh | Adds informational dev-dependency advisory scan alongside prod audit. |
| scripts/git-hooks/pre-push | Runs the OpenCode config smoke test on push. |
| scripts/dev/generate-context-pack.sh | Adds canonical git-ls-files-based context-pack generator with run-logs purge. |
| scripts/ci/check-registry-counts.sh | Adds CI enforcement for agent/command/skill counts vs REGISTRY/README. |
| scripts/ci/check-all.sh | Wires new smoke test + registry/permission consistency checks into the CI-equivalent script. |
| scripts/ci/check-agent-permissions.sh | Adds CI check to keep secret-path read-deny patterns consistent across key agents. |
| README.md | Updates command count reference (27 → 28). |
| planning/runs/AUD-OPENSYS-PHASE-A.md | Adds Phase A run record (secrets + scanner exclusion fix). |
| planning/runs/AUD-OPENSYS-PHASE-B.md | Adds Phase B run record (ADR-0008 alignment + generator + smoke test). |
| planning/runs/AUD-OPENSYS-PHASE-C.md | Adds Phase C run record (audit workflow docs + template). |
| planning/runs/AUD-OPENSYS-PHASE-D.md | Adds Phase D run record (registry, CI assertions, dev-dep scan policy, /quality-check). |
| planning/PHASE-B-EXECUTION-PLAN.md | Adds Phase B execution plan document for the audit remediation work. |
| opencode.jsonc | Changes git push* permission from deny → ask. |
| docs/workflows/repository-audit-workflow.md | Documents the audit → handoff → repair workflow and components. |
| docs/adr/0008-canonical-opencode-project-configuration.md | Updates ADR-0008 to match implemented default agent (delivery). |
| audits/opencode-system-audit-2026-06-20.md | Adds the audit report artifact under audits/. |
| AGENT_HANDOFF_OPENCODE_SYSTEM.md | Adds the audit handoff bridging findings to an execution plan. |
| .opencode/REGISTRY.md | Adds registry of agents/commands/skills + CI assertion references. |
| .opencode/commands/quality-check.md | Adds /quality-check command wiring for git-quality. |
| .opencode/agents/repo-auditor.md | References the new external audit template. |
| .opencode/agents/delivery.md | Changes git push* permission from deny → ask in agent frontmatter. |
| .gitignore | Replaces legacy context-pack ignores with canonical /.context-pack/. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| echo -n "10. Destructive commands denied ... " | ||
| DESTRUCTIVE=("git push*" "git reset*" "git clean*" "git restore*" "rm -rf *" "sudo *" "npm publish*" "pnpm publish*") | ||
| CMD_PROBLEMS=0 | ||
|
|
||
| for cmd in "${DESTRUCTIVE[@]}"; do | ||
| CV=$(jsonc_get_key '.permission.bash' "$cmd") | ||
| [ "$CV" != "deny" ] && CMD_PROBLEMS=$((CMD_PROBLEMS + 1)) | ||
| done | ||
|
|
||
| if [ "$CMD_PROBLEMS" -eq 0 ]; then | ||
| echo "PASSED (${#DESTRUCTIVE[@]} commands)" | ||
| PASSED=$((PASSED + 1)) | ||
| else | ||
| echo "FAILED — $CMD_PROBLEMS commands not denied" | ||
| FAILED=$((FAILED + 1)) | ||
| fi |
| # Uses `pnpm audit --prod` to check production dependencies against | ||
| # the public vulnerability database. Dev-only dependencies are scanned | ||
| # separately as informational only (they do not block the pipeline but | ||
| # are reported for awareness). | ||
| # Any vulnerability finding causes a non-zero exit to ensure issues are | ||
| # visible in CI. |
- P0: update check-opencode-config.sh check 10 to assert git push* as "ask" (split out from deny list; new check 10a verifies ask policy) - P1: fix broken ADR link in repository-audit-workflow.md (0008-opencode-config-consolidation → 0008-canonical-opencode-project-configuration) - P2: clarify check-dependencies.sh header comment (production audit blocks; dev audit is informational only) - P2: remove dead pnpm-lock.yaml from context-pack allowlist (excluded by Python filter as "huge, not useful for context")
|
|
||
| > **Template ID:** `opencode-system-audit-template` | ||
| > **Source:** extracted from `.opencode/agents/repo-auditor.md` §Required AGENT_HANDOFF.md | ||
| > **Canonical schema version:** as of `repo-auditor.md` lines 207-279 (2026-06-20) |
| # ── Step 2: Filter and generate with Python ── | ||
| echo "=== Generating context pack ($FORMAT format) ===" | ||
| rm -rf "$OUTPUT_DIR" | ||
| mkdir -p "$OUTPUT_DIR" |
| # Extract the read: section from the agent frontmatter | ||
| READ_SECTION=$(sed -n '/^ read:/,/^ [a-z]/{/^ read:/d;/^ [a-z]/d;p;}' "$AGENT_FILE" 2>/dev/null || echo "") | ||
|
|
||
| MISSING=0 | ||
| for pattern in "${CANONICAL_PATTERNS[@]}"; do | ||
| # Normalize pattern (remove leading/trailing whitespace, handle quoting) | ||
| normalized=$(echo "$pattern" | sed "s/'/\"/g") | ||
| if ! echo "$READ_SECTION" | grep -qF "$pattern" && ! echo "$READ_SECTION" | grep -qF "$normalized"; then | ||
| MISSING=$((MISSING + 1)) | ||
| fi | ||
| done | ||
|
|
||
| if [ "$MISSING" -eq 0 ]; then | ||
| echo " ✓ $agent — all ${#CANONICAL_PATTERNS[@]} secret-path read-denies present" | ||
| else | ||
| echo " ✗ $agent — $MISSING/${#CANONICAL_PATTERNS[@]} secret-path read-denies MISSING" | ||
| FAILED=1 | ||
| fi |
| AGENT_TABLE_START=$(grep -n "^## Agents" .opencode/REGISTRY.md | cut -d: -f1) | ||
| AGENT_TABLE_END=$(grep -n "^### Agent categories" .opencode/REGISTRY.md | cut -d: -f1) | ||
| REGISTRY_AGENTS=$(sed -n "${AGENT_TABLE_START},${AGENT_TABLE_END}p" .opencode/REGISTRY.md | grep -c "^| \`" || echo 0) | ||
| README_AGENTS=$(grep -oP '\d+(?= agents)' README.md 2>/dev/null | head -1 || echo 0) |
| CMD_TABLE_START=$(grep -n "^## Commands" .opencode/REGISTRY.md | cut -d: -f1) | ||
| CMD_TABLE_END=$(grep -n "^## Skills" .opencode/REGISTRY.md | cut -d: -f1) | ||
| REGISTRY_COMMANDS=$(sed -n "${CMD_TABLE_START},${CMD_TABLE_END}p" .opencode/REGISTRY.md | grep -c "^| \`/" || echo 0) | ||
| README_COMMANDS=$(grep -oP '\d+(?= commands)' README.md 2>/dev/null | head -1 || echo 0) |
- P0: add output-path safety checks to generate-context-pack.sh (blocks unsafe paths like ".", "/", empty, or non-hidden dirs) - P1: remove hard-coded line numbers from audit template header (prevents drift when repo-auditor.md changes) - P1: extend check-agent-permissions.sh to validate edit: denies (was only checking read:; now checks both read + edit) - P1: add missing edit: secret-path denies to qa, reviewer, repository-docs, and security agent configs - P2: replace grep -oP with portable grep -oE in check-registry-counts.sh (PCRE not available on BSD/macOS grep)
| ".opencode/agents" | ||
| ".opencode/commands" | ||
| ".opencode/skills" | ||
| ".opencode/documentation" | ||
| ".opencode/benchmarks" |
| if [ -d ".opencode/run-logs" ]; then | ||
| rm -f .opencode/run-logs/* | ||
| fi |
| # Safety: prevent --output from destroying the repo root or filesystem | ||
| if [ "$OUTPUT_DIR" = "." ] || [ "$OUTPUT_DIR" = "/" ] || [ "$OUTPUT_DIR" = "" ] || [ "$OUTPUT_DIR" = "$REPO_ROOT" ]; then | ||
| echo "ERROR: refusing to rm -rf unsafe output path: $OUTPUT_DIR" | ||
| exit 1 | ||
| fi | ||
| # Enforce output within repo (relative path starting with .context-pack or similar) | ||
| if [[ "$OUTPUT_DIR" != .* ]]; then | ||
| echo "ERROR: output directory must be a hidden dir inside the repo (starts with '.'), got: $OUTPUT_DIR" | ||
| exit 1 | ||
| fi |
| cd "$REPO_ROOT" | ||
|
|
||
| CONFIG_FILE="opencode.jsonc" | ||
| PACKAGE_FILE="package.json" | ||
| PASSED=0 | ||
| FAILED=0 | ||
|
|
* fix(security): narrow secret-scanner .opencode exclude to targeted subpaths (AUD-P0-001, AUD-P0-002)
Replace blanket '.opencode' EXCLUDE_DIRS with targeted subpath excludes
(.opencode/agents, commands, skills, documentation, benchmarks), leaving
.opencode/run-logs/ scannable by the secret scanner.
Also replace legacy .chatgpt-context-pack* excludes with .context-pack/.
* fix(audit): close structural gap — canonical generator + ADR-0008 smoke test (AUD-P0-003, AUD-P1-001)
AUD-P0-003: Create canonical context-pack generator (scripts/dev/generate-context-pack.sh)
- Uses git ls-files to respect .gitignore (root cause fix)
- Purges .opencode/run-logs/* before every generation (pre-export hook)
- Replaces two external unsafe generators with one source-controlled script
- Updated .gitignore: /.chatgpt-context-pack* -> /.context-pack/
AUD-P1-001: Build ADR-0008 smoke test (scripts/security/check-opencode-config.sh)
- 11 assertions against opencode.jsonc, all passing
- Wired into CI (check-all.sh) and pre-push hook
- ADR-0008 updated: default_agent plan->delivery (post-decision annotation)
* docs: add audit workflow documentation and template (AUD-P2-003, AUD-P2-004)
AUD-P2-003: Create docs/workflows/repository-audit-workflow.md
- Documents the repo-auditor -> AGENT_HANDOFF.md -> repo-repair cycle
- Mirrors the documentation workflow doc structure
AUD-P2-004: Extract generic audit template
- templates/repo-audits/opencode-system-audit-template.md from repo-auditor.md
- All 11 schema sections preserved
- repo-auditor.md updated with canonical template reference
- Audit report filed under audits/ as first worked example
* chore(audit): polish — registry, CI regression tests, dev-dependency scan (AUD-P2-001, P2-005, P2-006, P1-002, P3-001)
AUD-P2-001: Add /quality-check slash command for git-quality agent
AUD-P2-005: Create .opencode/REGISTRY.md (25 agents, 28 commands, 12 skills)
CI assertion validates counts vs. REGISTRY.md and README.md
AUD-P2-006: Permission-block regression test across 7 agents
(check-agent-permissions.sh verifies 12 secret-path deny patterns)
AUD-P1-002: Dev-dependency advisory scan added to check-dependencies.sh
(informational only, non-blocking per user decision)
AUD-P3-001: Bash deny-list asymmetry documented in REGISTRY.md §Notes
README.md: 27->28 commands (new /quality-check)
* docs(audit): add run records and handoff for opencode system audit (all phases)
Phase A: Stop the bleeding (AUD-P0-001, AUD-P0-002)
Phase B: Close structural gap (AUD-P0-003, AUD-P1-001)
Phase C: Fill documented gap (AUD-P2-003, AUD-P2-004)
Phase D: Polish (AUD-P2-001/005/006, P1-002, P3-001)
Includes AGENT_HANDOFF_OPENCODE_SYSTEM.md delivery handoff and
Phase B execution plan with pre-execution discoveries.
* docs(audit): polish formatting and structure across audit documentation and run records
- Align table formatting in REGISTRY.md, AGENT_HANDOFF, audit report, workflow doc
- Add spacing/readability improvements across all Phase A-D run records
- Consistent italic formatting and structural cleanup in PHASE-B execution plan
- No functional or code changes
* chore: change git push rule from deny to ask in opencode.jsonc
* chore: change git push rule from deny to ask in delivery agent config
* fix: address PR #17 review feedback — all 5 issues
- P0: update check-opencode-config.sh check 10 to assert git push* as "ask"
(split out from deny list; new check 10a verifies ask policy)
- P1: fix broken ADR link in repository-audit-workflow.md
(0008-opencode-config-consolidation → 0008-canonical-opencode-project-configuration)
- P2: clarify check-dependencies.sh header comment
(production audit blocks; dev audit is informational only)
- P2: remove dead pnpm-lock.yaml from context-pack allowlist
(excluded by Python filter as "huge, not useful for context")
* fix: address PR #17 re-review feedback — all 5 new issues
- P0: add output-path safety checks to generate-context-pack.sh
(blocks unsafe paths like ".", "/", empty, or non-hidden dirs)
- P1: remove hard-coded line numbers from audit template header
(prevents drift when repo-auditor.md changes)
- P1: extend check-agent-permissions.sh to validate edit: denies
(was only checking read:; now checks both read + edit)
- P1: add missing edit: secret-path denies to qa, reviewer,
repository-docs, and security agent configs
- P2: replace grep -oP with portable grep -oE in check-registry-counts.sh
(PCRE not available on BSD/macOS grep)
Summary
Bundled audit documentation, run records, and configuration improvements from the opencode system audit (2026-06-20).
Commits
586fdea0a31aba8728acce6449329e6f6011c6c5bfmain9999aa6565ae13cf1a8f4Files Changed
.opencode/REGISTRY.md— agent/command/skill registry with formatting polish.opencode/agents/delivery.md— git push deny → askAGENT_HANDOFF_OPENCODE_SYSTEM.md— audit handoff polishaudits/opencode-system-audit-2026-06-20.md— audit report polishdocs/workflows/repository-audit-workflow.md— workflow doc polishopencode.jsonc— git push deny → askplanning/PHASE-B-EXECUTION-PLAN.md— execution plan polishplanning/runs/AUD-OPENSYS-PHASE-A.mdthrough-D.md— run record formattingRisk
Low — documentation-only except for git-push permission changes (deny→ask), which adds a prompt rather than silent allow.
Review Focus
586fdea)