docs: give every fact one owning page and cut what restates it #289

Merged
natsukium merged 100 commits from docs/role-cleanup into main 2026-09-18 11:41:54 +09:00
Owner

Tree-wide pass on docs/ for role and redundancy: each fact now has one owning page (reference owns facts, explanation owns decisions with their rejected alternatives and revisit triggers), and text that restated another page, narrated history, opened on its audience, or trailed off into link lists is gone. Closes #242.

What changed

  • Protocols (#242): explanation/protocols/landscape.md is now "Protocol admission decisions" (263 → 80 lines). The support-matrix legend is the one status vocabulary (⚠️ = consumed without effect, 🚫 = reaches no implementation), with rows added for every verdict the landscape tables alone carried (?12, OSC 6, XTSETTCAP, legacy DCS = 1 s, 8-bit C1, SS2/SS3, PM/SOS, HVP, IND/NEL, VT500 page memory, NRCS, DECDLD, an APC table, mintty/mosh images). The OSC 66 key table moved to its reference page.
  • IPC / control surfaces: the design record stops re-telling the wire spec; the wire reference stops arguing; the CLI contract has one home in reference/cli.md; the registry caps have a row in "Semantic limits"; the Region Reply bullet now states the trim the daemon applies (the refusal it described was never implemented).
  • Architecture / data model: the daemon-process lifecycle lives in overview.md; the pipe/run action design lives in input.md; the session-spawn environment design moved from the security model into session-lifecycle.md "Creation"; the transient unit's properties and the KillUserProcesses logout condition are stated in reference/cli.md "Auto-spawning".
  • Foundation: design.md owns the boundary argument once; vision.md, comparison.md, feature-baseline.md and non-goals.md stop re-deriving it; input.md and security-model.md each own one half of the link-preview decision.
  • User-facing: the three "older build left a daemon elsewhere" blocks are gone (CHANGELOG already records the move); how-tos keep their steps and cite cli.md for verb facts; README points at the pages instead of replaying them.
  • Engineering: implementation.md keeps its decisions and drops the sourced catalog; the publication gate has one owner; mutation testing is documented; AGENTS.md and CONTRIBUTING.md cite Cargo.toml for MSRV/edition/lint values instead of restating them.
  • Skills: doc-cascade gains "One owner, outside docs/ too" (with the AGENTS.md guardrail and README summary exceptions) and the page-mechanics rules this pass established (subject opener, no description:, no pointer-only tails); section-number citations became heading citations; add-escape-sequence and implement-feature send the verdict lookup to the support matrix.
  • Citations: every intra-docs #anchor and every by-name page "Section" citation in docs/ and crates/ comments was checked against the target headings; 80 stale by-name citations (76 pre-dating this branch) and 3 pre-existing broken links are fixed.

Verification

just check green; just prose-check origin/main...HEAD 0 hits; just skill-check; cargo nextest run -p felis-workspace-tests (doc index + internal links) green; a fragment-aware anchor checker reports 0 broken links; five independent review rounds (pi sol ×5, luna ×2; the last verdict PASS) with every blocker resolved from the Rust source, plus a systematic pass over the 175 requirement rows that cite a changed page (27 citations retargeted, 9 clauses restored). Two daemon/bridge timing tests flaked once each under a saturated host while the CI runner compiled another job; both pass 3/3 in isolation and the crate diff is comments only.

Not in this PR

  • CHANGELOG.md's released [0.1.0] section says a pipe chord over an oversized scrollback "fails with a message naming the size"; the daemon has trimmed instead since 2026-09-04. Editing a released section is a maintainer call.
  • The payload-suppression flag noted in explanation/architecture/ipc.md "Open extensibility considerations" has no issue yet; a ready body is in the session notes.
Tree-wide pass on `docs/` for role and redundancy: each fact now has one owning page (reference owns facts, explanation owns decisions with their rejected alternatives and revisit triggers), and text that restated another page, narrated history, opened on its audience, or trailed off into link lists is gone. Closes #242. ## What changed - **Protocols (#242)**: `explanation/protocols/landscape.md` is now "Protocol admission decisions" (263 → 80 lines). The support-matrix legend is the one status vocabulary (⚠️ = consumed without effect, 🚫 = reaches no implementation), with rows added for every verdict the landscape tables alone carried (`?12`, `OSC 6`, XTSETTCAP, legacy `DCS = 1 s`, 8-bit C1, SS2/SS3, PM/SOS, HVP, IND/NEL, VT500 page memory, NRCS, DECDLD, an APC table, mintty/mosh images). The OSC 66 key table moved to its reference page. - **IPC / control surfaces**: the design record stops re-telling the wire spec; the wire reference stops arguing; the CLI contract has one home in `reference/cli.md`; the registry caps have a row in "Semantic limits"; the Region `Reply` bullet now states the trim the daemon applies (the refusal it described was never implemented). - **Architecture / data model**: the daemon-process lifecycle lives in `overview.md`; the pipe/run action design lives in `input.md`; the session-spawn environment design moved from the security model into `session-lifecycle.md` "Creation"; the transient unit's properties and the `KillUserProcesses` logout condition are stated in `reference/cli.md` "Auto-spawning". - **Foundation**: `design.md` owns the boundary argument once; `vision.md`, `comparison.md`, `feature-baseline.md` and `non-goals.md` stop re-deriving it; `input.md` and `security-model.md` each own one half of the link-preview decision. - **User-facing**: the three "older build left a daemon elsewhere" blocks are gone (CHANGELOG already records the move); how-tos keep their steps and cite `cli.md` for verb facts; README points at the pages instead of replaying them. - **Engineering**: `implementation.md` keeps its decisions and drops the sourced catalog; the publication gate has one owner; mutation testing is documented; AGENTS.md and CONTRIBUTING.md cite `Cargo.toml` for MSRV/edition/lint values instead of restating them. - **Skills**: doc-cascade gains "One owner, outside `docs/` too" (with the AGENTS.md guardrail and README summary exceptions) and the page-mechanics rules this pass established (subject opener, no `description:`, no pointer-only tails); section-number citations became heading citations; `add-escape-sequence` and `implement-feature` send the verdict lookup to the support matrix. - **Citations**: every intra-docs `#anchor` and every by-name `page "Section"` citation in `docs/` and `crates/` comments was checked against the target headings; 80 stale by-name citations (76 pre-dating this branch) and 3 pre-existing broken links are fixed. ## Verification `just check` green; `just prose-check origin/main...HEAD` 0 hits; `just skill-check`; `cargo nextest run -p felis-workspace-tests` (doc index + internal links) green; a fragment-aware anchor checker reports 0 broken links; five independent review rounds (pi sol ×5, luna ×2; the last verdict PASS) with every blocker resolved from the Rust source, plus a systematic pass over the 175 requirement rows that cite a changed page (27 citations retargeted, 9 clauses restored). Two daemon/bridge timing tests flaked once each under a saturated host while the CI runner compiled another job; both pass 3/3 in isolation and the crate diff is comments only. ## Not in this PR - `CHANGELOG.md`'s released `[0.1.0]` section says a `pipe` chord over an oversized scrollback "fails with a message naming the size"; the daemon has trimmed instead since 2026-09-04. Editing a released section is a maintainer call. - The payload-suppression flag noted in `explanation/architecture/ipc.md` "Open extensibility considerations" has no issue yet; a ready body is in the session notes.
Three legends described one axis: the matrix's symbols, the notification
reference's /⚠️/🚫, and the landscape's Adopt/Tolerate/Reject. A reader
comparing two pages had to translate, and a status flip had to be spelled
in two vocabularies to stay consistent.

The matrix legend now defines ⚠️ as the tolerated set (consumed without
effect) and cites the admission rule, so it covers what "Tolerate" named;
the dead  entry goes. The notification conformance table defers to that
legend and marks an absent surface with a dash instead of inventing .
The matrix also loses two prose passages that restated the tables beside
them, and keeps the one policy sentence they carried in the legend.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
`?12`, `OSC 6`, XTSETTCAP, the legacy `DCS = 1 s` synchronized-output
form, the 8-bit C1 rejection, and the SS2/SS3 and PM/SOS framing had no
status row in any reference page: a producer that emits one had to read
an explanation page to learn the answer, and the landscape's tables were
the only record. Each is now a matrix row, so the landscape's inventory
can go without losing a fact.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Four stance tables gave a per-family verdict the support matrix already
gave per sequence, in a second vocabulary, so a status flip meant two
edits in two legends and most rows carried no argument at all. The
"Modern protocols" section then stated the same verdicts a third time and
compressed the notification, graphics and input explanation pages a
fourth. What is left is what no other page holds: the admission rule for
a tolerated input, the `?2048`-over-window-geometry record, and the
handful of families whose status rests on an argument.

The page now opens by naming the matrix as the owner of the verdict, so a
reader looking for status no longer has two places to look, and its title
names what remains.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Ownership was inverted: the support matrix carried the metadata keys'
ranges, defaults and purposes, which are wire facts rather than status,
while the protocol reference pointed back at the matrix and repeated the
key list in prose. A reader of the wire format had to leave the page that
specifies it, and a second prose list restated the behavior rows.

The matrix keeps a status row for the key set and links the table.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Seven pages opened with the same "A reference for X, Y, and Z specifying
…" frame. The quadrant already declares the reader, so the role list was
filler between the title and the first fact. Five of them then closed
with a "## Status" section repeating the support-matrix link their own
first paragraph gives, which buys a table-of-contents entry and nothing
else.

The compliance reference also stops defending its "Consumed without
effect" table: why a tolerated reply is normative is the landscape's
argument, and the row it cites already carries it.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Four pages carried sections that state a status instead of arguing one.
The compliance omissions mixed real records (page geometry, colorimetric
specs, DECCOLM, tab stops) with one-word rows the matrix already carries;
kitty-graphics closed on a "Deviations" list whose three bullets are the
reference's own facts; text sizing spelled out two interactions the
reader derives from the handle living in the cell, and re-stated the
legacy sizing form a fourth time; notifications ended on a boundary list
restating its own conclusions and a link tail the body already gives.

A reader who wants status has one place to look, and the argument pages
are only argument.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The fenced arithmetic and the table below it carried the same four
numbers, so a count could be raised in one and left stale in the other.
The rejected-cluster bullets also re-argued rejections they cite an owner
for; a reader who wants the reason follows the link, and the accounting
page keeps the case names.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The how-to ran the whole `felis-pty` package while the harness reference
names the `esctest_smoke` target, so following the procedure paid for the
vttest suite as well and the two pages disagreed on the recipe. It also
defined `ESCTEST_BIN` and `ESCTEST_INCLUDE` in full beside the reference
that owns the harness configuration; the worked invocation stays, because
that is what a how-to is for.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The escape-sequence skill sent a contributor to the landscape for a
per-family adopt/reject verdict and told the doc cascade to update a
"stance line". Neither exists now: the matrix owns the verdict per
sequence, and the landscape holds only the arguments and their revisit
triggers, so a contributor following the old order would look for a table
that is gone and skip the page that answers "why".

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The comment pointed at the protocol landscape, which no longer carries a
per-sequence table: the `CSI 14 t` stub reply is the compliance
reference's "Consumed without effect" row.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The landscape page no longer opens with a per-family table, so a bare
file citation lands the reader on a rewritten page; the in-band ordering
argument is its "CSI" section.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The uid-derived endpoint move is recorded in CHANGELOG.md, so cli.md,
update-felis.md and attach-over-ssh.md each carried the same old-way /
new-way migration story, which doc-cascade keeps out of the docs tree.
update-felis.md keeps one present-tense sentence for the symptom a user
upgrading today can still meet, and its remote section drains over
--host like every other remote operation on the page.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Four how-to pages restated flag vocabularies, output shapes and exit
codes that cli.md owns, and two of them owned facts cli.md lacked: the
window `switch` picks on a mirrored session, and the tail-only
transmission `--lines` buys under `--source scrollback`. A reader
looking up a flag now finds it in one place, and each task page carries
the steps plus a link.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The SSH page's operational notes and the update page's restart section
re-derived carrier resolution, keymap action environment, the systemd
stop refusal and the live-reload list, each of which has a reference
owner. A task page that states them a second time is a place they can
go stale.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
install.md and enable-notifications.md both enabled the home-manager
notification service and listed its options, and install.md and
fix-terminfo-problems.md both carried the `tic` invocation. Each pair
pointed at the other for the rest, so a reader could not tell which
page to trust when they drift.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Two how-to pages closed a code block by describing what the reader had
just done, and the tmux page stated the no-multiplexer boundary three
times in one screen. Neither instructs, and a reader scanning for the
next step has to read both to find that out.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
A dozen because-clauses argued the endpoint derivation, the cold-socket
rule, the doctor sibling probe and the retarget landing inside the CLI
reference, where a reader is looking up what a verb does. Each argument
already has an owner (ipc.md, security-model.md, control-surfaces.md),
so the page keeps the behavior and cites them.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
"The scripting contract" re-summarized the envelope, the attachment id
spelling and the stream terminal after the sections that define them,
and every verb table spelled out the exit codes the Exit codes rule
already derives. The window-exit order also read as one 90-word comma
chain with a one-row table under it. What is left states each fact
once, where a reader looking it up will be.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Twelve pages ended in a See also / Guides / Cross-references list that
re-derived docs/README.md, mostly with links the body had already made;
the two reference pages opened by naming their audience and then
listing their own headings. The index is docs/README.md and the site
has a sidebar, so only the symptom-sibling pair between the two fix-*
guides keeps a tail, and the links a body lacked moved into it.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
A tutorial carries no theory and no design rationale: the paste-aware
shell aside taught a concept the step does not need, the --wait aside
recorded where that flag sits, and both pages closed with a one-line
moral of the recap bullet directly above it.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Quick start ran the whole of the first-session tutorial and repeated
install.md's commands byte for byte, and each "Working with your tools"
subsection gave a command, restated the linked page, then linked it. A
reader who wants the walkthrough should land on the page that is
maintained as the walkthrough.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
"The rule above" now sits several sections below "Exit codes", and the
remote-update step broke its own numbered list with a fenced block.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Half the page was a per-dependency catalog: a `Source:` line, a
block-quoted upstream README, and no decision inside. Those sections
re-tell facts their reference twin owns (the IME backend table, the
shaping cache shape, the fuzz acceptance bar, the protocol support
matrix) or document a crate the reader can read upstream (`tracing`'s
macro list, `vte`'s README, the Williams action set), so every upstream
edit lands here and nothing in the argument consumes it. The
thiserror/anyhow split is not a decision anyone re-proposes; what is
load-bearing about it is normative, so it moves to the workspace
reference beside the pins it constrains.

A reader now finds one thing on this page: a choice, the alternative it
rejects, and the trigger that reopens it.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The rule that "supported" means a runtime gate passed on that revision
was argued three times: once in implementation.md, once more in the
testing explanation as "why a tag rebuilds", and a third time inside the
workspace reference. Three copies of one argument across two quadrants
means a change to the policy has to find all three, and the reference
page was carrying rationale it is not supposed to hold.

The testing explanation owns it now, as one argument with its three
consequences, since the gate is a claim about evidence the test layers
produce. implementation.md and workspace.md cite it and keep only the
facts a reader looks up: which job publishes what, and from which file.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
"Why the layers exist" walked the reference layer table row by row, and
the benchmark section opened by saying the mechanics were the reference
twin's job and then stated them anyway, down to a memory-ledger
paragraph duplicated near verbatim across the two pages. A reader who
follows the pointer gets the same sentences twice, and a harness change
has to be found in two files.

Each bullet now keeps only the shape decision, the alternative it
rejects and its revisit trigger. The Kani packaging record moves to the
file it governs, per the rule that toolchain decisions live with their
config; the deferral lists go with it, because what has not been decided
belongs in an issue, not in the argument quadrant.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
cargo-mutants has shipped recipes, a committed `.cargo/mutants.toml` and
a triage procedure, but it existed only inside a skill: the reference
layer table omitted it and the strategy page still listed it as an open
decision. A contributor reading the docs to find out what verifies felis
was told something false, and a skill is supposed to hold the procedure,
not the layer's existence and scope.

The reference page now carries the row, the recipes and the scoping; the
strategy page carries the one decision that explains the shape (a
meta-tool on a perpendicular axis, a worklist and not a gate).

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Both pages opened by telling the reader who they are for instead of what
they cover, and the workspace page argued where it is only supposed to
state: why a break burns no version number, why an abbreviated revision
is not a parse target, whose job a dirty release is. The arguments have
owners elsewhere, so the facts stay and the because-clauses go.

The handshake-helper line pointed at "the decision record above", which
is on another page entirely; it now names it. The hand-maintained source
list at the foot of the testing reference is deleted: every URL in it is
already cited where it is used, so the list was a second place for a
moved link to go stale.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
AGENTS.md names CONTRIBUTING.md, workspace.md and Cargo.toml as the
contract and then restates each of them, and three of its four workflow
bullets are verbatim copies of CONTRIBUTING's. One copy had already
drifted: the four-command CI list matched no workflow, since the real
pipeline runs `nix flake check`, nextest, a wasm32 clippy pass,
proto-compat and a headless smoke. The MSRV and edition literals had the
same problem from the other side, because a version bump had to edit two
prose files that both disclaim owning the number.

Each section keeps its pointer and drops the copy, so a rule has one
place to change: the config for values, CONTRIBUTING for the human
workflow, reference/testing.md for what CI runs. The quadrant paraphrase
in the reading order goes the same way; docs/README.md defines it.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Every cross-file citation into doc-cascade named the wrong section:
"Default to no record" was cited as §1 from AGENTS.md and
implement-feature when it is §3, the history rule as §1 when it is §4,
the sweep as §3 when it is §6. That is what a section number does when a
skill grows a section, so the citations now name headings.

The gap those citations sat in was larger: nothing said who owns a fact
stated both in docs/ and at the repo root, which is how the root files
and the skills grew copies that drift. doc-cascade gets the rule, plus
the two page conventions this docs pass settled (a reference page opens
with its subject; a page ends where its content ends), and doc-prose
gets the matching line about hand-maintained link indexes.

implement-feature's second expansion of `just check` had already fallen
out of step with the justfile, so it points at CONTRIBUTING's instead,
and test-strategy points at the Kani packaging record's new home.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Both came out of this pass's compression, and a sentence that stacks a
colon on a colon makes the reader hold the first clause while parsing
the second.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
vision.md and feature-baseline.md both re-derived the layout-to-the-WM,
replay, and heuristics arguments they also linked to, so a change to any
of them had to be made on three pages and a reader met the same reasoning
twice. Both now keep the conclusion plus the link, and the in-client
performance overlay moves to non-goals.md, which is where an enumerated
scope rejection belongs.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Four of the seven entries re-derived "felis has no multiplexer because
layout belongs to the WM", which is principles.md's conclusion, not a
per-peer one; stating it once in the intro leaves each entry carrying
only what that peer's decision changes. The sketches lose the inventory
lines no following paragraph consumes, and the trailing cross-reference
list goes: its links are already inline, except the replay one, which
moves into the tmux entry where replay is argued.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Five of input.md's sections carried no argument: a scope rejection that
belongs in the enumerated list, a per-platform IME inventory, clipboard
surface definitions and per-compositor caveats, and wire forms
key-encoding.md already specifies. An explanation page that restates
reference facts makes every behavior change a two-file edit, and it hides
the decisions that are the page's job. The window-management refusal
moves to non-goals.md, the PRIMARY details to keybindings.md, and the
paste gate's reasoning joins the confirmation bar it arms.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
input.md and keybindings.md each carried the default-keymap provenance,
the `escapes = "none"` rationale, and the pipe sink mechanics, then cited
the other for the half it had just repeated; the reference page also held
two worked shell recipes, which a page that is consulted rather than read
cannot serve. The reference now keeps the tables and the one-line rules,
and the explanation keeps the reasons.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
input.md and security-model.md argued the same anti-spoofing rule,
including the clip-marking and the frame-that-was-painted test, in places
near-verbatim, and each linked the other as context rather than as owner.
security-model.md now keeps the guarantee and input.md keeps the
chrome-row ordering, so a change to either lands in one place.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
"Process and environment boundary" spent a hundred lines on how session
spawn resolves an environment: the inheritance chain, name folding and
dedup, the agent-symlink design, and the macOS LANG fill. None of those
turn on an adversary, and their nesting (four levels of sub-bullet)
showed a section holding a second document. What stays is what an
attacker could try: the denylist's reasons, the reserved-key refusals,
the no-content-in-logs property, and the repointable agent link with the
argument that no privilege boundary is crossed. The design itself belongs
to session-lifecycle.md, which owns session creation.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
"Resource exhaustion" restated six caps whose decision records live on
the pages each bullet already named, so the same argument had two homes
and the digest could drift from the record. It now states the threat and
cites the owners. "Open questions" went with them: its one entry restated
the clipboard rule stated forty lines above, and the SSH trust statement
it closed on is reference/ipc.md "Authentication"'s. Two "everyone gets
this wrong" claims naming no case also go, on a page that cites CVEs
where it has them.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
"Cross-platform constraints" catalogued four platform shims by repeating
the mechanism each owning page already argues, the sandbox entry was six
lines of mount-namespace mechanism ending in a workaround, and the
promotion rule was stated in the intro and again as a preamble. A scope
list is read to learn what is excluded and why, so each entry now keeps
the rule and the link and nothing else. The closing "What this list is
not" defended the list against a reading nobody made; its one load-
bearing sentence joins the intro.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
security-audits.md exists to say which sites are audited and whether they
pass, but three rows argued why the check is the right one, duplicating
the explanation page they point at in their own header. glossary.md's
rehydration entry expanded into the burst ordering session-lifecycle.md
owns, and its DCS entry said "legacy passthrough" where the dispatcher
drops every body it does not answer. spec.md restated its own intro as a
section and closed on twelve links its rows already carry. The audience
openers go with them: a reference page opens with its subject.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The security-audits blurb named two of that page's three standing audits,
so a reader looking for the OS hand-off audit had no reason to open it,
and the input blurb listed five of its sections while omitting the two
bars a reader most often comes looking for.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Two connective paragraphs stood before it, the second restating the first
plus a pointer each principle's own links already carry. The page is read
to apply a test, so the tests should start at the top.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The closing paragraph only announced what design.md and principles.md
are, which the page has already linked and docs/README.md orders.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
A reference page's first sentence was an audience roll-call ("a reference
for contributors, client implementers and tool authors specifying …")
that told a reader looking up a wire fact nothing they did not already
know from arriving on the page. Reference is declarative lookup
material, so each page now starts with the thing it specifies.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
"CLI clients" and the bridge section restated cli.md's exit-code
mapping, --format envelope, per-field CLI rendering, auto-spawn table
and bridge ceilings while naming cli.md as the normative home for each,
so every change to that surface had to be made twice and a reader could
not tell which page to trust. The wire reference now keeps only what a
client implementer needs at this layer -- which families each verb
rides, SessionInfo's fields and their wire semantics, and the bridge's
correlation and one-terminal rules -- and points at cli.md for the rest.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The correlation, connection-mode and corruption sections each stated a
rule and then argued it, repeating the case the IPC design record makes
in full a few links away: why two id sequences rather than one, why the
active set alone is not enough, why a self-declared mode grants nothing,
why there is no skip-and-continue. Reference states what holds; the
because-clauses now live only where a reader who wants them looks.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The kind/arm, connection-mode, protobuf, image-transfer and
schema-evolution sections each restated the arm table's columns, the
mode admission facts, the crate layout, the completion-proof derivation
and the three versioning mechanisms before reaching the decision they
exist to record, so a future column or mechanism had to be edited on two
pages. Each now opens on its decision and cites the reference for the
facts. "Cancel races the terminal" recorded no decision at all and its
one argument, that cancellation needs a producer that can stop, moves to
the section on where leniency is correct.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Four sections failed the decision gate: the sentinel rule walked every
optional roster field in turn when one rule covers them, the typed-union
rule re-argued itself on a second instance, the extensibility section
parked a mechanism that already ships behind a sentence saying nothing
is owed, and the tmp-cleaner survey inventoried three cleaners plus a
commit sha to support a claim the page already makes. The boundary
statement about what never crosses the wire recorded no decision either;
it belongs beside the daemon/client split it restates.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Seven sites described a rejected shape as the one felis used to have
("the choice this replaces", "the shape this replaces", "the one the
code held until it was challenged", "the string it supersedes"), which
dates the page and tells a reader nothing about why the alternative
fails. Each now states the alternative and its cost in the present
tense. The Windows config and doctor suites could not isolate a temp
profile before --config existed; that is the flag's motivation, not a
fact about the test suites, so the page states the standing constraint
instead.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Five headings on the IPC design page stated the section's verdict ("A
claim is not a length", "Absence is the only thing a sentinel may mean",
"Switch targets are typed, not implied"), so the table of contents spoiled
every argument before the reader met it, and two read as aphorisms whose
referent is clear only afterwards. Each now names the object it covers.
The wire reference's links to the renamed anchors move with them.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The codec spec argued a decoder policy inline ("rejecting it would turn
another implementation's failure to coalesce into an interop break"),
which is a rejected alternative and belongs with the codec's other
rationale. The two reference pages also justified the soft-wrap bit's
placement differently; the codec page owns the layout, so it owns the
reason and the wire page states only where the bit rides.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Two records that are not about placing a capability on a surface (the
CLI machine-output contract, config architecture) had grown to 290 of
this page's 717 lines, most of it restating cli.md's framing rules,
channels, bridge ceilings and id spellings before reaching the rejected
alternative that is the record. Each bullet now states its decision, its
rejection and its trigger, and cites the owner doc for the facts.

"Deliberate asymmetries" loses the entries that record nothing a
contributor would re-propose (a blank cell in the name map already says a
surface has no form there) and the self-defense sentence that opened it.
Bold marked every bullet's lead-in on both lists, which left nothing
standing out; it survives only on the terms being defined. The daemon
status record also cited a release-review item a reader cannot consult,
while making the real argument in the next clause.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The sequence field's `0` refusal and its error name, and the fact that a
build needs no protoc, lived only in the IPC design record; with the
retelling gone they had no home. Both are lookup facts, so the wire
reference states them where the field and the schema are described.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The pipe and run actions were argued twice: input.md "Action mapping"
owns the action surface and session-lifecycle.md "The trail" owns the
transient's place on the trail, yet scrollback.md re-derived the
carrier, the transient lifecycle, the origin environment and the pager
start position. A reader met the same design in two places, and a
change to `run` had to be found filed under a data structure. What is
left here is what the buffer contributes: the two encoders, the
soft-wrap stitch, the client-side selection boundary, and the
region-size refusal.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
session-lifecycle.md's subject is one PTY, one shell, one grid, yet its
largest single block argued where the daemon process is started, how it
is replaced, what happens when it dies and where it logs. overview.md
owns the process model, so those decisions sit there, compressed to the
records: the rejected in-place upgrade, the best-effort systemd
hand-off with the fork behind it, the rejected orphan reclaim, and the
file-over-console logging rule. The unit's per-property tuning and the
log-rotation mechanics go with cli.md, which states them normatively.

What stays with sessions is what a restart or a crash does to them, and
the per-task watchdog that cleans up after a panicking session task.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The additive-attach rule opened "Attach", was re-argued to justify the
switch overlap, was the subject of "Same-user mirroring", and appeared a
fourth time as bullets whose only content was a restatement or a link.
"Destruction" and "Multi-session within the daemon" restated "States",
"Post-exit reaping" and "Detach", and the three-axes list compressed
decisions the subsections beneath it argue in full. Each claim now lives
where it is decided and is referenced from the other sites.

The backpressure sections kept the asymmetry argument and dropped the
mechanism retelling: reference/ipc.md "Backpressure" specifies the
gauges, the cap and the eviction, so the numbers no longer live in two
places.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
reference/ipc.md already specifies registry delivery, the attach
burst's contents and their order, and the semantic limits; the
data-model pages re-told each before arguing it, so one rule lived on
three pages and every future change had to edit them all. Each
explanation now carries the decision and cites the reference for the
shape and the numbers.

The two cluster-cap sections argued the same bound per dimension and
per measurement, which is the decision-gate test; they merge into one
section that states both dimensions once. The `Grid` field block and
the image-store lifecycle list were code and protocol restatement with
no argument around them.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
damage-tracking.md argued its alternatives twice, once as a prior-art
survey and once as a rejected-alternatives list that repeated three of
them, and surrounded the decision with a struct block and an API roster
that teach what the type is rather than why the boundary is drawn
there. pipeline.md restated reference/config.md's material vocabulary
and reference/shaders.md's shader shapes, trail easing and failure
behavior before arguing them, so a shader author or a config reader now
had two places to look and felis two places to update.

text-shaping.md opened with a tutorial's motivation section; the pages
that announced themselves now start with their subject.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Six pages in this area ended with their own "what felis does not do"
list. non-goals.md owns scope rejections, and the rest of these
restated the daemon/client split overview.md owns or the mechanics the
page had already argued, so each one gave a reader a second, thinner
account of a boundary drawn elsewhere.

The detached revisit lists go the same way: a trigger earns its line
attached to the decision it would reopen, not gathered into a table of
contents for the page's own `Revisit if` lines. The two triggers that
were only in such a list move to the decisions they name.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
The `pairs` pin, the size ceiling, the canceled-capability set and the
`tic` fallback appeared on both terminal-identity pages: the reference
as facts, the explanation as a retelling ahead of its argument. That is
the pair most at risk of drifting, so the explanation keeps the
argument (the limits are the reader's, and either violation is total
and silent) and cites the twin for the values.

The reference's Rationale column argued the case the explanation owns;
the canceled capabilities now state their own fate instead.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Thirty concern-owner rows restated facts their owning pages already
state normatively, so every change to the split edited two files, and
"Components at a glance" listed the same responsibilities a third time
after the diagram and the crate map. The table keeps the six
assignments the mechanism-vs-policy principle does not decide on
sight; the rest follow from the principle and are named in one
sentence.

The lifecycle walkthrough restated Creation, Attach and Detach and
ended on a CLI-surface fact control-surfaces.md owns. Two sentences of
orientation are what the page needs before the links take over.

Assisted-by: Claude Code
Assisted-by: Claude Code:Fable 5.1
Build flags, worked scripts and per-verb behavior are task and lookup
material, so they belong on the how-to and reference pages a user reaches
for, not inside the arguments that motivated them. Each fact here had
exactly one home and that home was an explanation page: the Linux
clipboard build feature, the remote-host and pager-anchor recipes, the
retarget tie-break, the bridge's permit lifetime, the human label for a
session's last exit code, and the fact that felis-daemon itself offers no
way down.

Assisted-by: Claude Code:Fable 5.1
A decision that outlived the page it was written on reads as an orphan:
the environment a child inherits argued from the threat model rather than
from creation, the pipe carrier and transient lifecycle argued from the
scrollback's data model rather than from the action surface, and the
wire's deliberate omissions argued apart from the split that produces
them. Each now sits under the concern it belongs to, and the citations
that pointed at the old location follow it.

The grid's four registry caps had no reference row at all, so the
explanation was the only statement of their values; they join the other
semantic limits, leaving the explanation to cite them. The scope
rejections that no owning page may keep (a keymap over the wire,
cross-session image sharing, and the fuller XTSMGRAPHICS argument) move
to non-goals.md, and the citation for the rejected `felis-server-core`
crate now names the section that actually records it.

Assisted-by: Claude Code:Fable 5.1
A REQ row is only as good as the citation that redeems it, and twelve
pointed at headings that no longer exist or at rationale pages that no
longer carry the fact. Each now names the page that commits to it: the
support matrix where a verdict decides the requirement, the reference
twin where a wire fact does, and the explanation section that still holds
the argument. Rows that cited two sources for one fact keep the
reference one alone.

Assisted-by: Claude Code:Fable 5.1
The map is how a reader picks a page without opening it, so a blurb that
promises a section the page no longer has costs more than no blurb. Four
promised removed inventories (a per-family stance catalog, a behaviors
table, web-sourced citations, a deviations list) and one missed the
mutation layer that was added. The protocol reading-order row now names
the support matrix as the verdict, since that is where a contributor
checks a family's status before arguing about it.

Assisted-by: Claude Code:Fable 5.1
A skill sends an agent to a section by name, so a stale name costs the
reading the skill exists to force. The wire's deliberate omissions are
argued from the daemon/client split now, the protocol verdict is the
support matrix with the rationale beside it, and cli.md no longer has a
section by the name the skill used for it.

Assisted-by: Claude Code:Fable 5.1
The page argued a typed refusal past half the 64 MiB framing backstop,
while `MAX_REGION_REPLY_BYTES` is 32 MiB and `trim_region_reply` keeps
the youngest bytes at a resumable cut and drops the viewport position
with the head it lost. The reference row was right, so the argument is
rewritten around the trim: the youngest lines are what the chord was
pressed for, and a refusal answers a size question nobody asked.

Assisted-by: Claude Code:Fable 5.1
The clipping comment named `protocols/text-sizing.md`, which has never
existed; the OSC 66 reference is `protocols/kitty-text-sizing.md`, so the
pointer resolved for nobody.

Assisted-by: Claude Code:Fable 5.1
Both doc comments named a heading on a page that no longer argues it: the
auto-spawn landing is argued from the architecture overview, and the
transient's lifecycle from the action surface that spawns it.

Assisted-by: Claude Code:Fable 5.1
The header says why the derivation exists but not what would retire it,
and a toolchain decision's record is its config file rather than a docs
page. Four observable triggers now sit beside it: a nixpkgs `kani`, a
sysroot buildable in one derivation, a proof target beyond
x86_64-linux, and CBMC drift breaking goto-binary compatibility.

Assisted-by: Claude Code:Fable 5.1
AGENTS.md is the only file an agent session reads unprompted, so a
rule it must hold before opening anything (protected main, Forgejo
Actions, the grep-before-consistent check, the pin-free dev-env rule)
cannot be reduced to a pointer at CONTRIBUTING.md without disappearing
from the agent's view. Restore those lines as one-line restatements and
record the exception in doc-cascade's one-owner rule so the next
deduplication pass keeps them.

Assisted-by: Claude Code:Fable 5.1
Two rows carried 🚫 while their notes said the sequence is consumed and
dropped, which is the ⚠️ vocabulary, so the same behavior read as two
verdicts depending on the row. Membership in the compliance reference's
tolerated set is the one test a reader can apply: an input the parser
consumes and drops takes ⚠️ and names the non-goal behind it, and 🚫 is
left to the capabilities whose inputs reach no implementation at all.

Assisted-by: Claude Code:Fable 5.1
The admission page argues verdicts, and the matrix is where a reader
looks up what felis does with a sequence, so a family named in one and
absent from the other has no normative status: HVP, IND / NEL, the
VT500 page-memory controls, Sun-keyboard sequences, NRCS, non-`G` APC
bodies, and mintty / mosh inline images each get the row their verdict
belongs in.

Assisted-by: Claude Code:Fable 5.1
REQ-301 commits felis to reassembling chunked `t=d` payloads and to
taking oversized or unpadded chunks, and cites this section as the
source, but the section stopped at the envelope. A producer reading it
could not tell whether a 5 KiB chunk or an unpadded tail is a protocol
error, which is the question the requirement answers.

Assisted-by: Claude Code:Fable 5.1
REQ-506 commits felis to honoring `CSI > 4 ; Pv m` and to letting any
Kitty flag supersede it, and cites this page, which named neither the
sequence nor the precedence. A TUI author had no way to learn which
bytes a level produces, or that pushing a Kitty flag silently retires
the level it set.

Assisted-by: Claude Code:Fable 5.1
The CLI reference is where the auto-spawn contract lives, and it named
the slice, the OOM policy and the manual-stop refusal while leaving out
the properties that decide whether a window opens: the notify type, its
start budget, and the collection that keeps a failed start from wedging
the unit name. The two that answer a specific failure keep their
argument next to the hand-off design, `KillMode=process` included, since
the unit takes the default only because that alternative breaks restart.

Assisted-by: Claude Code:Fable 5.1
A plain child outliving the last logout is logind's default, not a
felis guarantee: on a host with `KillUserProcesses=yes` the session
scope takes the daemon and every session it owns down with it, and a
reader told it "survives regardless" loses that work with no way to
have seen it coming. The rule and both remedies belong with the rest of
the auto-spawn contract, so the SSH how-to and the design page cite it.

Assisted-by: Claude Code:Fable 5.1
Five pages send a reader to the CLI reference's global-options section
for the carrier resolution order and the socket-directory rule, both of
which are bullets under "Carrier and connection lifetime". A reader
following the link lands on the flag table and cannot check the claim
the citation was carrying.

Assisted-by: Claude Code:Fable 5.1
The hand-off's two modules point a reader at the session-lifecycle
page for the placement argument, which the architecture overview owns.

Assisted-by: Claude Code:Fable 5.1
The enumeration covers the matrix's supported rows only, and a tolerated
row cannot satisfy its assertion: the input is consumed and dropped,
which is what the ⚠️ status means.

Assisted-by: Claude Code:Fable 5.1
The admission page points a reader at the compliance design for four
omissions, and that page argues one of them. The other three have a
status and nothing to argue, so the matrix is where they belong.

Assisted-by: Claude Code:Fable 5.1
The Region family's `Reply` bullet promised a `Conn::Error
{ InvalidRequest }` refusal for an over-budget region, while the
semantic-limits row, REQ-105a and scrollback.md state the trim the
daemon performs (`trim_region_reply` cuts to the youngest resumable
boundary and returns no position). A reader looking up the wire
behavior found the contract the code does not implement, and the
pager-anchor pages promised an anchor that a trimmed reply cannot
carry.

Assisted-by: Claude Code:Fable 5.1
REQ-912's "every fd is `O_CLOEXEC`" clause was sourced to the rule
alone, so a reader checking which descriptors actually carry the flag
had no route to the standing audit that enumerates the sites; the rule
itself pointed at the audit page rather than at the audit, which holds
four other checklists.

Assisted-by: Claude Code:Fable 5.1
The rows abbreviated DECDWL / DECSWL to DWL / SWL and named DECANM's
reset state only as "VT52 mode", so a reader who greps the standard
identifier finds no status anywhere in the tree.

Assisted-by: Claude Code:Fable 5.1
Whether a size change is tweened is observable behavior a producer plans
around, and no page stated it. The pointer sentences also promised
graphics-interaction and implementation-scope arguments the explanation
twin does not carry: an image placement's box is the graphics
reference's fact, and the legacy form's rejection is a status the
support matrix holds.

Assisted-by: Claude Code:Fable 5.1
The cited explanation section no longer exists; the reference's "Wire
format" states both the keys this parser accepts and the legacy form it
refuses.

Assisted-by: Claude Code:Fable 5.1
REQ-210's two sources stopped naming DECDLD, so nothing a reader
followed from the requirement committed to the status. The status lives
in the matrix, and DECDLD downloads a soft character set, so it belongs
with NRCS in the charset table rather than bundled into the VT52 row.

Assisted-by: Claude Code:Fable 5.1
Page mechanics allow `title:` and `sidebar:` only: a second summary in
frontmatter is a fact with two homes, and the one readers see is the
blurb in docs/README.md.

Assisted-by: Claude Code:Fable 5.1
The one-owner rule read as "root files cite, never restate", which the
front page cannot follow: a reader who lands there needs a sentence of
what felis does before a link is worth clicking. The exception is
bounded by the same test as the rule, so no fact reaches the README
without a page under docs/ that owns it.

Assisted-by: Claude Code:Fable 5.1
The `--format` values, the bridge's connection lifetime and the
config's live reload are lookups the CLI and config references answer;
restating them on the front page puts the same fact in two places and
buries the one thing the paragraph is for.

Assisted-by: Claude Code:Fable 5.1
The pipe comments cited a scrollback section whose argument moved to
input.md, the confirmation module cited a paste section that no longer
exists, and the announced-quantity bullet cited an IPC heading that was
renamed. A citation a reader cannot follow is worse than none: it reads
as if the invariant were written down somewhere.

Assisted-by: Claude Code:Fable 5.1
Every comment here named a section by a title the page no longer has:
the graphics dispatcher record lives in the explanation twin, not the
reference; the font-mmap and PTY audits are checklist bullets in
security-audits.md; and the rest were headings renamed or given a
subtitle. A citation a reader cannot follow reads as if the invariant
were recorded somewhere, which is worse than citing the page alone.

Assisted-by: Claude Code:Fable 5.1
The prose named sections by titles that moved, were renamed, or gained a
subtitle, while several links already carried the right anchor. The
requirement sources are the sharpest case: REQ-009d cited a title that
belongs to another page, and the platform-claim entry cited an
install-guide section that forwards to the workspace matrix.

Assisted-by: Claude Code:Fable 5.1
Each of the three cited a section that no longer commits to the
requirement's clauses, so a reader following the Source column could not
confirm the contract:

- REQ-803's "always updates the session-local mirror" survives only in
  the support matrix's OSC 52 row, which states the whole requirement;
  input.md "Clipboard" now argues the asymmetry alone.
- REQ-805's per-platform backend mapping was dropped. It is a lookup
  fact, so it returns as a table in the keybindings reference, which
  owns the page's other input facts, rather than to the explanation.
- REQ-912b's clauses (newest live relay, next-newest on disconnect, the
  Windows no-op) are all stated in session-lifecycle.md "Creation";
  security-model.md only restates the symlink's existence.

The mapping's Windows entry said TSF. winit 0.30.13 drives Windows IME
through IMM32 (`ImmGetContext` / `ImmGetCompositionStringW` in
`platform_impl/windows/ime.rs`), gated on `SM_IMMENABLED`, so the row
names IMM32.

Assisted-by: Claude Code:Fable 5.1
Machine-output consumers need the shape of `operation_id` to know what
a `switch` or `ssh` reply hands them; the IPC wire reference stated
`<incarnation:016x>-<sequence>` and the CLI reference did not, so the
form was lost when the CLI became its one owner. The opaque-token
instruction stays, with the reason a consumer can check: `incarnation`
is redrawn at every daemon start.

Assisted-by: Claude Code:Fable 5.1
`security-audits.md` and `architecture/overview.md` resolve from nowhere
near these files, so the audit trail the citation is for dead-ends at a
grep. A root-relative `docs/...` path resolves from any crate and is
what the link checker can verify.

Assisted-by: Claude Code:Fable 5.1
An audit of every spec.md row against its Source sections found clauses
with no home. Each is now stated where its subject is looked up, read
off the source:

- The Kitty graphics reply shape (`format_response` in felis-vt: the id
  keys echo `i`, `I` and `p` in that order, a message's `;`, C0 bytes
  and DEL become `_`).
- The OSC 66 `v` and `h` value meanings (`parse_metadata`), which only
  the row codec's cell layout spelled out.
- The OSC 8 grammar and its closing form (`dispatch_osc_8`), which the
  compliance reference's OSC list omitted entirely.
- The peer-identity exception to spawn-and-retry
  (`may_be_a_cold_socket` rejects the `PermissionDenied` that
  `connect_expecting` raises), and which stream each binary's console
  half is.
- The shaping cache's key tuple, whose axis list named the pixel size
  twice and left `FontStyle` out.

Assisted-by: Claude Code:Fable 5.1
Auditing every row whose Source names a page this branch edited turned
up twenty rows citing a section that covers the subject but commits to
no clause, mostly because the committing paragraph now lives one
section over. The citations follow it: synchronized output to
"Synchronization with the daemon", the reflow contract to scrollback's
prior-art section, the switch scope to `Ops`, the grace default to
"Post-exit reaping", the environment order to terminal-identity's
default-identity section, the shader levers to "Idle-zero under
animation", and the caps and refusal fields to the wire and CLI
references that carry the numbers.

REQ-1100 claimed a per-session log. The daemon installs one
process-wide `tracing` subscriber writing to stderr and `daemon.log`
(`felis-transport::logging::init`), with no per-session sink or span, so
the row now says what the code does.

Assisted-by: Claude Code:Fable 5.1
The second pass of the audit covered the rows whose cited sections this
branch left byte-identical, so these gaps predate it. Each clause is
stated on the cited page, one section away from the anchor: the
four-pipeline count and the procedural decorations in the rendering
prior-art section, the post-process present pass under the shader
section, pixel-aligned rasterization under "Atlas integration", the
redraw flag under "Client repaint", `--regex` in the CLI verb details,
and the TUI target list in the compliance explanation. REQ-001's
sentence sits in overview.md's opening, above any heading, so the row
cites the page.

Two facts read off the source rather than re-pointed:

- `f=` defaults to `32` (`decode_format`'s `unwrap_or(b"32")`), which no
  page stated; the graphics reference now does.
- REQ-1010 called the shaping cache's 16 MiB a hard cap.
  `ShapeCache::get_or_insert_sized` inserts first and then evicts other
  entries until it is back under budget, so the cap is transiently
  exceeded and a single oversized bitmap survives alone. The row says
  soft, matching the page.

Assisted-by: Claude Code:Fable 5.1
REQ-213 called the legacy charset family "DECSCS / SCS". DECSCS is
DEC's Select Communication Speed, not charset selection; every other
page and the parser call the family SCS. A reader searching for the
wrong mnemonic would find nothing.

Assisted-by: Claude Code:Fable 5.1
docs: state where the cursor lands after an image placement
All checks were successful
bench / Criterion full-suite snapshot (pull_request) Has been skipped
fuzz / cargo fuzz nightly long-run (pull_request) Has been skipped
fuzz / cargo fuzz smoke (per target) (pull_request) Successful in 1m12s
bench / Criterion regression gate (pull_request) Successful in 2m12s
darwin / detect relevant changes (pull_request) Successful in 3s
darwin / darwin docs-only no-op (pull_request) Has been skipped
darwin / build felis (aarch64-darwin) (pull_request) Successful in 52s
pr / nix flake check (pull_request) Successful in 32s
pr / cargo build / clippy / test / deny (pull_request) Successful in 1m56s
pr / wire schema is compatible with the base (pull_request) Successful in 8s
windows / detect relevant changes (pull_request) Successful in 3s
windows / windows docs-only no-op (pull_request) Has been skipped
windows / cargo clippy (Windows cross) (pull_request) Successful in 12s
windows / cargo nextest (Windows) (pull_request) Successful in 3m59s
pr / frontend smoke (x86_64-linux) (pull_request) Successful in 1m1s
pr / publish felis (x86_64-linux) (pull_request) Has been skipped
windows / frontend smoke (Windows) (pull_request) Successful in 1m38s
windows / package felis (x86_64-pc-windows-msvc) (pull_request) Has been skipped
91f5c250df
The reference listed `C=1` as the way to prevent cursor motion but never
said what the motion is, so the grid test asserting (row + rows, col +
cols) cited a design section that does not state the formula. The
reference now carries the rule the daemon applies, including the wrap
and clamp edges, and the test cites it.

Assisted-by: Claude Code:Fable 5.1
natsukium deleted branch docs/role-cleanup 2026-09-18 11:41:54 +09:00
Sign in to join this conversation.
No description provided.