Repository navigation
Remove quadratic remainder copying from code-point/octet slicing in both realizations (skip/take/get/count to their contracts; Value drop no longer walks a shared slice; cost controls enrolled) - #13346
Conversation
…ier in both realizations Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…he slice Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…share the carrier; regen fixed point holds Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…threshold Dropping a slice of a shared RRB list consumed it into the iterative-drop worklist, cloning every member out of nodes it shared with its source: O(len) per drop, so an offset walk was quadratic in drop alone (measured: 12000 m:count calls = 13.2s at 49k members; the skip arms themselves 207ms). Detach only past 64 nested drops. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…n follows) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…d; fixed_point_equal=true) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ice surface (#13346) The body is unfolded to code points once; delimiters are found by get, the length is count, and each field is skip/take folded back with unicode_scalar_fold, so the decode is linear on non-ASCII text and on the emitted runtime, not only on ASCII in the interpreter. Adds a non-ASCII witness: accented, CJK and astral paths containing the body's own delimiters round-trip in order. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… enrol the slice cost controls on the generated job Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…d over its code points Per the side-chat ruling: no get-by-index and no re-slicing; a state machine folds the unfolded code points once, collecting each field by prepend and reversing it once when it closes, so the decode is linear on any text in either realization. Length prefixes keep code-point semantics. Unstacked from #13346 (its merge reverted above). The cost control is gunbc.instruments.workspace_entry_decode_scaling decode_scaling, whose verdict is claimed with a quadratic red. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Every file this PR does not own is taken from main, so the reverted #13346 merge leaves no residue. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e controls The portable round-trip deep test overflowed the fleet runner's test stack on the first CI run that executed it; it passes on main and this branch alike off the fleet (3/3 each), so it is a separate finding about the portable form. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ness eval-step budget Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
On the advisory about the new hand-written Rust in What it displaces. Each addition replaces a copying path that this diff deletes in the same arm:
What does not shrink. No seed feature, language behaviour or escape hatch is added. The admission class is Line count, stated honestly. Most of the line growth is test code (the RED/GREEN cost pairs) and doc comments, not production arms. The net production growth is the two helpers, the read helper, and the drop threshold with its two empty-carrier thread-locals. There is no separate seed census row for it, because nothing here is retained-for-later. The bodies retire with the interpreter they live in. — sent from swift-ibex-835 |
…gen follows) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…_size Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…red-regen converged) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Changed since
Nothing else changed. — sent from swift-ibex-835 |
…gen follows) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…red-regen converged) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…threshold; the slice step now runs only the runtime crate's controls (rust-unit-tests runs v1-compiler whole) Generated artifacts conflicted and were taken from main; regen follows. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…me_rust.dag block); regen verifies Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s restored, regen verifies) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…converged, v1_rt.rs equals its emission) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ane off the merge path Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…rged) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s the runtime_rust.dag list_skip/list_take block; regen follows) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…red-regen converged; v1_rt.rs equals its emission) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…regen follows) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…deps_version_semver.rs re-emitted) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…_tests_claim_interpolation_hole_census.rs) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
What
Removes the quadratic remainder copying from slicing a code-point or octet list, in both realizations. The interpreter and the emitted Rust runtime (
v1_rt) both change, plus the emit bridge. No new primitive. The existing slice surface already declares the right cost; its realizations didn't meet it.The surface a decoder uses (agreed with proud-wren-11 for #13214's
std.checkpointed_workspaceentry decoder):dag/test/claim/code_point_slice_witness_test.dagdecodes<len>:<code points>fields exactly this way. It is the worked example #13214 mirrors.What this establishes, and what it does not
Both realizations already hold a list as a persistent RRB vector: the interpreter's
Value::ListisRc<im::Vector>, andv1_rt'sVecisim::Vector. Splitting one is O(log n) and shares every node except one boundary path, so a slice now costs log len to form and its own length to read. That removes the quadratic remainder copying. It does not make an offset walk linear. Every member read isget_contract's log n on this carrier, so a walk that reads each offset is O(n log n). This PR does not discharge #13214's linear obligation; per the side-chat ruling, #13214 gets a sequential fold decoder instead.Counts are clamped exactly. With
k = if n < 0 then len else min(n, len),skipkeepslen - kmembers andtakekeepsk. That is the copying forms' reading, now written intoskip_contractandtake_contract.The copies, and the earliest boundary for each (§6b)
The
std.primitivescontracts are the authority. Each defect below is a realization breaking its own declared contract, so each repair is local to its owning link.get(list, i)get_contractwork 1 / log nfree_monoid_to_veccopied all n members as a type guardcount(list)count_contractwork 1len()chars_to_string(cps, s, e)skip/takeon the RRB, then reads only the sliceskip/takeskip_contract(now carrier-sensitive) and a newtake_contractrrb_skip/rrb_take: O(log n), sharedskip/take(extdeps.languages.rust.emitrust_simple_method_specs).iter().cloned().skip(n).collect()copied the remainderv1_rt::list_skip/list_take: O(log n), sharedxs.skip(n).first()(v1.compiler.emit_rustemit_rust_first_method_call)get.iter().cloned().skip(n).next()walked n.get(n as usize).cloned()(same answer, including negativen)impl Drop for Valuedrop, while the depth counter is raisedThe last row was found by measurement, not by the brief. After the first six fixes, an end-to-end walk was still quadratic. Decomposing it showed
getandcountscaled with eval steps and onlyskipdid not.GUNBC_FLATTEN_SITE_DUMP_SECSbuiltin timings then put 12,000m:countcalls at 13,247 ms and theskiparms at 207 ms. The time was the drop of each slice, which happens inside the next call that consumes it. Memo-off A/B (GUNBC_EVAL_MEMO=0) ruled out the eval memo first. The drop gate keeps the totality that the iterative drop exists for:value_depth_walker_tests::a_deep_list_drops(a 262,144-deep nested list on the default 2 MiB test stack) and the rest of that module, 11 tests, pass.Not changed, and why:
char_at/substringover host text inv1_rtstay O(offset) on a bare&str; their own notes name the cursor as that residual's next rung. A decoder that wants linear reads uses the code-point surface above instead.Evidence
Cost controls: RED on the old form, GREEN on the new, deterministic (counts, not clocks), non-ASCII input. All run on the merge path:
Run the slice cost controlsstep (slice_cost_controls) runsv1-stage0-runtimelist_slice_testson the existinggeneratedjob, beside the lint and under the same status guard. Its command is authored atgunbc.repo_self_buildrepo_self_slice_cost_control_command, and the workflow is regenerated fromgunbc.compiler_gate_workflow. No new job. That crate is outside the package the unit-test lane runs, so without this step its controls would only compile.slice_cost_testsand the deep-value drop tests arev1-compilerunit tests. They run in the existingrust-unit-testslane (repo_self_test_command), not in this step, so they aren't run twice.v1_rt::list_slice_tests, in cratev1-stage0-runtime:a_slice_from_the_middle_copies_only_boundary_chunkschecks a clone-counting code point (é, 中, 😀, a) at N = 200,000: a mid-listskip+takecopies ≤ 2,048 members.the_copying_template_form_exceeds_the_budgetruns the old emit templates, spelled exactly as they emitted, on the same input and bound. They must exceed it (the RED).v1_interpreter::slice_cost_tests:rrb_skip/rrb_take.reading_a_list_value_does_not_flatten_it(with the old flatten as its RED).dropping_a_slice_of_a_shared_list_moves_no_member, withthe_detaching_drop_moves_the_slice_membersas its RED.negative_and_overlong_counts_keep_the_copying_forms_reading(both realizations):n ∈ {-3, 0, 4, 10, 11, i64::MAX}gives the same answer as the copying form. The witnesscode_point_slice_decodes_non_ascii_fieldscovers astral code points, an empty field and a two-digit prefix.code_point_slice_refuses_an_overlong_fieldcovers refusal rather than truncation.End to end (interpreter),
claim_batchCPU ms at identical eval steps. This is a probe walking 2^9 / 2^11 / 2^13 three-code-point non-ASCII fields, i.e. 4× per step:The probe is the witness's
decode_fieldsat three sizes. It isn't committed, because a 49k walk is a measurement, not a floor claim: the floor's new-witness budget is 72,300 eval steps, and the committed many-fields claim walks 3,072 code points (50,828 steps). Eval steps cannot see a host copy, so the floor claim checks correctness and the enrolled Rust controls check cost. To re-derive the table, rundecode_fields(body: doubled(s: <the witness field>, times: t))at t = 9 / 11 / 13 throughclaim_batch, against each binary.Regen. The stage0 mirrors are regenerated through the documented route (
gunbc.generated_artifact_merge_driverrepair steps). On the merged tree,required-regenconverged tofirst_generation_equal=true. Conflicted mirrors were taken from main and regenerated. This head's evidence is one emission, not a fixed point: thegeneratedjob's stepStage0 mirrors match one emission by this seedchecks that the committed mirrors equal what this seed emits. No two-generation fixed point is claimed for this head. My local--required-regen-fixed-pointrun ended with no observation (rc 2), so it is not evidence.Admission (v1 seed)
This is admitted under
gunbc.v1_maintenance_standingv1_seed_standing's purpose test asSupportsV2SelfHostProgram { BehaviorPreservingRedundancyRemoval }. Every change removes copies while keeping answers identical; the positive controls above pin that.It serves v2. The emitted runtime is what v2's self-emitted crates run on, and slicing there was a remainder copy on every target. Any emitted decoder walking text by offset was quadratic, ASCII or not. The interpreter is v2's measurement substrate.
Refused classes:
PublicSurfaceGrowth, stated rather than claimed absent:v1_rtgains twopub fns (list_skip,list_take). They realize two existing methods and add no language-level name. This sits on the same boundaryv1_maintenance_typecheck_progress_admission_notesays is undrawn, so a reviewer should judge it rather than take my classification.Operator decision msg_6e6044ca (2026-10-04, option A) authorized the lane.
🤖 Generated with Claude Code