Skip to content

fix(pm): fail closed when the tree under test co-edits the generator the provenance exception trusts - #11283

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-11084-provenance-coedit-failclosed
Aug 23, 2026
Merged

fix(pm): fail closed when the tree under test co-edits the generator the provenance exception trusts#11283
os-zhuang merged 1 commit into
mainfrom
claude/issue-11084-provenance-coedit-failclosed

Conversation

@claude

@claudeclaudeBot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Fixes#11084

The #9866 provenance exception recomputes from the tree under test — it must, since the derivation has to reflect the PR's own docs. recomputeDocsAuditProvenance therefore executes the PR's own scripts/docs-audit/affected-docs.mjs and imports the PR's own check-audit-scope.mjsreplaceBlock. A diff that edits the generator and hand-edits .claude/workflows/docs-accuracy-audit.js together can in principle construct a splice that byte-equals its own hand edit: the tree certifies itself.

What changed

One conditional in --test, consulted before provenance: if the submitted path list contains any scripts/docs-audit/** path, the recompute is skipped entirely (no git, no generator exec) and the path stays governed with the reason stated.

  • TRUSTED_GENERATOR_PREFIX — the directory the recompute actually runs from.
  • generatorCoEditProvenance(paths) — pure, so --self-test pins both directions offline. Returns a fail-closed provenance verdict on a co-edit, or null when the generator is untouched. null is the only branch that goes on to recompute, and there is no branch that lifts anything, so no spelling it fails to recognise can open the fence.

This narrows the ruled exception and widens nothing: verdicts only ever move toward governed, and the pure-regeneration path with an untouched generator lifts exactly as before. The four ruled constraints, the mixed-diff rule, and every other governed-surface judgment are character-for-character unchanged.

Verification (all at 04371a39)

--self-test assertions: 119 before → 129 after, verdict line:

✓ check-governed-merges --self-test: 129 assertions (… the #11084 generator co-edit fence in both directions …)

Both directions, end-to-end against the real tree (not fixtures):

directioninvocationexitresult
co-edit--test .claude/workflows/docs-accuracy-audit.js scripts/docs-audit/affected-docs.mjs3GOVERNED — generated-surface exception (#9866) did NOT lift …: the tree under test modifies the generator this exception trusts — the path stays governed (co-edited here: scripts/docs-audit/affected-docs.mjs)
untouched generator--test .claude/workflows/docs-accuracy-audit.js content/docs/some-new-page.mdx0NOT governed — PURE REGENERATION — byte-equal to \node scripts/docs-audit/check-audit-scope.mjs --write` recomputed on THIS tree`

Reverse-verification — the fence neutered to return null unconditionally, run from the committed state, mutation confirmed on disk by anchor/inject grep counts (anchor=1 inject=0anchor=0 inject=1), restored by an EXIT INT TERM trap and re-confirmed green afterwards:

ABLATED_SELFTEST_EXIT=1
✗ check-governed-merges --self-test — 4 failure(s)
• a-generator-co-edit-answers-fail-closed-before-any-recompute: null
• the-co-edit-reason-states-the-ruled-words-and-names-the-co-edited-file: undefined
• the-co-edit-render-stays-GOVERNED-and-tells-the-seat-why-it-did-not-lift: …

Gates derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack on the actual change set (1 path), all green at 04371a39: check:cross-package-test-inputs, check:entry-guard, check:parse-guard, check:pm-governed-merges, check:pnpm-filter-targets, check-ci-filter-parity.mjs, check-cross-package-test-inputs.mjs.

No changeset: PM tooling only, nothing user-visible ships — skip-changeset.

This PR's own file list is not governed by the register (--test scripts/pm/check-governed-merges.mjs → 0 of 1 hit, exit 0). Left as draft; PM decides landing at ACCEPT.

Generated by Claude Code


Generated by Claude Code

…the provenance exception trusts
The #9866 exception's recompute necessarily runs the PR's own
scripts/docs-audit/** (the derivation must reflect the PR's docs), so a
diff editing the generator and hand-editing the workflow artifact
together could construct a splice that byte-equals its own hand edit.
In --test, before consulting provenance: any scripts/docs-audit/** path
in the submitted list skips the recompute and keeps the path governed
with the reason stated. Narrows the ruled exception only — a pure
regeneration with an untouched generator lifts exactly as before.
Fixes#11084
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 23, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review August 23, 2026 08:54
@os-zhuang
os-zhuang added this pull request to the merge queueAug 23, 2026
Merged via the queue into main with commit 91e97afAug 23, 2026
32 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-11084-provenance-coedit-failclosed branch August 23, 2026 09:13
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants

@os-zhuang@zhuangjianguo