docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding - #14779

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors
Sep 3, 2026
Merged

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding#14779
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Fixes#14146

Five semantic minors in the axis-weighting / batch-presentation encoding, caught by the at-tier compensating review of PR #14142 and fixed exactly as the reviewer prescribed. Every edit is in place: zero net lines in all four ratcheted files, and the published entry shrinks.

Positions are re-measured on today's main (224f8ea4a); the card's line numbers predate two merges, so they are restated below with the old number in parentheses.

Item 1 — stale cap-form restatement replaced by a pointer

Landing:.claude/skills/pm-dispatch/SKILL.mdL454 (card: L441)

before…照旧现场呈报,走每批 ≤5 与详细写法纪律。
after…照旧现场呈报,走常设决裁批流程与详细写法纪律。

The class-2/3 live-presentation route carried an inline 每批 ≤5 while the single home now rules 恰好 5 张 — a seat following the old line could present a 2-card batch and claim compliance. The number is gone; 常设决裁批流程 is the verbatim section heading in references/decision-analysis.md, so the pointer is greppable and there is now exactly one place that states the batch size. Line is 119 bytes (limit 120), zero lines added.

Item 2 — the final partial batch gets its legal move

Landing:.claude/skills/pm-dispatch/references/decision-analysis.mdL13

before- 每批**恰好 5 张,呈完即停等回批**(2026-09-01
after- 每批**恰好 5 张(末批不足照呈),呈完即停等回批**(2026-09-01

恰好 5 张 plus 收件箱读数为零才收工 (L17) forbade both presenting fewer than 5 and holding the remainder — the last batch of any queue that is not a multiple of five had no legal move. Inserted in place on the existing line: 57 B to 77 B, file stays at 54 lines (ceiling 54, headroom 0).

Item 3 — count-free wording, in every copy

Chosen: count-free wording. NOT a MENTION_PATTERNS extension. The reasoning, since the card left the choice open:

  • The gate's own charter is "blind to prose and sharp on shape", and its %N% / %Q% design exists so that an anchor never spells the value it compares. A count − 1 mention check re-introduces a derived arithmetic relationship that the regex must know in two languages — and a regex can only ever see the spellings it enumerates. Miss one (另外三轴, 其余三条, the remaining three) and the gate is green while the text is stale: the exact defect being repaired, one layer up.
  • Count-free wording removes the failure mode instead of policing it. After this PR there is no derived count anywhere in the four copies, so there is nothing for a future axis-count change to leave behind.
  • A MENTION_PATTERNS extension landed alongside count-free wording would have zero live matches — a dormant pattern, which is the shape this repo's gates treat as rot.

frameCountMentions still sees and checks the 4 real count mentions (gate output below); this change adds nothing to it and removes nothing from it.

Six sites, all count − 1 hard-codings (the card named five weighting clauses; the sixth, L553, is the same defect class in the axis-① worked example — same file already in this claim's surface, same gate family, mechanical, no new verification surface):

landingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L905另三轴合起来投不翻它其余各轴合起来投不翻它
references/decision-analysis.md L51另三轴合起来投不翻①其余各轴合起来投不翻①
.claude/agents/os-dev.md L418推荐以它领起,另三轴合起来投不翻它推荐以它领起,其余各轴合起来投不翻它
skills/objectstack-pm-dispatch/SKILL.md L553On the other three axes theyOn the other axes they
skills/objectstack-pm-dispatch/SKILL.md L593the other three together cannot outvotethe others together cannot outvote
skills/objectstack-pm-dispatch/SKILL.md L659lead with it, the other threelead with it, the others

另三轴 and the other three are now at 0 occurrences across all four copies.

Item 4 — published entry: dangling anchor and the dropped term

Landing:skills/objectstack-pm-dispatch/SKILL.mdL594 (card: L703) and L660-661 (card: L859)

sitebeforeafter
L594Read that weight through axis ②'s own definition — shrink special-cases and contract accretion, never grow themRead that weight as shrinking special-cases and contract accretion, never growing them
L660-661read it as shrinking special-cases rather than as licence to expand speculativelyread it as shrinking special-cases and contract accretion rather than as licence to expand speculatively

The L594 citation pointed at that file's axis-② definition for the shrink-not-grow reading, which that definition nowhere states (the real anchor deliberately does not ship under the route-B generalization) — it is now self-contained and asserts the reading directly. L660-661 regains and contract accretion, the term the zero-pull no-conflict argument turns on.

Item 5 — the lead-with-long-term duty, unconditional in all five encodings

The card's premise held on today's tree: 3 unconditional, 2 scoped to axis conflict.

encodingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L904-905四轴冲突时推荐以长远的读数领起,另三轴合起来投不翻它conditional推荐以长远的读数领起,四轴冲突时其余各轴合起来投不翻它 — unconditional lead
skills/objectstack-pm-dispatch/SKILL.md L592-593**Axis ② carries the highest weight — at least 50%** when the axes conflict: lead with the long-term reading, and…conditional**Axis ② carries the highest weight — at least 50%.** Lead with the long-term reading; when the axes conflict, the others…
references/decision-analysis.md L50-51①恒 ≥50%,推荐以①领起 — already unconditionalunchanged (item 3 rewording only)
.claude/agents/os-dev.md L417-418推荐以它领起 — already unconditionalunchanged (item 3 rewording only)
skills/objectstack-pm-dispatch/SKILL.md L659lead with it — already unconditionalunchanged (item 3 rewording only)

Conflict-scoping is kept, in both rewritten copies, on the cannot-outvote consequence only — which is where it is meaningful, since there is nothing to outvote absent a conflict.

Line and token arithmetic, per file

filelines beforelines afterceilingheadroom
.claude/skills/pm-dispatch/SKILL.md989989100516 (unchanged)
.claude/skills/pm-dispatch/references/decision-analysis.md5454540 (unchanged)
.claude/agents/os-dev.md4694694690 (unchanged)
skills/objectstack-pm-dispatch/SKILL.md753753not line-ratcheted

No line in any edited file exceeds the 120-byte rule; the widest edited lines are SKILL.md L454 (119 B), L904 (118 B) and os-dev.md L418 (120 B). max-table-row-bytes pins are untouched — no table was edited.

Published entry, token ratchet (convention ceil(utf8 bytes / 4)), measured per site:

siteitemsbeforeafterdelta
L553377 B71 B−6 B
L592-5963, 4, 5372 B335 B−37 B
L657-6623, 4235 B253 B+18 B
file38,832 B = 9,708 tokens38,807 B = 9,702 tokens−25 B / −6 tokens

How item 4's added words are paid, inside the same file, without a re-wrap and without a ceiling change: item 4's only cost is and contract accretion at L660-661, +23 B. It is paid by item 4's own other half — deleting the dangling citation through axis ②'s own definition — (38 B, replaced by as , 3 B) at L594 — with item 3's −16 B of count-free rewording on top. The ceiling stays at 9,708 and is not lowered, per the dispatch's explicit no-ceiling-change constraint; the file now sits 6 tokens under it.

Published-surface readings (skills/** diff)

Both readings the published surface requires, lines first, tokens beside them:

readingbeforeafterdelta
edited file — skills/objectstack-pm-dispatch/SKILL.md753 lines · 38,832 B · 9,708 tokens753 lines · 38,807 B · 9,702 tokens0 lines · −25 B · −6 tokens
whole published package — all 11 skills/*/SKILL.md6,862 lines · 318,948 B · 79,737 tokens6,862 lines · 318,923 B · 79,731 tokens0 lines · −25 B · −6 tokens

No net expansion in either reading: this PR corrects wording in place and the published surface comes out marginally smaller. There is no new capability here and therefore no "small feature, big write-up" to price — the one clause that gains words (item 4's and contract accretion) is paid twice over inside the same file.

skip-changeset

Applied. The diff publishes nothing from any package: .claude/** agent protocol plus the skills/** catalog, which ships through npx skills add, not through a package release. Measured rather than assumed — none of the six most recent commits touching skills/objectstack-pm-dispatch/SKILL.md carried a .changeset/ file (c985ae958, a9b2be0b0, 2bff79ae3, bcc9189e6, 3d0897459, d250754fd), and 2bff79ae3 is this card's own parent PR with the identical face set.

Gates

Every command ran through scripts/pm/os-verify-lock.sh (slot issue-14146), each exit code captured by redirect before any pipe. The union below was re-derived after the final commit with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and run at dd9f7d39f — the branch head.

gateverdict line
check:skill-frame-sync✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files · 4 axes: business-need → long-term-soundness → ai-authoring-safety → startup-scope-discipline · binding sentence present in all 4; 4 count mention(s) agree; 40 markdown files scanned for undeclared copies.
check:skill-frame-sync --self-test✓ check-skill-frame-sync self-test: 12 cases pass, plus 5 dispatch-gates declaration cases.
check:skill-frame-freshness✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:skill-frame-freshness --self-test✓ check-skill-frame-freshness self-test: 12 cases pass.
check:pm-skill-ratchet✓ …SKILL.md is 989 lines (ceiling 1005; headroom 16). · ✓ …decision-analysis.md is 54 lines (ceiling 54; headroom 0). · ✓ …os-dev.md is 469 lines (ceiling 469; headroom 0).
check:pm-skill-ratchet --self-test✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g). · self-test 14 cases pass.
check-skills-token-ratchet✓ …skills/objectstack-pm-dispatch/SKILL.md is 9702 tokens (ceiling 9708; headroom 6). · ✓ …36 authored bundle file(s) within their ceilings
check-skills-token-ratchet --self-test✓ check-skills-token-ratchet self-test: 64 cases pass.
@objectstack/spec check:skill-docs✓ skills/README.md · ✓ content/docs/ai/skills-reference.mdx · ✅ Skill docs in sync
check:nul-bytescheck-nul-bytes: OK (scanned 8052 text file(s) — 8052 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes). · self-test 75 assertions

Full derived union at dd9f7d39f20 of 22 green, and the two that are not green are NOT MEASURED, not red:

check-ci-filter-parity · check-cross-package-test-inputs · check-shard-attestation · check-skills-token-ratchet · check:skill-docs · check:agent-model-declared · check:agent-test-spelling · check:corpus-claim-drift · check:cross-package-test-inputs · check:doc-authoring · check:nul-bytes · check:pm-governed-merges · check:pm-governed-prose · check:pm-skill-id-lint · check:pm-skill-ratchet · check:role-word · check:skill-compatibility · check:skill-frame-sync · check:skill-identifier-liveness · check:skill-frame-freshness — all green.

  • check-test-completenessexit 3, NOT MEASURED. Its own text: "That list names this script with NO argument… There is no local log to hand it, so the local reading for this gate is NOT MEASURED. ⛔ It is not a red, and there is nothing here to fix." It consumes a turbo run test log that only CI produces; this diff touches no test.
  • check:doc-formula-expressionsexit 3, PREREQUISITE NOT MET (@objectstack/formula is not built in this worktree). Not a finding. Building it needs the shared verify lock, and two bounded acquisitions timed out at the 540 s budget behind a sibling's run (exit 99, place kept — also NOT MEASURED, never a red). Declared narrowing, measured from the gate's own predicate rather than asserted:fencedBlocks() keeps only fences whose language tag is ts, typescript or tsx, and the text scan is FIELD_RULE_TEXT_RE (visibleWhen|readonlyWhen|requiredWhen). Across all four edited files the gate would parse 0 fenced blocks — the fences present are bash, json, text and bare, none of them a parsed language — 0 of the 17 changed lines fall inside a parsed block, and there are 0FIELD_RULE_TEXT_RE occurrences. The gate has nothing to read in this diff, so its verdict cannot move. CI builds the package and runs it for real.

Beyond the derived union I also self-scanned the four edited files for raw control bytes (grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'): zero hits.

Premise notes


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

… encoding
Five in-place, zero-net-line corrections to the escalation decision frame's
four copies and the decision-analysis reference:
1. The class-2/3 live-presentation route in the internal PM skill restated a
stale per-batch cap; it now points at the single home that rules the batch
size, so the two cannot drift apart again.
2. The standing adjudication batch flow had no legal move for a final partial
batch (an exact-size rule plus a drain-the-inbox rule forbade both
presenting short and holding the remainder). The short last batch is now
presented as-is.
3. Every weighting clause hard-coded "the other three", an axis-count minus one
that the frame-sync gate's MENTION_PATTERNS structurally cannot see. All six
sites are now count-free, so no derived count can go stale.
4. Published entry: the shrink-not-grow reading no longer cites an axis
definition that does not state it, and the embedded dev template regains
"and contract accretion" — the term the zero-pull argument turns on.
5. The lead-with-long-term duty is now unconditional in all five encodings;
conflict-scoping is kept only on the cannot-outvote consequence.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/s labels Sep 3, 2026 — with Claude
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Sep 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 33706142983 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (1/6) — 失败步骤: Run this shard's tests

    @objectstack/cli:test: FAIL integration test/run-dev-unbuilt-workspace.e2e.test.ts > the mirror direction: a reader that is never coming back > gives up and exits instead of waiting forever
    ↳ 失败原因: @objectstack/cli:test: AssertionError: expected 'SIGKILL' to be null
    

↳ 失败原因 是判读的关键:超时Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 39 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

Merged via the queue into main with commit db07f69Sep 3, 2026
39 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14146-frame-copy-minors branch September 3, 2026 02:51
This was referenced Sep 3, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding - #14779

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors
Sep 3, 2026
Merged

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding#14779
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Fixes#14146

Five semantic minors in the axis-weighting / batch-presentation encoding, caught by the at-tier compensating review of PR #14142 and fixed exactly as the reviewer prescribed. Every edit is in place: zero net lines in all four ratcheted files, and the published entry shrinks.

Positions are re-measured on today's main (224f8ea4a); the card's line numbers predate two merges, so they are restated below with the old number in parentheses.

Item 1 — stale cap-form restatement replaced by a pointer

Landing:.claude/skills/pm-dispatch/SKILL.mdL454 (card: L441)

before…照旧现场呈报,走每批 ≤5 与详细写法纪律。
after…照旧现场呈报,走常设决裁批流程与详细写法纪律。

The class-2/3 live-presentation route carried an inline 每批 ≤5 while the single home now rules 恰好 5 张 — a seat following the old line could present a 2-card batch and claim compliance. The number is gone; 常设决裁批流程 is the verbatim section heading in references/decision-analysis.md, so the pointer is greppable and there is now exactly one place that states the batch size. Line is 119 bytes (limit 120), zero lines added.

Item 2 — the final partial batch gets its legal move

Landing:.claude/skills/pm-dispatch/references/decision-analysis.mdL13

before- 每批**恰好 5 张,呈完即停等回批**(2026-09-01
after- 每批**恰好 5 张(末批不足照呈),呈完即停等回批**(2026-09-01

恰好 5 张 plus 收件箱读数为零才收工 (L17) forbade both presenting fewer than 5 and holding the remainder — the last batch of any queue that is not a multiple of five had no legal move. Inserted in place on the existing line: 57 B to 77 B, file stays at 54 lines (ceiling 54, headroom 0).

Item 3 — count-free wording, in every copy

Chosen: count-free wording. NOT a MENTION_PATTERNS extension. The reasoning, since the card left the choice open:

  • The gate's own charter is "blind to prose and sharp on shape", and its %N% / %Q% design exists so that an anchor never spells the value it compares. A count − 1 mention check re-introduces a derived arithmetic relationship that the regex must know in two languages — and a regex can only ever see the spellings it enumerates. Miss one (另外三轴, 其余三条, the remaining three) and the gate is green while the text is stale: the exact defect being repaired, one layer up.
  • Count-free wording removes the failure mode instead of policing it. After this PR there is no derived count anywhere in the four copies, so there is nothing for a future axis-count change to leave behind.
  • A MENTION_PATTERNS extension landed alongside count-free wording would have zero live matches — a dormant pattern, which is the shape this repo's gates treat as rot.

frameCountMentions still sees and checks the 4 real count mentions (gate output below); this change adds nothing to it and removes nothing from it.

Six sites, all count − 1 hard-codings (the card named five weighting clauses; the sixth, L553, is the same defect class in the axis-① worked example — same file already in this claim's surface, same gate family, mechanical, no new verification surface):

landingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L905另三轴合起来投不翻它其余各轴合起来投不翻它
references/decision-analysis.md L51另三轴合起来投不翻①其余各轴合起来投不翻①
.claude/agents/os-dev.md L418推荐以它领起,另三轴合起来投不翻它推荐以它领起,其余各轴合起来投不翻它
skills/objectstack-pm-dispatch/SKILL.md L553On the other three axes theyOn the other axes they
skills/objectstack-pm-dispatch/SKILL.md L593the other three together cannot outvotethe others together cannot outvote
skills/objectstack-pm-dispatch/SKILL.md L659lead with it, the other threelead with it, the others

另三轴 and the other three are now at 0 occurrences across all four copies.

Item 4 — published entry: dangling anchor and the dropped term

Landing:skills/objectstack-pm-dispatch/SKILL.mdL594 (card: L703) and L660-661 (card: L859)

sitebeforeafter
L594Read that weight through axis ②'s own definition — shrink special-cases and contract accretion, never grow themRead that weight as shrinking special-cases and contract accretion, never growing them
L660-661read it as shrinking special-cases rather than as licence to expand speculativelyread it as shrinking special-cases and contract accretion rather than as licence to expand speculatively

The L594 citation pointed at that file's axis-② definition for the shrink-not-grow reading, which that definition nowhere states (the real anchor deliberately does not ship under the route-B generalization) — it is now self-contained and asserts the reading directly. L660-661 regains and contract accretion, the term the zero-pull no-conflict argument turns on.

Item 5 — the lead-with-long-term duty, unconditional in all five encodings

The card's premise held on today's tree: 3 unconditional, 2 scoped to axis conflict.

encodingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L904-905四轴冲突时推荐以长远的读数领起,另三轴合起来投不翻它conditional推荐以长远的读数领起,四轴冲突时其余各轴合起来投不翻它 — unconditional lead
skills/objectstack-pm-dispatch/SKILL.md L592-593**Axis ② carries the highest weight — at least 50%** when the axes conflict: lead with the long-term reading, and…conditional**Axis ② carries the highest weight — at least 50%.** Lead with the long-term reading; when the axes conflict, the others…
references/decision-analysis.md L50-51①恒 ≥50%,推荐以①领起 — already unconditionalunchanged (item 3 rewording only)
.claude/agents/os-dev.md L417-418推荐以它领起 — already unconditionalunchanged (item 3 rewording only)
skills/objectstack-pm-dispatch/SKILL.md L659lead with it — already unconditionalunchanged (item 3 rewording only)

Conflict-scoping is kept, in both rewritten copies, on the cannot-outvote consequence only — which is where it is meaningful, since there is nothing to outvote absent a conflict.

Line and token arithmetic, per file

filelines beforelines afterceilingheadroom
.claude/skills/pm-dispatch/SKILL.md989989100516 (unchanged)
.claude/skills/pm-dispatch/references/decision-analysis.md5454540 (unchanged)
.claude/agents/os-dev.md4694694690 (unchanged)
skills/objectstack-pm-dispatch/SKILL.md753753not line-ratcheted

No line in any edited file exceeds the 120-byte rule; the widest edited lines are SKILL.md L454 (119 B), L904 (118 B) and os-dev.md L418 (120 B). max-table-row-bytes pins are untouched — no table was edited.

Published entry, token ratchet (convention ceil(utf8 bytes / 4)), measured per site:

siteitemsbeforeafterdelta
L553377 B71 B−6 B
L592-5963, 4, 5372 B335 B−37 B
L657-6623, 4235 B253 B+18 B
file38,832 B = 9,708 tokens38,807 B = 9,702 tokens−25 B / −6 tokens

How item 4's added words are paid, inside the same file, without a re-wrap and without a ceiling change: item 4's only cost is and contract accretion at L660-661, +23 B. It is paid by item 4's own other half — deleting the dangling citation through axis ②'s own definition — (38 B, replaced by as , 3 B) at L594 — with item 3's −16 B of count-free rewording on top. The ceiling stays at 9,708 and is not lowered, per the dispatch's explicit no-ceiling-change constraint; the file now sits 6 tokens under it.

Published-surface readings (skills/** diff)

Both readings the published surface requires, lines first, tokens beside them:

readingbeforeafterdelta
edited file — skills/objectstack-pm-dispatch/SKILL.md753 lines · 38,832 B · 9,708 tokens753 lines · 38,807 B · 9,702 tokens0 lines · −25 B · −6 tokens
whole published package — all 11 skills/*/SKILL.md6,862 lines · 318,948 B · 79,737 tokens6,862 lines · 318,923 B · 79,731 tokens0 lines · −25 B · −6 tokens

No net expansion in either reading: this PR corrects wording in place and the published surface comes out marginally smaller. There is no new capability here and therefore no "small feature, big write-up" to price — the one clause that gains words (item 4's and contract accretion) is paid twice over inside the same file.

skip-changeset

Applied. The diff publishes nothing from any package: .claude/** agent protocol plus the skills/** catalog, which ships through npx skills add, not through a package release. Measured rather than assumed — none of the six most recent commits touching skills/objectstack-pm-dispatch/SKILL.md carried a .changeset/ file (c985ae958, a9b2be0b0, 2bff79ae3, bcc9189e6, 3d0897459, d250754fd), and 2bff79ae3 is this card's own parent PR with the identical face set.

Gates

Every command ran through scripts/pm/os-verify-lock.sh (slot issue-14146), each exit code captured by redirect before any pipe. The union below was re-derived after the final commit with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and run at dd9f7d39f — the branch head.

gateverdict line
check:skill-frame-sync✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files · 4 axes: business-need → long-term-soundness → ai-authoring-safety → startup-scope-discipline · binding sentence present in all 4; 4 count mention(s) agree; 40 markdown files scanned for undeclared copies.
check:skill-frame-sync --self-test✓ check-skill-frame-sync self-test: 12 cases pass, plus 5 dispatch-gates declaration cases.
check:skill-frame-freshness✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:skill-frame-freshness --self-test✓ check-skill-frame-freshness self-test: 12 cases pass.
check:pm-skill-ratchet✓ …SKILL.md is 989 lines (ceiling 1005; headroom 16). · ✓ …decision-analysis.md is 54 lines (ceiling 54; headroom 0). · ✓ …os-dev.md is 469 lines (ceiling 469; headroom 0).
check:pm-skill-ratchet --self-test✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g). · self-test 14 cases pass.
check-skills-token-ratchet✓ …skills/objectstack-pm-dispatch/SKILL.md is 9702 tokens (ceiling 9708; headroom 6). · ✓ …36 authored bundle file(s) within their ceilings
check-skills-token-ratchet --self-test✓ check-skills-token-ratchet self-test: 64 cases pass.
@objectstack/spec check:skill-docs✓ skills/README.md · ✓ content/docs/ai/skills-reference.mdx · ✅ Skill docs in sync
check:nul-bytescheck-nul-bytes: OK (scanned 8052 text file(s) — 8052 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes). · self-test 75 assertions

Full derived union at dd9f7d39f20 of 22 green, and the two that are not green are NOT MEASURED, not red:

check-ci-filter-parity · check-cross-package-test-inputs · check-shard-attestation · check-skills-token-ratchet · check:skill-docs · check:agent-model-declared · check:agent-test-spelling · check:corpus-claim-drift · check:cross-package-test-inputs · check:doc-authoring · check:nul-bytes · check:pm-governed-merges · check:pm-governed-prose · check:pm-skill-id-lint · check:pm-skill-ratchet · check:role-word · check:skill-compatibility · check:skill-frame-sync · check:skill-identifier-liveness · check:skill-frame-freshness — all green.

  • check-test-completenessexit 3, NOT MEASURED. Its own text: "That list names this script with NO argument… There is no local log to hand it, so the local reading for this gate is NOT MEASURED. ⛔ It is not a red, and there is nothing here to fix." It consumes a turbo run test log that only CI produces; this diff touches no test.
  • check:doc-formula-expressionsexit 3, PREREQUISITE NOT MET (@objectstack/formula is not built in this worktree). Not a finding. Building it needs the shared verify lock, and two bounded acquisitions timed out at the 540 s budget behind a sibling's run (exit 99, place kept — also NOT MEASURED, never a red). Declared narrowing, measured from the gate's own predicate rather than asserted:fencedBlocks() keeps only fences whose language tag is ts, typescript or tsx, and the text scan is FIELD_RULE_TEXT_RE (visibleWhen|readonlyWhen|requiredWhen). Across all four edited files the gate would parse 0 fenced blocks — the fences present are bash, json, text and bare, none of them a parsed language — 0 of the 17 changed lines fall inside a parsed block, and there are 0FIELD_RULE_TEXT_RE occurrences. The gate has nothing to read in this diff, so its verdict cannot move. CI builds the package and runs it for real.

Beyond the derived union I also self-scanned the four edited files for raw control bytes (grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'): zero hits.

Premise notes


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

… encoding
Five in-place, zero-net-line corrections to the escalation decision frame's
four copies and the decision-analysis reference:
1. The class-2/3 live-presentation route in the internal PM skill restated a
stale per-batch cap; it now points at the single home that rules the batch
size, so the two cannot drift apart again.
2. The standing adjudication batch flow had no legal move for a final partial
batch (an exact-size rule plus a drain-the-inbox rule forbade both
presenting short and holding the remainder). The short last batch is now
presented as-is.
3. Every weighting clause hard-coded "the other three", an axis-count minus one
that the frame-sync gate's MENTION_PATTERNS structurally cannot see. All six
sites are now count-free, so no derived count can go stale.
4. Published entry: the shrink-not-grow reading no longer cites an axis
definition that does not state it, and the embedded dev template regains
"and contract accretion" — the term the zero-pull argument turns on.
5. The lead-with-long-term duty is now unconditional in all five encodings;
conflict-scoping is kept only on the cannot-outvote consequence.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/s labels Sep 3, 2026 — with Claude
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Sep 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 33706142983 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (1/6) — 失败步骤: Run this shard's tests

    @objectstack/cli:test: FAIL integration test/run-dev-unbuilt-workspace.e2e.test.ts > the mirror direction: a reader that is never coming back > gives up and exits instead of waiting forever
    ↳ 失败原因: @objectstack/cli:test: AssertionError: expected 'SIGKILL' to be null
    

↳ 失败原因 是判读的关键:超时Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 39 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

Merged via the queue into main with commit db07f69Sep 3, 2026
39 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14146-frame-copy-minors branch September 3, 2026 02:51
This was referenced Sep 3, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding - #14779

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors
Sep 3, 2026
Merged

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding#14779
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Fixes#14146

Five semantic minors in the axis-weighting / batch-presentation encoding, caught by the at-tier compensating review of PR #14142 and fixed exactly as the reviewer prescribed. Every edit is in place: zero net lines in all four ratcheted files, and the published entry shrinks.

Positions are re-measured on today's main (224f8ea4a); the card's line numbers predate two merges, so they are restated below with the old number in parentheses.

Item 1 — stale cap-form restatement replaced by a pointer

Landing:.claude/skills/pm-dispatch/SKILL.mdL454 (card: L441)

before…照旧现场呈报,走每批 ≤5 与详细写法纪律。
after…照旧现场呈报,走常设决裁批流程与详细写法纪律。

The class-2/3 live-presentation route carried an inline 每批 ≤5 while the single home now rules 恰好 5 张 — a seat following the old line could present a 2-card batch and claim compliance. The number is gone; 常设决裁批流程 is the verbatim section heading in references/decision-analysis.md, so the pointer is greppable and there is now exactly one place that states the batch size. Line is 119 bytes (limit 120), zero lines added.

Item 2 — the final partial batch gets its legal move

Landing:.claude/skills/pm-dispatch/references/decision-analysis.mdL13

before- 每批**恰好 5 张,呈完即停等回批**(2026-09-01
after- 每批**恰好 5 张(末批不足照呈),呈完即停等回批**(2026-09-01

恰好 5 张 plus 收件箱读数为零才收工 (L17) forbade both presenting fewer than 5 and holding the remainder — the last batch of any queue that is not a multiple of five had no legal move. Inserted in place on the existing line: 57 B to 77 B, file stays at 54 lines (ceiling 54, headroom 0).

Item 3 — count-free wording, in every copy

Chosen: count-free wording. NOT a MENTION_PATTERNS extension. The reasoning, since the card left the choice open:

  • The gate's own charter is "blind to prose and sharp on shape", and its %N% / %Q% design exists so that an anchor never spells the value it compares. A count − 1 mention check re-introduces a derived arithmetic relationship that the regex must know in two languages — and a regex can only ever see the spellings it enumerates. Miss one (另外三轴, 其余三条, the remaining three) and the gate is green while the text is stale: the exact defect being repaired, one layer up.
  • Count-free wording removes the failure mode instead of policing it. After this PR there is no derived count anywhere in the four copies, so there is nothing for a future axis-count change to leave behind.
  • A MENTION_PATTERNS extension landed alongside count-free wording would have zero live matches — a dormant pattern, which is the shape this repo's gates treat as rot.

frameCountMentions still sees and checks the 4 real count mentions (gate output below); this change adds nothing to it and removes nothing from it.

Six sites, all count − 1 hard-codings (the card named five weighting clauses; the sixth, L553, is the same defect class in the axis-① worked example — same file already in this claim's surface, same gate family, mechanical, no new verification surface):

landingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L905另三轴合起来投不翻它其余各轴合起来投不翻它
references/decision-analysis.md L51另三轴合起来投不翻①其余各轴合起来投不翻①
.claude/agents/os-dev.md L418推荐以它领起,另三轴合起来投不翻它推荐以它领起,其余各轴合起来投不翻它
skills/objectstack-pm-dispatch/SKILL.md L553On the other three axes theyOn the other axes they
skills/objectstack-pm-dispatch/SKILL.md L593the other three together cannot outvotethe others together cannot outvote
skills/objectstack-pm-dispatch/SKILL.md L659lead with it, the other threelead with it, the others

另三轴 and the other three are now at 0 occurrences across all four copies.

Item 4 — published entry: dangling anchor and the dropped term

Landing:skills/objectstack-pm-dispatch/SKILL.mdL594 (card: L703) and L660-661 (card: L859)

sitebeforeafter
L594Read that weight through axis ②'s own definition — shrink special-cases and contract accretion, never grow themRead that weight as shrinking special-cases and contract accretion, never growing them
L660-661read it as shrinking special-cases rather than as licence to expand speculativelyread it as shrinking special-cases and contract accretion rather than as licence to expand speculatively

The L594 citation pointed at that file's axis-② definition for the shrink-not-grow reading, which that definition nowhere states (the real anchor deliberately does not ship under the route-B generalization) — it is now self-contained and asserts the reading directly. L660-661 regains and contract accretion, the term the zero-pull no-conflict argument turns on.

Item 5 — the lead-with-long-term duty, unconditional in all five encodings

The card's premise held on today's tree: 3 unconditional, 2 scoped to axis conflict.

encodingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L904-905四轴冲突时推荐以长远的读数领起,另三轴合起来投不翻它conditional推荐以长远的读数领起,四轴冲突时其余各轴合起来投不翻它 — unconditional lead
skills/objectstack-pm-dispatch/SKILL.md L592-593**Axis ② carries the highest weight — at least 50%** when the axes conflict: lead with the long-term reading, and…conditional**Axis ② carries the highest weight — at least 50%.** Lead with the long-term reading; when the axes conflict, the others…
references/decision-analysis.md L50-51①恒 ≥50%,推荐以①领起 — already unconditionalunchanged (item 3 rewording only)
.claude/agents/os-dev.md L417-418推荐以它领起 — already unconditionalunchanged (item 3 rewording only)
skills/objectstack-pm-dispatch/SKILL.md L659lead with it — already unconditionalunchanged (item 3 rewording only)

Conflict-scoping is kept, in both rewritten copies, on the cannot-outvote consequence only — which is where it is meaningful, since there is nothing to outvote absent a conflict.

Line and token arithmetic, per file

filelines beforelines afterceilingheadroom
.claude/skills/pm-dispatch/SKILL.md989989100516 (unchanged)
.claude/skills/pm-dispatch/references/decision-analysis.md5454540 (unchanged)
.claude/agents/os-dev.md4694694690 (unchanged)
skills/objectstack-pm-dispatch/SKILL.md753753not line-ratcheted

No line in any edited file exceeds the 120-byte rule; the widest edited lines are SKILL.md L454 (119 B), L904 (118 B) and os-dev.md L418 (120 B). max-table-row-bytes pins are untouched — no table was edited.

Published entry, token ratchet (convention ceil(utf8 bytes / 4)), measured per site:

siteitemsbeforeafterdelta
L553377 B71 B−6 B
L592-5963, 4, 5372 B335 B−37 B
L657-6623, 4235 B253 B+18 B
file38,832 B = 9,708 tokens38,807 B = 9,702 tokens−25 B / −6 tokens

How item 4's added words are paid, inside the same file, without a re-wrap and without a ceiling change: item 4's only cost is and contract accretion at L660-661, +23 B. It is paid by item 4's own other half — deleting the dangling citation through axis ②'s own definition — (38 B, replaced by as , 3 B) at L594 — with item 3's −16 B of count-free rewording on top. The ceiling stays at 9,708 and is not lowered, per the dispatch's explicit no-ceiling-change constraint; the file now sits 6 tokens under it.

Published-surface readings (skills/** diff)

Both readings the published surface requires, lines first, tokens beside them:

readingbeforeafterdelta
edited file — skills/objectstack-pm-dispatch/SKILL.md753 lines · 38,832 B · 9,708 tokens753 lines · 38,807 B · 9,702 tokens0 lines · −25 B · −6 tokens
whole published package — all 11 skills/*/SKILL.md6,862 lines · 318,948 B · 79,737 tokens6,862 lines · 318,923 B · 79,731 tokens0 lines · −25 B · −6 tokens

No net expansion in either reading: this PR corrects wording in place and the published surface comes out marginally smaller. There is no new capability here and therefore no "small feature, big write-up" to price — the one clause that gains words (item 4's and contract accretion) is paid twice over inside the same file.

skip-changeset

Applied. The diff publishes nothing from any package: .claude/** agent protocol plus the skills/** catalog, which ships through npx skills add, not through a package release. Measured rather than assumed — none of the six most recent commits touching skills/objectstack-pm-dispatch/SKILL.md carried a .changeset/ file (c985ae958, a9b2be0b0, 2bff79ae3, bcc9189e6, 3d0897459, d250754fd), and 2bff79ae3 is this card's own parent PR with the identical face set.

Gates

Every command ran through scripts/pm/os-verify-lock.sh (slot issue-14146), each exit code captured by redirect before any pipe. The union below was re-derived after the final commit with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and run at dd9f7d39f — the branch head.

gateverdict line
check:skill-frame-sync✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files · 4 axes: business-need → long-term-soundness → ai-authoring-safety → startup-scope-discipline · binding sentence present in all 4; 4 count mention(s) agree; 40 markdown files scanned for undeclared copies.
check:skill-frame-sync --self-test✓ check-skill-frame-sync self-test: 12 cases pass, plus 5 dispatch-gates declaration cases.
check:skill-frame-freshness✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:skill-frame-freshness --self-test✓ check-skill-frame-freshness self-test: 12 cases pass.
check:pm-skill-ratchet✓ …SKILL.md is 989 lines (ceiling 1005; headroom 16). · ✓ …decision-analysis.md is 54 lines (ceiling 54; headroom 0). · ✓ …os-dev.md is 469 lines (ceiling 469; headroom 0).
check:pm-skill-ratchet --self-test✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g). · self-test 14 cases pass.
check-skills-token-ratchet✓ …skills/objectstack-pm-dispatch/SKILL.md is 9702 tokens (ceiling 9708; headroom 6). · ✓ …36 authored bundle file(s) within their ceilings
check-skills-token-ratchet --self-test✓ check-skills-token-ratchet self-test: 64 cases pass.
@objectstack/spec check:skill-docs✓ skills/README.md · ✓ content/docs/ai/skills-reference.mdx · ✅ Skill docs in sync
check:nul-bytescheck-nul-bytes: OK (scanned 8052 text file(s) — 8052 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes). · self-test 75 assertions

Full derived union at dd9f7d39f20 of 22 green, and the two that are not green are NOT MEASURED, not red:

check-ci-filter-parity · check-cross-package-test-inputs · check-shard-attestation · check-skills-token-ratchet · check:skill-docs · check:agent-model-declared · check:agent-test-spelling · check:corpus-claim-drift · check:cross-package-test-inputs · check:doc-authoring · check:nul-bytes · check:pm-governed-merges · check:pm-governed-prose · check:pm-skill-id-lint · check:pm-skill-ratchet · check:role-word · check:skill-compatibility · check:skill-frame-sync · check:skill-identifier-liveness · check:skill-frame-freshness — all green.

  • check-test-completenessexit 3, NOT MEASURED. Its own text: "That list names this script with NO argument… There is no local log to hand it, so the local reading for this gate is NOT MEASURED. ⛔ It is not a red, and there is nothing here to fix." It consumes a turbo run test log that only CI produces; this diff touches no test.
  • check:doc-formula-expressionsexit 3, PREREQUISITE NOT MET (@objectstack/formula is not built in this worktree). Not a finding. Building it needs the shared verify lock, and two bounded acquisitions timed out at the 540 s budget behind a sibling's run (exit 99, place kept — also NOT MEASURED, never a red). Declared narrowing, measured from the gate's own predicate rather than asserted:fencedBlocks() keeps only fences whose language tag is ts, typescript or tsx, and the text scan is FIELD_RULE_TEXT_RE (visibleWhen|readonlyWhen|requiredWhen). Across all four edited files the gate would parse 0 fenced blocks — the fences present are bash, json, text and bare, none of them a parsed language — 0 of the 17 changed lines fall inside a parsed block, and there are 0FIELD_RULE_TEXT_RE occurrences. The gate has nothing to read in this diff, so its verdict cannot move. CI builds the package and runs it for real.

Beyond the derived union I also self-scanned the four edited files for raw control bytes (grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'): zero hits.

Premise notes


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

… encoding
Five in-place, zero-net-line corrections to the escalation decision frame's
four copies and the decision-analysis reference:
1. The class-2/3 live-presentation route in the internal PM skill restated a
stale per-batch cap; it now points at the single home that rules the batch
size, so the two cannot drift apart again.
2. The standing adjudication batch flow had no legal move for a final partial
batch (an exact-size rule plus a drain-the-inbox rule forbade both
presenting short and holding the remainder). The short last batch is now
presented as-is.
3. Every weighting clause hard-coded "the other three", an axis-count minus one
that the frame-sync gate's MENTION_PATTERNS structurally cannot see. All six
sites are now count-free, so no derived count can go stale.
4. Published entry: the shrink-not-grow reading no longer cites an axis
definition that does not state it, and the embedded dev template regains
"and contract accretion" — the term the zero-pull argument turns on.
5. The lead-with-long-term duty is now unconditional in all five encodings;
conflict-scoping is kept only on the cannot-outvote consequence.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/s labels Sep 3, 2026 — with Claude
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Sep 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 33706142983 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (1/6) — 失败步骤: Run this shard's tests

    @objectstack/cli:test: FAIL integration test/run-dev-unbuilt-workspace.e2e.test.ts > the mirror direction: a reader that is never coming back > gives up and exits instead of waiting forever
    ↳ 失败原因: @objectstack/cli:test: AssertionError: expected 'SIGKILL' to be null
    

↳ 失败原因 是判读的关键:超时Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 39 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

Merged via the queue into main with commit db07f69Sep 3, 2026
39 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14146-frame-copy-minors branch September 3, 2026 02:51
This was referenced Sep 3, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding - #14779

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors
Sep 3, 2026
Merged

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding#14779
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Fixes#14146

Five semantic minors in the axis-weighting / batch-presentation encoding, caught by the at-tier compensating review of PR #14142 and fixed exactly as the reviewer prescribed. Every edit is in place: zero net lines in all four ratcheted files, and the published entry shrinks.

Positions are re-measured on today's main (224f8ea4a); the card's line numbers predate two merges, so they are restated below with the old number in parentheses.

Item 1 — stale cap-form restatement replaced by a pointer

Landing:.claude/skills/pm-dispatch/SKILL.mdL454 (card: L441)

before…照旧现场呈报,走每批 ≤5 与详细写法纪律。
after…照旧现场呈报,走常设决裁批流程与详细写法纪律。

The class-2/3 live-presentation route carried an inline 每批 ≤5 while the single home now rules 恰好 5 张 — a seat following the old line could present a 2-card batch and claim compliance. The number is gone; 常设决裁批流程 is the verbatim section heading in references/decision-analysis.md, so the pointer is greppable and there is now exactly one place that states the batch size. Line is 119 bytes (limit 120), zero lines added.

Item 2 — the final partial batch gets its legal move

Landing:.claude/skills/pm-dispatch/references/decision-analysis.mdL13

before- 每批**恰好 5 张,呈完即停等回批**(2026-09-01
after- 每批**恰好 5 张(末批不足照呈),呈完即停等回批**(2026-09-01

恰好 5 张 plus 收件箱读数为零才收工 (L17) forbade both presenting fewer than 5 and holding the remainder — the last batch of any queue that is not a multiple of five had no legal move. Inserted in place on the existing line: 57 B to 77 B, file stays at 54 lines (ceiling 54, headroom 0).

Item 3 — count-free wording, in every copy

Chosen: count-free wording. NOT a MENTION_PATTERNS extension. The reasoning, since the card left the choice open:

  • The gate's own charter is "blind to prose and sharp on shape", and its %N% / %Q% design exists so that an anchor never spells the value it compares. A count − 1 mention check re-introduces a derived arithmetic relationship that the regex must know in two languages — and a regex can only ever see the spellings it enumerates. Miss one (另外三轴, 其余三条, the remaining three) and the gate is green while the text is stale: the exact defect being repaired, one layer up.
  • Count-free wording removes the failure mode instead of policing it. After this PR there is no derived count anywhere in the four copies, so there is nothing for a future axis-count change to leave behind.
  • A MENTION_PATTERNS extension landed alongside count-free wording would have zero live matches — a dormant pattern, which is the shape this repo's gates treat as rot.

frameCountMentions still sees and checks the 4 real count mentions (gate output below); this change adds nothing to it and removes nothing from it.

Six sites, all count − 1 hard-codings (the card named five weighting clauses; the sixth, L553, is the same defect class in the axis-① worked example — same file already in this claim's surface, same gate family, mechanical, no new verification surface):

landingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L905另三轴合起来投不翻它其余各轴合起来投不翻它
references/decision-analysis.md L51另三轴合起来投不翻①其余各轴合起来投不翻①
.claude/agents/os-dev.md L418推荐以它领起,另三轴合起来投不翻它推荐以它领起,其余各轴合起来投不翻它
skills/objectstack-pm-dispatch/SKILL.md L553On the other three axes theyOn the other axes they
skills/objectstack-pm-dispatch/SKILL.md L593the other three together cannot outvotethe others together cannot outvote
skills/objectstack-pm-dispatch/SKILL.md L659lead with it, the other threelead with it, the others

另三轴 and the other three are now at 0 occurrences across all four copies.

Item 4 — published entry: dangling anchor and the dropped term

Landing:skills/objectstack-pm-dispatch/SKILL.mdL594 (card: L703) and L660-661 (card: L859)

sitebeforeafter
L594Read that weight through axis ②'s own definition — shrink special-cases and contract accretion, never grow themRead that weight as shrinking special-cases and contract accretion, never growing them
L660-661read it as shrinking special-cases rather than as licence to expand speculativelyread it as shrinking special-cases and contract accretion rather than as licence to expand speculatively

The L594 citation pointed at that file's axis-② definition for the shrink-not-grow reading, which that definition nowhere states (the real anchor deliberately does not ship under the route-B generalization) — it is now self-contained and asserts the reading directly. L660-661 regains and contract accretion, the term the zero-pull no-conflict argument turns on.

Item 5 — the lead-with-long-term duty, unconditional in all five encodings

The card's premise held on today's tree: 3 unconditional, 2 scoped to axis conflict.

encodingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L904-905四轴冲突时推荐以长远的读数领起,另三轴合起来投不翻它conditional推荐以长远的读数领起,四轴冲突时其余各轴合起来投不翻它 — unconditional lead
skills/objectstack-pm-dispatch/SKILL.md L592-593**Axis ② carries the highest weight — at least 50%** when the axes conflict: lead with the long-term reading, and…conditional**Axis ② carries the highest weight — at least 50%.** Lead with the long-term reading; when the axes conflict, the others…
references/decision-analysis.md L50-51①恒 ≥50%,推荐以①领起 — already unconditionalunchanged (item 3 rewording only)
.claude/agents/os-dev.md L417-418推荐以它领起 — already unconditionalunchanged (item 3 rewording only)
skills/objectstack-pm-dispatch/SKILL.md L659lead with it — already unconditionalunchanged (item 3 rewording only)

Conflict-scoping is kept, in both rewritten copies, on the cannot-outvote consequence only — which is where it is meaningful, since there is nothing to outvote absent a conflict.

Line and token arithmetic, per file

filelines beforelines afterceilingheadroom
.claude/skills/pm-dispatch/SKILL.md989989100516 (unchanged)
.claude/skills/pm-dispatch/references/decision-analysis.md5454540 (unchanged)
.claude/agents/os-dev.md4694694690 (unchanged)
skills/objectstack-pm-dispatch/SKILL.md753753not line-ratcheted

No line in any edited file exceeds the 120-byte rule; the widest edited lines are SKILL.md L454 (119 B), L904 (118 B) and os-dev.md L418 (120 B). max-table-row-bytes pins are untouched — no table was edited.

Published entry, token ratchet (convention ceil(utf8 bytes / 4)), measured per site:

siteitemsbeforeafterdelta
L553377 B71 B−6 B
L592-5963, 4, 5372 B335 B−37 B
L657-6623, 4235 B253 B+18 B
file38,832 B = 9,708 tokens38,807 B = 9,702 tokens−25 B / −6 tokens

How item 4's added words are paid, inside the same file, without a re-wrap and without a ceiling change: item 4's only cost is and contract accretion at L660-661, +23 B. It is paid by item 4's own other half — deleting the dangling citation through axis ②'s own definition — (38 B, replaced by as , 3 B) at L594 — with item 3's −16 B of count-free rewording on top. The ceiling stays at 9,708 and is not lowered, per the dispatch's explicit no-ceiling-change constraint; the file now sits 6 tokens under it.

Published-surface readings (skills/** diff)

Both readings the published surface requires, lines first, tokens beside them:

readingbeforeafterdelta
edited file — skills/objectstack-pm-dispatch/SKILL.md753 lines · 38,832 B · 9,708 tokens753 lines · 38,807 B · 9,702 tokens0 lines · −25 B · −6 tokens
whole published package — all 11 skills/*/SKILL.md6,862 lines · 318,948 B · 79,737 tokens6,862 lines · 318,923 B · 79,731 tokens0 lines · −25 B · −6 tokens

No net expansion in either reading: this PR corrects wording in place and the published surface comes out marginally smaller. There is no new capability here and therefore no "small feature, big write-up" to price — the one clause that gains words (item 4's and contract accretion) is paid twice over inside the same file.

skip-changeset

Applied. The diff publishes nothing from any package: .claude/** agent protocol plus the skills/** catalog, which ships through npx skills add, not through a package release. Measured rather than assumed — none of the six most recent commits touching skills/objectstack-pm-dispatch/SKILL.md carried a .changeset/ file (c985ae958, a9b2be0b0, 2bff79ae3, bcc9189e6, 3d0897459, d250754fd), and 2bff79ae3 is this card's own parent PR with the identical face set.

Gates

Every command ran through scripts/pm/os-verify-lock.sh (slot issue-14146), each exit code captured by redirect before any pipe. The union below was re-derived after the final commit with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and run at dd9f7d39f — the branch head.

gateverdict line
check:skill-frame-sync✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files · 4 axes: business-need → long-term-soundness → ai-authoring-safety → startup-scope-discipline · binding sentence present in all 4; 4 count mention(s) agree; 40 markdown files scanned for undeclared copies.
check:skill-frame-sync --self-test✓ check-skill-frame-sync self-test: 12 cases pass, plus 5 dispatch-gates declaration cases.
check:skill-frame-freshness✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:skill-frame-freshness --self-test✓ check-skill-frame-freshness self-test: 12 cases pass.
check:pm-skill-ratchet✓ …SKILL.md is 989 lines (ceiling 1005; headroom 16). · ✓ …decision-analysis.md is 54 lines (ceiling 54; headroom 0). · ✓ …os-dev.md is 469 lines (ceiling 469; headroom 0).
check:pm-skill-ratchet --self-test✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g). · self-test 14 cases pass.
check-skills-token-ratchet✓ …skills/objectstack-pm-dispatch/SKILL.md is 9702 tokens (ceiling 9708; headroom 6). · ✓ …36 authored bundle file(s) within their ceilings
check-skills-token-ratchet --self-test✓ check-skills-token-ratchet self-test: 64 cases pass.
@objectstack/spec check:skill-docs✓ skills/README.md · ✓ content/docs/ai/skills-reference.mdx · ✅ Skill docs in sync
check:nul-bytescheck-nul-bytes: OK (scanned 8052 text file(s) — 8052 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes). · self-test 75 assertions

Full derived union at dd9f7d39f20 of 22 green, and the two that are not green are NOT MEASURED, not red:

check-ci-filter-parity · check-cross-package-test-inputs · check-shard-attestation · check-skills-token-ratchet · check:skill-docs · check:agent-model-declared · check:agent-test-spelling · check:corpus-claim-drift · check:cross-package-test-inputs · check:doc-authoring · check:nul-bytes · check:pm-governed-merges · check:pm-governed-prose · check:pm-skill-id-lint · check:pm-skill-ratchet · check:role-word · check:skill-compatibility · check:skill-frame-sync · check:skill-identifier-liveness · check:skill-frame-freshness — all green.

  • check-test-completenessexit 3, NOT MEASURED. Its own text: "That list names this script with NO argument… There is no local log to hand it, so the local reading for this gate is NOT MEASURED. ⛔ It is not a red, and there is nothing here to fix." It consumes a turbo run test log that only CI produces; this diff touches no test.
  • check:doc-formula-expressionsexit 3, PREREQUISITE NOT MET (@objectstack/formula is not built in this worktree). Not a finding. Building it needs the shared verify lock, and two bounded acquisitions timed out at the 540 s budget behind a sibling's run (exit 99, place kept — also NOT MEASURED, never a red). Declared narrowing, measured from the gate's own predicate rather than asserted:fencedBlocks() keeps only fences whose language tag is ts, typescript or tsx, and the text scan is FIELD_RULE_TEXT_RE (visibleWhen|readonlyWhen|requiredWhen). Across all four edited files the gate would parse 0 fenced blocks — the fences present are bash, json, text and bare, none of them a parsed language — 0 of the 17 changed lines fall inside a parsed block, and there are 0FIELD_RULE_TEXT_RE occurrences. The gate has nothing to read in this diff, so its verdict cannot move. CI builds the package and runs it for real.

Beyond the derived union I also self-scanned the four edited files for raw control bytes (grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'): zero hits.

Premise notes


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

… encoding
Five in-place, zero-net-line corrections to the escalation decision frame's
four copies and the decision-analysis reference:
1. The class-2/3 live-presentation route in the internal PM skill restated a
stale per-batch cap; it now points at the single home that rules the batch
size, so the two cannot drift apart again.
2. The standing adjudication batch flow had no legal move for a final partial
batch (an exact-size rule plus a drain-the-inbox rule forbade both
presenting short and holding the remainder). The short last batch is now
presented as-is.
3. Every weighting clause hard-coded "the other three", an axis-count minus one
that the frame-sync gate's MENTION_PATTERNS structurally cannot see. All six
sites are now count-free, so no derived count can go stale.
4. Published entry: the shrink-not-grow reading no longer cites an axis
definition that does not state it, and the embedded dev template regains
"and contract accretion" — the term the zero-pull argument turns on.
5. The lead-with-long-term duty is now unconditional in all five encodings;
conflict-scoping is kept only on the cannot-outvote consequence.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/s labels Sep 3, 2026 — with Claude
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Sep 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 33706142983 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (1/6) — 失败步骤: Run this shard's tests

    @objectstack/cli:test: FAIL integration test/run-dev-unbuilt-workspace.e2e.test.ts > the mirror direction: a reader that is never coming back > gives up and exits instead of waiting forever
    ↳ 失败原因: @objectstack/cli:test: AssertionError: expected 'SIGKILL' to be null
    

↳ 失败原因 是判读的关键:超时Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 39 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

Merged via the queue into main with commit db07f69Sep 3, 2026
39 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14146-frame-copy-minors branch September 3, 2026 02:51
This was referenced Sep 3, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding - #14779

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors
Sep 3, 2026
Merged

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding#14779
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Fixes#14146

Five semantic minors in the axis-weighting / batch-presentation encoding, caught by the at-tier compensating review of PR #14142 and fixed exactly as the reviewer prescribed. Every edit is in place: zero net lines in all four ratcheted files, and the published entry shrinks.

Positions are re-measured on today's main (224f8ea4a); the card's line numbers predate two merges, so they are restated below with the old number in parentheses.

Item 1 — stale cap-form restatement replaced by a pointer

Landing:.claude/skills/pm-dispatch/SKILL.mdL454 (card: L441)

before…照旧现场呈报,走每批 ≤5 与详细写法纪律。
after…照旧现场呈报,走常设决裁批流程与详细写法纪律。

The class-2/3 live-presentation route carried an inline 每批 ≤5 while the single home now rules 恰好 5 张 — a seat following the old line could present a 2-card batch and claim compliance. The number is gone; 常设决裁批流程 is the verbatim section heading in references/decision-analysis.md, so the pointer is greppable and there is now exactly one place that states the batch size. Line is 119 bytes (limit 120), zero lines added.

Item 2 — the final partial batch gets its legal move

Landing:.claude/skills/pm-dispatch/references/decision-analysis.mdL13

before- 每批**恰好 5 张,呈完即停等回批**(2026-09-01
after- 每批**恰好 5 张(末批不足照呈),呈完即停等回批**(2026-09-01

恰好 5 张 plus 收件箱读数为零才收工 (L17) forbade both presenting fewer than 5 and holding the remainder — the last batch of any queue that is not a multiple of five had no legal move. Inserted in place on the existing line: 57 B to 77 B, file stays at 54 lines (ceiling 54, headroom 0).

Item 3 — count-free wording, in every copy

Chosen: count-free wording. NOT a MENTION_PATTERNS extension. The reasoning, since the card left the choice open:

  • The gate's own charter is "blind to prose and sharp on shape", and its %N% / %Q% design exists so that an anchor never spells the value it compares. A count − 1 mention check re-introduces a derived arithmetic relationship that the regex must know in two languages — and a regex can only ever see the spellings it enumerates. Miss one (另外三轴, 其余三条, the remaining three) and the gate is green while the text is stale: the exact defect being repaired, one layer up.
  • Count-free wording removes the failure mode instead of policing it. After this PR there is no derived count anywhere in the four copies, so there is nothing for a future axis-count change to leave behind.
  • A MENTION_PATTERNS extension landed alongside count-free wording would have zero live matches — a dormant pattern, which is the shape this repo's gates treat as rot.

frameCountMentions still sees and checks the 4 real count mentions (gate output below); this change adds nothing to it and removes nothing from it.

Six sites, all count − 1 hard-codings (the card named five weighting clauses; the sixth, L553, is the same defect class in the axis-① worked example — same file already in this claim's surface, same gate family, mechanical, no new verification surface):

landingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L905另三轴合起来投不翻它其余各轴合起来投不翻它
references/decision-analysis.md L51另三轴合起来投不翻①其余各轴合起来投不翻①
.claude/agents/os-dev.md L418推荐以它领起,另三轴合起来投不翻它推荐以它领起,其余各轴合起来投不翻它
skills/objectstack-pm-dispatch/SKILL.md L553On the other three axes theyOn the other axes they
skills/objectstack-pm-dispatch/SKILL.md L593the other three together cannot outvotethe others together cannot outvote
skills/objectstack-pm-dispatch/SKILL.md L659lead with it, the other threelead with it, the others

另三轴 and the other three are now at 0 occurrences across all four copies.

Item 4 — published entry: dangling anchor and the dropped term

Landing:skills/objectstack-pm-dispatch/SKILL.mdL594 (card: L703) and L660-661 (card: L859)

sitebeforeafter
L594Read that weight through axis ②'s own definition — shrink special-cases and contract accretion, never grow themRead that weight as shrinking special-cases and contract accretion, never growing them
L660-661read it as shrinking special-cases rather than as licence to expand speculativelyread it as shrinking special-cases and contract accretion rather than as licence to expand speculatively

The L594 citation pointed at that file's axis-② definition for the shrink-not-grow reading, which that definition nowhere states (the real anchor deliberately does not ship under the route-B generalization) — it is now self-contained and asserts the reading directly. L660-661 regains and contract accretion, the term the zero-pull no-conflict argument turns on.

Item 5 — the lead-with-long-term duty, unconditional in all five encodings

The card's premise held on today's tree: 3 unconditional, 2 scoped to axis conflict.

encodingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L904-905四轴冲突时推荐以长远的读数领起,另三轴合起来投不翻它conditional推荐以长远的读数领起,四轴冲突时其余各轴合起来投不翻它 — unconditional lead
skills/objectstack-pm-dispatch/SKILL.md L592-593**Axis ② carries the highest weight — at least 50%** when the axes conflict: lead with the long-term reading, and…conditional**Axis ② carries the highest weight — at least 50%.** Lead with the long-term reading; when the axes conflict, the others…
references/decision-analysis.md L50-51①恒 ≥50%,推荐以①领起 — already unconditionalunchanged (item 3 rewording only)
.claude/agents/os-dev.md L417-418推荐以它领起 — already unconditionalunchanged (item 3 rewording only)
skills/objectstack-pm-dispatch/SKILL.md L659lead with it — already unconditionalunchanged (item 3 rewording only)

Conflict-scoping is kept, in both rewritten copies, on the cannot-outvote consequence only — which is where it is meaningful, since there is nothing to outvote absent a conflict.

Line and token arithmetic, per file

filelines beforelines afterceilingheadroom
.claude/skills/pm-dispatch/SKILL.md989989100516 (unchanged)
.claude/skills/pm-dispatch/references/decision-analysis.md5454540 (unchanged)
.claude/agents/os-dev.md4694694690 (unchanged)
skills/objectstack-pm-dispatch/SKILL.md753753not line-ratcheted

No line in any edited file exceeds the 120-byte rule; the widest edited lines are SKILL.md L454 (119 B), L904 (118 B) and os-dev.md L418 (120 B). max-table-row-bytes pins are untouched — no table was edited.

Published entry, token ratchet (convention ceil(utf8 bytes / 4)), measured per site:

siteitemsbeforeafterdelta
L553377 B71 B−6 B
L592-5963, 4, 5372 B335 B−37 B
L657-6623, 4235 B253 B+18 B
file38,832 B = 9,708 tokens38,807 B = 9,702 tokens−25 B / −6 tokens

How item 4's added words are paid, inside the same file, without a re-wrap and without a ceiling change: item 4's only cost is and contract accretion at L660-661, +23 B. It is paid by item 4's own other half — deleting the dangling citation through axis ②'s own definition — (38 B, replaced by as , 3 B) at L594 — with item 3's −16 B of count-free rewording on top. The ceiling stays at 9,708 and is not lowered, per the dispatch's explicit no-ceiling-change constraint; the file now sits 6 tokens under it.

Published-surface readings (skills/** diff)

Both readings the published surface requires, lines first, tokens beside them:

readingbeforeafterdelta
edited file — skills/objectstack-pm-dispatch/SKILL.md753 lines · 38,832 B · 9,708 tokens753 lines · 38,807 B · 9,702 tokens0 lines · −25 B · −6 tokens
whole published package — all 11 skills/*/SKILL.md6,862 lines · 318,948 B · 79,737 tokens6,862 lines · 318,923 B · 79,731 tokens0 lines · −25 B · −6 tokens

No net expansion in either reading: this PR corrects wording in place and the published surface comes out marginally smaller. There is no new capability here and therefore no "small feature, big write-up" to price — the one clause that gains words (item 4's and contract accretion) is paid twice over inside the same file.

skip-changeset

Applied. The diff publishes nothing from any package: .claude/** agent protocol plus the skills/** catalog, which ships through npx skills add, not through a package release. Measured rather than assumed — none of the six most recent commits touching skills/objectstack-pm-dispatch/SKILL.md carried a .changeset/ file (c985ae958, a9b2be0b0, 2bff79ae3, bcc9189e6, 3d0897459, d250754fd), and 2bff79ae3 is this card's own parent PR with the identical face set.

Gates

Every command ran through scripts/pm/os-verify-lock.sh (slot issue-14146), each exit code captured by redirect before any pipe. The union below was re-derived after the final commit with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and run at dd9f7d39f — the branch head.

gateverdict line
check:skill-frame-sync✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files · 4 axes: business-need → long-term-soundness → ai-authoring-safety → startup-scope-discipline · binding sentence present in all 4; 4 count mention(s) agree; 40 markdown files scanned for undeclared copies.
check:skill-frame-sync --self-test✓ check-skill-frame-sync self-test: 12 cases pass, plus 5 dispatch-gates declaration cases.
check:skill-frame-freshness✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:skill-frame-freshness --self-test✓ check-skill-frame-freshness self-test: 12 cases pass.
check:pm-skill-ratchet✓ …SKILL.md is 989 lines (ceiling 1005; headroom 16). · ✓ …decision-analysis.md is 54 lines (ceiling 54; headroom 0). · ✓ …os-dev.md is 469 lines (ceiling 469; headroom 0).
check:pm-skill-ratchet --self-test✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g). · self-test 14 cases pass.
check-skills-token-ratchet✓ …skills/objectstack-pm-dispatch/SKILL.md is 9702 tokens (ceiling 9708; headroom 6). · ✓ …36 authored bundle file(s) within their ceilings
check-skills-token-ratchet --self-test✓ check-skills-token-ratchet self-test: 64 cases pass.
@objectstack/spec check:skill-docs✓ skills/README.md · ✓ content/docs/ai/skills-reference.mdx · ✅ Skill docs in sync
check:nul-bytescheck-nul-bytes: OK (scanned 8052 text file(s) — 8052 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes). · self-test 75 assertions

Full derived union at dd9f7d39f20 of 22 green, and the two that are not green are NOT MEASURED, not red:

check-ci-filter-parity · check-cross-package-test-inputs · check-shard-attestation · check-skills-token-ratchet · check:skill-docs · check:agent-model-declared · check:agent-test-spelling · check:corpus-claim-drift · check:cross-package-test-inputs · check:doc-authoring · check:nul-bytes · check:pm-governed-merges · check:pm-governed-prose · check:pm-skill-id-lint · check:pm-skill-ratchet · check:role-word · check:skill-compatibility · check:skill-frame-sync · check:skill-identifier-liveness · check:skill-frame-freshness — all green.

  • check-test-completenessexit 3, NOT MEASURED. Its own text: "That list names this script with NO argument… There is no local log to hand it, so the local reading for this gate is NOT MEASURED. ⛔ It is not a red, and there is nothing here to fix." It consumes a turbo run test log that only CI produces; this diff touches no test.
  • check:doc-formula-expressionsexit 3, PREREQUISITE NOT MET (@objectstack/formula is not built in this worktree). Not a finding. Building it needs the shared verify lock, and two bounded acquisitions timed out at the 540 s budget behind a sibling's run (exit 99, place kept — also NOT MEASURED, never a red). Declared narrowing, measured from the gate's own predicate rather than asserted:fencedBlocks() keeps only fences whose language tag is ts, typescript or tsx, and the text scan is FIELD_RULE_TEXT_RE (visibleWhen|readonlyWhen|requiredWhen). Across all four edited files the gate would parse 0 fenced blocks — the fences present are bash, json, text and bare, none of them a parsed language — 0 of the 17 changed lines fall inside a parsed block, and there are 0FIELD_RULE_TEXT_RE occurrences. The gate has nothing to read in this diff, so its verdict cannot move. CI builds the package and runs it for real.

Beyond the derived union I also self-scanned the four edited files for raw control bytes (grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'): zero hits.

Premise notes


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

… encoding
Five in-place, zero-net-line corrections to the escalation decision frame's
four copies and the decision-analysis reference:
1. The class-2/3 live-presentation route in the internal PM skill restated a
stale per-batch cap; it now points at the single home that rules the batch
size, so the two cannot drift apart again.
2. The standing adjudication batch flow had no legal move for a final partial
batch (an exact-size rule plus a drain-the-inbox rule forbade both
presenting short and holding the remainder). The short last batch is now
presented as-is.
3. Every weighting clause hard-coded "the other three", an axis-count minus one
that the frame-sync gate's MENTION_PATTERNS structurally cannot see. All six
sites are now count-free, so no derived count can go stale.
4. Published entry: the shrink-not-grow reading no longer cites an axis
definition that does not state it, and the embedded dev template regains
"and contract accretion" — the term the zero-pull argument turns on.
5. The lead-with-long-term duty is now unconditional in all five encodings;
conflict-scoping is kept only on the cannot-outvote consequence.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/s labels Sep 3, 2026 — with Claude
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Sep 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 33706142983 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (1/6) — 失败步骤: Run this shard's tests

    @objectstack/cli:test: FAIL integration test/run-dev-unbuilt-workspace.e2e.test.ts > the mirror direction: a reader that is never coming back > gives up and exits instead of waiting forever
    ↳ 失败原因: @objectstack/cli:test: AssertionError: expected 'SIGKILL' to be null
    

↳ 失败原因 是判读的关键:超时Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 39 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

Merged via the queue into main with commit db07f69Sep 3, 2026
39 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14146-frame-copy-minors branch September 3, 2026 02:51
This was referenced Sep 3, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding - #14779

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors
Sep 3, 2026
Merged

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding#14779
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Fixes#14146

Five semantic minors in the axis-weighting / batch-presentation encoding, caught by the at-tier compensating review of PR #14142 and fixed exactly as the reviewer prescribed. Every edit is in place: zero net lines in all four ratcheted files, and the published entry shrinks.

Positions are re-measured on today's main (224f8ea4a); the card's line numbers predate two merges, so they are restated below with the old number in parentheses.

Item 1 — stale cap-form restatement replaced by a pointer

Landing:.claude/skills/pm-dispatch/SKILL.mdL454 (card: L441)

before…照旧现场呈报,走每批 ≤5 与详细写法纪律。
after…照旧现场呈报,走常设决裁批流程与详细写法纪律。

The class-2/3 live-presentation route carried an inline 每批 ≤5 while the single home now rules 恰好 5 张 — a seat following the old line could present a 2-card batch and claim compliance. The number is gone; 常设决裁批流程 is the verbatim section heading in references/decision-analysis.md, so the pointer is greppable and there is now exactly one place that states the batch size. Line is 119 bytes (limit 120), zero lines added.

Item 2 — the final partial batch gets its legal move

Landing:.claude/skills/pm-dispatch/references/decision-analysis.mdL13

before- 每批**恰好 5 张,呈完即停等回批**(2026-09-01
after- 每批**恰好 5 张(末批不足照呈),呈完即停等回批**(2026-09-01

恰好 5 张 plus 收件箱读数为零才收工 (L17) forbade both presenting fewer than 5 and holding the remainder — the last batch of any queue that is not a multiple of five had no legal move. Inserted in place on the existing line: 57 B to 77 B, file stays at 54 lines (ceiling 54, headroom 0).

Item 3 — count-free wording, in every copy

Chosen: count-free wording. NOT a MENTION_PATTERNS extension. The reasoning, since the card left the choice open:

  • The gate's own charter is "blind to prose and sharp on shape", and its %N% / %Q% design exists so that an anchor never spells the value it compares. A count − 1 mention check re-introduces a derived arithmetic relationship that the regex must know in two languages — and a regex can only ever see the spellings it enumerates. Miss one (另外三轴, 其余三条, the remaining three) and the gate is green while the text is stale: the exact defect being repaired, one layer up.
  • Count-free wording removes the failure mode instead of policing it. After this PR there is no derived count anywhere in the four copies, so there is nothing for a future axis-count change to leave behind.
  • A MENTION_PATTERNS extension landed alongside count-free wording would have zero live matches — a dormant pattern, which is the shape this repo's gates treat as rot.

frameCountMentions still sees and checks the 4 real count mentions (gate output below); this change adds nothing to it and removes nothing from it.

Six sites, all count − 1 hard-codings (the card named five weighting clauses; the sixth, L553, is the same defect class in the axis-① worked example — same file already in this claim's surface, same gate family, mechanical, no new verification surface):

landingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L905另三轴合起来投不翻它其余各轴合起来投不翻它
references/decision-analysis.md L51另三轴合起来投不翻①其余各轴合起来投不翻①
.claude/agents/os-dev.md L418推荐以它领起,另三轴合起来投不翻它推荐以它领起,其余各轴合起来投不翻它
skills/objectstack-pm-dispatch/SKILL.md L553On the other three axes theyOn the other axes they
skills/objectstack-pm-dispatch/SKILL.md L593the other three together cannot outvotethe others together cannot outvote
skills/objectstack-pm-dispatch/SKILL.md L659lead with it, the other threelead with it, the others

另三轴 and the other three are now at 0 occurrences across all four copies.

Item 4 — published entry: dangling anchor and the dropped term

Landing:skills/objectstack-pm-dispatch/SKILL.mdL594 (card: L703) and L660-661 (card: L859)

sitebeforeafter
L594Read that weight through axis ②'s own definition — shrink special-cases and contract accretion, never grow themRead that weight as shrinking special-cases and contract accretion, never growing them
L660-661read it as shrinking special-cases rather than as licence to expand speculativelyread it as shrinking special-cases and contract accretion rather than as licence to expand speculatively

The L594 citation pointed at that file's axis-② definition for the shrink-not-grow reading, which that definition nowhere states (the real anchor deliberately does not ship under the route-B generalization) — it is now self-contained and asserts the reading directly. L660-661 regains and contract accretion, the term the zero-pull no-conflict argument turns on.

Item 5 — the lead-with-long-term duty, unconditional in all five encodings

The card's premise held on today's tree: 3 unconditional, 2 scoped to axis conflict.

encodingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L904-905四轴冲突时推荐以长远的读数领起,另三轴合起来投不翻它conditional推荐以长远的读数领起,四轴冲突时其余各轴合起来投不翻它 — unconditional lead
skills/objectstack-pm-dispatch/SKILL.md L592-593**Axis ② carries the highest weight — at least 50%** when the axes conflict: lead with the long-term reading, and…conditional**Axis ② carries the highest weight — at least 50%.** Lead with the long-term reading; when the axes conflict, the others…
references/decision-analysis.md L50-51①恒 ≥50%,推荐以①领起 — already unconditionalunchanged (item 3 rewording only)
.claude/agents/os-dev.md L417-418推荐以它领起 — already unconditionalunchanged (item 3 rewording only)
skills/objectstack-pm-dispatch/SKILL.md L659lead with it — already unconditionalunchanged (item 3 rewording only)

Conflict-scoping is kept, in both rewritten copies, on the cannot-outvote consequence only — which is where it is meaningful, since there is nothing to outvote absent a conflict.

Line and token arithmetic, per file

filelines beforelines afterceilingheadroom
.claude/skills/pm-dispatch/SKILL.md989989100516 (unchanged)
.claude/skills/pm-dispatch/references/decision-analysis.md5454540 (unchanged)
.claude/agents/os-dev.md4694694690 (unchanged)
skills/objectstack-pm-dispatch/SKILL.md753753not line-ratcheted

No line in any edited file exceeds the 120-byte rule; the widest edited lines are SKILL.md L454 (119 B), L904 (118 B) and os-dev.md L418 (120 B). max-table-row-bytes pins are untouched — no table was edited.

Published entry, token ratchet (convention ceil(utf8 bytes / 4)), measured per site:

siteitemsbeforeafterdelta
L553377 B71 B−6 B
L592-5963, 4, 5372 B335 B−37 B
L657-6623, 4235 B253 B+18 B
file38,832 B = 9,708 tokens38,807 B = 9,702 tokens−25 B / −6 tokens

How item 4's added words are paid, inside the same file, without a re-wrap and without a ceiling change: item 4's only cost is and contract accretion at L660-661, +23 B. It is paid by item 4's own other half — deleting the dangling citation through axis ②'s own definition — (38 B, replaced by as , 3 B) at L594 — with item 3's −16 B of count-free rewording on top. The ceiling stays at 9,708 and is not lowered, per the dispatch's explicit no-ceiling-change constraint; the file now sits 6 tokens under it.

Published-surface readings (skills/** diff)

Both readings the published surface requires, lines first, tokens beside them:

readingbeforeafterdelta
edited file — skills/objectstack-pm-dispatch/SKILL.md753 lines · 38,832 B · 9,708 tokens753 lines · 38,807 B · 9,702 tokens0 lines · −25 B · −6 tokens
whole published package — all 11 skills/*/SKILL.md6,862 lines · 318,948 B · 79,737 tokens6,862 lines · 318,923 B · 79,731 tokens0 lines · −25 B · −6 tokens

No net expansion in either reading: this PR corrects wording in place and the published surface comes out marginally smaller. There is no new capability here and therefore no "small feature, big write-up" to price — the one clause that gains words (item 4's and contract accretion) is paid twice over inside the same file.

skip-changeset

Applied. The diff publishes nothing from any package: .claude/** agent protocol plus the skills/** catalog, which ships through npx skills add, not through a package release. Measured rather than assumed — none of the six most recent commits touching skills/objectstack-pm-dispatch/SKILL.md carried a .changeset/ file (c985ae958, a9b2be0b0, 2bff79ae3, bcc9189e6, 3d0897459, d250754fd), and 2bff79ae3 is this card's own parent PR with the identical face set.

Gates

Every command ran through scripts/pm/os-verify-lock.sh (slot issue-14146), each exit code captured by redirect before any pipe. The union below was re-derived after the final commit with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and run at dd9f7d39f — the branch head.

gateverdict line
check:skill-frame-sync✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files · 4 axes: business-need → long-term-soundness → ai-authoring-safety → startup-scope-discipline · binding sentence present in all 4; 4 count mention(s) agree; 40 markdown files scanned for undeclared copies.
check:skill-frame-sync --self-test✓ check-skill-frame-sync self-test: 12 cases pass, plus 5 dispatch-gates declaration cases.
check:skill-frame-freshness✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:skill-frame-freshness --self-test✓ check-skill-frame-freshness self-test: 12 cases pass.
check:pm-skill-ratchet✓ …SKILL.md is 989 lines (ceiling 1005; headroom 16). · ✓ …decision-analysis.md is 54 lines (ceiling 54; headroom 0). · ✓ …os-dev.md is 469 lines (ceiling 469; headroom 0).
check:pm-skill-ratchet --self-test✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g). · self-test 14 cases pass.
check-skills-token-ratchet✓ …skills/objectstack-pm-dispatch/SKILL.md is 9702 tokens (ceiling 9708; headroom 6). · ✓ …36 authored bundle file(s) within their ceilings
check-skills-token-ratchet --self-test✓ check-skills-token-ratchet self-test: 64 cases pass.
@objectstack/spec check:skill-docs✓ skills/README.md · ✓ content/docs/ai/skills-reference.mdx · ✅ Skill docs in sync
check:nul-bytescheck-nul-bytes: OK (scanned 8052 text file(s) — 8052 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes). · self-test 75 assertions

Full derived union at dd9f7d39f20 of 22 green, and the two that are not green are NOT MEASURED, not red:

check-ci-filter-parity · check-cross-package-test-inputs · check-shard-attestation · check-skills-token-ratchet · check:skill-docs · check:agent-model-declared · check:agent-test-spelling · check:corpus-claim-drift · check:cross-package-test-inputs · check:doc-authoring · check:nul-bytes · check:pm-governed-merges · check:pm-governed-prose · check:pm-skill-id-lint · check:pm-skill-ratchet · check:role-word · check:skill-compatibility · check:skill-frame-sync · check:skill-identifier-liveness · check:skill-frame-freshness — all green.

  • check-test-completenessexit 3, NOT MEASURED. Its own text: "That list names this script with NO argument… There is no local log to hand it, so the local reading for this gate is NOT MEASURED. ⛔ It is not a red, and there is nothing here to fix." It consumes a turbo run test log that only CI produces; this diff touches no test.
  • check:doc-formula-expressionsexit 3, PREREQUISITE NOT MET (@objectstack/formula is not built in this worktree). Not a finding. Building it needs the shared verify lock, and two bounded acquisitions timed out at the 540 s budget behind a sibling's run (exit 99, place kept — also NOT MEASURED, never a red). Declared narrowing, measured from the gate's own predicate rather than asserted:fencedBlocks() keeps only fences whose language tag is ts, typescript or tsx, and the text scan is FIELD_RULE_TEXT_RE (visibleWhen|readonlyWhen|requiredWhen). Across all four edited files the gate would parse 0 fenced blocks — the fences present are bash, json, text and bare, none of them a parsed language — 0 of the 17 changed lines fall inside a parsed block, and there are 0FIELD_RULE_TEXT_RE occurrences. The gate has nothing to read in this diff, so its verdict cannot move. CI builds the package and runs it for real.

Beyond the derived union I also self-scanned the four edited files for raw control bytes (grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'): zero hits.

Premise notes


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

… encoding
Five in-place, zero-net-line corrections to the escalation decision frame's
four copies and the decision-analysis reference:
1. The class-2/3 live-presentation route in the internal PM skill restated a
stale per-batch cap; it now points at the single home that rules the batch
size, so the two cannot drift apart again.
2. The standing adjudication batch flow had no legal move for a final partial
batch (an exact-size rule plus a drain-the-inbox rule forbade both
presenting short and holding the remainder). The short last batch is now
presented as-is.
3. Every weighting clause hard-coded "the other three", an axis-count minus one
that the frame-sync gate's MENTION_PATTERNS structurally cannot see. All six
sites are now count-free, so no derived count can go stale.
4. Published entry: the shrink-not-grow reading no longer cites an axis
definition that does not state it, and the embedded dev template regains
"and contract accretion" — the term the zero-pull argument turns on.
5. The lead-with-long-term duty is now unconditional in all five encodings;
conflict-scoping is kept only on the cannot-outvote consequence.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/s labels Sep 3, 2026 — with Claude
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Sep 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 33706142983 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (1/6) — 失败步骤: Run this shard's tests

    @objectstack/cli:test: FAIL integration test/run-dev-unbuilt-workspace.e2e.test.ts > the mirror direction: a reader that is never coming back > gives up and exits instead of waiting forever
    ↳ 失败原因: @objectstack/cli:test: AssertionError: expected 'SIGKILL' to be null
    

↳ 失败原因 是判读的关键:超时Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 39 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

Merged via the queue into main with commit db07f69Sep 3, 2026
39 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14146-frame-copy-minors branch September 3, 2026 02:51
This was referenced Sep 3, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding - #14779

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors
Sep 3, 2026
Merged

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding#14779
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Fixes#14146

Five semantic minors in the axis-weighting / batch-presentation encoding, caught by the at-tier compensating review of PR #14142 and fixed exactly as the reviewer prescribed. Every edit is in place: zero net lines in all four ratcheted files, and the published entry shrinks.

Positions are re-measured on today's main (224f8ea4a); the card's line numbers predate two merges, so they are restated below with the old number in parentheses.

Item 1 — stale cap-form restatement replaced by a pointer

Landing:.claude/skills/pm-dispatch/SKILL.mdL454 (card: L441)

before…照旧现场呈报,走每批 ≤5 与详细写法纪律。
after…照旧现场呈报,走常设决裁批流程与详细写法纪律。

The class-2/3 live-presentation route carried an inline 每批 ≤5 while the single home now rules 恰好 5 张 — a seat following the old line could present a 2-card batch and claim compliance. The number is gone; 常设决裁批流程 is the verbatim section heading in references/decision-analysis.md, so the pointer is greppable and there is now exactly one place that states the batch size. Line is 119 bytes (limit 120), zero lines added.

Item 2 — the final partial batch gets its legal move

Landing:.claude/skills/pm-dispatch/references/decision-analysis.mdL13

before- 每批**恰好 5 张,呈完即停等回批**(2026-09-01
after- 每批**恰好 5 张(末批不足照呈),呈完即停等回批**(2026-09-01

恰好 5 张 plus 收件箱读数为零才收工 (L17) forbade both presenting fewer than 5 and holding the remainder — the last batch of any queue that is not a multiple of five had no legal move. Inserted in place on the existing line: 57 B to 77 B, file stays at 54 lines (ceiling 54, headroom 0).

Item 3 — count-free wording, in every copy

Chosen: count-free wording. NOT a MENTION_PATTERNS extension. The reasoning, since the card left the choice open:

  • The gate's own charter is "blind to prose and sharp on shape", and its %N% / %Q% design exists so that an anchor never spells the value it compares. A count − 1 mention check re-introduces a derived arithmetic relationship that the regex must know in two languages — and a regex can only ever see the spellings it enumerates. Miss one (另外三轴, 其余三条, the remaining three) and the gate is green while the text is stale: the exact defect being repaired, one layer up.
  • Count-free wording removes the failure mode instead of policing it. After this PR there is no derived count anywhere in the four copies, so there is nothing for a future axis-count change to leave behind.
  • A MENTION_PATTERNS extension landed alongside count-free wording would have zero live matches — a dormant pattern, which is the shape this repo's gates treat as rot.

frameCountMentions still sees and checks the 4 real count mentions (gate output below); this change adds nothing to it and removes nothing from it.

Six sites, all count − 1 hard-codings (the card named five weighting clauses; the sixth, L553, is the same defect class in the axis-① worked example — same file already in this claim's surface, same gate family, mechanical, no new verification surface):

landingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L905另三轴合起来投不翻它其余各轴合起来投不翻它
references/decision-analysis.md L51另三轴合起来投不翻①其余各轴合起来投不翻①
.claude/agents/os-dev.md L418推荐以它领起,另三轴合起来投不翻它推荐以它领起,其余各轴合起来投不翻它
skills/objectstack-pm-dispatch/SKILL.md L553On the other three axes theyOn the other axes they
skills/objectstack-pm-dispatch/SKILL.md L593the other three together cannot outvotethe others together cannot outvote
skills/objectstack-pm-dispatch/SKILL.md L659lead with it, the other threelead with it, the others

另三轴 and the other three are now at 0 occurrences across all four copies.

Item 4 — published entry: dangling anchor and the dropped term

Landing:skills/objectstack-pm-dispatch/SKILL.mdL594 (card: L703) and L660-661 (card: L859)

sitebeforeafter
L594Read that weight through axis ②'s own definition — shrink special-cases and contract accretion, never grow themRead that weight as shrinking special-cases and contract accretion, never growing them
L660-661read it as shrinking special-cases rather than as licence to expand speculativelyread it as shrinking special-cases and contract accretion rather than as licence to expand speculatively

The L594 citation pointed at that file's axis-② definition for the shrink-not-grow reading, which that definition nowhere states (the real anchor deliberately does not ship under the route-B generalization) — it is now self-contained and asserts the reading directly. L660-661 regains and contract accretion, the term the zero-pull no-conflict argument turns on.

Item 5 — the lead-with-long-term duty, unconditional in all five encodings

The card's premise held on today's tree: 3 unconditional, 2 scoped to axis conflict.

encodingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L904-905四轴冲突时推荐以长远的读数领起,另三轴合起来投不翻它conditional推荐以长远的读数领起,四轴冲突时其余各轴合起来投不翻它 — unconditional lead
skills/objectstack-pm-dispatch/SKILL.md L592-593**Axis ② carries the highest weight — at least 50%** when the axes conflict: lead with the long-term reading, and…conditional**Axis ② carries the highest weight — at least 50%.** Lead with the long-term reading; when the axes conflict, the others…
references/decision-analysis.md L50-51①恒 ≥50%,推荐以①领起 — already unconditionalunchanged (item 3 rewording only)
.claude/agents/os-dev.md L417-418推荐以它领起 — already unconditionalunchanged (item 3 rewording only)
skills/objectstack-pm-dispatch/SKILL.md L659lead with it — already unconditionalunchanged (item 3 rewording only)

Conflict-scoping is kept, in both rewritten copies, on the cannot-outvote consequence only — which is where it is meaningful, since there is nothing to outvote absent a conflict.

Line and token arithmetic, per file

filelines beforelines afterceilingheadroom
.claude/skills/pm-dispatch/SKILL.md989989100516 (unchanged)
.claude/skills/pm-dispatch/references/decision-analysis.md5454540 (unchanged)
.claude/agents/os-dev.md4694694690 (unchanged)
skills/objectstack-pm-dispatch/SKILL.md753753not line-ratcheted

No line in any edited file exceeds the 120-byte rule; the widest edited lines are SKILL.md L454 (119 B), L904 (118 B) and os-dev.md L418 (120 B). max-table-row-bytes pins are untouched — no table was edited.

Published entry, token ratchet (convention ceil(utf8 bytes / 4)), measured per site:

siteitemsbeforeafterdelta
L553377 B71 B−6 B
L592-5963, 4, 5372 B335 B−37 B
L657-6623, 4235 B253 B+18 B
file38,832 B = 9,708 tokens38,807 B = 9,702 tokens−25 B / −6 tokens

How item 4's added words are paid, inside the same file, without a re-wrap and without a ceiling change: item 4's only cost is and contract accretion at L660-661, +23 B. It is paid by item 4's own other half — deleting the dangling citation through axis ②'s own definition — (38 B, replaced by as , 3 B) at L594 — with item 3's −16 B of count-free rewording on top. The ceiling stays at 9,708 and is not lowered, per the dispatch's explicit no-ceiling-change constraint; the file now sits 6 tokens under it.

Published-surface readings (skills/** diff)

Both readings the published surface requires, lines first, tokens beside them:

readingbeforeafterdelta
edited file — skills/objectstack-pm-dispatch/SKILL.md753 lines · 38,832 B · 9,708 tokens753 lines · 38,807 B · 9,702 tokens0 lines · −25 B · −6 tokens
whole published package — all 11 skills/*/SKILL.md6,862 lines · 318,948 B · 79,737 tokens6,862 lines · 318,923 B · 79,731 tokens0 lines · −25 B · −6 tokens

No net expansion in either reading: this PR corrects wording in place and the published surface comes out marginally smaller. There is no new capability here and therefore no "small feature, big write-up" to price — the one clause that gains words (item 4's and contract accretion) is paid twice over inside the same file.

skip-changeset

Applied. The diff publishes nothing from any package: .claude/** agent protocol plus the skills/** catalog, which ships through npx skills add, not through a package release. Measured rather than assumed — none of the six most recent commits touching skills/objectstack-pm-dispatch/SKILL.md carried a .changeset/ file (c985ae958, a9b2be0b0, 2bff79ae3, bcc9189e6, 3d0897459, d250754fd), and 2bff79ae3 is this card's own parent PR with the identical face set.

Gates

Every command ran through scripts/pm/os-verify-lock.sh (slot issue-14146), each exit code captured by redirect before any pipe. The union below was re-derived after the final commit with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and run at dd9f7d39f — the branch head.

gateverdict line
check:skill-frame-sync✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files · 4 axes: business-need → long-term-soundness → ai-authoring-safety → startup-scope-discipline · binding sentence present in all 4; 4 count mention(s) agree; 40 markdown files scanned for undeclared copies.
check:skill-frame-sync --self-test✓ check-skill-frame-sync self-test: 12 cases pass, plus 5 dispatch-gates declaration cases.
check:skill-frame-freshness✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:skill-frame-freshness --self-test✓ check-skill-frame-freshness self-test: 12 cases pass.
check:pm-skill-ratchet✓ …SKILL.md is 989 lines (ceiling 1005; headroom 16). · ✓ …decision-analysis.md is 54 lines (ceiling 54; headroom 0). · ✓ …os-dev.md is 469 lines (ceiling 469; headroom 0).
check:pm-skill-ratchet --self-test✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g). · self-test 14 cases pass.
check-skills-token-ratchet✓ …skills/objectstack-pm-dispatch/SKILL.md is 9702 tokens (ceiling 9708; headroom 6). · ✓ …36 authored bundle file(s) within their ceilings
check-skills-token-ratchet --self-test✓ check-skills-token-ratchet self-test: 64 cases pass.
@objectstack/spec check:skill-docs✓ skills/README.md · ✓ content/docs/ai/skills-reference.mdx · ✅ Skill docs in sync
check:nul-bytescheck-nul-bytes: OK (scanned 8052 text file(s) — 8052 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes). · self-test 75 assertions

Full derived union at dd9f7d39f20 of 22 green, and the two that are not green are NOT MEASURED, not red:

check-ci-filter-parity · check-cross-package-test-inputs · check-shard-attestation · check-skills-token-ratchet · check:skill-docs · check:agent-model-declared · check:agent-test-spelling · check:corpus-claim-drift · check:cross-package-test-inputs · check:doc-authoring · check:nul-bytes · check:pm-governed-merges · check:pm-governed-prose · check:pm-skill-id-lint · check:pm-skill-ratchet · check:role-word · check:skill-compatibility · check:skill-frame-sync · check:skill-identifier-liveness · check:skill-frame-freshness — all green.

  • check-test-completenessexit 3, NOT MEASURED. Its own text: "That list names this script with NO argument… There is no local log to hand it, so the local reading for this gate is NOT MEASURED. ⛔ It is not a red, and there is nothing here to fix." It consumes a turbo run test log that only CI produces; this diff touches no test.
  • check:doc-formula-expressionsexit 3, PREREQUISITE NOT MET (@objectstack/formula is not built in this worktree). Not a finding. Building it needs the shared verify lock, and two bounded acquisitions timed out at the 540 s budget behind a sibling's run (exit 99, place kept — also NOT MEASURED, never a red). Declared narrowing, measured from the gate's own predicate rather than asserted:fencedBlocks() keeps only fences whose language tag is ts, typescript or tsx, and the text scan is FIELD_RULE_TEXT_RE (visibleWhen|readonlyWhen|requiredWhen). Across all four edited files the gate would parse 0 fenced blocks — the fences present are bash, json, text and bare, none of them a parsed language — 0 of the 17 changed lines fall inside a parsed block, and there are 0FIELD_RULE_TEXT_RE occurrences. The gate has nothing to read in this diff, so its verdict cannot move. CI builds the package and runs it for real.

Beyond the derived union I also self-scanned the four edited files for raw control bytes (grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'): zero hits.

Premise notes


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

… encoding
Five in-place, zero-net-line corrections to the escalation decision frame's
four copies and the decision-analysis reference:
1. The class-2/3 live-presentation route in the internal PM skill restated a
stale per-batch cap; it now points at the single home that rules the batch
size, so the two cannot drift apart again.
2. The standing adjudication batch flow had no legal move for a final partial
batch (an exact-size rule plus a drain-the-inbox rule forbade both
presenting short and holding the remainder). The short last batch is now
presented as-is.
3. Every weighting clause hard-coded "the other three", an axis-count minus one
that the frame-sync gate's MENTION_PATTERNS structurally cannot see. All six
sites are now count-free, so no derived count can go stale.
4. Published entry: the shrink-not-grow reading no longer cites an axis
definition that does not state it, and the embedded dev template regains
"and contract accretion" — the term the zero-pull argument turns on.
5. The lead-with-long-term duty is now unconditional in all five encodings;
conflict-scoping is kept only on the cannot-outvote consequence.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/s labels Sep 3, 2026 — with Claude
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Sep 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 33706142983 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (1/6) — 失败步骤: Run this shard's tests

    @objectstack/cli:test: FAIL integration test/run-dev-unbuilt-workspace.e2e.test.ts > the mirror direction: a reader that is never coming back > gives up and exits instead of waiting forever
    ↳ 失败原因: @objectstack/cli:test: AssertionError: expected 'SIGKILL' to be null
    

↳ 失败原因 是判读的关键:超时Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 39 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

Merged via the queue into main with commit db07f69Sep 3, 2026
39 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14146-frame-copy-minors branch September 3, 2026 02:51
This was referenced Sep 3, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding - #14779

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors
Sep 3, 2026
Merged

docs(skills): repair five semantic minors in the axis-weighting and batch-presentation encoding#14779
os-zhuang merged 1 commit into
mainfrom
claude/issue-14146-frame-copy-minors

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Fixes#14146

Five semantic minors in the axis-weighting / batch-presentation encoding, caught by the at-tier compensating review of PR #14142 and fixed exactly as the reviewer prescribed. Every edit is in place: zero net lines in all four ratcheted files, and the published entry shrinks.

Positions are re-measured on today's main (224f8ea4a); the card's line numbers predate two merges, so they are restated below with the old number in parentheses.

Item 1 — stale cap-form restatement replaced by a pointer

Landing:.claude/skills/pm-dispatch/SKILL.mdL454 (card: L441)

before…照旧现场呈报,走每批 ≤5 与详细写法纪律。
after…照旧现场呈报,走常设决裁批流程与详细写法纪律。

The class-2/3 live-presentation route carried an inline 每批 ≤5 while the single home now rules 恰好 5 张 — a seat following the old line could present a 2-card batch and claim compliance. The number is gone; 常设决裁批流程 is the verbatim section heading in references/decision-analysis.md, so the pointer is greppable and there is now exactly one place that states the batch size. Line is 119 bytes (limit 120), zero lines added.

Item 2 — the final partial batch gets its legal move

Landing:.claude/skills/pm-dispatch/references/decision-analysis.mdL13

before- 每批**恰好 5 张,呈完即停等回批**(2026-09-01
after- 每批**恰好 5 张(末批不足照呈),呈完即停等回批**(2026-09-01

恰好 5 张 plus 收件箱读数为零才收工 (L17) forbade both presenting fewer than 5 and holding the remainder — the last batch of any queue that is not a multiple of five had no legal move. Inserted in place on the existing line: 57 B to 77 B, file stays at 54 lines (ceiling 54, headroom 0).

Item 3 — count-free wording, in every copy

Chosen: count-free wording. NOT a MENTION_PATTERNS extension. The reasoning, since the card left the choice open:

  • The gate's own charter is "blind to prose and sharp on shape", and its %N% / %Q% design exists so that an anchor never spells the value it compares. A count − 1 mention check re-introduces a derived arithmetic relationship that the regex must know in two languages — and a regex can only ever see the spellings it enumerates. Miss one (另外三轴, 其余三条, the remaining three) and the gate is green while the text is stale: the exact defect being repaired, one layer up.
  • Count-free wording removes the failure mode instead of policing it. After this PR there is no derived count anywhere in the four copies, so there is nothing for a future axis-count change to leave behind.
  • A MENTION_PATTERNS extension landed alongside count-free wording would have zero live matches — a dormant pattern, which is the shape this repo's gates treat as rot.

frameCountMentions still sees and checks the 4 real count mentions (gate output below); this change adds nothing to it and removes nothing from it.

Six sites, all count − 1 hard-codings (the card named five weighting clauses; the sixth, L553, is the same defect class in the axis-① worked example — same file already in this claim's surface, same gate family, mechanical, no new verification surface):

landingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L905另三轴合起来投不翻它其余各轴合起来投不翻它
references/decision-analysis.md L51另三轴合起来投不翻①其余各轴合起来投不翻①
.claude/agents/os-dev.md L418推荐以它领起,另三轴合起来投不翻它推荐以它领起,其余各轴合起来投不翻它
skills/objectstack-pm-dispatch/SKILL.md L553On the other three axes theyOn the other axes they
skills/objectstack-pm-dispatch/SKILL.md L593the other three together cannot outvotethe others together cannot outvote
skills/objectstack-pm-dispatch/SKILL.md L659lead with it, the other threelead with it, the others

另三轴 and the other three are now at 0 occurrences across all four copies.

Item 4 — published entry: dangling anchor and the dropped term

Landing:skills/objectstack-pm-dispatch/SKILL.mdL594 (card: L703) and L660-661 (card: L859)

sitebeforeafter
L594Read that weight through axis ②'s own definition — shrink special-cases and contract accretion, never grow themRead that weight as shrinking special-cases and contract accretion, never growing them
L660-661read it as shrinking special-cases rather than as licence to expand speculativelyread it as shrinking special-cases and contract accretion rather than as licence to expand speculatively

The L594 citation pointed at that file's axis-② definition for the shrink-not-grow reading, which that definition nowhere states (the real anchor deliberately does not ship under the route-B generalization) — it is now self-contained and asserts the reading directly. L660-661 regains and contract accretion, the term the zero-pull no-conflict argument turns on.

Item 5 — the lead-with-long-term duty, unconditional in all five encodings

The card's premise held on today's tree: 3 unconditional, 2 scoped to axis conflict.

encodingbeforeafter
.claude/skills/pm-dispatch/SKILL.md L904-905四轴冲突时推荐以长远的读数领起,另三轴合起来投不翻它conditional推荐以长远的读数领起,四轴冲突时其余各轴合起来投不翻它 — unconditional lead
skills/objectstack-pm-dispatch/SKILL.md L592-593**Axis ② carries the highest weight — at least 50%** when the axes conflict: lead with the long-term reading, and…conditional**Axis ② carries the highest weight — at least 50%.** Lead with the long-term reading; when the axes conflict, the others…
references/decision-analysis.md L50-51①恒 ≥50%,推荐以①领起 — already unconditionalunchanged (item 3 rewording only)
.claude/agents/os-dev.md L417-418推荐以它领起 — already unconditionalunchanged (item 3 rewording only)
skills/objectstack-pm-dispatch/SKILL.md L659lead with it — already unconditionalunchanged (item 3 rewording only)

Conflict-scoping is kept, in both rewritten copies, on the cannot-outvote consequence only — which is where it is meaningful, since there is nothing to outvote absent a conflict.

Line and token arithmetic, per file

filelines beforelines afterceilingheadroom
.claude/skills/pm-dispatch/SKILL.md989989100516 (unchanged)
.claude/skills/pm-dispatch/references/decision-analysis.md5454540 (unchanged)
.claude/agents/os-dev.md4694694690 (unchanged)
skills/objectstack-pm-dispatch/SKILL.md753753not line-ratcheted

No line in any edited file exceeds the 120-byte rule; the widest edited lines are SKILL.md L454 (119 B), L904 (118 B) and os-dev.md L418 (120 B). max-table-row-bytes pins are untouched — no table was edited.

Published entry, token ratchet (convention ceil(utf8 bytes / 4)), measured per site:

siteitemsbeforeafterdelta
L553377 B71 B−6 B
L592-5963, 4, 5372 B335 B−37 B
L657-6623, 4235 B253 B+18 B
file38,832 B = 9,708 tokens38,807 B = 9,702 tokens−25 B / −6 tokens

How item 4's added words are paid, inside the same file, without a re-wrap and without a ceiling change: item 4's only cost is and contract accretion at L660-661, +23 B. It is paid by item 4's own other half — deleting the dangling citation through axis ②'s own definition — (38 B, replaced by as , 3 B) at L594 — with item 3's −16 B of count-free rewording on top. The ceiling stays at 9,708 and is not lowered, per the dispatch's explicit no-ceiling-change constraint; the file now sits 6 tokens under it.

Published-surface readings (skills/** diff)

Both readings the published surface requires, lines first, tokens beside them:

readingbeforeafterdelta
edited file — skills/objectstack-pm-dispatch/SKILL.md753 lines · 38,832 B · 9,708 tokens753 lines · 38,807 B · 9,702 tokens0 lines · −25 B · −6 tokens
whole published package — all 11 skills/*/SKILL.md6,862 lines · 318,948 B · 79,737 tokens6,862 lines · 318,923 B · 79,731 tokens0 lines · −25 B · −6 tokens

No net expansion in either reading: this PR corrects wording in place and the published surface comes out marginally smaller. There is no new capability here and therefore no "small feature, big write-up" to price — the one clause that gains words (item 4's and contract accretion) is paid twice over inside the same file.

skip-changeset

Applied. The diff publishes nothing from any package: .claude/** agent protocol plus the skills/** catalog, which ships through npx skills add, not through a package release. Measured rather than assumed — none of the six most recent commits touching skills/objectstack-pm-dispatch/SKILL.md carried a .changeset/ file (c985ae958, a9b2be0b0, 2bff79ae3, bcc9189e6, 3d0897459, d250754fd), and 2bff79ae3 is this card's own parent PR with the identical face set.

Gates

Every command ran through scripts/pm/os-verify-lock.sh (slot issue-14146), each exit code captured by redirect before any pipe. The union below was re-derived after the final commit with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands and run at dd9f7d39f — the branch head.

gateverdict line
check:skill-frame-sync✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files · 4 axes: business-need → long-term-soundness → ai-authoring-safety → startup-scope-discipline · binding sentence present in all 4; 4 count mention(s) agree; 40 markdown files scanned for undeclared copies.
check:skill-frame-sync --self-test✓ check-skill-frame-sync self-test: 12 cases pass, plus 5 dispatch-gates declaration cases.
check:skill-frame-freshness✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:skill-frame-freshness --self-test✓ check-skill-frame-freshness self-test: 12 cases pass.
check:pm-skill-ratchet✓ …SKILL.md is 989 lines (ceiling 1005; headroom 16). · ✓ …decision-analysis.md is 54 lines (ceiling 54; headroom 0). · ✓ …os-dev.md is 469 lines (ceiling 469; headroom 0).
check:pm-skill-ratchet --self-test✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g). · self-test 14 cases pass.
check-skills-token-ratchet✓ …skills/objectstack-pm-dispatch/SKILL.md is 9702 tokens (ceiling 9708; headroom 6). · ✓ …36 authored bundle file(s) within their ceilings
check-skills-token-ratchet --self-test✓ check-skills-token-ratchet self-test: 64 cases pass.
@objectstack/spec check:skill-docs✓ skills/README.md · ✓ content/docs/ai/skills-reference.mdx · ✅ Skill docs in sync
check:nul-bytescheck-nul-bytes: OK (scanned 8052 text file(s) — 8052 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes). · self-test 75 assertions

Full derived union at dd9f7d39f20 of 22 green, and the two that are not green are NOT MEASURED, not red:

check-ci-filter-parity · check-cross-package-test-inputs · check-shard-attestation · check-skills-token-ratchet · check:skill-docs · check:agent-model-declared · check:agent-test-spelling · check:corpus-claim-drift · check:cross-package-test-inputs · check:doc-authoring · check:nul-bytes · check:pm-governed-merges · check:pm-governed-prose · check:pm-skill-id-lint · check:pm-skill-ratchet · check:role-word · check:skill-compatibility · check:skill-frame-sync · check:skill-identifier-liveness · check:skill-frame-freshness — all green.

  • check-test-completenessexit 3, NOT MEASURED. Its own text: "That list names this script with NO argument… There is no local log to hand it, so the local reading for this gate is NOT MEASURED. ⛔ It is not a red, and there is nothing here to fix." It consumes a turbo run test log that only CI produces; this diff touches no test.
  • check:doc-formula-expressionsexit 3, PREREQUISITE NOT MET (@objectstack/formula is not built in this worktree). Not a finding. Building it needs the shared verify lock, and two bounded acquisitions timed out at the 540 s budget behind a sibling's run (exit 99, place kept — also NOT MEASURED, never a red). Declared narrowing, measured from the gate's own predicate rather than asserted:fencedBlocks() keeps only fences whose language tag is ts, typescript or tsx, and the text scan is FIELD_RULE_TEXT_RE (visibleWhen|readonlyWhen|requiredWhen). Across all four edited files the gate would parse 0 fenced blocks — the fences present are bash, json, text and bare, none of them a parsed language — 0 of the 17 changed lines fall inside a parsed block, and there are 0FIELD_RULE_TEXT_RE occurrences. The gate has nothing to read in this diff, so its verdict cannot move. CI builds the package and runs it for real.

Beyond the derived union I also self-scanned the four edited files for raw control bytes (grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'): zero hits.

Premise notes


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1


Generated by Claude Code

… encoding
Five in-place, zero-net-line corrections to the escalation decision frame's
four copies and the decision-analysis reference:
1. The class-2/3 live-presentation route in the internal PM skill restated a
stale per-batch cap; it now points at the single home that rules the batch
size, so the two cannot drift apart again.
2. The standing adjudication batch flow had no legal move for a final partial
batch (an exact-size rule plus a drain-the-inbox rule forbade both
presenting short and holding the remainder). The short last batch is now
presented as-is.
3. Every weighting clause hard-coded "the other three", an axis-count minus one
that the frame-sync gate's MENTION_PATTERNS structurally cannot see. All six
sites are now count-free, so no derived count can go stale.
4. Published entry: the shrink-not-grow reading no longer cites an axis
definition that does not state it, and the embedded dev template regains
"and contract accretion" — the term the zero-pull argument turns on.
5. The lead-with-long-term duty is now unconditional in all five encodings;
conflict-scoping is kept only on the cannot-outvote consequence.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/s labels Sep 3, 2026 — with Claude
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Sep 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 33706142983 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (1/6) — 失败步骤: Run this shard's tests

    @objectstack/cli:test: FAIL integration test/run-dev-unbuilt-workspace.e2e.test.ts > the mirror direction: a reader that is never coming back > gives up and exits instead of waiting forever
    ↳ 失败原因: @objectstack/cli:test: AssertionError: expected 'SIGKILL' to be null
    

↳ 失败原因 是判读的关键:超时Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 39 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

Merged via the queue into main with commit db07f69Sep 3, 2026
39 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14146-frame-copy-minors branch September 3, 2026 02:51
This was referenced Sep 3, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude