fix(composer): read a titled composer rule instead of discarding a live composer - #2495
Open
Inthuson wants to merge 7 commits into
Open
fix(composer): read a titled composer rule instead of discarding a live composer#2495Inthuson wants to merge 7 commits into
Inthuson wants to merge 7 commits into
Conversation
…poser
Claude draws its borderless composer between two horizontal `─` rules. When a
terminal-title overlay is burned into the TOP rule, that rule is dashes PLUS
text and fails the dashes-only separator predicate. The separated pair never
opens, so the composer's own BOTTOM rule becomes an unmatched separator sitting
below the `❯` row the scan had already matched. The cursorless staleness rule
reads an unmatched separator below a candidate as proof the candidate is
scrollback, discards the correct match, and returns `unknown` - which defers
away-mode escalation indefinitely and silently. This host paid one 8.5-hour
undelivered-escalation outage for it.
Narrow the consumer rather than loosen the predicate: the dashes-only separator
test also feeds the pi identity conjunction, where being wrong about what closes
a separated composer would promote an unidentified blank region into an injection
target. It is left strictly as-is. Instead the staleness invalidation now spares
a bare agent glyph immediately sandwiched between a rule above (plain or titled)
and the window's only unmatched separator directly below - the composer's own
box. Adjacency on both edges preserves the staleness rule everywhere else,
because a glyph genuinely stranded in scrollback has transcript rows, not its own
box edges, between it and the separator below.
The rule test makes no assumption about where the title sits: mid-rule and flush
at the row's end both read as a rule, because position is the vendor's choice and
has already moved. What it does assume is structural - an overlaid title
overwrites dashes rather than displacing them, so the titled rule keeps its
partner's width. Width is proven by comparing canonical space strings, the same
idiom _fm_composer_titled_bottom_ok uses, because `${#row}` counts characters
under UTF-8 and BYTES under LC_ALL=C and a length test would disagree with itself
between locales.
This is the herdr counterpart of the cmux borderless-composer fix (kunchenguid#2029).
Verification:
- The portable regression builds the shape from its structure rather than from a
captured pane, so it holds on every Claude release. It asserts the divergence
from the strict predicate so the case cannot go vacuously green, covers both
title positions across every capture profile in both locales, and reproduces
the exact failure when only the consumer narrowing is reverted.
- Negative cases pin the boundaries: a titled row of any other width, a glyph
separated from the closing rule by transcript rows, a non-ASCII title, a dead
shell glyph, and a blank row all still read `unknown`; typed text still reads
`pending` where styling proves it.
- Only the cursorless profiles regressed (herdr, zellij, cmux, orca); a tmux
capture reaches its verdict through the cursor row and read `empty` throughout.
- The live guard now scans every claude pane rather than only the focused one,
and reports explicitly when no pane renders a titled rule. Its idle-pane check
derives the expected verdict from that pane's own composer row instead of from
herdr's agent state, so an operator's unsubmitted draft reads `pending` rather
than failing the guard on a working fleet.
- docs/verification/runtime-backends.md records the real-capture counterfactual
and corrects a version-scoped claim: the overlay stopped rendering across two
Claude patch releases with no code change on either side, so a version-scoped
live pass would have rotted into a false claim of coverage.
…erclaiming comments
…solidate column proof
… proof and guard diagnostics
…assifier boundary
4 tasks
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.
Intent
Decide whether firstmate's herdr composer-state fix is still needed after the upstream consolidation refactor 7f05100, then land it properly or retire it with evidence. The investigation found the original defect was actually two independent defects: defect A (a NO-BREAK SPACE after Claude's idle glyph being misread) is genuinely fixed upstream by the Unicode-space normalization, but defect B (a terminal-title overlay burned into the composer's top rule making the cursorless staleness rule discard a correctly matched live composer and return
unknown) survived the consolidation verbatim and is still in the tree. Defect B is dormant rather than fixed: the shape stopped appearing on the live pane only because Claude changed what it renders, not because any code changed. The captain read that report and decided: LAND the defect-B fix.The captain's decision names four required pieces, all of which are in this branch:
Constraints the captain set explicitly, all of which are deliberate and should not be flagged as oversights:
${x#??}-style slicing would re-land issue herdr backend: prompt-glyph matching breaks under LC_ALL=C (bracket expression + ${content#??} operate on bytes) #883. Width is proven by comparing canonical space strings built by character-for-character substitution, the same idiom _fm_composer_titled_bottom_ok and fm_composer_geometry_spaces already use fleet-wide, because${#row}counts characters under UTF-8 and BYTES under LC_ALL=C and a length test would silently disagree with itself between locales (issue Away mode never delivers: Claude's composer renders as ❯+U+00A0, which the classifier reads as pending instead of empty #1988).unknownrule and the strict blank-row posture untouched. Both are asserted in the new test so a future relaxation cannot hide behind it.unknown- a refusal to read, which is the safe direction. That boundary is pinned by a test because the live terminal title on the host that paid for this defect began with U+2733.pending; the earlier version demandedemptythere and failed on the captain's own live draft.Why the failing local test files are not this change's fault: 17 test files in this repo fail on pristine main at 6789876 as well (the teardown family, secondmate handoff, backend dispatch PATH contract, and others). The same 17 files were run against a real clone of pristine main and against this branch; the failure sets are identical except for one pre-existing flake that failed on main and passed here. bin/fm-lint.sh (pinned shellcheck 0.11.0), bin/fm-doc-audience-check.sh, tests/fm-composer-lib.test.sh, and tests/fm-composer-ghost.test.sh are all green on this branch.
Acceptance: the fix lives in bin/fm-composer-lib.sh with a portable regression that fails when only the consumer narrowing is reverted, the dead-shell rule and separator predicate are unchanged, no adapter carries a copy of shape logic, and no-mistakes itself raises the PR. The captain will decide the merge; do not merge it.
What Changed
bin/fm-composer-lib.sh: a new_fm_composer_bare_rule_sandwichexception spares a bare agent-glyph row whose closing separator sits immediately below it and whose row above reads as a composer rule, so a terminal-title overlay burned into Claude's top rule now classifiesemptyinstead ofunknown. The overlaid rule is recognized by a new_fm_composer_rule_rowpredicate — a separate consumer-side predicate that requires the same opening 8-column dash run, accepts a title mid-rule or flush at the row's end, and proves the row's width by comparing canonical space strings rather than measuring length. The dashes-only_fm_composer_pi_separator_rowthat gates pi identity, the dead-shell rule, and the strict blank-row posture are all untouched.fm_composer_column_spacesproof (withFM_COMPOSER_STRUCTURAL_LEADSand a byte-exactFM_COMPOSER_UTF8_CHAR_RE) shared by the new rule predicate,_fm_composer_titled_bottom_ok, andfm_composer_geometry_spaces; it refuses structural box-drawing glyphs, control bytes, and malformed UTF-8 including overlongs, surrogates, and code points above U+10FFFF. The two bordered callers keep their pre-existing ASCII-only content boundary through a new_fm_composer_ascii_only, so only the titled rule reads non-ASCII title text.test_matrix_claude_titled_composer_ruleintests/fm-composer-lib.test.sh, built from the shape rather than a captured pane, pinning divergence from the strict separator, mismatched-width rejection, the U+2733-style non-ASCII title, each refused byte class, edge adjacency, and the unchanged dead-shell/blank-row verdicts, plus both directions of the bordered ASCII-only boundary; extended the env-gated live guard intests/fm-composer-matrix-live-e2e.test.shto scan every live Claude pane, distinguish documented refusals from real regressions, and derive its idle-pane expectation from that pane's own composer row; and replaced the Claude-version-scoped record indocs/verification/runtime-backends.mdwith a version-independent one, with a summary indocs/herdr-backend.md.Risk Assessment
✅ Low: Every acceptance criterion was independently verified against the code - the portable regression reproduces the defect when only the consumer narrowing is reverted,
_fm_composer_pi_separator_rowis byte-identical to base, a base-vs-HEAD sweep across 17 fixtures in both locales moved only the three intended titled-rule verdicts, the restored bordered ASCII boundary is pinned in both directions and demonstrably bites, and the tightened UTF-8 proof refuses every malformed class its comment claims - leaving only two wording-accuracy items inside an env-gated developer guard.Testing
I ran the composer-owner tests and both cursorless adapter suites green (31/33/175/61 ok, matching the branch's own docs record), then proved the change is a real regression fix rather than a passing assertion: reverting only the consumer narrowing makes the new portable test fail on the herdr row while tmux still passes, and reintroducing the earlier attempt's at-end gap fails the flush-at-end fixture. For product-level evidence I drove the real away-mode daemon over the real herdr backend against a real pane rendering Claude's titled composer rule in a throwaway
fm-lab-*session - base reader:unknown,inject deferred, nothing submitted; this branch:empty, escalation typed and submitted; and a human draft in the same composer stillpendingso away mode defers. I also reproduced the docs record's real-capture counterfactual against a live claude pane read-only (163 columns, non-ASCII title, unknown→empty in both locales), showed the base commit's own test file still passes against the new reader, and showed the bordered ASCII-only injection boundary and the plain-vs-titled parity are unchanged. Visual evidence: no browser or screenshot tool exists on this host (no chromium/wkhtmltoimage/PIL, and installing one would breach the worktree boundary), so I rendered the captured pane surface, verdicts and delivery outcome into a self-contained SVG/HTML artifact built verbatim from the two transcripts. The only failures anywhere were the live guard'sclaudeandcodextmux-launch sections hitting each vendor's folder-trust dialog in this gate worktree - pre-existing, environmental, in code this branch does not touch, and documented as expected by the guard itself./tmp/no-mistakes-evidence/01M004MQF4M9EKB5G0JGHCQZGJ/away-mode-titled-rule.svg)Evidence: Same visual as standalone HTML page
Evidence: BEFORE (base 6789876 reader): real away-mode daemon over real herdr, escalation silently deferred
--- what the supervisor pane actually renders (real herdr capture) --- | transcript line: opening the review deck | ──────────── ✳ Review demo ───────────── | ❯ | ──────────────────────────────────────── | bypass permissions on fm_backend_composer_state herdr <pane> -> unknown [..] inject deferred: supervisor composer not confirmed-empty (state=unknown: pending input, dead-shell prompt, or unreadable pane) (x6) --- what the supervisor pane received (submitted lines) --- (nothing submitted) RESULT: escalation NOT delivered - away mode deferred it silently (composer guard read unknown)Evidence: AFTER (this branch): same pane, same daemon - digest delivered; and a human draft in the same composer still defers
fm_backend_composer_state herdr <pane> -> empty --- what the supervisor pane received (submitted lines) --- FIRSTMATE_OP: v1 away-supervisor: Supervisor escalate (1 event(s)): fake-c1.status: done: PR https://example.test/pr/451 (catch-all scan) ... injection RESULT: escalation DELIVERED to the titled-rule composer (composer guard read empty) --- a human types a draft into the same titled-rule composer, no Enter --- | ❯ half-typed thought about the deck fm_backend_composer_state herdr <pane> -> pending RESULT: away mode defers on the draft (state=pending), the human keystrokes are safeEvidence: Real-capture counterfactual: a live claude pane's own 20-row capture with only the top rule overwritten by its real terminal title
pane : w1:p9 (livedefaultHerdr session, read-only) claude : claude 2.1.233.669 (ASBX Claude Code, channel stable) terminal_title : [⠐ Review interview demo and deck prep] (non-ASCII leading glyph) live verdict now: empty (this build draws a CLEAN rule, so the shape is dormant) top rule row 14, composer row 15, closing rule row 16, 163 columns wide ### base 6789876 reader (before the fix) top=asis cols=163 residue=[] verdict=empty (LC_ALL=C: empty) top=at-end cols=163 residue=[⠐ Review interview demo and deck prep] verdict=unknown (LC_ALL=C: unknown) top=embedded cols=163 residue=[⠐ Review interview demo and deck prep] verdict=unknown (LC_ALL=C: unknown) ### this branch's reader (after the fix) top=asis cols=163 residue=[] verdict=empty (LC_ALL=C: empty) top=at-end cols=163 residue=[⠐ Review interview demo and deck prep] verdict=empty (LC_ALL=C: empty) top=embedded cols=163 residue=[⠐ Review interview demo and deck prep] verdict=empty (LC_ALL=C: empty)Evidence: Regression proof: revert ONLY the consumer narrowing -> the new portable test fails
not ok - claude titled-rule idle on herdr: expected empty, got 'unknown' (the tmux row above it still passes, matching the claim that only the cursorless profiles regressed)Evidence: At-end gap proof: reintroduce the earlier attempt's "row must end in a dash" rule -> the flush-at-end fixture fails
not ok - titled rule '─────────────────────────────Review demo' must read as a rule at its partner's widthEvidence: No pinned verdict moved: the BASE commit's own composer test file run against this branch's reader (30 ok, 0 not ok)
Evidence: Bordered ASCII-only boundary unmoved: base vs branch accept/refuse differential for fm_composer_geometry_spaces and _fm_composer_titled_bottom_ok (0 diffs, both locales)
Evidence: Parity probe: a titled rule earns exactly what a plain rule already earned, never more
- idle composer, footer below the closing rule (the real Claude shape) herdr base: plain=empty titled=unknown | branch: plain=empty titled=empty titled == plain cmux/orca base: plain=empty titled=unknown | branch: plain=empty titled=empty titled == plain - a dead SHELL glyph in the same sandwich herdr base: plain=unknown titled=unknown | branch: plain=unknown titled=unknown titled == plain - a BLANK row in the same sandwich cmux/orca base: plain=unknown titled=unknown | branch: plain=unknown titled=unknown titled == plainEvidence: Env-gated live guard run (FM_COMPOSER_MATRIX_LIVE=1): new herdr section read 5 live idle claude panes; reports the titled shape absent on this build rather than passing vacuously
Evidence: Evidence index (what each file proves, host/version context)
Pipeline
Updates from git push no-mistakes
... (6 earlier update rounds omitted to keep the PR body within GitHub's 65536-char limit; full history is in the run log.)
🔧 Fix: fail exact-width live mismatches; narrow idle-pane read race
2 issues (1 warning, 1 info) still open:
tests/fm-composer-matrix-live-e2e.test.sh:550- The new race-skip branch discards the verdict wholesale, so it excuses the two verdicts the same commit promises always fail.elif [ "$hd_accept" = empty ] && ! hd_composer_row_blank "default:$hd_pane"is reached for ANY unmet blank expectation, includinghd_verdict=unknownand an unreadable (empty) verdict. That directly contradicts this loop's own comment at lines 493-496 ("What is never accepted, in both cases, isunknownor an unreadable verdict on a composer this loop can see - the defect that deferred every away-mode escalation, and the whole reason this guard exists") and the sentence this change added to docs/verification/runtime-backends.md:272 ("unknownand an unreadable verdict fail in both cases, which is the behaviour the guard exists to catch"). Concrete sequence: an idle pane's composer row is blank in the first capture, sohd_accept='empty'; the classifier returnsunknownfor a reason no documented boundary explains (I verifiedhd_rule_refusal_reasoncorrectly returns empty for an ASCII-titled width mismatch and for a structural glyph, sohd_documented_unknowndeclines and the first elif is false); the operator types a character beforehd_composer_row_blankre-reads, so it returns 1, and the pane is noted as a race withFAILEDuntouched. The verdictunknownwas never something a keystroke can legitimately produce - typing on a herdr styled capture yieldspending- so the race does not explain it and it should still fail. A second, narrower path reaches the same skip with no race at all:hd_composer_row_blankreturns 1 whenfm_backend_herdr_capturefails or when the re-read finds no agent glyph row (lines 286 and 299), so a transient capture hiccup alone downgrades a liveunknownto a skip. Mitigation that keeps this at warning rather than error: the titled loop above scans every claude pane and fails independently on an ASCII-titled width mismatch, so the headline shape still tripsFAILEDthrough that path. Minimal fix that stays inside the authorized posture: keep the race skip only forpendingandpending-unproven(the verdicts a keystroke can legitimately produce), and continue to FAIL onunknownor an unreadable verdict regardless of what the re-read shows; and distinguish "re-read unreadable" from "row is no longer blank" so the note's reason is the one it claims.bin/fm-composer-lib.sh:150- The comment onFM_COMPOSER_STRUCTURAL_LEADSclaims "This is a superset of every glyph fm_composer_row_has_edge treats as structural", but that is false for the two ASCII edges.fm_composer_row_has_edge(line 912) treats|and+as structural, and neither is in U+2500..U+25FF, sofm_composer_column_spacespass 1 does not reject them - they fall through to pass 3 and are credited with one column each. The Unicode half of the claim checks out: I verified the four lead pairs E2 94/95/96/97 cover exactly U+2500..U+25FF, which contains every box-drawing (│┃║╭╮┌┐╔╗┏┓╰╯└┘╚╝┗┛─━═) and block (▀▄▁▔) glyph in that predicate, and that E2 can never appear as a UTF-8 continuation byte so the two-byte prefix test cannot false-positive. There is no behaviour defect: crediting an ASCII|in a title with one column is correct (it occupies one), and base's ASCII pass did exactly the same, so nothing moved. The problem is only that a load-bearing safety comment in the file whose comments the last three rounds were spent correcting now overstates the rejection's reach, which is how a future maintainer concludes an ASCII-bordered container's edge is caught here when it is not. Narrow the sentence to what the set proves: every box-drawing, block, and geometric glyph in U+2500..U+25FF, which is every NON-ASCII glyph that predicate treats as structural.🔧 Fix: gate live race skip on draft verdicts; narrow structural claim
2 infos still open:
tests/fm-composer-matrix-live-e2e.test.sh:510- The idle loop's comment (lines 509-512) and docs/verification/runtime-backends.md:279 both claim without qualification thatunknownand an unreadable verdict always fail ("What is never accepted, in both cases..." / "fail in both cases"). The elif at lines 562-565 does the opposite: whenhd_documented_unknownsupplies a reason, the pane is noted and FAILED is untouched. I confirmed that path is reachable -hd_documented_unknownreturns a reason for a non-ASCII-title width mismatch, a title preceding the opening dash run, and the single-row adjacency limit. Round 5's new sentence at docs line 274 is correctly scoped to the race allowance; line 279 and this comment are the unscoped copies. Qualify both to "unknownwith no documented boundary reason".tests/fm-composer-matrix-live-e2e.test.sh:607-hd_failedis incremented only by the titled loop's two failure paths (lines 457, 469); the idle loop's failure paths at 577 and 586 set FAILED but not hd_failed. Concrete path: Claude restyles so the closing rule also carries text, the titled loop skips the pane at line 429 without counting it, the idle loop fails it withunknownand no documented reason, and the elif at 606 still prints "the titled-rule regression was NOT exercised live here" in the same run that failed on that shape. This is the residue of the round-3 finding that round 4 fixed only for the titled loop. The run still exits non-zero via line 617, so the impact is a misleading line rather than a false pass. Either increment the same counter on the idle loop's failure paths or gate the "NOT exercised" wording on FAILED -eq 0.tests/fm-composer-matrix-live-e2e.test.sh:123-FM_COMPOSER_MATRIX_LIVE=1 tests/fm-composer-matrix-live-e2e.test.shexits non-zero here, but both failures are in sections this branch does not touch: launchingclaudeandcodexin the guard's isolated tmux server with the gate worktree as cwd opens each vendor's first-launch folder-trust dialog, which the strict classifier correctly refuses to call a composer (last verdict: pending/unknown, with the trust prompt visible in the guard's own pane dump). The guard's header documents a trust dialog as the expected failure in an untrusted cwd, and the branch's own docs record already lists codex as unverified for exactly this reason. Not fixable from inside the worktree - it would mean writing trust state into vendor config outside it. The new herdr section that this change adds passed: 5 live idle claude panes classifiedemptyagainst their own composer rows, and the absent titled rule was reported as absent rather than as a pass.tests/fm-composer-matrix-live-e2e.test.sh:418- One branch of the new live idle-pane check could not be exercised live: the guard scans the operator'sdefaultHerdr session, and its draft-tolerant direction (acceptingpendingfor an idle pane whose operator typed and did not submit) only fires when a live pane carries an unsubmitted draft. Forcing that would mean typing into the captain's own panes, which is not a safe validation action, so all 5 live panes exercised the blank-row direction. I covered the behaviour that branch depends on instead on a real pane in an isolatedfm-lab-*session: a human draft in the titled-rule composer classifiespending, so away mode defers rather than typing over the keystrokes (see away-mode-after-fix.txt).tests/fm-composer-lib.test.sh(31 ok, includes the newtest_matrix_claude_titled_composer_rule)tests/fm-composer-ghost.test.sh(33 ok)tests/fm-backend-herdr.test.sh(175 ok) andtests/fm-backend-cmux.test.sh(61 ok) - the cursorless adapters that consume the classifierCounterfactual: reverted ONLY the_fm_composer_bare_rule_sandwichsparing in_fm_composer_select_cursorless, re-rantests/fm-composer-lib.test.sh->not ok - claude titled-rule idle on herdr: expected empty, got 'unknown'; source restored and worktree verified cleanCounterfactual: reintroduced the earlier attempt's at-end gap (case "$row" in *─) ;; *) return 1) in_fm_composer_rule_row->not ok - titled rule '─…─Review demo' must read as a rule at its partner's width; source restoredNo-regression differential: ran the base commit's owntests/fm-composer-lib.test.shagainst this branch'sbin/fm-composer-lib.sh(30 ok, 0 not ok)Real-capture counterfactual:bash real-capture-counterfactual.sh- read-onlypane list+pane captureon the livedefaultHerdr session, rebuilt pane w1:p9's own capture with only the top rule's dashes overwritten by its real terminal title (at-end and embedded), classified under base and branch readers through the herdr ANSI capability descriptor inC.UTF-8andLC_ALL=CEnd-to-end away mode:bash away-mode-titled-rule-demo.sh- isolatedfm-lab-titledrule-*Herdr session viabin/fm-herdr-lab.sh, a pane rendering Claude's titled composer rule, realbin/fm-supervise-daemon.shwithFM_SUPERVISOR_BACKEND=herdr, a crewmate status file to trigger an escalation; run once with the branch reader and once with the base reader swapped in (then restored)Real-pane draft check: typed an unsubmitted draft into the same titled-rule composer and readfm_backend_herdr_composer_state->pending(away mode defers)Preserved bordered boundary:bash bordered-boundary-differential.sh- base vs branch accept/refuse forfm_composer_geometry_spacesand_fm_composer_titled_bottom_okacross ASCII, tab, NBSP, empty, prompt-glyph, accented, Cyrillic, CJK, box-drawing and ESC inputs, both locales (0 diffs)Parity probe:bash parity-plain-vs-titled.sh- every fixture classified with a plain top rule and with the same row titled, under base and branch, on the herdr and cmux/orca capability profilesFM_COMPOSER_MATRIX_LIVE=1 tests/fm-composer-matrix-live-e2e.test.sh(env-gated live guard)Cleanup verification:git status --porcelainempty,herdr session listshows onlydefault, no leftover lab tripwires or temp dirsdocs/verification/runtime-backends.md:244- Intent-vs-code divergence I documented as-landed rather than resolved: the intent lists "ASCII-printable-only title text" as a deliberate constraint and says a non-ASCII title glyph must leave the verdictunknown, but review commit a00ae2e widened_fm_composer_rule_rowto read titles of any well-formed single-width script, so the U+2733 title from the outage host now readsemptyandtests/fm-composer-lib.test.shpins that. The verification record and code comments now assert the wider boundary as the guarantee. If the ASCII-only constraint is the binding one, the code, its tests, and this record all have to move together - that is a behavior change outside this documentation phase.docs/verification/runtime-backends.md:264- Out-of-scope consolidation worth a follow-up: the repository has no in-tree owner for its set of pre-existing failing test files. This record leaned on "the pre-existing failures recorded for this repository", which resolves to nothing tracked (I reduced it to the durable fact instead: the orca/zellij teardown-family failure is byte-identical with the composer narrowing reverted). Every branch that touches these suites re-argues the same point in its own prose. A single maintainer-verification record of the known-failing set, refreshed by one command, would give those sentences an owner to point at.✅ **Push** - passed
✅ No issues found.