Skip to content

pm-dispatch(triage audit): a queue card with labels but no triage audit comment is invisible to both sides — lanes knock Request: triage, and the triage sweep derives the missing audits every round #29682

Closed

Description

@objectstack-fleet

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Filing gate ③: the maintainer's word. In the triage seat's session on 2026-11-03, the maintainer asked, verbatim: 「他在等,为什么没有用邮箱提醒你,是否应该立卡改进技能」. That was about domain:server#4 reporting six pm:queue cards with no triage audit comment (#29613, #29510, #29557, #29558, #29544, #29527) to the maintainer, and not to the triage mailbox. ⛔ Not a claim.

维护者速读

Change

  1. execution-duties.md, beside 「无分诊审计评论即非候选」: a seat that finds a non-candidate card it would otherwise pull sends Request: triage · #n · first-touch audit to triage's mailbox in the same round, one doorbell per card or one listing several. ⛔ It does not wait silently, and it does not report the gap to the maintainer in place of the mailbox. When triage is vacant, it sends to the director.
  2. lanes/triage.md and the triage sweep. The round's sweep derives the missing audits: an open pm:queue or pm:blocked card whose body or thread carries no triage audit comment. That is a comment whose first line is a triage#N signature and which contains ## Triage, or the older Triage: record shapes. Triage audits each one in the round it is found, exactly as an ungraded card, and the round record reports the count. Exempt: tracking, pm:epic, pm:seat, qa-run, status:parked, queue-flake anchors, and [maintainer] cards.
  3. Tooling. If the sweep's derivation lives in a script (check-half-states.mjs or the triage sweep helper), add it as one report-only row. It writes nothing and refuses nothing. The maintainer's word is quoted above, as instrument-discipline.md asks for a new patrol row.

⛔ No gate, no label.

Acceptance

  • The text edits are in .claude/skills/pm-dispatch/**. If a report row is added, its self-test pins one card with an audit and one without.
  • At the first triage round after landing, the derivation lists no card that a lane has also knocked about. Both channels converge on the same set.

Reader who acts: domain:skills.


Generated by Claude Code

Activity

  1. added
    toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
    pm:queueReady for the PM dispatch loop
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 3, 2026
  2. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#3 · os-support-ai · session_01WGufzhd2Ad9ANGTyAMW7pH

    Claim: PM loop round 5 · 2026-11-03T15:49Z
    Session: session_01WGufzgjcGBFsSmg6tHbbJq (os-dev card thread "Knock triage for unaudited queue cards"; dispatched by session_01WGufzhd2Ad9ANGTyAMW7pH)
    Account: os-support-ai
    Branch: claude/project-thread-28iqp6
    Worktree: objectstack-issue-29682
    Domain: domain:skills
    Seat: domain:skills#3
    File surface: .claude/skills/pm-dispatch/SKILL.md (候选 rule, L171) or references/execution-duties.md, one place; references/lanes/triage.md; at most one report-only row in scripts/pm/check-half-states.mjs or the triage sweep helper with its self-test; reuses the existing Request: triage key; ceiling raises only as the ratchet header admits, by measured delta; no changeset (skip-changeset)
    Container & model: M, mode:thread, model: CONTRACT_REVIEW_TIER — reason: governed pm rules text plus a report-only sweep row (per-card call; --tier: no path mandate), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: none
    Premise: holds — the non-candidate rule sits at SKILL.md L171 (not execution-duties.md as the card says; order corrects it); request:triage key exists in MAILBOX_KEYS; no sweep derivation of audit-less queue cards on origin/main 21510bb
    Serial constraints cleared: no open PR touches SKILL.md, execution-duties.md, lanes/triage.md or check-half-states.mjs (measured over the 19 open PRs at 2026-11-03T15:42Z); disjoint from this seat's #29731 and #29445 surfaces

  3. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#3 · os-support-ai · session_01WGufzgjcGBFsSmg6tHbbJq

    os-dev-report

    {
      "issue": 29682,
      "status": "done",
      "branch": "claude/project-thread-28iqp6",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29940",
      "head": "197f87e0",
      "session": "session_01WGufzgjcGBFsSmg6tHbbJq",
      "premise_still_valid": true,
      "summary": "Lane side: one line in references/execution-duties.md (候选与批次, under the generic 不静默等分诊 line) — a candidate with no triage audit comment is knocked in the same round with the existing key Request: triage · #n · first-touch audit, never reported to the maintainer instead. Placed there, not beside SKILL.md L171, because that file is where the execution seat's candidate rule and generic knock live and SKILL.md has no restated line to pay with. Triage side: one line in references/lanes/triage.md — the sweep derives pm:queue / pm:blocked cards with no audit comment, audits them as an ungraded first touch and reports the count. Tooling: H74 in scripts/pm/check-half-states.mjs, report-only, both channels (body then one gated comment-page read off the shared cache), audit record = triage-signed body with a ## Triage heading or the older Triage: openings isTriageRulingComment already reads; exempt tracking, pm:epic, pm:seat, qa-run, status:parked, queue-flake-anchor, [maintainer] titles. No new key, label, gate or ceiling raise.",
      "files_changed": [
        ".claude/skills/pm-dispatch/references/execution-duties.md (+1 −1, 188/188)",
        ".claude/skills/pm-dispatch/references/lanes/triage.md (+1 −1, 20/20)",
        "scripts/pm/check-half-states.mjs (+243: H74 section, band, count keys, summary clause, sweep gather/judge, self-test battery)"
      ],
      "line_budget": "no ceiling moved. execution-duties.md 188→188: new knock line paid by deleting 「降档的档位与理由记入认领评论 Container & model 行;档位逐次派发显式传参,永不省略」 (restated by the SKILL.md claim template's model: field and by the effort line below it). lanes/triage.md 20→20: new sweep line paid by deleting 「security#1 空缺时沿用 security-findings.md 第 7 节处置,⛔ 不代席、不追加细节」 (restated by security-findings.md §7 and §9; §8 forbids a second copy). The ratchet header admits a raise only against a ruling comment id; the maintainer's word on this card is a session sentence with none, so no raise was taken. Widest line 120 bytes in both files.",
      "tests": "node scripts/pm/check-half-states.mjs --self-test → ✓ 5199 cases pass, battery H74 first-touch audit 37/32 (frozen roster, pin 32). npx eslint scripts/pm/check-half-states.mjs → exit 0. First run had 3 red controls: the older Triage anchor reads a ## Triage heading as the first line whatever the signature, and a null body is no crash but still fires — both corrected as pins of the real behaviour, not silenced.",
      "gates": "head 197f87e0; node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack → 54 commands (merge base 21510bba, 3 paths, +245/−2); all run serially, exit codes captured before any pipe; --ran → ✓ 54 accounted — 53 run, 1 NOT-MEASURED. 52 exit 0 incl. check:pm-half-states, check:pm-skill-ratchet, check:pm-skill-id-lint, check:pm-dispatch-gates, check:pm-governed-merges, check:pm-post-stamped, check:skill-frame-sync, check:single-claim-paths, check:nul-bytes, check:doc-authoring, check:platform-checklist. check-release-section-coverage.mjs --strict :: exit 1 — identical finding on origin/main 21510bba (releases/v18 page has no 18.3 heading), release-owned page not touched here, out of scope. lint check:doc-formula-expressions :: exit 3 — PREREQUISITE NOT MET (lint dist unbuilt in a fresh worktree), NOT MEASURED, CI's Lint & Repo Gates is the reading. Roster/wide/changeset-pending families and type-check lanes: CI on PR 29940. merge-tree HEAD vs origin/main at open: clean.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "deviations": [
        "card text 'one doorbell per card or one listing several': the request:triage reader takes one #n, so the lane line spells one knock per card",
        "card text 'when triage is vacant, it sends to the director': not restated on the lane line (120-byte cap; the mailbox table already routes a vacant triage to the director); the H74 row text names the triage mailbox only",
        "PR subscription: not subscribed, per os-dev.md (the dispatch contract overrides the platform's auto-subscribe posture; the seat owns landing)",
        "worktree node_modules removed and worktree detached after the report, per resource rule 4"
      ],
      "mcp_calls": "6 — GitHub MCP reads only: issue_read ×4 (card body, comments ×3), list_issues ×2 (open pm:queue = 33, open pm:blocked = 23, for the cost note); no write tool",
      "api_writes": "4 — git push ×2 (WIP 197f87e0, no second commit needed); relay pr_create ×1 (draft, labels skip-changeset, no assignees, read back 12188/12188 bytes identical, run 41673329630); post-stamped.mjs --comment ×1 (this report)",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "class: none of a/b/c (gate reading on a release-owned page) · check-release-section-coverage.mjs --strict exit 1 on origin/main 21510bba: content/docs/releases/v18/ names no 18.3 heading while @objectstack/spec 18.3.0 is published · carrier: release notes are compiled at release time (AGENTS.md Documentation Guardrails) — noted, not filed · dedupe words: release-section-coverage, v18, 18.3.0, strict"
      ]
    }
  4. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#3 · os-support-ai · session_01WGufzhd2Ad9ANGTyAMW7pH

    Seat status · PR #29940 landing · 2026-11-03T17:02Z

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:p2Medium: important, M3toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions