Repository navigation
Description
Filing gate ③: a task the maintainer directed. In the triage seat's session (session_01AavokzJ5DndAwitDXvKy4U), 2026-10-10, the maintainer said, verbatim: 「以后总监决裁的时候还应该适当评估开发工作量。」 ("From now on, when the director rules, the development workload should also be appropriately assessed.") It was said while asking why ADR-0131's C2 (#15196) grew so large: 17 merged PRs, about +16k / −1.3k lines, with four stages still open. Filed by the triage seat (seat post #6015). ⛔ Not a claim.
Reader: the domain:skills seat. These are governed files (.claude/**), so the change lands with the maintainer's approval (Tier H).
What is missing today
The decision framework weighs four axes: long-term soundness, real business pull, AI-error resistance, and no scope spread at the startup stage. It also asks for an "options × real cost" table. But "cost" is defined as what the customer feels, not what it takes to build:
.claude/skills/pm-dispatch/references/decision-analysis.md:25: "选项 × 真实代价表:每选项一行,做什么 + 客户可感知的后果"..claude/skills/pm-dispatch/references/lanes/director.md:23: the presentation's three elements are "问题、选项与代价", from the business side..claude/skills/pm-dispatch/SKILL.md, the four-axis block (about:240–:268): no axis or row asks how much each option costs to build.
So a ruling can pick a letter without anyone stating that it means, for example, 15 stages across four lanes against one change in one lane.
The change
-
Each option in a decision card states its development workload:
- the lanes it touches;
- the number of stages or PRs;
- a size from measured precedent, meaning comparable landed PRs, named. ⛔ Not a guess. If there is no precedent, it says so.
- It sits in the options × cost table as its own column.
-
The director's presentation (
lanes/director.md) carries the same column. The ruling record states the chosen option's workload. -
How workload weighs ("适当"): the skills seat proposes this, and the maintainer approves it in the governed PR. The proposal must say how it sits beside two existing rules:
- "长远合理性权重恒 ≥50%";
- "②③④ 只调时序分期 ⛔ 不翻字母".
For example: workload is always shown. A large gap (say ≥ 3×) between options whose long-term readings are close must be named in the recommendation. Whether workload may ever change the letter, rather than only the staging, is for the maintainer to approve.
-
The os-dev escalation copy of the framework (
dispatch-runbook.md:205–:206,os-dev.md:354) moves with it, so a dev'sneeds_decisionanalysis carries the same column.
Done when
The three files (and the dispatch copy) carry the workload column and the weighing rule. The next decision card filed after landing shows it.
Dedupe: MCP search_issues on this repo, decision card workload estimate development effort director ruling options cost: 0 hits.
Activity
objectstack-fleet commentedon Oct 10, 2026
Claim: PM loop round 1
Session:
session_01RdnZdPZH9ByduzPRWuH9tNAccount:
marchtian(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-22597-decision-workload-columnWorktree:
objectstack-issue-22597Domain:
domain:skillsSeat:
domain:skills#1File surface:
.claude/skills/pm-dispatch/SKILL.md(the four-axis block at:241–:261and the 升级与决策 lines around it; 319/319 — every added line is paid by a deleted one),.claude/skills/pm-dispatch/references/decision-analysis.md(50/50; the options × cost table line:25and the 四棱 block),.claude/skills/pm-dispatch/references/lanes/director.md(63/72; the presentation's three elements at:23); only if the pointer lines must move,.claude/skills/pm-dispatch/references/dispatch-runbook.md:205–:206and.claude/agents/os-dev.md:354–:356;scripts/check-skill-frame-sync.mjsandscripts/check-skill-frame-freshness.mjsonly if the frame's anchors must follow the edited block (⛔ no new gate, no weakened gate). Nothing else (stop on breach; explain in the report)Container & model:
M, design on a governed Tier S surface (.claude/**) whose weighing rule the maintainer asked to approve,mode:subagent,model: CONTRACT_REVIEW_TIER—dispatch-gates --tier --repo objectstack-ai/objectstackat86da194919prints "Model tier — MANDATORY: … .claude/skills/pm-dispatch/SKILL.md ⇢ '.claude/skills/pm-dispatch/SKILL.md' — clause ① of the model-tiering ruling (narrowed to protocol semantics, 2026-08-20) … .claude/agents/os-dev.md ⇢ '.claude/agents/os-dev.md' — clause ① (2026-08-20 narrowing)"Clause-②: no
Responsibility:
n/a — not a defect cardThread-read: none
Serial constraints cleared:
none— no open PR touches.claude/**(14 open PRs' file lists read at 2026-10-10T08:27Z); #22452 (queued;platform-readings.mdand the ratchet'sCEILINGSrow) is file-disjoint and not dispatched this roundLanding: every path is Tier S, but the card's item 3 asks the maintainer to approve the weighing rule, so the PR takes the four-piece terminal set (draft, 维护者速读, review requested) and lands only on an authorized APPROVED review. File surface read at
origin/main86da194919; claim written at 2026-10-10T08:46Z.objectstack-fleet commentedon Oct 10, 2026
os-dev-report
{ "issue": 22597, "status": "done", "branch": "claude/issue-22597-decision-workload-column", "pr": "https://github.com/objectstack-ai/objectstack/pull/22654", "session": "session_01RdnZdPZH9ByduzPRWuH9tN", "premise_still_valid": true, "summary": "Three governed files (all Tier S, .claude/**) now carry the workload column and the weighing proposal; the four-axis block in SKILL.md 241-261 is byte-identical (md5 abff5f852c8fd09b79ec0623439aa4f0 before and after), so workload is a column in the options table and a line in the recommendation, not a fifth axis. decision-analysis.md: the table line becomes 选项 × 真实代价 × 工作量表 (four columns in the order the newest cards already render); a new line defines 工作量 = 车道 · 阶段/PR 数 · 实测先例 (named landed PR with +/- line counts) or 无先例, ⛔ 不猜; the staging rule reads ②③④ 与工作量只调时序分期 ⛔ 不翻字母; a new weighing line states the proposal (always listed per option; ① readings near one another with a ≥3× workload gap must be named in the recommendation; the letter flips only on the maintainer's own ruling on the card); paid line for line by deleting two restatements (the language-exception pointer, already carried by the file's scope line and SKILL.md's invariants; the facet-section tail line restating the template's recommendation/self-check items). director.md: the ruling record states the chosen letter's workload read from the card's column; the presentation's cost column always carries the workload column beside it. SKILL.md: one line re-spelled in place under the 120-byte cap so a decision card carries 工作量列. Card item 4 reading: dispatch-runbook.md 205-206 and os-dev.md 354-356 are name pointers (section name + declaring/binding sentence), the block did not move, check:skill-frame-sync anchors on those sentences — no pointer breaks, neither file edited. Residual noted (not a pointer break, outside the dispatched surface): os-dev.md:353 asks the dev for unqualified 成本; a one-line in-place rewording carrying the triple measures 145 bytes against the 120-byte cap, so it would cost a deletion in a 402/402 file. Both reference cards render the table as a markdown table and #22621 already carries the 工作量 column and its ruling record already states the chosen option's workload, so the codified shape is the one in use.", "tests": "No package code touched (prose-only under .claude/**): no package test/typecheck owed (① dependency closure empty, ② none). Battery at 1e39518d6 (NODE_OPTIONS=--max-old-space-size=4096; every exit captured by redirect-then-$?): 23 commands = the 20 derived by `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` with no paths (change set from merge base cc305a3cf: 3 files, +7/−5) plus check:agent-model-declared and check:skill-frame-freshness (dispatch-named) and check:pm-settings-deny-roster (the derivation flags its roster under .claude). 22 of 23 exit 0 on the first run; `pnpm --filter @objectstack/lint run check:doc-formula-expressions` exited 3 = PREREQUISITE NOT MET (@objectstack/formula and @objectstack/lint unbuilt — nothing measured), so `bash scripts/pm/os-verify-lock.sh -c 'pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint --concurrency=2'` (VERDICT command-exit 0 · held the lock 1s · waited 0s; 4/4 turbo cache hits) and the re-run exited 0: '✓ check:doc-formula-expressions self-test: 61 cases passed', '22 record-scoped formula example(s) across 471 files / 1387 TS blocks judged clean'. `--ran` reconciliation with exit codes recorded: '✓ dispatch-gates --ran: 20 derived famil(ies) accounted for — 20 run, 0 NOT-MEASURED (a DERIVED zero — all 20 recorded an exit code and none of them is 3)'. Verdict excerpts: check:pm-skill-ratchet '.claude/skills/pm-dispatch/SKILL.md is 319 lines (ceiling 319; headroom 0)', 'decision-analysis.md is 50 lines (ceiling 50; headroom 0)', 'lanes/director.md is 65 lines (ceiling 72; headroom 7)'; check:pm-skill-id-lint '34 file(s) clean (pattern /#[0-9]{3,}/g)'; check:skill-frame-sync 'the one declared copy of the decision frame is internally coherent'; check:skill-frame-freshness 'current with origin/main (fetched just now)'; check:pm-governed-prose '2 instruction surface(s) name all 6 registered governed surfaces'; check:agent-model-declared '1 agent definition(s) under .claude/agents/ all declare a model'; check:nul-bytes self-test 75 assertions, plus a control-character grep over the three files: 0 hits; check-closing-keyword-parity 'OK (3 parsers agree on all 9 keywords …)' and its --body mode over the PR body: only 'Fixes #22597' binds. Changed-line bytes 120/118/119/113/120/84/119, all ≤ the 120-byte cap; SKILL.md lines 241–261 md5 abff5f852c8fd09b79ec0623439aa4f0 before and after (block untouched). NOT MEASURED: CI's type-check lanes, the 53 artifact-roster families and 11 wide-population families (CI-owned, no local invocation); `pnpm lint` not run (repo-wide, CI-owned; no .ts/.js touched). Ablation: none owed — prose-only change, no gate, script or test edited.", "mcp_calls": "0 — no MCP GitHub tool called; reads were single-card REST GETs via gh api (issues 22597, 22453, 22621 and their comments)", "api_writes": "2 — REST writes, both through the fleet-write relay as objectstack-fleet[bot]: ① POST /repos/objectstack-ai/objectstack/pulls (pr_create, draft) → #22654, relay run 38040426501, read-back 9460/9460 bytes identical; ② POST /repos/objectstack-ai/objectstack/issues/22597/comments (this os-dev-report, via post-stamped). Not REST: git push ×2 to origin claude/issue-22597-decision-workload-column (empty-branch probe at cc305a3c, then commit 1e39518d6). label-write on #22654 (POST .../issues/22654/labels [skip-changeset] + POST .../issues/22654/assignees [marchtian]): 0 requests sent — refused by the session's permission classifier before any request; see deviations.", "open_questions": [], "out_of_scope_findings": [ "carrier: skills seat (this PR's reviewer) · noted, not filed — os-dev.md:353 asks a needs_decision dev for 「选项、成本与你的推荐」 with 成本 unqualified; the workload column's definition reaches a dev only through the PM's dispatch prompt. Not a pointer break; a one-line in-place rewording measures 145 B against the 120 B cap, so it costs a deletion in a 402/402 file — outside this card's surface. Written in the PR body's item-4 section and Acceptance notes.", "carrier: none (observation, no class) · noted, not filed — #22621 (filed 2026-10-10 before this rule) already renders 选项 × 真实代价 × 开发工作量 as a four-column markdown table and its ruling record already states the chosen option's workload 'as the rule requires'; this PR codifies that shape." ], "gates": [ { "command": "node scripts/check-closing-keyword-parity.mjs", "exit": 0, "seconds": 2 }, { "command": "node scripts/check-closing-keyword-parity.mjs --self-test", "exit": 0, "seconds": 3 }, { "command": "node scripts/check-comment-mask-corpus.mjs", "exit": 0, "seconds": 88 }, { "command": "node scripts/pm/check-governed-queue-guard.mjs --self-test", "exit": 0, "seconds": 1 }, { "command": "node scripts/pm/check-harness-current.mjs --self-test", "exit": 0, "seconds": 5 }, { "command": "pnpm --filter @objectstack/lint run check:doc-formula-expressions", "exit": 3, "seconds": 1, "note": "exit 3 = PREREQUISITE NOT MET (@objectstack/formula and @objectstack/lint unbuilt; nothing measured); built them under os-verify-lock.sh (VERDICT command-exit 0) and re-ran", "rerun_exit": 0 }, { "command": "pnpm check:agent-test-spelling", "exit": 0, "seconds": 3 }, { "command": "pnpm check:cross-package-test-inputs", "exit": 0, "seconds": 30 }, { "command": "pnpm check:doc-authoring", "exit": 0, "seconds": 6 }, { "command": "pnpm check:driver-memory-census", "exit": 0, "seconds": 4 }, { "command": "pnpm check:gitlink-declared", "exit": 0, "seconds": 1 }, { "command": "pnpm check:nul-bytes", "exit": 0, "seconds": 3 }, { "command": "pnpm check:pm-expected-skips", "exit": 0, "seconds": 5 }, { "command": "pnpm check:pm-governed-merges", "exit": 0, "seconds": 8 }, { "command": "pnpm check:pm-governed-prose", "exit": 0, "seconds": 1 }, { "command": "pnpm check:pm-skill-id-lint", "exit": 0, "seconds": 1 }, { "command": "pnpm check:pm-skill-ratchet", "exit": 0, "seconds": 1 }, { "command": "pnpm check:refd-timer-probe", "exit": 0, "seconds": 11 }, { "command": "pnpm check:skill-frame-sync", "exit": 0, "seconds": 1 }, { "command": "pnpm check:watch-hint-literal", "exit": 0, "seconds": 5 }, { "command": "pnpm check:agent-model-declared", "exit": 0, "seconds": 1 }, { "command": "pnpm check:skill-frame-freshness", "exit": 0, "seconds": 3 }, { "command": "pnpm check:pm-settings-deny-roster", "exit": 0, "seconds": 1 } ], "line_budget": { ".claude/skills/pm-dispatch/SKILL.md": { "before": 319, "after": 319, "ceiling": 319 }, ".claude/skills/pm-dispatch/references/decision-analysis.md": { "before": 50, "after": 50, "ceiling": 50 }, ".claude/skills/pm-dispatch/references/lanes/director.md": { "before": 63, "after": 65, "ceiling": 72 }, ".claude/skills/pm-dispatch/references/dispatch-runbook.md": { "before": 241, "after": 241, "ceiling": 241, "touched": false }, ".claude/agents/os-dev.md": { "before": 402, "after": 402, "ceiling": 402, "touched": false }, "max_line_bytes": { "cap": 120, "changed_lines": [ 120, 118, 119, 113, 120, 84, 119 ] } }, "deviations": [ "label-write refused by the harness permission classifier ([External System Writes]) before any request was made — exact command: `node scripts/pm/label-write.mjs --repo objectstack-ai/objectstack --issue 22654 --add skip-changeset --assign marchtian` — not retried by any other route; the seat applies skip-changeset and assignee marchtian on #22654.", "The review request on #22654 (pr_request_reviewers) is outside this dev's write budget; the seat requests it per the claim's four-piece terminal set.", "Commit trailers: AGENTS.md's model-free pair written (Claude-Session + Co-authored-by: Claude); the harness attribution reminder's model-named Co-Authored-By line was not written — the pre-push hook refuses a model identifier in that pair. Reported, not mimicked.", "The prerequisite build for check:doc-formula-expressions was a 4/4 turbo cache HIT from the worktree-shared .turbo cache (a dist restore, not a compile); the gate then ran its own 61-case self-test and full sweep on that dist and exited 0." ], "files_changed": [ ".claude/skills/pm-dispatch/SKILL.md", ".claude/skills/pm-dispatch/references/decision-analysis.md", ".claude/skills/pm-dispatch/references/lanes/director.md" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 10, 2026
ACCEPT: PR #22654 (head
1e39518d6), Tier S by path, held draft with the four-piece set — the maintainer approves the weighing rule (card item 3)Skills seat 1 (#7623) ·
session_01RdnZdPZH9ByduzPRWuH9tN· 2026-10-10T09:18Z. Reviewed against GitHub (the diff on the head, the ratchet and byte readings, the head's check-runs), not against the report. Thread-read: 6096004928.main,Fixes #22597/Clause-②: no; three files +7/−5 inside the claim's surface (6095813674);## 维护者速读(草稿)present; authorobjectstack-fleet[bot]; no other closing keyword near a card number..claude/**prose files, nothing publishes, soskip-changesetis the seat's own verdict, applied in this act after the dev's label write was refused by the session classifier (0 requests); premise — decision-analysis:25, director:23, the frame block:241–:261byte-identical (md5abff5f852c8fd09b79ec0623439aa4f0read on the head); the two paid deletions have homes (SKILL.md's invariants;decision-analysis.md:30and:34) and are not re-wraps; item 4 needs no edit (name pointers; frame-sync and freshness 0).1e39518d6by the report,--ran0 NOT-MEASURED;check:doc-formula-expressionsfirst exit 3 PREREQUISITE NOT MET, rebuilt, re-run 0. CI at this read:Lint & Repo GatesandType Check · workspacein progress;Check Changesetred for want of the label, re-read at landing.SKILL.mdis protocol semantics).label-write … --add skip-changeset --assign marchtianwas refused by the classifier before any request; the seat does not repeat a refused write. The command line is recorded on pm tooling: the os-dev's PR-assignee write (label-write.mjs --assign) is refused by the auto-mode permission classifier on 4 of 12 objectui PRs in one seat's session — same command, same brief, nondeterministic #22467 as a measured data point (that card's first step); the PR is listed on the seat post instead.needs-user-decision+ 维护者速读(终稿), review requested fromos-zhuangandhotlong. The PR waits draft. On the maintainer's word (an APPROVED review, or a 「同意」 on the PR or this card recorded with its provenance) the seat lands it:check-expected-skips --pr 22654exit 0,check-governed-merges --pr 22654, relaypr_ready+automerge_enable. Close-out: strippm:dispatchedhere (closes byFixes) andneeds-user-decisionfrom the PR.os-dev.md:353成本 unqualified (carrier: this seat's next os-dev.md edit); [Decision] 切换后谁能在 Setup 里新建/编辑岗位和权限集:保持今天的权限(持 manage_metadata 者),还是放开给组织管理员(安全边界) #22621 already renders the column (observation, no action).pm:dispatched, waiting on the maintainer's word from this stamp; the PR subscription is armed.Generated by Claude Code
objectstack-fleet commentedon Oct 10, 2026
Landed: PR #22654 MERGED (merge queue); the card closes by
Fixes; the weighing rule is approved as proposedSkills seat 1 (#7623) ·
session_01RdnZdPZH9ByduzPRWuH9tN· 2026-10-10T10:12Z. MERGED proof:merged: true; the merge commit is an ancestor oforigin/main; the three.claude/**files at that commit are byte-identical to the PR head1e39518d6. The maintainer's word on card item 3 (how workload weighs) isos-zhuang's APPROVED review 5478481215 on the PR at 2026-10-10T09:34Z, who also readied, armed and enqueued it; the seat's landing stroke was not used. From this merge the rule stands: every decision card's options table carries the 工作量 column (车道 · 阶段/PR 数 · 实测先例 or 「无先例」), the director's presentation carries the same column and the ruling record states the chosen letter's workload; workload is always listed, a ≥3× gap between options with near long-term readings is named in the recommendation, and workload adjusts staging only — the letter flips only on the maintainer's own ruling on the card. Close-out in this act:pm:dispatchedand the claim assignee stripped here;needs-user-decisionstripped from the PR. Carried:os-dev.md:353still asks aneeds_decisiondev for 「选项、成本与你的推荐」 with 成本 unqualified — the column's definition reaches a dev through the PM's dispatch prompt; carrier: this seat's next os-dev.md edit.Generated by Claude Code