Skip to content

fix(pm): the relay reads the workflows split before requesting governed review - #31710

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-jhc8or
Nov 8, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-jhc8or

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steedos · project thread

Fixes #31690

维护者速读

  • 改了什么:中继在 PR 转 ready 时,如果改动只碰 .github/workflows/**,会先用合并队列守卫同一套读法(合并基点到 head)判 Tier,判出 S 就不再请你和 hotlong 审。
  • 为什么改:[Decision · ruled C] .github/workflows/** landing: split workflow PRs, keep high-risk edits Tier H, move the rest to Tier S #31538 之后 objectstack 的工作流 PR 可以是 Tier S,但中继只看路径,仍然给你发不需要的审阅请求。
  • 风险与回滚:读不到(无检出、缺提交、git 出错、读 compare 失败)、读出 H、混有其他受治理路径、或是 objectui/cloud 仓,一律照旧请审;回滚即 revert 这一个文件。
  • 先看:scripts/pm/fleet-write/execute.mjs 里的 workflowSplitReadable、workflowReadingFor 和 requestGovernedReview 新加的一段。
  • 两分钟验证:node scripts/pm/fleet-write/execute.mjs --self-test,看 312 个用例全过,其中 6 个新用例覆盖 S 不请、H 请、读不到请、混合请、objectui 请。
  • 需要你做的:无,席位审完按 TIER_DEFAULT 落地。

What changes

  • governedReviewPlan takes an optional workflowDiff and reads the tier through applyWorkflowSplit, imported from check-governed-merges.mjs. Without a reading the answer is byte-identical to the path-only plan.
  • requestGovernedReview (the pr_ready follow-up) reads the split only when workflowSplitReadable says so: every governed hit is the workflows row and the target is in its split.repos. workflowReadingFor then gets the merge base from GET /repos/{repo}/compare/{base.sha}...{head.sha}, checks that the checkout's origin is the target (slugFromRemote), fetches the merge base and head by sha at depth 1 when they are missing, and calls readWorkflowDiff with base = inventory base = merge base. This is the queue guard's pull_request leg. The reader is imported, not copied.
  • A reading that says S produces one row and no reviews read or requested. Every other outcome requests as before, and the verdict row names which case happened: workflow split read (merge base … → head …): <file> S|H (reason), workflow split UNREAD …: <reason> — fail closed, the path-only tier H stands, or workflow split not read: <another governed row | repo not in split.repos>.
  • The CLI passes checkoutGit(<repo root>) as deps.git. Without that seam the run reads as "no checkout" and fails closed.

Why

PR #31628 (ruling C on #31538) lets an objectstack workflow PR land as Tier S. The relay's governed-review follow-up still decided from paths alone, so it requested both approvers anyway. That was review flag B2 of contract review 6724981811.

The relay's checkout: fleet-write.yml uses actions/checkout@v7 with defaults: main, depth 1, persist-credentials: false. The pull's head and merge base are not in it. The run fetches those two commits anonymously (the repository is public) instead of deepening the checkout, so no workflow file is edited and this card's tier does not change.

Verification

Head 49babaa0 (fix 1fd8b980, plus a merge of origin/main).

  • node scripts/pm/fleet-write/execute.mjs --self-test: 306 → 312 cases, 25 batteries, exit 0. The governed-review battery floor goes from 30 to 36.
  • New pins: tier-s-workflow-pull-requests-no-one, h-reading-workflow-pull-requests, unreadable-workflow-pull-requests (covers no checkout, a commit the fetch cannot bring, git throwing, a fetch that throws, a checkout of another repository, and a refused compare), mixed-workflow-pull-requests, objectui-workflow-pull-requests, and the pure plan-with-a-reading case.
  • Ablation, run once and not kept: with workflowSplitReadable forced to read: false, the self-test exits 1 and the S, H and unreadable pins go red. The file was restored with git checkout HEAD --, and its hash matched the HEAD blob.
  • Live reading against real commits, from an empty git init checkout with the compare answered by the real API: ci(glue): narrow the Merge Queue Triage and Scheduled Full Run Card workflow_run triggers by branch #31544 (two workflow files) reads S on both files, with no review requested. ci(lint): run check:liveness in the required source-gates lane on every change #31559 reads H (a new continue-on-error). ci(fleet-write): the advisory mint comment names its five write rows and both read rows #31468 reads H (fleet-write.yml, Tier H by path). Each fetch took about 21 s from an empty repository.
  • Derived gates (dispatch-gates --commands, 36 families) all exit 0 at 1fd8b980. --ran reconciliation: 36 derived, 36 run, 0 NOT-MEASURED.

Clause-②: no
Metadata-protocol: none

skip-changeset: scripts/pm/** only, no published package moves.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (untouched)
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint passes. (CI owns the repo-wide lint)
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset. (no publish: skip-changeset)
  • 6. packages/spec touched: its generated artifacts are regenerated and committed. (not touched)
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English. (except the seat-required 维护者速读 section)
  • The Before Submitting list in CONTRIBUTING.md is done.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QsR2jTJ27J6P6KVq74iiqQ

…ed review

governedReviewPlan decided from paths alone, so a workflow-only pull the
queue guard measures as Tier S still had both approvers requested at
pr_ready. The follow-up now reads the queue guard's own measure
(readWorkflowDiff, imported) merge base to head when every governed hit
is the workflows row in its split.repos, and requests nobody when it
says S. No checkout, a missing commit, git throwing, an unread compare,
an H reading, a mixed pull or a repository outside split.repos request
exactly as before, and the verdict row says which.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsR2jTJ27J6P6KVq74iiqQ
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Nov 8, 2026
@github-actions github-actions Bot added the size/m label Nov 8, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · zhuangjianguo · session_01QsR2jT34CXs5fCn3BDirZw

维护者速读

  • 改了什么:中继在 PR 转 ready 时,如果受管命中只有 .github/workflows/**、仓库在 objectstack,就先用合并队列守卫同一套读法(readWorkflowDiff,合并基点 → head)判档;判出 S 就不再请你和 hotlong 审。中继的检出只有 main 一层,所以它先用 compare 接口取合并基点,再按 sha 匿名拉取两个提交(深度 1),只读不执行。
  • 为什么改:[Decision · ruled C] .github/workflows/** landing: split workflow PRs, keep high-risk edits Tier H, move the rest to Tier S #31538 裁决 C 之后 objectstack 的工作流小改可以是 Tier S,但中继只看路径,仍然给你发不需要的审阅请求,正是裁决要停掉的那种。
  • 风险与回滚:读不到(无检出、compare 失败、缺提交、git 出错、检出不是本仓)、读出 H、还碰了别的受管路径、或是 objectui/cloud 仓,一律照旧请审,日志行写明是哪一种。读法是从 check-governed-merges.mjs 导入的,没有第二份。最终把关仍是合并队列守卫,这里只决定发不发审阅请求。回滚即 revert 这一个文件。
  • 先看:scripts/pm/fleet-write/execute.mjs 的 workflowSplitReadable、workflowReadingFor,和 requestGovernedReview 里新加的一段。
  • 两分钟验证:node scripts/pm/fleet-write/execute.mjs --self-test,312 个用例全过。
  • 需要你做的:无。未受管的 scripts/pm,席位 ACCEPT 即落地。
  • 席位意见:ACCEPT。

席位核对

Head-sha: 49babaa0a307b3764c08d666259c1f938e6bffa1

  1. Shape: draft, base main, body carries Fixes #31690, skip-changeset. 1 file (scripts/pm/fleet-write/execute.mjs, +188 −11), inside the claim's file surface. check-governed-merges.mjs is imported, not edited. Ungoverned: TIER_DEFAULT, the seat's ACCEPT.
  2. Premise measured: on main governedReviewPlan (L706) took paths only, and both callers passed no reading, so a workflow-only objectstack PR always requested approvers.
  3. Code read: the split is read only when every governed hit is a split row whose split.repos names this repo (workflowSplitReadable); any other hit keeps the path-only plan. workflowReadingFor never throws: every failure returns measured: false, which applyWorkflowSplit keeps at H. The CLI hands in checkoutGit on the relay's own main checkout (L3582), so the reader that decides is main's code. The fetched commits are only read (cat-file, show, ls-tree), never checked out or run. A fork head the compare cannot answer falls to H.
  4. Gates: the seat ran node scripts/pm/fleet-write/execute.mjs --self-test at this head: 312 cases across 25 batteries, exit 0. Dev: 36 derived, 36 exit 0, --ran reconciled. Ablation (workflowSplitReadable forced unreadable) goes red on 3 pins. The dev also read live PRs from an empty checkout: ci(glue): narrow the Merge Queue Triage and Scheduled Full Run Card workflow_run triggers by branch #31544 S, ci(lint): run check:liveness in the required source-gates lane on every change #31559 H, ci(fleet-write): the advisory mint comment names its five write rows and both read rows #31468 H. Check-runs: none red at ACCEPT; auto-merge waits for the rest. K = 0.
  5. Accepted deviations: the order named the checkout but not a fetch. The relay now makes one extra compare GET and one anonymous depth-1 git fetch (about 21 s, 120 s timeout), and only on workflow-only objectstack pulls at pr_ready. No workflow file changed, so fleet-write.yml stays as it is.
  6. Landing: ungoverned, seat lands. pr_ready + automerge_enable on this head.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 8, 2026 22:44
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 8, 2026 22:44
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 8, 2026
Merged via the queue into main with commit 9feb925 Nov 8, 2026
49 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-jhc8or branch November 8, 2026 23:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fleet-write relay: governedReviewPlan reads paths only, so a Tier S workflow PR still gets approvers requested

1 participant