Skip to content

feat(workflows): add archon-doc-agent bundled workflow#1287

Open
seanrobertwright wants to merge 3 commits intocoleam00:devfrom
seanrobertwright:feat/archon-doc-agent
Open

feat(workflows): add archon-doc-agent bundled workflow#1287
seanrobertwright wants to merge 3 commits intocoleam00:devfrom
seanrobertwright:feat/archon-doc-agent

Conversation

@seanrobertwright
Copy link
Copy Markdown

@seanrobertwright seanrobertwright commented Apr 18, 2026

Summary

  • Problem: Comment/doc rot and undocumented exported symbols accumulate silently between releases; fixing them by hand is the "boring stuff" that gets deferred.
  • Why it matters: Bad docs compound — every new contributor pays the cost, and stale comments actively mislead during debugging.
  • What changed: Adds a new bundled workflow archon-doc-agent that scopes files (git diff / any ref / full repo), runs a heuristic scan, classifies findings via Claude, edits source to add missing doc comments and fix stale ones, scaffolds Markdown docs under /docs, and writes a run report with uncertain items flagged for human review.
  • What did NOT change (scope boundary): No code changes. No schema changes. No new CLI flags, routes, or providers. Pure data-file addition in .archon/workflows/defaults/.

Updates since first review

Two follow-up commits address review findings on the original PR. See this comment for the full disposition (including one finding declined with evidence).

  • eb1af823fix(workflows): harden archon-doc-agent scope node against shell injection. The scope bash node originally interpolated $ARGUMENTS directly with ARG="$ARGUMENTS". Archon's substituteWorkflowVariables (dag-executor.ts:290) does plain regex replacement with no shell escaping; only $nodeId.output is auto-quoted. Crafted input containing an unescaped double quote followed by shell metacharacters could break out of the ARG= assignment and execute arbitrary commands — a real concern when $ARGUMENTS flows from a platform adapter (Slack/Telegram/GitHub comment). Capture now uses a single-quoted heredoc so the substituted value is treated as literal text. Verified with a live injection test: payload "; echo INJECTED; echo " survives as literal and no command runs.
  • f8b02becfix(workflows): honor $DOCS_DIR config in archon-doc-agent. The generate_docs and report node prompts hardcoded docs/ paths. $DOCS_DIR is a first-class Archon variable (substituted in dag-executor.ts via resolvedDocsDir), configurable via docs.path in .archon/config.yaml. Hardcoding docs/ broke users who had chosen a different documentation directory. Replaced literal docs/ with $DOCS_DIR across scaffolding, git diff --stat invocation, and the review instructions. README.md / CHANGELOG.md references at the repo root are unchanged — those are not configured via docs.path.

archon validate workflows archon-doc-agent passes after both commits.

UX Journey

Before

User                             Archon                           AI
────                             ──────                           ──
(manually hunt for stale
 comments + missing docs)

  grep TODOs ────────────▶
  read files by hand
  write doc comments
  update /docs by hand

(no feedback loop, easy to miss)

After

User                             Archon                           AI (Claude)
────                             ──────                           ───────────
archon workflow run ─────────▶   scope files (bash)
archon-doc-agent HEAD~N          heuristic_scan (bash) ──────────▶ [audit]
                                                                    classify findings
                                 findings.json ◀───────────────────
                                 [fix_source] ────────────────────▶ edit source in scope
                                 [generate_docs] ─────────────────▶ scaffold/update /docs
                                 [report] ────────────────────────▶ write $ARTIFACTS_DIR/report.md
review git diff ◀───────────────                                    (skips uncertain items)
commit / revert

User-facing addition: archon workflow run archon-doc-agent [ref|all].

Architecture Diagram

Before

workflow discovery ──▶ .archon/workflows/defaults/*.yaml ──▶ executor ──▶ provider (claude/codex)
                                   (20 bundled workflows)

After

workflow discovery ──▶ .archon/workflows/defaults/*.yaml ──▶ executor ──▶ provider (claude/codex)
                                   (21 bundled workflows) [+archon-doc-agent]

No new modules, no new module-to-module edges.

Connection inventory:

From To Status Notes
workflow-discovery .archon/workflows/defaults/archon-doc-agent.yaml new Discovered like any other bundled default
All other edges unchanged

Label Snapshot

  • Risk: risk: low
  • Size: size: S
  • Scope: workflows
  • Module: workflows:defaults

Change Metadata

  • Change type: feature
  • Primary scope: workflows

Linked Issue

  • Closes #
  • Related #
  • Depends on #
  • Supersedes #

(No linked issue — new workflow contribution.)

Validation Evidence (required)

# Workflow-schema validation (the only validator that applies to YAML data files):
bun run cli validate workflows archon-doc-agent
# Result: archon-doc-agent                         ok
#         Results: 1 valid, 0 with errors

# Smoke test in an isolated worktree:
bun run cli workflow run archon-doc-agent --branch docs/audit-smoke-test "HEAD~5"
# Total runtime: ~10 minutes
# Result: 6/6 nodes completed, exit 0
#   scope            214ms
#   heuristic_scan   2.5s
#   audit            6m14s   (classified 12 findings across 17 in-scope files)
#   fix_source       1m26s   (7 fixes applied, 5 uncertain findings skipped)
#   generate_docs    1m49s   (scaffolded docs/{index,architecture,api}.md — 470 lines)
#   report           43.9s   (wrote $ARTIFACTS_DIR/report.md)
  • Evidence provided: smoke-run confirmed scope was honored (only in-scope files edited), uncertain findings correctly skipped rather than auto-fixed, report structure matches spec, docs scaffolding is idempotent on subsequent runs.
  • bun run validate intentionally skipped: this PR adds a single YAML data file under .archon/workflows/defaults/. No TypeScript, no imports, no tests reference it. Type-check / lint / format / unit tests have no code paths to exercise. The workflow-schema validator above is the applicable check.

Security Impact (required)

  • New permissions/capabilities? No — inherits default Claude SDK tool set; the audit node uses denied_tools: [Write, Edit] to enforce read-only analysis.
  • New external network calls? No — Claude API calls only, same as every other bundled workflow.
  • Secrets/tokens handling changed? No.
  • File system access scope changed? No — reads repo files, writes to docs/ and (when fixes are applied) to source files in the execution directory. Same access profile as archon-architect and archon-refactor-safely.

Compatibility / Migration

  • Backward compatible? Yes — additive only.
  • Config/env changes? No.
  • Database migration needed? No.

Human Verification (required)

What was personally validated beyond CI:

  • Verified scenarios:
    • Smoke-tested with archon workflow run archon-doc-agent --branch docs/audit-smoke-test "HEAD~5" against coleam00/Archon itself.
    • Scope honored: all edited files were in scope.txt; no out-of-scope edits.
    • Legitimate stale-comment catch: rewrote an outdated class doc in packages/providers/src/community/pi/provider.ts that falsely claimed "v1 capabilities are all false" — updated to accurately list supported/unsupported caps.
    • Legitimate doc-add: added a JSDoc to startServer documenting its process.exit(1) side effect on fatal init failure.
    • Uncertain findings skipped (not auto-fixed): e.g., ClaudeProviderDefaults missing interface-level JSDoc while all fields are individually documented — correctly flagged rather than edited.
    • Report writes to $ARTIFACTS_DIR/report.md with the sections documented in the workflow (Summary, Source edits, Docs changes, Flagged for human review, How to review).
  • Edge cases checked: empty scope (scope node early-exits with count=0); unknown git ref (scope node errors cleanly); all mode uses git ls-files; filter strips node_modules/dist/build/__pycache__/etc.
  • What was not verified: all-mode scan against this full repo (bounded smoke only); non-TS/Python/Go/Rust language coverage (heuristic export-scan currently handles JS/TS/Py/Go/Rust — other languages fall back to AI-only audit).

Side Effects / Blast Radius (required)

  • Affected subsystems/workflows: Makes the archon-doc-agent workflow discoverable to all Archon users after next release. Does not change behavior of any existing workflow.
  • Potential unintended effects: When a user runs the workflow, the AI can edit source files in the execution directory — same as other action-taking bundled workflows (archon-architect, archon-refactor-safely). The workflow defaults to worktree isolation via --branch; fix_source does not commit, so changes are always reviewable via git diff before acceptance.
  • Guardrails/monitoring for early detection: audit node is read-only via denied_tools: [Write, Edit]; fix_source is instructed to respect the scope file and skip uncertain findings; report surfaces skipped items.

Rollback Plan (required)

  • Fast rollback command/path: git revert <merge-sha> or delete the file .archon/workflows/defaults/archon-doc-agent.yaml. No state, no migration, no cache to clear.
  • Feature flags or config toggles: A user can opt out of bundled workflows entirely via defaults.loadDefaultWorkflows: false in .archon/config.yaml.
  • Observable failure symptoms: archon workflow list would stop showing archon-doc-agent.

Risks and Mitigations

  • Risk: AI may hallucinate documentation content when generating /docs/*.md on first run.
    • Mitigation: The generate_docs node instructs the AI to only claim what it can verify in code and to write TODO: describe X stubs for anything it is uncertain about, which the report surfaces for human review.
  • Risk: AI may apply an incorrect "fix" to a comment it misjudged as stale.
    • Mitigation: fix_source is instructed to skip any finding marked uncertain: true; all edits land in the worktree diff for human review before commit; no auto-commit.
  • Risk: Scope drift — AI edits a file outside the declared scope.
    • Mitigation: Scope list written to $ARTIFACTS_DIR/scope.txt; fix_source instruction forbids editing files outside it. Smoke test confirmed no scope drift on the verification run.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Added an automated documentation workflow that scans the repository for missing or stale documentation and comment markers, performs scoped doc/comment-only edits, generates or updates idempotent Markdown docs under docs/, and produces a human-readable audit report listing findings, applied changes, and items flagged for human review. Runs in diff, ref, or full-repo modes and records per-item actions while skipping uncertain or out-of-scope edits.

Adds a documentation-audit workflow that scopes files (diff vs
$BASE_BRANCH, any git ref, or full repo), runs a heuristic scan for
TODO/FIXME markers and export-surface candidates, classifies findings
via Claude, edits source files to add missing doc comments and fix
stale ones, scaffolds Markdown docs under /docs, and writes a run
report with items flagged for human review.

Designed to be safe-by-default: uncertain findings are skipped rather
than auto-fixed, scope is honored per fix-source rules, and docs
changes are left in the worktree diff for human review before commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 18, 2026 14:45
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 18, 2026

📝 Walkthrough

Walkthrough

Adds a new Archon workflow .archon/workflows/defaults/archon-doc-agent.yaml implementing a staged docs-audit pipeline: compute scope, run heuristic scans, perform an AI-only audit, apply AI doc-only source edits, generate/update idempotent Markdown docs under docs/, and emit an artifacts report.

Changes

Cohort / File(s) Summary
Documentation Audit Workflow
.archon/workflows/defaults/archon-doc-agent.yaml
New workflow (~351 added lines) defining scope computation (diff/ref/all), heuristic scans (todos.txt, exports.txt), an AI-only audit producing $ARTIFACTS_DIR/findings.json, AI doc-only fix_source step that edits only comments/docs (with guardrails), idempotent docs generation under $DOCS_DIR, and a final report.md. Invocation modes and step-level safety constraints are specified (no commits during audit, edits restricted to scope, no new files during fixes).

Sequence Diagram(s)

sequenceDiagram
    participant User as User / Trigger
    participant Runner as CI Workflow Runner
    participant Git as Git Repository
    participant Heuristic as Heuristic Scanner
    participant AI as AI Audit Agent
    participant Artifacts as Artifacts (artifacts/*)
    participant Docs as Docs (docs/)

    User->>Runner: invoke workflow (diff | ref | all)
    Runner->>Git: compute scope (diff or full)
    Git-->>Runner: artifacts/scope.txt
    Runner->>Heuristic: scan scoped files
    Heuristic-->>Artifacts: todos.txt, exports.txt
    Runner->>AI: run AI-only audit (reads scope + heuristics)
    AI-->>Artifacts: findings.json
    Runner->>AI: doc-only fix step (reads findings, scope)
    AI-->>Artifacts: fix-source-log.md (applied/skipped)
    Runner->>Docs: generate/update docs/*.md (idempotent)
    Docs-->>Artifacts: updated docs files
    Runner->>Git: run git diff --stat and aggregate
    Runner-->>Artifacts: report.md
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐇 I hop through changed lines with a nose for stray notes,

I gather TODOs and exports in tiny paper boats.
AI hums advice, I nudge comments to shine,
Docs grow like clover in neat, labeled lines. 🌿📖

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: a new bundled workflow named archon-doc-agent is being added to the workflows system.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The pull request description is comprehensive and closely follows the template structure, covering all required sections including summary, UX journey, architecture, validation evidence, security impact, compatibility, human verification, side effects, rollback plan, and risks/mitigations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.archon/workflows/defaults/archon-doc-agent.yaml:
- Around line 257-293: Update the workflow to use the executor-provided
$DOCS_DIR variable instead of the hardcoded "docs/" path wherever the steps
reference creating, checking, or reporting files (notably the step "Check
whether `docs/` exists" and the list of files `docs/index.md`,
`docs/architecture.md`, `docs/api.md` and subsequent reporting lines around the
block that appears also at 316-340); change all literal "docs/" occurrences to
"$DOCS_DIR/" (or use "${DOCS_DIR}" where needed) and update the output/reporting
text that prints "docs/" to reference $DOCS_DIR so file creation, existence
checks, and git diff use the configured docs directory.
- Around line 132-177: The audit node (id: audit) currently includes Write in
denied_tools which prevents creation of $ARTIFACTS_DIR/findings.json needed by
downstream nodes (fix_source, generate_docs, report); remove Write from the
denied_tools array for the audit node so the agent can write the findings file,
or alternatively replace the broad denied_tools restriction with a path-scoped
policy that only disallows edits to source files while allowing writes to
$ARTIFACTS_DIR/* (ensure the audit node prompt still forbids modifying source
files verbally).
- Around line 24-35: Replace the unsafe raw interpolation ARG="$ARGUMENTS" in
the scope node with a safe here-document capture using a single-quoted delimiter
so the substituted $ARGUMENTS is treated as literal text and cannot inject shell
syntax; update the assignment that sets ARG (the ARG variable inside the scope
node) to read from a single-quoted heredoc (e.g., using a <<'DELIM' / DELIM
pattern) so the executor's substitution becomes the heredoc body rather than
executable shell code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7f715d74-ce70-41f6-a38a-3e91bf257f49

📥 Commits

Reviewing files that changed from the base of the PR and between d89bc76 and 4134ac4.

📒 Files selected for processing (1)
  • .archon/workflows/defaults/archon-doc-agent.yaml

Comment thread .archon/workflows/defaults/archon-doc-agent.yaml
Comment on lines +132 to +177
- id: audit
depends_on: [heuristic_scan]
context: fresh
denied_tools: [Write, Edit]
prompt: |
You are a documentation auditor. Your job is to classify documentation
problems and write a structured findings report. You MUST NOT modify
source files in this step — analysis only.

## Inputs

Scope summary: $scope.output
Heuristic scan summary: $heuristic_scan.output

Full inputs on disk:
- $ARTIFACTS_DIR/scope.txt — list of files in audit scope
- $ARTIFACTS_DIR/todos.txt — TODO/FIXME/XXX/HACK markers
- $ARTIFACTS_DIR/exports.txt — candidate exported symbols per file

## Method

1. Read `$ARTIFACTS_DIR/scope.txt`. If empty, write an empty findings file
(see Output) and stop.
2. For each file in scope (cap at ~25 files for a single pass — prioritize
files with the most heuristic hits):
a. Read the file.
b. Identify **undocumented exports**: public/exported symbols that lack
an adjacent doc comment in the language's native style (JSDoc for
JS/TS, docstring for Python, doc comment for Go, `///` for Rust,
etc.). Ignore trivial re-exports and type aliases that are self-
documenting (e.g., `export type UserId = string`).
c. Identify **stale comments**: comments whose content contradicts or
no longer matches the adjacent code. Classify each as:
- `stale` : comment describes behavior the code no longer has
- `outdated_example` : example in a comment references removed/renamed API
- `contradictory` : comment asserts something the code contradicts
- `orphan_ref` : comment references a symbol that isn't in the file
- `todo` : a TODO/FIXME worth surfacing (don't auto-fix)
d. When uncertain, mark the finding with `"uncertain": true` and
explain briefly — the human will review these.
3. Do NOT flag internal (non-exported) helpers for missing docs.
4. Do NOT invent fixes for things you haven't verified.

## Output

Write a single JSON file to `$ARTIFACTS_DIR/findings.json` with this shape:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check for workflow nodes that deny Write while instructing the agent to write artifact files.
rg -n -C6 'denied_tools:\s*\[[^]]*Write|Write.*denied_tools|findings\.json|ARTIFACTS_DIR/.+\.json' --glob '*.yaml' --glob '*.yml' .archon

Repository: coleam00/Archon

Length of output: 28942


Remove Write from denied_tools in the audit node.

The audit node denies Write but explicitly instructs the agent to write $ARTIFACTS_DIR/findings.json. This prevents artifact creation while downstream nodes (fix_source, generate_docs, report) depend on the findings file. Allowing Write is necessary for the workflow to function; if you need to restrict edits to source files only, use path-scoped tool policies instead.

🛠️ Proposed fix
  - id: audit
    depends_on: [heuristic_scan]
    context: fresh
-   denied_tools: [Write, Edit]
+   denied_tools: [Edit]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- id: audit
depends_on: [heuristic_scan]
context: fresh
denied_tools: [Write, Edit]
prompt: |
You are a documentation auditor. Your job is to classify documentation
problems and write a structured findings report. You MUST NOT modify
source files in this step — analysis only.
## Inputs
Scope summary: $scope.output
Heuristic scan summary: $heuristic_scan.output
Full inputs on disk:
- $ARTIFACTS_DIR/scope.txt — list of files in audit scope
- $ARTIFACTS_DIR/todos.txt — TODO/FIXME/XXX/HACK markers
- $ARTIFACTS_DIR/exports.txt — candidate exported symbols per file
## Method
1. Read `$ARTIFACTS_DIR/scope.txt`. If empty, write an empty findings file
(see Output) and stop.
2. For each file in scope (cap at ~25 files for a single pass — prioritize
files with the most heuristic hits):
a. Read the file.
b. Identify **undocumented exports**: public/exported symbols that lack
an adjacent doc comment in the language's native style (JSDoc for
JS/TS, docstring for Python, doc comment for Go, `///` for Rust,
etc.). Ignore trivial re-exports and type aliases that are self-
documenting (e.g., `export type UserId = string`).
c. Identify **stale comments**: comments whose content contradicts or
no longer matches the adjacent code. Classify each as:
- `stale` : comment describes behavior the code no longer has
- `outdated_example` : example in a comment references removed/renamed API
- `contradictory` : comment asserts something the code contradicts
- `orphan_ref` : comment references a symbol that isn't in the file
- `todo` : a TODO/FIXME worth surfacing (don't auto-fix)
d. When uncertain, mark the finding with `"uncertain": true` and
explain briefly — the human will review these.
3. Do NOT flag internal (non-exported) helpers for missing docs.
4. Do NOT invent fixes for things you haven't verified.
## Output
Write a single JSON file to `$ARTIFACTS_DIR/findings.json` with this shape:
- id: audit
depends_on: [heuristic_scan]
context: fresh
denied_tools: [Edit]
prompt: |
You are a documentation auditor. Your job is to classify documentation
problems and write a structured findings report. You MUST NOT modify
source files in this step — analysis only.
## Inputs
Scope summary: $scope.output
Heuristic scan summary: $heuristic_scan.output
Full inputs on disk:
- $ARTIFACTS_DIR/scope.txt — list of files in audit scope
- $ARTIFACTS_DIR/todos.txt — TODO/FIXME/XXX/HACK markers
- $ARTIFACTS_DIR/exports.txt — candidate exported symbols per file
## Method
1. Read `$ARTIFACTS_DIR/scope.txt`. If empty, write an empty findings file
(see Output) and stop.
2. For each file in scope (cap at ~25 files for a single pass — prioritize
files with the most heuristic hits):
a. Read the file.
b. Identify **undocumented exports**: public/exported symbols that lack
an adjacent doc comment in the language's native style (JSDoc for
JS/TS, docstring for Python, doc comment for Go, `///` for Rust,
etc.). Ignore trivial re-exports and type aliases that are self-
documenting (e.g., `export type UserId = string`).
c. Identify **stale comments**: comments whose content contradicts or
no longer matches the adjacent code. Classify each as:
- `stale` : comment describes behavior the code no longer has
- `outdated_example` : example in a comment references removed/renamed API
- `contradictory` : comment asserts something the code contradicts
- `orphan_ref` : comment references a symbol that isn't in the file
- `todo` : a TODO/FIXME worth surfacing (don't auto-fix)
d. When uncertain, mark the finding with `"uncertain": true` and
explain briefly — the human will review these.
3. Do NOT flag internal (non-exported) helpers for missing docs.
4. Do NOT invent fixes for things you haven't verified.
## Output
Write a single JSON file to `$ARTIFACTS_DIR/findings.json` with this shape:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.archon/workflows/defaults/archon-doc-agent.yaml around lines 132 - 177, The
audit node (id: audit) currently includes Write in denied_tools which prevents
creation of $ARTIFACTS_DIR/findings.json needed by downstream nodes (fix_source,
generate_docs, report); remove Write from the denied_tools array for the audit
node so the agent can write the findings file, or alternatively replace the
broad denied_tools restriction with a path-scoped policy that only disallows
edits to source files while allowing writes to $ARTIFACTS_DIR/* (ensure the
audit node prompt still forbids modifying source files verbally).

Comment thread .archon/workflows/defaults/archon-doc-agent.yaml Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new bundled default workflow (archon-doc-agent) intended to audit stale comments and undocumented exported symbols, apply in-scope doc fixes, scaffold/update /docs, and emit a run report for human review.

Changes:

  • Introduces a new bundled workflow YAML with a 6-node DAG (scope → heuristic scan → AI audit → source doc fixes → docs generation → reporting).
  • Adds scope selection modes (diff vs $BASE_BRANCH, arbitrary ref, or full repo via all) and writes intermediate artifacts (scope.txt, todos.txt, exports.txt, findings.json, logs, report).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +132 to +140
- id: audit
depends_on: [heuristic_scan]
context: fresh
denied_tools: [Write, Edit]
prompt: |
You are a documentation auditor. Your job is to classify documentation
problems and write a structured findings report. You MUST NOT modify
source files in this step — analysis only.

Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The audit node is configured with denied_tools: [Write, Edit], but the prompt requires writing $ARTIFACTS_DIR/findings.json. With Write denied, the agent can’t reliably create that file (and downstream fix_source depends on it). Also, this setup does not actually enforce read-only analysis because Bash remains available and can still modify the repo. Consider switching to a restrictive allowlist like allowed_tools: [Read, Write] (and explicitly disallow Edit/Bash), and clarify that the only permitted write is to $ARTIFACTS_DIR/findings.json.

Copilot uses AI. Check for mistakes.
seanrobertwright and others added 2 commits April 18, 2026 10:54
…ction

The scope bash node interpolated $ARGUMENTS directly with ARG="$ARGUMENTS".
Archon's substituteWorkflowVariables (dag-executor.ts:290) replaces $ARGUMENTS
via plain regex replacement with no shell escaping — only $nodeId.output is
auto-quoted via shellQuote. Crafted user input containing an unescaped double
quote followed by shell metacharacters could break out of the ARG= assignment
and execute arbitrary commands. This is a real concern when $ARGUMENTS flows
from a platform adapter (Slack/Telegram/GitHub comment) rather than the CLI.

Capture $ARGUMENTS via a single-quoted heredoc so the substituted value is
treated as literal text. Verified with an injection payload that the literal
string is preserved and no shell command runs.

Addresses PR review feedback on coleam00#1287.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The generate_docs and report node prompts hardcoded `docs/` paths.
$DOCS_DIR is a first-class Archon variable (substituted in dag-executor.ts
via resolvedDocsDir) configured via `docs.path` in .archon/config.yaml;
hardcoding `docs/` broke users who'd chosen a different documentation
directory.

Replaced literal `docs/` with `$DOCS_DIR` in generate_docs scaffolding,
report `git diff --stat` invocation, and the review instructions.
README.md / CHANGELOG.md references at repo root are unchanged — those
are not configured via docs.path.

Addresses PR review feedback on coleam00#1287.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@seanrobertwright
Copy link
Copy Markdown
Author

Review responses — addressed in commits eb1af823 and f8b02bec.

✅ Finding 1 ($DOCS_DIR) — valid, fixed in f8b02bec

Confirmed $DOCS_DIR is a first-class Archon variable substituted by substituteWorkflowVariables at packages/workflows/src/dag-executor.ts:293 (via resolvedDocsDir), and documented in CLAUDE.md as configurable via docs.path in .archon/config.yaml. Hardcoding docs/ would have broken users who'd chosen a different docs directory.

Replaced literal docs/ with $DOCS_DIR in:

  • generate_docs prompt — scaffolding paths ($DOCS_DIR/index.md, etc.) and the final reply instruction
  • report prompt — the git diff --stat -- $DOCS_DIR invocation and the "How to review" instructions
  • Description header — updated to note $DOCS_DIR defaults to docs/

Left unchanged: README.md / CHANGELOG.md references at repo root, which are not configured via docs.path.

✅ Finding 3 (heredoc) — valid, fixed in eb1af823 (earlier commit)

Verified the injection risk by reading the substitution logic: substituteWorkflowVariables at dag-executor.ts:287-295 does plain regex replacement for workflow variables (including $ARGUMENTS) with no shell escaping, while only $nodeId.output references get shellQuote-ed via the escapedForBash=true path in substituteNodeOutputRefs. So ARG="$ARGUMENTS" was a real command-injection vector when $ARGUMENTS flows from a platform adapter (Slack/Telegram/GitHub comment).

Applied the single-quoted heredoc pattern and validated with a live injection test: payload "; echo INJECTED; echo " is preserved as literal text and no command runs.

❌ Finding 2 (denied_tools: [Write, Edit] prevents creation of findings.json) — respectfully declining; empirically refuted

The smoke-test run (workflow ID 2dccb79ad38944fd9d48398730fe88e8) completed successfully with this exact config, and the audit node did produce findings.json:

$ ls ~/.archon/workspaces/coleam00/Archon/artifacts/runs/2dccb79ad38944fd9d48398730fe88e8/
_diff.txt        exports.txt      findings.json    fix-source-log.md
report.md        scope.txt        todos.txt

$ head findings.json
{
  "mode": "ref",
  "files_audited": 17,
  "findings": [
    { "file": "packages/providers/src/community/pi/provider.ts", "line": 73,
      "kind": "contradictory", "severity": "high", "symbol": "PiProvider", ... },
    ...

17 files audited, 12 findings classified across 4 kinds. The downstream fix_source, generate_docs, and report nodes consumed the file without issue.

Why it works: denied_tools: [Write, Edit] denies those named SDK tools specifically. The AI writes findings.json via the still-allowed Bash tool (heredoc/redirection). The reviewer's suggested alternative — a path-scoped policy allowing writes to $ARTIFACTS_DIR/* while blocking source edits — isn't supported by Archon's tool-restriction model (allowed_tools/denied_tools are name-based, not path-based). The current config is the correct trade-off for a read-only analysis node that must still emit one artifact file:

  • Write/Edit denied → prevents the audit node from mutating source files (defense-in-depth alongside the prompt instruction "You MUST NOT modify source files in this step")
  • Bash allowed → lets the AI emit the findings artifact via redirection
  • Prompt-level instruction reinforces the boundary verbally

Removing Write from denied_tools would reduce the safety margin without fixing a real problem. Happy to revisit if there's a mechanism I've missed.

@Wirasm
Copy link
Copy Markdown
Collaborator

Wirasm commented Apr 19, 2026

hey @seanrobertwright could you please explain the difference between this and the "docs-impact-agent"?

i see no reason to have two agents for this use case, unless there is a clear gap?

@seanrobertwright
Copy link
Copy Markdown
Author

Rasmus, I will confirm when I get home, but my installation did not show such a workflow. I will followup on this.

@seanrobertwright
Copy link
Copy Markdown
Author

hey @seanrobertwright could you please explain the difference between this and the "docs-impact-agent"?

i see no reason to have two agents for this use case, unless there is a clear gap?

Rasmus, after discussion in the hangout today - the "docs-impact-agent" is not a workflow, but it was explained that it is used to develop Archon. My proposal was to have a document generation / updater for ANY project / repo the user is working on.

Unless, that agent can be invoked directly? I might need more clarification on this.

@Wirasm
Copy link
Copy Markdown
Collaborator

Wirasm commented Apr 20, 2026

the doc impact agent is a generic doc generation command that can be inserted at any node as a generic doc updater for any project

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants