Skip to content

skills(pm-dispatch): a dispatched PR carries its card's assignee (the seat's linked user), set at pr_create and moved on takeover — maintainer 2026-09-25 「同意」 #20063

Closed

Description

@objectstack-fleet

Filing-gate category: ③ — a maintainer-directed task. Filed by the domain:skills#1 seat (session_01LNRg6FUMXYWgkAbDsfZpC8) under the direct-dispatch channel; the audit comment on this card quotes the authorization verbatim.

Maintainer's words (verbatim, this seat's chat, 2026-09-24/25, ⛔ not translated)

The question: 「现在pr都是车队提交的,有点分不清是谁在处理,是否建议也写入 assignee,包括pr被接管时应该更新 assignee」

The seat's recommendation, given in chat: PR assignee = the card's assignee (the dispatching seat's linked user account), set by the dev right after pr_create with the label-write tool; a takeover moves every open PR's assignee of that card in the same stroke as the card's; a seat's own tool PR is assigned to the seat; the reader is the filter is:pr is:open assignee:LOGIN; no new patrol row unless the maintainer names one.

The ruling: 「同意」

What lands (rule text only; ⛔ no gate, no patrol row, no new tool)

  1. .claude/skills/pm-dispatch/references/execution-duties.md, 认领 section — one rule: the dev's pr_create is followed by label-write --issue PR_NUMBER --assign with the card's assignee; the takeover four-piece (C9) moves the assignee of every open PR of the card in the same stroke (--unassign old --assign new on the PR number too); a seat's own PR is assigned to the seat. The file sits at its line ceiling (183 / 183): pay every added line with a deletion or an in-place rewrite, ⛔ never a re-wrap.
  2. .claude/agents/os-dev.md, rule 2 (「你恒不写 assignee」) narrowed to the CARD's assignee, and the write budget line (「写预算四笔」) naming the PR-assignee write as the label-write slot it already has; the standard clause that objectui path labels belong to the labeler is unchanged.
  3. Any other reader of the assignee rule found by a sweep of .claude/** and AGENTS.md for assignee — listed in the PR body with a per-hit decision (changed / already consistent / out of scope with reason).

Pilot already run: PRs objectui#10410, #10412, #10413 carry assignee os-elon-musk (= the cards' assignee), set by their devs through the relay; the measured spelling is node scripts/pm/label-write.mjs --repo OWNER/NAME --issue PR_NUMBER --assign LOGIN (the relay's assign op, POST /issues/{n}/assignees, works on a PR number).

Who acts

The domain:skills seat: Tier S (.claude/** only) ⇒ in-seat contract review at CONTRACT_REVIEW_TIER, then the queue.

Dedupe

search_issues on objectstack at filing: 「PR assignee equals card assignee dispatching seat linked user takeover updates assignee」 → 52 (open + closed); the nearest are #15670 (closed — who sets the ISSUE assignee, CLAUDE.md vs os-dev.md rule 2) and #17932 (closed — a re-routed card keeping the old lane's assignee). Neither concerns the PR's assignee. Dedupe words: PR assignee mirrors card · pr_create assign · takeover moves PR assignee · is:pr assignee filter · os-dev rule 2 assignee


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01LNRg6FUMXYWgkAbDsfZpC8
    Branch: claude/issue-20063-pr-assignee-mirrors-card
    Worktree: objectstack-issue-20063
    Domain: domain:skills
    Seat: domain:skills#1
    File surface: .claude/skills/pm-dispatch/references/execution-duties.md (认领 section, the assignee rules — 183 / 183, every added line paid in place) · .claude/agents/os-dev.md (rule 2 and the write-budget line) · any other .claude/** / AGENTS.md reader of the assignee rule the sweep finds, decided per hit (stop on breach; explain in the report)
    Container & model: S — rule text, a few sentences rewritten in place, mode:subagent, model: opus — dispatch-gates --tier --repo objectstack-ai/objectstack on these paths prints the clause-① mandate for .claude/agents/os-dev.md (CONTRACT_REVIEW_TIER) and its exit: "a one-line-class mechanical governed edit drops to opus execution … compensated by the skill-face review at claude-fable-5-1" — taken: opus build, this seat's in-seat review at CONTRACT_REVIEW_TIER
    Clause-②: no
    Thread-read: none
    Serial constraints cleared: execution-duties.md and os-dev.md are FREE — PR #20009 (the last PR on execution-duties.md) MERGED on 2026-09-24 (the timeline on that PR carries the minute); no open objectstack PR touches either file (open PR head list read at {{NOW}}); no claude/issue-20063* head on origin; the sibling take of this round (objectui #10048) is in another repo

    Take basis (written at 2026-09-25T01:02Z): category ③ — the maintainer's 「同意」 on this seat's recommendation, both quoted verbatim on the card; under 「并发恢复3」 (batch 3, 1 other in flight). Premise on origin/main 3557f85: os-dev.md rule 2 still reads 「你恒不写 assignee」 and execution-duties.md :56 「assignee 字段归 PM:原子对 step 1 设,dev 席恒不写它」 — both about the card; neither text mentions the PR's assignee. Dispatched as a subagent of this session with this comment as its only claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    Reported at 2026-09-25T01:18Z by session_01LNRg6FUMXYWgkAbDsfZpC8 for PR 20066.

    {
      "issue": 20063,
      "status": "done",
      "branch": "claude/issue-20063-pr-assignee-mirrors-card",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/20066",
      "session": "session_01LNRg6FUMXYWgkAbDsfZpC8",
      "premise_still_valid": true,
      "summary": "Rule text only, as the ruling says. execution-duties.md (the claim section): the card assignee stays the PM's and the dev never writes it; the PR assignee equals the card's; the dev sets it in the same round as pr_create with `label-write.mjs --issue PR_NUMBER --assign LOGIN`; a seat's own PR is assigned to the seat; the takeover's step two moves it in the same stroke; the reader is `is:pr is:open assignee:LOGIN`. os-dev.md: rule 2 is narrowed to the CARD's assignee and gives the PR spelling, and the write-budget line names the PR-assignee write inside its label-write slot. PR 20066 is a draft, its assignee is os-elon-musk (read back), and it carries skip-changeset. The newest Claim (5824909861) names this branch, and the card's assignee was os-elon-musk when this run picked it up.",
      "tests": "No code changed. The gates below ran at head 6364f11. dispatch-gates --ran: '✓ 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).'",
      "gates": [
        "node scripts/check-closing-keyword-parity.mjs :: exit 0",
        "node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 · '40 assertions, 5 mutations … each driven to red'",
        "node scripts/check-comment-mask-corpus.mjs :: exit 0 · '7124 files, 0 disagree'",
        "node scripts/pm/check-governed-queue-guard.mjs --self-test :: exit 0 · '279 cases pass'",
        "node scripts/pm/check-harness-current.mjs --self-test :: exit 0 · 'all 26 cases passed'",
        "pnpm --filter @objectstack/lint run check:doc-formula-expressions :: first exit 3 (PREREQUISITE NOT MET: formula+lint not built, nothing measured) → built under os-verify-lock (VERDICT command-exit 0) → exit 0",
        "pnpm check:agent-model-declared :: exit 0 · 'no definition leaves its tier to the dispatching session'",
        "pnpm check:agent-test-spelling :: exit 0",
        "pnpm check:commit-card-trailers :: exit 0 · '81 cases pass'",
        "pnpm check:cross-package-test-inputs :: exit 0",
        "pnpm check:doc-authoring :: exit 0 · 'no growth, no burn-down unrecorded'",
        "pnpm check:driver-memory-census :: exit 0",
        "pnpm check:gitlink-declared :: exit 0",
        "pnpm check:nul-bytes :: exit 0 · 'no raw ASCII control bytes'",
        "pnpm check:pm-governed-merges :: exit 0",
        "pnpm check:pm-skill-id-lint :: exit 0 · '✓ check-skill-id-lint: 34 file(s) clean'",
        "pnpm check:pm-skill-ratchet :: exit 0 · '✓ check-skill-line-ratchet: declared cross-file moves: 2, total ceilings down 477 lines.'",
        "pnpm check:refd-timer-probe :: exit 0",
        "pnpm check:skill-frame-sync :: exit 0",
        "pnpm check:watch-hint-literal :: exit 0",
        "beyond derivation: pnpm check:pm-settings-deny-roster :: exit 0 (roster under .claude); pnpm check:pm-governed-prose :: exit 0",
        "node scripts/pm/check-governed-merges.mjs --test (2 paths) :: 'GOVERNED — Tier S' (both .claude/**)"
      ],
      "line_budget": {
        ".claude/skills/pm-dispatch/references/execution-duties.md": "183 → 183 (ceiling 183). Diff +2/-2. No re-wrap; paid by deleting three things already stated elsewhere: the clause 「原子对 step 1 设」 (same file, atomic-pair line), the clause 「跨账号 assignee 不是你 ⇒ 永不碰」 (SKILL.md card-state row), and the line 「dev 每个可编译小步即 push …」 (os-dev.md 资源纪律 6 carries it). All changed lines ≤120 bytes (118, 107).",
        ".claude/agents/os-dev.md": "402 → 402 (ceiling 402). Diff +3/-3. Three lines rewritten in place (103, 116, 120 bytes)."
      },
      "files_changed": [
        ".claude/skills/pm-dispatch/references/execution-duties.md",
        ".claude/agents/os-dev.md"
      ],
      "deviations": [
        "The dispatch named worktree /home/user/objectstack-issue-20063 as cut from 3557f85, but it did not exist when I started. I created it from origin/main at 5b9402d, since main had moved on, and recorded BASE=5b9402d.",
        "PM route said the takeover-② line (execution-duties :78) should get a 「含该卡 open PR」 increment. That line is 118 bytes, and every spelling of the increment I measured came to 130+ bytes. So I stated the takeover half on the rewritten assignee line as 「接管 ② 同笔换」 and left :78 byte-identical.",
        "PM route hoped for a net 0 with no deletion. It came to +1 line in execution-duties, paid for by deleting a duplicate. My first candidate for the deletion was 「释放是显式动作 …」 (state-machine.md :41 repeats it). I rejected it before committing because scripts/pm/check-half-states.mjs quotes that exact line as RELEASE_ACT_RULE, the protocol's own words, and deleting it would leave that quotation with no source.",
        "Commit trailer: I used the model-free pair (Claude-Session + 'Co-authored-by: Claude') that AGENTS.md requires, not the model-named Co-Authored-By from the harness attribution reminder."
      ],
      "mcp_calls": "0",
      "api_writes": "4 relay strokes, each one repository_dispatch executed as objectstack-fleet[bot]: (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (draft); (2) label-write assign → POST /repos/objectstack-ai/objectstack/issues/20066/assignees [os-elon-musk]; (3) label-write add → POST /repos/objectstack-ai/objectstack/issues/20066/labels [skip-changeset]; (4) this report → POST /repos/objectstack-ai/objectstack/issues/20063/comments. git push ×2 (empty-branch probe, then commit 6364f11) is not REST.",
      "open_questions": [
        {
          "question": "AGENTS.md (Tier H, not touched) :405-406 says a dispatched executor 'never writes the assignee'. In its paragraph that means the card's, but read on its own it now contradicts os-dev.md rule 2's PR-assignee write. Should a separate maintainer-merged edit make it explicit?",
          "options": [
            "A: replace 'it ⛔ never writes the assignee' with 'it ⛔ never writes the card's assignee (the PR's assignee mirrors the card's, set by the executor at pr_create)'",
            "B: leave AGENTS.md as is; the paragraph is about claiming the card"
          ],
          "recommendation": "A. It is a single sentence, and it removes the one place where the Tier H text and the Tier S rule read differently. It needs its own PR with the maintainer's approval."
        }
      ],
      "out_of_scope_findings": [
        "noted, not filed (no class): the ruling does not cover the PR assignee when a card that still has an open PR is RELEASED without a takeover. The new rule moves it only on takeover. Recorded in the PR's Acceptance notes. carrier: 承接者:无"
      ]
    }

    Generated by Claude Code

  3. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — os-dev-report 5825053461 reviewed against references/review-checklist.md by the domain:skills#1 seat (session_01LNRg6FUMXYWgkAbDsfZpC8) at 2026-09-25T01:22Z. Tier S (.claude/** ×2, check-governed-merges --test GOVERNED — Tier S) ⇒ in-seat ## Contract review record (next comment) + every check green ⇒ this seat lands it through the fleet-write relay (pr_ready + automerge_enable), the landing route the maintainer chose today (objectstack#20048, 「B:走中继落地」).

    PR form: draft PR #20066 on main, first line Fixes #20063, line 2 Clause-②: no — the only closing keyword; head 6364f11 (one commit, model-free trailers); assignee os-elon-musk (the rule this PR writes, applied to itself); labels documentation · size/s · skip-changeset (nothing publishes: .claude/**); 速读 draft present, session-URL footer intact.

    Diff, read hunk by hunk (origin/main...6364f11, +5/−5 over 2 files):

    • .claude/agents/os-dev.md (402 / 402): rule 2's head 「assignee 归 PM」 → 「卡 assignee 归 PM」; its second sub-item → 「恒不写卡的 assignee(空也开工,报 summary);PR assignee = 卡的:--issue PR_NUMBER --assign LOGIN」; the write-budget line names the PR-assignee write inside the existing label-write slot. Three lines rewritten in place, 103 / 116 / 120 bytes.
    • references/execution-duties.md (183 / 183): the :56 rule becomes two lines — 「卡 assignee 归 PM,dev 恒不写;PR assignee = 卡的,接管 ② 同笔换;读者 is:pr is:open assignee:LOGIN」 and 「dev pr_create 同轮 label-write.mjs --issue PR_NUMBER --assign LOGIN;席位自有 PR 指派自己」 — the ruling's four parts (card assignee stays the PM's; PR assignee mirrors it, set at pr_create; takeover moves it; the seat's own PR; the reader) all present. Paid by deleting the line 「dev 每个可编译小步即 push …」 (os-dev.md 资源纪律 6 carries it verbatim: 「每个可编译小步即 commit + push」) and the two clauses 「原子对 step 1 设」 (the atomic-pair line ① four lines below) and 「跨账号 assignee 不是你 ⇒ 永不碰」 (SKILL.md's card-state row 「不是你的就永不碰」) — each checked by this seat to survive elsewhere; no re-wrap. The takeover line :78 byte-identical (the increment did not fit 120 bytes; the takeover half lives on the rewritten line — accepted).
    • The ruling's exclusions hold: no gate, no patrol row, no tool; AGENTS.md untouched.

    Tests / gates (all at 6364f11, exit codes captured before any pipe): dispatch-gates --ran 20 / 20 derived families run, 0 NOT-MEASURED · pm-skill-ratchet 0 · pm-skill-id-lint 0 (34 clean) · skill-frame-sync 0 · doc-authoring 0 · agent-model-declared 0 · pm-governed-merges 0 · pm-governed-prose 0 · pm-settings-deny-roster 0 · nul-bytes 0 · commit-card-trailers 0 · governed-queue-guard self-test 279 · doc-formula-expressions 0 after the lock-guarded build (first attempt exit 3 = prerequisite, nothing measured). CI on the head at this ACCEPT: 15 success + 12 rostered skips, 2 in progress (Lint & Repo Gates, Type Check · workspace) — landing waits for them.

    Deviations (four, all accepted): base 5b9402d rather than 3557f85 (main moved; both files' regions unchanged) · the takeover-② increment did not fit the 120-byte line — stated on the rewritten line instead, accepted · the deletion candidate 「释放是显式动作」 was correctly rejected (quoted as RELEASE_ACT_RULE by check-half-states.mjs) — the better reading · attribution per AGENTS.md.

    Open question (the dev's), carried to the maintainer: AGENTS.md's claim paragraph (Tier H) says a dispatched executor 「⛔ never writes the assignee」 — in context the card's, but read alone it now contradicts os-dev.md rule 2's PR-assignee write. Recommendation A (one sentence: 「never writes the card's assignee (the PR's assignee mirrors the card's, set by the executor at pr_create)」) needs its own Tier H PR — put to the maintainer in the round report, ⛔ not filed by this seat without their word.

    Finding (the dev's, judged): a card released WITHOUT a takeover while its PR is still open — the rule moves the PR assignee only on takeover; Acceptance notes only, not filed (the release line already clears the card's assignee; the PR follows on the next claim).

    Landing from here: flip 定点 after the two jobs finish; relay pr_ready → automerge_enable (one actions file) → followed to MERGED; on MERGED the card closes by Fixes, then pm:dispatched and the assignee come off.

    Four axes, one line each: business need — measured (the maintainer could not tell who handles a fleet-authored PR; the assignee filter answers it) · long-term — the same identity record the card already carries, no second field · AI-error — one line each in the two files every dev and seat reads, no fallback path · startup scope — five lines rewritten, zero added, no gate.


    Generated by Claude Code

  4. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Contract review

    Served-tier: CONTRACT_REVIEW_TIER
    Head-sha: 6364f11c08248fa8a4d30902a108c4bfd05010db

    ① Derived judgments

    • The diff rewrites rule text in .claude/agents/os-dev.md (a MANDATORY-tier protocol file, built at the default tier under the one-line-class exit and reviewed here) and .claude/skills/pm-dispatch/references/execution-duties.md; no accepted set, schema or export changes: +5/−5, two governed Tier S files, skip-changeset correct (nothing publishes). Correct.
    • The rule as written matches the ruling 「同意」 on the seat's recommendation, part by part: card assignee stays the PM's and the dev never writes it (os-dev rule 2; execution-duties :56); PR assignee = the card's, set by the dev at pr_create with label-write.mjs --issue PR_NUMBER --assign LOGIN (both files); takeover ② moves it in the same stroke (execution-duties :56); a seat's own PR is assigned to the seat (:57); the reader is:pr is:open assignee:LOGIN (:56). The spelling is the one measured on objectui#10410 / docs(qa): rewrite the cli.migrate-meta-codemod P1 to what os migrate meta actually does #10412 / /api/v1/analytics/query still drops per-measure and dataset-level filter on the ObjectQL path — engine.aggregate receives no filter at all #10413 / objectstack#20066 through the relay's assign op. Correct.
    • Nothing the ruling excluded was added: no gate, no patrol row, no tool, AGENTS.md untouched. Correct.
    • Line-ratchet payment: execution-duties.md 183 → 183 by deleting one line and two clauses whose content survives elsewhere (os-dev.md 资源纪律 6; execution-duties ①; SKILL.md card-state row) — verified by this seat; no re-wrap. os-dev.md 402 → 402, three lines in place ≤ 120 bytes. Correct.
    • Reader check (skills-lane): every changed line has a named reader — the dev at pr_create (os-dev.md), the seat at claim and takeover (execution-duties.md), the maintainer's PR filter. No token tax.

    ② Semver level

    None owed: nothing published changes; consistent with Clause-②: no and skip-changeset.

    ③ Boundary flags

    • open_questions: one — AGENTS.md's claim paragraph 「never writes the assignee」 now reads narrower than the rule; Tier H, carried to the maintainer in the round report (ACCEPT names it). Not a blocker for this PR: AGENTS.md's paragraph is about the card, and AGENTS.md outranks the skill text where they conflict, so a dev reading both still writes only the card's assignee never — and the PR assignee write is what os-dev.md now instructs.
    • Not a widening: no accepted set touched.

    Implemented-by: claude/issue-20063-pr-assignee-mirrors-card
    Reviewed-by: session_01LNRg6FUMXYWgkAbDsfZpC8

    VERDICT: PASS


    Generated by Claude Code

  5. added 2 commits that reference this issue on Sep 28, 2026
    9b8c74c
    45bda83
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions