Repository navigation
docs(pm-dispatch): a queue card with no triage audit is knocked by the lane and derived by the sweep - #29940
Conversation
…e lane and derived by the sweep A lane seat that finds a `pm:queue` / `pm:blocked` card with no triage audit comment now rings `Request: triage · #n · first-touch audit` in the same round instead of waiting or reporting the gap to the maintainer (execution-duties.md, beside the generic doorbell line). The triage lane charter gains the matching sweep duty, and `check-half-states.mjs` gains H74, a report-only row that derives the set from both channels — the body and the thread — through the existing audit-record recognisers plus the signed `## Triage` shape, with its own self-test battery. Both reference files stay at their ceilings: each new line is paid by deleting a line whose content lives elsewhere (the downgrade-tier record line restated by the claim template and its neighbour; the security vacancy line restated by security-findings.md §7/§9). Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGufzgjcGBFsSmg6tHbbJq
|
domain:skills#3 · os-support-ai · session_01WGufzhd2Ad9ANGTyAMW7pH Contract reviewServed-tier: Inputs read: card #29682 body and both comments (the claim and the os-dev-report); PR #29940 body, file list (3 files, +245/−2) and the net diff against Check-runs on the head at the time of writing: every completed non-skipped run is ① Derived judgments
② Semver levelNothing published: no package path in the diff. ③ Boundary flagsThe dev declared four deviations on the os-dev-report, one acceptance-note flag and one out-of-scope finding;
④ Design judgment
Must-fix: none. Should-fix: items 1, 2, 6, 7. Implemented-by: VERDICT: PASS |
…e reason kept, H74 reads the three audit exemptions Four should-fixes from the contract review of the first commit, in one round: - execution-duties.md: the knock line routes a vacant triage seat to the director (project-forms.md routes only `Request: main-red` that way), and the downgraded tier with its reason is written on the claim comment's Container & model line again — folded into the effort line, so the file stays at 188 and no line passes 120 bytes. - check-half-states.mjs H74: the `[maintainer]` title test was a no-op (no such spelling exists on the board); it now reads SKILL.md's non-fleet card through one shared `isFleetCard` (human author, no seat signature) that H67's read order uses too. A main-red anchor card is exempt by its measured title openings, and a sub-issue that inherits its parent's domain or grade is exempt through the sub-issues parent read H45 already takes — bought only for a card whose thread was read and found clean, with an unreadable parent fired as UNJUDGED. The battery pins each exemption beside the twin that still fires. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGufzgjcGBFsSmg6tHbbJq
|
domain:skills#3 · os-support-ai · session_01WGufzhd2Ad9ANGTyAMW7pH Contract reviewServed-tier: Round 1, after record 6609708274 on head Check-runs on ① Derived judgmentsRound 1 after 6609708274. The four round-0 should-fixes and what the delta does with each:
② Semver levelUnchanged from round 0: nothing published, ③ Boundary flagsNo round-1 os-dev-report on the card and no new
④ Design judgment
Must-fix: none. Should-fix: items 2 and 4. Implemented-by: VERDICT: PASS |
… by its identity label Contract review r1's one should-fix. `fleet-patrols.yml` files its platform-checklist watchdog anchor as `pm:queue,tooling` under an App author with the title `check:platform-checklist is red on main`, which the main-red title regex does not open (no colon before `red on main`), so the anchor stayed in H74's population. It is now exempt by its identity label `platform-checklist-watchdog`, the way `queue-flake-anchor` is, because the identity label is the machine's and is never graded off while a title is one template's wording. Census of every `.github/workflows/**` template that files a card: this is the only one that applies `pm:queue` on create; the nightly-tiers and scheduled full-run cards file without it (the full-run refresh may re-queue an unassigned card) and their titles open `: red on main`. The battery pins the anchor as filed beside the same card without its identity label, which still fires. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGufzgjcGBFsSmg6tHbbJq
|
domain:skills#3 · os-support-ai · session_01WGufzhd2Ad9ANGTyAMW7pH Contract reviewServed-tier: Round 2, after record 6610054068 on head Check-runs on ① Derived judgmentsRound 2 after 6610054068. The two round-1 should-fixes and what this head does with each:
② Semver levelUnchanged: nothing published, ③ Boundary flagsNo round-2 os-dev-report on the card and no new
④ Design judgment
Must-fix: none. Should-fix: none. Implemented-by: VERDICT: PASS |
|
domain:skills#3 · os-support-ai · session_01WGufzhd2Ad9ANGTyAMW7pH 维护者速读
席位意见:按你的原话落地,三轮复审 PASS,同意落地。 席位核对 — ACCEPT · domain:skills#3 · head
|
Requested by Yibo Wang · project thread
Fixes #29682
维护者速读
Request: triage · #n · first-touch audit敲分诊信箱,分诊空席改敲总监(execution-duties.md候选节);分诊席章程加一条:每轮 sweep 推导这类卡并照首触补审计、报数(lanes/triage.md);半状态巡查check-half-states.mjs加一行只报告的 H74,从正文与评论两个通道推导同一集合,豁免 SKILL.md 的三类免审计卡(非车队卡、main-red 锚卡、承父卡域/级的子卡)与机器锚卡的身份标签。pm:queue一笔挂齐,分诊 sweep 的五个析取都按「缺标签」找卡,看不见它;车道一侧读到「无分诊审计评论 ⛔ 不得认领」就停着等。两边互等,没人被提醒;当日实测 15 张,含两张 p1。pm:queue33 张 +pm:blocked23 张为上界)。回滚 = revert 本 PR,无数据与门禁副作用。scripts/pm/check-half-states.mjs的 H74 节(isTriageAuditRecord两种记录形状、isFleetCard、H74_MAIN_RED_ANCHOR_TITLE、h74InheritsFromParent与H74_EXEMPT_LABELS);②execution-duties.md第 63 行门铃句、第 121 行降档理由并入与删掉的旧第 120 行;③lanes/triage.md第 16 行 sweep 句与删掉的末行。node scripts/pm/check-half-states.mjs --self-test,预期末行5222 cases pass,电池清单含H74 first-touch audit 60/46。.claude/**为 Tier S,席内达档复核后由席位入队)。Clause-②: no
Metadata-protocol: none
What changes
Lane side —
references/execution-duties.md, 候选与批次 section (net 0 lines, 188/188). One line added directly under the generic doorbell line 「⛔ 不静默等分诊」: a candidate with no triage audit comment is knocked in the same round with the existing keyRequest: triage · #n · first-touch audit; when the triage seat is vacant the knock goes to the director (project-forms.mdroutes a vacant triage to the director only on itsRequest: main-redrow, so the route is spelled here for this key); and ⛔ the gap is never reported to the maintainer in the mailbox's place. The rule sits here rather than beside SKILL.md line 171 (where 「无分诊审计评论 ⛔ 不得认领」 lives) because this file is where the execution seat's candidate definition and its generic knock already live, SKILL.md is at its ceiling with no restated line to pay with, and the card asked for one place only. Paid by deleting the line 「降档的档位与理由记入认领评论 Container & model 行;档位逐次派发显式传参,永不省略」 — and because its first half (the downgraded tier AND its reason go on the claim comment) was stated nowhere else, that half is folded into the effort line below (now 「effort 按卡难度定,与档位、降档理由写进 Container & model 行与派发令,显式传参,⛔ 不留空」); its second half (the tier passed explicitly at every dispatch) was already carried by that same line.One thing the card said that the text does not spell, on purpose: "one doorbell per card or one listing several" — the
request:triagereader (record-recognisers.mjs) takes exactly one#n, so the line says one knock per card.Triage side —
references/lanes/triage.md(net 0 lines, 20/20). One line added under the push list: the sweep also derivespm:queue/pm:blockedcards with no audit comment (exemptions as the H74 row lists them), audits each as an ungraded first touch and reports the count. Paid by deleting the last line 「security#1空缺时沿用security-findings.md第 7 节处置,⛔ 不代席、不追加细节」, which restatessecurity-findings.md§7 (no details, hand to the maintainer) and §9 (a vacantsecurity#1seat hands to the maintainer) — and §8 of that file forbids a second copy outright. The line above it still points atsecurity.md.Tooling —
scripts/pm/check-half-states.mjs, H74 (report-only). The triage sweep's disjunct derivations do live in this script (H13 mirrors disjunct ③), so the card's "if a script owns the sweep" arm applies. H74 speaks about open issues carryingpm:queueorpm:blocked, minus:tracking,pm:epic,pm:seat,qa-run,status:parked,queue-flake-anchor— the labelmerge-queue-triage.ymlstamps on its anchors) plusplatform-checklist-watchdog, the identity label of the one in-tree anchor templatefleet-patrols.ymlfiles ASpm:queue,tooling(titlecheck:platform-checklist is red on main, which the main-red title reading below does not open; the identity label is the machine's and is never graded off, so it is the right key). A census of every.github/workflows/**template that files a card found no other that appliespm:queueon create;[maintainer]cards", read as 「非车队卡:作者非Bot且首行非席位签名」 through one sharedisFleetCard— an App author or a seat-signed body is the fleet's, an unreadable author is never promoted to a human's — which H67's read order now uses in place of its inline copy); a main-red anchor card, by its measured title openings (main red:/main red (…)/main red since …as seats file them, and: red on mainas the scheduled-run cards file them; a card about main-red such aspm-dispatch(main-red): …stays in); and a sub-issue inheriting its parent's domain or grade, read through the sub-issues parent fetch class H45 already takes (subIssueParentPath, same documented-404 reading), bought only for a card whose thread was READ and found clean — a non-404 failure fires the card's own UNJUDGED row through a sentinel, never silence.A triage audit record is either a text whose first line is a
triage#Nsignature and which carries a## Triageheading (fences stripped), or one of the older openingsisTriageRulingCommentalready reads for H33 (Triage:,Grading, …, signature-tolerant). The body is read first; a body-clean member buys one comment-page read off the shared cache (H55's gated-fetch pattern,needsTriageAuditComments), so a card H2 or H4 already fetched costs nothing. Three thread states: unconsulted ⇒ silent (never a fabricated row); unreadable ⇒ an UNJUDGED row; read ⇒ fires when neither channel carries a record. Bandstate(H13's), a coverage pair in the summary sentence (First-touch audits (H74): comment threads read on X of Y …), two count keys on the forwarding contract, no label, no exit code, no gate.Not changed:
SKILL.md(untouched; line 171 stays the lane's ⛔ line),triage-duties.md(held by #29445's dispatch),record-recognisers.mjs(therequest:triagekey is reused as is), no new key, label, gate or ceiling raise. The line ratchet's raise rule asks for a ruling comment id; the maintainer's word on this card is a session sentence with no comment id, so every added line is paid by deletion.Why
Both sides had a rule that read 「not mine」: triage's sweep derived cards by missing labels and this shape has every label; the lane read the audit-less card as non-candidate and waited. The maintainer's own word is on the card. The fix is the smallest pair that converges: the lane rings the existing bell in the round it notices, and the sweep lists the same set so the first triage round after landing finds nothing a lane has not also knocked about.
Tests
node scripts/pm/check-half-states.mjs --self-test—✓ check-half-states self-test: 5222 cases pass, batteryH74 first-touch audit 60/46(frozen roster, pin under the count). The battery drives: a card with an audit comment and one without (the card's acceptance pin), each record shape as its own positive control (signed## Triage,### Triage, the olderTriage:opening, a lane-signed self-triageTriage:record), the controls that must still fire (a triage-signed comment with no heading, a lane-signed heading below prose, a fenced## Triagecitation), the body channel (clean and buys no thread), the three thread states, every exempt label beside a non-exempt twin, the watchdog anchor asfleet-patrols.ymlfiles it beside the same card without its identity label (fires — the title alone does not exempt it), the non-fleet card beside its three fleet twins (seat-signed body under the same human account, App author, unreadable author) and theisFleetCardleg of H67's order, six measured main-red anchor titles beside a card about main-red and a mid-titlered on main, the sub-issue exemption by domain and by grade beside a parent sharing neither, a parentless 404, an unread parent, the unreadable-parent UNJUDGED row, the parent-read gating policy, the population edges (closed, PR row, unreadable labels, missing row, null body), the row text (no angle bracket, no tracker number, both remedies named), the summary pair and its shortfall clause, the two count keys on the contract, the band and the emitted-code coverage.npx eslint scripts/pm/check-half-states.mjs— exit 0.pnpm check:pm-half-states,pnpm check:pm-skill-ratchet(both edited files at their ceilings, widest line 120 bytes),pnpm check:pm-skill-id-lint(109 files clean) — exit 0 on the final head.Acceptance notes
isTriageRulingCommentis reused unchanged, so a## Triageheading as a comment's FIRST line reads as a record under the older anchor whatever the signature (H33's reading, pinned as kept); the signed shape only adds the case where the heading sits below prose.[maintainer]title prefix has no spelling in the protocol text or scripts onorigin/main, so the card's "[maintainer]cards" are read as SKILL.md's 非车队卡 (a human author with no seat signature) rather than as a title test that would never match.pm:queue+ 23 openpm:blockedcards, less exemptions and cards H2/H4 already fetch. No cap was added because H2, H4 and H45 buy the same way without one; the summary pair reports any thread shortfall, and an unreadable parent is its own UNJUDGED row.Writes:git push×4 (WIP, final, patch round 1, patch round 2), relaypr_create×1 (draft,labels: ["skip-changeset"], no assignees),post-stamped.mjs --comment×1 for theos-dev-report.mcp_calls: GitHub MCP reads only (issue_read×6,list_issues×2); no MCP write.Verification
Final head
1281c79a(three commits on the branch: the change, contract review r0's four should-fixes, contract review r1's one). On the first head197f87e0, derived withnode scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackagainst merge base21510bba(3 paths), 54 commands run serially in the worktree with each exit code captured before any pipe, then reconciled:✓ dispatch-gates --ran: 54 derived famil(ies) accounted for — 53 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3). The two later heads touch the same three paths and re-ran the gates the diff can move:pnpm check:pm-half-states,pnpm check:pm-skill-ratchet,pnpm check:pm-skill-id-lintandnpx eslinton the script, all exit 0.197f87e0, among thempnpm check:pm-half-states(the H74 battery),pnpm check:pm-skill-ratchet,pnpm check:pm-skill-id-lint,pnpm check:pm-dispatch-gates,pnpm check:pm-governed-merges,pnpm check:pm-post-stamped,pnpm check:skill-frame-sync,pnpm check:single-claim-paths,pnpm check:nul-bytes,pnpm check:doc-authoring,pnpm check:platform-checklist.node scripts/check-release-section-coverage.mjs --strict :: exit 1— the same finding, byte for byte, on the primary checkout atorigin/main21510bba(content/docs/releases/v18/has no heading for the published spec 18.3 series). A release-owned page this diff does not touch; out of scope, not fixed here.pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 3— PREREQUISITE NOT MET (the lint package's built output is absent in a fresh worktree;--ranclassifies the recorded exit 3 as NOT MEASURED). CI builds it; read the PR'sLint & Repo Gatescheck-run for the verdict.Plan Test Core shardsstep — CI's runs on this PR are the readings for those. No package test or typecheck is owed: the diff touches no package.git merge-tree --write-tree HEAD origin/mainclean at every push;origin/mainhas not moved any of the three paths since the branch point.Repeat the two-minute check:
node scripts/pm/check-half-states.mjs --self-test→✓ check-half-states self-test: 5222 cases pass … H74 first-touch audit 60/46.Human Minimum
packages/specholds no runtime logic. (no spec change)main, one pull request..claude/**,scripts/pm/**), soskip-changeset; both declaration lines are above.packages/specnot touched.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01WGufzgjcGBFsSmg6tHbbJq
Generated by Claude Code