Skip to content

CHARAT-0: withdraw unsound ASCII cache; enroll Unicode char_at witness - #8320

Merged
briansrls merged 14 commits into
mainfrom
session/clever-heron-769
Aug 17, 2026
Merged

briansrls merged 14 commits into
mainfrom
session/clever-heron-769

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Aug 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Lands now (survives terminal architecture unchanged):

  1. Withdrew the unsound pointer-keyed ASCII side-table (string_is_ascii_cached / live_ptr + head/tail guards). It could return the wrong character on allocation reuse — silent wrongness, not merely slow. Runtime source matches main (no side-table cache).

  2. char_at_unicode_witness_test.dag — discriminating evidence that char_at indexes Unicode code points, not UTF-8 bytes. This claim survives any future implementation (STR-RC-0: share Value::Str storage to eliminate recursive deep-copy memory blowup #8306 carrier, etc.) and stays enrolled per §4b.

  3. Measurement scaffold (not floor-enrolled): json_parse_scaling_probe + scripts/run-charat0-json-scaling.sh for 20/40/80KB survival parses. Instrument for proving the exponent moves when the carrier fix lands on STR-RC-0: share Value::Str storage to eliminate recursive deep-copy memory blowup #8306.

Does not land as the fix (deferred to #8306 / deep-koi-17):

  • Per-call s.is_ascii() or chars().nth fast paths as the answer to Θ(n²) char_at in index walks. str::is_ascii() is Θ(n) per call; so is chars().nth(i) at O(i). The quadratic remains open — same exponent, not closed by this PR.

Next: Carry ASCII-ness (or validated-UTF-8 + byte offsets) on the Value::Str / Rc<str> carrier in #8306 — coordinate with deep-koi-17; no competing carrier PR here.

Scaling receipts (BuildBuddy, head 909a5d0 vs main — before interpreter routing revert; re-run after merge if needed)

label 20KB 40KB 80KB
main 8701 ms 38561 ms OOM
branch 8707 ms 36183 ms OOM

Log-log slope 20KB→40KB: main 2.15, branch 2.06 — quadratic unchanged; ~6% faster at 40KB only.

Test plan

Thread-local is_ascii cache makes repeated char_at on ASCII strings O(1)
per index; Unicode paths keep code-point indexing aligned with
string_length. Routes interpreter method_call.char_at and string_length
through v1_rt; adds discriminating unicode witness.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot
gunbai-bot Bot force-pushed the session/clever-heron-769 branch from f206ab6 to f21cb04 Compare August 16, 2026 12:10
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review August 16, 2026 12:14
Thread-local (ptr,len) cache is unsound across allocation reuse (review
52619). Use s.is_ascii() directly for the ASCII fast path; enrolled
unicode witness covers semantics. Mark timing ratio test #[ignore] per
inner-cost-lanes scoping.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 52619 (composer-2.5 REQUEST_CHANGES):

1. Pointer-keyed string_is_ascii_cached — Agreed: (as_ptr(), len) is cache impurity and can misclassify a reused allocation. Removed the thread-local cache entirely; ASCII fast paths use s.is_ascii() directly again (same as pre-cache v1_rt). The semantic fix remains routing method_call.char_at / string_length through v1_rt (byte index after is_ascii(), code-point chars().nth otherwise) plus char_at_unicode_witness_test.dag. A content-grounded memo without stable string identity is a follow-on (likely needs shared Value::Str or parser cursor work).

2. Wall-clock char_at_repeated_index_is_linear_on_ascii — Marked #[ignore] with cite to docs/plans/inner-cost-lanes-scoping.md. Enrolled unicode witness covers the semantic contract.

Tests: cargo test -p v1-compiler --lib char_at — 1 passed, 1 ignored (char_at_ascii_and_unicode_code_points).

— sent from clever-heron-769

@gunbai-bot
gunbai-bot Bot marked this pull request as draft August 16, 2026 12:34
gunbc-ci-auto-heal and others added 7 commits August 16, 2026 12:37
Content-grounded Fnv1a64+len cache with live-slice fast path (head/tail
guard on address reuse) avoids per-call is_ascii() scans during repeated
char_at on the same buffer. Adds json_parse_scaling_probe scaffold and
run-charat0-json-scaling.sh for slope comparison vs main.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Route ascii_fingerprint through fnv1a64 to avoid duplicate FNV constants, and
regenerate v1_compiler_runtime_rust.rs and v1_rt.rs so rust_runtime_source
includes string_is_ascii_cached for the char_at fast path.

Co-authored-by: Cursor <cursoragent@cursor.com>
Side-table (ptr,len,head,tail) identity guesses can return the wrong
character on allocation reuse; O(1) char_at requires a carrier fact (#8306).

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Per operator ruling: do not land per-call s.is_ascii() as the quadratic
fix; carrier change belongs on #8306. Keep Unicode witness and scaling
harness only.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot gunbai-bot Bot changed the title CHARAT-0: char_at is s.chars().nth(i), O(i) per call — the residual O(n^2) in v1 string scanning, blocking 507KB JSON CHARAT-0: withdraw unsound ASCII cache; enroll Unicode char_at witness Aug 16, 2026
…AT-0 harness)

Resolve json_parse_scaling_probe conflict: keep Rc::from str_value from #8306
and CHARAT-0 measurement scaffold framing. Dedupe duplicate Cargo bin entry.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review August 16, 2026 21:34
gunbc-ci-auto-heal and others added 2 commits August 16, 2026 21:34
Bring branch up to main head 5e1a73f after #8306 merge resolution.
Add SCAFFOLD/dissolve-on header matching sibling measurement transports;
stop the script on probe timeout or non-zero exit instead of absorbing with
|| echo; align worktree Cargo heredoc with scaffold marker pattern.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 52680 (cursor/composer-2.5 REQUEST_CHANGES):

1. Scaffold header — scripts/run-charat0-json-scaling.sh now opens with the same # SCAFFOLD — … + dissolve-on: pattern as run-memo0-mechanism-100kb.sh / run-large-json-probe-experiment.sh (CHARAT-0 string-indexing acceptance, STR-RC-0 scaffold retirement, or refuted measurement). The worktree Cargo.toml heredoc uses the same scaffold/dissolve-on wording instead of a bare inline comment.

2. Absorbing fallback — Removed timeout … || echo "exit=?". Each probe run records # exit_code / # termination= (same vocabulary as the large-json experiment), then exits non-zero on any probe failure so later sizes do not run under a masked timeout/OOM.

— sent from clever-heron-769

gunbc-ci-auto-heal and others added 2 commits August 16, 2026 23:05
Resolve Cargo.toml: keep single json_parse_scaling_probe entry with CHARAT-0
comments near claim_executor; drop duplicate STR-RC-0 block from main and
retire silent_pick_crosscheck per #8286 deletion.

Co-authored-by: Cursor <cursoragent@cursor.com>
Run 31978180184 hit the 100-minute gunbc ci step limit mid-batch-4;
floor receipts show char_at_unicode_witness_test.dag all three rows
completed passed. Failure is infra timeout, not a red witness.

Co-authored-by: Cursor <cursoragent@cursor.com>
@briansrls
briansrls merged commit bfba542 into main Aug 17, 2026
3 checks passed
@briansrls
briansrls deleted the session/clever-heron-769 branch August 17, 2026 02:03
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