Skip to content

re-pin readiness: pipeline compiles against the queued compiler/pdf/math-layout (runbook for the integration lane) - #631

Closed
d-q222 wants to merge 218 commits into
mainfrom
agent/daniel-parent/repin-readiness-2
Closed

d-q222 wants to merge 218 commits into
mainfrom
agent/daniel-parent/repin-readiness-2

Conversation

@d-q222

@d-q222 d-q222 commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

What

The pipeline side of the vendor re-pin for daniel-parent's queue, made ready ahead of time, plus a runbook (docs/integration/repin-runbook.md) so the integration lane can do the re-pin as a mechanical copy.

vendor/ is untouched. All re-pin validation ran in a scratch worktree that was never committed.

Why

Corpus sweep 2 found that swapping the preview's crates into render-pipeline/vendor/ did not build:

  • the bibliography mirror was missing;
  • adapter.rs/typeset.rs had 13 compile errors.

The drafts that fix those errors sat on separate branches behind features. This branch combines them and proves the result builds and passes.

Features to flip at re-pin

Required, in default: linebreak-skip, amsmath-sideset, compiler-text-run.

Optional:

  • math-font-kerns builds and its own test passes, but it was not measured corpus-wide.
  • math-glyph-spans builds.
  • compiler-text-nucleus is dead.

Overlap check

Test results

Compile errors in crates/render-pipeline/src, against the re-pinned vendor:

  • preview src: 13
  • after the merges (default features): 8
  • with the three features on: 1
  • after 58118db5: 0

Scratch re-pin (vendor crates from c47e1452, CARGO_BUILD_JOBS=4, release):

  • render-pipeline cargo test --release --no-fail-fast: all binaries ok, 466 passed, 0 failed, 3 ignored. One of the ignored, coloneqq_decomposes_like_mathtools, passes un-ignored.
    • page_para_control: test result: ok. 19 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s
    • display_placement, toc_oracle, tabular_oracle: test result: ok. 1 passed; 0 failed
    • amsmath_sideset: test result: ok. 3 passed; 0 failed
  • flashtex-cli cargo test --release: ok. 31 passed; 0 failed and ok. 26 passed; 0 failed; 1 ignored
  • amsmath oracle: TOTAL 59/59 within 0.5 bp
  • amssymb oracle: TOTAL 38/39 within 0.5 bp (32-braces-narrow, same on main)
  • tabular oracle: TOTAL 128/128 (words 0.5 bp, rules 0.1 bp)
  • display-placement oracle: TOTAL 47/48 within 0.5 bp (15-align-tag-notag-eqref, same on main; the new 37–48 all pass)

Not done

🤖 Generated with Claude Code

https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz

d-q222 and others added 30 commits September 13, 2026 21:26
…art 2)

`flashtex check`/`build`/`watch` print each diagnostic as a header, a
`--> file:line:col` pointer, the source line(s) under a line-number
gutter, carets under the byte span and a wrapped `= recovery:` line.

- `--diagnostics=full|short|json`: full is the new form; short is the
  unchanged one-line `line_text`; json is `--json`. The default is full
  when stderr is a terminal and short otherwise, so piped output and
  scripts see exactly what they did before.
- `--color=auto|always|never`; auto is on for a terminal unless NO_COLOR.
- Uses only the fields a diagnostic already has (code, message, span,
  recovery). Structured labels/help from #277 part (1) can be added to
  the renderer without changing this path.
- Spans: tabs expanded so carets line up, multi-byte text, empty spans
  and spans past the end of the text get one caret, spans longer than
  four lines show the first two and the last.

Tests: 7 renderer unit tests, one end-to-end test for the flags. The
pre-existing multi_file_project_resolves_inputs_from_the_project_root
failure reproduces on unmodified main 9bd4b02 and is not touched here.

Implementation-Agent: daniel-parent (mac-m5pro-dq222)
Commit-Executor: git, direct
Co-authored-by: d-q222 <279808976+d-q222@users.noreply.github.com>
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>
…g-forward' into agent/daniel-parent/cli-fix

Stacking base for an overnight daniel-parent lane (#277); announced on #2.

Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…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 six cli.rs tests that pin GH-277 acceptance: rustc-style help for
\alpah, JSON suggestion, check --fix rewrite, --dry-run diff, suggestion
in an \input file, and --help mentioning --fix/--dry-run. Overlap and
hash-changed refusal will land with the apply module (need synthetic
edits; the compiler does not emit overlapping spans for \alpah).

Control (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-clifix, base 5b7a88b):
- unittests: test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
- --test cli: test result: FAILED. 12 passed; 1 failed (multi_file_project_resolves_inputs_from_the_project_root, fixture-dependent / PR #308)

New tests (same target dir):
- typo_alpah_full_output_has_a_help_block: FAILED (no "= help: did you mean `\alpha`?")
- typo_alpah_json_includes_suggestion: FAILED (suggestion key absent, left None)
- check_fix_rewrites_alpah_to_alpha / dry_run / input file: FAILED (exit 2, unknown option "--fix")
- check_help_mentions_fix_and_dry_run: FAILED (--help has no --fix)

Next: copy suggestion onto the CLI Diagnostic next to code.clone(), then
render the help block / short parenthetical / JSON key, then check --fix.

Open questions: none in-scope. Overlap/hash/symlink tests belong in the
apply module; they cannot be driven from the compiler's \alpah diagnostic.

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>
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>
CLI Diagnostic copies pipeline suggestion next to code.clone(). Full
renderer prints `= help: did you mean \`\\alpha\`?` plus a `+` gutter over
the replaced line; short appends `(did you mean \alpha?)`; JSON emits
`suggestion` only when set. `check --fix [--dry-run]` applies non-
overlapping back-to-front byte edits, refuses changed files (SHA-256),
symlinks and paths outside the project root, writes atomically with mode
preserved, then re-checks. Overlap/hash/symlink/mode covered by fix.rs
unit tests (the compiler does not emit overlapping \alpah spans).

Ran (CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-clifix):
- --bin flashtex: test result: ok. 21 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
- full cargo test --manifest-path crates/flashtex-cli/Cargo.toml:
  unittests ok. 21 passed; --test cli FAILED. 18 passed; 1 failed
  (multi_file_project_resolves_inputs_from_the_project_root — same
  pre-existing control failure; all six new GH-277 tests passed)

Next: no in-scope follow-up; lane is ready for daniel-parent review (no PR).

Open questions: none. Known #308 fixture failure left untouched.

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>
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>
…g it

Review fix on the GH-277-cli-fix lane: collect_edits used
`end_byte.unwrap_or(start)`, so a diagnostic with a start but no end (or an
empty span) became an insertion at `start`. A compiler suggestion replaces
its span, so both ends are now required and the span must be non-empty.

cargo test -p flashtex-cli: bin 22/0 (+1: a_suggestion_without_a_full_span_is_not_turned_into_an_insertion);
tests/cli 18 passed, 1 failed: multi_file_project_resolves_inputs_from_the_project_root,
the same fixture-dependent failure as on the base 5b7a88b (replaced by #308).

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
…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
…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
…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
What changed:
- Added compiler regression tests for nested math in tags/text, text styles, unsupported commands, tag glue, and eqref labels.
- Added math-layout width/style-size regression tests.

What was run:
- test result: FAIL (expected): CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-tag cargo test --manifest-path crates/compiler/Cargo.toml --test text_runs
- test result: FAIL (expected): CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-tag cargo test --manifest-path crates/math-layout/Cargo.toml --test text_runs

Next step:
- Add the minimal text-run IR and parser/layout support.

Implementation-Agent: codex gpt-5.6-luna (max)

Commit-Executor: codex (this session)

Lane-Owner: daniel-parent (mac-m5pro-dq222)
Merged origin/main (2cf635b). #303 and #354 are on main; this lane no
longer needs its stacked pipeline-diag-forward display.rs code.

Conflict resolution:
- crates/flashtex-cli/src/main.rs: kept --fix/--dry-run and main's
  version_string (#420), collapse_repeats, and watch screen-clear. The
  post-fix re-check also uses collapse_repeats.
- crates/flashtex-cli/src/report.rs (add/add): kept main's structure
  (collapse_repeats) and ported this lane's `= help:` / `+` gutter
  suggestion rendering. Fold equality also compares suggestion.
- crates/render-pipeline/src/display.rs: took main's file. #354 already
  forwards compiler `code` exactly and runtime-v1 `suggestion`. This
  lane's default_code re-derivation was dropped (CLI reads suggestion
  from the pipeline Diagnostic; it does not need that re-derivation).

--fix still has no ambiguity policy. None existed; PR #444 is the
unique-closest-match rule, so the CLI applies whatever suggestion the
compiler emitted.

compile.rs auto-merged: suggestion copy plus main's missing-include
dedup. Tests in tests/cli.rs stayed at the end of the file.

Ran:
- CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-clifix cargo test --manifest-path crates/flashtex-cli/Cargo.toml
  unittests: test result: ok. 24 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
  tests/cli.rs: test result: ok. 20 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
  (multi_file_project_resolves_inputs_from_the_project_root now passes; #308 landed on main)
- cargo test --manifest-path crates/render-pipeline/Cargo.toml --lib
  test result: ok. 110 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

Next: push this merge to origin/agent/daniel-parent/cli-fix.

Open questions: none in-scope. Ambiguous suggestions are compiler-side (#444, still open).

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>
…ment

Conflict in crates/render-pipeline/src/display.rs: one hunk, the
Diagnostic.suggestion doc-comment. Kept HEAD's capability-gated wording
(serialised on display-list-v2 only when Wire.diagnostics is set). Took
main's #354 from_compiler (exact compiler code, in-memory suggestion) as
the auto-merged base; Wire.diagnostics / diagnostic_json_wire /
write_diagnostics gating came through from this branch.

Ran: git fetch origin && git merge origin/main. Tests not yet run.

Next: add a negotiated-case integration test next to #354's
"v2 omits suggestion" test; run render-pipeline lib + diagnostic/delta
tests; confirm remaining diff vs origin/main is only the capability.

Open questions: none on the conflict. document-runtime allowlist is out
of scope (#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>
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>
Adds the --fix safety matrix. Two tests fail on 6abfbec, as intended:

- a_symlinked_parent_directory_is_refused: with root/link -> root/src
  and diagnostic path link/main.tex, apply reports issues=1, skipped=[],
  and rewrites src/main.tex. resolve_writable only lstats the leaf and
  canonicalises the parent, so the temp+rename follows the directory
  symlink.
- a_span_on_a_utf8_multibyte_boundary_is_refused: start=1,end=3 on
  éé (c3 a9 c3 a9) with an empty replacement leaves a valid é;
  from_utf8 accepts it and the file is written.

The rest of the matrix already passes: leaf symlink, ../ and absolute
paths, CRLF preservation, back-to-front non-overlapping edits,
overlapping skips, dry-run directory listing, JSON omitting the
suggestion key (extracted diagnostic_json so the assertion is
unconditional).

Ran:
- CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-clifix cargo test --manifest-path crates/flashtex-cli/Cargo.toml --bin flashtex -- a_symlinked_parent_directory_is_refused a_span_on_a_utf8_multibyte_boundary_is_refused
  test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 29 filtered out
- same binary filter for the other new tests
  test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 24 filtered out

Next: walk every path component with symlink_metadata and refuse
non-char-boundary spans before splicing.

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>
resolve_writable walked only the leaf and canonicalised the parent, so a
directory symlink (root/link -> root/src, diagnostic link/main.tex) still
took the temp+rename to src/main.tex. It now lstats every component from
the project root to the file and returns Skip::Symlink if any is a
symlink. `..` and absolute paths are still rejected before the walk.
The atomic temp+rename stays in that verified real directory.

apply_edits_back_to_front also refuses a span whose start or end is not
a UTF-8 char boundary, even when the spliced bytes happen to be valid
UTF-8.

Ran:
- CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-clifix cargo test --manifest-path crates/flashtex-cli/Cargo.toml --bin flashtex -- a_symlinked_parent_directory_is_refused a_span_on_a_utf8_multibyte_boundary_is_refused a_symlink_target a_parent_escape crlf_bytes non_overlapping overlapping dry_run_creates json_omits a_file_changed
  test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 21 filtered out

The two tests that failed on 83211e8 now pass.

Next: git fetch origin && git merge origin/main, then an end-to-end
test that an ambiguous typo (#444: igl/lph/igm) gets no suggestion and
--fix writes nothing, while \\alpah is still fixed.

Open questions: CLI links render-pipeline/vendor/compiler, not
crates/compiler. If origin/main's #444 did not re-pin the vendor, the
e2e test is a vendor-re-pin (out of scope) and will be reported.

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>
…orrection and nested-list closing skips (display-placement 35/36))

Conflicts resolved; see docs/integration/daniel-parent-preview.md.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…k and phi extract as the right Unicode)

Conflicts resolved; see docs/integration/daniel-parent-preview.md.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…cross-references (for Commander decision))

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…put, and flashtex check --fix [--dry-run] with symlink-safe atomic writes)

Conflicts resolved; see docs/integration/daniel-parent-preview.md.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…-v2-diagnostics capability carries suggestion on the v2 wire)

Conflicts resolved; see docs/integration/daniel-parent-preview.md.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…tics — v2 suggestions reach Problems and Tab-to-fix (after #358))

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
What changed:
- docs/integration/daniel-parent-preview.md: recommended merge order for the
  43 merged daniel-parent PRs, the 16 conflict resolutions, combined test
  results, the two failures caused by the combination, and the vendor re-pins.

What was run:
- compiler (debug): 747 passed, 1 failed (robustness stack overflow, debug only; passes in --release), 7 ignored
- tex-expansion: 75 passed; project-files: 97 passed; pdf: 123 passed; math-layout: 74 passed
- render-pipeline --release: 439 passed, 1 failed (math_symbols common_math_glyph_runs_use_semantic_unicode, #536 x #597), 3 ignored

Next step: the integration lane merges the individual PRs in the recorded order.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
What changed:
- `\addbibresource` and `\printbibliography` move out of `P::command` into
  `#[inline(never)]` helpers (`add_bib_resource`, `print_bibliography`);
  `biblatex_cite` is `#[inline(never)]` too.
- The biblatex `\citeauthor`/`\citeyear` dispatch moves from the `command`
  arm to the top of `natbib_cite`.
- Why: `P::command` is on the stack once per nested sub-parse. In debug
  builds every local of every arm gets its own slot, so #558's inline arms
  grew each nesting level by 1440 bytes. Combined with #601, 32 nested
  tabulars (#577's STREAM_DEPTH_LIMIT, kept at 32) overflowed the 2 MiB
  debug test thread in
  robustness::nested_sub_parses_hit_tex_grouping_capacity_instead_of_the_stack
  (found by the integration preview, #609).

What was run:
- Stack per nesting level (debug), measured with a scratch probe that prints
  the stack address in `parse_stream` at each depth (not committed):
  | construct | #601 | #601+#558 before | #601+#558 after |
  | tabular   | 57232 | 58672 | 57360 |
  | footnote  | 31424 | 32864 | 31552 |
  | colorbox  | 30928 | 32368 | 31056 |
  | rotatebox | 32048 | 33488 | 32176 |
  | uline     | 30336 | 31776 | 30464 |
- #601 + #558 (merge), debug, CARGO_BUILD_JOBS=4:
  cargo test --test robustness --test biblatex
  biblatex: test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
  robustness: test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 41.06s
- This branch, debug:
  biblatex: test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
  robustness: test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 40.81s
  natbib: test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
  --lib cite: test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 331 filtered out; finished in 0.00s

Next step: merge into the integration preview (#609) and rerun there.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…er arms out of the recursive command frame)

What changed:
- Merges agent/daniel-parent/biblatex-basic at 16dd331 (no rebase, no conflicts).

What was run (this merge, CARGO_BUILD_JOBS=4):
- crates/compiler, debug: cargo test --locked --test robustness --test biblatex
  biblatex: test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
  robustness: test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 42.11s
- crates/render-pipeline, release: cargo test --release --locked --test math_symbols --test long_arrows
  long_arrows: test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.08s
  math_symbols: test result: FAILED. 15 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.05s
  (common_math_glyph_runs_use_semantic_unicode, the #536/#597 conflict, still open)

Next step: the #536/#597 long-arrow extraction decision.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…g-arrow blocker

What changed:
- Failure 1 (debug stack overflow): fixed on #558 (16dd331), with the measured per-level stack before/after, and a margin warning. This preview's frame is 65136 bytes per nested tabular.
- Failure 2 (#536/#597 long arrows): why the decided fix is blocked as specified. Empty-text clusters are invalid in display-list-v2, the join's pieces are in different runs, and the exact PDF route's per-glyph-id ToUnicode made real `=`/`−`/`→` extract as the arrow in a prototype.

What was run:
- Documentation only; the test lines are in the preceding merge commit.

Next step: the long-arrow decision from daniel-parent.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
What changed:
- The long arrows move out of common_math_glyph_runs_use_semantic_unicode
  into long_arrows_extract_as_their_drawn_pieces (option C from #536).
- A two-glyph join (#536's drawing) must extract as `=⇒` / `−→`, matching
  pdfTeX's own PDF (`x =⇒y −→z`, pdflatex + PyMuPDF). While main still draws
  one Latin Modern Math glyph, the text is the single `⟹` / `⟶`.
- A comment records that one `⟹` for two drawn glyphs needs PDF /ActualText
  marked content, a future crates/pdf change outside this PR.

What was run:
- math_symbols (debug): test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.46s

Next step:
- Merge into agent/daniel-parent/integration-preview and rerun math_symbols there.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…xtract as their drawn join pieces)

What changed:
- Merged origin/agent/daniel-parent/pdf-math-tounicode (5bf6d57) with --no-ff; no conflicts.
- Notes: failure 2 (math_symbols long arrows) is recorded as resolved by option C.

What was run:
- math_symbols (debug): test result: ok. 17 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.41s

Next step:
- GH-PARSER-STACK-FRAME for the debug stack margin warning.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…trol from the compiler's penalty, discretionary and parameter nodes)

What changed:
- Merged refs/review/pr-569 (agent/daniel-parent/page-para-control-pipeline) with --no-ff onto the integration preview.
- adapter.rs: the preview (aaaac95) moved the trailing page-style/mark command loop into the unit loop; kept that move and #569's `(page_starts, double_page_starts)` from `clear_page_blocks`.
- incremental.rs: kept #569's Penalty/PagePenalty/Discretionary hash arms and the preview's `Item::Quad { em, style }` arm.
- style.rs: `Stylesheet` keeps both the preview's `input` and #569's `hyphenation`.

What was run:
- Not built here: the committed vendor/ predates the compiler API #569 needs. The scratch re-pin build follows in this branch.

Next step:
- Merge #584.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…arpage float flush, \flushbottom after \pagebreak, \nobreakdash)

What changed:
- Merged refs/review/pr-584 (agent/daniel-parent/page-control-followups) with --no-ff.
- adapter.rs: the preview's unit loop holds `next: Option<Unit>` (aaaac95: a float-only chapter still clears its page). Ported #584's forced-penalty eject check (non-paragraph unit with `penalty_before <= EJECT_PENALTY`) onto that option shape; everything else kept from the preview.

What was run:
- Not built here (committed vendor/ predates the needed compiler API); the scratch re-pin build follows.

Next step:
- Merge #599.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…reak, \pagebreak\section under \flushbottom, \enlargethispage with floats and * squeeze)

What changed:
- Merged refs/review/pr-599 (agent/daniel-parent/page-control-3) with --no-ff; no conflicts.

What was run:
- Not built here (committed vendor/ predates the needed compiler API); the scratch re-pin build follows.

Next step:
- Merge #582.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…ath-layout left scripts)

What changed:
- Merged refs/review/pr-582 (agent/daniel-parent/sideset-pipeline) with --no-ff; no conflicts. Adds the off-by-default `amsmath-sideset` feature.

What was run:
- Not built here (committed vendor/ predates the needed math-layout API); the scratch re-pin build follows.

Next step:
- Merge #585.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…smath does)

What changed:
- Merged refs/review/pr-585 (agent/daniel-parent/tag-placement-pipeline) with --no-ff. It also carries its compiler commit 1b6f03f (a \tag in an align/gather/multline row replaces its number).
- Cargo.toml: kept the preview's `math-font-kerns` feature and #585's `compiler-text-run`.
- incremental.rs `hash_math`/`shift_math`, typeset.rs `math_grids`/`math_glue_em`/`math_approximations`: kept #582's `SideSet` arms, then #585's `TextRun` arms (hash tag 17 vs 18, as #585 anticipated).
- tests/display_placement.rs module doc: kept the preview's text (17 and 20 pass there) and appended #585's `compiler-text-run` paragraph.

What was run:
- Not built here (committed vendor/ predates the needed compiler/math-layout API); the scratch re-pin build follows.

Next step:
- Scratch re-pin build.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
What changed:
- tools/visual-oracle/rank.py `norm` folds U+2212 MINUS SIGN into U+002D
  before alignment. pdfTeX's own PDFs extract a math minus as U+2212
  (PyMuPDF on pdflatex's 19-vmatrix.pdf: "= ad −bc"; 28-xrightarrow.pdf:
  "f−→B", "h←−"), which is what this branch now emits. The pinned references
  read "-" only because pdftext's glyph-name table maps `minus` to "-". The
  references and FlashTeX are both right; the word matcher was not.
- amsmath_corpus/oracle.py `regroup` orders coincident glyphs (the \relbar
  and arrow head of \xrightarrow) with the same fold, so `−→` sorts like the
  references' `-→`.
- test_rank.py: a minus sign aligns with a hyphen-minus.

What was run:
- amsmath oracle, this branch's flashtex-render: TOTAL 58/59 after the norm
  fold alone (28-xrightarrow order tie), TOTAL 59/59 within 0.5 bp with both
- amsmath oracle, main's flashtex-render (36fe7ec): TOTAL 59/59 within 0.5 bp
- amssymb oracle, main and this branch: TOTAL 38/39 within 0.5 bp (both;
  32-braces-narrow fails identically on main)
- tabular oracle, main and this branch: TOTAL 106/106 (words 0.5 bp, rules 0.1 bp)
- display-placement oracle, main and this branch: TOTAL 33/36 within 0.5 bp (identical rows)
- python3 -m unittest discover -s tools/visual-oracle -p 'test_*.py': Ran 14 tests, OK

Next step: merge into the integration preview (#609) and rerun there.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
What changed:
- rank.v2_words sliced the glyph run's Python str with the display list's
  cluster ranges, which are UTF-8 byte offsets. After the first non-ASCII
  character in a run (`∈`, and now this branch's U+2212 minus) every later
  glyph got its neighbour's text: `|f(x_k) − f(y_k)|` read as words `−f`,
  `(y` instead of `−`, `f(y`, and `x ∈ K` left an empty-text word. The
  sweep-2 "apparent regressions with identical pixels" (inline-math p1/p2,
  math-sheet p2, hw1 p1, conf-paper p2) were this. The amsmath oracle's own
  reader already encoded before slicing.
- test_rank.py: the v2 fixture helper writes byte offsets; a run with
  `−` and `∈` keeps its word text.

What was run (tools/visual-oracle/rank.py, all 22 real-world fixtures, same
flashtex-pdf-exact; aligned words summed over every page):
- old rank.py: main 36fe7ec 15285, preview 5d1eb06 15253
- this rank.py: main 15330, preview 15326
- pages whose aligned/within-0.5 counts differed main vs preview only
  through text (conf-paper p2, hw1 p1, inline-math p1/p2, math-sheet p1/p2,
  ps-calculus p2/p3, twelvept-plain p2, lecture-notes p2) are now identical
- amsmath 59/59, amssymb 38/39, tabular 106/106, display-placement 33/36
  (main) and 35/36 (preview): unchanged by this commit
- python3 -m unittest discover -s tools/visual-oracle -p 'test_*.py': OK

Next step: merge into the integration preview (#609).

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…p-2 regression verdicts

What changed:
- Merged origin/agent/daniel-parent/pdf-math-tounicode (d999108) with --no-ff; no conflicts.
  b283587: rank.norm folds U+2212 into "-", amsmath regroup orders with the same fold.
  d999108: rank.v2_words slices cluster byte ranges as bytes.
- Notes: new "Corpus sweep 2 regressions" section. Per regression: the cause PR found by
  rebuilding flashtex-render at each render-pipeline merge, the verdict against pdflatex's
  positions, and the oracle results. Also repaired the #556/#596 conflict-table row, which
  had swallowed the #536/#597 row.

What was run (this tip; render-pipeline unchanged by the merge, flashtex-render built at 5d1eb06):
- amsmath: TOTAL 59/59 within 0.5 bp
- amssymb: TOTAL 38/39 within 0.5 bp
- tabular: TOTAL 128/128 (words 0.5 bp, rules 0.1 bp)
- display-placement: TOTAL 35/36 within 0.5 bp
- tools/visual-oracle unit tests: Ran 15 tests, OK
- rank.py real-world: aligned words 15326 (15253 with the old rank.py)

Next step: comment the verdicts on #597, #596, #536 and #547.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
… the queued compiler

What changed:
- adapter.rs: the queued compiler's `Inline::HSpace` gained `space_before_pt`/`space_after_pt` (d67be8c). The quad/hspace lowering now matches with `..`; the gaps around `\hspace` keep coming from the source bytes, as every other interword gap does. No behaviour change.

What was run:
- Scratch re-pin (vendor compiler/pdf/math-layout/tex-expansion/project-files/bibliography from c47e145, features linebreak-skip + amsmath-sideset + compiler-text-run on): cargo build --release: Finished; cargo test --release --no-run: all test targets build.

Next step:
- Full release suite and oracles in the scratch re-pin; runbook.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
What changed:
- Merged origin/agent/daniel-parent/integration-preview at da03ac9 (#597's oracle fixes: math minus aligns with hyphen-minus; candidate word slices by bytes; sweep-2 verdict notes). No conflicts.

What was run:
- None for this merge (oracle tooling and docs only).

Next step:
- Re-run the amsmath corpus oracle against the scratch re-pin binary.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
…he readiness merges

What changed:
- New docs/integration/repin-runbook.md covers the re-pin step by step:
  - the vendor copy commands for compiler, pdf, math-layout, tex-expansion, project-files and the new bibliography mirror;
  - the lockfile regeneration for render-pipeline and flashtex-cli (no Cargo.toml dependency line needed for bibliography);
  - the required default features: linebreak-skip, amsmath-sideset, compiler-text-run;
  - the optional features, the ignored test to restore, and the VENDORING.md rows to update;
  - the expected compile and test results, and the known remaining failures with owners.
- docs/integration/daniel-parent-preview.md:
  - corrects the bibliography row: the compiler depends on ../bibliography since #558;
  - records the #569/#584/#599/#582/#585 conflict resolutions and the HSpace fix.

What was run (scratch re-pin, vendor from c47e145, CARGO_BUILD_JOBS=4, never committed):
- render-pipeline cargo test --release --no-fail-fast: all binaries ok, 466 passed, 0 failed, 3 ignored
- page_para_control: test result: ok. 19 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s
- flashtex-cli cargo test --release: ok. 31 passed; 0 failed / ok. 26 passed; 0 failed; 1 ignored
- amsmath TOTAL 59/59 within 0.5 bp; amssymb TOTAL 38/39 within 0.5 bp; tabular TOTAL 128/128 (words 0.5 bp, rules 0.1 bp); display-placement TOTAL 47/48 within 0.5 bp

Next step:
- Integration lane applies the runbook after the queue merges.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
@GoKubar

GoKubar commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Re-pin readiness re-measured against current main (ec3cb67), per your runbook. Short answer: it is no longer the mechanical copy the runbook describes, and I have not executed it.

What I did: scratch worktree off this branch, copied the six crates from main exactly as step 1 prescribes (git archive PIN crates/$c | tar -x --strip-components=2, PIN written), then cargo check --release --tests on crates/render-pipeline. Nothing committed; the vendor copy was discarded.

Preconditions that now hold (all good news): Inline::LineBreak::skip_pt (#479), Nucleus::SideSet + math-layout left_scripts (#581), Nucleus::TextRun/TextPiece (#470), crates/bibliography with compiler's flashtex-bibliography = { path = "../bibliography" } (so the new sibling mirror resolves), project-files #518/#539 — every one merged.

Precondition that does not hold: step 0.2 says "#585 carries compiler commit 1b6f03f2, which is in no other PR". 1b6f03f2 is still not on main — git merge-base --is-ancestor 1b6f03f2 origin/main fails, and its tests (a_tag_on_any_multline_row_replaces_the_display_number, tagged_align_and_gather_rows_do_not_step_the_equation_counter) are absent from main. So no PIN on main contains the whole queue today.

Measured result — the runbook's table predicts 8 errors, then 1 after the three feature flips, then 0 with 58118db5. Actual, against main:

State Errors
main's vendor copy, default features 18
+ linebreak-skip, amsmath-sideset, compiler-text-run flipped 15

The three flips do their job (skip_pt, TextRun, SideSet all clear). The 15 that remain are compiler API that landed after the runbook's validated revision c47e1452, so the runbook never saw them:

Locations: src/adapter.rs 822/2375/2843/7314/7539, src/typeset.rs 6678/7553/7624/7663/7711, src/incremental.rs 325/660.

Assessment. Most of those 15 are mechanical (add a field, add an arm), but Lap, Tabbing, TabStop, ThePage and PageNumbering are not purely mechanical: each needs a decision about whether the pipeline lays the construct out or diagnoses it as unsupported, and a wrong _ => catch-all would silently drop rendering that the compiler now emits. That is product work for the pipeline lane, not an integration copy.

Recommendation, since this must still land atomically with both lockfiles and the feature flips: (1) land #585's compiler half so 1b6f03f2 reaches main; (2) have the pipeline lane clear the 15 post-c47e1452 errors on a branch stacked on this one and re-record the runbook's step 5 table; (3) only then do the copy + lockfiles + flips as one change. Unblocking #569#584#599#617, plus #607, #557, #561, #582 and #585 is still the prize — that is 9 drafts — but the gate is now step 2, not the copy.

@d-q222

d-q222 commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #711, which redoes this fresh against current main. This PR was built on an integration-preview snapshot that is now ~250 commits stale, so its evidence no longer describes the tree it would be applied to.

#711 carries what this was meant to provide, plus two things this one could not have known: vendor/compiler cannot move without vendor/tex-expansion (21 errors inside the vendored compiler itself against the 7-commit-stale expansion mirror), and the newly-declared flashtex-bibliography path dependency needs a lockfile entry in both crates/render-pipeline/Cargo.lock and crates/flashtex-cli/Cargo.lock or every --locked CI job fails before compiling. Full detail: #2 (comment) and PR #711. — daniel-parent

@d-q222 d-q222 closed this Sep 16, 2026
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.

2 participants