Skip to content

skills(pm-dispatch): push-notify the maintainer when an item moves into the maintainer's hands (a Tier H PR to merge, a decision card, a release step) #24481

Closed

Description

@objectstack-fleet

Filing gate ③: a task the maintainer directed. In the epic seat's chat (epic:#15194, session_01Y5583bs2RDd53MH6kM1ca3), on 2026-10-19, the maintainer wrote 「24422 等我合并,你改过之后没给我推送消息,是skills的问题吗」, and then 「长期固定下来,立一张skills卡片」.

Reader who acts: whichever seat owns .claude/skills/**. It is a governed path (#7548), so the PR is Tier H, and the maintainer reviews and merges it.

Dedupe: semantic search on objectstack-ai/objectstack for "pm-dispatch skill notify maintainer push notification when action needed merge decision" returned 6 hits, all closed, none about push notifications. The nearest is #23934 (a chat that lists options and waits is a popup), which is a different rule.

What happened (measured)

  • At about 05:46Z on 2026-10-19, PR docs(adr): ADR-0131 D6 charts sharing_rule under regime C; D7 ledger reading and lines for #24377 and #24435; D14 records the 18.0 scope #24422 (Tier H, ADR-0131) became ready for the maintainer's approval and merge. Its at-tier contract review had passed (6260552601), and the seat had corrected the PR body.

  • The seat said so in chat only. It sent no push notification, so a maintainer away from that session learned nothing.

  • .claude/skills/pm-dispatch/SKILL.md has no rule for this. The nearest lines are:

    • :268, 「卡先于弹窗 …… ⛔ 不 assign 推送」, which forbids using a GitHub assignment as a nudge;
    • :270, 「AskUserQuestion 只是在场加速器 …」, which covers a maintainer who is present.

    Nothing covers a maintainer who has stepped away, while an item waits on the maintainer's own click or word.

Wanted

Add one rule next to SKILL.md :268–:270. It follows the skill's own style (Chinese bullet, ⛔ markers). Suggested wording, which the implementing seat may tighten:

If the hourly wake routine's prompt template, or references/execution-duties.md, carries the round-report duty, mirror the rule there in one line. ⛔ Add no new gate. This is a seat behaviour, not a CI check.

Acceptance

  • SKILL.md carries the rule. The PR body quotes the maintainer's two sentences above verbatim.
  • On the next item that moves into the maintainer's hands, the seat sends exactly one push. Record that in the seat's next round report.

Activity

  1. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3
    Session: session_01FM29ZqLTrnPNXxijioZwMp
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-24481-push-notify-maintainer-hands
    Worktree: objectstack-issue-24481
    Domain: domain:devx
    Seat: domain:devx#1
    File surface: .claude/skills/pm-dispatch/SKILL.md, one rule bullet beside :268–:270; one mirror line in .claude/skills/pm-dispatch/references/execution-duties.md only if that file carries the round-report duty (stop on breach; explain in the report). .claude/skills/** is Tier H governed (#7548): the PR stays draft for an authorised approval.
    Container & model: S (one governed rule bullet, wording suggested on the card), mode:subagent, model: CONTRACT_REVIEW_TIER (dispatch-gates --tier MANDATORY path row: .claude/skills/pm-dispatch/SKILL.md, clause ① of the model-tiering ruling)
    Clause-②: no
    Responsibility: n/a — not a defect card (a seat behaviour the maintainer directed)
    Thread-read: none
    Serial constraints cleared: none — no open PR touches .claude/skills/pm-dispatch/** or .claude/agents/** (read at 2026-10-19T06:46Z).


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 24481,
      "status": "done",
      "branch": "claude/issue-24481-push-notify-maintainer-hands",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/24488",
      "session": "session_01FM29ZqLTrnPNXxijioZwMp",
      "premise_still_valid": true,
      "summary": "Added the maintainer-push rule to .claude/skills/pm-dispatch/SKILL.md as two bullets at :272-:273 in 升级与决策, right after the AskUserQuestion pair (:270-:271). Net 0 lines (319 to 319): paid by deleting two director-seat bullets whose content is carried verbatim-equivalent by references/lanes/director.md (its three 职责 headers; :53-:54 for the ≤5-row batch and the maintainer's click, also AGENTS.md Prime Directive #14), and repointing the :56 director arg row at that file. No neighbouring bullet was re-wrapped. Draft PR #24488 opened with Fixes #24481, Clause-②: no, the maintainer's two sentences verbatim, the 维护者速读(草稿) section, assignee os-warren and label skip-changeset; it stays draft.",
      "rule_text": "- 推送维护者:受管 PR 待批合、决策卡待字、发版、仅其可解之阻 ⇒ 另发 `PushNotification`。\n- 一行 ≤200 字,先写动作与编号;每项恰一次,例行进展、刚问刚答与在场即见的不推。",
      "files_changed": [".claude/skills/pm-dispatch/SKILL.md (3 insertions, 3 deletions: 2 bullets added at :272-:273; 2 bullets deleted, former :273 三职 =… and former :274 每场召唤…≤5 行…; table row :56 repointed)"],
      "line_budget": "SKILL.md 319 to 319 lines (ceiling 319, headroom 0); widest table row 342 bytes unchanged (pin 342); 6 diff lines (+3/-3), 5 changed lines; every changed line ≤120 bytes (56: 117, 272: 118, 273: 112) matching the file's prose-bullet norm; dispatch-gates: changed lines 6 vs the 3000 human-merge threshold: under",
      "tests": "No package touched, so no build/test/typecheck owed. Prose gates at committed HEAD c4341e35c (git rev-parse --short HEAD): pnpm check:pm-skill-ratchet exit 0 — '.claude/skills/pm-dispatch/SKILL.md is 319 lines (ceiling 319; headroom 0)', 'widest table row is 342 bytes (pin 342; headroom 0)'; pnpm check:pm-skill-id-lint exit 0 — '87 file(s) clean (pattern /#[0-9]{3,}/g)'; pnpm check:skill-frame-sync exit 0 — 'the one declared copy of the decision frame is internally coherent', 4 axes, 90 markdown files scanned; pnpm check:pm-governed-prose exit 0. No ablation: a rules-text edit, nothing tested changed behaviour. Control-character scan of SKILL.md and of the PR body: none.",
      "gates": "Derived at c4341e35c with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 20 runnable families (12 by path, 8 whole-tree) + check-governed-queue-guard.mjs (CI-measured only, not runnable). All 20 run locally, exit codes captured before any pipe (cmd redirected to a log, then EXIT=$?): pnpm check:pm-skill-ratchet :: exit 0 · pnpm check:pm-skill-id-lint :: exit 0 · pnpm check:pm-governed-prose :: exit 0 · pnpm check:skill-frame-sync :: exit 0 · pnpm check:pm-expected-skips :: exit 0 · pnpm check:doc-authoring :: exit 0 · pnpm check:agent-test-spelling :: exit 0 · pnpm check:cross-package-test-inputs :: exit 0 · pnpm check:pm-governed-merges :: exit 0 · pnpm --filter @objectstack/lint run check:doc-formula-expressions :: first run exit 3 PREREQUISITE NOT MET (@objectstack/lint and @objectstack/formula unbuilt, nothing measured), then pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint --concurrency=2 under scripts/pm/os-verify-lock.sh (VERDICT command-exit 0, held 159s, waited 0s), rerun :: exit 0 ('22 record-scoped formula example(s) across 476 files / 1393 TS blocks judged clean') · node scripts/pm/check-governed-queue-guard.mjs --self-test :: exit 0 · node scripts/pm/check-harness-current.mjs --self-test :: exit 0 · pnpm check:driver-memory-census :: exit 0 · pnpm check:gitlink-declared :: exit 0 · pnpm check:nul-bytes :: exit 0 · pnpm check:refd-timer-probe :: exit 0 · pnpm check:watch-hint-literal :: exit 0 · node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 · node scripts/check-closing-keyword-parity.mjs :: exit 0 · node scripts/check-comment-mask-corpus.mjs :: exit 0. --ran reconciliation with exit codes recorded: '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)'. Local-only family run because the four-axis frame file was touched: pnpm check:skill-frame-freshness :: exit 0 (reading stays local). The union first ran on the uncommitted tree, byte-identical to c4341e35c which was then committed with no other change; the four SKILL.md-reading prose gates were rerun at c4341e35c. Every family CI runs: the check-runs on https://github.com/objectstack-ai/objectstack/pull/24488 at head c4341e35c are the record; CI status at report time: in_progress (not awaited, per the role file).",
      "mcp_calls": "0 — no MCP GitHub tool called; reads went through gh api and git. One harness ToolSearch for 'push notification' tested whether a PushNotification tool exists in this container: it does not.",
      "api_writes": "2 relay strokes = 4 REST requests, all as objectstack-fleet[bot] through scripts/pm: (1) pr_create via with-fleet.sh --via dispatch (run 39215031005, success): POST /repos/objectstack-ai/objectstack/pulls (draft forced), POST /repos/objectstack-ai/objectstack/issues/24488/assignees [os-warren], POST /repos/objectstack-ai/objectstack/issues/24488/labels [skip-changeset]; (2) this os-dev-report comment via post-stamped.mjs --comment=24481: POST /repos/objectstack-ai/objectstack/issues/24481/comments. Plus 2 git pushes (not REST): the empty-branch probe and commit c4341e35c. Read-backs: PR body 9059 bytes sent, 9059 stored, diff identical; REST read of PR 24488: draft true, labels [documentation, size/xs, skip-changeset], assignees [os-warren], auto_merge null, requested_reviewers none.",
      "deviations": [
        "Line-budget mechanism: the dispatch's hypothesis 2 proposed folding neighbouring bullets for a net-zero fit; the role file forbids re-wrap as ratchet currency (「⛔ 不拿 re-wrap(折行合并)当筹行,新增以删减付账」), and the file's prose bullets are all ≤120 bytes, so a two-bullet fold could not keep style either. Resolved by the role file's precedence clause: paid by deleting duplicated content (two director bullets carried by references/lanes/director.md) instead. Candidate folds not taken, for the record: (a) :270+:271 into one 166-byte line 「`AskUserQuestion` 只是在场加速器:维护者本会话 ~30 分钟内有人类输入才可发;每问带推荐项,Skip 或长挂即转卡,⛔ 不重弹。」; (b) :264 into :266 as 「序与权重只排推荐不授权:分歧块照旧升级,四棱同向置信门与代裁面不变;读缩小特例与契约增生,⛔ 不背书投机扩张、不放行人工地板事。」 (192 bytes). Both are re-wraps.",
        "Tier: the card and the dispatch call the PR Tier H; GOVERNED_SURFACES (scripts/pm/check-governed-merges.mjs row claude-tree), AGENTS.md Prime Directive #14 and SKILL.md :204 place .claude/** in Tier S. Same posture here (draft; never readied, queued or armed by this agent); the PR body states the register's tier. Under Tier S the landing record is the seat's contract-review PASS, not a maintainer approval — the seat should reconcile.",
        "Hypothesis 4: the card's 「工具回 not sent 即视为在场,不重发」 clause was not written — PushNotification is unreferenced in the tracked tree, .claude/settings.json, .claude/hooks and this container's tool list; the tool name is kept as the card names it (unverified in seat sessions). The card's example 「#24422 ADR 待您合并」 was not written (id-lint pattern /#[0-9]{3,}/ refuses it; an #N example did not fit the 120-byte norm with the exclusions kept). The 「⛔ 不以 GitHub assign 代推送」 clause is the existing :268 bullet and is not restated.",
        "No mirror line, per the dispatch ruling, verified: the round-report duty is at references/seat-lifecycle.md:66-:68 only; execution-duties.md has none (:54 is a triage-gap line); seat-lifecycle.md not edited.",
        "Relay read-back for pr_create listed the assignee but printed no label line; the label leg was confirmed by a REST read of the PR at close (skip-changeset present). documentation and size/xs on the PR were applied by other actors and were not touched.",
        "Commit trailers: the harness reminder asked for a model-named Co-Authored-By; AGENTS.md's model-free pair (Claude-Session plus Co-authored-by: Claude) was used per instruction precedence; no harness-written trailer was appended to c4341e35c.",
        "origin/main moved between the PM's reading (e11ae4b6b) and BASE fb9c22aa0 (PR 24422 and 24451 landed) and again to 01fafdee2 during the run; none of those commits touch .claude/; SKILL.md :268 and :270 re-measured identical at BASE; no merge of main performed."
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: the dispatching seat (domain:devx seat 1) · noted, not filed — the card and the dispatch state Tier H for .claude/skills/**; the register, AGENTS.md Prime Directive #14 and SKILL.md :204 say Tier S. Evidence: scripts/pm/check-governed-merges.mjs GOVERNED_SURFACES row claude-tree, tier GOVERNED_TIER_S. Dedupe words: governed tier claude-tree Tier S Tier H register.",
        "carrier: none · noted in the PR's Acceptance notes only — check-skill-line-ratchet prints a pre-existing info line: .claude/skills/spec-property-retirement/SKILL.md max-table-row-bytes headroom 2 (pin 326, measured 324), inviting a pin lowering. Observation, not a defect."
      ]
    }

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Lane correction · domain:devx seat 1 · os-warren · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-19T10:51Z

    This card's change belongs to domain:skills, not domain:devx. The domain lane table in SKILL.md gives domain:skills the whole governed surface, the pm-dispatch skill included. The domain:devx label was applied by the filing act (2026-10-19T06:28Z, together with pm:queue). This seat claimed the card on that label and did not check it against the table, which is the claim-time check the table's self-labelled-card exception requires. That was this seat's miss.

    State, unchanged by this note:


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Lane correction: domain:devx → domain:skills · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-19T10:57Z

    Triage seat (objectstack-wide, seat post #6015). ⛔ Not a claim. The assignee and pm:dispatched are unchanged.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:devx seat 1 (carrying this domain:skills card; lane note above) · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-19T11:35Z

    reading result
    merge queue (gh-readonly-queue/main/pr-24488-* heads) none left: the entry has drained
    PR object PR #24488 merged by os-zhuang at 2026-10-19T11:18:48Z, on the at-tier review of record 6262172588 (PASS, Tier S)
    origin/main, by content SKILL.md:272 reads 「- 推送维护者:受管 PR 待批合、决策卡待字、发版、仅其可解之阻 ⇒ 另发 PushNotification。」 and :273 reads 「- 一行 ≤200 字,先写动作与编号;每项恰一次,例行进展、刚问刚答与在场即见的不推。」; the file is 319 lines (ceiling 319)

    State change: PR #24488 closed this card through Fixes #24481 (completed); pm:dispatched comes off in this act.

    Acceptance item 2, the seat's post-landing reading: the rule was applied before it landed, on the maintainer's standing order. This seat sent exactly one PushNotification per item that moved into the maintainer's hands: #24445's decision after its reading, #24488's landing block, and #24503's Tier H approval. The round report on #6023 records them.


    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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions