Skip to content

seller memory: truncate an over-budget MEMORY.md, doctor row, quickstart §3d - #983

Open
maxy-player wants to merge 7 commits into
MakePrisms:mainfrom
maxy-player:feat/seller-memory-truncate-warn
Open

seller memory: truncate an over-budget MEMORY.md, doctor row, quickstart §3d#983
maxy-player wants to merge 7 commits into
MakePrisms:mainfrom
maxy-player:feat/seller-memory-truncate-warn

Conversation

@maxy-player

@maxy-player maxy-player commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Base

Base commit: ec95eb2e995d357b5382e46d0efb3025f7d803a0 (MakePrisms/maxplayerai main). Every commit on this branch is on top of it, in order: 6eec9da, f64506f, 117bf2c, c5dac39, d32c018, e8963eb, 285e2f6. No rebase, no force-push, no amend.

What

An operator who writes a MEMORY.md one byte over the 64 KiB injection budget used to lose the whole file: read_on_start refused it with InvalidData, and every job ran as a generalist with one per-job log line as the only signal. Four commits close that:

6eec9da — truncate, never drop. read_on_start cuts an over-budget index, appends one marker line inside the injected text, and returns Ok(Some(..)), never an error. job_memory_section keeps its degrade contract and logs a per-job warning naming the real byte count, budget and path. Boot warns ONCE, in the shape of unreachable_seat_warning, via the new read-only inspect_index (IndexState: NoMemoryDir / NoIndex / Empty / Fits / OverBudget). Nothing creates memory/.

f64506fmaxplayer doctor gets a seller memory row. A thin probe over inspect_index plus a pure, total fold (MemoryIndexProbe → Check). PASS with bytes + headroom; WARN over budget in the boot siren's wording; WARN when memory/ exists but MEMORY.md is missing or empty; WARN (not FAIL) when the index cannot be read; PASS quiet when memory_enabled = false or there is no memory dir. Never a FAIL, never creates memory/. Registered in build_checks after seat reachability, reading the SAME resolved home the job path reads.

117bf2c — docs. SELLER-QUICKSTART.md new §3d "Seat memory — MEMORY.md": opt-in by writing the file, why only the index's own content reaches a docker job, [seller_memory] keys and defaults, retro_enabled declared-not-live, the budget and exact marker, the three warnings, a table of every doctor row, opt-out. Plus one clippy fix in this branch's own test hunk.

c5dac39 — the cut contract, ruled and stated (review round 1, F1/F2).

d32c018 — format-only: the 17 in-hunk rustfmt wraps round 2 found, lifted by hand. No token changed.

e8963eb — the cut is chosen by surviving content, not by newline offset (review round 2, findings 1 and 2). line_boundary_cut accepted any newline at offset > 0, but fit_index_to_budget trim_end()s the head AFTER that choice, so an opening of two LF bytes, a \r\n blank line or an indented blank line selected an all-whitespace prefix that then trimmed to nothing — dropping every byte of specialization that could have fit. The guard now asks whether the head actually survives the trim (!text[..newline].trim_end().is_empty()); checking the RIGHTMOST in-window newline settles all of them, because every earlier newline's prefix is a prefix of this one. When none qualifies, the authorized char-boundary fallback keeps the file's own opening bytes plus as much of the long line as fits. Doc comments and quickstart §3d restated to match, and three regressions added.

285e2f6 — format-only: the two in-hunk rustfmt sites e8963eb introduced, both the same new assert! line, wrapped by hand.

The truncation contract

An index over the budget is cut at the last complete line at or before the budget whose head SURVIVES trimming — the head is trim_ended after the cut, so the line is chosen by what is left standing, not by where a newline happens to sit — and the marker is appended as the final line. When no such line exists — a single line longer than the budget, or a file whose in-budget newlines all sit inside an all-whitespace opening (one LF, two LFs, a CRLF blank line, an indented blank line: the head would trim to empty and the seat would inject zero specialization) — the long-line fallback applies: the cut lands on the nearest lower char boundary, never mid-UTF-8-character, and the file's own opening bytes are kept as-is rather than skipped. The rule cannot reach text that only begins beyond the budget: an index whose whole in-budget window is whitespace has no non-empty head to keep and gets none. The marker's bytes are reserved BEFORE the cut, so the returned text is always <= MAX_MEMORY_INDEX_BYTES including the marker; the bound covers the index text plus the marker, not the surrounding prompt template.

The same words appear in the doc comments on fit_index_to_budget and line_boundary_cut (crates/maxplayer-core/src/seller_memory.rs), in docs/SELLER-QUICKSTART.md §3d, and in four tests: read_on_start_leading_blank_line_then_overlong_line_keeps_a_non_empty_head (one LF then 65,536 x), read_on_start_whitespace_opening_then_overlong_line_keeps_the_files_own_head (two-LF, \r\n, " \n\t\n", "\n \n", four-LF openings), read_on_start_blank_opening_still_cuts_on_a_complete_line (a blank opening followed by in-budget content lines still cuts on a whole line) and read_on_start_all_whitespace_in_budget_window_has_no_head_to_keep (the stated limit). Each checks retained specialization, prefix identity, the marker as final line, valid UTF-8 and the total index-plus-marker bound.

Verified first-hand on 285e2f6

All logs are under ~/forge/v2/worker/reports/w-seller-memory-guard/r4-*.log. Every log prints git rev-parse HEAD, branch + origin/ ref, git status --porcelain (empty) and date -u at its top and bottom, so each witnesses the tree it ran on: HEAD 285e2f6af7f92d69b476d394e8405ef2d7884b96, clean, equal to origin/feat/seller-memory-truncate-warn. No figure below is carried over from an earlier head.

  • r4-build.log (sha256 26f23e420fddb8e9e606f30273adc42fae96f970d54024f9e8c2cd4dc1a9e35b) — cargo build --locked -p maxplayer-core -p maxplayer: exit 0 (line 72).
  • r4-t6-full-tests.log (sha256 9858e0c72862a84498c21de0dc47b0d65f52b792337724f40b0f80056cc20a34) — the full standard run cargo test -p maxplayer-core -p maxplayer --locked: exit 0 (line 1929). All 18 test result: lines are ok; 0 failed anywhere. Core lib: 1418 passed, 0 failed, 2 ignored (line 1785) — three more than round 3's 1415, the three new regressions. CLI unit tests: 161 passed (line 306). Integration seller_memory_read_on_start: 6 passed (line 346). Per-test ok lines — core seller_memory::: read_on_start_blank_opening_still_cuts_on_a_complete_line :1457 (new), read_on_start_leading_blank_line_then_overlong_line_keeps_a_non_empty_head :1460, read_on_start_all_whitespace_in_budget_window_has_no_head_to_keep :1463 (new), read_on_start_whitespace_opening_then_overlong_line_keeps_the_files_own_head :1469 (new), read_on_start_cuts_a_3x_over_index_on_a_line_boundary_within_budget :1458, read_on_start_cuts_multibyte_utf8_on_a_char_boundary :1459, read_on_start_truncates_index_over_size_bound :1464, read_on_start_accepts_index_at_exact_bound :1456, inspect_index_reports_every_state_and_creates_nothing :1453; core seller_node::run::the_memory_budget_warnings_name_bytes_budget_and_path :1634; CLI doctor::: doctor_seller_memory_fold_never_fails :185, doctor_seller_memory_is_quiet_when_disabled_or_without_a_memory_dir :188, doctor_seller_memory_warns_on_an_unreadable_index :189, doctor_seller_memory_passes_with_bytes_and_headroom :192, doctor_seller_memory_warns_on_missing_or_empty_index_in_an_existing_dir :197, doctor_seller_memory_warns_over_budget_with_truncation_wording :201, seller_memory_check_is_wired_into_the_boot_gate :294; integration: the_read_wire_never_creates_the_memory_directory :339, an_index_of_exactly_65536_bytes_is_accepted_and_reaches_the_agent :341, the_golden_invariant_holds_no_memory_is_byte_identical :343, an_over_budget_index_degrades_instead_of_blocking_the_job :344. credential_proxy::tests::a_declared_over_cap_body_is_refused_before_the_upstream_sees_it :673 passed. No test exception is claimed or needed.
  • r4-t1-focused-seller-memory.log (sha256 48d9f5fcaa32e7601e4d38aa073ad256a5d487744f47bb80bbda8f720a8e483f) — cargo test --locked -p maxplayer-core -p maxplayer seller_memory::: exit 0 (line 263), 18 passed / 0 failed (line 195).
  • r4-redcheck.log (sha256 b88057517a275c8deb3385b8dfad9568a308b6fcee04a9d6ef6ce53ee5ff0d1f) — evidence the new regressions BITE, not just pass. The finding-1 guard is reverted in the working tree to the round-2 code (if newline > 0 {; the one-line mutation diff is at line 10), the focused suite is re-run, and the file is restored. Under the old guard read_on_start_whitespace_opening_then_overlong_line_keeps_the_files_own_head FAILS (line 189) with two-lf: the head carries specialization, not an all-whitespace opening at seller_memory.rs:811; result FAILED. 17 passed; 1 failed (line 215), cargo exit 101 (line 218). git checkout -- then restores the file (exit 0, line 220) and the bottom state block shows HEAD 285e2f6 with an empty porcelain. Nothing from this check is committed.
  • r4-fmt-check.log (sha256 76cc8dcc469ab9e5dfe71365d6099b10da9233d228543138cde62440e9948cab) — per-file rustfmt --check --edition 2024 on the four touched .rs files (seller_memory.rs, seller_node/run.rs, doctor.rs, tests/seller_memory_read_on_start.rs), each exit 1 because of base drift; the appended classification (lines 6946–6951) counts every Diff in site against the added-line ranges of git diff ec95eb2 HEAD -U0: 0 sites inside this branch's added lines, 481 outside = 13 / 349 / 115 / 4 per file in that order. Population for both counts: rustfmt Diff in blocks, not diff -U0 hunks. Identical base-drift figures to round 3, so the repair added no drift and cleaned none.
  • Scope of the repair (same log): git diff d32c018 HEAD --stat = 2 files, +208/−21 (seller_memory.rs 214 changed lines, docs/SELLER-QUICKSTART.md 15). No other file is touched; doctor.rs and the integration test are unchanged since d32c018.

Round-3 receipts on d32c018 (history)

Build, tests and fmt figures for the current head are in the section above; the d32c018 receipts stand as the record of round 3 and are NOT claimed to have run on 285e2f6.

All logs are under ~/forge/v2/worker/reports/w-seller-memory-guard/r3-*.log. Every log prints git rev-parse HEAD, branch + origin/ ref, git status --porcelain (empty) and date -u at its top and bottom, so each witnesses the tree it ran on: HEAD d32c01894007924a03c409cd874cf92c630bec1b, clean.

  • r3-build.log (sha256 2630e72af9bc468392093d0ee2771a69aad4aa0dbb9c886a1950c04da7f65f85) — cargo build --locked -p maxplayer-core -p maxplayer: exit 0 (line 71). Prints git state top and bottom.
  • r3-t6-full-tests.log (sha256 7fb946cf4aa78be1ee63e595cee8e95fe596169128b488649c2948086bd9f5a7) — the full standard run cargo test -p maxplayer-core -p maxplayer --locked: exit 0 (line 1928). Every test result: line is ok; 0 failed anywhere. Core lib: 1415 passed, 0 failed, 2 ignored (line 1784). CLI unit tests: 161 passed (line 308). Per-test ok lines — core seller_memory::: inspect_index_reports_every_state_and_creates_nothing :1451, read_on_start_cuts_a_3x_over_index_on_a_line_boundary_within_budget :1454, read_on_start_cuts_multibyte_utf8_on_a_char_boundary :1455, read_on_start_leading_blank_line_then_overlong_line_keeps_a_non_empty_head :1456, read_on_start_truncates_index_over_size_bound :1459; core seller_node::run::: the_memory_budget_warnings_name_bytes_budget_and_path :1633; CLI doctor::: doctor_seller_memory_fold_never_fails :187, doctor_seller_memory_is_quiet_when_disabled_or_without_a_memory_dir :192, doctor_seller_memory_passes_with_bytes_and_headroom :199, doctor_seller_memory_warns_on_an_unreadable_index :201, doctor_seller_memory_warns_on_missing_or_empty_index_in_an_existing_dir :202, doctor_seller_memory_warns_over_budget_with_truncation_wording :212, seller_memory_check_is_wired_into_the_boot_gate :283; integration seller_memory_read_on_start: the_read_wire_never_creates_the_memory_directory :341, an_index_of_exactly_65536_bytes_is_accepted_and_reaches_the_agent :343, the_golden_invariant_holds_no_memory_is_byte_identical :345, an_over_budget_index_degrades_instead_of_blocking_the_job :346 (6 passed, line 348). credential_proxy::tests::a_declared_over_cap_body_is_refused_before_the_upstream_sees_it :675 passed. Prints git state top and bottom.
  • r3-fmt-check.log (sha256 769952b1e3172e36990930b9f8c70eed54de964ae79961a2c07da28273620c67) — per-file rustfmt --check --edition 2024 on the four touched .rs files, each exit 1 because of base drift; the appended classification (lines 6944–6949) counts every Diff in site against the added-line ranges of git diff ec95eb2 HEAD -U0: 0 sites inside this branch's added lines, 481 outside = 13 / 349 / 115 / 4 per file in that order. Population for both counts: rustfmt Diff in blocks, not diff -U0 hunks. Prints git state top and bottom.
  • Format-only proof (same log, lines 6935–6938): git show --stat d32c018 = 3 files, +124/−31 (seller_memory.rs 104, seller_node/run.rs 39, tests/seller_memory_read_on_start.rs 12); the sha256 of each touched file with all whitespace and commas stripped is identical between c5dac39 and d32c018 (SAME ×3), so no token changed.

Round-2 receipts on c5dac39 (history)

Build, tests and fmt figures for the current head are in the 285e2f6 section above; the c5dac39 receipts stand as the record of round 2.

All logs are under ~/forge/v2/worker/reports/w-seller-memory-guard/r2-*.log. Every log prints git rev-parse HEAD, git status --porcelain (empty) and date -u at its top and bottom, so each witnesses the tree it ran on: HEAD c5dac397c9d4930f47d409559ee2e8a2871d4b4c, clean.

  • r2-build.logcargo build --locked -p maxplayer-core -p maxplayer (the two crates, not the whole workspace): exit 0 (line 71). Dead-code warnings in engine.rs are pre-existing at base and not in this branch's hunks.
  • r2-t1-core-seller-memory.logcargo test -p maxplayer-core --locked seller_memory::: 15 passed, 0 failed (line 72). Per-test ok lines: read_on_start_cuts_a_3x_over_index_on_a_line_boundary_within_budget :64, read_on_start_truncates_index_over_size_bound :65, read_on_start_leading_blank_line_then_overlong_line_keeps_a_non_empty_head :67 (new), read_on_start_cuts_multibyte_utf8_on_a_char_boundary :69, inspect_index_reports_every_state_and_creates_nothing :61.
  • r2-t2-core-run-warnings.logcargo test -p maxplayer-core -p maxplayer --locked the_memory_budget_warnings_name_bytes_budget_and_path: 1 passed (line 174 ok, line 176 result). Both packages are needed for feature unification; the log's header records that the single-package form selects a binary where the test is gated out.
  • r2-t3-cli-read-on-start.logcargo test -p maxplayer --locked --test seller_memory_read_on_start: 6 passed, 0 failed (line 80). Per-test ok: the_read_wire_never_creates_the_memory_directory :73, an_index_of_exactly_65536_bytes_is_accepted_and_reaches_the_agent :76, the_golden_invariant_holds_no_memory_is_byte_identical :77, an_over_budget_index_degrades_instead_of_blocking_the_job :78.
  • r2-t4-doctor.logcargo test -p maxplayer --locked doctor::: 86 passed, 0 failed (line 160). Per-test ok: doctor_seller_memory_fold_never_fails :92, doctor_seller_memory_warns_on_an_unreadable_index :95, doctor_seller_memory_passes_with_bytes_and_headroom :98, doctor_seller_memory_warns_over_budget_with_truncation_wording :99, doctor_seller_memory_warns_on_missing_or_empty_index_in_an_existing_dir :103, doctor_seller_memory_is_quiet_when_disabled_or_without_a_memory_dir :104, seller_memory_check_is_wired_into_the_boot_gate :154.
  • r2-t6-full-tests.log — the full standard run cargo test -p maxplayer-core -p maxplayer --locked: exit 0 (line 1926). Every test result: line in the log is ok; 0 failed anywhere. Core lib: 1415 passed, 0 failed, 2 ignored (line 1782). CLI unit tests: 161 passed (line 306). Integration binaries run and ok: cli_e2e, mcp_daemon, seller_declared_output, seller_memory_read_on_start, acp_concurrency, collect_integrity, free_post_no_wallet, git_config_isolation, hostile_local_git_config, no_system_git, push_destination_binding, reap_isolated_linux, relay_canary, relay_git_http_auth, sandbox_netns_live. credential_proxy::tests::a_declared_over_cap_body_is_refused_before_the_upstream_sees_it passed in this run (line 673); the round-1 failure of that test is not reproduced here and no claim about its cause is made.
  • r2-t5-clippy.logcargo clippy -p maxplayer-core -p maxplayer --locked --all-targets -- -D warnings: exit 101 (line 1537), i.e. red. The appended proof block (lines 1541–end) parses every --> site (108 distinct) against the added-line ranges of git diff ec95eb2 HEAD -U0 -- crates/: 0 sites inside this branch's hunks; the site set is identical to the round-1 clippy log taken on 117bf2c. This shows no reported site in these hunks; it does not make clippy green.
  • r2-fmt-check.logcargo fmt --check -p maxplayer-core -p maxplayer: exit 1 (workspace-wide pre-existing drift). Per-file rustfmt --check --edition 2024 on the four touched .rs files: all four exit 1. The appended in-hunk summary counts 17 rustfmt diff sites inside this branch's added lines (seller_memory.rs 10, seller_node/run.rs 4, tests/seller_memory_read_on_start.rs 3, doctor.rs 0) and 481 outside them; every sampled in-hunk site is rustfmt wanting a multi-line assert_eq!/assert! argument wrap. This branch is not rustfmt-clean. The round-1 body's "rustfmt-clean" sentence was wrong and is withdrawn.

Not done / owed

  • The 17 in-hunk rustfmt wraps round 2 found are cleared in d32c018, and the two that e8963eb introduced are cleared in 285e2f6. Current-head receipt r4-fmt-check.log: 0 Diff in sites inside this branch's added lines, 481 outside. The base's own drift (481 sites in these files) stays out of scope and is untouched.
  • clippy -D warnings base drift (108 sites, none in this branch's hunks) is pre-existing and untouched. No clippy run was taken on 285e2f6; the 108-site figure is the round-2 measurement on c5dac39 and is not claimed for the current head.
  • The retro write-back (retro_enabled) is config-declared but no code path runs a retro turn or writes memory/; documented in §3d as declared-not-live rather than wired here.
  • The contract does not promise a non-empty head when the whole in-budget window is whitespace — no byte-bounded rule can reach content that starts past the budget. That limit is stated in the contract above, in the doc comments, in §3d, and pinned by read_on_start_all_whitespace_in_budget_window_has_no_head_to_keep.
  • No merge, no tag: branch + this PR only.

🤖 Generated with Claude Code

w-seller-memory-guard added 3 commits September 8, 2026 11:09
… dropping it

An index one byte over MAX_MEMORY_INDEX_BYTES used to be refused with
InvalidData and the job ran with no memory at all — a specialized seat
silently became a generalist, with one per-job log line as the only
signal. Now `read_on_start` cuts at the last complete line at or before
the budget (never mid-line, never mid-UTF-8-char; a single over-long
line is cut at the nearest lower char boundary), appends a marker line
inside the injected text, and the whole injected index incl. marker
stays <= the budget because the marker's bytes are reserved before the
cut. The result is Ok(Some(..)), never an error.

- `job_memory_section` keeps its degrade contract (Option, never
  propagates, never fails a job) and now logs a truncation warning that
  names the real byte count, the budget and the file path.
- Boot warns once, in the shape of `unreachable_seat_warning`, when
  memory_enabled and the index is over budget. Read-only: never creates
  memory/.
- New `inspect_index` / `IndexState` for the operator surfaces (boot and
  the doctor check to follow).
- Doc comments stating the old REFUSED contract corrected.

Tests: `read_on_start_refuses_index_over_size_bound` rewritten as
`read_on_start_truncates_index_over_size_bound` (one byte over is
truncated, still injects, marker present, <= budget);
`an_over_budget_index_degrades_instead_of_blocking_the_job` now asserts
the prompt CONTAINS the surviving head plus the marker. New: 3x-over
line-boundary cut, multi-byte UTF-8 char-boundary cut, inspect_index
states, boot/per-job warning wording. Exact-cap, golden invariant and
never-creates tests untouched and green.
`maxplayer doctor` now has a "seller memory" row so the operator can ask,
on demand, what every job prompt is actually starting with — the boot
scroll only sirens the over-budget case, and a per-job log line is not a
surface anyone reads.

- PASS with the index's byte size AND the headroom left under
  MAX_MEMORY_INDEX_BYTES, so "how much more can I write" needs no source.
- WARN over budget, in the boot siren's wording: every job prompt gets a
  TRUNCATED copy; fix hint says shorten MEMORY.md itself (linked topic
  files are outside a container job's mount namespace).
- WARN when memory/ exists but MEMORY.md is missing or empty — a seat that
  started to specialize and stopped; both inject nothing, both name the
  path to write.
- WARN (not FAIL) when MEMORY.md exists but cannot be read: the job path
  degrades to no-memory, and the check learned nothing about the content.
- PASS, quietly, when memory_enabled = false or there is no memory dir
  (the state of nearly every seat). Read-only: never creates memory/.

Never a FAIL: memory is a quality lever, not a money-path or containment
invariant. Shape follows check_sandbox_image: a thin probe over
seller_memory::inspect_index plus a pure, total fold (MemoryIndexProbe ->
Check) so every verdict's wording is testable without a home.

Registered in build_checks after seat reachability, reading
config.seller_memory.memory_enabled and seller_memory::memory_dir(&home.root)
— the SAME resolved home the job path and the boot siren read.

Tests (doctor.rs): PASS bytes+headroom; WARN over budget with the
truncation wording; WARN missing/empty index in an existing dir; PASS
quiet when disabled (even over a planted over-budget file) or without a
dir, asserting the dir is not created; WARN unreadable (a directory
wearing the MEMORY.md name); fold-never-fails over every probe; and a
RED-PROVE wiring test through build_checks on a bootstrapped home.
`cargo test -p maxplayer --locked doctor::` 86 passed.
…tion, doctor row

New §3d after the sandbox section: what memory/ + MEMORY.md are and that
the daemon never creates them (opt-in by writing the file); what loads at
job start and why only the index's OWN content reaches a docker job (the
linked topic files are outside the mount namespace); the [seller_memory]
keys with defaults, and that retro_enabled is declared but no retro turn
runs yet, so MEMORY.md is operator-written; the 64 KiB injection budget
and that an over-budget index is TRUNCATED with a marker line, never
dropped, with the exact marker and the boot/per-job/doctor warnings; a
table of every `maxplayer doctor` "seller memory" row (advisory, never
FAIL); and how to opt out. Acceptance checklist gains a memory line.

Also: one clippy hit inside this branch's own test hunk
(seller_memory.rs, manual_str_repeat/manual_repeat_n) → `glyph.repeat(..)`.
The remaining `clippy -D warnings` sites are pre-existing base drift.
@vercel

vercel Bot commented Sep 8, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the MakePrisms Team on Vercel.

A member of the Team first needs to authorize it.

w-seller-memory-guard added 4 commits September 8, 2026 12:03
… in code and quickstart (MakePrisms#983 r1 F1, F2)

Contract revision (addendum 1, ordering seat): the last-complete-line rule applies to the last
complete line that leaves a NON-EMPTY head. When the only newline at or before the content budget
sits at offset 0, the head would be empty and the seat would inject zero specialization, so the
long-line fallback applies (cut at the nearest lower char boundary). Behaviour of
`line_boundary_cut` is unchanged; its doc comment, `fit_index_to_budget`'s doc comment and the
inline comment now state that rule in the ruling's words, and a focused test pins the case:
one LF followed by 65,536 ASCII `x` bytes -> result <= budget, valid UTF-8, marker as the final
line, head non-empty and cut on a char boundary inside the second line.

SELLER-QUICKSTART §3d no longer promises "never mid-line or mid-character": it now states the
last-complete-line cut, the two shapes that fall back to a character-boundary cut (never
mid-character), that the marker's bytes are reserved before the cut, and that the 64 KiB bound
covers the index text plus the marker, not the surrounding prompt template.
Hand-lift of rustfmt's output for exactly the 17 `rustfmt --check --edition 2024`
diff blocks that fall inside this branch's own added lines (seller_memory.rs 10,
seller_node/run.rs 4, tests/seller_memory_read_on_start.rs 3, doctor.rs 0). The
481 blocks in the same files outside this branch's hunks are base drift and are
untouched. Format-only: each file is byte-identical to c5dac39 once whitespace
and commas are stripped. Method: rustfmt --emit stdout to scratch, diff -U0,
apply only hunks whose original range lies wholly inside the added ranges of
`git diff ec95eb2 -U0` (25 -U0 hunks, 0 straddling).
…wline offset

Round-2 DENY finding 1: line_boundary_cut accepted any newline at offset > 0,
but fit_index_to_budget trim_end()s the head AFTER that choice. Two LF bytes,
a CRLF blank line or an indented blank opening therefore selected an
all-whitespace prefix that trimmed to nothing, dropping every byte of
specialization that could have fit.

Decide on the head that survives the trim instead: a newline is a usable
complete-line cut only when the text before it is not all whitespace. The
rightmost in-window newline settles all of them, since every earlier one has a
prefix of this prefix. When none qualifies, the authorized char-boundary
fallback keeps the file own opening bytes plus as much of the long line as fits.

Tests: two-LF, CRLF, indented-blank and multi-LF openings (retained
specialization, prefix identity, marker last, UTF-8, budget); a blank opening
followed by content still cuts on a complete line; and the documented limit,
an all-whitespace in-budget window, which has no head to keep. The one-LF
regression is unchanged.

Finding 2: doc comments and quickstart 3d now state the surviving-head rule and
the fallback, including that opening bytes are kept, not skipped.
The two in-hunk rustfmt sites were both the same new assert line in the tests
added by the previous commit. Wrapped by hand; no whole-file fmt, no base-drift
cleanup.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant