pmacs/docs
Levi Neuwirth 7b2f90c77e
docs: one signature cannot serve two contracts
Revision 16 said the scroll formatter could keep its signature and
change only what callers pass. It cannot, and the byte fallback in
revision 17 made that unavoidable rather than merely untidy.

Every branch of format_scroll_indicator derives from total_lines:

  total_lines <= 1                      -> All
  visible >= total_lines                -> All
  view_top == 0                         -> Top
  view_top + visible >= total_lines     -> Bot
  pct = (cursor_row + 1) * 100 / total_lines

Revision 17 removed the total. Passing byte counts makes the Bot branch
compare rows against bytes --- it would return plausible strings that
mean nothing. Passing any stand-in small enough to satisfy the guards
restores the false All this section exists to remove. And "local
predicates" is not something that signature can evaluate, because it
has no parameter for them.

Resolved by not asking it to. truncate calls the existing formatter
UNTOUCHED, with the same arguments in the same units, so its output is
byte-identical by construction rather than by assertion, and every
existing formatter test stays valid --- including the GPU's
format_scroll_indicator(0, 10, 1, 0) == "All", which correctly pins
line-space behavior. wrap calls a new classifier:

  classify(first_visible: bool, last_visible: bool,
           byte_pos: u64, byte_len: u64) -> ScrollPosition

All = first && last; Top = first && !last; Bot = last && !first;
otherwise Percent from bytes. No count of rows enters it, so the unit
mixing is not avoided but unrepresentable.

The actual mistake was trying to serve two genuinely different
contracts from one four-count signature. It could only do that by
making units implicit, which is how the contradiction arose. This is
5b.5's identity-case strategy applied to the indicator itself: the old
mode keeps the old code, and the new mode gets code shaped to it.

Leaves one question open. pmacs-gpu depends on pmacs-protocol only,
never on the pmacs lib, so format_scroll_indicator is duplicated
STRUCTURALLY and the classifier faces the same fork. Duplicating it
preserves exactly the condition that produced the earlier defect, where
one copy was fixed and the other was not. Sharing it through
pmacs-protocol makes the agreement structural rather than maintained,
which is the principle that chose byte-anchoring, additive sub_row, and
a content-derived cache key --- but it widens that crate from wire
vocabulary toward presentation, which is a COHERENCE section 16
layering question and not this lane's to settle alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai
2026-08-06 22:56:35 +02:00
..
active-work.md docs: one signature cannot serve two contracts 2026-08-06 22:56:35 +02:00
agent-handoff.md docs: four review defects, and a documented error that never happens 2026-08-06 10:40:54 +02:00
auto-indent-framing.md
auto-pairing-framing.md
autosave-recovery-framing.md
bottom-panel-framing.md
bottom-panel-stage2-framing.md docs(bottom-panel): record framing revision 7 2026-07-29 22:37:41 -04:00
bottom-panel-stage3-framing.md review round 1: the crdt suite Stage 3 missed, and two stale explanations 2026-08-04 12:08:28 +02:00
ci-crdt-coverage-framing.md review round 2: assert the CRDT capability defaults, not their round-trip 2026-08-01 11:37:19 -04:00
ci-red-signatures.md docs: four review defects, and a documented error that never happens 2026-08-06 10:40:54 +02:00
comment-toggle-framing.md
compile-mode-framing.md
config-registry-framing.md
context-menu-framing.md
cua-typeover-undo-framing.md
desktop-save-framing.md
dired-framing.md
dired-stage2-framing.md docs: dired Stage 2 framing rev 9 2026-07-28 21:09:11 -04:00
discovery-stage1-command-family-framing.md docs(discovery): finalize Stage 1 framing review 2026-07-31 18:28:35 -04:00
distribution-stage1-framing.md docs(release): a tag before the merge does nothing, silently 2026-08-01 14:46:27 -04:00
editing-conveniences-framing.md
folding-framing.md
folding-stage2-framing.md
full-grid-resync-framing.md docs: the framing said "awaiting approval" after being approved 2026-08-06 15:22:03 +02:00
generated-buffer-immutability-framing.md merge: integrate main after PR 188 lands 2026-07-29 12:28:25 -04:00
gpu-attach-robustness-framing.md
gpu-chord-forwarding-framing.md
gpu-golden-harness-framing.md
gpu-initial-target-framing.md test(journey): pin the destination commit, and land the doc updates 2026-07-26 17:25:22 -04:00
gpu-invocation-framing.md
gpu-minibuffer-framing.md
gpu-set-font-framing.md
gpu-terminal-input-framing.md
in-buffer-completion-framing.md
in-buffer-search-framing.md
inline-math-framing.md docs: record the inline-math slice (#158) as landed 2026-07-25 18:16:31 -04:00
inline-math-slice-framing.md
journey-stage1a-framing.md feat(compile): make building discoverable — journey step 9 2026-07-30 21:13:12 -04:00
journey-stage1b1-compile-defaults-framing.md docs(journey): framing revision 2 — close review round 1 2026-07-30 18:40:34 -04:00
journey-stage1b2-lsp-guidance-framing.md docs(journey): framing revision 4 — close review round 3 2026-07-30 21:52:15 -04:00
journey-stage1b3-welcome-framing.md docs(journey): framing revision 4 — close review round 3 2026-07-31 14:55:57 -04:00
json-yaml-framing.md docs: absorption pass at c5f7501#209 landed, and six weeks of drift 2026-08-01 13:56:23 -04:00
keybindings.md docs(coherence): §5 substrate-without-surface -> Partial 2026-07-31 19:17:22 -04:00
kill-ring-framing.md
latex-grammar-math-substrate-framing.md
lean4-mode-framing.md fix(lean4): count fan-outs where a claim cannot skip the count 2026-07-26 17:15:24 -04:00
locals-query-processing-framing.md
long-lines-framing.md docs: one signature cannot serve two contracts 2026-08-06 22:56:35 +02:00
lsp-panels-framing.md
lua-bindings-split-framing.md
macos-ci-signal-integrity-framing.md docs: record Stage 2 in the framing, and fence R3 off from R2's retirement 2026-08-05 13:51:40 +02:00
mcp-for-package-authors.md
mode-system-wiring-framing.md
modeline-detection-framing.md
multi-language-injections-framing.md
package-author-guide.md
package-manager-hardening-framing.md
packages.md
persistence-framing.md
pmacs-gpu-design.md
pmacs-gpu-diagnostic-parity-framing.md
pmacs-gpu-mouse-deferred-framing.md
pmacs-gpu-mouse-framing.md
pmacs-gpu-perline-reshape-framing.md
pmacs-gpu-phase-a-audit.md
pmacs-gpu-quad-backgrounds-audit.md
pmacs-gpu-quad-backgrounds-framing.md
pmacs-gpu-scroll-framing.md
pmacs-gpu-status-band-framing.md
pmacs-gpu-wavy-squiggles-framing.md
process-signal-diagnostic-completeness-framing.md docs(process): stop overclaiming the pre-kill sample; drop a dead comment 2026-07-30 14:41:50 -04:00
process-signal-tolerance-framing.md docs: frame the PTY terminate diagnostic (revision 4) 2026-07-25 21:12:51 -04:00
process-teardown-stdin-deadlock-framing.md fix(process): arm the setsid dependency, correct the orphan account 2026-07-29 22:54:06 -04:00
project.md
query-replace-framing.md
reap-ledger-silent-failures-framing.md fix(process): scope the escalation claim to ticks, and pin the boundary 2026-07-30 20:41:03 -04:00
repository-audit-2026-07-03.md
resource-op-delete-guard-framing.md fix(lsp): close review gaps in workspace edit reporting 2026-07-29 12:29:50 -04:00
roadmap-2026-07.md
semantic-frontend-protocol.md
side-quest-backlog.md docs: absorption pass at c5f7501#209 landed, and six weeks of drift 2026-08-01 13:56:23 -04:00
statusline-segments-framing.md
tab-width-parity-framing.md
terminal-config-and-copy-mode-framing.md docs: correct the non-adopter attribution and two stale anchors 2026-07-26 16:45:12 -04:00
test-ambient-config-isolation-framing.md docs(framing): record the deliberate departure from the §7 branch plan 2026-07-31 19:46:33 -04:00
theme-faces-framing.md
tree-primitive-framing.md fix(listview): ids must also be unique and not NaN 2026-08-05 23:06:25 +02:00
ux-arc-framing.md
vterm-framing.md Merge main, and fold #173's a37 findings into the CI-coverage lane 2026-07-26 09:29:42 -04:00
web-grammars-html-css-framing.md