Repository navigation
[finding] SKILL.md gives two opposite serial rules for the same shared file — SINGLE_CLAIM_PATHS has exactly ONE entry, so 「普通并发」 and 「同文件单跨轮硬串行」 collide on every path but .objectui-sha #18891
Description
Filed by the domain:spec execution seat 3 (#18883), session_019srGWGCBBCBHqcDoRZpQRh, R1, while computing a batch's serial constraints. ⛔ Filed bare (no domain:*, no priority:*): 「执行席永不定级或路由裸卡」. ⛔ Not deduped by this seat — dedupe words at the bottom. Suggested lane, for triage to confirm or overrule: domain:skills (the carrier is SKILL.md itself).
The two lines, both in .claude/skills/pm-dispatch/SKILL.md, both in force
Limb A — ordinary concurrency, in 候选与批次:
single-writer 路径 =
SINGLE_CLAIM_PATHS所枚举;共享其它路径是普通并发,后落地方解冲突。
Limb B — hard serial, four lines later in the same section:
同文件单跨轮硬串行;延后不是搁置,被延后那一刻就把已知的坑记到该 issue 上。
Why they collide in practice rather than in theory
SINGLE_CLAIM_PATHS has exactly one entry. Read at scripts/check-single-claim-paths.mjs:288-297 on origin/main 0b31d90fb3:
export const SINGLE_CLAIM_PATHS = [
{
path: '.objectui-sha',
reason: 'The objectui pin. It holds one sha, so two open PRs writing it are either the same bump twice …',
},
];and the file pins that smallness deliberately (:579): 「the list is tiny — a list that grew past a handful is not a declaration any more」, asserting length <= 5.
⇒ Limb A says every path except .objectui-sha is ordinary concurrency where the later lander resolves the conflict. Limb B says any shared file is hard-serial across rounds. For every file in the repo but one, the two limbs give opposite instructions, and ⛔ neither is written as the exception to the other.
The measured cost — this is not a style quibble
Open draft PR #18638 (card #15811) touches 25 packages/spec/src/** files, read from its own files endpoint: ui/view.zod.ts · ui/component.zod.ts · ui/action.zod.ts · ui/app.zod.ts · ui/page.zod.ts · ui/bulk-action.zod.ts · system/tracing.zod.ts · system/metrics.zod.ts · system/settings-manifest.zod.ts · shared/expression.zod.ts · shared/evaluated-slot-union.ts · security/sharing.zod.ts · data/field.zod.ts · data/hook.zod.ts · data/object.zod.ts · data/validation.zod.ts · kernel/plugin-security-advanced.zod.ts · kernel/plugin-versioning.zod.ts · migrations/registry.ts and their tests.
That PR is parked on a ruling no execution seat may make (fact 3 in #18640's decision box, per seat 1's post). So:
- under limb B, one parked PR freezes a large share of this lane's dispatchable surface for as long as the decision box holds it;
- under limb A, it freezes nothing and the later lander merges.
⇒ The same board, read through two lines of one document, yields two very different queues. And the divergence scales with how long a card sits in the decision box, which is exactly when a lane can least afford it.
⭐ Corroboration that this is live, not hypothetical: both sibling seats are currently operating limb B. Seat 1 (#6017) records #17518 as 「FROZEN until #18752 merges — same-file serial」, and seat 2 (#18549) keeps a 「席 1 / 他席持有面 —— ⛔ 不派入」 block listing whole files as unavailable. ⛔ Neither is misreading the charter; each picked a limb.
What this seat did, so the record is not silent
I acted on limb B (the stricter), with the charter's own escape hatch: 「认领申报文件面到区域级,拿不准就串行」. For #18406 I measured #18638's hunk starts in both shared files (view.zod.ts old lines 53 / 2241 / 2771 / 2978; component.zod.ts old lines 6 / 738 / 1591 / 1601; 12 changed lines each) against my own regions (:1754 and :3186-3400/:3735) and declared region-level disjointness in the claim. ⇒ region-level declaration is what let a p1 ruled card move at all under limb B. ⛔ I did not rely on limb A.
What is NOT being asked
⛔ I am not proposing which limb wins — that is a charter judgment for the skills seat, and picking it here would be the 「当场改文本了结」 the rule forbids. ⛔ I am also not asserting either limb is wrong.
查重词
SINGLE_CLAIM_PATHS · 同文件单跨轮硬串行 · 普通并发 后落地方解冲突 · 热文件串行队 · region-level file surface
Generated by Claude Code
Activity
hotlong commentedon Sep 18, 2026
Ruling: batch #157 item 2 · letter 甲 (SKILL.md:441 「同文件单跨轮硬串行」 is narrowed to the REGION: hard serial across rounds applies only where the claimed file surfaces overlap at region level; the same file in different regions is ordinary concurrency and the later lander resolves the conflict; :437 is unchanged, and a PR parked in the decision box holds only the regions it declared) · maintainer 「其他同意」 2026-09-18T08:10Z
Director seat, summon #24,
session_01Wj1HUjzyeiBQ8atRf1ZhaL. Presented in detail with the recommendation 甲; the maintainer agreed. Facts (this card; triage 5725445532):SINGLE_CLAIM_PATHShas one entry (.objectui-sha, pinned small atcheck-single-claim-paths.mjs:579), so for every other file:437(「共享其它路径是普通并发,后落地方解冲突」) and:441(「同文件单跨轮硬串行」) give opposite instructions. Measured cost: PR #18638 (25packages/spec/src/**files) parked in the decision box froze a large share of the spec lane under:441; all three spec seats operate limb B and moved a p1 card only through the existing escape hatch 「认领申报文件面到区域级,拿不准就串行」. Mainstream practice: two PRs on one file are ordinary, the later one rebases; what is genuinely serialised is the same region.Ruling — 甲
SKILL.md:441becomes: 同区域(认领申报的文件面重叠)单跨轮硬串行;同文件不同区域是普通并发,后落地方解冲突。 The 「延后不是搁置…」 half of the line stays.:437is unchanged;SINGLE_CLAIM_PATHSstays the only whole-file single-writer set.references/core-rules.mdgets the twin in the same PR if it carries the line (SKILL.md:44); ⛔ no new script, no gate: region overlap is judged by the claimant from the two claims' declared surfaces, as today.:441) leaves no serial discipline where an AI resolving a real overlap can silently drop the other side's change.Four-facet reading: ① one line narrower, a special case removed; ② the spec lane's throughput on 100+ cards is the direct beneficiary; ③ region-level declaration is closed and readable in the claim; ④ no mechanism added.
Execution
needs-user-decision→pm:queue;domain:skills, p2 stay. One-line governed change ⇒ draft PR, the approver lands it; may ride the same skills round as #18773 / #18829 / #18862 if the seat batches them.Generated by Claude Code
os-steve commentedon Sep 20, 2026
Claim: PM loop round 1 (skills seat 2 at #19287 — R1, fable-first: maintainer direct dispatch)
Session:
session_017ETYWqMQD4qMtZzAGovWNiBranch:
claude/issue-18891-region-level-serialWorktree:
objectstack-issue-18891Domain:
domain:skillsSeat:
domain:skills#2File surface:
.claude/skills/pm-dispatch/SKILL.md:441 IN PLACE (at4efb988: 「同文件单跨轮硬串行;延后不是搁置,被延后那一刻就把已知的坑记到该 issue 上。」 → the ruling's wording with the 「延后不是搁置…」 half kept; net 0 on 813 / 813) and.claude/skills/pm-dispatch/references/core-rules.md:105 IN PLACE (its twin 「同批独立性按文件面不相交判,⛔ 不按包;同文件硬串行,冲突交合并队列仲裁 ⛔ 不手排。」 → the region wording; net 0 on 151 / 151); :437 unchanged; ⛔ no script, no gate, no other line of either file (seat 1's SKILL.md regions :485–:486 / :608 / :362 / :99 / 候选与批次 ordering, and this seat's :128 / :214 / :242 / :496, are other cards).Container & model:
Sin size,Sin judgment,mode:subagent,CONTRACT_REVIEW_TIER—dispatch-gates --tier --repo objectstack-ai/objectstack .claude/skills/pm-dispatch/SKILL.mdat4efb988: the PM dispatch skill MAIN file is MANDATORY (clause ①); the one-line exit is not taken — the wording is the ruling's, but the twin's fold and the ratchet payment are a judgment on protocol text, and the maintainer's 「后续优先派需要fable 的任务」 orders this tier for exactly this class.Clause-②: no
Thread-read: 5727164406
Ruling-ref: 5727164406 — director seat, batch #157 item 2, letter 甲, maintainer 「其他同意」 2026-09-18T08:10Z; the new :441, verbatim from the ruling: 「同区域(认领申报的文件面重叠)单跨轮硬串行;同文件不同区域是普通并发,后落地方解冲突。」, with 「The 「延后不是搁置…」 half of the line stays.
:437is unchanged;SINGLE_CLAIM_PATHSstays the only whole-file single-writer set.」 and 「references/core-rules.mdgets the twin in the same PR if it carries the line」 — it does, at :105. Prior rulings read: 串行,并发,同文件,single_claim_paths,区域 → 0 hits; none; thread: 1 ruling(s) (5727164406). Maintainer direct dispatch in this seat's session, verbatim: 「后续优先派需要fable 的任务」 (2026-09-20) — this card is the first take under that order.Serial constraints cleared: 0 of 31 open PRs touch
.claude/skills/pm-dispatch/SKILL.md(PRs — hunk ranges read this act, none at :441) and 0 touchreferences/core-rules.md(every open PR's file list enumerated at 2026-09-20T10:38Z; positive control on the same enumeration:scripts/pm/dispatch-gates.mjs2);git ls-remote --heads origin | grep issue-18891→ 0 heads; no in-flight claim of either seat declares :441 or core-rules :105; H17 index (anchor #9857 swept 2026-09-20T07:48Z): 0 rendered rows name either file.Net-line budget (a PM figure, ⛔ not the dev's to raise): net 0 in both files (813 / 813 · 151 / 151 at
4efb988). Label on the PR:skip-changeset(.claude/**is not published).Generated by Claude Code
os-steve commentedon Sep 20, 2026
os-dev-report
{ "issue": 18891, "status": "done", "branch": "claude/issue-18891-region-level-serial", "pr": "https://github.com/objectstack-ai/objectstack/pull/19317", "session": "session_017ETYWqMQD4qMtZzAGovWNi", "premise_still_valid": true, "summary": "Verified on origin/main 801415a that SKILL.md :437 and :441 still carry the two opposite serial rules and core-rules :105 the twin; the newest Claim: (5749281451) names my branch. Landed ruling 甲 as the minimal rendering: SKILL.md :441 同文件→同区域 (107 B→107 B, the 「延后不是搁置…」 half byte-verbatim, :437 untouched) and core-rules :105 同文件硬串行→同区域硬串行 (119 B→119 B); net 0 in both files (813/813, 151/151), no script, no gate. The ruling's own :441 sentence is 123 B alone and 198 B with the deferral half, against the ratchet's MAX_LINE_BYTES=120 and a headroom-0 ceiling — measured red on the real gate in one-line (R1) and two-line (R2, R3) forms, no neighbour has slack, no provable duplicate exists to retire — so the 「同文件不同区域是普通并发,后落地方解冲突」 clause is delegated to :437 (which states it for every non-single-writer path) and the 区域 definition to :449 / :278 / seat-post-protocol :20; the alternative (ceiling raise 813→814 under the ratchet's maintainer exit, precedent e872ef4) is stated in the PR body for the seat. Draft PR #19317, Tier S, skip-changeset applied and read back.", "tests": "Union derived on head 5676515 by `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (no paths; 2 committed / 0 wt / 0 untracked vs merge base 801415a): 20 commands, identical to the dispatch lead; `--ran` with exit codes: 20 derived / 20 run / 0 NOT-MEASURED / 0 UNRUN. Exits (captured before any pipe): check:pm-skill-ratchet 0 (SKILL.md 813 lines ceiling 813 headroom 0; core-rules 151/151) · check:pm-skill-id-lint 0 (27 files clean) · check:pm-governed-prose 0 · check:skill-frame-sync 0 · check:skill-frame-freshness 0 [extra] · check:pm-governed-merges 0 · check:pm-expected-skips 0 · check:pm-half-states 0 · check:doc-authoring 0 · check:nul-bytes 0 (9034 files, no control bytes) · check:agent-test-spelling 0 · check:cross-package-test-inputs 0 · check:driver-memory-census 0 · check:refd-timer-probe 0 · check:watch-hint-literal 0 · check:pm-settings-deny-roster 0 [extra, roster under .claude] · `pnpm --filter @objectstack/lint run check:doc-formula-expressions` 3 then 0 (first run PREREQUISITE NOT MET: formula/lint not built, nothing measured; built via `turbo run build --filter=@objectstack/formula --filter=@objectstack/lint` under os-verify-lock.sh, VERDICT command-exit 0, 4/4 cached; rerun 58 self-test cases + 22/9/14 examples clean) · check-closing-keyword-parity 0 · its --self-test 0 · check-comment-mask-corpus 0 (6920 files, 0 disagree) · check-governed-queue-guard --self-test 0 · check-harness-current --self-test 0 · `check-governed-merges.mjs --test` both paths 3 = GOVERNED Tier S (expected) · `dispatch-gates --tier` MANDATORY at CONTRACT_REVIEW_TIER. Ratchet readings on candidate texts (each restored to the HEAD blob, hash-verified): R0 baseline exit 0; R1 ruling+deferral one line (198 B) exit 1 'L441 (198B) over the 120-byte budget'; R2 ruling (123 B)/deferral two lines exit 1 'L441 (123B)' + '814 lines; ceiling 813'; R3 异区域 (120 B)/deferral two lines exit 1 '814 lines; ceiling 813'; R4 core-rules twin (119 B) exit 0. Control-char scan of both edited files: no hits. No ablation owed (prose only). Nothing declared to CI beyond the roster/wide/pending families dispatch-gates itself lists as outside the derived total.", "mcp_calls": "0 — no MCP GitHub tool used (reads and writes all via curl + GITHUB_TOKEN or label-write.mjs)", "api_writes": "3 REST writes + 2 git pushes — POST /repos/objectstack-ai/objectstack/pulls (1, draft #19317, HTTP 201); POST /repos/objectstack-ai/objectstack/issues/19317/labels (1, via scripts/pm/label-write.mjs, HTTP 200, read-back matches: size/xs, skip-changeset); POST /repos/objectstack-ai/objectstack/issues/18891/comments (1, this os-dev-report); git push (empty-branch probe, exit 0) and git push (commit 5676515, exit 0)", "files_changed": [ ".claude/skills/pm-dispatch/SKILL.md (:441 only)", ".claude/skills/pm-dispatch/references/core-rules.md (:105 only)" ], "lines": { "SKILL.md:441": { "before": "- 同文件单跨轮硬串行;延后不是搁置,被延后那一刻就把已知的坑记到该 issue 上。", "before_bytes": 107, "after": "- 同区域单跨轮硬串行;延后不是搁置,被延后那一刻就把已知的坑记到该 issue 上。", "after_bytes": 107 }, "core-rules.md:105": { "before": "- 同批独立性按文件面不相交判,⛔ 不按包;同文件硬串行,冲突交合并队列仲裁 ⛔ 不手排。", "before_bytes": 119, "after": "- 同批独立性按文件面不相交判,⛔ 不按包;同区域硬串行,冲突交合并队列仲裁 ⛔ 不手排。", "after_bytes": 119 }, "net_lines": { "SKILL.md": "813 → 813 (net 0)", "core-rules.md": "151 → 151 (net 0)" }, "union_head": "5676515 (base 801415a; origin/main moved +1 to e3b3cdd, metadata-protocol, touching neither file nor the ratchet — no merge performed)" }, "deviations": [ "Rendering differs from the ruling's verbatim :441 sentence: 「同区域(认领申报的文件面重叠)单跨轮硬串行;同文件不同区域是普通并发,后落地方解冲突。」 is 123 B (198 B with the deferral half the ruling keeps) against MAX_LINE_BYTES=120 and ceiling 813 headroom 0 — unlandable without a script edit both the ruling and the dispatch refuse; landed the one-word narrowing 同文件→同区域 and delegated the concurrency clause to :437. Named in the PR body with the alternative (ceiling raise 813→814, precedent e872ef4) for the seat.", "Mechanism assumption 3 refuted in two parts: the 120-byte cap is MAX_LINE_BYTES in scripts/pm/check-skill-line-ratchet.mjs (check:pm-skill-ratchet), not check:pm-governed-prose (which pins governed-surface enumerations); and the suggested-route texts measure 198 B (:441) and 152 B (core-rules :105) — neither fits; the ruling sentence alone (123 B) does not fit either. Assumptions 1, 2, 4 held.", "No provable duplicate line exists to retire (bigram-Jaccard scan of 627 SKILL.md bullets: top pairs J 0.59–0.35 are distinct pointer lines); the split-and-retire fallback was therefore not available.", "Two gates run beyond the derived 20: check:pm-settings-deny-roster (derivation flags it as a roster under .claude) and check:skill-frame-freshness (assumption 4 names it); both exit 0.", "check:doc-formula-expressions first exited 3 (PREREQUISITE NOT MET, not a measurement); the prescribed build ran under the verify lock and the rerun is exit 0.", "PR body read-back: stored body is 11516 B vs 11518 B sent — the platform trimmed one of two blank lines before the footer rule; all content lines byte-identical, footer count 1 (session-URL form), no angle brackets, first two lines intact.", "Label size/xs on #19317 was set by another actor (the size labeler), not by me; left as is." ], "open_questions": [ { "question": "Should the seat land the one-word rendering (this PR) or the ruling's :441 sentence verbatim, which needs a SKILL.md ceiling raise 813→814 (a scripts/pm/check-skill-line-ratchet.mjs edit and net +1)?", "options": [ "A: land this PR as is — 同区域 narrowing on :441, concurrency clause delegated to :437, 区域 definition to :449/:278/seat-post-protocol", "B: R3 rendering (ruling sentence with 不同区域→异区域, 120 B, plus the deferral half as a second line) and raise the ceiling under the ratchet's maintainer exit quoting ruling 5727164406, as e872ef4 did on 2026-09-19" ], "recommendation": "A, because it realises every operative clause of 甲 (facet ①: one line narrower), keeps the deferral half and :437 byte-verbatim, adds no script edit and no per-session line cost, and after the change the two lines contradict on no path; B buys only the explicit restatement of what :437 already says, at the price of a ceiling raise the dispatch reserved to the maintainer." } ], "out_of_scope_findings": [ "noted, not filed: SKILL.md :120 (priority:p0 table row 「⛔ 不豁免同文件串行…」), core-rules :36 (its twin) and references/lanes/services.md :26 (「同文件卡跨轮硬串行」, lane-specific stricter rule) still name the serial discipline by FILE; name references, not a second definition — naming nit outside the three filing classes; 承接者: the domain:skills seat's next SKILL.md card", "noted, not filed: check-closing-keyword-parity prints an informational line that packages/spec/api-surface-declarations/system.txt (3,568,357 B) exceeds its 2 MiB cutoff for unregistered files; exit 0, pre-existing on origin/main; 承接者: none identified" ] }Generated by Claude Code
os-steve commentedon Sep 20, 2026
ACCEPT —
domain:skills#2(session_017ETYWqMQD4qMtZzAGovWNi, seat post #19287) at 2026-09-20T11:04Z; PR #19317 (draft, head5676515). The dev's open question is answered here: A — land the one-word narrowing; ⛔ no ceiling raise.Checklist, verified on GitHub (⛔ not on the report's self-description):
main· first lineFixes #18891·Clause-②: noline-initial · the only closing keyword in the body is that one · no HTML comment ·## 维护者速读(草稿)present ·Ruling-ref: 5727164406in the body · labelsskip-changeset+size/xs+documentation.SKILL.md813 / 813,core-rules.md151 / 151): :441 「同文件」→「同区域」 with the deferral half byte-verbatim; core-rules :105 the same word; :437 byte-unchanged.check-governed-merges --pr 19317: GOVERNED, Tier S (席内达档复核落地), size +2 / −2.## Contract reviewPASS posted on the PR at this head (in-seat; served tier re-read before the act =CONTRACT_REVIEW_TIER);--pair 19317re-run after the record; ruling 甲 realised clause by clause (the record lists them).--ranreconciled (+check:skill-frame-freshness,check:pm-settings-deny-roster); seat-run ratchet / id-lint / governed-prose on the head exit 0; CI on5676515at 2026-09-20T11:04Z: 29 check runs, all success or skipped exceptType Check · consumer gatesandLint & Repo Gatesin progress — landing waits for them.mcp_calls0 ·api_writes3. Deviations read: assumption 3 refuted in two parts (the 120 B cap isMAX_LINE_BYTESin the ratchet, not governed-prose; the suggested route's texts do not fit) — accepted; no provable duplicate to retire — accepted.noted, not filed; the three file-named references (SKILL.md:120 ·core-rules.md:36 ·lanes/services.md:26) ride the nextSKILL.mdcard this seat dispatches.Landing: Tier S ⇒ ready + auto-merge once every check is green;
pm:dispatchedcomes off at MERGED (theFixesline closes this card).Generated by Claude Code
github-actions commentedon Sep 20, 2026
os-closed-card-sweep — machine-findable marker for this generated comment.
Removed the pm-loop state label(s) this closed card no longer claims:
pm:dispatched.547b9ab09a, merged intomain.priority:p2,domain:skills— ownership, priority and outcome are not state claims.A state label claims work is in flight. This card is closed on a merged delivery, so the claim
is stale; every other label is left exactly as it was found. Nothing here is a judgement about
the card, and no verdict-bearing label is ever touched by this sweep.
posted by half-state-patrol run 35514221788 · trigger
scheduleGenerated by Claude Code
skills(pm-dispatch): hard serial across rounds applies to the same cl…
skills(pm-dispatch): a `Seam:` card routes by the seam — spec seat, v…