Repository navigation
fix(pm-dispatch): give the decision-facets marker a sanitizer-safe spelling - #14264
Merged
Merged
Conversation
…elling The 四棱 block's machine-findable marker was prescribed in exactly one spelling — a raw HTML comment — and that spelling is not readable through the channel the seats verify and extract with. Measured 2026-09-01 on a live specimen, both channels on the same comment in the same minute: the comment's bytes ARE in GitHub's storage (the page's embedded JSON payload returns the marker line intact), and the MCP read path returns that line with its text removed and the newline kept. A seat performing the prescribed read-back therefore sees absence and cannot tell it from a strip — which is what happened, and produced a repair comment for a marker that had never been lost. The remedy is the one the sibling os-dev-report marker has carried all along and that was never carried over: two equivalent spellings, one of them ordinary visible text, plus the clause that absence of the HTML form is never evidence of absence of the thing. The plain-text form is the same literal token, so literal-text grep extraction is unchanged. Line-neutral by construction: the prescription is rewritten in place and the file stays at 54 of 54, headroom 0, measured with the gate's own wrapLine rather than counted by hand. The now-obsolete 转义拼写写入 qualifier is dropped — the measurement shows escaping was never what decided survival. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Whev4BkZ4BRcgiXYo4muWP
This was referenced Sep 1, 2026
os-zhuang
approved these changes
Sep 2, 2026
os-zhuang
approved these changes
Sep 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #14237
The 四棱 block's machine-findable marker was prescribed in exactly ONE spelling, and that spelling is the one the seats cannot read back.
CMT-OPEN os-decision-facets CMT-CLOSE, because writing the real angle-bracket shape into a GitHub body is exactly the hazard this PR is about — the body sanitizer would eat it and this description would misreport its own subject.The broken prescription — before
One spelling, shown raw. An author copying the canonical example produces a card whose marker no seat can find, and the four-character 转义拼写写入 qualifier is attached to an example that is itself unescaped — so the failure mode is following the example.
After
Three things land, mirroring what the sibling
os-dev-reportmarker has carried all along and that was never carried across:The now-obsolete 转义拼写写入 qualifier is dropped, because the measurement below shows escaping was never what decided survival.
Measured 2026-09-01 — the mechanism in the card is not what happens
Both channels, same specimen comment (
5496301851on #14103 — that card is referenced for evidence only and is not addressed by this PR; it remains open), same minute:**四棱**headingissue_read get_comments投不翻它。then two blank lines then**四棱**⇒ the bytes survived the write and are in GitHub's storage. The read path drops them. So the filed diagnosis ("the write channel strips it") is falsified, and the defect is worse than filed rather than better: a seat that performs the mandated read-back sees absence and cannot distinguish it from a real strip. That is not hypothetical — it produced a repair comment for a marker that had never been lost. The absence clause is the rule that makes that misreading impossible in either direction, which is why it lands whichever way the byte-level story goes.
Reproduced on a second card: #12911's marker was written in the entity-escaped spelling, is ordinary literal text, and survives both channels intact.
Line budget — line-neutral, measured with the gate's own counter
The file is ratchet-pinned at 54 lines, headroom 0. This is a correction of a measured-broken prescription, and it fits by rewriting the prescription in place:
check-skill-line-ratchet: .claude/skills/pm-dispatch/references/decision-analysis.md is 54 lines (ceiling 54; headroom 0).0 bytes (pin 0; headroom 0)— unchanged, no table added.wrapLine. 809 is the measured ceiling for this paragraph shape: 812 and 815-byte variants both spill to 8 lines, so the wording was chosen against the gate's own wrapper rather than by eye.scripts/pm/check-skill-line-ratchet.mjs(held by another in-flight PR). No ceiling was raised.Frame-sync pre-check — cleared, and checked before the first edit
check:skill-frame-synccompares four declared COPIES across.claude/skills/pm-dispatch/SKILL.md,.claude/agents/os-dev.mdand two entries inskills/objectstack-pm-dispatch/SKILL.md.references/decision-analysis.mdis not a declared copy; it is reached only by the anti-dormancy sweep, which reds an undeclared file matching a frame FINGERPRINT. It matched none before this change and matches none after. The marker line does not sit inside a frame-enforced isomorphic block, so this is not a frame-copy change.Gates — union re-derived and re-run on the final commit
fc8caa2anode scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(paths derived by the script from the merge base, not hand-built) named 7 families before and after the commit — no family appeared or vanished. All 7 green, each exit captured by redirect before any pipe:check:pm-skill-ratchetcheck:pm-skill-id-lint23 file(s) cleancheck:skill-frame-sync4 copies ... structurally isomorphic across 3 filescheck:doc-authoringcheck:agent-test-spellingcheck:pm-governed-mergescheck:doc-formula-expressionscheck:doc-formula-expressionsfirst returned exit 3 — PREREQUISITE NOT MET, twice, naming@objectstack/formulaand then@objectstack/lintas unbuilt. Recorded here because it is NOT a finding and was NOT read as one: the gate's own text says nothing was measured. It was re-run to a real 0 only after both packages were built.No control characters:
grep -naPover the changed file returns nothing beyond the gate.Governance
Governed face (
.claude/**) ⇒ draft, human merge. ⛔ Auto-merge is not armed and this seat does not flip it ready or enqueue it.skip-changeset: the diff is.claude/**only and publishes nothing from any package.Generated by Claude Code
Generated by Claude Code