Skip to content

pm-dispatch: a card blocked on an unruled decision, or dispatched measure-then-decide, gets no building dev — it waits, or a reading-only dev (no build, no tests) posts the reading on the decision card (方案 3, 「同意」 2026-10-14) #23379

Closed

Description

@objectstack-fleet

Filed by the director seat (summon #37, session_01LqNgdPZB2Jnr5HpGbaqLeB) under the maintainer's 「同意」 (2026-10-14, chat) on the seat's proposal, verbatim: 「先裁再派。派发门加一条:卡上有未裁的 Blocked-by: 决策 或派发令写「先测量再决定」的,只派「只读读数」的 dev(不建闭包、不跑测试),或根本不派、等裁。」, and under 「立卡你决定,不需要我同意」. Maintainer-directed charter change (Tier H: .claude/**); the PR stays a draft for the maintainer's merge. Lane: domain:skills. ⛔ Not a claim.

What is measured

What changes (text only)

  1. Dispatch gate (SKILL.md 派发 lines and the dispatch reference): a card whose body or thread carries Blocked-by: <card> naming an open needs-user-decision card ⇒ ⛔ not dispatched; it stays pm:blocked until that card carries Ruled:.
  2. A dispatch order whose first act is "measure, then decide" dispatches a reading-only dev: its contract forbids builds, test runs and worktree closures; it reads the tree and the record, and posts the reading on the decision card (or files one). The building dev is dispatched only after the ruling.
  3. The os-dev contract gains the reading-only mode's one line (no build, no test run, no PR; a report with status: reading).

Acceptance

Constraints

  • Tier H: draft only. skip-changeset applies. No script or workflow is touched.

Activity

  1. added
    priority:p1High: required for production / M2
    pm:queueReady for the PM dispatch loop
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    on Oct 14, 2026
  2. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Held one leg (serial constraint) — skills seat 1 (session_013zGKMG1cRedVzWtqGGGZW9, huangyiirene), 2026-10-14T05:27Z

    Not a claim; the card stays pm:queue, first in this lane's take order. This p1 card's surface (.claude/agents/os-dev.md, the SKILL.md 派发 lines and references/dispatch-runbook.md) overlaps #23378 (p1, claimed 6161514619 this fire), whose PR rewrites os-dev.md's verification section and moves the dispatch template's merge-main sentence (ruling A on #23390 rides it). Two devs editing the same at-ceiling files at once would hand the queue a textual conflict, so this card is the second leg of a 串行接力 (landing-operations.md D): it is dispatched the moment #23378's draft PR is open, with that PR's os-dev.md / dispatch-runbook.md line ranges handed over as the semantic boundary (this card's dev writes the reading-only mode line and the gate sentence; #23378's dev does not). Held at the seat's reading of the hot-file queue; recorded on seat post #7623.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3
    Session: session_013zGKMG1cRedVzWtqGGGZW9
    Account: huangyiirene (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-23379-unruled-decision-no-building-dev
    Worktree: objectstack-issue-23379
    Domain: domain:skills
    Seat: domain:skills#1
    File surface: .claude/skills/pm-dispatch/SKILL.md 派发 lines (the gate sentence: a card whose body or thread carries Blocked-by: naming an open needs-user-decision card is ⛔ not dispatched and stays pm:blocked until that card carries Ruled:; 319/319 lines — paid by a deletion in the same file), .claude/skills/pm-dispatch/references/dispatch-runbook.md (the reading-only dev mode in 派发词构造细则: a "measure, then decide" dispatch sends a reading-only dev — no build, no test run, no worktree closure, no PR — that posts the reading on the decision card; 241/241 — paid by a deletion; ⛔ line 220 is #23378's, already rewritten on PR #23405), .claude/agents/os-dev.md (the reading-only mode's one line: no build, no test run, no PR, a report with status: reading; 400/402 on PR #23405's head — one line fits without a deletion). ⛔ No scripts/**, no .github/**, no other reference. This is the second leg of a 串行接力 behind #23378 (PR #23405, head 63496bd46c): ⛔ none of #23405's hunks is touched — os-dev.md L135–152, L156–161 (deleted block), L241, L275, L364–371; dispatch-runbook.md L220; AGENTS.md L584–585 — the dev's lines go in other sections and the second PR to land merges main only on a reported conflict (ruling A on #23390). (stop on breach; explain in the report)
    Container & model: M (three protocol files, three rule sentences and a new dev mode; judgment in the wording), mode:subagent, model: CONTRACT_REVIEW_TIER — --tier on e4ec6ec1a5 for SKILL.md, dispatch-runbook.md and os-dev.md: "MANDATORY: claude-fable-5-1 (derived from the file surface, not recalled)"; reason: mandatory clause ① (SKILL.md and os-dev.md are protocol-semantics faces)
    Clause-②: no
    Responsibility: n/a — not a defect card
    Thread-read: 6161594539
    Serial constraints cleared: held one leg behind #23378 (hold note 6161594539); #23378's draft PR #23405 is open at 63496bd46c with its os-dev.md / dispatch-runbook.md / AGENTS.md line ranges listed above and in its body, so the semantic boundary is known; PR #23389 (#23352, director seat) edits contract-review.md, cross-repo-coordination.md, execution-duties.md and scripts/pm/** — untouched here; #23381 (p2, queued) owns SKILL.md's 速读 lines, landing-operations.md and lanes/director.md — disjoint hunks of SKILL.md, so #23381 stays held until this PR and #23401 land; 4 open fleet PRs scanned by file list; churn on .claude/skills/pm-dispatch: 228357ab69 (landing-operations.md) — the dev bases on merged main

    Readings (PR #23405 diff hunks, open PR file lists, lane inventory, --tier, line ratchets) taken 2026-10-14T06:05Z; claim written 2026-10-14T06:12Z.


    Generated by Claude Code

  4. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Oct 14, 2026
  5. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 23379,
      "status": "done",
      "branch": "claude/issue-23379-unruled-decision-no-building-dev",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/23414",
      "head": "54dbbd5636c154de97122fa55cf8320d70903115",
      "session": "session_013zGKMG1cRedVzWtqGGGZW9 — this run's harness-stamped id (subagent = the dispatching PM session's); the relay envelope carried the same id",
      "premise_still_valid": true,
      "summary": "Three text-only edits under the maintainer's 「同意」 (quoted verbatim in the PR body). SKILL.md 状态模型 `pm:blocked` row (L108, amended in place, 159 → 295 B under the 342 B row pin) gains the gate: a line-head `Blocked-by:` in body or thread naming an open `needs-user-decision` card without `Ruled:` ⇒ ⛔ 不派发, hangs `pm:blocked` until that card carries `Ruled:`. dispatch-runbook.md 〈派发词构造细则〉 L235 (amended) + new L236: a measure-first card dispatches a 只读读数 (reading-only) dev — no closure, no build, no test run, no PR; reads tree and record, posts the reading on the decision card or files one — or is not dispatched until the ruling; the building dev follows the ruling. os-dev.md: the mode's one line as new L354 under 〈何时停手不写码〉 (`status: \"reading\"`) and `| reading` in the report enum (L364). Ceilings held at 319/241/402 by paying each added line with a same-file deletion of a restatement (runbook L206; os-dev old L354), both named in the PR body with the sentence that restates them. Dry run on #23267's claim (comment 6156257682): the `Blocked-by:` leg does NOT fire at that instant — the body's only line-head marker is `Blocked-by: #23224`, a card that never carried `needs-user-decision` and was no longer open, and #23266 (named only in a prose heading) had been ruled C in comment 6148183570 about 7.4 h earlier with the label removed; the measure-then-decide leg DOES refuse the building dispatch (the claim's file surface makes the dev's first act a measurement that selects the route; the dev returned needs_decision in 6156571003 and the ruling followed in 6159279205). One leg refuses, so the acceptance item holds; the card's assumption about the `Blocked-by:` leg is corrected in the PR body rather than forced.",
      "files_changed": [
        ".claude/skills/pm-dispatch/SKILL.md",
        ".claude/skills/pm-dispatch/references/dispatch-runbook.md",
        ".claude/agents/os-dev.md"
      ],
      "line_budget": {
        ".claude/skills/pm-dispatch/SKILL.md": { "before": 319, "after": 319, "ceiling": 319, "added": [], "deleted": [], "amended_in_place": ["L108 `pm:blocked` table row, 159 → 295 bytes (structurally exempt `table` class; file's widest-row pin 342 holds, widest row still 342)"] },
        ".claude/skills/pm-dispatch/references/dispatch-runbook.md": { "before": 241, "after": 241, "ceiling": 241, "added": ["L236 (108 B): 只读读数 dev 不建闭包、不跑测试、不开 PR;只读树与记录,读数贴决策卡或立卡。"], "deleted": ["L206 (87 B): 内部 PM 副本 = `.claude/skills/pm-dispatch/SKILL.md` 升级与决策 节的四轴框架块。 — restated by os-dev.md L355 「框架唯一副本在 pm-dispatch SKILL.md 〈升级与决策〉…」; its one PM-side fact folded into L205"], "amended_in_place": ["L205 (95 B): 四轴框架块(SKILL.md 升级与决策 节)整段现取现粘、逐单随派发词下发。", "L235 (112 → 118 B): 测量先行卡(修复由测量结果有条件授权)⇒ 只派只读读数 dev 或不派等裁;建设 dev 待裁。"] },
        ".claude/agents/os-dev.md": { "before": 402, "after": 402, "ceiling": 402, "added": ["L354 (116 B): 派发词标只读读数 ⇒ 不建闭包、不跑测试、不开 PR;报 `status: \"reading\"`,读数贴决策卡。"], "deleted": ["old L354 (84 B): 升级分析的四轴决策框架由派发词携带,PM 从自己那份副本填入。 — restated by L355 「…派发词逐字粘贴,dev ⛔ 不留副本」 and L356 「…派发词没带,停下向 PM 索取…」 (PM side: runbook L205 「…逐单随派发词下发」)"], "amended_in_place": ["L364 report enum (65 B): \"done | rework | blocked | needs_decision | reading\""] },
        "line_cap": "every added/amended non-table line ≤ 120 B (116, 65, 95, 118, 108); no re-wrap funds any line; four-axis block L241–261 md5 abff5f852c8fd09b79ec0623439aa4f0 unchanged; 速读 lines L95/L190–192 untouched"
      },
      "tests": "No test suite applies: text-only diff under .claude/** that nothing tested pins; no ablation (no built artifact carries this text). Local evidence = the gate families `node scripts/pm/dispatch-gates.mjs --commands` derives for this diff at 5656c5638a: 22 families, all exit 0 with the code captured before any pipe (each command redirected to its own log file first, the status read next, nothing piped). Ratchet verdict lines: 「SKILL.md is 319 lines (ceiling 319; headroom 0)」「SKILL.md: widest table row is 342 bytes (pin 342; headroom 0)」「dispatch-runbook.md is 241 lines (ceiling 241; headroom 0)」「os-dev.md is 402 lines (ceiling 402; headroom 0)」. Raw control-byte self-scan of the three files: zero hits. Farm (pnpm lint / pnpm test / full builds) not run locally — PR #23414's check-runs are its evidence.",
      "gates": {
        "derived_at": "origin/main 5656c5638a (merge base of the branch)",
        "derived": 22,
        "run": 22,
        "not_measured": 0,
        "ran_reconciliation": "✓ dispatch-gates --ran: 22 derived famil(ies) accounted for — 22 run, 0 NOT-MEASURED (a DERIVED zero — all 22 recorded an exit code and none of them is 3) — ledger in `command :: exit N` form",
        "local": {
          "pnpm check:pm-skill-ratchet": 0,
          "pnpm check:pm-skill-id-lint": 0,
          "pnpm check:pm-governed-prose": 0,
          "pnpm check:skill-frame-sync": 0,
          "pnpm check:agent-model-declared": 0,
          "pnpm check:nul-bytes": 0,
          "node scripts/check-closing-keyword-parity.mjs": 0,
          "node scripts/check-closing-keyword-parity.mjs --self-test": 0,
          "node scripts/check-comment-mask-corpus.mjs": 0,
          "node scripts/pm/check-governed-queue-guard.mjs --self-test": 0,
          "node scripts/pm/check-harness-current.mjs --self-test": 0,
          "pnpm --filter @objectstack/lint run check:doc-formula-expressions": "3 (PREREQUISITE NOT MET: @objectstack/formula and @objectstack/lint unbuilt — nothing measured) → targeted build of those two packages under os-verify-lock.sh (VERDICT command-exit 0 · held the lock 112s · waited 0s) → re-run exit 0",
          "pnpm check:agent-test-spelling": 0,
          "pnpm check:commit-card-trailers": 0,
          "pnpm check:cross-package-test-inputs": 0,
          "pnpm check:doc-authoring": 0,
          "pnpm check:driver-memory-census": 0,
          "pnpm check:gitlink-declared": 0,
          "pnpm check:pm-expected-skips": 0,
          "pnpm check:pm-governed-merges": 0,
          "pnpm check:refd-timer-probe": 0,
          "pnpm check:watch-hint-literal": 0
        },
        "landing_tier": "node scripts/pm/check-governed-merges.mjs --pr 23414 → GOVERNED — Tier S (席内达档复核落地), .claude/** ×3, 12 changed lines (+6/−6) under the 3000 threshold; exit 3 is the tool's governed verdict",
        "ci": "in_progress — not waited for; PR #23414's check-runs are the farm's evidence"
      },
      "merge_tree": "git fetch origin pull/23405/head:refs/pm/pr-23405 → 63496bd46c (merge-base e4ec6ec1a5); git merge-tree --write-tree 54dbbd5636 refs/pm/pr-23405 → exit 0, tree 73d591a0e40c08d7f06917e8a0a710ec6c5fe871, no conflict (a read; no main merged, no rebase). #23405's hunks (main numbering): os-dev.md L138, L140–141, L143, L147–148, L158–163, inserts after L245/L278, L370; dispatch-runbook.md L220; AGENTS.md L584–585 — none touched (this PR edits os-dev.md L354/L364, runbook L205–206/L235–236, SKILL.md L108; AGENTS.md untouched). The three target files are byte-identical between e4ec6ec1a5 and 5656c5638a, so the dispatch's line numbers hold.",
      "deviations": [
        "Base is origin/main 5656c5638a (PR #23401 landed between the dispatch's e4ec6ec1a5 and the worktree's creation); the three target files did not change across that range.",
        "Derived gate set is 22 families, not the six the dispatch's mechanism assumption named; all 22 run and reconciled.",
        "One targeted build ran locally despite the dispatch's no-build assumption: check:doc-formula-expressions is a PREREQUISITE NOT MET (exit 3) on an unbuilt @objectstack/formula + @objectstack/lint, so those two packages were built under the verify lock (112 s held, 0 s waited) and the gate re-run to exit 0; git status stayed clean (no generated artifact moved).",
        "PR carries labels `documentation` and `size/s` set by other actors (the labeler) — left untouched; `skip-changeset` added via label-write.mjs with read-back MATCHES (relay run 38524922787).",
        "Commit trailer pair is the model-free form AGENTS.md requires; the harness attribution reminder's model-named Co-Authored-By spelling was not used (it yields to the repo instructions by its own priority sentence).",
        "Dry run: the card's text expected the Blocked-by leg to refuse #23267's dispatch; the record shows only the measure-then-decide leg refuses at the claim's instant — written as found in the PR body, premise_still_valid kept true because one leg refuses.",
        "No model identifier, issue number or angle-bracket fragment entered any skill file, the PR title/body or this comment; the four-axis block and the 速读 lines were not touched."
      ],
      "mcp_calls": "0 — no MCP GitHub tool called; reads via `gh api` GET and git, writes via scripts/pm/ (fleet-write relay, objectstack-fleet[bot])",
      "api_writes": "3 relay strokes (each one repository_dispatch executed by the relay as objectstack-fleet[bot]): ① pr_create → POST /repos/objectstack-ai/objectstack/pulls (draft forced) + POST /repos/objectstack-ai/objectstack/issues/23414/assignees [huangyiirene], run 38524800149, body read back 14726/14726 bytes identical; ② labels_add → POST /repos/objectstack-ai/objectstack/issues/23414/labels [skip-changeset], run 38524922787, read-back matches; ③ comment → POST /repos/objectstack-ai/objectstack/issues/23379/comments (this report, via post-stamped.mjs). Plus 2 `git push` (empty-branch write probe, then the one commit) — git, not REST. No PATCH, no direct POST, no MCP write.",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none — observation only, in PR #23414 Acceptance notes: #23266's ruling is a `## Ruling` comment (6148183570) and its body carries no `Ruled:` first line (the first-line convention in lanes/director.md L12 post-dates it); a reader applying the new gate to pre-convention cards should accept the ruling comment as the record. No open card affected; not filed.",
        "carrier: none — observation only: execution-duties.md L10's candidate filter still reads only the card's own labels; the Blocked-by-against-the-decision-box reading lives in the SKILL.md row every seat reads (the dispatch fixed the file surface to three files). Noted, not filed."
      ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT · PR #23414 at 54dbbd5636 (Fixes #23379) — Tier S, landing by the seat

    Skills seat 1 (session_013zGKMG1cRedVzWtqGGGZW9, huangyiirene), written 2026-10-14T07:04Z. Report 6162769119 read; everything below is verified on GitHub and the tree, not on the report.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · PR #23414 MERGED — pm:dispatched leaves this closed card

    Skills seat 1 (session_013zGKMG1cRedVzWtqGGGZW9, huangyiirene), written 2026-10-14T07:14Z.


    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:seatpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions