fix: credit a workspace run only to the tool itself; mark non-exact reuse as needing review (Q01, Q02) - #170
Merged
Conversation
…euse as needing review
The 2026-09-27 recheck of v1.7.3 confirmed N01-N08 closed and found two
adjacent cases. Both are fixed conservatively: what cannot be established
runs the members on their own, or is served as a candidate to review.
Q02 (P1), workspace coverage: `./tools/npm test --workspaces` was credited
as npm's recursive run because recognition read only the file's basename,
so a stub that exited 0 hid a failing workspace behind a PASS.
- a tool is recognized by its bare name or its node_modules/.bin install;
any other path is an unknown program, and the refusal is reported
- variables on the command line are allowlisted (PATH, LD_PRELOAD, HOME
and a NODE_OPTIONS preload are refused); npx -p and env -i/-C refused
- shadows are refused: a package manager or system program in any
node_modules/.bin on the script PATH, another package's binary (or a
link out of the package) under a tool's name, a same-named Windows
executable in the root, a yarnPath outside .yarn/releases, and a
packageManager fetched from a URL
- node-options must be inert, a script-shell inside the project is not a
shell, and nx plugins run the members on their own
- a verify.workspaces "root" declaration stays labelled declared
Q01 (P2), near reuse: "Deny admins and allow guests..." near-hit an
artifact verified for "Allow admins and deny guests..." (MinHash 0.83) and
was called a "reworded match".
- every hit carries semanticEquivalence ("identical" only for exact,
"unverified" otherwise) and requiresReview (true unless exact), in
`forge reuse query --json` and the gate's reuse summary
- the semantic guard's new `binding` kind holds opposite bindings
(allow->admins vs deny->admins, from/to swaps) and same-word
rearrangements at adapt; consolidation lists such pairs as conflicts
- the CLI, the gate and the docs no longer call a near hit reworded
The claims check no longer fails in a checkout that lacks newer release
tags: such a claim is reported unchecked (fetch the tags), not failed.
Docs (GUIDE, Mintlify, the reuse plan), CHANGELOG and the rendered
changelog page are updated in the same change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GVVG2VDETWsDxMu6MBWPz2
The 2026-09-27 recheck of 1.7.3 (6d98121) independently confirmed the N01-N08 fixtures closed, and found Q01 and Q02, fixed in cf89040. - verify-pass-binding: re-assessed on cf89040 with Q02 as a regression test; the scope now says forge trusts installed tools only past the identity and shadow checks - similar-rules-never-merged: re-assessed on cf89040, since the guard's binding kind now lists the N02 pair as a conflict rather than a proposal - reuse-review-contract (new): non-exact hits carry semanticEquivalence "unverified" and requiresReview; known relational reversals are held at adapt (Q01) - route-outcome-provenance, phase-p3-reuse-cache, reuse-exact-identity, phase-p4-context-assembly, context-completeness: the recheck's confirmation recorded; their assessment is unchanged Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GVVG2VDETWsDxMu6MBWPz2
Creating a symlink needs elevation on Windows; the repo's other symlink tests skip there for the same reason. The check moves into its own test with the same skip, so a non-elevated Windows checkout runs the rest of the Q02 shadow tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GVVG2VDETWsDxMu6MBWPz2
CodeWithJuber
marked this pull request as ready for review
September 27, 2026 05:17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
The 2026-09-27 recheck of v1.7.3 (
6d98121) confirmed that all eight N01–N08 reproduction cases are closed. It reported two adjacent findings, and this PR fixes both. It also records the recheck's confirmation in the claims registry. All three of the review package's scripts pass with--assert-fixedon this branch:reproduce_remaining.mjs: N01–N08 stay closed.original-reproduce.mjs: F01–F16 stay closed.edge-probes.mjs: Q01 and Q02 no longer reproduce.Q02 (P1): a local program named like a package manager covered the workspaces.
testscript of./tools/npm test --workspaceswas credited as npm's recursive run, because recognition read only the file's basename. The fixture's stub exits 0, sopackages/badnever ran andforge verifysaid PASS.node_modules/.bin. Any other path (./tools/npm,./scripts/pnpm.js,/usr/bin/env) is an unknown program. The review's fixture now runs the member and reports FAIL, with every basismeasured.forge verifyprints the root run as "not credited" and names the program.PATH,LD_PRELOAD,HOMEand aNODE_OPTIONSpreload are refused.npx -p/--package,env -iandenv -C/--chdirare refused.node_modules/.binentry on the script's PATH (the package's own, then each parent directory's) must be the tool's own package's binary, and a symlink must resolve into that package;npm.cmd) counts too, because cmd.exe runs it first.yarnPathoutside.yarn/releases/, or apackageManagerfetched from a URL, is refused.node-optionsmust be inert, ascript-shellthat is a project file is not a shell, and nx plugins (which can definetest) run the members on their own.npm test --workspaces,turbo run test --force,./node_modules/.bin/turbo,yarn turbo,CI=1 …), andverify.workspaces: "root"stays labelled declared.Q01 (P2): opposite requirements were labelled a near "reworded match".
semanticEquivalenceis"identical"only for exact and"unverified"for near and adapt, andrequiresReviewistruefor every non-exact hit. Both fields are inforge reuse query --jsonand the gate's reuse summary. The CLI, gate and docs no longer call a near hit reworded.bindingkind. Each polarity, negation or direction word binds the next content word of its clause. A word bound to opposite relations, or the same words in another order, is a conflict. Permission-subject, source/destination,into, negation-scope, quoted-literal and possessive role swaps are held atadapt, with the conflict named. Consolidation lists such pairs as conflicts rather than proposals.adapt. Both tiers require review now, so the cost is a note, never a refusal.Claims check without release tags. The reviewer's first full run failed once because the clone lacked the newer release tags. Now a claim naming a release newer than every local tag, but not newer than
package.json's version, is reported unchecked with agit fetch --tagshint instead of failing. I reproduced the reviewer's condition (a clone with only v1.4.0 and v1.4.3) and verified the fix there.Claims (second commit):
verify-pass-bindingandsimilar-rules-never-mergedare re-assessed oncf89040.reuse-review-contract, links Q01.Docs are updated in the same change: GUIDE, the Mintlify verify, reuse and memory pages, the reuse-cache plan, and CHANGELOG with the rendered changelog page.
Checklist
npm testpasses: 1,778 tests, 1,774 pass, 0 fail, 4 platform-gated skips (Node 22)npm run checkpasses (Biome lint + format; the same 14 pre-existing warnings as master)compareVersions, thebinsfield ofrecursiveTestInvocation, the review contract fields, and the guard'sbindingkindCHANGELOG.mdupdated under## [Unreleased]forge verify/forge reusechanged, and their docs changed with themRisk & rollback
.yarn/releases/, or an nx workspace with plugins;adaptnote, never as a false PASS.semanticEquivalenceandrequiresReviewon reuse hits, andbinsonrecursiveTestInvocation's result. No existing field changed.Extra checks (tick if applicable)
npm run typecheckpasses🤖 Generated with Claude Code
https://claude.ai/code/session_01GVVG2VDETWsDxMu6MBWPz2
Generated by Claude Code