Skip to content

governance: .github/workflows/** joins the governed-surface register (GOVERNED_SURFACES, Tier H) and the prose that enumerates it — a workflow PR waits for an authorised approval, as this round practised (ruled A) #23048

Closed

Description

@objectstack-fleet

Ruled: 6135970276 · letter B2 · 2026-10-13T01:18Z
Filed by the director seat (summon #37, session_01LqNgdPZB2Jnr5HpGbaqLeB) on the maintainer's word 「两仓加治理行」 (2026-10-12), the answer A to the seat's question (A: the two public repositories add the row and the tooling register follows; B: leave workflows ungoverned). Filing gate ③: maintainer-directed. ⛔ Not a claim. Tier H: AGENTS.md (H) and .claude/** (S) are in the diff, so the PR stays a draft until a GOVERNED_APPROVERS member approves it; the seat then lands it.

Why

This round every CI PR of the fleet waited for the maintainer's approval (objectstack #23014, #23020, #23043; objectui #12232, #12250; cloud #2800, #2802, #2810, #2812, #2813), and cloud wrote .github/workflows/** into its governed table (cloud#2809, PR #2810). In this repository the register GOVERNED_SURFACES (scripts/pm/check-governed-merges.mjs) has six rows and no workflows row, so check-governed-merges.mjs --pr 23043 answered NOT governed and the queue guard would have let a seat land a workflow PR on green. Three devs flagged the gap (objectui#12214 report 6123124321, objectstack#23017 report 6124930963, cloud#2805 report 6123735599). Rule 14 of AGENTS.md says adding a surface is an edit to the register, never to the prose alone, and check:pm-governed-prose pins the prose to it.

What to build

  1. The register row in scripts/pm/check-governed-merges.mjs: { id: 'workflows', prefix: '.github/workflows/', glob: '.github/workflows/**', tier: GOVERNED_TIER_H, what: 'CI, deploy and release workflows: what runs on every push, what deploys, what gates the queue' } (the wording of cloud's table row), with the register's own self-test cases (a workflow path → GOVERNED Tier H; .github/ISSUE_TEMPLATE/** → not).
  2. The prose the checker pins: rule 14's enumeration in AGENTS.md (containment: the glob verbatim as a code span) and every other region check-governed-prose.mjs reads (read its region list; the .claude/skills/pm-dispatch/SKILL.md line 「governed 面统一定义」 and any reference file that enumerates the surfaces move with it); pnpm check:pm-governed-prose exit 0 after.
  3. Consumers: scripts/pm/check-governed-queue-guard.mjs imports the register — its self-test gains the workflow case; dispatch-gates.mjs reads ROOT_FILE_WATCH_HINTS only (no change unless its tier globs enumerate surfaces); the queue guard workflow's paths: filter, if it enumerates the surfaces, gains the glob.
  4. Nothing else: no tier change for existing rows, no change to GOVERNED_APPROVERS.

Acceptance

  • node scripts/pm/check-governed-merges.mjs --pr 23043 (a workflow-only PR) answers GOVERNED, Tier H; pnpm check:pm-governed-prose exit 0; node scripts/pm/check-governed-queue-guard.mjs --self-test exit 0 and --test .github/workflows/lint.yml answers GOVERNED; the PR body lists every prose region touched.

Related: cloud#2809 (PR #2810) · objectui's sibling card (filed in the same act) · objectstack#22998 · scripts/pm/check-governed-merges.mjs · AGENTS.md rule 14.

Activity

  1. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage answers pm:retriage 6126718250: re-routed to domain:skills. The row's reach follows the ruling's two repositories

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-12T16:52Z. ⛔ Not a claim, ⛔ not a dispatch. Thread-read: 6125839958, 6126718250.

    • Lane: domain:skills, as asked. Every declared path is in that row of the lane table: AGENTS.md and .claude/** (the governed surface in full), check-governed-merges.mjs (named there as the governed surface's own audit), and the two gates whose subject is the governed surface. domain:devx is replaced.
    • The scope the stopped dev raised: the ruling is 「两仓加治理行」, the two public repositories. Cloud already has its own row (cloud#2809). The register is read for all five governed repositories, so a plain row would also govern .github/workflows/** in objectos and hotcrm. Nobody ruled that, and a new gate defaults to no.
      • The claiming seat measures first whether the register can scope a row to named repositories.
      • If it can, the row covers objectstack and objectui only.
      • If it cannot, the claim stops before any edit and puts one question to the maintainer as a decision with a 速读: all five, or a per-repository scope added to the register. ⛔ The row is not landed wider than the ruling.
    • The line-ceiling facts the stopped dev read stand: AGENTS.md and the skill's line each need a same-line rewrite.
    • pm:retriage is removed. The card stays pm:queue, unassigned.
  2. added and removed
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 12, 2026
  3. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    决策:.github/workflows/** 治理行该覆盖哪些仓 —— 五仓全覆盖(A),还是给登记表加按仓范围、只覆盖裁定的仓(B)

    domain:skills 席 2(seat post #19287)· os-justin · session_012dGTuJen61ECNHXYXKChoC · 2026-10-12T23:44Z。⛔ 不是认领,⛔ 不是派发。Thread-read: 6125429458、6125839958、6126718250、6128713087。分诊 6128713087 写定的条件成立(登记表做不到按仓限定一行),本卡在任何编辑之前停下,只呈这一个问题。pm:queue → needs-user-decision(同笔替换)。

    维护者速读

    • 一句话: 您裁的「两仓加治理行」要求 objectstack 和 objectui 的 CI 改动先等授权批准再落地。但承载这条规则的登记表对五个仓一视同仁,直接加一行,objectos 和 hotcrm 的 CI 改动也会开始等批准,而这两个仓没人裁过。
    • A = 直接加一行,五仓都管。改动最小,但规则比裁定宽。
    • B = 登记表加一个「适用仓」栏,缺省仍是五仓,既有六行不变;新行只列裁定的仓。改动更大,但表上写的就是裁定。
      • 同笔请裁子参数:B1 只列 objectstack、objectui;B2 再加 cloud(cloud#2809 已把 workflows 列进 cloud 自己的治理表)。
    • 席位推荐 B2,回退 A。回一个字母即可:A / B1 / B2。

    背景

    卡面的裁定:「两仓加治理行」(2026-10-12,答 A)。登记表是 scripts/pm/check-governed-merges.mjs 的 GOVERNED_SURFACES。下列地方都读它:

    • 每个席位在转 ready 前跑的落地判定(--test / --pr,可判任何受管仓的 PR);
    • 五仓的合并后审计扫描;
    • 本仓的队列守卫 check-governed-queue-guard.mjs;
    • 半态巡检 check-half-states.mjs;
    • 规则文本校验 check-governed-prose.mjs。

    objectui 另有自己的队列守卫登记表,由兄弟卡 objectui#12255(domain:devx)处理,本卡不碰。

    Governing text:

    • AGENTS.md 规则 14(263–270 行):"The register is the GOVERNED_SURFACES table in scripts/pm/check-governed-merges.mjs, each row carrying its tier; adding a surface is an edit there, never here"。
    • 登记表 docblock(check-governed-merges.mjs 1126–1127 行):"The register is repo-agnostic: it applies in all of GOVERNED_REPOS."
    • 两个选项都不与规则 14 冲突。B 改的是第二条:登记表自己的 docblock 和工具内部形状,不是规则 14 的条文。

    协议声明: 本卡不改协议。规则 14 只在原行的枚举里加一个 glob。B 给登记表加一个新键,属于工具内部契约,不是 spec。

    前提(每条带 re-check)

    1. 登记表行没有按仓的字段,六行只有 id / prefix|exact / glob / tier / what —— grep -n "Object.freeze({ id: '" scripts/pm/check-governed-merges.mjs | head -6
    2. 登记表对五仓通用,GOVERNED_REPOS = objectstack、objectui、cloud、objectos、hotcrm —— sed -n 1126,1127p scripts/pm/check-governed-merges.mjs;sed -n 1333,1339p scripts/pm/check-governed-merges.mjs
    3. 匹配函数不收仓参数,签名是 governedPathsIn(paths) —— grep -n "export function governedPathsIn" scripts/pm/check-governed-merges.mjs
    4. 调用匹配函数的是 merges 本身、queue-guard、half-states;prose 读 glob;dispatch-gates 只在注释里提到 —— grep -lE "governedPathsIn|GOVERNED_SURFACES" scripts/pm/*.mjs
    5. 两份规则文本都顶格,只能同行改写:SKILL.md 319/319,AGENTS.md 1116 行 —— node scripts/pm/check-skill-line-ratchet.mjs;wc -l AGENTS.md
    6. 审计扫描按时间窗口跑(缺省 24h),加行不会把历史合并翻成新告警 —— sed -n 16,17p scripts/pm/check-governed-merges.mjs

    具体问题

    新行覆盖五仓(A),还是登记表先获得按仓范围,新行只覆盖裁定的仓(B)?若选 B,范围里是否含 cloud(B1 / B2)?

    选项 × 真实代价 × 工作量

    选项 做什么 客户可感知后果 工作量
    A 加一行 .github/workflows/**(Tier H)+ 自测 + 两份规则文本同行改写 五个仓的 CI、部署、发布工作流改动都要等授权批准才落地;审计扫描在五仓都点出未经批准的工作流合并 domain:skills · 1 PR · 先例 #19142:north-star 那一行连同规则文本是 4 个文件 +33/−24(捆在 +70/−182 的 PR 里)
    B1 登记表加「适用仓」键(缺省=全部,既有六行不动);匹配函数改为必须收仓,不传即报错;各调用点传入所在仓;新行只列 objectstack、objectui;其余同 A 只有这两个仓的工作流改动等批准;cloud 由它自己的治理表管,中央审计不点 cloud;objectos、hotcrm 照旧绿灯即落 domain:skills · 1 PR · 无先例。至少 merges、queue-guard、half-states 三处逻辑加自测;行数估不出,⛔ 不猜
    B2 同 B1,新行再列 cloud 同 B1,另外 cloud 的工作流合并也进中央审计,和 cloud 自己的表一致 同 B1,多一个列表元素

    业务含义直译

    • A: 像集团给所有子公司统一加一条「改生产流水线须签批」。其中两家子公司从没讨论过这条。
    • B: 制度条目多一栏「适用公司」,这次只勾裁定的几家。以后哪家要加,勾一下即可,不必再改制度本身。参照 GitHub 组织级 rulesets 的「目标仓库」。

    四轴

    推荐 + 回退 + 置信缺口

    • 推荐 B2。
      • 只看 ①:表上写的就是各仓已有的裁定;形状对齐主流的「规则 × 目标仓库」。
      • 列 cloud,是因为 cloud#2809 已经裁过,中央审计和 cloud 自己的表应当一致。
    • 回退 A: 如果您不想登记表多一个键,宁可五仓统一。代价是 objectos、hotcrm 的工作流改动从此也要等您批准。
    • 置信缺口:
      • objectos、hotcrm 的工作流改动频率读不到;
      • cloud#2809 的裁决原文读不到,依据是本卡正文的转述;
      • B 的实际行数无先例。工作量 B 明显大于 A:A 只动数据行,B 动三处逻辑。差距是否 ≥3× 未实测,在此点名。
    • 自检: 只看 ① 选 B;②③④ 是否翻转:否。③ 偏 A,但只要求 B 把漏传仓做成报错;④ 两边各有代价,A 是未点名的门禁,B 是一个永久键。

    裁后执行

    • 答 A:
    • 答 B1 / B2: 同一个 PR,按下面顺序做,其余同 A:
      1. 登记表先加范围键,缺省 = 全部,既有六行不动;
      2. 匹配函数改为必须收仓,不传就报错;
      3. 各调用点传入所在仓;
      4. 再加 workflows 行,只列裁定的仓;
      5. 自测覆盖「objectos 的工作流路径 → 不受管」和「不传仓 → 报错」;
      6. 登记表 docblock 的 "repo-agnostic" 改写为「缺省全仓,可按行限定」。
    • 无论哪个答复,都不动 objectui#12255(那是 objectui 自己的守卫登记表),不改既有行的档位,不改 GOVERNED_APPROVERS。

    os-decision-facets

    • ① 项目长远合理性:B 让一张登记表如实写下每仓的裁定(对齐 GitHub 组织 rulesets 的「规则×目标仓库」);A 零新键,但表上的规则比裁定宽。
    • ② 实际业务拉动:objectstack、objectui、cloud 本轮 10 个 CI PR 实际等批;objectos、hotcrm 拉动未测(本会话读不到这两个仓)。
    • ③ 防 AI 犯错:A 在五仓一律响亮拒绝绿灯落地;B 必须把「不传仓」做成报错,否则漏传即静默答错。
    • ④ 创业阶段不扩散:A 在维护者未点名的两个仓新增门禁;B 给登记表新增一个永久键。

    Prior rulings read: unresolved。本会话的 issue 搜索 API 被拒(403)。本地读数:git log -S"The register is repo-agnostic" -- scripts/pm/check-governed-merges.mjs → 1 hit(56103b7,#17775);grep -rlE "GOVERNED_REPOS|repo-agnostic" docs/adr → 0 hits,ADR none;thread: 4。

    Related: objectui#12255 · cloud#2809(PR #2810)· objectstack#22998 · 分诊 6128713087 · scripts/pm/check-governed-merges.mjs · AGENTS.md 规则 14

  4. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: batch #333 item 1 · letter B2 · maintainer 「同意」 2026-10-13T01:17Z

    Director seat, summon #39, session_01TJKP6W6UDYEBHtccVdpVoz (GitHub os-steve; written as objectstack-fleet[bot] through the relay, read back). Presented in this seat's chat as batch #333, the one card, with recommendation B2; the maintainer's word was 「同意」. Thread-read: 6134774406.

    B2 — the register gains a per-row repository scope; the workflows row lists objectstack, objectui and cloud. GOVERNED_SURFACES in scripts/pm/check-governed-merges.mjs gains a scope key whose default is every repository in GOVERNED_REPOS; the six existing rows keep that default and their tiers. The new row { id: 'workflows', glob: '.github/workflows/**', tier: GOVERNED_TIER_H } is scoped to objectstack, objectui and cloud: the two repositories the ruling 「两仓加治理行」 names, and cloud because cloud#2809 (PR #2810) already carries the same row in cloud's own table, so the central audit and cloud's table agree. objectos and hotcrm are not governed by the row: no ruling names them, and a new gate defaults to no. A (five repositories) is not taken; B1 (without cloud) is the fallback and is not taken.

    • Governing text: the card's ruling 「两仓加治理行」 (2026-10-12, answer A on the original question); cloud#2809; AGENTS.md rule 14 (the register is the table, adding a surface is an edit there); the four-axis rule 「新增门禁默认否…例外只有维护者点名」; triage's condition at 6128713087 (⛔ the row is not landed wider than the ruling).
    • Workload (the card's column for B2): domain:skills · 1 PR · no precedent; merges, queue-guard and half-states logic plus self-tests; the line count is not guessed. Noted as the charter asks: B's workload is plainly above A's, whether by three times is unmeasured.
    • Execution parameters: this card moves needs-user-decision → pm:queue (domain:skills) in this act, unassigned; domain:skills seat 2 ([PM seat] domain:skills · seat 2 — ⏳ vacant #19287) claims and dispatches one PR, in this order: (1) the scope key on the register, default all, the six rows untouched; (2) governedPathsIn takes the repository and refuses a call without one, loudly; (3) every caller passes its repository (merges, queue-guard, half-states); (4) the workflows row, scoped to the three; (5) self-tests for "an objectos workflow path is not governed", "a cloud workflow path is governed Tier H", and "no repository → error"; (6) the register docblock's "repo-agnostic" sentence rewritten to "default every repository, a row may be scoped"; AGENTS.md rule 14's enumeration and the pm-dispatch SKILL.md line 「governed 面统一定义」 rewritten on their own lines (both files at their line ceilings); pnpm check:pm-governed-prose exit 0; check-governed-merges.mjs --pr 23043 answers GOVERNED Tier H. The PR touches AGENTS.md and .claude/**: Tier H draft, the contract review at CONTRACT_REVIEW_TIER on the SKILL.md hunk, the maintainer's approval, then the seat lands it. ⛔ objectui#12255 untouched; no tier change on existing rows; GOVERNED_APPROVERS unchanged.
    • Premise and fork clause: the register cannot scope a row today (triage's condition, measured by the skills seat: governedPathsIn(paths) takes no repository). If a caller cannot know its repository at the call site, the dev reports the fork rather than defaulting silently to "all"; ⛔ no silent A.
    • 四棱:卡面 6134774406 的四棱块本席逐条确认;只看①选 B;②③④ 是否翻转:否。
  5. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 4 (#23048 — .github/workflows/** joins the governed register, scoped by the per-row repository key ruled B2) · 2026-10-13T01:30Z
    Session: session_012dGTuJen61ECNHXYXKChoC
    Account: os-justin (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-23048-workflows-governed (the released claim-marker branch at 1959aacd, reused as release 6125839958 allows; it is an ancestor of origin/main, so the first push fast-forwards it)
    Worktree: objectstack-issue-23048
    Domain: domain:skills
    Seat: domain:skills#2
    File surface: scripts/pm/check-governed-merges.mjs (the scope key on GOVERNED_SURFACES, governedPathsIn taking the repository and refusing a call without one, its in-file callers including the --test/--pr/--branch predicate and the sweep, the workflows row scoped to objectstack, objectui and cloud, the self-tests, the docblock's "repo-agnostic" sentence), scripts/pm/check-governed-queue-guard.mjs (its callers pass the repository; self-test cases), scripts/pm/check-half-states.mjs (the H43 caller passes the repository; self-test cases), scripts/pm/check-governed-prose.mjs (only if its region list or reading of globs must learn the scope), AGENTS.md rule 14's enumeration (same-line rewrite paid by deleted content), .claude/skills/pm-dispatch/SKILL.md line 「governed 面统一定义」 (same-line rewrite, 120-byte cap); ⛔ not scripts/pm/dispatch-gates*.mjs (frozen), ⛔ not objectui (objectui#12255), ⛔ no tier change on existing rows, ⛔ no change to GOVERNED_APPROVERS (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: ceiling — CONTRACT_REVIEW_TIER; dispatch-gates --tier --repo objectstack-ai/objectstack on the six paths at e9e10fdab printed 「Model tier — MANDATORY: … (derived from the file surface, not recalled)」 for .claude/skills/pm-dispatch/SKILL.md; no exit is taken: the card changes a shared matcher's signature across three gate scripts, not a one-line mechanical edit
    Clause-②: no
    Responsibility: n/a — not a defect card (a maintainer-directed governance extension)
    Thread-read: 6135970276
    Ruling-ref: B2, maintainer 「同意」 2026-10-13T01:17Z, recorded by the director seat in 6135970276 (batch #333 item 1), on the decision analysis 6134774406; its execution parameters (1)–(6) and its fork clause (a caller that cannot know its repository at the call site is reported as a fork, ⛔ never a silent default to every repository) are the dispatch's scope.
    Resume-from: none
    Serial constraints cleared: no open PR changes any declared file (11 open PRs' file lists read at e9e10fdab). No in-flight claim declares one (18 open pm:dispatched claims read; #23088, #23050 and #15953 name check-governed-merges only as a command they run). objectui#12255 edits objectui files only.
    Delivery shape: Fixes #23048; Tier H (AGENTS.md) with a Tier S hunk (.claude/**), so the PR stays draft until an authorized approval; the contract review at CONTRACT_REVIEW_TIER covers the governed prose and the register. skip-changeset (repo-root scripts/** and governed prose publish no package).


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 23048,
      "status": "done",
      "branch": "claude/issue-23048-workflows-governed",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/23129",
      "session": "session_012dGTuJen61ECNHXYXKChoC — subagent of the PM session (same id; identity is the branch)",
      "premise_still_valid": true,
      "summary": "Ruled B2 implemented in one draft PR (#23129, head bd5ad0e95, assignee os-justin, skip-changeset read back). GOVERNED_SURFACES rows may carry a `repos` key (default: every id in GOVERNED_REPOS; the six existing rows untouched, tiers unchanged); the `workflows` row (.github/workflows/**, Tier H) is scoped to objectstack, objectui and cloud. governedPathsIn/governedTierFor/testVerdict/classifyCommit take the repository and refuse a call without one (assertGovernedRepo throws a TypeError naming the caller, the roster and the fix). Every caller passes its repository: the sweep iterates GOVERNED_REPOS; --pr resolves the slug it names (a slug outside the register is refused); --test and --branch answer for the checkout at --root (origin → id, printed on stderr; no --repo flag, per the closed-argv ruling in the file header); the queue guard resolves GITHUB_REPOSITORY (guardRepository) before reading the diff and threads it through every leg; check-half-states binds its swept board at load (a foreign board is NOT MEASURED, named); check-governed-prose demands the rows that govern SELF_REPO_ID; record-recognisers' pin names its repository. Register docblock rewritten (default every repository, a row may be scoped); AGENTS.md rule 14 (lines 266–268 enumeration, line 279 Tier H parenthetical → complement form) and SKILL.md lines 184–185 rewritten on their own lines, both files at their ceilings (1116/1116, 319/319). H1–H5 held except H5's queue-guard --test (the guard has no --test mode; reported) and H2's --repo override (not taken, --root used instead).",
      "tests": "Self-tests (all exit 0, read from shell status): check-governed-merges --self-test 500 assertions (new battery 'the per-row repository scope (ruled B2, 2026-10-13)' 23 cases, roster floor 32→33); check-governed-queue-guard --self-test 312 cases (new battery 15 cases, floor 24→25); check-half-states --self-test 4916 cases (+4 H43 register cases); record-recognisers --self-test 136 cases; check-governed-prose self-test 28 + gate '✓ … name all 7 registered governed surfaces that govern objectstack (… · .github/workflows/**) and claim no others.'; check:pm-skill-ratchet exit 0. Acceptance: `check-governed-merges.mjs --pr 23043` → exit 3, '1 of 1 path(s) hit the register (7 surfaces govern objectstack)', GOVERNED, 'landing tier: H(人合)', '.github/workflows/** ×1'; `--test .github/workflows/lint.yml` from this checkout → exit 3 GOVERNED Tier H, stderr 'ℹ️  judged for objectstack (objectstack-ai/objectstack, the checkout at --root)'; same with --root at a fixture whose origin is objectstack-ai/objectos → exit 0 '0 of 1 … (6 surfaces govern objectos)' NOT governed; cloud fixture → exit 3 GOVERNED '(7 surfaces govern cloud)'; /home/user/objectui (origin objectstack-ai/objectui) → exit 3 GOVERNED; fixture with origin someone/fork → exit 1 '❌  --test answers for the repository the checkout at --root belongs to … someone/fork, which is not a governed repository'; governedPathsIn(paths) with no repository → TypeError 'governedPathsIn wants the repository the paths belong to, as a GOVERNED_REPOS id (objectstack, objectui, cloud, objectos, hotcrm); it got null …' (pinned); `check-governed-queue-guard.mjs --test .github/workflows/lint.yml` → exit 1 'could not read GITHUB_EVENT_PATH' — the guard has no --test mode (confirmed by grep: no --test parsing), its battery pins the workflow case instead. Gates: dispatch-gates --commands (no paths, changeset at bd5ad0e95, --repo objectstack-ai/objectstack checked against origin) derived 54 families = the dispatch's 53 + `pnpm check:pm-record-recognisers`; all 54 run alone in the foreground, exit codes captured directly; all exit 0 — `pnpm --filter @objectstack/lint run check:doc-formula-expressions` first exit 3 PREREQUISITE NOT MET (formula/lint unbuilt), exit 0 after `turbo run build --filter=@objectstack/formula --filter=@objectstack/lint --concurrency=2` under os-verify-lock (VERDICT command-exit 0, held 137s, waited 0s); `pnpm check:pm-dispatch-gates` via nohup + tail --pid, 285s, '✓ dispatch-gates self-test (fast tier): 1833 cases pass; 6 slow section(s) deferred'. `dispatch-gates --ran` with ':: exit N' annotations → '✓ 54 derived famil(ies) accounted for — 54 run, 0 NOT-MEASURED (a DERIVED zero — all 54 recorded an exit code and none of them is 3)'. Ablation (committed tree, scripts/ablation-replace.mjs, no dist): (1) delete `repos: Object.freeze(['objectstack', 'objectui', 'cloud']), ` — anchor x1→x0, blob ad718b3a906d→46ec4a7ba233 — merges self-test RED, 5 failures (the-workflows-row-is-scoped…, an-objectos-workflow-path-is-NOT-governed, a-hotcrm-workflow-path-is-NOT-governed, surfacesChecked-counts…, the-verdict-head-names… '7 surfaces govern objectos'); (2) replace the missing-repository branch `if (typeof repo !== 'string' || repo === '') {` with `if (false) {` — blob →cf93c00d9c5c — RED, 2 failures (no-repository-is-an-ERROR…, the-refusal-names-the-caller…); both restored by `git checkout HEAD -- …`: blob == HEAD ad718b3a906d, `git diff HEAD` empty, anchor x1 again. Direction observed both times: red. Control-char scan of changed files: clean; check:nul-bytes exit 0. Package tests: none owed (no package touched; the lint/formula build was a gate prerequisite, not a change).",
      "gates": "54/54 exit 0 at bd5ad0e95. node scripts/check-ci-filter-parity.mjs 0; check-closing-keyword-parity 0 (+--self-test 0, '40 assertions'); check-comment-mask-corpus 0 ('8926 files, 0 disagree'); check-declaration-mirrors 0 (+--self-test 0); check-issue-citations 0; check-scripts-symbol-anchors 0 (+--self-test 0); check-self-test-wired 0 ('233 script(s)') (+--self-test 0); check-self-test-workflow-commands 0 (+--self-test 0); check-skills-token-ratchet 0 ('5541 tokens (ceiling 6806)') (+--self-test 0); check-whole-set-label-write 0 ('0 violations') (+--self-test 0); pm/bare-root-worklist --self-test 0; pm/board-snapshot --self-test 0; pm/check-governed-queue-guard --self-test 0 ('312 cases pass'); pm/check-harness-current --self-test 0; pm/sweep-closed-cards --self-test 0 ('87 cases'); pnpm --filter @objectstack/lint run check:doc-formula-expressions 3 (PREREQUISITE NOT MET, not a measurement) then 0; check:agent-test-spelling 0; check:bash32-floor 0; check:cli-command-ids 0 ('57 cases'); check:closing-target-claim 0; check:commit-card-trailers 0; check:cross-package-test-inputs 0; check:doc-authoring 0; check:docs-audit-scope 0 ('605 cases'); check:driver-memory-census 0; check:entry-guard 0 ('54 cases'); check:gitlink-declared 0 ('36 assertions'); check:issue-citations 0; check:nul-bytes 0 ('75 assertions'); check:parse-guard 0 ('46 cases'); check:partof-closing-keyword 0; check:pm-dispatch-gates 0 ('1833 cases pass'); check:pm-expected-skips 0 ('154 cases'); check:pm-governed-merges 0 ('500 assertions'); check:pm-governed-prose 0 ('28 cases' + gate ✓); check:pm-half-states 0 ('4916 cases'); check:pm-post-stamped 0; check:pm-record-recognisers 0 ('136 cases'); check:pm-skill-id-lint 0; check:pm-skill-ratchet 0; check:pnpm-filter-targets 0 ('54 assertions over 82 real workspace packages'); check:ratchet-remedy-authority 0; check:refd-timer-probe 0; check:required-contexts 0 ('174 assertions'); check:single-claim-paths 0; check:skill-frame-sync 0; check:watch-hint-literal 0 ('72 cases'). CI on PR #23129 not waited for (in_progress at report time, per the dispatch).",
      "line_budget": "AGENTS.md 1116 → 1116 lines; .claude/skills/pm-dispatch/SKILL.md 319 → 319 lines. Content bytes per edited line (before → after): AGENTS.md 266: 117 → 114; 267: 116 → 116; 268: 116 → 120; 279: 117 → 81. SKILL.md 184: 102 → 120 (「(全量)」 kept, spaces around + removed); 185: 119 → 120. Paid by deletion: 'the file you are reading is one' → 'this file is one'; 'on a single path hit' → 'on one path hit'; the explicit Tier H list → 'every register row except `.claude/**`'; '各仓同治理待遇' → '同治理、行可限仓'. No line bought by re-wrap; pm-skill-ratchet exit 0.",
      "files_changed": "scripts/pm/check-governed-merges.mjs, scripts/pm/check-governed-queue-guard.mjs, scripts/pm/check-half-states.mjs, scripts/pm/check-governed-prose.mjs, scripts/pm/record-recognisers.mjs (beyond the declared surface — a caller of the changed signature, 2 call sites), AGENTS.md, .claude/skills/pm-dispatch/SKILL.md. Commits 54823a7bf, bd5ad0e95 on origin/claude/issue-23048-workflows-governed (first push fast-forwarded the released marker 1959aacd → bcebd8409). Not touched: any workflow file, dispatch-gates*.mjs, GOVERNED_APPROVERS, existing row tiers, objectui, references prose, scripts/invoked-as.mjs.",
      "deviations": "(1) record-recognisers.mjs edited outside the claim's declared file surface: it calls the re-exported governedTierFor and runGuard, whose signatures changed; covered by the ruling's '(3) every caller passes its repository'. (2) SKILL.md line 185 (adjacent to the named line) rewritten in place: it said every GOVERNED_REPOS repository receives the same governance, which the scoped row makes wider than the register; the four in-place conditions hold (same defect class, mechanical with the ruled wording, no other claim on the file, same gate family). (3) PM route H2's `--repo ID` override not taken: the file's '## The argv is closed' section records the ruling 'There is no --repo'; --test/--branch read the checkout at --root (checkoutRepoFor) and say so on stderr. (4) H5: the queue guard has no --test; reported as such, not invented. (5) The harness attribution reminder's `Co-Authored-By: Claude Fable 5.1` trailer was refused by the pre-push hook (model identifier in the pair); the commits carry the repository's model-free pair per AGENTS.md. (6) Gate 23 needed a build of @objectstack/formula and @objectstack/lint (run under the verification lock) before it could measure. (7) AGENTS.md's Tier H parenthetical moved to the complement form rather than enumerating the seventh glob (byte budget; the register holds the tier column) — a maintainer may prefer the explicit list; the seat can restate it if so. (8) Writes went through the fleet relay (repository_dispatch) as the cloud container requires; the PR body was read back byte-identical (14698 bytes), draft true, assignee os-justin.",
      "mcp_calls": "0 — no MCP GitHub tool was called (reads via gh api GET; writes via scripts/pm/ only)",
      "api_writes": "4 — (a) git push ×3 to origin claude/issue-23048-workflows-governed (probe fast-forward, then two commits; not REST); (b) POST /repos/objectstack-ai/objectstack/dispatches (fleet-write request fw-20261013T022307Z-3bfc84 → relay run 38336629421: POST /repos/…/pulls + POST /repos/…/issues/23129/assignees, pr_create draft with assignee, read back identical); (c) POST /repos/objectstack-ai/objectstack/dispatches via label-write (request fw-20261013T022405Z-a062ef → run 38336703974: POST /repos/…/issues/23129/labels skip-changeset; read back: documentation, size/l, skip-changeset); (d) this os-dev-report comment on #23048 via post-stamped (POST /repos/…/issues/23048/comments through the relay). No PATCH on the PR body.",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed — scripts/pm/check-governed-merges.mjs parsePullTarget still accepts any owner/repo#N; --pr now refuses a slug outside GOVERNED_REPOS before any read (exit 1 with the roster named), so no silent answer exists; observation only.",
        "carrier: none · noted, not filed — .github/workflows/governed-surface-guard.yml has no paths: filter by design (its header states it), so the card's item 3 'the queue guard workflow's paths: filter, if it enumerates the surfaces' needed no edit; dispatch-gates.mjs names a register row only in a comment table (frozen file, nothing to move).",
        "carrier: none · noted, not filed — AGENTS.md has lines far over 120 bytes elsewhere (table rows at lines 709–711, up to 768 bytes); the 120-byte cap is the skill ratchet's rule for its covered files' edited lines, not a repo-wide AGENTS.md invariant; nothing to do here."
      ]
    }
  7. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    REWORK, round 1 (two docblock passages) — PR #23129 @ bd5ad0e95 · seat domain:skills#2 · session_012dGTuJen61ECNHXYXKChoC · 2026-10-13T02:43Z

    The at-tier contract review 6137036198 reads FAIL on this head, for one omission under the ruling's step (6). The seat read both passages on the head and agrees.

    The GOVERNED_SURFACES docblock was rewritten as ruled, but the same file's header still states the overturned claim in two places:

    • Section "The governed REPOS" (head ~538–546): "So the surface register above is REPO-AGNOSTIC: the same five surface globs are governed in objectstack, objectui, cloud, objectos and hotcrm, and this sweep covers all five repos in one invocation regardless of the working directory it is run from." After this PR, a row may be scoped, and --test / --branch answer for the checkout at --root.
    • The tier table (head ~417–419): Tier H is listed as "docs/adr/**, docs/NORTH-STAR.md, skills/**, AGENTS.md, CLAUDE.md … Unchanged." It omits the new Tier H workflows row.

    Patch round sent to the same dev on the same claim:

    1. Rewrite the REPO-AGNOSTIC sentence to the ruled shape:

      • every row governs every repository by default, and a row may be scoped (the workflows row: objectstack, objectui, cloud);
      • the sweep still covers all five repositories in one invocation;
      • --test / --branch answer for the checkout at --root.

      Keep the dated history around it, and the 2026-08-18 quotation, as written.

    2. Bring the tier table's Tier H line up to date: name the workflows row (scoped), or use the complement rule 14 now uses. The "Unchanged." note must not claim the list did not move.

    3. Re-grep the whole file, case-insensitively, for every other present-tense statement that the register applies the same to every repository, or that --test ignores the working directory, and fix any left.

    Comments only: ⛔ no behaviour, self-test or prose-file change.

    The review's three maintainer items go to the final quick-read after a PASS on the patched head:

    • the rule-14 complement form;
    • --root rather than a --repo flag;
    • the lane-table overlap on .github/workflows/** between SKILL.md 164 and 165. The seat files that as its own follow-up card, not in this PR.

    Generated by Claude Code

  8. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    Rework round 1 on PR #23129 (contract review 6137036198 FAIL, scope 6137045911): comments only in scripts/pm/check-governed-merges.mjs, one commit 27902d268 pushed to claude/issue-23048-workflows-governed (no force; no merge of origin/main — the branch does not conflict). No behaviour, self-test or prose-file change: git diff -U0 of the commit has zero changed lines outside * comment lines.

    Passage 1 — header section "The governed REPOS" (head 543–546 → 547–554). Before: "So the surface register above is REPO-AGNOSTIC: the same five surface globs are governed in objectstack, objectui, cloud, objectos and hotcrm, and this sweep covers all five repos in one invocation regardless of the working directory it is run from." After: "So the surface register above reaches every governed repository: by default each row governs all five — objectstack, objectui, cloud, objectos and hotcrm — and since the B2 ruling of 2026-10-13 (header section "The register is scoped per row") a row may be scoped to a subset: the workflows row names objectstack, objectui and cloud. This sweep still covers all five repos in one invocation, judging each against the rows that govern it; --test and --branch answer for ONE repository, the checkout at --root (checkoutRepoFor), and say which one on stderr." The 2026-08-18 quotation and the dated history around it are untouched.

    Passage 2 — the tier table's Tier H line (head 417–419 → 417–423). Before: "H 人合 — docs/adr/**, docs/NORTH-STAR.md, skills/**, AGENTS.md, CLAUDE.md: the maintainer's hand, or an authorized APPROVED review by GOVERNED_APPROVERS and then the owning seat lands it. Unchanged." After: "H 人合 — every register row except .claude/** (today: docs/adr/**, docs/NORTH-STAR.md, skills/**, AGENTS.md, CLAUDE.md, and since the B2 ruling of 2026-10-13 the workflows row, .github/workflows/**, scoped to objectstack, objectui and cloud): the maintainer's hand, or an authorized APPROVED review by GOVERNED_APPROVERS and then the owning seat lands it. The tier ruling left this landing as it was; the list itself grew by one row on 2026-10-13."

    Step 3 re-grep (case-insensitive, whole file: agnostic · regardless of the working directory · same five · all five · in all of · every repo · any of them · from anywhere · wherever · judged the same · Unchanged.): one more present-tense statement found and qualified — the 2026-09-03 hotcrm justification (head 559–560) "judged the same across repos" now reads "judged the same across repos — still true of every row that declares no repos scope". Every other hit is about the sweep covering five repositories (still true), a --since-ref tried per repo, --pr's own-checkout reading, or a test name; none states that a row applies alike everywhere or that --test ignores the working directory.

    Gates on 27902d2: node scripts/pm/check-governed-merges.mjs --self-test → exit 0, 500 assertions. dispatch-gates --commands --repo objectstack-ai/objectstack derived the same 54 families as round 1; all 54 ran alone in the foreground, exit codes read from the shell status, all exit 0 (pnpm --filter @objectstack/lint run check:doc-formula-expressions first exit 3 PREREQUISITE NOT MET on the recreated worktree, exit 0 after the formula+lint build under the verification lock, VERDICT command-exit 0; pnpm check:pm-dispatch-gates via nohup + tail --pid, 296s, fast tier 1833 cases). Named families: pnpm check:pm-governed-merges 0 (500 assertions), node scripts/check-scripts-symbol-anchors.mjs 0 (+ --self-test 0), pnpm check:nul-bytes 0, pnpm check:issue-citations 0, node scripts/check-issue-citations.mjs 0, pnpm check:pm-governed-prose 0, pnpm check:pm-skill-ratchet 0. dispatch-gates --ran with :: exit N annotations → "✓ 54 derived famil(ies) accounted for — 54 run, 0 NOT-MEASURED (a DERIVED zero — all 54 recorded an exit code and none of them is 3)". Verify lock: no holder, no tickets (nothing held by this run). Worktree removed after this comment.

    PR body: not patched. One edit for the seat, if wanted: the body's "Acceptance readings (all on bd5ad0e)" and "Gates" headings read bd5ad0e; the code is byte-identical on 27902d2 (comments only), and the gate and acceptance readings above are the 27902d2 readings.

    {
      "issue": 23048,
      "status": "done",
      "branch": "claude/issue-23048-workflows-governed",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/23129",
      "session": "session_012dGTuJen61ECNHXYXKChoC — subagent of the PM session (same id; identity is the branch)",
      "premise_still_valid": true,
      "summary": "Rework round 1, head 27902d268 (one comments-only commit on bd5ad0e95). The check-governed-merges.mjs header's 'The governed REPOS' section no longer calls the register REPO-AGNOSTIC: it states the ruled shape (every row governs every repository by default; a row may be scoped — the workflows row names objectstack, objectui, cloud; the sweep still covers all five; --test/--branch answer for the checkout at --root). The tier table's Tier H line names the scoped workflows row in the complement form rule 14 uses and no longer says 'Unchanged.'. The hotcrm justification's 'judged the same across repos' is qualified to the unscoped rows. The 2026-08-18 quotation and dated history stand as written. No behaviour, self-test, AGENTS.md or SKILL.md change.",
      "tests": "node scripts/pm/check-governed-merges.mjs --self-test exit 0 (500 assertions). dispatch-gates --commands on 27902d268: 54 families (identical to round 1); all run alone in the foreground, all exit 0 (gate 23 exit 3 PREREQUISITE NOT MET then 0 after the formula+lint build under os-verify-lock; pm-dispatch-gates battery via nohup + tail --pid, 296s, 1833 cases). Named: check:pm-governed-merges 0, check-scripts-symbol-anchors 0 (+self-test 0), check:nul-bytes 0, check:issue-citations 0, check:pm-governed-prose 0, check:pm-skill-ratchet 0. dispatch-gates --ran (coded) → 54 run, 0 NOT-MEASURED, 0 UNRUN. git diff -U0 of the commit: no non-comment line. Verify lock: no holder, no tickets.",
      "mcp_calls": "0 — no MCP GitHub tool was called (reads via gh api GET; writes via scripts/pm/ only)",
      "api_writes": "2 this round — (a) git push ×1 of 27902d268 to origin claude/issue-23048-workflows-governed (not REST); (b) this comment on #23048 via post-stamped (POST /repos/objectstack-ai/objectstack/dispatches → relay → POST /repos/…/issues/23048/comments). No PATCH on the PR body; no label write.",
      "open_questions": [],
      "out_of_scope_findings": []
    }
  9. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #23129 @ 27902d268 · seat domain:skills#2 · session_012dGTuJen61ECNHXYXKChoC · 2026-10-13T03:12Z

    Checked against GitHub and origin/main, not the reports (6136862799, rework 6137254453):

    • Shape: draft, base main, first line Fixes #23048, Clause-②: no, assignee os-justin, skip-changeset (repo-root scripts/pm/** and governed prose publish no package). Seven files, +603/−218: check-governed-merges.mjs, check-governed-queue-guard.mjs, check-half-states.mjs, check-governed-prose.mjs, record-recognisers.mjs, AGENTS.md, .claude/skills/pm-dispatch/SKILL.md.
    • The ruling's six steps (6135970276), as implemented:
      • (1) GOVERNED_SURFACES rows may carry repos; without it a row governs every GOVERNED_REPOS id. The six existing rows are byte-identical and keep their tiers.
      • (2) governedPathsIn, governedTierFor, testVerdict, classifyCommit and governedSurfacesFor throw a TypeError on a missing or unknown repository.
      • (3) Every caller passes its repository:
        • the sweep passes the repo it iterates;
        • --pr passes the slug it names, refusing one outside the register;
        • --test and --branch pass the checkout at --root, refusing a fork;
        • the queue guard passes GITHUB_REPOSITORY, read before the diff;
        • the half-state patrol binds to its swept board once; a foreign board is NOT MEASURED;
        • the prose gate passes SELF_REPO_ID;
        • record-recognisers passes its repository.
      • (4) The workflows row is Tier H and scoped to objectstack, objectui and cloud.
      • (5) The self-tests cover an objectos workflow path (not governed), a cloud workflow path (Tier H) and a missing repository (error). The dev's two ablations each turned the battery red.
      • (6) The register docblock and the file header both state the ruled shape.
      • The fork clause did not fire: no caller defaults to every repository.
    • Prose: AGENTS.md rule 14 names .github/workflows/**. SKILL.md lines 184–185 name it and say a row may be scoped. Both files stay at their ceilings (1116/1116, 319/319), with the additions paid for by deleted words. pnpm check:pm-governed-prose exits 0 and names all seven globs that govern objectstack.
    • Acceptance readings (dev, on code byte-identical to this head):
      • --pr 23043 → GOVERNED, Tier H;
      • an objectos-origin checkout → NOT governed;
      • a cloud-origin checkout → GOVERNED;
      • a fork-origin checkout → refused.
    • REWORK round 1 (6137045911): the round-1 contract review (6137036198) failed the head because the file header still called the register "REPO-AGNOSTIC" and its Tier H list omitted the new row. The rework is comments only: every changed line is a docblock line, and the file with comments stripped is byte-identical.
    • CI on this head: 41 check-runs, none red: 33 success, 8 skipped by path filter or by design.
    • Contract review: PASS at CONTRACT_REVIEW_TIER on this head, record 6137353215 (previous head 6137036198, FAIL, answered by the rework). Its three maintainer items ride with the approval and are restated in the final quick-read on the PR.
    • Follow-up, this seat's, after the merge: the pm-dispatch lane table will route .github/workflows/** two ways (SKILL.md 164 gives .github/workflows/(接线) to domain:spec by the anchoring exception; 165 gives the governed set to domain:skills). The seat files a card once this lands, so its premise is true on main.
    • Landing: Tier H (AGENTS.md). The PR stays draft; needs-user-decision goes on the PR; review is requested from os-zhuang and hotlong. After an authorized APPROVED review this seat lands it.

    Generated by Claude Code

  10. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed — PR #23129 MERGED as d206d08ca (merged by os-zhuang through the queue: APPROVED review 5498345134 on 27902d268, flipped ready, enqueued) · seat domain:skills#2 · session_012dGTuJen61ECNHXYXKChoC · 2026-10-13T03:32Z

    • Content read on origin/main after the merge: all seven files are byte-identical to the approved head 27902d268. The workflows row is at check-governed-merges.mjs:1183, with repos: ['objectstack', 'objectui', 'cloud'], Tier H. "repo-agnostic" no longer appears in the file.
    • Live acceptance reading on main: node scripts/pm/check-governed-merges.mjs --pr 23043 exits 3: "1 of 1 path(s) hit the register (7 surfaces govern objectstack)", GOVERNED, landing tier H.
    • The maintainer approved without comment, so the three design calls in the quick-read (6137371438) land as the PR stood:
      • rule 14's complement form;
      • --root rather than a --repo flag;
      • the lane-table overlap, carried to a follow-up card.
    • The card closed by Fixes; pm:dispatched is stripped in this act. The seat files the lane-table follow-up card next, now that its premise is true on main.

    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