Repository navigation
skills(pm-dispatch): flip the gate asymmetry — adding a required gate / hook / ratchet joins the human floor; retiring a zero-catch, no-contract gate becomes class-1 (maintainer ruling F) #18473
Description
Activity
Claim: PM loop round 1 — maintainer direct dispatch to the director seat
Session:session_01Wj1HUjzyeiBQ8atRf1ZhaL
Branch:claude/issue-18473-gate-asymmetry-flip
Worktree:objectstack-issue-18473
Domain:domain:skills
File surface:.claude/skills/pm-dispatch/SKILL.md(the 人工地板 lines around :391–:392 and the class-1 floor line, in place, 812/812) ·.claude/skills/pm-dispatch/references/core-rules.md(twins, 151/151) (stop on breach; explain in the report)
Container & model:M,mode:subagent,model: claude-fable-5-1—dispatch-gates.mjs --tier: SKILL.md path mandate 「MANDATORY: claude-fable-5-1」; no downgrade exit taken
Clause-②: no
Thread-read: none
Serial constraints cleared: SAME FILE in flight — objectstack#18468 → PR #18476 (SKILL.md:92, draft, CI running) and objectstack#18434 (queued,:523); this card edits neither of those lines; ordering by ruling: this PR mergesorigin/mainafter PR #18476 lands and before its own enqueue (scripts/pm/os-regen-merge.sh), so the 812/812 ratchet is paid once per PR on disjoint lines;os-verify-lock.sh --statusread no holder, no tickets at 14:2xZAuthority for a director claim: the maintainer's ruling 「F」 on this session's channel (2026-09-16 ~14:4xZ) — item 1 of the three-part proposal — and the standing instruction that the director dispatches these cards directly.
Generated by Claude Code
os-dev-report
{ "issue": 18473, "status": "done", "branch": "claude/issue-18473-gate-asymmetry-flip", "pr": "https://github.com/objectstack-ai/objectstack/pull/18481", "session": "session_01Wj1HUjzyeiBQ8atRf1ZhaL", "premise_still_valid": true, "summary": "Maintainer ruling 「F」 implemented as two line-neutral re-keys (SKILL.md 812/812, core-rules.md 151/151, every touched line ≤120 B). (1) 人工地板 gains 新增必需门禁/hook/棘轮 with the card requirement (卡具名所守契约与预期捕获), paid in place by compressing the weakening examples, spelling 抬 ratchet 上限 as 抬上限 and dropping the repeated 人工地板同含 prefix; the 具名不升级 line is scoped to 既有门禁 … 非新增. (2) The class-1 floor line ③ now ends in ; and continues into :404, which carries the carve-out (门禁普查标 retire 的退役除外,总监/技能席引该行裁) plus its own two clauses tightened. (3) core-rules twins re-keyed identically; the 95–96 block was re-wrapped across both lines to pay 33 B (declared). Draft PR #18481 opened, skip-changeset applied and read back; governed rules layer, stays draft. Card said :391–392 / ④; on base 85c6d76e the lines are :390–391 / :403 ③ (one-line drift, not a false premise). Lines :92 and :523 hash-identical to origin/main. origin/main unmoved at 85c6d76e (os-regen-merge.sh: Already up to date); PR #18476 still an open draft, so no merge landed under this branch yet. Assignee was already set by the dispatch; no assignee write.", "line_budget": { "SKILL.md": "812/812 (ceiling 812, headroom 0)", "core-rules.md": "151/151 (ceiling 151, headroom 0)", "max_touched_line_bytes": 120 }, "files_changed": [ ".claude/skills/pm-dispatch/SKILL.md (lines 390, 391, 403, 404, 712)", ".claude/skills/pm-dispatch/references/core-rules.md (lines 95, 96, 137)" ], "changed_lines": [ { "file": "SKILL.md", "line": 390, "before_bytes": 118, "after_bytes": 120, "before": "- 人工地板同含:安全/权限边界;门禁削弱(降阈值、删必查项、抬 ratchet 上限、跳过测试)。", "after": "- 人工地板同含:安全/权限边界;门禁削弱(降阈/删必查/抬上限/跳测);新增运行时第三方依赖;" }, { "file": "SKILL.md", "line": 391, "before_bytes": 100, "after_bytes": 119, "before": "- 人工地板同含:花费/配额/舰队形态/默认模型档位;新增运行时第三方依赖。", "after": "- 花费/配额/舰队形态/默认模型档位;新增必需门禁/hook/棘轮(卡具名所守契约与预期捕获)。" }, { "file": "SKILL.md", "line": 403, "before_bytes": 110, "after_bytes": 108, "before": "- ③ 四类地板零移动:安全/权限边界、已发布契约语义、产品能力取舍、门禁强度。", "after": "- ③ 四类地板零移动:安全/权限边界、已发布契约语义、产品能力取舍、门禁强度;" }, { "file": "SKILL.md", "line": 404, "before_bytes": 77, "after_bytes": 119, "before": "- 任一地板触碰 ⇒ 照常现场呈报;地板是排除项不是权重。", "after": "- 门禁普查标 retire 的退役除外,总监/技能席引该行裁;触地板即呈报,地板是排除项非权重。" }, { "file": "SKILL.md", "line": 712, "before_bytes": 110, "after_bytes": 117, "before": "- 纯文档措辞更正(无契约声明改动);门禁内部参数与扫描器盲区修复(加强,非削弱)。", "after": "- 纯文档措辞更正(无契约声明改动);既有门禁内部参数与盲区修复(加强,非削弱,非新增)。" }, { "file": "core-rules.md", "line": 95, "before_bytes": 111, "after_bytes": 119, "before": "- 人工地板恒交维护者:功能新增、ADR、协议与公开契约变化、破坏性或难回滚动作。", "after": "- 人工地板恒交维护者:新功能、ADR、协议/公开契约变化、破坏性/难回滚动作、门禁削弱。" }, { "file": "core-rules.md", "line": 96, "before_bytes": 116, "after_bytes": 120, "before": "- 人工地板同样含安全与权限边界、门禁削弱、花费配额与模型档位、新增运行时依赖。", "after": "- 地板含安全/权限边界、花费配额与模型档位、新增运行时依赖、新增必需门禁/hook/棘轮。" }, { "file": "core-rules.md", "line": 137, "before_bytes": 119, "after_bytes": 119, "before": "- 记账事不升级(无产品可见行为变化):去重并卡、台账整理、纯文档措辞、门禁盲区加强。", "after": "- 记账不升级(无产品可见行为变化):去重并卡、理台账、纯文档措辞、既有门禁盲区加强。" } ], "gates": { "head": "45aeee5d", "derivation": "node scripts/pm/dispatch-gates.mjs --commands (no paths) = 17 families, identical to the two-path derivation; --ran on the exit-coded record: 17 derived, 17 run, 0 NOT-MEASURED, 0 UNRUN (DERIVED zero)", "exit_codes": { "pnpm check:pm-skill-ratchet": 0, "pnpm check:pm-skill-id-lint": 0, "pnpm check:skill-frame-sync": 0, "pnpm check:skill-frame-freshness (outside union, dispatch-named)": 0, "pnpm check:pm-governed-prose": 0, "pnpm check:pm-governed-merges": 0, "pnpm check:pm-half-states": 0, "pnpm check:nul-bytes": 0, "node scripts/pm/check-governed-queue-guard.mjs --self-test": 0, "node scripts/check-closing-keyword-parity.mjs": 0, "node scripts/check-closing-keyword-parity.mjs --self-test": 0, "node scripts/check-comment-mask-corpus.mjs": 0, "pnpm --filter @objectstack/lint run check:doc-formula-expressions": 0, "pnpm check:agent-test-spelling": 0, "pnpm check:doc-authoring": 0, "pnpm check:driver-memory-census": 0, "pnpm check:refd-timer-probe": 0, "pnpm check:watch-hint-literal": 0 }, "notes": "doc-formula-expressions first exited 3 (declared PREREQUISITE NOT MET: @objectstack/formula and @objectstack/lint unbuilt) — not a measurement; built both under os-verify-lock.sh (VERDICT command-exit 0, held 2s) and re-ran: exit 0. All exits captured by redirect-then-$?, never through a pipe." }, "tests": "Gate verdict lines on 45aeee5d: ratchet 「SKILL.md is 812 lines (ceiling 812; headroom 0)」 · 「core-rules.md is 151 lines (ceiling 151; headroom 0)」; id-lint 「27 file(s) clean」; frame-sync 「the one declared copy of the decision frame is internally coherent」; frame-freshness 「current with origin/main」; governed-prose 「2 instruction surface(s) name all 5 registered governed surfaces」; nul-bytes 「scanned 8734 text file(s) … no raw ASCII control bytes」. Positive greps with origin/main controls: 新增必需门禁/hook/棘轮 SKILL 1/0, core-rules 1/0; ③ line + continuation contains 门禁普查标 retire 1/0; 既有门禁内部参数 1/0; 既有门禁盲区加强 1/0; old spelling 加强,非削弱) 0/1. Card's own grep (新增 + 人工地板 ≥ 1) reads 2/2 — control-insensitive on this base. Lines 92 and 523 hash-identical to origin/main. No package build/test owed: diff touches no package (① empty, ② none). No ablation applicable (rule text, no gate logic changed).", "deviations": [ "Card body cited SKILL.md:391–392 and ④; on base 85c6d76e the 人工地板 pair is :390–391 and the class-1 floor line is :403 reading ③ (matches the dispatch). Treated as one-line drift, not a false premise.", "Item 1 payment: weakening examples compressed to 降阈/删必查/抬上限/跳测 (、→/), 抬 ratchet 上限 → 抬上限 (the :392/:785 spelling), :391's repeated 人工地板同含 prefix dropped (continuation of :390 which now ends in ;). The ⛔ zero-baseline-on-own-warrant half is carried by floor membership (:389 恒交维护者), not spelled.", "SKILL.md:712 pays 既有 + 非新增 by dropping 扫描器.", "Item 2: :403 had 10 B slack, so per the ruling the carve-out is paid by tightening the adjacent list line :404 (both its clauses kept, 照常现场 sense carried by :407); :403's terminal 。→; so ③ continues into :404. The census's three-part definition of retire is not restated; docs/audits/gate-census-*.md is #18472's deliverable and not yet on origin/main (forward reference, no gate reads the path).", "core-rules.md: the human-floor block :95–96 had 4 B slack against a 33 B re-key, so it was re-wrapped across both lines like the SKILL.md pair (门禁削弱 moved to :95; 功能新增→新功能; 与/或→/; 同样含→含). :95 twins SKILL.md:389, which the ruling did not touch — the one place payment crossed into a neighbour line. Every item kept. core-rules has no class-1 twin, so item 2 has no core-rules half.", "core-rules.md:137 pays 既有 with 记账事→记账 and 台账整理→理台账 (boundary phrase 无产品可见行为变化 kept byte-identical to SKILL.md:711).", "Dispatch's write list omitted the label endpoint while naming skip-changeset; the base contract budgets POST /issues/N/labels, so one was made (read back: present). Dispatch derivation passed explicit paths; the base contract says no paths — both were run and produced identical 17-command lists; the no-path run is the one cited.", "Two commits, not one: 45aeee5d re-spells core-rules:96 so the literal 新增必需门禁/hook/棘轮 greps 1/1 across the twin pair (first cut used 或必需门禁, grepping 0 in core-rules)." ], "mcp_calls": "0 — no MCP GitHub tools called (read or write)", "api_writes": "3 REST writes + 3 git pushes — POST /repos/objectstack-ai/objectstack/pulls (201, PR #18481 draft); POST /repos/objectstack-ai/objectstack/issues/18481/labels (200, skip-changeset, read back present); POST /repos/objectstack-ai/objectstack/issues/18473/comments (this report); PATCH /pulls ×0. git push ×3 (empty-branch probe, cbea8298, 45aeee5d). Reads: GET issue/comments/pulls/labels/diff only.", "open_questions": [], "out_of_scope_findings": [ "noted, not filed: the card's acceptance grep (新增 + 人工地板 ≥ 1) is control-insensitive on this base (2 before, 2 after); discriminating greps are in the PR body. 承接者: PM (this report).", "noted, not filed: core-rules.md carries no digest of the class-1 self-adjudication list, so item 2 exists in one copy by construction — coverage observation, not a defect. 承接者: skills seat (reads PR #18481).", "noted, not filed: the 门禁普查 reference has no row to cite until #18472 lands docs/audits/gate-census-*.md. 承接者: #18472." ] }
Generated by Claude Code
ACCEPT — director seat,
session_01Wj1HUjzyeiBQ8atRf1ZhaL, served tierclaude-fable-5-1· 2026-09-16T15:18ZVerified against GitHub (PR #18481, head
45aeee5d, draft, 2 files +8/−8), ⛔ not against the report — diff read whole onpr/18481vsorigin/main:- Item 1 (adding joins the floor):
SKILL.md:390–391now read 「…门禁削弱(降阈/删必查/抬上限/跳测);新增运行时第三方依赖;」 / 「- 花费/配额/舰队形态/默认模型档位;新增必需门禁/hook/棘轮(卡具名所守契约与预期捕获)。」;:712「既有门禁内部参数与盲区修复(加强,非削弱,非新增)」 — a new gate can no longer ride the non-escalation line. Paid in place (no new line). - Item 2 (retirement becomes class-1):
:403③ now continues into:404「门禁普查标 retire 的退役除外,总监/技能席引该行裁;触地板即呈报,地板是排除项非权重。」 — both original clauses of :404 kept. - Twins:
core-rules.md:95–96re-wrapped to carry 门禁削弱 and 新增必需门禁/hook/棘轮 (every item kept; :95 twins SKILL.md:389 — the one payment that crossed into a neighbour, declared);:137「既有门禁盲区加强」. - Line-neutral: SKILL.md 812/812, core-rules 151/151; every touched line ≤120 B (120/119/108/119/117);
:92and:523byte-identical toorigin/main(no collision with PR fix(pm): drop the re-seat prescription — check-harness-current and SKILL.md:92 become a seat-post reading #18476 or finding(pm-dispatch): SKILL.md forbids an off-tier seat from spawning a clause-② review subagent while contract-review.md prescribes exactly that — so a default-tier lane has no legal route to a Clause-② yes verdict at all #18434). - Gates: 17 derived / 17 run / 0 unrun (
--ran, DERIVED zero), all 0 after one prerequisite build; ratchet, id-lint, frame-sync, frame-freshness, governed-prose green; positive greps 1/0 with controls;mcp_calls0;api_writes3 REST + 3 pushes, read back;skip-changesetread back. CI on45aeee5dat review: 14 success · 12 skipped · 3 in progress · 0 failed. - Deviations answered: the :390 ⛔-zero-baseline half is carried by floor membership rather than spelled — accepted (the floor line is the rule); 「门禁普查」 forward-references [audit] gate census — every check-*.mjs, check:* script, hook and required job on one table: what it guards, real catches since landing, blast radius — and the retirement list (maintainer ruling F) #18472's deliverable — accepted (no gate reads the path; the census PR is in flight); two commits — accepted.
Landing (governed rules layer, ruling C): four-piece hung on PR #18481. Sequencing: merges
origin/mainafter PR #18476 lands (same file, disjoint lines) before its own enqueue. Card stayspm:dispatcheduntil MERGED.Implemented-by:
claude/issue-18473-gate-asymmetry-flip(mode:subagent)
Reviewed-by:session_01Wj1HUjzyeiBQ8atRf1ZhaL
Generated by Claude Code
- Item 1 (adding joins the floor):
Landed — director seat,
session_01Wj1HUjzyeiBQ8atRf1ZhaL· 2026-09-16T15:58ZPR #18481 (head
45aeee5d) merged by the queue as3dfcee2dfeat 2026-09-16T15:57:59Z (merged_byos-zhuang);git log origin/maincarries(#18481)at the tip. Verified onorigin/main:SKILL.md:391reads 「…新增必需门禁/hook/棘轮(卡具名所守契约与预期捕获)。」 — adding a required gate is on the human floor; the class-1 floor line carries the census-retirement carve-out;core-rules.mdtwins landed with it. Governed landing by ruling C: APPROVED 5224850379 on that head, in-seat ACCEPT (stamped 2026-09-16T15:18Z), provenance on the PR. Ruling F item 1 is in text; item 2 (the census) is #18472, in flight. Same act:pm:dispatchedremoved and the assignee cleared on this auto-closed card;domain:skillsstays. #18489 (ADR-0136 enforcement) is now unblocked on this file and waits only for PR #18480's final approval.
Generated by Claude Code
- added a commit that references this issue
on Sep 17, 2026
Filed and dispatched by the director seat (summon #24,
session_01Wj1HUjzyeiBQ8atRf1ZhaL) under the maintainer's ruling F (verbatim 「F」, 2026-09-16 ~14:4xZ) on the direct-channel question 「我们的项目是不是门禁用的太重了。有这个必要吗?」. ⛔ Nodomain:*set by the filer; the surface isSKILL.md+core-rules.md, anchored todomain:skills.Dedup terms:
gate asymmetry·人工地板 新增门禁·一类自裁 拆门禁·门禁加强 免升级Why (director's reading, on origin/main)
SKILL.md:391— 「人工地板同含:安全/权限边界;门禁削弱(降阈值、删必查项、抬 ratchet 上限、跳过测试)。」 puts weakening on the floor. Adding or strengthening a gate is free: 具名不升级类 lists 「门禁内部参数与扫描器盲区修复(加强,非削弱)」 and 换班报告 routes every 可机械化项 to 「门禁/脚本卡,⛔ 不是散文」. A fleet under that rule turns every finding into a gate and can never take one down without the maintainer: 182check-*.mjs, 164check:*scripts, 42% of last week's 597 merges gate-shaped. The maintainer chose to flip it.Deliverable — two re-keys, line-neutral (SKILL.md 812/812, core-rules 151/151), each line ≤120 B
SKILL.md:391or its neighbour, wherever it fits in place) reads that a new required gate, a new hook, or a new ratchet is a human-floor item — a seat proposes it as a decision card with the contract it guards and the measured catch it expects; ⛔ it no longer lands zero-baseline on a seat's own warrant. 「门禁内部参数与扫描器盲区修复(加强)」 stays non-escalating only for an existing gate's internals, never for a new gate.retire— process class, zero real catches, guarding no published contract — is not 门禁强度 movement; the director or the skills seat rules it, records the census row as the authority, and the removal PR follows.references/core-rules.mdtwin lines re-keyed identically (一条规则两处同改).⛔ Not touched:
SKILL.md:92(owned by #18468, in flight) and:523(owned by #18434, queued). This card is serialised behind #18468 (same file): claim after its PR is up, merge main first.Acceptance
pnpm check:pm-skill-ratchet812/812 · 151/151;check:pm-skill-id-lintgreen;check:skill-frame-syncuntouched.git grep -n '新增' .claude/skills/pm-dispatch/SKILL.md | grep -c 人工地板≥ 1 and the class-1 floor line names the census carve-out (positive greps in the PR body, with controls).Refs the gate-census card filed alongside · #18468 · #18434 · #18095
Generated by Claude Code