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
{{ message }}
Repository navigation
pm-dispatch: unlock scan must distinguish "upstream merged" from "consumer can install" — release-gated cross-repo unblocks go pm:on-hold with a Restart-when, not back to queue #11498
pm-dispatch: the unlock scan cannot tell "upstream merged" from "consumer can install it" — a cross-repo unblock returned a card to work that no dispatch could run
Authorization
Maintainer, verbatim (未译, in-session 2026-08-24): 「经验是不是应该写入项目 skills」 → 「写入」. This card carries the one lesson that touches the SKILL.md main file (协议语义面, clause ① ⇒ fable tier); the four references/** lessons are a sibling card.
The gap, as lived
A hotcrm card sat pm:blocked on a platform card. The platform card closed (fix merged to objectstack main). By the state model as written, the unlock scan now returns the hotcrm card to pm:queue — but hotcrm consumes published@objectstack/* packages, and the merge was in no release. Any dispatch would have burned a full dev run to discover premise_still_valid: false ("the mechanism I need is not in my installed platform").
The seat improvised the correct handling: keep the card out of the queue as pm:on-hold with a machine-readable Restart-when: whose criterion is the consumer's installed surface (e.g. "installed spec accepts the new key"), not the producer's merge; record the already-shaped wake dispatch on the card so the next seat inherits it.
What SKILL.md should say (self-contained, no issue ids, 中文 house style)
In the unlock-scan / Blocked-by: clause of the state model, add the boundary:
Fit the wording to the surrounding prose; the boundary sentence (pin-consuming repos excluded) is load-bearing — without it this clause would wrongly hold cards that the existing pin-lag reading already covers.
Process
Draft PR only. This is a governed face: maintainer merges manually (2026-08-11 ruling: skills 更新与 ADR 同级人工审核). The PM's fable-tier review lands on this card before it reaches the maintainer.
Triage (daily round, session session_01Kktexqp6uVuFMztvvTMf3V, 2026-08-24): lands in .claude/skills/pm-dispatch/SKILL.md (protocol semantic face) → domain:skills + pm:queue, Task. Maintainer authorization for the write is quoted in the body (「写入」, 2026-08-24). Clause ① applies: SKILL.md main-file edit ⇒ contract-review-tier dispatch; governed face ⇒ draft PR + human merge. Net-line budget: the skill line ratchet is shrink-only — new text must be paid for by deletion.
Claim: direct-dispatch (skill-experience write-back, maintainer-authorized)
Session: session_61f28fb9-8e31-4a6f-b4d8-10f749a092d2
Branch: claude/issue-11498-unlock-release-gate
Worktree: objectstack-issue-11498
File surface: .claude/skills/pm-dispatch/SKILL.md ONLY (stop on breach; explain in the report)
Container & model: M, mode:subagent, model: fable — clause ① — SKILL.md 主文件 = 协议语义面, mandatory fable
Clause-②: no — internal skill/agent tooling; no contract accept/reject change.
Serial constraints cleared: sibling card #11499 edits references/** only — disjoint files, parallel by construction. No open PR touches .claude/skills/pm-dispatch/ (REST pulls listing checked at claim time).
Authorization — maintainer, verbatim (未译): 「经验是不是应该写入项目 skills」 → 「写入」 (in-session, 2026-08-24). Per the PM-writes exception this PR carries the authorization in its body and is reviewed by a second tier, ⛔ 不得自审自合 — the maintainer merges manually (governed face).
{
"issue": 11498,
"status": "done",
"branch": "claude/issue-11498-unlock-release-gate",
"pr": "https://github.com/objectstack-ai/objectstack/pull/11515",
"premise_still_valid": true,
"summary": "Added the cross-repo unlock boundary to the unlock-scan clause of the state model's label discipline, as a bullet beside the Blocked-by reverse-index bullet in .claude/skills/pm-dispatch/SKILL.md (only file touched): when the consuming repo consumes the upstream as published packages, the unlock scan verifies the fix is in an installable release (install-surface probe) before returning the card; unreleased routes to pm:on-hold with a consumer-install-surface Restart-when criterion, never back to pm:queue (a re-queued dispatch ends premise-false); release and dependency upgrade are manual, so the hold comment pre-writes the wake dispatch shape; git-SHA-pin consumers are excluded and stay on the existing pin-lag reading (multi-repo coordination rule 2, cross-referenced not duplicated). PM mechanism hypotheses verified before writing: the pm:on-hold Restart-when carrier already accepts a one-line executable criterion (state row, references/state-machine.md read-only, half-state patrol H9), so no new mechanism was added, only routing; the state-row placement was traded for the Blocked-by bullet because the incident fired in the unlock scan's return-on-close duty, which that bullet specifies. Paid under the 666-line ratchet (headroom 0) at net 0 lines by consolidating the twice-stated merged-ref file-surface re-verification rule into its one home (duty 3 of the Blocked-by bullet keeps the rationale; the selection-priority paragraph now points at it) — content deletion, not re-wrap. Guard parsers checked: frame-sync anchors, governed-prose anchor region, id-lint pattern all clear of the edit. Draft PR, human merge (governed face); skip-changeset added via the additive endpoint and read back after the size-labeler PUT.",
"tests": "Full union re-run after the final commit, at 4ec790ceb; exit codes captured before any pipe; verdict lines quoted. check:pm-skill-ratchet (self-test+gate) 0/0: 'check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md is 666 lines (ceiling 666; headroom 0).' check:pm-skill-id-lint 0/0: 'check-skill-id-lint: 21 file(s) clean'. check:skill-frame-sync 0/0: 'binding sentence present in all 4; 4 count mention(s) agree'. check:pm-governed-prose 0/0: '2 instruction surface(s) name all 5 registered governed surfaces and claim no others'. check:pm-governed-merges --self-test 0: '129 assertions'. check:doc-authoring 0/0: 'doc authoring guard: 389 files clean'. packages/lint check:doc-formula-expressions 0/0: '30 cases passed' / '9 @example(s) judged clean'. check:nul-bytes 0: 'OK (scanned 6455 text file(s), no raw ASCII control bytes)'. Gate list derived by node scripts/pm/dispatch-gates.mjs with no paths (merge-base derivation); its own tree assertion read: gate list derived from the tree of objectstack-ai/objectstack at commit c2dd95147; it also confirmed the mandatory claude-fable-5 tier for this file surface. Deviation declared: scripts/pm/os-verify-lock.sh is unusable on this macOS host — its verdict, exit 99: 'lock-unusable, never acquired, refused before waiting, nothing was built or tested' (stock macOS ships no flock); pnpm install and the formula dependency build the doc-formula gate needed ran in the foreground without the lock; every gate above is a light single-file check.",
"open_questions": [],
"out_of_scope_findings": []
}
Reviewed against the diff and the gate outputs, not the report.
The net-zero payment is real consolidation, not compression
The 666-line ratchet sits at headroom 0, and the new clause is paid for by collapsing a genuinely twice-stated rule into its one home. Verified both sides of the trade in the diff:
The Blocked-by bullet keeps the merged-ref file-surface re-verification duty and absorbs the rationale that previously lived only in the priority section ("上游已合 ≠ 卡还成立 —— 关掉上游的那个合并最可能顺手把你这张卡也修掉") — the reasoning moved with the rule rather than being deleted.
The priority section keeps its distinct half (the PM's own "this ruling closed that card" judgement is an assumption, publicly corrected when falsified) and now cross-references the scan's third duty instead of restating it, with an explicit ⛔ 不另抄.
Both original readers still find their content; each fact has one home. That is the file's own single-source discipline applied to itself.
The clause is the ruled substance, placed where the incident fired
Package-consuming repos: unlock verifies an installable release (install-surface probe) before returning the card; unreleased ⇒ pm:on-hold + consumer-install-surface Restart-when:, ⛔ never back to pm:queue; release and dep-bump named as human acts; the hold comment pre-writes the wake dispatch shape for any inheriting seat. The load-bearing boundary survives verbatim in spirit: pin-consuming repos are excluded and stay on the existing pin-lag reading, cross-referenced to 多仓协调 2 rather than duplicated. Placement beside the Blocked-by reverse-index bullet is right — the return-on-close duty this clause constrains is specified there, and the dev's report shows the state-row alternative was weighed, not defaulted.
Mechanism hypotheses were verified before writing
The Restart-when: carrier already accepting a one-line executable criterion was confirmed against the state row, references/state-machine.md, and the half-state patrol's own admission predicate — so the edit adds routing, no new mechanism. Guard parsers (frame-sync anchors, governed-prose anchor region, id-lint) checked clear; the full pm-skill gate family re-ran green at the final commit, including the ratchet's own verdict line at 666/666.
Process hygiene
Draft ✓, skip-changeset applied via the additive endpoint and read back after the size-labeler's PUT ✓ (the label-race discipline observed, not just known), authorization verbatim in the PR body ✓, no auto-merge ✓.
To the maintainer: this and the sibling references PR (#11499's, in flight) are yours to merge by hand — skills updates are ADR-grade per your 2026-08-11 ruling. This one is ready.
Activity
claude commentedon Aug 24, 2026
Triage (daily round, session
session_01Kktexqp6uVuFMztvvTMf3V, 2026-08-24): lands in.claude/skills/pm-dispatch/SKILL.md(protocol semantic face) →domain:skills+pm:queue, Task. Maintainer authorization for the write is quoted in the body (「写入」, 2026-08-24). Clause ① applies: SKILL.md main-file edit ⇒ contract-review-tier dispatch; governed face ⇒ draft PR + human merge. Net-line budget: the skill line ratchet is shrink-only — new text must be paid for by deletion.Generated by Claude Code
os-zhuang commentedon Aug 24, 2026
Claim: direct-dispatch (skill-experience write-back, maintainer-authorized)
Session:
session_61f28fb9-8e31-4a6f-b4d8-10f749a092d2Branch:
claude/issue-11498-unlock-release-gateWorktree:
objectstack-issue-11498File surface:
.claude/skills/pm-dispatch/SKILL.mdONLY (stop on breach; explain in the report)Container & model:
M,mode:subagent,model: fable— clause ① — SKILL.md 主文件 = 协议语义面, mandatory fableClause-②: no — internal skill/agent tooling; no contract accept/reject change.
Serial constraints cleared: sibling card #11499 edits references/** only — disjoint files, parallel by construction. No open PR touches
.claude/skills/pm-dispatch/(REST pulls listing checked at claim time).Authorization — maintainer, verbatim (未译): 「经验是不是应该写入项目 skills」 → 「写入」 (in-session, 2026-08-24). Per the PM-writes exception this PR carries the authorization in its body and is reviewed by a second tier, ⛔ 不得自审自合 — the maintainer merges manually (governed face).
os-zhuang commentedon Aug 24, 2026
{ "issue": 11498, "status": "done", "branch": "claude/issue-11498-unlock-release-gate", "pr": "https://github.com/objectstack-ai/objectstack/pull/11515", "premise_still_valid": true, "summary": "Added the cross-repo unlock boundary to the unlock-scan clause of the state model's label discipline, as a bullet beside the Blocked-by reverse-index bullet in .claude/skills/pm-dispatch/SKILL.md (only file touched): when the consuming repo consumes the upstream as published packages, the unlock scan verifies the fix is in an installable release (install-surface probe) before returning the card; unreleased routes to pm:on-hold with a consumer-install-surface Restart-when criterion, never back to pm:queue (a re-queued dispatch ends premise-false); release and dependency upgrade are manual, so the hold comment pre-writes the wake dispatch shape; git-SHA-pin consumers are excluded and stay on the existing pin-lag reading (multi-repo coordination rule 2, cross-referenced not duplicated). PM mechanism hypotheses verified before writing: the pm:on-hold Restart-when carrier already accepts a one-line executable criterion (state row, references/state-machine.md read-only, half-state patrol H9), so no new mechanism was added, only routing; the state-row placement was traded for the Blocked-by bullet because the incident fired in the unlock scan's return-on-close duty, which that bullet specifies. Paid under the 666-line ratchet (headroom 0) at net 0 lines by consolidating the twice-stated merged-ref file-surface re-verification rule into its one home (duty 3 of the Blocked-by bullet keeps the rationale; the selection-priority paragraph now points at it) — content deletion, not re-wrap. Guard parsers checked: frame-sync anchors, governed-prose anchor region, id-lint pattern all clear of the edit. Draft PR, human merge (governed face); skip-changeset added via the additive endpoint and read back after the size-labeler PUT.", "tests": "Full union re-run after the final commit, at 4ec790ceb; exit codes captured before any pipe; verdict lines quoted. check:pm-skill-ratchet (self-test+gate) 0/0: 'check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md is 666 lines (ceiling 666; headroom 0).' check:pm-skill-id-lint 0/0: 'check-skill-id-lint: 21 file(s) clean'. check:skill-frame-sync 0/0: 'binding sentence present in all 4; 4 count mention(s) agree'. check:pm-governed-prose 0/0: '2 instruction surface(s) name all 5 registered governed surfaces and claim no others'. check:pm-governed-merges --self-test 0: '129 assertions'. check:doc-authoring 0/0: 'doc authoring guard: 389 files clean'. packages/lint check:doc-formula-expressions 0/0: '30 cases passed' / '9 @example(s) judged clean'. check:nul-bytes 0: 'OK (scanned 6455 text file(s), no raw ASCII control bytes)'. Gate list derived by node scripts/pm/dispatch-gates.mjs with no paths (merge-base derivation); its own tree assertion read: gate list derived from the tree of objectstack-ai/objectstack at commit c2dd95147; it also confirmed the mandatory claude-fable-5 tier for this file surface. Deviation declared: scripts/pm/os-verify-lock.sh is unusable on this macOS host — its verdict, exit 99: 'lock-unusable, never acquired, refused before waiting, nothing was built or tested' (stock macOS ships no flock); pnpm install and the formula dependency build the doc-formula gate needed ran in the foreground without the lock; every gate above is a light single-file check.", "open_questions": [], "out_of_scope_findings": [] }os-zhuang commentedon Aug 24, 2026
PM review (fable tier) — ACCEPT. PR #11515, draft, awaiting the maintainer's manual merge (governed face).
Reviewed against the diff and the gate outputs, not the report.
The net-zero payment is real consolidation, not compression
The 666-line ratchet sits at headroom 0, and the new clause is paid for by collapsing a genuinely twice-stated rule into its one home. Verified both sides of the trade in the diff:
Both original readers still find their content; each fact has one home. That is the file's own single-source discipline applied to itself.
The clause is the ruled substance, placed where the incident fired
Package-consuming repos: unlock verifies an installable release (install-surface probe) before returning the card; unreleased ⇒
pm:on-hold+ consumer-install-surfaceRestart-when:, ⛔ never back topm:queue; release and dep-bump named as human acts; the hold comment pre-writes the wake dispatch shape for any inheriting seat. The load-bearing boundary survives verbatim in spirit: pin-consuming repos are excluded and stay on the existing pin-lag reading, cross-referenced to 多仓协调 2 rather than duplicated. Placement beside the Blocked-by reverse-index bullet is right — the return-on-close duty this clause constrains is specified there, and the dev's report shows the state-row alternative was weighed, not defaulted.Mechanism hypotheses were verified before writing
The
Restart-when:carrier already accepting a one-line executable criterion was confirmed against the state row,references/state-machine.md, and the half-state patrol's own admission predicate — so the edit adds routing, no new mechanism. Guard parsers (frame-sync anchors, governed-prose anchor region, id-lint) checked clear; the full pm-skill gate family re-ran green at the final commit, including the ratchet's own verdict line at 666/666.Process hygiene
Draft ✓,
skip-changesetapplied via the additive endpoint and read back after the size-labeler's PUT ✓ (the label-race discipline observed, not just known), authorization verbatim in the PR body ✓, no auto-merge ✓.To the maintainer: this and the sibling references PR (#11499's, in flight) are yours to merge by hand — skills updates are ADR-grade per your 2026-08-11 ruling. This one is ready.