Skip to content

feat(check): gate managed output content - #18

Merged
jdh313 merged 2 commits into
mainfrom
check-output-content-gates
Aug 29, 2026
Merged

feat(check): gate managed output content#18
jdh313 merged 2 commits into
mainfrom
check-output-content-gates

Conversation

@jdh313

@jdh313 jdh313 commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Ports the two content gates that jdh-agents currently runs outside the compiler (marketplace scan, marketplace lint) into agentforge check, so a consumer repo no longer needs its own Python tooling to know whether a compiled tree is publishable.

Both gates ride on the byte read checkManagedOutput already performs for the drift comparison, so copied passthrough resources are covered, not just generated documents — at no extra I/O. Nothing previously read those bytes for anything but equality.

Commits

  1. feat(check): gate managed output content on declared redactions — new unsafe-output-content issue. Flags absolute home directories (/Users/<name>/, /home/<name>/) and any literal string a marketplace declares under a new optional redactions: block.
  2. feat(check): report a managed .json output that does not parse — new invalid-output-document issue for a .json output that is not one of the native documents.

Design notes

  • Redactions are literal strings, not patterns. A declaration names a vocabulary; a regex invites an author to encode matching logic the compiler then has to defend against (backtracking, silent over-match). The one patterned class that generalizes across every repository — the home directory — is built in, where it is tested once. Follows the authoring-keys / documents precedent (ndr:4nshwv).
  • Carried on the plan, not passed alongside it. check derives every judgement from the compilation plan (ndr:tfee0d); a gate handed in as a separate optional argument is a gate a caller can forget — the same reasoning that keeps rootOutputs on the plan.
  • Gates on check, never on compile. Compilation stays total. A leak that reaches disk under --out has not been published; one that survives check is about to be.
  • Deliberately narrower than the linter it replaces. Empty-markdown, short-markdown, and the allowed-extension list did not port: none is a runtime failure on either harness, and turning one repository's house style into every consumer's build error is the overreach ndr:17dhph rejected for strict target schemas. Two tests pin that tolerance.
  • Not ported, and cannot be: the repo-wide sweep over every git-tracked file. agentforge only ever sees files a publication declares, so that stays a publishing repo's own pre-push hook.

Risk surface

Low. Both gates are additive to check and touch no compile or materialize path — output bytes are unchanged, and bun test snapshots are untouched (67 unchanged). The only breaking shape is CompilationPlan.redactions being required rather than optional, which is deliberate: the type surfaces every construction site rather than letting one silently skip the gate.

The realistic failure mode is a false positive failing a consumer's build. Mitigated by scoping the built-in detector to absolute home paths only — secret-shaped detection was deliberately left out, since it belongs to the repo-wide scan that stays put.

Testing

  • 167 pass / 0 fail, typecheck and biome clean.
  • 7 new tests, including two negatives (an undeclared sensitive-looking string passes; an empty markdown resource passes) and a binary-payload skip.
  • Verified against both real consumer corpora with zero false positives: jdh-agents 420 managed files, ndr 77 managed files, all ok.
  • Each commit verified green independently before the next was layered on.

Rollback

Revert either commit alone — they are independent gates sharing only the read site. Reverting both restores check exactly.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LxNdWk6ZUzq6uWFtd94yWD

jdh313 and others added 2 commits August 29, 2026 12:05
Scan every managed output for absolute home directories and for strings a
marketplace declares under `redactions:`. The scan rides on the byte read
`checkManagedOutput` already performs for the drift comparison, so copied
passthrough resources are covered at no extra I/O — until now nothing read
those bytes for anything but equality.

Redactions are literal strings rather than patterns: a declaration names a
vocabulary, and a regex invites an author to encode matching logic the
compiler then has to defend against. The one patterned class that
generalizes across every repository is built in.

A gate on `check`, never on `compile` (ndr:tfee0d): compilation stays total,
and whether a tree is publishable is a judgement about a finished tree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LxNdWk6ZUzq6uWFtd94yWD
Validate any `.json` output that is not one of the native documents — a hook
configuration, a package's own settings file, anything a publication ships
verbatim. Both harnesses parse these at load time, so a file that does not
parse is one the runtime rejects.

Narrower than the repo-local linter this replaces, which also failed an empty
markdown file and warned on a short one. Neither is a runtime failure on
either harness, and turning one repository's house style into every consumer's
build error is the overreach ndr:17dhph rejected for strict target schemas.
Two tests pin the tolerance.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LxNdWk6ZUzq6uWFtd94yWD
@jdh313
jdh313 merged commit ea00271 into main Aug 29, 2026
1 check passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.3.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@jdh313
jdh313 deleted the check-output-content-gates branch August 29, 2026 16:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant