Skip to content

Codify the triage direct-session operating mode: self-timed rounds, transcript-verified verdict subagents, Director backstop - #12744

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-12706-triage-direct-session
Aug 27, 2026
Merged

Codify the triage direct-session operating mode: self-timed rounds, transcript-verified verdict subagents, Director backstop#12744
os-zhuang merged 1 commit into
mainfrom
claude/issue-12706-triage-direct-session

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Fixes#12706

Codifies the six maintainer rulings recorded on the card (2026-08-27) into the pm-dispatch governed protocol text. All ruling quotes verbatim, untranslated.

The six rulings

  1. Triage seat = normal direct session, whole seat at opus. 「我觉得分诊也和普通项目经理一样走普通的session,然后需要高级别处理的任务走 fable 子agent,然后自己默认定时1小时,除非人工要求。」 The mechanical trio (hourly sweep, unlock scan, half-state healing) needs at most opus; the tier analysis is on the card.
  2. Tier-gated duties (proxy-adjudication, Clause-②/contract-review increments) run via a claude-fable-5 subagent dispatched with explicit model — the dispatch-param mechanism, not session self-introspection.
  3. Transcript tier verification. Before any verdict is adopted or any label cleared, the dispatching session greps the subagent's transcript for the per-message API-stamped model field; every verdict-producing turn must read claude-fable-5; fallback evidence voids the verdict (redo or maintainer path). Dispatch params are configuration; the fuse measures serving.
  4. No-edit guardrail. The opus parent has exactly two legal actions on a fable verdict — adopt verbatim, or void whole (void reasons mechanical only: tier verification failed / scope exceeded / format incomplete). Never rewrite, trim, or "improve" verdict content; acceptance = evidence checklist, never substantive re-judgment.
  5. Self-timer default = armed at round END, delay at most 55 minutes (the 1-hour prompt-cache TTL minus measured minutes-level timer jitter keeps the shift on one cache chain; two boundaries recorded as a note: usage-overage drops the TTL to 5 minutes and the benefit to zero, and compaction rounds rewrite regardless — neither changes the default). Overridable by explicit maintainer request. The five-piece package was approved whole: 「同意,重新汇总给我解释一下新的分诊项目经理完整的工作。」
  6. Chain timed-processing split. 「契约复审也是很重要的职责,也是需要定时处理的」, approved 「同意,继续」: standing contract-review processing = the triage timed round; every round report carries the 复审清单 (same mandatory-audit shape as the 代裁清单); the Director seat = summon-time backstop (only carriers triage explicitly parked, failed tier-verification on, or aged out) plus the BLOCKED branch inside adjudication batches; anti-double-run hard line — the standing processor is uniquely the triage timed round.

Per-file clause rewrites

.claude/skills/pm-dispatch/SKILL.md (1005 lines before and after)

  • 「座位 Routine 三原则」 paragraph rewritten to 「分诊席直连自排」 (pieces 1 and 5, full ruling quote carried); the round-open mutex/release text from the shift-close ruling is kept verbatim inside the same paragraph.
  • 代裁通道 clause: runner set restated at pointer altitude — verdicts only from a tier-proven producer: the triage seat's explicit-model fable subagent, each verdict past transcript verification (2026-08-27 裁), or the at-tier Director seat; mechanics live in references/contract-review.md. The 2026-08-26 hard-gate quote and the 2026-08-12 confidence-gate conditions are unchanged.
  • Consistency touches: the role-arg sentence (Routine-rebuild vocabulary retired), 席位档策略 (the triage seat joins the opus-session default; fable reserved for verdict/review subagents, the skills seat and Clause-② work; Routine-UI-pin wording retired), urgent-triage wording (Routine 班次 → 定时轮次), and the daily low-frequency subround owner (分诊 Routine → 分诊席).

.claude/skills/pm-dispatch/references/contract-review.md (48 lines before and after)

  • 资格 clause: the machine reading splits by path — own-session via the downgrade fuse, subagent path via transcript tier verification.
  • 归属 clause: standing owner uniquely = the triage timed round via verified subagent; PASS / FAIL / BLOCKED branch endings; 复审清单 in every round report; Director = summon backstop plus the BLOCKED branch; the anti-double-run hard line.
  • The ⛔ 反模式 paragraph became the 转录档位核验 bullet: the higher-tier-subagent review path WAS constructively unmeasurable and is legal exactly when transcript verification passes; the get_session-measures-the-dispatching-session measurement stays as the reason introspection or params alone remain inadmissible; the no-edit guardrail (adopt verbatim or void whole; three mechanical void reasons) lands in the same bullet.
  • Fail-safe unchanged: the opening get_session fuse bullet and the no-quota-exemption bullet stay (wording compressed only).

.claude/skills/pm-dispatch/references/lanes/director.md (75 lines before and after)

  • 授权与形态: parking-between-summons now covers decision cards and the audit window only (review carriers' standing timed processing moved to the triage round).
  • 职责一 reframed as the backstop: only parked / failed-verification / aged-out carriers plus the BLOCKED branch; never sweeps the timed round's carrier set in parallel. The 处理三分支 ruling text is untouched.
  • 职责二: runner-set wording 分诊 Routine → 分诊席.
  • 交接台账: the two supersession bullets merged into one dated chain (dead hourly clock → director summon → 2026-08-27: standing = triage timed round, director = backstop).

Cut ledger (net 0 per file; every cut names its surviving home)

SKILL.md:

  1. Old 三原则 items ① and ② (Routines-UI creation, UI model pin, manual fire smoke test) — retired by the ruling itself; the obsolete Routine's UI disable is already filed as its own pm:awaiting-maintainer item.
  2. Old item ③ (per-fire rebuild from labels, no context inheritance) — survives in 全体座位的不变量, first bullet (all state on GitHub; the loop must recover from a fresh session).
  3. 「⛔ 永不靠重建Routine 改行为」 — retired with the Routine; the surviving half (behaviour versioned in git, upgrades via skill PR) kept in place.
  4. Sanitizer bullet: the dispatch-order incident illustration and the standalone read-back framing — write-side shapes and the read-back duty live in references/platform-readings.md (写侧 sanitizer 条款); incident case law lives in git history per house rules.
  5. Gate-verdict bullet detail (in_progress does not count; aggregate only as negative screening; read the single job by name, never the full table) — verbatim home in references/platform-readings.md (状态核验/门禁放行判据 entry).
  6. Wall-detection bullet: the ccusage single-container-view detail — home in references/platform-readings.md (断粮检测 section); the fact-table pointer stays in the bullet.
  7. 代裁通道 clause: the literal serving-model spelling plus 「(钉档)」 — replaced by the ruled subagent mechanism; the machine-reading requirement survives as the transcript-verification pointer, and 「⛔ 永不凭自述」 is kept in place.

contract-review.md:

  1. 出处 paragraph compressed in place (nothing dropped; the tier-constant name still appears in the fuse section).
  2. 重挂前先查裁决 compressed in place (all three verdict conditions kept).
  3. Old 归属 dead-clock note and 「常设 = 项目总监席人工召唤」 — superseded by ruling 6; the supersession chain is recorded in references/lanes/director.md 交接台账.
  4. 「分诊席达档时照旧可清」 — dead under ruling 1 (the triage seat is opus by design; it clears via the verified subagent).
  5. 清标即落地: the landing-precheck parenthetical (mergeable_state first, closing-keyword scan, true-green job conclusions, ready before arm) — verbatim home in references/landing-operations.md section B.
  6. The get_session dual-reading same-source note — home in references/platform-readings.md (读数陷阱, get_session entry).
  7. 「派发席不写代码」 rationale — home in SKILL.md 全体座位的不变量 (PM 不写文件、不写代码).
  8. The old 反模式 refusal measurement (subagent read back the parent tier and refused to produce a verdict) — the parent-tier read-back half is kept in the fuse bullet; the refusal detail is subsumed by the now-legal verified path.

director.md:

  1. 职责一 review-process arrows (enumerate → review the diff → one-line conclusion → PASS clears both carriers) — home in ../contract-review.md (归属 and 载体纪律), pointed at by the same bullet.
  2. 交接台账 runner-set spelling history — compressed into the dated chain in the merged bullet; both quotes kept.

Ratchet readings (at 0006e0c)

  • ✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md is 1005 lines (ceiling 1005; headroom 0); widest table row is 765 bytes (pin 765; headroom 0).
  • ✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/contract-review.md is 48 lines (ceiling 48; headroom 0); widest table row is 0 bytes (pin 0; headroom 0).
  • ✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/lanes/director.md is 75 lines (ceiling 75; headroom 0); widest table row is 0 bytes (pin 0; headroom 0).

Gates — all re-run at HEAD 0006e0c; every exit captured before any pipe via the verify-lock VERDICT line

  • pnpm check:pm-skill-ratchet — exit 0; per-file verdict lines quoted above.
  • pnpm check:pm-skill-id-lint — exit 0; "✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g)."
  • pnpm check:skill-frame-sync — exit 0; "✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files".
  • pnpm check:skill-frame-freshness — exit 0; "✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now)."
  • pnpm check:pm-governed-prose — exit 0; "✓ check-governed-prose: 2 instruction surface(s) name all 5 registered governed surfaces (docs/adr/** · .claude/** · skills/** · AGENTS.md · CLAUDE.md) and claim no others."
  • Derived union via node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (9 matched families for this diff; run without paths, changeset derived by the script from merge-base): additionally pnpm check:agent-test-spelling (exit 0), pnpm check:doc-authoring (exit 0; "✓ doc authoring guard: 48 published skill files clean — no internal issue-id references."), pnpm check:pm-governed-merges (exit 0; self-test 206 assertions plus live generator certification), pnpm check:nul-bytes (exit 0; "check-nul-bytes: OK (scanned 7072 text file(s) ... no raw ASCII control bytes)"), and pnpm --filter @objectstack/lint run check:doc-formula-expressions (exit 0; "✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 424 files / 1451 TS blocks judged clean"). The last gate refused twice with PREREQUISITE NOT MET (unbuilt @objectstack/formula, then @objectstack/lint) — both recorded as NOT MEASURED, both packages built, gate re-run green.
  • check-governed-queue-guard — CI-only (governed-surface-guard.yml) ⇒ NOT MEASURED locally.
  • Derivation staleness note: the branch base is 4 commits behind origin/main; the two gate sources changed in that range are i18n/prerelease scripts with no coverage of this diff's paths, and none of the 4 commits touches any pm-dispatch file.

Acceptance replay — one triage round under the new text

  1. Round open: the mutex four readings run unchanged; the round-open marker lands on the seat post; the cheapest inventory probe goes first.
  2. The mechanical trio runs at opus inside the direct session (sweep, unlock scan, half-state healing) — no tier gate is touched.
  3. One contract-review carrier and one adjudicable decision card: a claude-fable-5 subagent is dispatched with explicit model per task; before adopting either verdict or clearing any label, the session greps the subagent transcript's per-message model field — every verdict-producing turn reads the contract-review tier, and a fallback stamp voids that verdict whole (redo or maintainer path); the parent adopts verbatim or voids whole, never edits.
  4. The round report carries both the 复审清单 and the 代裁清单 as mandatory-audit sections.
  5. Round end: the self-timer is armed with delay at most 55 minutes; the shift stays on one prompt-cache chain; an explicit maintainer request overrides the default.

Not touched

seat-post-protocol.md (pointed at, not edited), decision-analysis.md, state-machine.md, every script, the four-copy decision frame, the governed-surface namings. Fail-safe direction intact everywhere: unverifiable ⇒ skip/void, never self-report; the Director's own get_session fuse for its direct-session duties stays as-is.

Draft on purpose — the diff touches a governed surface (.claude/skills), human merge only. skip-changeset: internal agent instruction text, nothing publishes.

Generated by Claude Code


Generated by Claude Code

…ier-gated duties run via transcript-verified subagents
Codifies the six 2026-08-27 maintainer rulings recorded on the triage
operating-mode card (the 14:07Z ruled shape, the five-piece package, and
the chain timed-processing split):
1. Triage seat = normal direct session, whole seat at opus (the mechanical
trio needs at most opus).
2. Tier-gated duties (proxy-adjudication, Clause-2/contract-review
increments) run via a subagent dispatched with explicit `model`.
3. Transcript tier verification: before any verdict is adopted or any label
cleared, the dispatching session greps the subagent transcript for the
per-message API-stamped model field; every verdict-producing turn must
read the contract-review tier; fallback evidence voids the verdict.
Dispatch params are configuration; the reading measures serving.
4. No-edit guardrail: the parent adopts a verdict verbatim or voids it
whole (mechanical void reasons only); it never rewrites, trims, or
improves verdict content.
5. Self-timer default: armed at round END, delay at most 55 minutes (the
1-hour prompt-cache TTL minus measured timer jitter keeps the shift on
one cache chain; overage and compaction boundaries recorded as a note);
overridable by explicit maintainer request.
6. Chain timed-processing split: standing contract-review processing = the
triage timed round; the Director seat = summon-time backstop plus the
BLOCKED branch inside adjudication batches; anti-double-run hard line;
every round report carries the review roster beside the adjudication one.
All three files stay at their zero-headroom ratchet ceilings (1005/48/75);
every added line is paid by same-file cuts whose surviving homes are listed
in the PR body. Fail-safe direction untouched everywhere: unverifiable
means skip/void, never self-report; the Director's own get_session fuse for
its direct-session duties stays as-is.
Claude-Session: https://claude.ai/code/session_01MnijPVVDakqK2J335JoJtq
Co-authored-by: Claude <noreply@anthropic.com>
@os-litantos-litant added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 27, 2026 — with Claude
@github-actionsgithub-actionsBot added size/m documentation Improvements or additions to documentation labels Aug 27, 2026
@os-litant
os-litant marked this pull request as ready for review August 27, 2026 16:16
@os-litant
os-litant enabled auto-merge August 27, 2026 16:16
@os-litant
os-litant disabled auto-merge August 27, 2026 16:17
@os-zhuang
os-zhuang added this pull request to the merge queueAug 27, 2026
@os-zhuang
os-zhuang removed this pull request from the merge queue due to a manual request Aug 27, 2026
@os-zhuang
os-zhuang merged commit 1e3e667 into mainAug 27, 2026
29 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-12706-triage-direct-session branch August 27, 2026 16:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude