Repository navigation
chore(governance): .github/workflows/** joins the governed surfaces (objectui#12255) - #12289
Merged
Merged
Conversation
…objectui#12255) The maintainer's ruling on objectui#12255 (answer A, verbatim 「两仓加治理行」) adds `.github/workflows/**` to this repository's governed surfaces. - scripts/check-governed-queue-guard.mjs: the `workflows` register row; the header comment that named the row as a widening NOT taken now names what it costs (the guard governs its own workflow; a Dependabot github-actions bump is governed) and what stays out (the rest of .github/); the carrierVerdict comment's restraint example moves with it; the self-test pins six surfaces, reverses the own-workflow case into a GOVERNED pin, and adds the .github/ negatives, a near-miss and the Dependabot bump's queue refusal. - scripts/__tests__/check-governed-queue-guard.test.ts: the six-surface case, the reversed own-workflow case and the .github/ negatives. - AGENTS.md 「受管面」: 五项 -> 六项, one bullet, 上面六项. - content/docs/guide/ci-cd-pipeline.md: the fixed-list sentence and the "does not govern" sentence. - scripts/dependabot-merge-gate.mjs: the comment that said a Dependabot diff touches no governed path. No behaviour change. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oKFDZMRoPGDbStvxQa172
…aragraph names `ci-cd-pipeline-doc.test.ts`'s workflow inventory reads every bare `NAME.yml` in prose as a workflow file; `dependabot.yml` is the Dependabot config, not a workflow, so it is spelled `.github/dependabot.yml` (and its two neighbours likewise), the form that test skips by design. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oKFDZMRoPGDbStvxQa172
…n test `markdown-test-inputs.mjs --audit` reads a markdown path literal in a test source as a document that test consumes, and flagged `.github/prompts/component.prompt.md` as unadjudicated. The pin test now names YAML paths only (`.github/ISSUE_TEMPLATE/config.yml` stands in for the card's `.github/ISSUE_TEMPLATE/**`); the self-test keeps the `.github/prompts/**` negative, and the audit is green again. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oKFDZMRoPGDbStvxQa172
Contributor
Author
维护者速读(终稿)席位 改了什么:按您「两仓加治理行」的裁决,把 为什么改:本轮每个 CI PR 都实际等了您的批准,而守卫还答 NOT GOVERNED,规则和机器对不上。合并后,改 workflow 的 PR 没有授权批准就进不了合并队列。 风险与代价(含回滚):
席位意见:可合。登记行与您的裁决逐字一致,6 个文件 +112/−38,CI 全绿。dev 留的一个问题我已按既有规则答复:批准后的 Dependabot workflow 升级,您批准时可顺手入队,否则由本席落地,不加新触发器。 你要做的:批准本 PR( Generated by Claude Code |
os-zhuang
approved these changes
Oct 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #12255
Clause-②: no
.github/workflows/**joins this repository's governed surfaces, on the maintainer's word on the card (answer A, verbatim 「两仓加治理行」). A pull request that edits a workflow now waits as a draft for an APPROVED review by an account inGOVERNED_APPROVERS, and the guard'smerge_groupleg refuses it without one. No tier mechanism, no change toGOVERNED_APPROVERS, no workflow file edited, no behaviour change to any gate other than the register it reads.Tier H: this pull request touches
AGENTS.md, so it stays a draft until an authorized approval is on record; the claiming seat lands it after that.维护者速读(草稿)
改了什么: 本仓的受管面从五项变成六项,新增
.github/workflows/**。合并队列守卫脚本的登记表加了一行;AGENTS.md的「受管面」一节(标题改为六项、新增一条、「上面六项」)、CI 指南里的两句话、Dependabot 合并门禁脚本里的一句注释跟着改。守卫的判定逻辑、两条腿、GOVERNED_APPROVERS名单都没动。为什么改: 您在卡上答 A(「两仓加治理行」):workflow 决定每次 push 跑什么、发布什么、合并队列拿什么门禁挡,改它们应该经您批准。cloud 仓已经在它的表里加了同一行;objectstack 那边的同类卡还在决策箱里,这个 PR 不碰它。
风险与代价(含回滚): ① 以后每个改
.github/workflows/**的 PR 都要等您批准才能落地,包括 Dependabot 的github-actions升级:自动合并流程照常批准、入队,然后被队列拒绝一次,等您批准后才能落地(Dependabot 每推一次新提交,就会再入队、再被拒一次;不会无限循环)。② 守卫自己的 workflow 文件也受管了,改守卫的接线同样要您批准。③.github/下其余文件(dependabot.yml、labeler.yml、prompts/、新加的 PR 模板)不受管。回滚:revert 这个 PR 即可,无数据或配置迁移。席位意见:
你要做的: 读一遍改动,同意就在这个 PR 上留一条 approve;之后由席位落地。另有一个小问题请您顺手定(见下方 Acceptance notes 最后一条):您批准过的 Dependabot workflow 升级,由谁来把它重新放进队列。
The six governed surfaces (after this change)
docs/adr/**.claude/**skills/**AGENTS.mdCLAUDE.md.github/workflows/**(new: register row{ id: 'workflows', prefix: '.github/workflows/', glob: '.github/workflows/**', what: 'CI, deploy and release workflows: what runs on every push, what deploys, what gates the queue' })Still NOT governed, pinned both in the self-test and the pin test: the rest of
.github/(.github/dependabot.yml,.github/labeler.yml,.github/ISSUE_TEMPLATE/**,.github/prompts/**), a near-miss such as.github/workflow/ci.yml, andscripts/check-governed-queue-guard.mjsitself (scripts/**is not a row).Every file touched
scripts/check-governed-queue-guard.mjs: theworkflowsrow; the register's header comment (it named.github/workflows/**as a widening NOT taken; it now names the ruling, what the row costs and what stays out); the restraint example in the comment abovecarrierVerdict; self-test: six surfaces and the six globs verbatim, the own-workflow case reversed into a GOVERNED pin (namedthis-guards-own-workflow-IS-governed-and-its-script-is-not) rather than deleted, the.github/negatives, a near-miss, the Dependabot bump's queue refusal, and the OK summary text (the six ruled surfaces).scripts/__tests__/check-governed-queue-guard.test.ts:declares exactly the six ruled surfaces;does not govern its own workflow, or CI configuration generallyreversed intogoverns every workflow, its own included, and not the script that workflow runs; newdoes not govern the rest of .github/.AGENTS.md, section 「⛔ 受管面」 only: heading 五项 → 六项, one bullet in the section's own wording, 「上面五项已含skills/**」 → 「上面六项已含skills/**」.content/docs/guide/ci-cd-pipeline.md,## Governed Surface Guardonly: the fixed-list sentence, and the "does not govern its own workflow or CI configuration" sentence.scripts/dependabot-merge-gate.mjs: the comment that said a Dependabot diff "touches no governed path"; it now splitsnpmfromgithub-actionsbumps. No behaviour change..changeset/12255-governed-workflows.md: empty frontmatter, no published package moves.The dispatch's hypotheses, measured on
origin/main(74964ad) before any editgoverned-surface-guard.ymlcarries nopaths:/paths-ignore:(the pattern exits 1 there; the same pattern hitsci.ymland four other workflows as the control), so the card'spaths:clause does not apply and no workflow file is edited.dependabot-merge-gate.mjsimportsnode:fsand./invoked-as.mjsonly; outside the guard,GOVERNED_SURFACESis named only in prose comments and in the guard's own pin test (control: the guard file itself holds it nine times).check-doc-snippet-types.mjs,merge-queue-reporting.test.tsandci-cd-pipeline-doc.test.tsenumerate no surface list (control: the guard's pin test does)..github/ISSUE_TEMPLATE/**and.github/dependabot.ymlnegatives stay NOT GOVERNED.--test .github/workflows/ci.yml .github/workflows/lint.ymlanswered NOT GOVERNED (exit 0) before and answers GOVERNED (exit 3) after. On the bump's pull request the guard exits 0 (early warning), sodependabot-merge-gate.mjsstill goes green and the workflow approves (asgithub-actions[bot]) and enqueues; the queue leg's authorized predicate then refuses it with exit 3. The self-test now pins that consequence. Re-enqueue loop:dependabot-auto-merge.ymlsubscribespull_requestwith GitHub's default types only and nomerge_group,check_suiteorpull_request_reviewtrigger, so a queue refusal fires nothing; the bump re-enters the queue only on Dependabot's next push. Read from the trigger block, not replayed live.AGENTS.mdlines or bytes per line. The file-name probe for a line ratchet answers nothing here and answersscripts/pm/check-skill-line-ratchet.mjsin the objectstack checkout (control). So the new bullet is a new line.Gates, at
d5f0181e(the final commit; exit code captured before any pipe)node scripts/check-governed-queue-guard.mjs --self-testOK check-governed-queue-guard self-test: 193 cases pass (the six ruled surfaces …node scripts/check-governed-queue-guard.mjs --test .github/workflows/ci.yml⛔ GOVERNED — 1 of 1 path(s) are on a governed surfacenode scripts/check-governed-queue-guard.mjs --testover this PR's six files⛔ GOVERNED — 1 of 6 path(s) are on a governed surface(AGENTS.md)--testover.github/dependabot.yml .github/labeler.yml .github/ISSUE_TEMPLATE/bug_report.md .github/pull_request_template.md✅ NOT GOVERNED — 4 path(s) checked against 6 governed surface(s)pnpm exec vitest run --maxWorkers=2 scripts/(lock)Test Files 187 passed, 2 skipped (189)·Tests 5622 passed, 2 skipped (5624)pnpm exec vitest runover the four package tests that readcontent/docs/**(lock)Test Files 4 passed (4)·Tests 175 passed (175)pnpm type-check:scripts(lock; the pin test and the guard are in its--listFilesOnly)VERDICT command-exit 0pnpm exec eslint --format jsonover the three touched script filesnode scripts/check-control-bytes.mjs✅ check-control-bytes: OKnode scripts/check-new-cross-file-line-citations.mjsVERDICT new-cross-file-line-citations: 0 new citation(s)node scripts/check-doc-links.mjsLinks are valid across 17 scan roots.node scripts/check-shell-escape-residue.mjs✅ check-shell-escape-residue: OK (5/5 root(s) resolved …node scripts/check-doc-fence-languages.mjs(+--self-test)✅ check:doc-fences …node scripts/check-doc-example-ids.mjs✅ 415 real reference(s) all resolvenode scripts/check-doc-component-types.mjs✅ Every documented component type is registered.node scripts/check-pre-install-import-graph.mjs(+--self-test)✅ check-pre-install-import-graph: OK …node scripts/markdown-test-inputs.mjs --audit123 candidate test files, all adjudicatednode scripts/check-changeset-presence.mjs✅ … no changeset is owed.node scripts/check-changeset-no-major.mjs,check-changeset-claims.mjs,check-pending-changeset-literals.mjsnode scripts/check-test-path-roots.mjs,check-entry-guard.mjs,check-action-ref-convention.mjsThe eslint run is a declared narrowing, not a repo-wide run: the root config lints
.ts/.tsxwithtseslint.configs.recommended(the.mjsfiles resolve to zero rules); noparserOptions.projectorprojectServiceis set, so type-aware linting is off and this diff cannot move a verdict on an untouched file.pnpm lintitself is CI's. Not run locally: the built-package gates ofRepo Gates(check-doc-snippet-types.mjs,check-doc-example-types.mjs,check-doc-json-fences.mjs,check-skill-examples.mjs), because this diff adds no fenced code block; CI runs them.Ablation (one-time proof, not a kept test)
With the fix committed,
node scripts/ablation-replace.mjs(objectstack's tool) deleted theworkflowsrow through a literal anchor that hit once (blob81a9eef6→abf64d8b, on-disk row count 1 → 0), ran the pins, and restored. Mutant:--self-testexit 1,4 of 192 case(s) failed(the-register-declares-exactly-the-six-ruled-surfaces,and-they-are-the-ruled-globs-verbatim,this-guards-own-workflow-IS-governed-and-its-script-is-not,a-github-actions-bump-approved-only-by-the-bot-is-REFUSED-at-the-queue-with-code-3); the pin test exit 1,3 failed;--test .github/workflows/ci.ymlback to NOT GOVERNED, exit 0. Restore: blob equalsHEAD(81a9eef6) andgit diff HEADis empty. Direction observed: red, as expected.Acceptance notes
scripts/__tests__/child-verdict.test.tscarries the stringthe five ruled surfacesinside a synthetic self-test line it feeds to a parser. It is a fixture of the parser, not a claim about the register, so it is left as is.ci-cd-pipeline.md's shell-escape-residue paragraph and that script's header nameAGENTS.md,CLAUDE.md,skills/**and.claude/**as governed. That lists the governed members of that scan's roots, not the whole set, and stays true.ci-cd-pipeline.md's### Dependabot Auto-Mergesection still says patch and minor bumps are approved and enqueued. That stays true; the queue refusal forgithub-actionsbumps is written in the Governed Surface Guard section this PR edits, and in the gate script's comment. Carrier: none..github/pull_request_template.mdarrived onmainwhile this branch was open. It is outside the row and NOT GOVERNED (the--testrow above)..github/negatives to YAML paths (.github/ISSUE_TEMPLATE/config.ymlstands in for the card'sISSUE_TEMPLATE/**): a markdown path literal in a test source is read bymarkdown-test-inputs.mjs --auditas a document the test consumes, which the audit flagged on the first version. The self-test keeps the.github/prompts/**negative.github-actionsbump, nothing re-enqueues it.dependabot-auto-merge.ymldoes not subscribepull_request_review, and ruling C hands landing to "the claiming seat", which a Dependabot PR does not have. This PR changes neither.Session:
https://claude.ai/code/session_011oKFDZMRoPGDbStvxQa172Generated by Claude Code