Repository navigation
fix(pm): the contract review's item ④ rides the narrowing face too - #26695
Conversation
The maintainer ruled (record 6442046166, letter A) that a PR narrowing a published accept set in runtime code alone owes the same design judgment the schema and rules faces owe: read against the spec on main, does the narrowing take a declared capability away at the consumer, or make the spec's own refusal real. `REVIEW_FACES.narrowing` gains `fullReview: true`, the record prints the fourth section on that face, the template notes and the reviewer brief name the narrowing's scenario in its own shape (no `hits`, the whole-diff floor), and contract-review.md names three faces on the lines that named two. Three self-test pins flip, two are added (template battery 28 to 29, brief 17 to 18); the declaration face keeps no ④. Claude-Session: https://claude.ai/code/session_01ADHkmRLPe6T3Z5Fy17DijY Co-authored-by: Claude <noreply@anthropic.com>
席位核对ACCEPT ·
|
Contract reviewServed-tier: Director seat (summon #52, ledger objectstack#12708), summoned by the ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
Implemented-by: VERDICT: PASS Generated by Claude Code |
Requested by Steve · project thread
Fixes #26527
Clause-②: no
Metadata-protocol: none
维护者速读
Clause-②: no (narrowing)),模板、简报与规则文本同步改成三面;申报面照旧无 ④。main上的 spec 问「这次收窄是在消费端砍掉了一个已声明的能力,还是把 spec 自己的拒绝落实了」。scripts/pm/record-recognisers.mjs的REVIEW_FACESnarrowing 行(fullReview: true)与简报的 narrowing 专用 ④ 段;contract-review.mdL22/L30。node scripts/pm/record-recognisers.mjs --brief-template --face narrowing应打出 ④ 段(「the narrowing itself, read against the published spec onmain」);--face declaration的围栏内无 ④。What changes
The maintainer's ruling on #26527 item 3 (letter A, ruling record 6442046166) hangs item ④, the design judgment, on the narrowing face of the contract review as well. A PR that narrows a published accept set in runtime code alone, touching neither
packages/spec/src/**nor a governed path, now gets the same ④ the schema and rules faces get, in the narrowing's own shape: nohitsfiles, so the judgment is of the narrowing itself, read against the published spec onmain— does it take a declared capability away at the consumer, or make the spec's own refusal real?scripts/pm/record-recognisers.mjsREVIEW_FACES.narrowinggainsfullReview: true;recordCarriesDesignJudgmentis unchanged and now answers true for that face, so the record prints### ④ Design judgmenton--face narrowing(the declaration face, below tier, still prints three headings).--templatenotes name three faces and the narrowing scenario (the narrowing itself against the published spec onmain); the declaration face alone is said to carry no ④.--brief-templateon the narrowing face carries a narrowing-specific ④ instruction (read against the published spec onmain; a capability declared and not delivered is an implementation gap, implemented or retired, never narrowed at the consumer) and a scope line saying ④ judges the narrowing over the whole-diff floor, lockfiles, generated output, changesets and prose not reviewed. The schema and rules faces keep the per-hits-file shape unchanged..claude/skills/pm-dispatch/references/contract-review.mdWhy
Faces resolve schema → rules → narrowing → declaration, so a narrowing PR that also touches a spec or governed path already carried ④; only the runtime-only narrowing fell to a face without it. That is exactly the face where the pm-dispatch principle 「声明而未兑现是实现缺口,补实现或退役,⛔ 不在消费端收窄」 is most easily broken (spec untouched, runtime narrowed first), and the review asked only whether the declaration line was spelled right. The ruling closes that gap without a new face or a new gate.
Tests
Forced test edits, all in the self-test of
scripts/pm/record-recognisers.mjs(pnpm check:pm-record-recognisers):--face narrowing); 「exactly the two path-read faces are full-review faces」 → the three at-tier faces (schema,rules,narrowing); 「the narrowing brief carries no ④」 → carries ④ in the narrowing's own shape (spec scenario, nohits-ONLY rule, no angle brackets, no model identifier).narrowingtoo.hitsfaces keep the per-file ④ shape and never the narrowing's (brief battery floor 17 → 18).Self-test at
78af1243: 219 cases pass, exit 0 (217 before the change). Mutation leg (one shot,scripts/ablation-replace.mjs, anchor hit exactly once, trap-restored, restored blob byte-identical to HEAD462459281f4b):fullReview: true→falseon the narrowing row ⇒ exit 1, 5 of 219 cases fail (the three flipped pins and the two added ones). No build or dist is involved; the script runs from source.Acceptance notes
--template --paths packages/objectql/src/x.tswith a narrowing face prints ④」 is not reachable through--pathsalone:reviewFacereads the narrowing face off theClause-②:line, which a path list cannot hand it. Measured at78af1243:--template --paths packages/objectql/src/x.ts(no changeset in the list) prints the declaration face, exit 0;--template --paths .changeset/x.md packages/objectql/src/x.tsis refused, exit 1, telling the caller to pass--face narrowing(pinned before this PR). The face that prints ④ is--template --face narrowing, and it does.fullReviewexists outside this file (git grep fullReviewat78af1243: record-recognisers.mjs only); the queue guard anddispatch-gatesdo not read it.Verification
node scripts/pm/record-recognisers.mjs --self-test— 219 cases pass, exit 0.pnpm check:pm-skill-ratchet— exit 0 (self-test and scan);pnpm check:pm-skill-id-lint— exit 0, 104 files clean.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackat78af1243): 38 commands; results in theos-dev-reportcomment on pm-dispatch(contract-review): item ④ names the rules face as three surfaces and the brief names the accepted scenario for an ADR only — reword to the governed register, add per-surface scenarios, decide ④ on the narrowing face #26527 and the details block below.Derived gate sweep at `78af1243` — 38 commands, every exit 0, captured before any pipe; `--ran` reconciliation: 38 derived, 38 run, 0 NOT-MEASURED, 0 UNRUN
Notes:
pnpm check:pm-dispatch-gatesran its fast tier (1935 cases pass; 7 slow sections deferred, as the script does on every local run) in 5m30s;@objectstack/lint check:doc-formula-expressionsneeded@objectstack/formulaand@objectstack/lintbuilt first (throughscripts/pm/os-verify-lock.sh, VERDICT command-exit 0, 99 s). Not in the derived list and not run locally: repo-widepnpm lint(CI owns it) and the CI families outside the derivation; the PR check-runs are the record for those.Human Minimum
packages/specholds no runtime logic. (not touched)pnpm lintis CI's run (repo-wide scan).main, one pull request..claude/**+scripts/pm/**), soskip-changeset; both declaration lines are filled in above.packages/specnot touched.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.Generated by Claude Code