You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This card is the single authoritative registration for the domain:spec-tooling seat (program card #5163). Index = label:pm:seat; entry point #4604.
Single-writer rule: only the incumbent seat PM edits this body; takeover = edit body + one audit comment. Before taking over: re-fetch the body, audit-comment timestamps arbitrate (first wins), read back after writing.
Current PM
GitHub account: os-help — ⚠️shared with other active sessions; the account does not identify the seat, the session ID in the claim comment does.
Session: session_01KJATVrh6V2ysutYUJigh3B · Took over 2026-08-10T01:2xZ from session_01AZgRyPVwi1jLb1mNNuUQ9o.
⛔ READ FIRST — the skill you just loaded may be STALE (standing condition)
/pm-dispatch loads SKILL.md from the shared checkout (/home/user/objectstack), whose HEAD is set by whatever agent touched it last. Measured stale four separate times today (09:5x, 14:51, 15:5x, 17:0x) — at one point 5 commits / +283−219 behind, and three of those commits changed rules this seat was actively using. Nothing warns you.
Non-empty ⇒ read git show origin/main:.claude/skills/pm-dispatch/SKILL.md. Same for references/compile-surfaces.md / references/incidents.md.
Protocol refresh (current as of 2026-08-10 ~17:0xZ)
Three-tier model: sonnet / opus / fable, explicit every dispatch, recorded in the claim comment. ⛔ Mandatory: any card touching .claude/skills/pm-dispatch/** is claude-fable-5.
Lane pm:queue unassigned: 0 — live at 17:0xZ. ⚠️ Refilled six times this shift. ⛔ Never report from cache.
⚠️#7217 and #7220 are the same family — #7217 added visibility-predicate-over-budget at ~04:xxZ; #7220 (17:5xZ) then had to move six ids, not the four its body names. A card filed against a rule family goes stale the moment that family gains a member. Re-count the family at dispatch time.
⚠️ Open for the maintainer
[finding] content/docs/references/contracts/ 是一个只剩 meta.json 的空目录,build-docs.ts 已不再产出它 #7303 — the ruling's premise does not hold and its action cannot land as written. Ruled "residue — delete" because "build-docs.ts's category table has no contracts entry". Measured: no category table exists (:127 = fs.readdirSync); content/docs/references/** is merge=os-regen (declared generated output); category-title.ts:75 declares the category and resolveCategoryTitles throws on a title with no directory. A delete-only PR reds check:docs; gen:docs restores it byte-for-byte. A = guard the meta.json emit on pages.length > 0 (mirroring build-docs.ts:849) — the delete then happens at the generator, permanently. B = leave the generator, fix the quick-reference row's now-false prose. Premises carry per-line re-check commands on the card (refreshed 15:5xZ); one drifted — packages/spec/src/contracts/ went 82 → 84 files, which strengthens B slightly. Claimed + assigned so no other seat spends a dev on it.
⚠️ Report to #6015 — a grade whose stated basis is falsified
#7181 was graded observation-class because "all three are check-only — none writes a tracked artifact". False: check-dual-source-exports.ts --updaterewrites the tracked baseline, so on a stale dist it launders a wrong ratchet exactly as #7122 did. Fix landed, so re-grading is moot; the point is the reasoning must not be inherited by the next card of this family without checking for an --update-shaped path. ⛔ Reported, not re-graded.
Findings produced this session (unassigned; grading is #6015's)
#7170 (fixed as #7354) · #7181 (unblocked + merged) · #7175 (transferred → PR #7235) · #7297 (transferred) · #7330 (fixed elsewhere) · #7373 (CEL defaultValue stores a raw Date) · #7412 (check-half-states.mjs live sweep unusable in a PM container) · #7465 (gate section ↔ cli.mdx disagree in 3 places).
Scope
Protocol toolchain / gates / generators + docs (#5163). Surface: scripts/**, packages/spec/scripts/**, packages/spec/docs/**, packages/lint/**, content/docs/** (⛔ never content/docs/releases/). ⛔ Never packages/spec/src/**/*.zod.ts or the strictness-ledger counts artifact. ⚠️ The runtime gate's dispatch side is packages/metadata* — another seat's; this lane owns the registry declaration in packages/lint (#7220 measured that declaring is sufficient, so no transfer was needed). devx boundary = #5469.
Patrol worktree at current main: /home/user/objectstack-pm-patrol (detached).
Standing disciplines
㉔ per-path history before EVERY dispatch · ㉕ disclose scope expansion · ㉖ report after push · ㉗ re-dispatch briefs measure THAT card's residue · ㉙ verify landing by content on a fresh ref · ㉚ a comment contradicting its PR body is a residual defect · ㉛ label provenance guesses as guesses · ㉜ a scanner must prove it can see before any zero is believed · ㉝ premise checks read origin/main · ㉞ never undraft on a webhook alone · ㉟ a positive control must be word-boundary exact · ㊱ a primitive you recommend must be measured against THIS consumer · ㊲ keep PM guesses out of the ruling block · ㊳ resolving a blocker is not dispatching the card · ㊴ "queue drained" has a shelf life of minutes · ㊵ name the obvious wrong fix and the dev builds the test for it · ㊶ line anchors go stale — anchor on text.
㊷ — a card can supply the fix and still never have measured it. Make the fix's own probe the accept bar (#7244).
㊸ — before dispatching ANY "delete this residue" card, establish WHO WRITES THE FILE.grep os-regen .gitattributes + run the generator. #7303 went four honest readings deep on one wrongly-scoped grep. Correct grep output from the wrong file reads exactly like proof.
㊹ — never wait on a background timer for CI; poll and report. Also protocol (#6644 L2).
㊺ — pm:blocked without a body Blocked-by: is a card parked with no exit. Unlock scan has two criteria: ① has the line ⇒ check upstream, then re-verify the file face on the merged ref; ② has none ⇒ that is itself the anomaly. ⚠️And check the upstream rather than trusting a cached line — #7220's blocker #4717 had closed six hours before anything said so; the standby criterion that said "re-verify rather than trust" is what turned a quiet standby into round 10.
㊻ — a card's SEVERITY GRADE rests on premises as falsifiable as its defect claim. When a grade is argued, put its load-bearing premise into the dispatch as a PM 机制假设 (#7181).
㊼ — a comment sitting next to the code is not a reading of the code, and the ones inside the file you are auditing are the most dangerous.#7442: runtime-gate.ts's own header comment listed a rule among those running on a flow snapshot; that rule never reads stack.flows — probed, zero errors. #7220 produced two more instances in one hour: my own grep returned runtimeTypes: ['permission_set'/'sharing_rule'] that live inside surfaceReason prose strings (\' escaping the only tell), and the dev found validateVisibilityPredicates carrying RUNTIME_NEEDS_FULL_SNAPSHOT — a reason describing nothing true about it, "the reason a rule got when nobody measured". ⇒ In a registry of self-describing entries, the descriptions are the least trustworthy field.
㊽ (new) — a card filed against a rule FAMILY goes stale the moment the family gains a member.#7220's body names four views[] visibility-predicate rules; by dispatch time the family was six ids across two registry entries — visibility-predicate-over-budget had been added by this same lane (#7217) hours earlier. The dev counted them rather than trusting the body, and flagged why the sixth carried no partial-enforcement risk. ⇒ For any "move/retire/audit this family" card, re-enumerate the family at dispatch time and put the count in the brief; a family card that moves N−1 members is the exact defect such cards exist to prevent.
Environment
Fresh container. In-flight zero at 18:0xZ (wave-close point). Standby cadence. ⛔ Every other entry in list_triggers belongs to another seat.
This card is the single authoritative registration for the
domain:spec-toolingseat (program card #5163). Index =label:pm:seat; entry point #4604.Single-writer rule: only the incumbent seat PM edits this body; takeover = edit body + one audit comment. Before taking over: re-fetch the body, audit-comment timestamps arbitrate (first wins), read back after writing.
Current PM
os-help—session_01KJATVrh6V2ysutYUJigh3B· Took over 2026-08-10T01:2xZ fromsession_01AZgRyPVwi1jLb1mNNuUQ9o.⛔ READ FIRST — the skill you just loaded may be STALE (standing condition)
/pm-dispatchloadsSKILL.mdfrom the shared checkout (/home/user/objectstack), whose HEAD is set by whatever agent touched it last. Measured stale four separate times today (09:5x, 14:51, 15:5x, 17:0x) — at one point 5 commits / +283−219 behind, and three of those commits changed rules this seat was actively using. Nothing warns you.Non-empty ⇒ read
git show origin/main:.claude/skills/pm-dispatch/SKILL.md. Same forreferences/compile-surfaces.md/references/incidents.md.Protocol refresh (current as of 2026-08-10 ~17:0xZ)
sonnet/opus/fable, explicit every dispatch, recorded in the claim comment. ⛔ Mandatory: any card touching.claude/skills/pm-dispatch/**isclaude-fable-5.mode:cloud; only S-grade mechanical staysmode:subagent.<!-- os-dev-report -->first, return message second.pm:queueat dispatch without applyingpm:dispatched— 7 instances of the ghost-card shape; pick the repair #7239). Rule 1 = file-at-destination (SKILL amendment: issues live where the fix lands — narrow the repo:* transfer lane to seam cards, adopt file-at-destination filing #7165). Release board = two queries.Ledger (18:0xZ)
Merged: 15 · In flight: 0 · In queue: 0 · Held for decision: 1 · Rework: 0 · Empty dispatch: 0 · Premise falsified: 1
target:v17lib/dist-freshness.tsPart of, did NOT close the cardvisibility-predicate-over-budget123b6c6bf7900527dff0ac3e47145cd354ec— gate table's 4th column; first cloud card333769d86—views[]visibility family → runtime-publish, whole family in one editpm:blockedon #7297 (domain:spec) — ⛔ stays OPENLane⚠️ Refilled six times this shift. ⛔ Never report from cache.
pm:queueunassigned: 0 — live at 17:0xZ.visibility-predicate-over-budgetat ~04:xxZ; #7220 (17:5xZ) then had to move six ids, not the four its body names. A card filed against a rule family goes stale the moment that family gains a member. Re-count the family at dispatch time.content/docs/references/contracts/是一个只剩meta.json的空目录,build-docs.ts 已不再产出它 #7303 — the ruling's premise does not hold and its action cannot land as written. Ruled "residue — delete" because "build-docs.ts's category table has nocontractsentry". Measured: no category table exists (:127=fs.readdirSync);content/docs/references/**ismerge=os-regen(declared generated output);category-title.ts:75declares the category andresolveCategoryTitlesthrows on a title with no directory. A delete-only PR redscheck:docs;gen:docsrestores it byte-for-byte. A = guard themeta.jsonemit onpages.length > 0(mirroringbuild-docs.ts:849) — the delete then happens at the generator, permanently. B = leave the generator, fix the quick-reference row's now-false prose. Premises carry per-line re-check commands on the card (refreshed 15:5xZ); one drifted —packages/spec/src/contracts/went 82 → 84 files, which strengthens B slightly. Claimed + assigned so no other seat spends a dev on it.@examplestrings (#6763) #7180's ruling-stretch; refactor(tooling): shard the ADR-anchor registry one file per anchor #7301's no-aggregate deviation.#7181 was graded observation-class because "all three are check-only — none writes a tracked artifact". False:
check-dual-source-exports.ts --updaterewrites the tracked baseline, so on a stale dist it launders a wrong ratchet exactly as #7122 did. Fix landed, so re-grading is moot; the point is the reasoning must not be inherited by the next card of this family without checking for an--update-shaped path. ⛔ Reported, not re-graded.Findings produced this session (unassigned; grading is #6015's)
#7170 (fixed as #7354) · #7181 (unblocked + merged) · #7175 (transferred → PR #7235) · #7297 (transferred) · #7330 (fixed elsewhere) · #7373 (CEL
defaultValuestores a rawDate) · #7412 (check-half-states.mjslive sweep unusable in a PM container) · #7465 (gate section ↔cli.mdxdisagree in 3 places).Scope
Protocol toolchain / gates / generators + docs (#5163). Surface:⚠️ The runtime gate's dispatch side is
scripts/**,packages/spec/scripts/**,packages/spec/docs/**,packages/lint/**,content/docs/**(⛔ nevercontent/docs/releases/). ⛔ Neverpackages/spec/src/**/*.zod.tsor the strictness-ledger counts artifact.packages/metadata*— another seat's; this lane owns the registry declaration inpackages/lint(#7220 measured that declaring is sufficient, so no transfer was needed).devxboundary = #5469.Operational facts
method: , enabled at) held as "armed but NOT enqueued" for 13 consecutive PRs, then broke twice in a row — docs(deployment): give the "gate" table its fourth column — the runtime publish surface (#7442) #7458 and feat(lint): move the views[] visibility-predicate family to the runtime publish gate (#7220) #7479 both enqueued on the firstenablewith the same empty receipt. On feat(lint): move the views[] visibility-predicate family to the runtime publish gate (#7220) #7479 the queue read completely empty immediately before the enqueue notice arrived, which under the old reflex reads as "flip now". ⇒ Afterenable, read the queue branch (or wait for the enqueue notice) BEFORE deciding to flip. ⛔ No reflexdisable→enable.disable_pr_auto_mergealone does NOT eject a queued PR — measured on docs(deployment): give the "gate" table its fourth column — the runtime publish surface (#7442) #7458 (disabled 13:54Z, still queued 14:19Z, merged 14:20Z). Only a draft conversion ejects.skip-changesettiming, measured both ways: late (docs(protocol): correct the two wrongdefaultValuesamples in schema.mdx #7376) ⇒ red, then a freshlabeledrun flipsunstable→cleanbut the failed run stays forever; applied while the gate is stillin_progress(fix(spec): check:dual-source-exports / check:exported-any / check:skill-examples refuse a stale dist (#7181) #7421, docs(deployment): give the "gate" table its fourth column — the runtime publish surface (#7442) #7458) ⇒ green first time.Check Changesetgreen on its own merits).dispatch-gates.mjsoutput WITH its invocation scope (pnpm --filter @objectstack/lint run check:…). It emits family names; ~half are package-scoped and a bare name is not runnable — docs: the "the gate" table has no fourth column for the runtime publish surface (#4463 P1 shipped one) #7442's dev reasonably concluded the gate did not exist and skipped it.lint.yml— 76check:*families across 23 workflow files.api.github.comunreachable here —GITHUB_TOKENis a 14-charprox…placeholder; 403 either way.check-half-states.mjslive mode cannot run (--self-test16/16 does; [finding]scripts/pm/check-half-states.mjslive sweep cannot run in a PM session container — direct api.github.com is 403 with or without the token, and the docblock's "unauthenticated works" is false here #7412).dispatch-gates.mjs/check-skill-line-ratchet.mjswork.create_sessionrejects apermission_modeabove the parent's — omit to inherit.docs/adr/**PR #6741). Read the file list before undrafting./home/user/objectstack-pm-patrol(detached).Standing disciplines
㉔ per-path history before EVERY dispatch · ㉕ disclose scope expansion · ㉖ report after push · ㉗ re-dispatch briefs measure THAT card's residue · ㉙ verify landing by content on a fresh ref · ㉚ a comment contradicting its PR body is a residual defect · ㉛ label provenance guesses as guesses · ㉜ a scanner must prove it can see before any zero is believed · ㉝ premise checks read
origin/main· ㉞ never undraft on a webhook alone · ㉟ a positive control must be word-boundary exact · ㊱ a primitive you recommend must be measured against THIS consumer · ㊲ keep PM guesses out of the ruling block · ㊳ resolving a blocker is not dispatching the card · ㊴ "queue drained" has a shelf life of minutes · ㊵ name the obvious wrong fix and the dev builds the test for it · ㊶ line anchors go stale — anchor on text.㊷ — a card can supply the fix and still never have measured it. Make the fix's own probe the accept bar (#7244).
㊸ — before dispatching ANY "delete this residue" card, establish WHO WRITES THE FILE.
grep os-regen .gitattributes+ run the generator. #7303 went four honest readings deep on one wrongly-scoped grep. Correct grep output from the wrong file reads exactly like proof.㊹ — never wait on a background timer for CI; poll and report. Also protocol (#6644 L2).
㊺ —⚠️ And check the upstream rather than trusting a cached line — #7220's blocker #4717 had closed six hours before anything said so; the standby criterion that said "re-verify rather than trust" is what turned a quiet standby into round 10.
pm:blockedwithout a bodyBlocked-by:is a card parked with no exit. Unlock scan has two criteria: ① has the line ⇒ check upstream, then re-verify the file face on the merged ref; ② has none ⇒ that is itself the anomaly.㊻ — a card's SEVERITY GRADE rests on premises as falsifiable as its defect claim. When a grade is argued, put its load-bearing premise into the dispatch as a PM 机制假设 (#7181).
㊼ — a comment sitting next to the code is not a reading of the code, and the ones inside the file you are auditing are the most dangerous. #7442:
runtime-gate.ts's own header comment listed a rule among those running on a flow snapshot; that rule never readsstack.flows— probed, zero errors. #7220 produced two more instances in one hour: my own grep returnedruntimeTypes: ['permission_set'/'sharing_rule']that live insidesurfaceReasonprose strings (\'escaping the only tell), and the dev foundvalidateVisibilityPredicatescarryingRUNTIME_NEEDS_FULL_SNAPSHOT— a reason describing nothing true about it, "the reason a rule got when nobody measured". ⇒ In a registry of self-describing entries, the descriptions are the least trustworthy field.㊽ (new) — a card filed against a rule FAMILY goes stale the moment the family gains a member. #7220's body names four
views[]visibility-predicate rules; by dispatch time the family was six ids across two registry entries —visibility-predicate-over-budgethad been added by this same lane (#7217) hours earlier. The dev counted them rather than trusting the body, and flagged why the sixth carried no partial-enforcement risk. ⇒ For any "move/retire/audit this family" card, re-enumerate the family at dispatch time and put the count in the brief; a family card that moves N−1 members is the exact defect such cards exist to prevent.Environment
Fresh container. In-flight zero at 18:0xZ (wave-close point). Standby cadence. ⛔ Every other entry in
list_triggersbelongs to another seat.