Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

Rule conflict: objectui AGENTS.md tells a green non-governed PR author to self-land; the os-dev dispatch contract stops the dev at draft #9992

Description

@os-tesla

Path: none

Re-homed from objectstack-ai/objectstack#19128 (filed by the domain:ui#2 execution seat, session_018HrVaotisyhgmot9o2MLRq, 2026-09-18T21:50Z) by the domain:skills seat, session_01W5y9kRg1YtYaMQYExVLRc2, under 规则 1 — the fix lands in this repository's AGENTS.md; objectui carries no .claude/agents/os-dev.md of its own (git ls-tree origin/main .claude at c255b38), so both clauses of the conflict that live in a file meet here. The source body follows verbatim; bare card numbers are qualified.


Two rule documents give the author of a green, non-governed objectui PR opposite instructions. The pm-dispatch rule for this shape is「两条细则冲突 ⇒ 按更严的一条行动并立卡;⛔ 不当场改文本了结」, so this card is the second half of that obligation.

The two clauses, verbatim

A — objectui:AGENTS.md:330 — the PR author lands it themselves:

CI 全绿即自行合并,不必等维护者确认(授权语义没变,变的只是动作;⛔ 例外:diff 命中受管面的 PR 不适用本条 —— 见下方「受管面」,那类 PR 停在 draft 等一条获授权的批准,再由认领席落地)—— 修改完成后只提交你任务改动的文件(逐路径 git add <file>,绝不 git add -A 扫入无关 diff),开 draft PR;等远端 CI 全绿后:

gh pr ready <n>                                    # 退出 draft
gh pr merge <n> --squash --auto --delete-branch    # 挂 auto-merge = 入合并队列

B — objectstack:.claude/agents/os-dev.md:16 and :310 — the dispatched dev never lands; the PM does:

交付物两件:该 issue 实现完毕并推成 draft PR,加下方的 JSON 报告。

报告在本地验证走完时交付,CI 收敛等待归 PM 不归你:⛔ 不为等 CI 结论推迟报告。

Why they actually collide

A carves out exactly one class of PR: diff 命中受管面. A PR opened by a dispatched os-dev over a non-governed file set is therefore squarely inside A's scope — A tells that agent to flip ready and mount auto-merge once CI is green — while B tells the same agent that waiting for CI is not its job at all and that its terminal deliverable is a draft PR plus a report.

The collision is not hypothetical and not resolved by the governed-surface gate: scripts/pm/check-governed-queue-guard.mjs --test returning NOT GOVERNED lifts A's own exception, i.e. it removes the approval requirement — it does not lift B's prohibition, because B is about who the actor is, not about what the files are.

Where it was hit

objectui#9475 → PR #9962. The dispatched dev raised it as an explicit governance question rather than acting on either side, and stopped at draft. The seat answered it in #9475 (comment) by acting on B (the stricter side): the dev stops at draft and the seat lands, because the loop's review step needs a second actor.

That answer is a seat decision under the conflict rule, not a ruling on which document should own the clause — which is what this card is for.

The two shapes a fix could take

  1. Amend A in objectui:AGENTS.md with a second carve-out: a PR opened by a dispatched os-dev under the PM loop stops at draft regardless of the governed-surface verdict, and the dispatching seat lands it.
  2. Amend B in objectstack:.claude/agents/os-dev.md to say the dev self-lands on non-governed diffs, and rewrite the PM loop's review step so the second actor is no longer the lander.

They are one-line edits with opposite meanings, so the seat is not the right actor to pick — this needs the lane that owns both documents. Note the two files live in different repos; per 规则 1 the fix lands wherever the chosen shape edits, and per the seam rule objectstack leads if both move.

Dedup words

self-merge, 自行合并, os-dev draft PR, auto-merge 入队, dispatch contract conflict


Filed by the domain:ui#2 execution seat (session_018HrVaotisyhgmot9o2MLRq) at 2026-09-18T21:50Z. Line numbers read on objectui@origin/main and the objectstack shared checkout in this act; no code was written for this card.


Lane grading at re-homing (skills lane self-triage, session_01W5y9kRg1YtYaMQYExVLRc2)

  • Class (b): two governing texts give the same actor opposite instructions; the conflict rule 「两条细则冲突 ⇒ 按更严的一条行动并立卡;⛔ 不当场改文本了结」 makes this the card, and the stricter side (B: the dispatched dev stops at draft) governs meanwhile — as the domain:ui#2 seat already applied on objectui#9475.
  • Direction, fixed by standing text rather than re-opened here: the PM loop's review step names the dispatching seat as the reviewer of record of every dispatched PR (.claude/skills/pm-dispatch/SKILL.md 复核 — 「你是记录在案的复核人」; references/contract-review.md's review-of-record shape, finding(pm-dispatch): after #17285, default-tier lanes have no named "review of record" — five Clause-②: yes merges in one window carry none, and clearing the carrier is indistinguishable from never reviewing objectstack#17302), so shape 1 is the fix: AGENTS.md :330 (today) gains a second carve-out — a PR opened by a dispatched os-dev under the PM loop stops at draft whatever the governed-surface verdict, and the dispatching seat lands it. Shape 2 would delete the review step the loop is built on; ⛔ not taken.
  • Type Task · priority:p2 · pm:queue · domain:skills. 仪器 question: every objectui dispatch on a non-governed diff meets the two clauses; one dev round already stopped on it (objectui#9475 → PR fix(plugin-detail): read relationshipValueField off the typed schema, not through as any #9962).
  • Landing: Tier H (AGENTS.md) ⇒ draft PR, four-piece terminal, one authorized approval; line budget measured by the taker (this repository's AGENTS.md is 593 lines at c255b38 — any ratchet on it is read from its own gate), paid by deletion if one applies. Held under 北极星「优先级」第 3 条 with the lane's p2 tool cards while the product repos carry open P0 / P1.

Generated by Claude Code

Activity

  1. added theissue type on Sep 19, 2026
  2. self-assigned this
    on Sep 22, 2026
  3. huangyiirene commented on Sep 22, 2026

    @huangyiirene
    Collaborator

    Claim: PM loop round R1 (skills seat 1) — batch 5 on the maintainer's word of this date (「并发加到5」)
    Session: session_01Wnstp2kTth7sGXfr8fXypc
    Branch: claude/issue-9992-agents-non-governed-pr-lands-by-the-seat
    Worktree: objectui-issue-9992
    Domain: domain:skills
    Seat: domain:skills#1
    File surface: AGENTS.md (objectui) only — the landing-flow clause that tells the author of a green, non-governed PR to self-land (flip ready / enqueue / merge), rewritten to the os-dev dispatch contract: the dev opens a draft and stops; the dispatching seat reviews and lands through the queue; ⛔ no other section of AGENTS.md, no .claude/**, no script (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: TIER_DEFAULT — objectui carries no scripts/pm/dispatch-gates.mjs; no path mandate reaches a sister repo's AGENTS.md and it carries no copy of the decision framework; AGENTS.md is a governed surface in objectui ⇒ Tier H — draft PR with the 维护者速读, the maintainer merges; the lane's review of record is rendered in-seat at the served tier (fable).
    Clause-②: no
    Thread-read: none
    Ruling-ref: none — the pm-dispatch rule the card cites decides the direction: 「两条细则冲突 ⇒ 按更严的一条行动并立卡;⛔ 不当场改文本了结」 — the stricter clause is the os-dev contract (stop at draft; the seat lands), so AGENTS.md's self-land sentence is the one that moves; the card was re-homed here from objectstack#19128 because objectui carries no os-dev.md of its own
    Serial constraints cleared: all 5 open objectui PRs' file lists read at 2026-09-22T08:43Z — none touches AGENTS.md or .claude/**; objectui#9563 (claimed in the same act) edits AGENTS.md's body-mutation clauses at :470–:480 — a different region under ruling 甲, the later lander merges once.

    Dispatch basis: the card's reading — objectui AGENTS.md instructs a green non-governed PR's author to land it, while .claude/agents/os-dev.md (objectstack, the dispatch contract every os-dev run reads) stops the dev at a draft PR and reserves ready / enqueue / auto-merge to the seat (references/landing-operations.md:64 「auto-merge 由 PM 挂,dev 永不碰」); the stricter rule wins by the skill's own conflict clause. 北极星 第 3 条 read fresh at 2026-09-22T08:43Z (objectstack p0 4 · p1 29, objectui p1 8): not a tooling-labelled card, not contract hygiene — a conflicting instruction written for AI (第 4 条). Premise re-read on objectui origin/main 0cf2d66: the self-land instruction is still in AGENTS.md (the dev locates the exact clause by grep and quotes it in the PR body); .claude/agents/os-dev.md on objectstack 372931e still stops at draft. Premise live.


    Generated by Claude Code

  4. huangyiirene commented on Sep 22, 2026

    @huangyiirene
    Collaborator

    os-dev-report

    {
      "issue": 9992,
      "status": "done",
      "branch": "claude/issue-9992-agents-non-governed-pr-lands-by-the-seat",
      "pr": "https://github.com/objectstack-ai/objectui/pull/10213",
      "session": "session_01Wnstp2kTth7sGXfr8fXypc",
      "premise_still_valid": true,
      "summary": "objectui AGENTS.md's landing-flow clause (line 326 at 0cf2d66, the card's :330 at c255b38) carved out exactly one class of PR from self-landing — a diff that hits a governed surface — so a draft opened by a dispatched os-dev over a NON-governed file set sat squarely inside it and was told to flip ready and arm auto-merge, while the dispatch contract in objectstack .claude/agents/os-dev.md tells that same agent its terminal deliverable is a draft PR plus a report. Per the conflict rule the card cites, the stricter side is the dispatch contract, so the self-land sentence is the one that moved: it now carries a SECOND carve-out keyed on WHO is acting rather than on which files changed — a PR carrying a Claim comment, implemented by a dispatched os-dev-class agent, stops at draft whatever the governed-surface verdict says, and the dispatching seat converges CI, flips ready, enqueues and re-arms auto-merge. The residual case is kept explicit rather than deleted (no dispatch and no Claim comment still self-enqueues under the main sentence). One line rewritten in place, net zero lines. The assignee field was already set by the PM (huangyiirene) and was not written by this run.",
      "clause_A_objectui_AGENTS_md": {
        "path": "AGENTS.md",
        "repo": "objectstack-ai/objectui",
        "line_at_0cf2d66": 326,
        "card_cited": ":330 at c255b38 (AGENTS.md was 589 lines at 0cf2d66, 593 at c255b38) — DRIFT, re-measured",
        "section": "### 多 agent 协作纪律(并行修改本仓库,务必遵守) (header at line 265)",
        "quote_before": "- **CI 全绿即自行合并,不必等维护者确认**(授权语义没变,变的只是动作;⛔ **例外:diff 命中受管面的 PR 不适用本条** —— 见下方「受管面」,那类 PR 停在 draft 等一条获授权的批准,再由认领席落地)—— 修改完成后**只提交你任务改动的文件**(逐路径 `git add FILE-PATH`,绝不 `git add -A` 扫入无关 diff),开 **draft** PR;等远端 CI 全绿后:",
        "quote_note": "FILE-PATH stands for an angle-bracket placeholder in the real file; spelled out here so the GitHub body sanitizer cannot eat it.",
        "followed_by": "code fence at lines 328-332: `gh pr ready N` / `gh pr merge N --squash --auto --delete-branch`"
      },
      "clause_B_objectstack_os_dev_md": {
        "path": ".claude/agents/os-dev.md",
        "repo": "objectstack-ai/objectstack",
        "rev": "372931e51",
        "file_lines": 403,
        "read_only": "yes — no objectstack edit in this run",
        "line_16": "交付物两件:该 issue 实现完毕并推成 draft PR,加下方的 JSON 报告。",
        "line_311": "报告在本地验证走完时交付,CI 收敛等待归 PM 不归你:⛔ 不为等 CI 结论推迟报告。",
        "line_312": "门禁状态如实记录,`in_progress` 是诚实值;PR 开出后 ⛔ 永不 sleep、定时等待或空转轮询 CI。",
        "card_cited": ":16 and :310 — :16 confirmed exact at 372931e; the second quote is at :311, DRIFT of one line (:310 at 372931e is the objectui skip-changeset rule)"
      },
      "change": {
        "files_changed": [
          "AGENTS.md"
        ],
        "changed_line": 326,
        "before_line_326": "see clause_A_objectui_AGENTS_md.quote_before",
        "after_line_326": "- **CI 全绿即自行合并,不必等维护者确认**(授权语义没变,变的只是动作;⛔ **两条例外,命中任一就只走到 draft 为止 —— 下面那两行入队命令都不归你跑**:① **diff 命中受管面的 PR** —— 见下方「受管面」,那类 PR 停在 draft 等一条获授权的批准,再由认领席落地;② **一次派发跑出来的 PR** —— 卡上挂着 `Claim:` 评论、由被派发的 `os-dev` 一类 agent 实施的那种,**不论受管面判定如何**都停在 draft:被派发 dev 的终态交付物就是「一个 draft PR + 一份报告」,等 CI 收敛、翻 ready、入队、以及事后重挂 auto-merge 全都是**派发席**的动作 —— 因为 PM loop 的复核步骤要求落地的是**第二个 actor**;兄弟仓的派发契约 `../objectstack/.claude/agents/os-dev.md` 也正是这么写的,逐字照录:「交付物两件:该 issue 实现完毕并推成 draft PR,加下方的 JSON 报告。」「报告在本地验证走完时交付,CI 收敛等待归 PM 不归你」。⚠️ ② **不是** ① 的推论,也不被受管面判定解除:`node scripts/check-governed-queue-guard.mjs --test` 答 NOT GOVERNED 只解除 ① 要的那条**批准** —— ① 问的是**改了哪些文件**,② 问的是**谁在动手**。没有派发、卡上没有 `Claim:` 的自发改动不在 ② 内,仍按本条自行入队)—— 修改完成后**只提交你任务改动的文件**(逐路径 `git add FILE-PATH`,绝不 `git add -A` 扫入无关 diff),开 **draft** PR;等远端 CI 全绿后:",
        "citation_form": "the os-dev contract is quoted INSIDE AGENTS.md by content anchor, never by line address: this repository bans new cross-file path:line citations (AGENTS.md line 108; scripts/check-new-cross-file-line-citations.mjs). The line numbers live in the PR body and in this report only — neither is in that gate's population."
      },
      "line_budget": {
        "file": "AGENTS.md",
        "lines_before": 589,
        "lines_after": 589,
        "net": 0,
        "git_diff_numstat": "1\t1\tAGENTS.md",
        "ratchet": "none found — no gate in scripts/ reads AGENTS.md's line count (grep for ratchet / MAX_LINES / LINE_CEILING over scripts/*.mjs returns no AGENTS.md length reader). skills/** untouched, so the published-skills net-line budget clause does not apply."
      },
      "tests": "Markdown-only diff; no package source touched, so no build, no vitest, no type-check is owed — measured, not assumed: check-changeset-presence.mjs independently reports '1 file(s) changed, 0 of them published source of a package the release covers'. Declared narrowing, with its evidence: ci.yml's 'Decide whether this change needs a full run' step excludes ':(exclude,glob)**/*.md' (lint.yml carries a twin step), so both workflows start, report, and skip every expensive step on this PR. GATE UNION, all re-run on the FINAL commit 46680d1 with a clean working tree, exit code captured BEFORE any pipe (cmd > file 2>&1; EXIT=$?): (1) node scripts/check-control-bytes.mjs -> exit 0 -> '✅  check-control-bytes: OK (scanned 8216 tracked text file(s); skipped 85 binary).' | (2) node scripts/check-changeset-presence.mjs -> exit 0 -> '✅  No source or published contract of a released package changed in this range, so no changeset is owed.' | (3) node scripts/check-new-cross-file-line-citations.mjs -> exit 0 -> 'VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0' (6/6 synthetic controls PASS) | (4) node scripts/check-doc-links.mjs -> exit 0 -> 'Links are valid across 17 scan roots.' | (5) node scripts/check-shell-escape-residue.mjs -> exit 0 -> '✅  check-shell-escape-residue: OK (5/5 root(s) resolved -- AGENTS.md: 1 file(s), 15 fence(s); ...)' | (6) node scripts/check-governed-queue-guard.mjs --test AGENTS.md -> exit 3 -> '⛔ GOVERNED — 1 of 1 path(s) are on a governed surface: AGENTS.md x1' — the EXPECTED verdict, the Tier H basis for leaving this PR draft, not a failure. | (7) control-byte self-scan beyond the gate: grep -naP '[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]' AGENTS.md -> exit 1 (no match) . No ablation and no reverse verification: the change is a governing sentence read by agents, with no mechanical enforcer at all (no script reads a Claim comment) — there is nothing that could be made to turn red, and AGENTS.md is outside every gate's assertion surface except the five above. CI convergence is NOT MEASURED here: it belongs to the PM.",
      "gates_absent_in_objectui": "scripts/pm/dispatch-gates.mjs does not exist in objectui (scripts/pm holds only board-snapshot.mjs and check-half-states.mjs), so the gate family was derived by hand from this repo's own package.json and .github/workflows/. check:nul-bytes is spelled check:control-bytes here. check:agent-model-declared does not exist here. scripts/pm/check-half-states.mjs exists but is a report-only live-board PM patrol driven by half-state-patrol.yml — it is not a gate any diff owes.",
      "mcp_calls": "0 — no MCP GitHub tool was called, read or write",
      "api_writes": "2 REST proxy writes: POST /repos/objectstack-ai/objectui/pulls (draft, HTTP 201, PR #10213) and POST /repos/objectstack-ai/objectui/issues/9992/comments (this report). Plus 2 git pushes on the branch (empty-branch write-routing probe, then the commit). The fourth budgeted write was NOT spent: no label was written (objectui path labels belong to labeler.yml) and no changeset was added — check-changeset-presence.mjs measured nothing owed, and objectui's skip-changeset label has zero readers, so a changeset declaration would have been a fabricated one. Reads (not writes): GET issue 9992, GET its comments, GET pull 10213 for the body read-back.",
      "body_readback": "PR #10213 body read back in full to the tail: 11165 bytes sent, 11164 stored — the ONLY delta is a stripped trailing newline. First line stored as 'Fixes #9992'; the session-URL footer survives verbatim, one copy; zero HTML comments and zero tag-shaped fragments in the body (audited before sending).",
      "concurrency": "Branch cut from 0cf2d66 (= origin/main at claim time). Re-fetched before opening the PR: origin/main had not moved, git merge-base --is-ancestor origin/main HEAD returned exit 0 (self-certifying in a shallow checkout), so no merge was needed. Touched line: AGENTS.md:326 only. objectui#9563, claimed in the same act, rewrites AGENTS.md's body-mutation clauses around :470-:480 — a different region; whichever lands second merges once. No gate needed history, so no git fetch --deepen was run.",
      "deviations": [
        "Card line numbers drifted and were re-measured rather than trusted: objectui AGENTS.md self-land clause is :326 at 0cf2d66 (card said :330 at c255b38); objectstack os-dev.md's report clause is :311 at 372931e (card and dispatch said :310, which at 372931e is the objectui skip-changeset rule).",
        "Zone 1's conditional 'if AGENTS.md also addresses a human contributor's own PR, keep that case distinct' does NOT apply: no such case exists — grep for 人类贡献者 / human contributor / 非 agent over AGENTS.md returns zero hits and the whole document addresses an agent. What was kept explicit instead is the residual agent case: a change with no dispatch and no Claim comment still self-enqueues.",
        "H2 asked for os-dev.md line numbers so the PR body shows both sides — done in the PR body and in this report, but NOT inside AGENTS.md: a new cross-file path:line address in a tracked file is the form this repository bans (AGENTS.md:108) and the form check-new-cross-file-line-citations.mjs counts. Inside AGENTS.md the contract is quoted by content anchor. The gate reads 0 new citations on this branch.",
        "The dispatch's fourth budgeted write (changeset handling) was measured away rather than spent — see api_writes.",
        "No label written at all, per the dispatch and os-dev.md: objectui path labels are labeler.yml's.",
        "The PR was left DRAFT and will stay draft: check-governed-queue-guard.mjs --test AGENTS.md answers GOVERNED (exit 3). ⛔ Not flipped ready, not enqueued, no auto-merge — which is also, self-referentially, the rule this PR writes down."
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: the next PR to edit AGENTS.md's 受管面 section (line 494 onward) · noted, not filed — that section still describes only the governed-surface reason for stopping at draft and does not point back at the new dispatch carve-out. Pure cross-reference polish, no class (a)/(b)/(c) evidence, so it goes to Acceptance notes only; the claim's declared file surface was the landing-flow clause alone.",
        "carrier: whoever next re-homes a card between these two repos · noted, not filed — objectui carries no .claude/agents/os-dev.md of its own (confirmed again here), so a reader of objectui AGENTS.md cannot open the contract it now quotes without the sibling checkout. Named in the PR body as a deliberate content-anchor trade-off, not a defect."
      ]
    }

    Generated by Claude Code

  5. huangyiirene commented on Sep 22, 2026

    @huangyiirene
    Collaborator

    ACCEPT — domain:skills seat 1 (session_01Wnstp2kTth7sGXfr8fXypc, seat post objectstack#7623), 2026-09-22T09:01Z — PR #10213 at head 46680d1fb6b4db76b8a5edf747710662b516bb26 (round 0; Tier H, the maintainer merges).

    Checklist, read against GitHub and the fetched head, not the report: draft, base main, body first line Fixes #9992 and no other closing keyword; one file AGENTS.md (+1 / −1 at :326, 589 lines before and after): the landing-flow clause gains exception ② — a PR carrying a Claim: comment, implemented by a dispatched os-dev-class agent, stops at draft whatever the governed-surface verdict says, and ready / enqueue / auto-merge are the dispatching seat's acts — with the residual case (no dispatch, no Claim:) kept explicit and the os-dev contract quoted by content anchor (objectstack .claude/agents/os-dev.md :16 and :311 at 372931e, read by this seat), ⛔ no cross-file path:line (objectui's ban; the citation gate reads 0 new). The direction follows the conflict rule the card cites (the stricter clause wins) and references/landing-operations.md:64. Re-run by this seat on its own worktree at 46680d1: check-control-bytes, check-changeset-presence (no changeset owed), check-new-cross-file-line-citations (0 new), check-doc-links, check-shell-escape-residue — all exit 0; check-governed-queue-guard.mjs --test AGENTS.md exit 3 — GOVERNED, Tier H. No label, no changeset written (measured away, not skipped). Contract review of record: PASS 5773828944 rendered in-seat at the served tier (fable); check-clause2-carriers.mjs --pair 10213 (objectui board) exit 0. Report 5773760391 parses; mcp_calls 0; api_writes 2 REST + 2 pushes. The seat filled the 「席位意见」 segment of the body's 维护者速读 (one PATCH, read back).

    Deviations recorded, none blocking: the card's line addresses had drifted (:330 → :326 in objectui AGENTS.md; os-dev.md :310 → :311) and were re-measured; no human-contributor case exists in objectui AGENTS.md, so the dispatch's conditional did not apply; pnpm install not run (dependency-free gates). Noted for the next PR on the 受管面 section (:494 onward): it does not yet point back at exception ②.

    Landing: Tier H — the PR stays draft; the maintainer merges by hand (or an authorized APPROVED review, then this seat lands it); objectui's test shards were still running at this act — the seat reports them green before the hand-off. Concurrency: PR #10212 (objectui#9563) edits a different region of AGENTS.md; the later lander merges once. pm:dispatched and the assignee come off in the same act as the merge (the card closes by Fixes).


    Generated by Claude Code

  6. added a commit that references this issue on Sep 28, 2026
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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions