Repository navigation
pm: land low-risk skills wording on the seat's review (Tier S arm on the catalog rows) - #33531
objectstack-fleet[bot] wants to merge 11 commits into
Conversation
…the catalog rows) The skills-catalog and ui-skills-catalog register rows keep tier H for every path-only reader and carry a low-risk reading: a diff whose only governed paths are catalog paths, whose other paths are changesets or docs prose, whose body declares a bare `Clause-②: no` and which carries no `security` label reads Tier S. The queue guard reads it on the merge_group leg off the pull object it already fetches, over every commit of the PR; `--pr` reads it off the same GET. Everything else, and any unread input, stays Tier H. docs/adr stays Tier H. AGENTS.md Prime Directive 14 and the pm-dispatch landing lines name the arm. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FEkQ5pF46HJnpBrhgVWtwV
…s root Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FEkQ5pF46HJnpBrhgVWtwV
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Contract reviewServed-tier: Inputs: card #33501 (body, claim, grading comment 6885437809, os-dev-report 6886128572), PR #33531 (body, five files, net diff against Check-runs on ① Derived judgments
② Semver levelNothing in the diff publishes. The changed files are Clause-②: no No published accept set or public surface moves. The changed exports belong to unpublished fleet tooling. ③ Boundary flags
④ Design judgmentM1 — must-fix. The arm reads contract declarations from the one carrier a seat can still change after the PASS, and leaves the committed carriers unread.
Fix: in both S1 — should-fix. Removing the S2 — should-fix. Clause-② lines with trailing text, or more than one Clause-② line, read S. S3 — should-fix. A fork PR passes the arm. S4 — should-fix. Inside the arm rows, anything under N1 — nit. PD 14 names N2 — nit. Holds, read against the code:
Implemented-by: VERDICT: FAIL Adopted by the seat 2026-11-14T23:59Z · isolated sub-agent at CONTRACT_REVIEW_TIER · Ruling-ref: Leehom card cmsg_01TenzsRopZj4jMbvjX8uz1XFhuiZmTH8VFgMmHRmpiGAb, option A, tapped 2026-11-14T15:37Z |
…and a PASS record The arm now holds a skills PR at Tier H unless its body carries exactly one bare `Clause-②: no` and `Metadata-protocol: none`, every changeset read at the head releases only `'@objectstack/skills': patch` with the same two lines, the timeline never removed a `security` label, the head is no fork, and every file under a catalog row is Markdown or an `evals/*.json`. At the queue the arm clears only on a same-head record that reads PASS, read with the fleet's verdict reader (re-exported by the recognisers). SKILL.md names the workflow Tier H triggers again. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FEkQ5pF46HJnpBrhgVWtwV
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Correction: contract-review tierThe contract-review record(s) 6886243839 on this PR say The seat re-runs the review at |
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Contract reviewServed-tier: Inputs: card #33501 (body, claim 6885432460, grading comment 6885437809, os-dev-report 6886128572), PR #33531 (the r2 body as the dev's file reads, six files, net diff against The ruling quoted on the card: 「同意 把低风险的 Tier H 放权给座位」 and 「把低风险的 Tier H 放权给座位,立 p1 卡优化」. Its scope, in the coordinator's words on the card: pure docs, ADR notes and skills wording land on the seat's own contract-review PASS; anything touching a contract (spec or published types, Clause ②, narrowing) or security stays with the maintainer. Check-runs on ① Derived judgments
② Semver levelNothing in the diff publishes: Clause-②: no No published accept set or public surface moves; the changed exports belong to unpublished fleet tooling. ③ Boundary flags
④ Design judgmentSF1 — should-fix. On the arm, a carried record lets the declarations and catalog files move after the PASS. The M1 fix makes the committed changeset the carrier of
N1 — nit. PD 14 and SKILL.md line 202 name the arm beside N2 — nit. The N3 — nit. The post-merge sweep classifies by path alone, so a seat-landed arm merge is listed as a Tier H row with no approval, and the auditor has to re-read the arm by hand to tell it from a violation. Card item 4 is met at parity with N4 — nit. Comments in both scripts cite 6886243839 as "contract review"; that record was served off-tier and is being replaced. The pointers describe history accurately, but they should name the record that stands. Accepted deviation on this head, since a comment edit moves it. Holds, read against the code and each tried as a break:
Implemented-by: VERDICT: PASS Adopted by the seat 2026-11-15T00:43Z · isolated sub-agent at CONTRACT_REVIEW_TIER (served model verified by the seat) · Ruling-ref: Leehom card cmsg_01TenzsRopZj4jMbvjX8uz1XFhuiZmTH8VFgMmHRmpiGAb, option A, tapped 2026-11-14T15:37Z |
…r catalog path moved The regeneration and prose-only carry admits `.changeset/**` and catalog prose such as a skill's CHANGELOG.md, yet those are what the arm reads its tier from. For an arm entry, a record carried from an older head now stands only when the hops (diffed with the leg's git reader) moved no changeset and no path under a catalog row; an unreadable diff refuses. PD 14 and SKILL.md say the skills arm is exclusive (skills-only wording), and the code comments drop the off-tier review citation. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FEkQ5pF46HJnpBrhgVWtwV
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Contract reviewServed-tier: This is a delta review at tier. Base: head Inputs: card #33501 (body and all three comments), PR #33531 (body, six files, the net diff at both heads, the commit Check-runs on ① Derived judgments
② Semver levelNothing in the diff publishes: Clause-②: no No published accept set or public surface moves; the changed code is unpublished fleet tooling. ③ Boundary flags
④ Design judgmentSF2 — should-fix. A rename OUT of a catalog row is invisible to the new check, so a catalog file can leave the published catalog after the PASS on a carried record.
N5 — nit. The check diffs the two trees whole, so a merge-forward from N6 — nit. The four new cases drive a fake git reader that answers one fixed list, so they pin the argument order and the path filter but cannot measure what git itself lists. That is why SF2 passed the battery. The pin SF2 asks for is on the flag. N7 — nit. Dropping the citations left three docblock lines unwrapped or short (the Holds, each read against the code and tried as a break:
Implemented-by: VERDICT: PASS Adopted by the seat 2026-11-15T01:16Z · isolated sub-agent at CONTRACT_REVIEW_TIER (served model verified by the seat) · Ruling-ref: Leehom card cmsg_01TenzsRopZj4jMbvjX8uz1XFhuiZmTH8VFgMmHRmpiGAb, option A, tapped 2026-11-14T15:37Z |
`git diff --name-only` names a rename by its destination alone, so a hop that moved a skill out of the catalog into the docs tree cleared on a carried record. The check now diffs with `--no-renames`; the self-test pins the argument and runs the rename on a real repository. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FEkQ5pF46HJnpBrhgVWtwV
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Contract reviewServed-tier: This is a delta review at tier. Base: head Inputs: card #33501 (body and comments), PR #33531 (body, six files, the net diff at both heads, the commit Check-runs on ① Derived judgments
② Semver levelNothing in the diff publishes: Clause-②: no No published accept set or public surface moves; the changed code is unpublished fleet tooling. ③ Boundary flags
④ Design judgmentSF2 — fixed. Read in the tree at this head:
SF3 — should-fix. The real-git case is not hermetic against the caller's git environment, and the repository states a rule for exactly this.
N7 — nit, partly taken. As in ③: "may change: skill" is still a short line, and one new docblock line is 88 columns. No effect on meaning. N8 — nit. Holds, each read against the code and tried as a break:
Implemented-by: VERDICT: PASS Adopted by the seat 2026-11-15T01:41Z · isolated sub-agent at CONTRACT_REVIEW_TIER (served model verified by the seat) · Ruling-ref: Leehom card cmsg_01TenzsRopZj4jMbvjX8uz1XFhuiZmTH8VFgMmHRmpiGAb, option A, tapped 2026-11-14T15:37Z |
…the caller's GIT_ env The temporary-repository case now runs every git call with `gitFreeEnv()` and `-c commit.gpgsign=false`, as the sibling fixtures do, so an inherited GIT_DIR or GIT_INDEX_FILE never reaches the real checkout. Docblock lines rewrapped. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FEkQ5pF46HJnpBrhgVWtwV
Requested by Leehom · project thread
Fixes #33501
domain:skills#1 · os-project-manager · session_01FEkQ5pF46HJnpBrhgVWtwV
Clause-②: no
Metadata-protocol: none
维护者速读
skills/**与ui/skills/**两行仍是 Tier H,但多了一个「低风险技能臂」读数。以下全部成立才读成 Tier S:受管路径只在这两行;这两行下只有.md与evals/*.json;其余路径只有 changeset 与docs/、content/docs/下的 Markdown 散文;正文恰好一行裸写的Clause-②: no和一行Metadata-protocol: none(引用、代码块、尾随文字、多行声明都算 H);至少一个 changeset,在 head 读出,只发布'@objectstack/skills': patch,也带这两行;不带security标签,时间线上也没被摘掉过;不是 fork。合并队列守卫在 merge_group 腿读这些,再要求同 head 的达档复核记录写的是 PASS,席位入队才放行;--pr预检给同一判定。AGENTS.md 第 14 条与 pm-dispatch 两处落地行同步。--test、--branch与中继请审照旧按路径读 H。docs/adr/**不动,仍 Tier H,ADR 那一半由 pm: let a seat land an add-only ADR note under the low-risk Tier H ruling (docs/adr/** stays Tier H until then) #33539 承接。回滚即还原本 PR。scripts/pm/check-governed-merges.mjs的lowRiskArmVerdict与readBareDeclaration;scripts/pm/check-governed-queue-guard.mjs的readLowRiskTier与lowRiskRecordVerdict;AGENTS.md 第 14 条 Tier S 括号。node scripts/pm/check-governed-merges.mjs --pr 33394,预期 exit 3、Tier S(席内达档复核落地)与low-risk skills arm ... Tier S一行。AGENTS.md,本身是 Tier H:请合并(或批准后由席位落地)。What changes
The register (
scripts/pm/check-governed-merges.mjs). Theskills-catalogandui-skills-catalogrows keeptier: Hand gainlowRisk(scoped to objectstack), modelled on the workflows split: a READING moves them, the row does not.lowRiskArmVerdict(matched, repo, reading)reads Tier S only when ALL of these hold, each a printed reason when it does not:LOW_RISK_RIDER_PATTERNS(a.changeset/*.md, or Markdown prose underdocs/orcontent/docs/), and every path under a catalog row is.mdorevals/*.json(LOW_RISK_ARM_FILE_PATTERNS);Clause-②: noand one bareMetadata-protocol: none.readBareDeclarationruns the fleet's own readers (readClause2Line,readMetadataProtocolLine) line by line, never a second parser: a second declaration, trailing words, an arm, or the line quoted or inside a fence is H;'@objectstack/skills': patch(an empty frontmatter is allowed) and whose body carries the same two bare lines (lowRiskChangesetReasons);security, and the timeline was read and has nounlabeledevent forsecurity;forkVerdictof the pull object reads a same-repository head.No reading, or an unmeasured one, is Tier H with its reason.
applyLowRiskArmruns afterapplyWorkflowSplit, so a split workflow row beside a catalog path counts as a governed row outside the arm.governedTierForandtestVerdicttake the reading as one more optional argument; every caller that passes none answers exactly as before (catalog paths Tier H).renderLowRiskLinesprints the arm's verdict.--prbuilds the reading from the pull object and file walk it already fetches (pullLowRiskReading), plus the timeline over the same channel (fetchTimelineOver, only when a catalog path is hit, every page or NOT MEASURED) and each changeset at the PR's head from this checkout (pullChangesetReading, NOT MEASURED with the fetch that cures it when the head is not here).--testand--branchhave no body and say NOT MEASURED. The header section "The low-risk skills arm" lists the conditions.The queue guard (
scripts/pm/check-governed-queue-guard.mjs).decomposeGovernedWorkkeepsallPaths(every path of every attributed commit of the PR, collected before the governed filter drops a row) andchangesetRefs(each changeset with the commit that touched it, ungoverned commits included). The entry reads the arm NOT MEASURED there; thepull_requestleg prints Tier H with that note and never reddens. Onmerge_group,readLowRiskTierre-reads each catalog entry's tier through the register'sgovernedTierForwith: the body, label names andforkVerdictof the pull object the leg already fetched (makePullReadernow returnslabelsandfork); the timeline the enqueue leg already read (kept, not re-fetched; an unread or failed timeline is NOT MEASURED); and each changeset bygit show <commit>:<path>. Then the Tier S record leg runs, and for an entry the arm put at Tier S the same-head record must also READ PASS:lowRiskRecordVerdictreads the comment the locator chose with the fleet'scontractReviewVerdictOf. FAIL, no verdict word, or no reader loaded is a refusal (not-pass) with its own line. A record carried from an older head (the regeneration and prose-only carry) stands for the arm only when the hops, diffed with the leg's git reader (--no-renames, so a rename lists both paths), moved no.changeset/path and no path under a catalog row (the carry admits both as prose, yet the arm reads its tier from them); an unreadable diff refuses. The other Tier S legs are unchanged and still read no verdict (pm: the queue guard's Tier S record leg checks a same-head record exists but never reads its verdict #33541).scripts/pm/record-recognisers.mjs. Re-exportscontractReviewVerdictOffromcheck-half-states.mjs(already its import), so the guard's lazy loader reaches the fleet's one verdict reader. One import name and one export line.AGENTS.mdPrime Directive 14. The surface list drops "all Tier H"; Tier H is "every register row outside Tier S"; Tier S names.claude/**and the objectstack workflow edits and skills-only wording the register reads as S (readWorkflowDiff,lowRiskArmVerdict). The detail lives in the script header, per AGENTS.md's own rule. Net content is 13 bytes shorter; the paragraph is re-wrapped at the 120-byte budget and keeps its 16 lines (AGENTS.md 1050 to 1050).pm-dispatch.
SKILL.md: "路径面命中 Tier H" becomes "定档 Tier H", and the workflows line names both readings and keeps the workflow Tier H triggers (readWorkflowDiff(发布面/C2/拒读⇒H),技能lowRiskArmVerdict,未读⇒H), within the 120-byte line budget.references/lanes/skills.md: the pre-arm check ischeck-governed-merges --pr N(only--prcan read the arm). The other places the card and comment 6885437809 listed were read and still hold as written:contract-review.md16 and 51 andlanding-operations.md12 and 89 speak of Tier S and Tier H generically,execution-duties.md17's soft cap already counts only PRs that stay Tier H, andcoordinator.mdnames no tier.Why
Ruling-ref: Leehom, project chat 2026-11-14, verbatim 「同意 把低风险的 Tier H 放权给座位」, then 「把低风险的 Tier H 放权给座位,立 p1 卡优化」. Measured on
origin/mainf068cde:GOVERNED_SURFACESputskills/**at Tier H, and the guard'smerge_groupleg passes a Tier H entry only on an authorized approval or enqueue (GOVERNED_APPROVERS), so a seat enqueue of a skills wording PR is refused. Comment 6885437809 measured that the ruleset requires no review (PRs merged with zero reviews), so the guard is the only stop and no settings change is owed.Acceptance notes
docs/adr/**stays Tier H. The ruling names ADR notes, but a path cannot tell a note from a changed decision. pm: let a seat land an add-only ADR note under the low-risk Tier H ruling (docs/adr/** stays Tier H until then) #33539 carries the ADR half of the ruling (an add-only note reading).scripts/pm/fleet-write/execute.mjsgovernedReviewPlanreads paths only): a summons, not a block. Follow-up pm: the relay's governedReviewPlan still summons the approvers on a low-risk Tier H PR the seat may land #33540..claude/**, the workflow split): only the low-risk arm requires PASS here. Follow-up pm: the queue guard's Tier S record leg checks a same-head record exists but never reads its verdict #33541.AGENTS.md's own rule allows no ruling date or quotation there (provenance cites a ruling record), and its line ceiling has no headroom. The conditions and the ruling live in the script header and thelowRiskArmVerdictdocblock, which PD 14 names.--testand--branchalways read the arm NOT MEASURED (they have no PR body); the seat's pre-arm check for a skills PR is--pr N..claude/skills/pm-dispatch/SKILL.md(two different lines). Whichever lands second mergesorigin/main.--pr 33394and--pr 33482both still read Tier S through the tightened arm (timeline, fork and changesets read; head fetched locally). They still need a same-headCONTRACT_REVIEW_TIERPASS record before the seat enqueues, and they can only use the arm once this PR is onmain.Verification
Head
e2b1cabc(after the at-tier reviews 6886787995, 6887175399 and 6887454202: the carried-record fix,--no-renameson its diff, then the real-git case detached from the caller'sGIT_environment; branch merged withorigin/main).Self-tests of the edited scripts
node scripts/pm/check-governed-merges.mjs --self-test: exit 0, 670 assertions. Battery "⚖️ the low-risk skills arm" now 54 cases (floor pinned at 54), pinning each review item: M1 (no changeset; changesets unread; another package,minor/major, or a second release line; changeset missing or annotating either declaration; no frontmatter; not readable at the head; a changed changeset the reading holds no file for; body without a bareMetadata-protocol: none; the catalog at patch in either quote or an empty frontmatter is S), S1 (unlabeledsecurity in any case; another label removed stays S; timeline unread or not a list;--prreads the timeline only when a catalog path is hit), S2 (trailing words; two declarations, even twono; a quoted or fencednobefore a realyes, backtick and tilde fences; a lone fenced or quotedno; a closed fence before the real line stays S), S3 (fork; deleted head repo; unread fork predicate), S4 (.js,.jsonoutsideevals/, nestedevals/sub/*.json,.yaml,.png,.share H;evals/*.jsonis S), pluspullChangesetReadingandlowRiskRowHit.node scripts/pm/check-governed-queue-guard.mjs --self-test: exit 0, 477 cases. Battery "⚖️ the low-risk skills arm at the queue" now 44 cases (floor 44), end to end throughrunGuardonmerge_group: the PASS clear; a PASS record carried over a docs-only hop clears, while one carried over a hop that rewrote the changeset or moved a skill'sCHANGELOG.mdis refused, as is a carried record whose hops cannot be diffed; the carry check's diff carries--no-renames(argument pinned), and on a real temporary repository (every git call undergitFreeEnv()with-c commit.gpgsign=false; the self-test also passes withGIT_DIRset to a bogus path) a skill renamed out of the catalog intocontent/docs/refuses the carried record while the plain diff names only the destination; a same-head FAIL record, a record with no verdict word, a newer FAIL behind an older PASS, and a recogniser set without the verdict reader are each refused (not-pass);**VERDICT: PASS**clears; a non-arm Tier S entry with a FAIL record still stands (unchanged, pm: the queue guard's Tier S record leg checks a same-head record exists but never reads its verdict #33541); M1, S1, S2, S3, S4 each H with a valid PASS record (changeset in another commit of the PR included; no git reader; a timeline that threw or was never read);makePullReadercarries the fork predicate.node scripts/pm/record-recognisers.mjs --self-test: exit 0, 383 cases.unlabeled, allowing a second declaration, allowing a fenced line, switching S4 off, allowing no changeset, skipping the carried-record check, and dropping--no-renameseach turn the self-test red.Derived gates: 47 derived, 47 run, all exit 0
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 47 families on heade2b1cabc(check:pm-record-recognisersjoins for the re-export). Each ran with its exit code captured before any pipe, after building@objectstack/lint...under the verify lock (VERDICT command-exit 0). All 47 exit 0.--ran: "47 derived famil(ies) accounted for — 47 run, 0 NOT-MEASURED (a DERIVED zero)". CI families are read from this PR's check-runs, not re-run here.Tier, governed reading, line budget
dispatch-gates --tier: MANDATORY contract-review tier, from.claude/skills/pm-dispatch/SKILL.md.node scripts/pm/check-skill-line-ratchet.mjs: exit 0.SKILL.mdstays 319 lines; its workflows line is exactly 120 bytes and the tier line says the skills arm is exclusive.AGENTS.mdstays 1050 lines; PD 14's last eight lines are re-wrapped at the byte budget for "skills-only".4a459236:--pr 33394and--pr 33482read Tier S through the arm with the timeline, fork and changesets read (heads fetched locally).Human Minimum
packages/specholds no runtime logic. (No schema touched.)pnpm lintpasses. (CI runs it.)main, one pull request.scripts/pm/**,.claude/**,AGENTS.md;skip-changeset.)packages/spectouched: its generated artifacts are regenerated and committed. (Not touched.)content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01FEkQ5pF46HJnpBrhgVWtwV