Skip to content

pm-dispatch: make close-out debt mechanical — same-round verdict-execution clause, H8 merged-but-dispatched detector, seat-title liveness sweep for the triage Routine #8683

Closed

Description

@hotlong

Filed and dispatched on direct maintainer instruction (2026-08-14, verbatim, untranslated): the maintainer asked whether 「合并即关账」 and 「下班即改贴」 should be codified into the skill; the seat's assessment was that both rules already exist as text and today's failures were execution failures, so the fix is one clause plus two mechanizations; the maintainer ruled 「现在开工派发」. Maintainer-pulled, so it outranks the process-class-last ordering rule.

Measured evidence (one day's worth)

  • Seven pm:seat posts corrected in one day for the same failure: the seat's own stand-down/handover was written in comments while the title stayed 🟢 (registry desync; two of today's corrections were themselves race-error re-corrections).
  • ~13 hotcrm rc-era cards carried explicit "recommends closing" retest comments — some for 9 days — that nobody executed; a 34-row verdict table sat unapplied for 3 days.
  • A theme-seat pre-work audit found five cards whose delivering Part of PR had MERGED with the protocol's paired write (drop pm:dispatched, re-grade the remainder) never made.

Deliverables (three, one PR)

  1. Runbook clause — .claude/skills/pm-dispatch/references/dispatch-runbook.md: a verdict executes in the round that produces it. Writing "recommends closing" (or any re-test verdict) without performing the close/label write in the same round is itself a half-state, on the same footing the half-states family already names — record-and-walk-away is prohibited; if the actor lacks authority to execute, the verdict must name who does and carry the state to their inbox, not sit in a comment. Fit the runbook's existing style; ⛔ no issue numbers in operational text (id-lint).
  2. H8 detector — scripts/pm/check-half-states.mjs: a new report-only half-state: a card's delivering PR is MERGED while the card still carries pm:dispatched. Follow H7's shape (exported predicate + report-only wiring); extend the self-test suite accordingly; keep the existing export pattern so gates can reuse the predicate.
  3. Triage-Routine patrol clause — first establish where the triage Routine's prompt lives: if it is versioned in-repo, patch it; if it is platform-side (trigger config), deliver the exact clause text in the report for the PM to apply. Clause: each patrol, scan pm:seat titles showing 🟢 against the incumbent's own recent activity; a seat silent beyond threshold is demoted to ⏳ vacant with an evidence comment (today's seven hand-corrections are the precedent and the template).

Constraints

  • Surface includes .claude/skills/pm-dispatch/references/** ⇒ fable-mandatory dispatch and ADR-class merge path: draft PR, human merge, auto-merge never armed.
  • SKILL.md untouched (686/686, headroom 0 — nothing in this card needs it).
  • Union of gates runs after the final commit with git rev-parse --short HEAD quoted in the report and PR body, per the contract that landed today.

Activity

  1. self-assigned this
    on Aug 14, 2026
  2. added theissue type on Aug 14, 2026
  3. added
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    on Aug 14, 2026
  4. hotlong commented on Aug 14, 2026

    @hotlong
    ContributorAuthor

    Claim: #8683 — close-out mechanization (maintainer-pulled)

    • Session: session_018WuTtyckQa1VcXwgd52JpN (former skills seat, re-activated for this single card by the maintainer's 「现在开工派发」; the skills lane seat [PM seat] domain:skills — 🟢 os-elon-musk · 由 os-elon-musk 账户的项目负责 #7623 stays ⏳ vacant — this is a one-card special dispatch, not a re-seating)
    • Branch: claude/issue-8683-closeout-mechanization
    • Worktree: dev agent creates its own per-task worktree per os-dev.md
    • Domain: domain:skills (pm-dispatch references + scripts/pm/** tooling)
    • File surface: .claude/skills/pm-dispatch/references/dispatch-runbook.md · scripts/pm/check-half-states.mjs (+ its self-test) · triage-Routine prompt location to be established (in-repo ⇒ in scope; platform-side ⇒ clause text delivered in report)
    • Container & model: os-dev subagent, claude-fable-5 — surface includes .claude/skills/pm-dispatch/references/**, fable-mandatory clause applies (checked against the roots list, not recalled — per the incident this rule now demands)
    • Serial constraints cleared: no open PR touches either file (today's skills-lane PRs all MERGED or closed); SKILL.md untouched so no ratchet interaction; spec-exclusivity boundary not touched (no domain:spec surface)

    ADR-class merge path: draft PR, human merge, auto-merge never armed.


    Generated by Claude Code

  5. hotlong commented on Aug 14, 2026

    @hotlong
    ContributorAuthor
    {
      "issue": 8683,
      "status": "done",
      "branch": "claude/issue-8683-closeout-mechanization",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/8685",
      "premise_still_valid": true,
      "summary": "All three premises verified against origin/main before implementing: (a) no same-round verdict-execution clause existed in dispatch-runbook.md, (b) check-half-states.mjs had H1-H7 only, (c) the triage Routine's prompt location was established rather than assumed — the platform-side prompt is a one-line skill invocation by design (SKILL.md: seat-Routine prompts converge to a skill call, behavior is versioned in git, upgrades go via skill PRs, never by rebuilding the Routine), so the behavior text IS in-repo and no live trigger was touched and no ready-to-paste platform-side clause is needed. Delivered in draft PR 8685 (ADR-class surface, stays draft, human merge): (1) runbook section 「结论当轮执行(维护者 2026-08-14)」 after the decision-recording section — verdict executes in the round that produces it, record-and-walk-away prohibited, an actor lacking authority names who has it and moves the state to their inbox in the same round; (2) H8 in check-half-states.mjs — exported pure predicate h8MergedPrStillDispatched following H7's shape, reusing H7's code-stripped extractors (Part-of / closing-keyword, bound per issue number), report-only wiring over a bounded 2-page window of recently merged PRs with the window boundary documented in the module header; (3) runbook section 「座位贴活性巡查(分诊轮常设项;维护者 2026-08-14)」 — each fire, scan green-titled pm:seat posts against the incumbent's own activity (not inbound notices), silent beyond the existing 24h threshold => demote to vacant, title + assignee in the same stroke, evidence comment required. One coherence edit beyond the two named files: seat-post-protocol.md's lazy-liveness bullet now names both paths (takeover-conflict evaluation + the standing patrol) so the two texts cannot contradict. skip-changeset applied via read-then-union (precedent: the PRs that introduced and last touched this module carry it) and read back confirmed as the full label set.",
      "tests": "Gate union run AFTER the final commit, git rev-parse --short HEAD = 3785d616fa. Derived with node scripts/pm/dispatch-gates.mjs over the actual changed paths; one family surfaced beyond the dispatch prompt's named set and was run: check:partof-closing-keyword (it imports h7PartOfWithClosingKeyword from the edited module). Results: check:pm-half-states self-test 91 cases pass (was 79, +12 H8 cases: positive, out-of-scope label, closed-unmerged not a delivery, per-number binding, backtick strip reuse, prose mention, multi-deliverer, empty/missing window); check:pm-skill-id-lint 9 files clean; check:pm-skill-ratchet SKILL.md 686 lines (ceiling 686, untouched); check:skill-frame-sync 4 copies isomorphic; check:nul-bytes 5725 files clean; check:doc-authoring 377 files clean; check:partof-closing-keyword 28 cases pass; check:doc-formula-expressions clean (22 record-scoped + 9 spec TSDoc examples) after pnpm --filter '@objectstack/formula...' build, run under flock -E 99 -w 540 /tmp/os-heavy-verify.lock. CI gate-job conclusions on the PR were not awaited per the draft-PR-time reporting contract.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  6. hotlong commented on Aug 14, 2026

    @hotlong
    ContributorAuthor

    Supersedes the previous report comment (rework round: maintainer ruling 「8685 字太多了」 — prose compressed in place, same branch, same PR).

    {
      "issue": 8683,
      "status": "done",
      "branch": "claude/issue-8683-closeout-mechanization",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/8685",
      "premise_still_valid": true,
      "summary": "Rework round applied on top of the accepted substance: the two new runbook sections (「结论当轮执行」「座位贴活性巡查」) were cut to roughly half — every normative bullet, ⛔ mark and load-bearing one-liner kept (「表不是交付物,落账才是」 and 「评论不是任何人的收件箱,标签才是」 both survive verbatim), provenance/实测 narratives cut to one line each, the 机械半边 bullet compressed to one line pointing at the script header. seat-post-protocol.md edit left as-is per instruction. H8 module prose trimmed: header narrative 17 -> 10 lines keeping definition + extractor-reuse + bounded-window boundary; predicate JSDoc and window-helper comment tightened; the boundary is now stated exactly twice (header + helper); no test cases or their comments cut (self-test unchanged at 91). References net delta of the PR after compression: +30 lines (dispatch-runbook +28/-0, seat-post-protocol +6/-4); the H8 module is +153/-6. All original deliverables unchanged in substance; PR stays draft, ADR-class, auto-merge never armed; skip-changeset still the full label set. Note: mid-round the shared origin/main ref moved under the worktree (another agent's fetch in the shared .git) — deltas above are measured against the PR's true merge base, and the branch contains exactly the two intended commits.",
      "tests": "Gate union re-run in full AFTER the final commit, git rev-parse --short HEAD = e75de0a890. Families re-derived with node scripts/pm/dispatch-gates.mjs over the actual changed paths (same 7 families; check:partof-closing-keyword remains the addition beyond the dispatch prompt's named set — it imports h7PartOfWithClosingKeyword from the edited module). Results at e75de0a890: check:pm-half-states self-test 91 cases pass; check:pm-skill-id-lint 9 files clean; check:pm-skill-ratchet SKILL.md 686 lines (ceiling 686, untouched); check:skill-frame-sync 4 copies isomorphic; check:nul-bytes 5725 files clean; check:doc-authoring 377 files clean; check:partof-closing-keyword 28 cases pass; check:doc-formula-expressions clean (22 record-scoped + 9 spec TSDoc examples) after pnpm --filter '@objectstack/formula...' build in the recreated worktree, run under flock -E 99 -w 540 /tmp/os-heavy-verify.lock. PR body's verification section updated to quote e75de0a890. CI gate-job conclusions were not awaited per the draft-PR-time reporting contract.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:skillsDomain lane — seat card indexed by label:pm:seat

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions