seller memory: truncate an over-budget MEMORY.md, doctor row, quickstart §3d - #983
Open
maxy-player wants to merge 7 commits into
Open
seller memory: truncate an over-budget MEMORY.md, doctor row, quickstart §3d#983maxy-player wants to merge 7 commits into
maxy-player wants to merge 7 commits into
Conversation
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.
|
Someone is attempting to deploy a commit to the MakePrisms Team on Vercel. A member of the Team first needs to authorize it. |
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Base
Base commit:
ec95eb2e995d357b5382e46d0efb3025f7d803a0(MakePrisms/maxplayeraimain). 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.mdone byte over the 64 KiB injection budget used to lose the whole file:read_on_startrefused it withInvalidData, 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_startcuts an over-budget index, appends one marker line inside the injected text, and returnsOk(Some(..)), never an error.job_memory_sectionkeeps its degrade contract and logs a per-job warning naming the real byte count, budget and path. Boot warns ONCE, in the shape ofunreachable_seat_warning, via the new read-onlyinspect_index(IndexState: NoMemoryDir / NoIndex / Empty / Fits / OverBudget). Nothing createsmemory/.f64506f—maxplayer doctorgets aseller memoryrow. A thin probe overinspect_indexplus a pure, total fold (MemoryIndexProbe → Check). PASS with bytes + headroom; WARN over budget in the boot siren's wording; WARN whenmemory/exists butMEMORY.mdis missing or empty; WARN (not FAIL) when the index cannot be read; PASS quiet whenmemory_enabled = falseor there is no memory dir. Never a FAIL, never createsmemory/. Registered inbuild_checksafter seat reachability, reading the SAME resolved home the job path reads.117bf2c— docs.SELLER-QUICKSTART.mdnew §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_enableddeclared-not-live, the budget and exact marker, the three warnings, a table of everydoctorrow, 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_cutaccepted any newline at offset > 0, butfit_index_to_budgettrim_end()s the head AFTER that choice, so an opening of two LF bytes, a\r\nblank 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 sitese8963ebintroduced, both the same newassert!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_BYTESincluding 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_budgetandline_boundary_cut(crates/maxplayer-core/src/seller_memory.rs), indocs/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,536x),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) andread_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
285e2f6All logs are under
~/forge/v2/worker/reports/w-seller-memory-guard/r4-*.log. Every log printsgit rev-parse HEAD, branch +origin/ref,git status --porcelain(empty) anddate -uat its top and bottom, so each witnesses the tree it ran on: HEAD285e2f6af7f92d69b476d394e8405ef2d7884b96, clean, equal toorigin/feat/seller-memory-truncate-warn. No figure below is carried over from an earlier head.r4-build.log(sha25626f23e420fddb8e9e606f30273adc42fae96f970d54024f9e8c2cd4dc1a9e35b) —cargo build --locked -p maxplayer-core -p maxplayer: exit 0 (line 72).r4-t6-full-tests.log(sha2569858e0c72862a84498c21de0dc47b0d65f52b792337724f40b0f80056cc20a34) — the full standard runcargo test -p maxplayer-core -p maxplayer --locked: exit 0 (line 1929). All 18test result:lines areok; 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). Integrationseller_memory_read_on_start: 6 passed (line 346). Per-testoklines — coreseller_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; coreseller_node::run::the_memory_budget_warnings_name_bytes_budget_and_path:1634; CLIdoctor:::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(sha25648d9f5fcaa32e7601e4d38aa073ad256a5d487744f47bb80bbda8f720a8e483f) —cargo test --locked -p maxplayer-core -p maxplayer seller_memory::: exit 0 (line 263), 18 passed / 0 failed (line 195).r4-redcheck.log(sha256b88057517a275c8deb3385b8dfad9568a308b6fcee04a9d6ef6ce53ee5ff0d1f) — 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 guardread_on_start_whitespace_opening_then_overlong_line_keeps_the_files_own_headFAILS (line 189) withtwo-lf: the head carries specialization, not an all-whitespace openingatseller_memory.rs:811; resultFAILED. 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 HEAD285e2f6with an empty porcelain. Nothing from this check is committed.r4-fmt-check.log(sha25676cc8dcc469ab9e5dfe71365d6099b10da9233d228543138cde62440e9948cab) — per-filerustfmt --check --edition 2024on the four touched.rsfiles (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 everyDiff insite against the added-line ranges ofgit 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: rustfmtDiff inblocks, notdiff -U0hunks. Identical base-drift figures to round 3, so the repair added no drift and cleaned none.git diff d32c018 HEAD --stat= 2 files, +208/−21 (seller_memory.rs214 changed lines,docs/SELLER-QUICKSTART.md15). No other file is touched;doctor.rsand the integration test are unchanged sinced32c018.Round-3 receipts on
d32c018(history)Build, tests and fmt figures for the current head are in the section above; the
d32c018receipts stand as the record of round 3 and are NOT claimed to have run on285e2f6.All logs are under
~/forge/v2/worker/reports/w-seller-memory-guard/r3-*.log. Every log printsgit rev-parse HEAD, branch +origin/ref,git status --porcelain(empty) anddate -uat its top and bottom, so each witnesses the tree it ran on: HEADd32c01894007924a03c409cd874cf92c630bec1b, clean.r3-build.log(sha2562630e72af9bc468392093d0ee2771a69aad4aa0dbb9c886a1950c04da7f65f85) —cargo build --locked -p maxplayer-core -p maxplayer: exit 0 (line 71). Prints git state top and bottom.r3-t6-full-tests.log(sha2567fb946cf4aa78be1ee63e595cee8e95fe596169128b488649c2948086bd9f5a7) — the full standard runcargo test -p maxplayer-core -p maxplayer --locked: exit 0 (line 1928). Everytest result:line isok; 0 failed anywhere. Core lib: 1415 passed, 0 failed, 2 ignored (line 1784). CLI unit tests: 161 passed (line 308). Per-testoklines — coreseller_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; coreseller_node::run:::the_memory_budget_warnings_name_bytes_budget_and_path:1633; CLIdoctor:::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; integrationseller_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(sha256769952b1e3172e36990930b9f8c70eed54de964ae79961a2c07da28273620c67) — per-filerustfmt --check --edition 2024on the four touched.rsfiles, each exit 1 because of base drift; the appended classification (lines 6944–6949) counts everyDiff insite against the added-line ranges ofgit 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: rustfmtDiff inblocks, notdiff -U0hunks. Prints git state top and bottom.git show --stat d32c018= 3 files, +124/−31 (seller_memory.rs104,seller_node/run.rs39,tests/seller_memory_read_on_start.rs12); the sha256 of each touched file with all whitespace and commas stripped is identical betweenc5dac39andd32c018(SAME×3), so no token changed.Round-2 receipts on
c5dac39(history)Build, tests and fmt figures for the current head are in the
285e2f6section above; thec5dac39receipts stand as the record of round 2.All logs are under
~/forge/v2/worker/reports/w-seller-memory-guard/r2-*.log. Every log printsgit rev-parse HEAD,git status --porcelain(empty) anddate -uat its top and bottom, so each witnesses the tree it ran on: HEADc5dac397c9d4930f47d409559ee2e8a2871d4b4c, clean.r2-build.log—cargo build --locked -p maxplayer-core -p maxplayer(the two crates, not the whole workspace): exit 0 (line 71). Dead-code warnings inengine.rsare pre-existing at base and not in this branch's hunks.r2-t1-core-seller-memory.log—cargo test -p maxplayer-core --locked seller_memory::: 15 passed, 0 failed (line 72). Per-testoklines: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.log—cargo test -p maxplayer-core -p maxplayer --locked the_memory_budget_warnings_name_bytes_budget_and_path: 1 passed (line 174ok, 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.log—cargo test -p maxplayer --locked --test seller_memory_read_on_start: 6 passed, 0 failed (line 80). Per-testok: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.log—cargo test -p maxplayer --locked doctor::: 86 passed, 0 failed (line 160). Per-testok: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 runcargo test -p maxplayer-core -p maxplayer --locked: exit 0 (line 1926). Everytest result:line in the log isok; 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_itpassed 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.log—cargo 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 ofgit diff ec95eb2 HEAD -U0 -- crates/: 0 sites inside this branch's hunks; the site set is identical to the round-1 clippy log taken on117bf2c. This shows no reported site in these hunks; it does not make clippy green.r2-fmt-check.log—cargo fmt --check -p maxplayer-core -p maxplayer: exit 1 (workspace-wide pre-existing drift). Per-filerustfmt --check --edition 2024on the four touched.rsfiles: all four exit 1. The appended in-hunk summary counts 17 rustfmt diff sites inside this branch's added lines (seller_memory.rs10,seller_node/run.rs4,tests/seller_memory_read_on_start.rs3,doctor.rs0) and 481 outside them; every sampled in-hunk site is rustfmt wanting a multi-lineassert_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
d32c018, and the two thate8963ebintroduced are cleared in285e2f6. Current-head receiptr4-fmt-check.log: 0Diff insites 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 warningsbase drift (108 sites, none in this branch's hunks) is pre-existing and untouched. No clippy run was taken on285e2f6; the 108-site figure is the round-2 measurement onc5dac39and is not claimed for the current head.retro_enabled) is config-declared but no code path runs a retro turn or writesmemory/; documented in §3d as declared-not-live rather than wired here.read_on_start_all_whitespace_in_budget_window_has_no_head_to_keep.🤖 Generated with Claude Code