Repository navigation
docs(pm-dispatch): split a card that straddles an unreachable repository by repository (ruling D) - #24712
Conversation
…ory by repository (ruling D) cross-repo-coordination.md lines 50-51 now carry the maintainer's letter D: a card with a part in a repository its lane cannot reach is split by repository at filing or first touch; that part is filed by a reaching seat or parked here under domain:cloud + status:parked; this card keeps only its own repository's work and does not read the other; when it cannot be split, that repository's prerequisite card is filed first; the dependent card goes pm:blocked + Blocked-by: owner/repo#N. The old line 51 (unreachable target = reading gap) is replaced, and the old line 50 (waiter flips pm:blocked + Blocked-by:) is folded into the new line 51. Line-neutral at the file's 51-line ceiling. Claude-Session: https://claude.ai/code/session_01HEdP5tPhqQfzwRmKDxwn85 Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewRendered 2026-10-20T01:29Z · isolated reviewer at Served-tier: Inputs read: card #24591's body and all 5 comments (seat delta 6279626277, ruling 6279888513, serial note 6280214060, claim 6280787852, os-dev-report 6281048362); PR #24712's body, file list (1 path) and net diff against ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
维护者速读(终稿)· PR #24712 ·
|
Fixes #24591
Clause-②: no
Ruled: letter D, ruling record
6279888513(director seat, batch #373 item 3, 2026-10-19T23:48Z). The maintainer's two sentences, verbatim:What the ruling binds, items 1-3 verbatim. Items 4 and 5 are already on
main: item 4 is the reading definition in AGENTS.md, and item 5 is the decision-card rule in SKILL.md. They are not restated here.repo:cloudlane card, filed by a seat that reaches cloud (the filer, when it is the cloud seat; otherwise the objectstack seat asks through the cross-repo request path — a comment on the cloud seat post naming the step, or parking the cloud part in this repository underdomain:cloud+status:parkedfor the cloud PM to migrate); the objectstack part stays in its lane and carries only what objectstack needs. Neither lane reads the other repository.」pm:blockedwithBlocked-by: objectstack-ai/cloud#Nand returns to its queue when that card closes (the unlock scan's cross-repo spelling; where the cloud part ships through a pin, the consumer-installable test applies).」The workload line, verbatim:
「skills lane · 1 Tier S text PR:
cross-repo-coordination.mdL51's rule becomes the split / prerequisite rule above (one or two lines, line-neutral at the file's ceiling);reading-discipline.mdL17 unchanged · precedent PR #24521 (+2/−2).」What changed: two lines in one file, no net lines
The file is
.claude/skills/pm-dispatch/references/cross-repo-coordination.md, lines 50-51. Base is8e14ce057, which wasorigin/mainat dispatch. It already carries line 37 from PR #24691. Head isad5a10688. Byte counts are of the whole line, with the leading list marker included and the newline left out. The cap isMAX_LINE_BYTES = 120(scripts/pm/check-skill-line-ratchet.mjs). The file stays at 51 lines against a ceiling of 51.pm:blocked+Blocked-by:指向请求卡;⛔ 不设新标签新 sweep。」domain:cloud+status:parked。」pm:blocked+Blocked-by: owner/repo#N。」reading-discipline.mdline 17 is unchanged, as the workload line requires.How the two lines map onto the ruling:
domain:cloud+status:parked.pm:blocked+Blocked-by: owner/repo#N. That is the generic spellingstate-machine.md:23defines for the ruling'sobjectstack-ai/cloud#N.pm:blocked+Blocked-by:指向请求卡」. It points the same way as item 2, so it is folded into new line 51'spm:blocked+Blocked-by:clause. Old line 51 is the rule the ruling replaces.What the 240 bytes could not carry, and the text on
mainthat already carries itTwo lines at 120 bytes each cannot hold every clause of items 1-3 plus old line 50. These clauses are left to text already on
main:SKILL.md:108, thepm:blockedrow (released by the unlock scan).SKILL.md:137-141, which says 「跨仓解锁判据是消费方可安装」 and that pin-consumed repositories read pin lag.SKILL.md:269「受阻执行卡同笔挂pm:blocked+Blocked-by:」 andSKILL.md:142「状态变更不过夜」.domain:cloud,status:parked,pm:blocked,Blocked-by:). The state model holds the rest:SKILL.md:136「一个标签存在当且仅当有具名读者」, andstate-machine.md:26「⛔ 不设新标签」.Reader check: who reads
Blocked-by: owner/repo#N, item 2's cross-repo spellingThis was read on this branch's tree; no script is changed here.
state-machine.md:23defines the spelling: 「正典标记 = 行首Blocked-by: #N(跨仓owner/repo#N)」.scripts/pm/check-half-states.mjsparses it.blockedByTargets(line 3744) collects an optionalowner/repoor barerepoqualifier before each#N. H4's presence test accepts any value, so a cross-repo-only line counts as present.buildBlockingIndex(line 3797) skips cross-repo refs on purpose, because it asks which local card is waiting. H19 does resolve cross-repo targets (blockerTargetKey, line 4814), but only when the target repository answers the install's own repo-scoped token. Otherwise it reports the block UNJUDGED as a loud row. The header (line 61) says so: "cross-repoBlocked-by:targets stay unresolvable per install (each token reads its own repo), so H19 reports them as UNJUDGED — accepted, and made loud separately."scripts/ci/scheduled-full-run.mjs, driven byscheduled-full-run-card.yml, readsBlocked-by:only on the hourly full-run card it refreshes. It never releases that card on a closed cross-repo target (workflow header, line 52).scripts/pm/sweep-closed-cards.mjshas noBlocked-by:reader. It matches zero times, case-insensitive, for "blocked". It only strips residue state labels from cards that are already closed.dispatch-runbook.md:72says 「逐仓state=CLOSED+since与Blocked-by:反向索引求交」.Conclusion: the spelling is defined and parsed, and no reader refuses it. What no script does from this repository's install is judge whether a cloud target has closed: H19 reports it UNJUDGED and leaves it to a seat. Under the new rule, a seat therefore releases an objectstack card blocked on a cloud card by hand. That seat is one that reads cloud, or one that acts on a reaching seat's quotation. This is the ruled per-install credential limit the script's header names, not a defect. It is recorded under Acceptance notes and not filed.
Acceptance notes
objectstack-ai/cloud#Nclosed". The release rests on a seat: the triage seat's per-repo unlock scan, or a reaching seat's comment on the waiting card. Carrier: none. This is a standing, accepted limit and not a defect to file.301 Moved Permanentlyon a single-card REST read today (2026-10-20). The ruling record and this card's body name objectstack-ai/cloud#3089 as its address. The redirect was not followed, because this lane does not read cloud.Verification, on head
ad5a10688node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived the change set from merge base8e14ce057: 1 path, +2/-2. It derived 17 commands, the same 17 as the dispatch order. All 17 were run on the head, with exit codes captured before any pipe:node scripts/check-closing-keyword-parity.mjs→ exit 0node scripts/check-closing-keyword-parity.mjs --self-test→ exit 0node scripts/check-comment-mask-corpus.mjs→ exit 0node scripts/pm/check-harness-current.mjs --self-test→ exit 0pnpm --filter @objectstack/lint run check:doc-formula-expressions→ exit 0pnpm check:agent-test-spelling→ exit 0pnpm check:cross-package-test-inputs→ exit 0pnpm check:doc-authoring→ exit 0pnpm check:driver-memory-census→ exit 0pnpm check:gitlink-declared→ exit 0pnpm check:nul-bytes→ exit 0pnpm check:pm-governed-merges→ exit 0pnpm check:pm-skill-id-lint→ exit 0pnpm check:pm-skill-ratchet→ exit 0pnpm check:refd-timer-probe→ exit 0pnpm check:skill-frame-sync→ exit 0pnpm check:watch-hint-literal→ exit 0pnpm --filter @objectstack/lint run check:doc-formula-expressionsfirst exited 3 (PREREQUISITE NOT MET:@objectstack/formulaand@objectstack/lintwere not built). That run measured nothing. Both packages were then built throughscripts/pm/os-verify-lock.sh(VERDICT command-exit 0, turbo cache hit), and the rerun exited 0.--ranreconciliation over the exit-coded record: "Run reconciliation — 17 derived, 17 run, 0 NOT-MEASURED, 0 UNRUN." It ended with "✓ dispatch-gates --ran: 17 derived famil(ies) accounted for — 17 run, 0 NOT-MEASURED (a DERIVED zero ...)".pnpm check:pm-settings-deny-rosterexited 0 (the derivation flags its roster as living under.claude), andpnpm check:pm-governed-proseexited 0..claude/**, and the dev contract excludes docs from ablation.Landing
Tier S: every path is under
.claude/**. The PR stays draft. The seat flips it ready and queues it after an isolatedCONTRACT_REVIEW_TIERreview PASS on this head, with every check green. The PR carriesskip-changesetbecause.claude/**publishes nothing from any released package. Precedent: PR #24521 (+2/-2).维护者速读(草稿)
cross-repo-coordination.md第 50–51 行),内容是您 10-19 裁的 D。一张卡如果有一半落在本车道读不到的仓(今天是 cloud),立卡或第一次接手时就按仓拆开。那一半有两条去路:由能读 cloud 的席位在 cloud 立卡,或在本仓挂domain:cloud+status:parked停放,等 cloud PM 迁走。本仓这张卡只留本仓的活,两边都不读对方的仓。拆不开的,先在 cloud 车道立前置卡,本仓卡挂pm:blocked+Blocked-by:等它。文件行数不变(51/51)。Blocked-by:的写法,但判断不了 cloud 那张卡关没关:它报 UNJUDGED,交给席位人工判断。这是既有裁定下的凭据边界,不是这次新出的问题。回滚就是 revert 这一个 commit。Generated by Claude Code