mac: consume display-list-v2-diagnostics — v2 suggestions reach Problems and Tab-to-fix (after #358) - #363
mac: consume display-list-v2-diagnostics — v2 suggestions reach Problems and Tab-to-fix (after #358)#363d-q222 wants to merge 37 commits into
Conversation
Decode optional code/suggestion/labels/notes/help on RuntimeV1.Diagnostic (FastJSON + Codable), group/categorise by code with the message-phrase fallback kept, show notes/help on the row, copy rustc-like = note/= help lines, and apply help.replacement through the existing QuickFix path when the range is in bounds and the compile revision still matches. Filtered swift test from apps/mac (StructuredDiagnosticTests, EditorDiagnostics*, DiagnosticsPanelTests, FastJSONTests, ProtocolTests): Executed 76 tests, with 7 tests skipped and 0 failures. Next: full `swift test` from apps/mac, then push this lane branch. Open questions: none in-scope; help.replacement with an explicit other-file path hides Fix… (QuickFix.otherDocument), matching today's explanation edits. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com>
Add display::Diagnostic.suggestion (None at every constructor) and tests that expect unknown_command/\alpha and unsupported_feature. from_compiler still hardcodes code "compiler" and does not copy suggestion. Ran: CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd cargo test --manifest-path crates/render-pipeline/Cargo.toml --lib from_compiler_forwards Result: test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 89 filtered out display::tests::from_compiler_forwards_code_and_suggestion: left "compiler" right "unknown_command" Next: forward compiler code (explicit, else default_code, else "compiler") and suggestion; emit suggestion only in runtime-v1 JSON; extend corpus owner_for; keep v2 diagnostics without a suggestion key. Open questions: none in-scope. vendor/, apps, protocol schema untouched. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com>
from_compiler copies the compiler's code (explicit, else default_code(message), else "compiler") and suggestion. runtime-v1 JSON emits suggestion only when set; display-list-v2 diagnostics are unchanged except the code value. owner_for accepts the compiler code set; tikz_pipeline rejects those codes too so a forwarded unknown_command cannot slip through as "not compiler". Ran (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd): - --lib from_compiler_forwards -- writer_matches_value_tree: test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 88 filtered out - --lib write_json_matches_the_value_tree: test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 89 filtered out - --test compiler_diagnostic_forward: test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out - --test tikz_pipeline: test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out - python3 -m unittest tools.real-world-corpus.test_run: Ran 6 tests in 0.008s OK Next: full cargo test --manifest-path crates/render-pipeline/Cargo.toml control-vs-after. Open questions: no in-scope golden embeds "code":"compiler" for a compiler diagnostic (vendor/pdf fixture and apps/mac display-list fixture are out of lane). docs/user/compiler.md still shows the old example. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com>
Add protocol/proposals/display-list-v2-diagnostics.md: capability accepted only with display-list-v2; suggestion/labels/notes/help use the runtime-v1 shapes with v2 #/$defs/source; omit-when-empty; deltas carry the same keys; without the cap bytes stay identical. Schema delta is text in the proposal (frozen rendering-v2.schema.json untouched). labels/notes/help wait for a vendor re-pin past #346; this lane serialises suggestion only. Ran: none (docs-only). Next: failing tests for negotiated vs not, compact vs JSON-tree, and a suggestion-only delta. Open questions: none in-scope. No vendor/, schema, apps, or contracts edits. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com>
CAP_DIAGNOSTICS and Wire.diagnostics / Capabilities.diagnostics, negotiated only with display-list-v2. Writers still emit the frozen four-key diagnostic, so capability-on output is byte-identical to capability-off and a suggestion change does not change the delta header digest. Ran (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd): cargo test --manifest-path crates/render-pipeline/Cargo.toml --lib diagnostics_capability_gates_suggestion -- suggestion_change_is_hashed -- negotiation_accepts_only_known Result: test result: FAILED. 1 passed; 2 failed; 0 ignored; 0 measured; 89 filtered out - negotiation_accepts_only_known_requested_capabilities: ok - diagnostics_capability_gates_suggestion_on_the_wire: left == right (no suggestion key) - suggestion_change_is_hashed_and_deltaed_only_when_serialised: header_digest equal with cap on Next: emit suggestion from write_diagnostics / diagnostic_json when the cap is on and the value is Some; hash it only then. Open questions: none. labels/notes/help still wait for #346 re-pin. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com>
write_diagnostics and diagnostic_json_wire add suggestion after sources when Wire.diagnostics is set and the value is Some (BTreeMap order; never null). Deltas use the same writer. header_digest hashes suggestion only then, so a suggestion-only change produces a delta. Frozen writers stay four-key. No labels/notes/help slots (vendor compiler has none until #346). Ran (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd): - --lib diagnostics_capability_gates_suggestion -- suggestion_change_is_hashed -- write_json_matches: test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 89 filtered out - --lib writer_matches_value_tree -- from_compiler_forwards -- negotiation_accepts: test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 89 filtered out - --test compiler_diagnostic_forward: test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out Next: full cargo test --manifest-path crates/render-pipeline/Cargo.toml. Open questions: none in-scope. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com>
…d-diagnostics' into agent/daniel-parent/mac-v2-diagnostics Stacking base for an overnight daniel-parent lane (#277); announced on #2. Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
Add display-list-v2-diagnostics.json (frozen four-key diagnostic plus one with suggestion/labels/notes/help), Codable slots on RenderingV2.Diagnostic, and tests for fast==slow, setLiveV2 negotiation, document-runtime allowlist, and Fix… from suggestion. Slow JSONDecoder already fills the slots; the fast reader still skips them, so decode() (fast-first) drops the fields. Ran: - apps/mac swift test --filter RenderingV2Tests.testDisplayListV2DiagnosticsFixtureKeepsStructuredFields|…|V2ImageTests.testPaneRequestsImagesAlongsideV2…|EditorDiagnosticsQuickFixTests.testSuggestionReplacementBoundsAndHelpWins|testHelpReplacementBoundsAndRevisionGate Executed 5 tests, with 18 failures (0 unexpected) in 0.252 seconds testHelpReplacementBoundsAndRevisionGate passed; the four new assertions fail - CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-macv2 cargo test --manifest-path crates/document-runtime/Cargo.toml --lib diagnostics_capability_is_accepted test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 20 filtered out unknown accepted capability display-list-v2-diagnostics Next: fast diagnostic() reads the new keys; setLiveV2 requests the cap with images; document-runtime allowlist mirrors images; canApplyHelpReplacement covers suggestion. Open questions: Mac compile path is WorkerClient / preview-controller, not document-runtime directly; the allowlist is still the documented reference. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com>
Fast and slow readers fill suggestion/labels/notes/help (v2 nested source on help.replacement). setLiveV2 asks for display-list-v2-diagnostics next to images. document-runtime accepts that cap only with display-list-v2. Fix… uses suggestion over sources[0] when help.replacement is absent. Delta header digest hashes suggestion when present (producer rule). Ran: - apps/mac swift test --filter RenderingV2Tests|V2ImageTests.testPaneRequestsImagesAlongsideV2…|EditorDiagnosticsQuickFixTests|LayoutCapabilityTests|DiagnosticsPanelTests Executed 41 tests, with 1 test skipped and 0 failures (0 unexpected) in 1.172 seconds - CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-macv2 cargo test --manifest-path crates/document-runtime/Cargo.toml --lib capability_is_accepted test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out Next: filtered RenderingV2*/V2*/EditorDiagnostics*/DiagnosticsPanel*/LayoutNegotiation* then full swift test and cargo test document-runtime. Open questions: Mac talks WorkerClient and preview-controller; document-runtime is the helper allowlist, not the direct-worker path. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com>
…no re-derived fallback Adopts the semantics of GoKubar's duplicate #370: the compiler's constructors already set `code` via `default_code`, and a `None` is deliberate (request validation), so re-deriving `default_code(message)` here could label a diagnostic the compiler's own runtime-v1 reply leaves uncoded. Now `d.code.map_or("compiler", ...)`. --lib from_compiler 1/0 (test updated: uncoded stays "compiler"); compiler_diagnostic_forward 2/0 (tikz still unsupported_feature, set by the compiler's constructor); tikz_pipeline 3/0; golden_v1 1/0. Implementation-Agent: Claude Code (daniel-parent, mac-m5pro-dq222) Commit-Executor: Claude Code (daniel-parent) Lane-Owner: daniel-parent (mac-m5pro-dq222) Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
|
daniel-muse-lead: ACK, claiming. |
|
daniel-muse-lead: slice 1 done — Rust half green ( |
|
daniel-muse-lead: done, PR #373 (draft, based on |
… pick up #327's Mac inventory sync (CI sync-supported-latex --check) Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…k up #327's Mac inventory sync (CI sync-supported-latex --check) Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…s and set diagnostics: false in flashtex-render's Wire Conflict in crates/render-pipeline/src/bin/flashtex-render.rs: main (#344) made --v2 honour --images; this branch added the Wire.diagnostics field. Resolved as Wire { images: self.images, device_color, diagnostics: false }. lib 97/0, compiler_diagnostic_forward 2/0, display_list_delta 3/0, cli_e2e 4/0. Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…act compiler code semantics Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…c-v2-diagnostics (main + inventory sync + flashtex-render Wire resolution) Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…c-v2-diagnostics (main + inventory sync + flashtex-render Wire resolution) Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…nt digest
Declining display-list-v2 now drops the whole family (images, device-color,
diagnostics, delta, only) via is_display_list_family. The size estimate
charges suggestion only when Wire.diagnostics would serialise it.
Some("") is omitted from the compact writer, JSON tree, and header_digest
through Diagnostic::wire_suggestion. Digest scheme stays dl2-canon-1:
optional negotiated fields are Wire-gated like image items, not a rename
(Mac still only accepts dl2-canon-1). LM skip in compiler_diagnostic_forward
is now an assert. Stale runtime-v1 "does not forward code/suggestion"
wording updated.
Ran (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd):
- cargo test --manifest-path crates/render-pipeline/Cargo.toml --lib
test result: ok. 115 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
- cargo test --test compiler_diagnostic_forward --test display_list_delta
compiler_diagnostic_forward: test result: ok. 4 passed; 0 failed; 0 ignored
display_list_delta: test result: ok. 3 passed; 0 failed; 0 ignored
- python unittest tests/test_rendering_v2.py: Ran 23 tests in 0.039s OK
Next: git fetch origin && git merge origin/main, re-run, push.
Open questions: none on the five review items.
Implementation-Agent: cursor-agent cursor-grok-4.6-high-fast
Commit-Executor: cursor-agent
Lane-Owner: daniel-parent (mac-m5pro-dq222)
Co-authored-by: Cursor <cursoragent@cursor.com>
Merge origin/main (Mac editor folding/indent/print, cleveref/includeonly, kernel inventory tests). No conflicts with the v2 diagnostics capability work. Re-ran the lane gates after the merge. Ran (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd): - cargo test --manifest-path crates/render-pipeline/Cargo.toml --lib test result: ok. 126 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out - cargo test --test compiler_diagnostic_forward --test display_list_delta compiler_diagnostic_forward: test result: ok. 4 passed; 0 failed; 0 ignored display_list_delta: test result: ok. 3 passed; 0 failed; 0 ignored - python unittest tests/test_rendering_v2.py: Ran 23 tests in 0.037s OK Next: push the lane branch. Open questions: none. Implementation-Agent: cursor-agent cursor-grok-4.6-high-fast Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com>
Appendix A header_digest now hashes suggestion at the same position and with the same encoding as delta.rs (only when display-list-v2-diagnostics is negotiated and the value is non-empty). Pinned c4e7c7129994d1b73c8dfe3d9b1b9a0cbf0edc49e7f9e6bc848d8c66e0126bb6 from a hand walk of that algorithm; diagnostics-off in-memory suggestion matches the no-suggestion digest. Overflow no longer echoes -images or -device-color. Ran (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd): - cargo test --manifest-path crates/render-pipeline/Cargo.toml --lib --test display_list_delta --test compiler_diagnostic_forward lib: test result: ok. 128 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out compiler_diagnostic_forward: test result: ok. 5 passed; 0 failed; 0 ignored display_list_delta: test result: ok. 3 passed; 0 failed; 0 ignored - /tmp/flashtex-schema-venv/bin/python -m unittest tests.test_rendering_v2 Ran 24 tests in 0.039s OK Next: push this checkpoint for daniel-parent re-review of the last PARTIAL. Open questions: none. Implementation-Agent: cursor-agent cursor-grok-4.6-high-fast Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com>
…d-diagnostics' into agent/daniel-parent/mac-v2-diagnostics
…ac-v2-diagnostics
…ac-v2-diagnostics
… flag Write the review-gap tests first. A v2 frame with a suggestion and an empty compile_result list still yields problemsList.count == 0 (caretFix and EditorDiagnostics cannot see it). headerDigest now takes diagnosticsCapability but still hashes a present suggestion, so the #358 capability-off golden e554935e… fails (got c4e7c712…). Empty-suggestion normalisation and decline logging for display-list-v2-diagnostics (including whole-family overflow) already pass. Ran (apps/mac): - swift test --filter 'ProblemsPanelV2Tests|RenderingV2Tests' Executed 23 tests, with 1 test skipped and 5 failures (testV2SuggestionWithEmptyV1… and hosted panel: problemsList 0 != 1; testHeaderDigestMatchesAppendixA… capability-off digest mismatch) Next: map v2 diagnostics through asRuntimeV1 into displayedDiagnostics (prefer v1 when non-empty, never duplicate) and hash suggestion only when the diagnostics capability is accepted. Open questions: none. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com>
|
Checkpoint Done: failing tests for the independent review (REQUEST_CHANGES). A v2 frame with a suggestion and an empty v1 list still yields Results: Next: map v2 diagnostics through |
Map a live v2 frame through asRuntimeV1 into displayedDiagnostics (and therefore problemsList, caretFix, and editor marks) when compile_result lists none; runtime-v1 wins when both sources carry rows so they are never concatenated. headerDigest hashes suggestion only when display-list-v2-diagnostics was accepted, matching Appendix A / #358. The live delta install path passes that flag from the applied result. Ran: - CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-macv2 cargo test --manifest-path crates/document-runtime/Cargo.toml lib: test result: ok. 18 passed; 0 failed; 3 ignored chunks: test result: ok. 6 passed display_sibling: test result: ok. 10 passed session: test result: ok. 19 passed; 0 failed; 1 ignored - swift test --filter 'RenderingV2|PreviewV2|EditorDiagnostics|ProblemsPanel|DisplayListDelta|CommandTable|HostedWindowSupport' Executed 109 tests, with 11 tests skipped and 0 failures - swift test --skip NearbyInterfaceTests --skip NearbyLANInterfaceTests Executed 1224 tests, with 135 tests skipped and 2 failures (RustPDFExportPipeTests load timeout) re-run --filter RustPDFExportPipeTests in isolation: Executed 4 tests, with 0 failures Next: daniel-parent review of the REQUEST_CHANGES fix-up. Open questions: none. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com>
|
Checkpoint Done: v2 frame diagnostics map through Results:
Next: daniel-parent review. Did not change #358 producer files. |
… gaps (ordering only, on #476) (#411) * wip(#76): failing tests for Problems list bucket order Add DiagnosticsPanelTests that pin errors-then-warnings-then-gaps across two documents, Copy Diagnostics walking that order, and ⌘⌥] starting on the first author error rather than an earlier gap. What was run: `swift test --filter` of the three new methods in apps/mac. Result: Executed 3 tests, with 7 failures (0 unexpected) in 0.238 seconds. Current groups(of:) still sorts by first occurrence in source, so the tikz gap leads the list. Next: sort groups(of:) by bucket while keeping document order inside each bucket and inside each group's occurrences; add summary() for the header counts; wire ProblemsPanel VoiceOver. Open questions: whether ProblemsPanel.idealHeight 260 (~1/3 of a typical window) still needs a smaller default; overlap with #363/#367/#403. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com> * wip(#76): sort Problems groups by bucket and show header counts groups(of:) lists author errors, then warnings, then FlashTeX gaps, keeping document order inside each bucket and inside each group's occurrences. result.diagnostics is not reordered. summary() reuses counts() for "2 errors · 5 warnings · 46 FlashTeX gaps"; the Problems header and VoiceOver label read that string. Opening height is 180 pt (was 260, ~1/3 of a typical window); the 40% cap is unchanged. What was run: swift test --filter DiagnosticsPanelTests| EditorDiagnostics*|WorkspaceShellTests in apps/mac. Result: Executed 54 tests, with 7 tests skipped and 0 failures (0 unexpected) in 2.107 seconds. Next: full `swift test` from apps/mac; overlap check; push. Open questions: none on ordering/header. Existing AppStorage values of 260 remain until the user resizes. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com> * wip(#76): restore coloured Problems header count chips Restore the three SF Symbol count labels (errors red, warnings orange, gaps puzzle-piece secondary) including zeros so an all-gap document still shows the error column. VoiceOver uses summary() once via .ignore on the chips; the panel stays .contain so the list remains accessible. DiagnosticsListView caption matches. idealHeight stays 180; a stored AppStorage 260 cannot be told from a user resize, so it is left as-is. What was run: swift test --filter 'DiagnosticsPanelTests|EditorDiagnostics|WorkspaceShellTests' in apps/mac. Result: Executed 59 tests, with 7 tests skipped and 0 failures (0 unexpected) in 2.112 seconds. Next: daniel-parent review / PR. Open questions: none on the header. AppStorage 260 left as-is. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
|
Refreshed onto current main (2d1b517). One conflict, crates/render-pipeline/src/protocol.rs: main's #651 rewrote the over-limit refusal to avoid serialising the 16 MB envelope, while this stack (#358) widens the capability filter to the display-list family. Resolved as the union: #651's non-serialising envelope_len pre-check structure with #358's |
crates/perf-bench (#206) constructs v1::Capabilities literally; the #358 half of this stack adds the diagnostics field, so the bench failed to compile (E0063) and the engine performance job failed at Build. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu
|
Re-refreshed onto main after #654/#294/#295/#296 landed (main is now 2890090). Three new conflicts, all from #294's windowing capability meeting this stack's diagnostics capability, resolved as unions:
|
…#658) * wip(#277): reproduce from_compiler dropping code and suggestion Add display::Diagnostic.suggestion (None at every constructor) and tests that expect unknown_command/\alpha and unsupported_feature. from_compiler still hardcodes code "compiler" and does not copy suggestion. Ran: CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd cargo test --manifest-path crates/render-pipeline/Cargo.toml --lib from_compiler_forwards Result: test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 89 filtered out display::tests::from_compiler_forwards_code_and_suggestion: left "compiler" right "unknown_command" Next: forward compiler code (explicit, else default_code, else "compiler") and suggestion; emit suggestion only in runtime-v1 JSON; extend corpus owner_for; keep v2 diagnostics without a suggestion key. Open questions: none in-scope. vendor/, apps, protocol schema untouched. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com> * wip(#277): forward compiler diagnostic code and suggestion from_compiler copies the compiler's code (explicit, else default_code(message), else "compiler") and suggestion. runtime-v1 JSON emits suggestion only when set; display-list-v2 diagnostics are unchanged except the code value. owner_for accepts the compiler code set; tikz_pipeline rejects those codes too so a forwarded unknown_command cannot slip through as "not compiler". Ran (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd): - --lib from_compiler_forwards -- writer_matches_value_tree: test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 88 filtered out - --lib write_json_matches_the_value_tree: test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 89 filtered out - --test compiler_diagnostic_forward: test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out - --test tikz_pipeline: test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out - python3 -m unittest tools.real-world-corpus.test_run: Ran 6 tests in 0.008s OK Next: full cargo test --manifest-path crates/render-pipeline/Cargo.toml control-vs-after. Open questions: no in-scope golden embeds "code":"compiler" for a compiler diagnostic (vendor/pdf fixture and apps/mac display-list fixture are out of lane). docs/user/compiler.md still shows the old example. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com> * wip(#277): propose display-list-v2-diagnostics capability Add protocol/proposals/display-list-v2-diagnostics.md: capability accepted only with display-list-v2; suggestion/labels/notes/help use the runtime-v1 shapes with v2 #/$defs/source; omit-when-empty; deltas carry the same keys; without the cap bytes stay identical. Schema delta is text in the proposal (frozen rendering-v2.schema.json untouched). labels/notes/help wait for a vendor re-pin past #346; this lane serialises suggestion only. Ran: none (docs-only). Next: failing tests for negotiated vs not, compact vs JSON-tree, and a suggestion-only delta. Open questions: none in-scope. No vendor/, schema, apps, or contracts edits. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com> * wip(#277): reproduce v2 suggestion omitted without diagnostics cap CAP_DIAGNOSTICS and Wire.diagnostics / Capabilities.diagnostics, negotiated only with display-list-v2. Writers still emit the frozen four-key diagnostic, so capability-on output is byte-identical to capability-off and a suggestion change does not change the delta header digest. Ran (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd): cargo test --manifest-path crates/render-pipeline/Cargo.toml --lib diagnostics_capability_gates_suggestion -- suggestion_change_is_hashed -- negotiation_accepts_only_known Result: test result: FAILED. 1 passed; 2 failed; 0 ignored; 0 measured; 89 filtered out - negotiation_accepts_only_known_requested_capabilities: ok - diagnostics_capability_gates_suggestion_on_the_wire: left == right (no suggestion key) - suggestion_change_is_hashed_and_deltaed_only_when_serialised: header_digest equal with cap on Next: emit suggestion from write_diagnostics / diagnostic_json when the cap is on and the value is Some; hash it only then. Open questions: none. labels/notes/help still wait for #346 re-pin. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com> * wip(#277): emit v2 suggestion when display-list-v2-diagnostics is on write_diagnostics and diagnostic_json_wire add suggestion after sources when Wire.diagnostics is set and the value is Some (BTreeMap order; never null). Deltas use the same writer. header_digest hashes suggestion only then, so a suggestion-only change produces a delta. Frozen writers stay four-key. No labels/notes/help slots (vendor compiler has none until #346). Ran (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd): - --lib diagnostics_capability_gates_suggestion -- suggestion_change_is_hashed -- write_json_matches: test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 89 filtered out - --lib writer_matches_value_tree -- from_compiler_forwards -- negotiation_accepts: test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 89 filtered out - --test compiler_diagnostic_forward: test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out Next: full cargo test --manifest-path crates/render-pipeline/Cargo.toml. Open questions: none in-scope. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com> * render-pipeline: from_compiler forwards exactly the compiler's code, no re-derived fallback Adopts the semantics of GoKubar's duplicate #370: the compiler's constructors already set `code` via `default_code`, and a `None` is deliberate (request validation), so re-deriving `default_code(message)` here could label a diagnostic the compiler's own runtime-v1 reply leaves uncoded. Now `d.code.map_or("compiler", ...)`. --lib from_compiler 1/0 (test updated: uncoded stays "compiler"); compiler_diagnostic_forward 2/0 (tikz still unsupported_feature, set by the compiler's constructor); tikz_pipeline 3/0; golden_v1 1/0. Implementation-Agent: Claude Code (daniel-parent, mac-m5pro-dq222) Commit-Executor: Claude Code (daniel-parent) Lane-Owner: daniel-parent (mac-m5pro-dq222) Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz * compiler: accept kernel preamble declarations as no-ops, warn on DocumentMetadata keys \NeedsTeXFormat, \ProvidesClass, \ProvidesPackage and \ProvidesFile are .cls/.sty declarations with no visible output in a document compiler, so they're accepted silently (required group, then the optional [info]/[date] bracket, both discarded). \DocumentMetadata (LaTeX2e 2022+) is different: its keys (pdfstandard, pdfversion, lang, testphase, ...) really do change real LaTeX's PDF output, which this compiler doesn't generate that way. Before \documentclass it's accepted with a warning naming the ignored keys; after \documentclass it's a real error, matching real LaTeX. Reuses the existing document_class: Option<String> field (set when \documentclass itself is processed) for the position check -- no new preamble-tracking mechanism needed. Regenerates the inventory artifacts and the Mac bundled copy. Implementation-Agent: muse-spark-1.3-contributor (Muse Code, lane kernel-text-symbols, slice 1) Commit-Executor: daniel-muse-lead (Claude Sonnet) Reviewed-by: daniel-muse-lead (Claude Sonnet) Muse-Lane-Head: 3dbf61de Co-authored-by: muse-spark-1.3-contributor <muse-contributor@flashtex.invalid> * wip(#358): negotiated-case protocol test next to #354's omit-suggestion compiler_diagnostic_forward.rs: keep typo_alpah_is_unknown_command_with_alpha_suggestion_in_v1_only (v2 omits suggestion when the cap is off). Add negotiated_v2_diagnostics_emits_suggestion through handle_line: capability off omits suggestion; with display-list-v2 + display-list-v2-diagnostics the sibling carries suggestion and echoes the cap; the cap alone is rejected. Proposal status no longer says stacked on #354. Ran (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd): - cargo test --manifest-path crates/render-pipeline/Cargo.toml --lib test result: ok. 112 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out - cargo test --manifest-path crates/render-pipeline/Cargo.toml --test compiler_diagnostic_forward --test display_list_delta compiler_diagnostic_forward: test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out display_list_delta: test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out - python unittest tests/test_rendering_v2.py: Ran 23 tests in 0.037s OK Next: push this lane branch. Open questions: none. document-runtime allowlist remains #363. Implementation-Agent: cursor-agent cursor-grok-4.6 Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com> * wip(#358): failing tests for overflow dependents, estimate, empty suggestion Reproduction tests for the independent review: declining display-list-v2 must also drop display-list-v2-diagnostics (FLASHTEX_MAX_REPLY_BYTES=6000); the size estimate with diagnostics off must match a suggestion-stripped list; Some("") must be omitted from the writer and the digest. Ran (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd): - cargo test --lib estimate_omits_suggestion test result: FAILED. 0 passed; 1 failed (784 vs 758) - cargo test --lib empty_suggestion test result: FAILED. 0 passed; 2 failed - cargo test --lib empty_suggestion_is_not_hashed test result: FAILED. 0 passed; 1 failed - cargo test --test compiler_diagnostic_forward declining_display_list test result: FAILED. 0 passed; 1 failed (echoed ["display-list-v2-diagnostics"] with no sibling) Next: drop dependents with one helper, gate the estimate on Wire, omit empty suggestions in writer and digest, document dl2-canon-1 conditional suggestion, make the LM skip visible. Open questions: digest scheme — document conditional suggestion under dl2-canon-1 (images already Wire-gate the same scheme) rather than rename to dl2-canon-1+diagnostics (Mac still only knows dl2-canon-1). Implementation-Agent: cursor-agent cursor-grok-4.6-high-fast Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com> * compiler: brace-aware DocumentMetadata keys, seen-documentclass flag Fixes all three of daniel-parent's re-review points on #440: 1. \DocumentMetadata{testphase={phase-III,math,table}} now warns naming only "testphase" (a top-level key with a braced value), not three separate "keys" -- keys are now split on top-level commas, tracking brace depth character by character, instead of a plain comma split over the raw (brace-stripped) argument text. 2. A new seen_documentclass flag (set on any \documentclass invocation, even an empty one) replaces document_class.is_some() for the \DocumentMetadata position check, so \documentclass{}\DocumentMetadata{lang=en-US} is now the real "must come before \documentclass" error instead of a warning. 3. missing_required_argument_is_a_parse_error now asserts the exact message this PR's own dispatch arm produces, instead of a generic "command not supported" message the unmodified parser already emits for any unknown preamble command. Mutation-tested for all three (revert -> new/strengthened test fails -> restore -> passes), independently spot-checked by the reviewer for fix 1 (disabling brace-depth tracking fails document_metadata_nested_braces_are_a_single_key as predicted). cargo test --test kernel_preamble_declarations: 8 passed, 0 failed. Full cargo test in crates/compiler: 0 FAILED across all suites. Implementation-Agent: muse-spark-1.3-contributor (Muse Code, lane fix440, slice 1) Commit-Executor: daniel-muse-lead (Claude Sonnet) Reviewed-by: daniel-muse-lead (Claude Sonnet) Co-authored-by: muse-spark-1.3-contributor <muse-contributor@flashtex.invalid> * wip(#358): drop dependents on overflow; omit empty suggestion; document digest Declining display-list-v2 now drops the whole family (images, device-color, diagnostics, delta, only) via is_display_list_family. The size estimate charges suggestion only when Wire.diagnostics would serialise it. Some("") is omitted from the compact writer, JSON tree, and header_digest through Diagnostic::wire_suggestion. Digest scheme stays dl2-canon-1: optional negotiated fields are Wire-gated like image items, not a rename (Mac still only accepts dl2-canon-1). LM skip in compiler_diagnostic_forward is now an assert. Stale runtime-v1 "does not forward code/suggestion" wording updated. Ran (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd): - cargo test --manifest-path crates/render-pipeline/Cargo.toml --lib test result: ok. 115 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out - cargo test --test compiler_diagnostic_forward --test display_list_delta compiler_diagnostic_forward: test result: ok. 4 passed; 0 failed; 0 ignored display_list_delta: test result: ok. 3 passed; 0 failed; 0 ignored - python unittest tests/test_rendering_v2.py: Ran 23 tests in 0.039s OK Next: git fetch origin && git merge origin/main, re-run, push. Open questions: none on the five review items. Implementation-Agent: cursor-agent cursor-grok-4.6-high-fast Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com> * wip(#358): pin Appendix A suggestion digest; drop overflow dependents Appendix A header_digest now hashes suggestion at the same position and with the same encoding as delta.rs (only when display-list-v2-diagnostics is negotiated and the value is non-empty). Pinned c4e7c7129994d1b73c8dfe3d9b1b9a0cbf0edc49e7f9e6bc848d8c66e0126bb6 from a hand walk of that algorithm; diagnostics-off in-memory suggestion matches the no-suggestion digest. Overflow no longer echoes -images or -device-color. Ran (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-diagfwd): - cargo test --manifest-path crates/render-pipeline/Cargo.toml --lib --test display_list_delta --test compiler_diagnostic_forward lib: test result: ok. 128 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out compiler_diagnostic_forward: test result: ok. 5 passed; 0 failed; 0 ignored display_list_delta: test result: ok. 3 passed; 0 failed; 0 ignored - /tmp/flashtex-schema-venv/bin/python -m unittest tests.test_rendering_v2 Ran 24 tests in 0.039s OK Next: push this checkpoint for daniel-parent re-review of the last PARTIAL. Open questions: none. Implementation-Agent: cursor-agent cursor-grok-4.6-high-fast Commit-Executor: cursor-agent Lane-Owner: daniel-parent (mac-m5pro-dq222) Co-authored-by: Cursor <cursoragent@cursor.com> * fix440: keep text glued after ']', honour escaped commas in DocumentMetadata - optional_bracket_argument consumes exactly up to the matching ']' at brace depth 0 and rewrites any trailing tail back into the token stream (fixes ProvidesFile{foo.cfg}[2024]VISIBLE losing VISIBLE). The helper predates this PR (on main since 01fb13c); all ~25 call sites benefit. - document_metadata treats a standalone one-character Word ',', '{', '}' (i.e. control symbols) as escaped literals via placeholders while splitting top-level commas (fixes foo=hello\,world reporting 'world'). - document_metadata_after_documentclass_is_an_error now asserts this PR's exact ordering message, not just any error mentioning DocumentMetadata. Implementation-Agent: muse-spark-1.3-contributor Commit-Executor: muse-spark-1.3-contributor * compiler: fix two real DocumentMetadata/bracket-argument bugs, merge main Fixes daniel-parent's third re-review of #440: 1. `optional_bracket_argument` (parser.rs): [ and ] are not lexer-special characters, so `[2024]VISIBLE` lexes as one Word token, and the old code consumed the whole token, dropping `VISIBLE`. Now scans token-by-token for the closing `]` at brace depth 0, and rewrites any unconsumed tail back into the token stream in place. Confirmed pre-existing beyond DocumentMetadata: ~25 call sites share this helper (cite, bibitem, linebreak, footnote, newtheorem, lstlisting, ...), all fixed at the helper. Also newly correct: a `]` inside a nested `{...}` group no longer closes the bracket argument early. 2. `document_metadata` (parser.rs): a control symbol like `\,`/`\{`/`\}` lexes as its own standalone one-character Word token, while a real separator character is always embedded inside a longer Word token -- a reliable signal this fix uses to hide escaped characters behind private-use-area placeholders during the top-level comma/brace scan, restoring them afterward, so \DocumentMetadata{foo=hello\,world, lang=en} no longer reports "world" as a spurious key. 3. document_metadata_after_documentclass_is_an_error now asserts the exact ordering-error message, not any error mentioning DocumentMetadata. Merged current main and regenerated all inventory artifacts via the project scripts (not hand-merged). Verified independently, including a mutation check on fix 2 (disabling the escaped-comma placeholder fails document_metadata_escaped_comma_is_ not_a_separator as predicted; restoring passes): - cargo test --test kernel_preamble_declarations: 10 passed, 0 failed. - cargo test --test supported_latex: 8 passed, 0 failed. - Full cargo test in crates/compiler: 0 FAILED across all suites. Implementation-Agent: muse-spark-1.3-contributor (Muse Code, lane fix440v2, slice 1) Commit-Executor: daniel-muse-lead (Claude Sonnet) Reviewed-by: daniel-muse-lead (Claude Sonnet) Co-authored-by: muse-spark-1.3-contributor <muse-contributor@flashtex.invalid> * compiler: split DocumentMetadata's plain top-level commas regardless of whitespace A standalone Word(",") from the lexer was always treated as an escaped `\,`, so `\DocumentMetadata{foo=bar , lang=en}` lost `lang`: a real separator comma surrounded by spaces lexes identically to an escaped one. The lexer gives both the same TokenKind::Word variant, so distinguish them the way optional_bracket_argument already does one function away: an escaped control symbol's source span is longer than its one-character text (it includes the backslash), while a plain word's span length always equals its text length. Applied the same check to `,`, `{`, `}`. Added regression tests for the shared optional_bracket_argument bracket reader across citation, footnote, \\[<length>], theorem-head and listing option callers, proving trailing text still survives after the bracket closes. Implementation-Agent: muse-spark-1.3-contributor Commit-Executor: daniel-muse-lead (Claude Sonnet) Reviewed-by: daniel-muse-lead (Claude Sonnet) Co-authored-by: muse-spark-1.3-contributor <muse-contributor@flashtex.invalid> * compiler: document macro-comma limit, keep only real ]-glued regression tests Documented the accepted macro-produced-comma limitation (a comma from expanding a user macro carries the macro invocation's span, so the span-length check can't tell it apart from a real separator) at the span-length check site. Replaced the caller-regression tests added for optional_bracket_argument with ones that actually exercise the bug this PR fixes: text glued directly after the closing ']', not after a following required argument. The previous \cite/\footnote tests put TEXT after a required {...}, so they passed even on the pre-fix helper and proved nothing; verified against the pre-fix helper directly and kept only the ]-glued cases that fail on it (\ProvidesFile{f}[i]TEXT), since \\[<length>] and \item[<label>] already had their own tail-rewrite predating this PR. Implementation-Agent: muse-spark-1.3-contributor Commit-Executor: daniel-muse-lead (Claude Sonnet) Reviewed-by: daniel-muse-lead (Claude Sonnet) Co-authored-by: muse-spark-1.3-contributor <muse-contributor@flashtex.invalid> * compiler tests: pin text glued after \\[2pt] line-break length skip_line_break_length has its own tail-rewrite for [2pt]TEXT-style glued text, separate from optional_bracket_argument; this pins that behavior next to the sibling ]-glued coverage. Implementation-Agent: muse-spark-1.3-contributor * compiler tests: pin text glued after explicit item label item_label_argument has its own tail-rewrite for [x]TEXT-style glued text, separate from optional_bracket_argument; this pins that behavior next to the other explicit-label coverage in list_structure.rs. Implementation-Agent: muse-spark-1.3-contributor * compiler: large-document bench and fixture output-identity digests (#65) What changed: - src/bin/large_doc_bench.rs: deterministic ~300-page article (sections, labels/refs, cites + thebibliography, equation/align*, itemize/enumerate, tabular); median-of-N cold and one-character-edit timings through Session and protocol::handle_line, plus a reply digest. - src/bin/fixture_digest.rs: per-fixture SHA-256 of the clean compile dump (blocks, diagnostics, pages), the protocol reply, and a warm edited Session output, for byte-identity checks across perf changes. What was run: large document: 637761 bytes, 450 sections, 5912 blocks, 302 pages, 0 diagnostics, profile=release fixture_digest over fixtures/ and crates/compiler/tests: 273 files, two runs identical Next step: profile and fix the top hotspots. Implementation-Agent: claude-opus-5 subagent of daniel-parent Commit-Executor: daniel-parent subagent Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz * compiler: memoise Core 14 shaping, index glyph tables, lend cleveref config (#65) What changed: - layout: shaping a Core 14 face is a pure function of (face, text); the width/source-bounds/missing-glyph summary layout reads is memoised per thread (reset past 131072 entries). Every cross-reference pass used to reshape every word with a fully allocated `Shaped`. - char_table: sorted binary-search index equal to `iter().find` (first occurrence) for lm_math/newcm_math/amssymb advances and the export Symbol/WinAnsi tables; math_font walked ~440 entries per ASCII character. - layout: inline_box (every tabular entry) lends the cleveref config to the detached cursor instead of building the default name table and cloning. What was run: fixture_digest over fixtures/ + crates/compiler/tests (273 files) and the 302-page doc: identical to origin/main 36fe7ec cargo test (debug): 59 suites, passed=671 failed=0 ignored=5 cargo fmt --check: ok; clippy -D warnings: 20 pre-existing errors, none in touched code Next step: interleaved A/B timings, PR. Implementation-Agent: claude-opus-5 subagent of daniel-parent Commit-Executor: daniel-parent subagent Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz * compiler: undo whole-crate reformatting swept into the previous commit (#65) What changed: - The previous commit accidentally included a local `cargo fmt` of the whole crate (43 unrelated files). Every file outside the perf change is restored to origin/main 36fe7ec; the perf edits are re-applied without reformatting. No behaviour change relative to the previous commit. What was run: git diff 36fe7ec --stat: 10 files changed, 607 insertions(+), 42 deletions(-) fixture_digest (273 files + 302-page doc): identical to origin/main Next step: interleaved A/B timings, PR. Implementation-Agent: claude-opus-5 subagent of daniel-parent Commit-Executor: daniel-parent subagent Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz * pdf: exact route rounds colours to xcolor's 5 decimals and paints TikZ path items What changed: - v2: `pdf_number` formats an f64 as a bounded PDF number (shortest decimal rounded half away from zero, no exponent, -0 -> 0); sRGB colour components use 5 digits (pdflatex measured: RGB{20,80,170} -> 0.07843 0.31374 0.66667 rg). Replaces the exact-binary requirement that refused 0.8 and 0.07843. - v2: `path_fill` / `path_stroke` items (with clips) become q [rg RG] [clip W n] [w M d J j] path f|f*|S Q, in pgf's pdfTeX order. - exact: `M` (miter limit) joins the bounded operator set. What was run: - cargo test (crates/pdf): lib 53 passed; tests/v2 7 passed; all targets 0 failed - cargo check --tests (crates/rendering-core): ok Next step: re-pin crates/render-pipeline/vendor/pdf so `flashtex build` uses it. Implementation-Agent: claude-opus-5 subagent of daniel-parent Commit-Executor: daniel-parent subagent Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz * pdf: exact route paints alpha through pgf's /pgf@CA and /pgf@ca ExtGStates What changed: - exact: Op::StrokeAlpha / Op::FillAlpha, written `/pgf@CA<a> gs` and `/pgf@ca<a> gs`, the names and one-key dictionaries pgf's pdfTeX driver writes (measured with pdflatex 1.40). `gs` joins the bounded operator set for those names only; any other ExtGState is still refused. Validation refuses an alpha outside [0, 1] and `gs` during path construction. Each page declares the states it selects once, sorted by name, inline: `/ExtGState << /pgf@ca0.4 << /ca 0.4 >> >>`. - v2: a paint alpha below 1 is no longer an error. It is rounded like a colour component and selected right after the colour inside the item's `q … Q`: path_stroke sets CA, path_fill, rule and glyph_run set ca. - Tests: exact operator stream and resources for stroke and fill alpha, per-page dedup, refusal of other gs names, text alpha on a glyph run. What was run: - cargo test (crates/pdf): test result: ok. 53 passed; 0 failed (lib), 12 passed (tests/exact), 5 (images), 11 (navigation), 28 (render), 3 (type1), 10 passed; 0 failed (tests/v2). - cargo check --tests (crates/rendering-core): Finished. Next step: build extended/tikz-clipping-patterns with a scratch copy whose render-pipeline/vendor/pdf is this crate. Implementation-Agent: claude-opus-5 subagent of daniel-parent Commit-Executor: daniel-parent subagent Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz * compiler: ignored large-document timing test; bench reports first compile (#65) What changed: - tests/large_document_timing.rs: #[ignore] timing test sharing the bench's 302-page generator; asserts >= 300 pages, no diagnostics, and warm edit == clean compile. - large_doc_bench prints the first compile in the process (empty memo). What was run: cargo test --release --test large_document_timing -- --ignored: 1 passed (302 pages) cargo test (debug): 60 suites, passed=671 failed=0 ignored=6 Next step: A/B timings, PR. Implementation-Agent: claude-opus-5 subagent of daniel-parent Commit-Executor: daniel-parent subagent Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz * compiler: stop copying placed text, lend the session output, serialise pages once (#65) What changed: - layout: clean layout and every cross-reference pass call a new non-collecting render_block; only incremental reuse collects placed items. - layout: the shaping memo hashes a word once per hit (get, not contains_key plus index). - incremental: Session::compile_project_borrowed lends the retained output; compile_project_with clones from it as before. protocol uses the borrow. - protocol: bound_pages serialises each page once and joins the result instead of serialising, cloning and serialising again. - parser: parse_stream handles space, comment and word tokens borrowed before cloning the token. What was run: fixture_digest (273 fixtures + 302-page doc) vs #535 head 3c2b0e1: IDENTICAL large_doc_bench reply sha256 51e4d9a9dc3f0ac0aa8cc90267fb8a73664650d2ebf246bcbb2958ad1cba9747 (same as base) large_doc_bench 5 (load ~44): cold session 50.9 -> 40.6 ms, cold protocol 68.7 -> 46.7, edit protocol 69.9 -> 50.0 Next step: full test run, interleaved median-of-5 timings, PR stacked on #535. Implementation-Agent: claude-opus-5 subagent of daniel-parent Commit-Executor: daniel-parent subagent Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz * pdf: support TikZ tiling patterns What changed: - Add deterministic PatternType 1 tiling resources and typed /Pattern cs, scn operators to the exact PDF route. - Generate the eight requested PGF cells with pattern color, accept the v2 path_fill pattern extension, and cover PaintType 2 RGB selection. - Add operator, resource, parser, deterministic-output, structure-check, and Ghostscript-backed sample verification coverage. What was run: - CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-pattern CARGO_BUILD_JOBS=4 cargo check --manifest-path crates/pdf/Cargo.toml - CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-pattern CARGO_BUILD_JOBS=4 cargo test --manifest-path crates/pdf/Cargo.toml --lib --tests - CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-pattern CARGO_BUILD_JOBS=4 cargo test --manifest-path crates/vector-graphics/Cargo.toml --lib tikz::tests::unsupported_input_is_reported_not_dropped - /opt/homebrew/bin/gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m -r144 on /private/tmp/flashtex-pattern-sample.pdf Next step: - Carry pattern name/color state through vector-graphics, render-pipeline display items, and display-list JSON so the live TikZ corpus can populate the new PDF contract. Implementation-Agent: codex gpt-5.6-luna (max) Commit-Executor: codex (this session) Lane-Owner: daniel-parent (mac-m5pro-dq222) * compiler: stop dropping six amsfonts symbols on a false premise gen_amssymb.py carried SKIP = {angle, hbar, mho, sqsubset, sqsupset, rightleftharpoons}, justified as "kernel commands amsfonts only redefines keep their kernel glyphs". That was wrong twice over (checked against pdfTeX 3.141592653-2.6-1.40.27, TeX Live 2025): - \mho, \sqsubset, \sqsupset are not kernel commands at all: latex.ltx makes them \not@base stubs and amsfonts.sty 99-101 is what provides them. FlashTeX diagnosed them "not supported in math mode" even with amssymb loaded. - \angle, \hbar, \rightleftharpoons are kernel composites that amsfonts replaces with one msam/msbm glyph of different metrics (\angle 6.37344pt -> 7.22223pt, \hbar 5.76172pt -> 5.40280pt at 10pt). With the package loaded, \angle/\hbar fell through to bare COMMAND_GLYPHS rows at Latin Modern advances matching neither pdflatex answer, and \rightleftharpoons was "not supported". Removing SKIP lets the generator emit all six with the class and slot amsfonts declares (provider Amsfonts, so \usepackage{amsfonts} alone suffices, matching the .sty). \hbar needs a MANUAL entry: amsfonts puts it on msbm "7E, the slot amssymb also gives \hslash, and unicode-math names that character only as \hslash. Since the original draft, main gained the package gate (543bde5) with kernel-width arms for unloaded \angle/\hbar; those keep working and the loaded case now takes the declared msam/msbm rows. \rightleftharpoons - whose comment said "no row at all, so nothing to gate yet" - gets the same treatment: a gated kernel arm (Rel, U+21CC, 1.000002em, the measured 10.00002pt \mathpalette stack) so an unloaded document does not regress to a missing-package error for a command base LaTeX2e does define. scripts/amssymb_api.rs.in is caught up with 84ff3c4's hand-edit of the generated file (CharTable index instead of linear find), so `python3 scripts/gen_amssymb.py > src/amssymb.rs` is byte-identical again; verified before this change the generator reproduced main's table except for that drift, and after it the diff is exactly the six rows plus their LM advances. Regenerated docs/user/compiler.md, supported/supported-latex.json, supported/coverage.md and the Mac bundled copy via scripts/render_supported_latex.sh. Tests: tests/amssymb_skip.rs reconstructs pdfTeX's \show mathchars ("340A "045C "057E "3440 "3441 "0566) from the generated class, font and slot, and pins the msam/msbm widths against the pdflatex \hbox measurements. angle_and_hbar_keep_the_kernel_composite_without_amsfonts extended to the loaded-case msam/msbm advances and to \rightleftharpoons. Salvaged from PR #212 (engine/amssymb-generator-skip), rebuilt against current main (post-543bde5c package gating). Implementation-Agent: fable-salvage Commit-Executor: fable-salvage (direct; Cursor usage limit) * compiler: regenerate supported-latex docs on the merged tree docs/user/compiler.md (generated) conflicted with the #641 integration batch; the merge took main's copy and this regenerates it via scripts/render_supported_latex.sh on the merged tree, restoring the six amssymb rows on top of main's new inventory (555 -> 559 math entries). supported-latex.json and the Mac bundled copy were already correct; sync-supported-latex.sh --check is byte-identical (704a3974fe88). gen_amssymb.py re-verified byte-identical against src/amssymb.rs after the merge. Gates re-run on the merged tree: cargo test --release --no-run clean; --lib 380 passed 0 failed; amssymb_skip 1 passed; supported_latex 8 passed; lm_math_binding 6 passed. Implementation-Agent: fable-salvage Commit-Executor: fable-salvage (direct; Cursor usage limit) * integration fix: #579's borrowed fast path passes control_symbol_kern's post-#576 arguments #579 predates #576 (kern control symbols measured by definition bytes); its new parse_stream_body fast path called the old 3-argument form. Pass maps_to_invocation and definition from the token entry, as the slow path does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu * integration: regenerate supported-latex artefacts (render_supported_latex.sh; sync-supported-latex.sh) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu * integration fix: #579's fast path must not shadow main's tabbing control arm #642 added a \\=/\\>/\\< tabbing arm to parse_stream_body's match that runs before the control_symbol_kern arm. #579's borrowed fast path, written before #642, matched those words first and typeset them as text, so tabbing produced 0 tab stops instead of 2 (5 failures in crates/compiler/tests/tabbing.rs). Mirror the slow path's guard. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu * integration fix: perf-bench names #358's new diagnostics capability main's crates/perf-bench (#206) constructs v1::Capabilities literally; #358 adds the diagnostics field, so the bench stopped compiling (E0063) and the engine performance job failed at Build. Pass diagnostics: false, matching the bench's other opt-in capabilities. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu * integration fix: #294's page window and #358's diagnostics wire meet #294 replaced Page's items field with PageContent + an accessor, added DisplayList::{window, document_features}, and added tests/page_window.rs; #358 adds Wire::diagnostics. Neither sees the other on its own branch: - delta.rs/display.rs test helpers built Page and DisplayList literally (E0560, E0063 x2) -> Page::resident(..) and the two new fields as None - tests/page_window.rs's const WIRE misses diagnostics (E0063) - tests/math_symbols.rs took Page::items as a field (E0615) -- broken on main itself, fixed separately in #664 and carried here cargo test --release --no-run on crates/render-pipeline: 0 errors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu * integration fix: #579's fast path must not swallow an \obeylines newline Third instance of the same combination bug, found by re-running the full suite after the rebase rather than assuming it was mechanical. #593 (landed on main via #649) makes a source newline end the line under \obeylines: the lexer folds a lone newline into TokenKind::Space, and parse_stream_body's Space arm turns it into an Inline::LineBreak. #579's borrowed fast path, written before #593 existed, matched Space first and skipped it, so crates/compiler/tests/obeylines.rs went 7 passing -> 2 passing / 5 failing. Take the fast path for a Space only when \obeylines is not in force; a Comment is still always skipped. Under \obeylines spaces fall through to the slow path, which is where the newline is read from the token's own source bytes. cargo test --release --test obeylines: 7 passed, 0 failed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xd5Hmwh5GHNTiAmHUJ1MZu --------- Co-authored-by: d-q222 <279808976+d-q222@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: muse-spark-1.3-contributor <muse-contributor@flashtex.invalid> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…e consumer What changed: main took #358's producer in via the integration commit 83285e3 ("integration: compiler + pdf + v2 queue (#579, #640, #440, #621, #358)"), so every Rust/protocol/docs/python file this branch carried is now already on main byte-for-byte. `git diff MERGE_HEAD -- crates/ protocol/ docs/ tests/ tools/` is down to the one producer-side piece main does NOT have: crates/document-runtime/src/lib.rs's capability allowlist. Conflicts and how they were resolved: - crates/render-pipeline/src/delta.rs, src/display.rs: took main. The branch's test helpers predate FT-070 (#294), which added `window` and `document_features` to DisplayList and turned `Page` into `Page::resident`. main's copies of `diag_list` / `header_only_diag_list` are the same tests with the new struct shape, and they pin the same Appendix A vectors (c4e7c712… on, e554935e… off). - apps/mac/Sources/FlashTeXMac/DisplayListDelta.swift: both sides changed `installed(from:pageBytes:lineBytes:)`. Kept main's windowed-frame guard and its doc comment, and re-applied this branch's `diagnosticsCapability:` flag, which is what gates `suggestion` into the header digest. Kept from this branch (nothing main provides): - crates/document-runtime allowlist: `display-list-v2-diagnostics` accepted only alongside `display-list-v2`, with the pairing/unknown-cap tests. - the whole Mac consumer: RenderingV2/RenderingV2Fast decode the optional `suggestion` (and tolerate labels/notes/help, which the proposal defines and main's producer documents as not yet on the wire), ShellModel.producerDiagnostics maps the live v2 frame through `asRuntimeV1` when compile_result.diagnostics is empty, and the delta digest hashes `suggestion` only when the capability was negotiated. Also dropped a stray blank line the branch had added to EditorDiagnostics.swift. What was run: - CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-merge363 CARGO_BUILD_JOBS=4 cargo test --manifest-path crates/document-runtime/Cargo.toml lib: test result: ok. 18 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out chunks: test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out display_sibling: test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out session: test result: ok. 19 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out - apps/mac: swift build -> Build complete! (19.60 sec) - apps/mac: swift test --filter 'RenderingV2|PreviewV2|EditorDiagnostics|ProblemsPanel|DisplayListDelta|V2Image' Executed 98 tests, with 12 tests skipped and 0 failures (0 unexpected) in 8.688 seconds Next step: push fast-forward to the PR branch and let CI run the full mac suite. Implementation-Agent: claude-opus-5 subagent of daniel-parent Commit-Executor: daniel-parent subagent Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…ers (unbreaks main) What changed: #689 (a7a90fc) added testPageReadoutCountsTheDisplayListNotTheElidedV1Pages to PreviewV2ParityTests, but `model()` and `load(_:_:)` are private members of PreviewV2ShellTests. The FlashTeXMacTests target therefore does not compile on main, so the whole apps/mac suite is red: PreviewV2Tests.swift:807:25: error: use of local variable 'model' before its declaration PreviewV2Tests.swift:809:9: error: static member 'load' cannot be used on instance of type 'PreviewV2ParityTests' PreviewV2Tests.swift:809:13: error: argument passed to call that takes no arguments error: Build failed The test is moved verbatim into PreviewV2ShellTests, which already has both helpers and `Self.fixtures`, and is already @mainactor at class level. No assertion changed. This merge cannot be validated at all without it. What was run: - apps/mac: swift build --build-tests -> Build complete! (12.09 sec) - apps/mac: swift test --filter PreviewV2 Test Suite 'PreviewV2ShellTests' passed Executed 9 tests, with 0 failures (0 unexpected) in 0.214 seconds - Baseline check that the remaining apps/mac failures are main's, not this branch's: the same relocation applied to a detached origin/main worktree (dbe3cac) gives an identical failure set -- origin/main: Executed 52 tests, with 1 test skipped and 86 failures (0 unexpected) this branch: Executed 52 tests, with 1 test skipped and 86 failures (0 unexpected) (swift test --filter 'SignatureHelpTests|SnippetTests|EditorChangeEnvironmentTests|EditorFirstFocusTests') Next step: the 86 SignatureHelp/Snippet/EditorChangeEnvironment/EditorFirstFocus failures and the Completion-family abort are pre-existing on main and belong to another lane; they are not touched here. Implementation-Agent: claude-opus-5 subagent of daniel-parent Commit-Executor: daniel-parent subagent Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
|
daniel-parent subagent — conflict resolved by merge (no rebase, no force-push). What drifted#358's producer already landed, not as #358 (which is CLOSED with no merge commit) but folded into That one file is the only producer-side piece main does not have: the Three conflicts:
Also dropped a stray blank line this branch had added to The consumer field shape is unchanged by the drift. main's producer serialises #363 is not redundant. The Mac consumer half is entirely absent from main; only the Rust producer landed. One thing that had to be fixed to test at allmain's Commit Test results
Per-suite, the ones this PR owns: Broad run (the Completion family reliably aborts the whole Those 86 are ( Not done
🤖 Generated with Claude Code |
|
Heads-up from daniel-parent: the PreviewV2 test move in While this lane was validating the merge it hit main's Integration lane: prefer #698 for the unbreak, since it is single-purpose and its body carries the before/after build output. If #698 lands first, this branch's copy of the move should drop out as an identical change or resolve trivially; if it does not resolve cleanly, take main's side. I am deliberately not rewriting history here to remove it — this branch is already pushed and reviewed, and no force-pushes. Everything else in this PR is its own: after merging main the Rust/protocol/docs diff collapsed to one file, +47 lines (the — daniel-parent |
daniel-parent (Cursor Grok lane, reviewed by daniel-parent plus an independent read-only Codex review). This is the Mac consumer of #358's
display-list-v2-diagnosticscapability. Merge after #358: this branch contains #358's producer files, so the diff shrinks to the Mac and runtime side once #358 lands.What changes
document-runtimeallowlist: it acceptsdisplay-list-v2-diagnosticsonly together withdisplay-list-v2. It still rejects the capability alone, and unknown capabilities, with tests.PreviewV2Viewasks for the capability alongsidedisplay-list-v2. When the producer declines it (including render-pipeline: opt-in display-list-v2-diagnostics capability carries suggestion on the v2 wire #358's whole-family decline on reply overflow), the preview logs that and carries on.RenderingV2andRenderingV2Fastboth decode an optionalsuggestion;""becomes nil in both readers, and unknown keys are still skipped.ShellModel.producerDiagnostics):compile_result.diagnosticswhen that list is non-empty.asRuntimeV1.EditorDiagnosticsand mac editor: Tab accepts the fix at the caret (#277) #445'sShellModel.caretFix, so Tab accepts them. There's no second accept path.DisplayListDelta):suggestionis hashed only when the capability was negotiated, per render-pipeline: opt-in display-list-v2-diagnostics capability carries suggestion on the v2 wire #358's Appendix A, with Swift golden tests pinned to the same digests as Rust and Python (c4e7c712…on,e554935e…off).Review round
An independent review found two issues, fixed test first at
ef4574d1→5fae83c0:asRuntimeV1was test-only. Before the fix,problemsListreturned 0 where 1 was expected.c4e7c712…wheree554935e…was expected.It also added tests for empty-suggestion handling in both readers and for decline logging.
Tests
cargo test --manifest-path crates/document-runtime/Cargo.toml: every result ok (lib 18, chunks 6, display_sibling 10, session 19).swift test --filter 'RenderingV2|PreviewV2|EditorDiagnostics|ProblemsPanel|DisplayListDelta|CommandTable|HostedWindowSupport':Executed 109 tests, with 11 tests skipped and 0 failures.swift test --skip NearbyInterfaceTests --skip NearbyLANInterfaceTests:Executed 1224 tests, with 135 tests skipped and 2 failures. Both failures areRustPDFExportPipeTests30 s load timeouts;--filter RustPDFExportPipeTestsalone givesExecuted 4 tests, with 0 failures.Overlap check
RenderingV2are untouched.Not done
labels,notesandhelpover v2 (see render-pipeline: opt-in display-list-v2-diagnostics capability carries suggestion on the v2 wire #358).🤖 Generated with Claude Code
https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz