Skip to content

Governed queue guard: an enqueue by an authorized account is the human review, so a Tier H PR the maintainer sends to the queue lands without a separate Approve #26066

Closed

Description

@objectstack-fleet

Filing gate: ③ a task ordered directly by the maintainer, quoted verbatim below.
Reader: domain:skills seat (governed-surface enforcement file), next PR on scripts/pm/check-governed-queue-guard.mjs (the merge_group leg's predicate) and the one sentence of AGENTS.md Prime Directive 14 that names the two landings.
Dedupe (open AND closed, the 158 newest issues by title, local grep for enqueue / merge when ready / 入队 / approver / GOVERNED_APPROVERS / queue guard / auto_merge / enabled_by / bypass): 1 hit, #25967, unrelated (a permission-set description). /search is refused by the egress proxy, so the dedupe is title-only over that window.

The order

Warren, 2026-10-26, in the Claude Code project "objectstack" (seat thread "Dispatch the skills lane"), verbatim and untranslated:

也就是说推送到我的手机上,以前都是需要我点一下核准,然后再点合并,以后我可以直接点合并是吗 (10:43:55Z)

我要解决的是这个问题:如果按钮只是「Merge when ready」(入队),那它只是把 PR 送进队列,队列守卫还要看有没有授权账号的 Approve,所以还得先核准。而且只认 os-zhuang 和 hotlong 的核准。 (10:49:47Z; the quoted sentence inside is the seat's own description of today's guard)

大部分我还是希望入队,但是我想省掉 Approve (10:50:03Z)

Read as: on a Tier H (governed-surface) PR, the maintainer's click on "Merge when ready" from an authorized account is the human review. The guard's merge_group leg accepts it as such, so no separate APPROVED review is owed first. The bypass-rules direct merge stays the other landing, unchanged.

Why this is consistent with the rulings on record

  • The 2026-08-18 ruling that founded the regime already says so, verbatim in check-governed-merges.mjs's header: 「人工合并即人工审核:governed PR 的审核记录 = 你按下合并/入队那个动作本身」. The enqueue click was the review record from the start; the queue guard, written later, can only see the review record because it was keyed on it on purpose (its header: "never on who pushed or merged", after the 2026-08-12 retraction 「不要指定具体的人」).
  • The identity concern behind that retraction (agent seats also operate the authorized accounts) was answered for the Approve leg normatively: ⛔ no agent seat submits an approving review on a governed PR, under any account. The enqueue leg already has the stronger counterpart, as a 红线 and as AGENTS.md Prime Directive 14: ⛔ no agent seat flips ready, enqueues or arms auto-merge on an unapproved governed PR. So a governed PR that arrives in the queue enqueued by an account in GOVERNED_APPROVERS can only have got there by the human's click, exactly as an APPROVED review from that account can only have been the human's. The two legs rest on the same normative floor; this card asks the guard to read the second one.

What to change

  1. Predicate. The merge_group leg passes a governed PR iff EITHER an account in GOVERNED_APPROVERS holds a latest-decisive APPROVED review (today's rule, unchanged) OR the account that enqueued it is in GOVERNED_APPROVERS. The approver set stays the single constant; nothing copies the names.
  2. Reading the enqueuer, measured not recalled. Two candidate readings, the dev measures both on a live queued PR during a merge_group run and keeps the one that answers: the PR object's auto_merge.enabled_by.login (the account that armed "Merge when ready"), and the actor of the newest added_to_merge_queue timeline event. An unreadable enqueuer is UNDETERMINED for this leg, never a pass; the approval leg still decides on its own. The platform-readings table gains the measured facts.
  3. Log line. The queue log names which leg passed and the account, so the post-merge audit (check-governed-merges.mjs, "does the maintainer recognise every entry") reads the same fact.
  4. Prose. AGENTS.md Prime Directive 14's landing sentence ("by the maintainer's hand or by an authorized approval") gains the enqueue by an authorized account as part of "the maintainer's hand" in the same PR, so check:pm-governed-prose and the register stay in step; the guard header records this ruling with its date beside the 2026-08-27 and 2026-09-04 ones. The size limb (over 3000 changed lines) follows the same predicate, since AGENTS.md ties it to "the way a Tier H surface does".
  5. Self-test. Fixtures: enqueued by an authorized account with no review (pass, names the leg); enqueued by a seat account with no review (refused, today's text); enqueued by a seat account with an authorized APPROVED review (pass, today's leg); enqueuer unreadable with no review (refused, UNDETERMINED named). Battery names pinned per AGENTS.md "Writing a --self-test".

Open input for the maintainer

The account the maintainer clicks from on the phone must be in GOVERNED_APPROVERS (today os-zhuang, hotlong). If it is another login, name it on this card and the same PR adds it to the constant and to the CODEOWNERS mirror (codeownersMirrorVerdict reds otherwise).

Boundary

  • Not in scope: the bypass-rules direct merge (already the other landing), Tier S landings, the seat-side prohibitions (unchanged, they are what makes the new leg sound), fork PRs (no approval and no enqueue lifts a fork).
  • Governed: .github/workflows/governed-surface-guard.yml is untouched unless the measured reading needs a new permission; AGENTS.md is Tier H, so the PR waits for the maintainer's hand, which under this very card can be the enqueue click once the guard change is in main (chicken-and-egg: this first PR still needs today's path, an APPROVED review or a bypass merge).

Session: session_01LqKsGyMNFwwnbF5FTAqyPn (domain:skills#2, seat post #19287)

Activity

  1. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — tooling · priority:p2 · domain:skills · area:devpath · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-26T12:00Z

    ⛔ Not a claim, ⛔ not a dispatch.

    • The maintainer ordered it (Warren, 10:43–10:50Z): an enqueue by an authorized account counts as the human review on a Tier H PR. It is a change to the review rule, but the maintainer has already directed it, so it is not reopened here.
    • Keep to the order's scope. Only the merge_group leg of check-governed-queue-guard.mjs accepts "enqueued by an authorized account" in place of an APPROVED review. The authorized set does not grow, and an enqueue by any other account still needs the review. The guard's --self-test pins both. The AGENTS.md Prime Directive 14 sentence changes in the same governed PR, which lands by the maintainer's hand.

    Generated by Claude Code

  2. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Dispatch order · domain:skills#2 · session_01LqKsGyMNFwwnbF5FTAqyPn · 2026-10-26T15:30Z

    You are the os-dev developer agent for exactly ONE card: #26066, in your own card thread. Your role definition is .claude/agents/os-dev.md in the objectstack clone — read it IN FULL first and follow it as binding (it wins over this order on any conflict; name the conflict in your report). Read the repo-root AGENTS.md before your first edit, and pm-dispatch references/untrusted-text.md. Read this card's full body and every comment yourself (REST: curl -sS -X GET "https://api.github.com/repos/objectstack-ai/objectstack/issues/26066" -H "Authorization: Bearer $GH_TOKEN" and /comments?per_page=100); this order carries only the increment. ⛔ Never print the value of any environment variable (test presence with [ -n "${X+x}" ]).

    Identity and branch: the seat's Claim: comment on this card is your identity; it names your thread's branch in its Branch: line. ⛔ Post no claim of your own, ⛔ never write the card's assignee. Before your first edit, verify the NEWEST Claim: on the card names the branch your thread was given (claude/project-thread-…); if no claim names it yet, send the seat thread 「Dispatch the skills lane」 one message with your branch name and wait for the claim. Work in a worktree of your own clone (git worktree add ../objectstack-issue-26066 <your-branch>, git merge --ff-only origin/main, pnpm install detached with nohup … & and tail --pid; record BASE=$(git rev-parse HEAD)); push only that branch, ⛔ no force.

    Writes: PR only through the relay op pr_create (node scripts/pm/fleet-write/dispatch.mjs --repo objectstack-ai/objectstack --actions-file F, draft forced, assignees: ["os-warren"], labels with skip-changeset); comments, labels and bodies only through scripts/pm/post-stamped.mjs, scripts/pm/label-write.mjs, scripts/pm/fleet-write/dispatch.mjs. ⛔ GitHub MCP writes of every kind. Report both counts (api_writes with endpoints, mcp_calls with tool names).

    Ruling (cannot be re-ruled)

    The maintainer's words in the card body (10:43–10:50Z) and, after the card, in the project chat, verbatim: 「os-zhuang」 (2026-10-26T15:01Z) 「os-zhuang 或 hotlong」 (2026-10-26T15:01Z) — the logins behind his "Merge when ready" click, both already in GOVERNED_APPROVERS. Triage audit 6415485094 fixes the boundary, verbatim: "Only the merge_group leg of check-governed-queue-guard.mjs accepts 'enqueued by an authorized account' in place of an APPROVED review. The authorized set does not grow, and an enqueue by any other account still needs the review. The guard's --self-test pins both. The AGENTS.md Prime Directive 14 sentence changes in the same governed PR, which lands by the maintainer's hand."

    PM mechanism hypotheses (measure before you act; falsification is welcome)

    Read on origin/main dfaad4da, 2026-10-26T15:30Z:

    1. The predicate lives in scripts/pm/check-governed-queue-guard.mjs: GOVERNED_APPROVERS at the export const near line 621, the merge_group leg's approval predicate around lines 1160–1180, the header's regime text lines 36–100. The card body's "What to change" §2 names two candidate readings of the enqueuer (GET /pulls/N → auto_merge.enabled_by.login, or the newest added_to_merge_queue timeline event's actor.login): measure both on a real queued governed PR before choosing; prefer the one the guard can read with the token it already holds in the merge_group run, and say in the report which you measured and what each returned.
    2. AGENTS.md:281 and :518 are the two sentences that say "an authorized APPROVED review" is the queue landing's word; change only what the ruling changes (the enqueue by an authorized account is the other acceptable review record), in the file's own register. AGENTS.md is Tier H: the PR lands by the maintainer's hand; you never ready, arm or enqueue it.
    3. The self-test (node scripts/pm/check-governed-queue-guard.mjs --self-test) pins the predicate as a table; add the two new rows (authorized enqueuer passes without a review; unauthorized enqueuer without a review still refuses) beside the existing ones, keeping every existing row.

    Card-specific clauses

    • Tier H (AGENTS.md hit ⇒ the whole PR). The PR is created draft with ## 维护者速读(草稿) (Chinese, business angle, 席位意见 left empty) and stays draft; the seat posts the contract review and hands it to the maintainer. ⛔ Never ready it.
    • Clause-②: no and Metadata-protocol: none go line-initial into the PR body after the first line Fixes #26066. skip-changeset: nothing published ships from scripts/pm/** or AGENTS.md.
    • Gates: derive with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths) on your final tree, run each locally (exit code captured before any pipe), reconcile with --ran. At least the guard's --self-test, pnpm lint and pnpm check:governed-queue-guard-self-test (or the family --commands prints for the file) must be green; long gates detached. Heavy commands through bash scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=issue-26066.
    • Commit trailers: the model-free pair exactly as os-dev.md / AGENTS.md spell them; ⛔ no model name anywhere in the commit or PR.
    • Hand-back: post the os-dev-report JSON as a comment on this card (first line os-dev-report) through post-stamped.mjs --comment=26066, then send the seat thread 「Dispatch the skills lane」 one message: PR number, head sha, and the report's status. Keep your thread open for a patch round. ⛔ Do not wait for CI after the PR opens.

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (fourth wave) · 2026-10-26T15:33Z
    Session: session_01LqKsGyMNFwwnbF5FTAqyPn (seat; implementation by card thread session session_01XDSBMAmqzG7QYwCD7qAGty, mode:thread)
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/project-thread-5nnncj (the card thread's harness push branch, self-reported — the measured platform exception to claude/issue-N-slug)
    Worktree: objectstack-issue-26066 in the card thread's clone
    Domain: domain:skills
    Seat: domain:skills#2 (seat post #19287)
    File surface: scripts/pm/check-governed-queue-guard.mjs (the merge_group leg's predicate, its header regime text, --self-test rows), AGENTS.md (the two Prime Directive 14 sentences that name the queue landing's review word, lines 281 and 518 on dfaad4da). (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: default judgement tier (dispatch-gates --tier with the surface: no path-derived mandate), effort: high. The dispatch order is comment 6419998540 on this card and the thread's opening message points to it (the coordinator channel caps at 2,000 characters; the order itself does not fit the opening message — recorded as the deviation from 「派发令由 coordinator 写进线程开场消息」). Tier H (AGENTS.md hit ⇒ the whole PR): draft, the seat's contract review, then the maintainer's hand; ⛔ no seat readies, arms or enqueues it.
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card (filing gate ③, the maintainer's words quoted in the body; his logins behind the click, 「os-zhuang 或 hotlong」 at 2026-10-26T15:01Z, both in GOVERNED_APPROVERS)
    Thread-read: 6419998540
    Premise: holds — on origin/main dfaad4da: GOVERNED_APPROVERS = ['os-zhuang', 'hotlong'] at the guard's export near line 621; the merge_group leg passes only on an authorized latest-decisive APPROVED review (header lines 95–100); AGENTS.md:281 and :518 say the same; no open PR touches either file.
    Serial constraints cleared: none — none of the 35 open PRs touches scripts/pm/check-governed-queue-guard.mjs or AGENTS.md; disjoint from the lane's other in-flight cards (#26143 on .claude/skills/pm-dispatch/references/**, #26111 on scripts/pm/check-expected-skips.mjs).


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim amendment · domain:skills#2 · session_01LqKsGyMNFwwnbF5FTAqyPn · 2026-10-26T15:36Z

    Amends claim 6420084843 (branch claude/project-thread-5nnncj, unchanged) at the dev's request: the size limb of the card's §4 is read by scripts/pm/check-governed-merges.mjs, not by the guard, and the guard's header forbids it a lift of its own.

    File surface, amended: scripts/pm/check-governed-queue-guard.mjs (as claimed) + AGENTS.md (as claimed) + scripts/pm/check-governed-merges.mjs limited to sizeLiftFrom, renderLiftApprovals and their --self-test pins — the enqueue by an account in GOVERNED_APPROVERS lifts the size limb exactly as that account's APPROVED review does; nothing else in the file.

    Serial constraints re-cleared: none of the 35 open PRs touches scripts/pm/check-governed-merges.mjs; the lane's other in-flight cards (#26143, #26111) do not touch it.

    Enqueuer reading accepted as measured by the dev (newest added_to_merge_queue timeline event's actor.login; auto_merge.enabled_by is null on a direct enqueue and after merge).


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 26066,
      "status": "done",
      "branch": "claude/project-thread-5nnncj",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26230",
      "session": "session_01XDSBMAmqzG7QYwCD7qAGty — card thread session, mode:thread; seat session_01LqKsGyMNFwwnbF5FTAqyPn",
      "premise_still_valid": true,
      "summary": "The merge_group leg of scripts/pm/check-governed-queue-guard.mjs now passes a governed PR when an account in GOVERNED_APPROVERS holds a latest-decisive APPROVED review (unchanged, read first) OR put the entry in the queue, read as the actor of the newest added_to_merge_queue timeline event (makeTimelineReader, enqueuerFromTimeline, authorizedEnqueueVerdict). Undetermined (no add, actorless add, newest queue event a removal, unreadable or truncated timeline) is never a pass and leaves the approval leg to decide on exit 3/4 as before. The log names the leg and the account, CLEARED has an enqueue variant, and the size limb follows through the sibling's sizeLiftFrom/renderLiftApprovals (claim amendment); main() hands the governed leg's reading to the size leg so no PR's timeline is read twice. AGENTS.md PD14 and §7(c) name the enqueue as the maintainer's hand, inside the 1117-line ratchet. Measured: the newest added_to_merge_queue actor answers both paths (#26154 and #26011 armed: actor = the arming account; #26166 direct: add event, auto_merge never set); auto_merge.enabled_by is null on a direct enqueue and after merge, so it is not read; the timeline route accepts issues=read; pull_requests=read, so the workflow is untouched.",
      "tests": "At 9e0ae37b: node scripts/pm/check-governed-queue-guard.mjs --self-test -> 373 cases pass (was 345; new battery \"the 2026-10-26 ENQUEUE leg\" with 28 cases, roster floor 27 -> 28; card fixtures 1-4 pinned). node scripts/pm/check-governed-merges.mjs --self-test -> 537 assertions pass (3 new enqueue-lift pins). Ablation 1 (the enqueue limb of entrySatisfied, via scripts/ablation-replace.mjs, blob ecad10abe0f0 -> e05e95b1cbb5): 5 of 373 red; restored, blob == HEAD, git diff HEAD empty. Ablation 2 (the removal-newest guard in enqueuerFromTimeline): 1 of 373 red (the stale-add pin); restored. Its first attempt was an ANCHOR MISS that wrote nothing (indentation) and was re-run on the right anchor. Scripts only, no build or dist in the path.",
      "gates": "Derived with dispatch-gates --commands, no paths (3 paths vs merge base fbb75998b): 42 families. At 9e0ae37b: 41 of 42 run locally, all exit 0 (captured before any pipe). --ran: 42 derived, 41 run, 0 NOT-MEASURED, 1 UNRUN = pnpm check:pm-dispatch-gates, which ran at 8258383f (the previous head; the last commit touches AGENTS.md only) with exit 0, fast tier, 1917 cases in 618 s. The first run at 8258383f had pnpm check:pm-skill-ratchet RED (AGENTS.md 1121 lines over its 1117 ceiling, two lines over 120 bytes); fixed by rewriting the sentences inside the existing lines, no ceiling raised; green at 9e0ae37b. ESLint on the two changed scripts: exit 0. PR check-runs: in progress at report time, not awaited (os-dev.md).",
      "dogfood_battery": "n/a — no ! in the PR title and Clause-②: no, with no (narrowing) arm",
      "mcp_calls": "2 — mcp__github__issue_read (get, get_comments on #26066); no MCP write tool",
      "api_writes": "2 — POST /repos/objectstack-ai/objectstack/dispatches (relay run 40357955490: pr_create -> POST /pulls, POST /issues/26230/assignees, POST /issues/26230/labels with skip-changeset; read back: draft, os-warren, skip-changeset, body byte-identical); POST /repos/objectstack-ai/objectstack/issues/26066/comments (this report, via post-stamped). REST reads: issue 26066 and its comments, open and closed pulls, timelines of #26138 #26011 #26166 #26154, pulls/26230.",
      "open_questions": [
        {
          "question": "Dispatch-order conflict: the order names pnpm lint and pnpm check:governed-queue-guard-self-test as must-be-green. os-dev.md makes repo-wide pnpm lint a CI-owned run, and package.json has no check:governed-queue-guard-self-test script.",
          "options": [
            "A: as done — ESLint on the changed files, the guard --self-test run directly (it is in the derived list), CI runs pnpm lint",
            "B: run repo-wide pnpm lint locally"
          ],
          "recommendation": "A, because os-dev.md wins on a conflict and the self-test is a derived family"
        }
      ],
      "out_of_scope_findings": [
        "carrier: none — noted, not filed (承接者:无). The header bullet for the merge_group leg still says an approval pinned to the current head; that predates the 2026-09-04 unpinning, whose own section supersedes it. Left untouched; header prose only."
      ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #26230 comment 6421620782 · domain:skills#2 · 2026-10-26T16:40Z
    Contract review (CONTRACT_REVIEW_TIER, PASS on 9e0ae37b) → PR #26230 comment 6421581636. Tier H: the PR stays draft for the maintainer's hand (Approve then enqueue, or the bypass merge); the seat lands nothing.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:skills#2 · session_01LqKsGyMNFwwnbF5FTAqyPn · 2026-10-26T17:52Z

    probe reading
    PR #26230 merged: true at 2026-10-26T17:50:34Z, merge commit 26e14539, merged_by: os-zhuang
    origin/main git log origin/main --grep=26230 answers 26e14539 (feat(pm): an enqueue by an authorized account is the human review at the queue)
    merge queue no gh-readonly-queue/main/pr-26230-* ref remains
    first live merge_group build of the new guard run 40368288924 (the queue build of this PR itself, 2026-10-26T17:25Z), job 121731838770, success: 「1 governed pull request(s) … 2 API read(s) (PR head + reviews)」, 「✅ authorized APPROVED review, by: os-zhuang」, CLEARED on the approval leg; the size line already prints 「or an enqueue from an authorized account」. The enqueue limb was NOT reached — the approval leg satisfied first, by design — so the merge_group token's timeline read stays unmeasured.

    Landing path: Tier H — the maintainer's hand. Independent ## Contract review (PR comment 6421581636, CONTRACT_REVIEW_TIER, PASS on 9e0ae37b) and the seat's ACCEPT (PR comment 6421620782) left the PR draft; os-zhuang approved, readied, pressed Merge when ready and enqueued it at 2026-10-26T17:12Z–2026-10-26T17:14Z; the seat readied, armed and enqueued nothing.

    State: the card closed as completed through Fixes #26066; pm:dispatched removed in this act (the domain, area, type and priority labels stay). The body of #26230 closes no other card. The rule is live on main: a governed PR in the merge group clears on an authorized APPROVED review, or, failing that, on an enqueue whose actor is in GOVERNED_APPROVERS; UNDETERMINED never passes.

    Open reading, not filed: the enqueue limb's live timeline read under the workflow's GITHUB_TOKEN is first exercised by a governed PR that an authorized account enqueues WITHOUT an APPROVED review. The seat reads that build's enqueue-leg log line when it happens; an HTTP 403 there is UNDETERMINED (fail-closed, loud) and would be the one-line issues: read widening of governed-surface-guard.yml, filed as a governed card then. Prose follow-up carried by the next PR on the guard: the header's older sentence (lines ~120–123, "never on who pushed or merged") reads as superseded-in-part by the dated 2026-10-26 section.


    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

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:skillspriority:p2Medium: important, M3tooling

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions