nigig-org/REVIEWS/PDF_PARITY_PHASE1_STATUS.md
andodeki bd01604e65
Some checks failed
repo hygiene / hygiene (push) Has been cancelled
PDF engine / engine (push) Has been cancelled
PDF engine / makepad-integration (push) Has been cancelled
PDF engine / fuzz (push) Has been cancelled
docs(pdf): Phase 1 status, and stop pdf-ui failing for an environmental reason
Phase 1 of NIGIG_PDF_FEATURE_PARITY_PLAN.md. Findings verified by running
them, written up in REVIEWS/PDF_PARITY_PHASE1_STATUS.md.

Three of the five exit criteria are met: the workspace is green on the new
rev (pdf 606 passing), both pins are already at 5efe6e24c, and the upstream
baseline is documented - libs/pdf_parse is 4,575 lines with no save/write
path at all, against nigig-pdf's 25,845 lines with writing, encryption,
signatures, structure tree and transparency. nigig-pdf supersedes both
libs/pdf_parse and widgets/src/pdf_view.rs; nothing in either is a
capability we lack.

The remaining two criteria need fork work this repo cannot do.

WHY THE UI SUITE CANNOT PASS YET

The six #[ignore] markers were removed from pdf-makepad/tests/ui.rs and the
docs now claim the suite runs without a Studio hub. The markers went but the
tests did not start passing - TEST_TARGET=pdf-ui was simply red. Three
layers, each found by fixing the one in front of it:

1. studio/hub/src/build_manager.rs:398 spawns the build with `sh -lc`. The
   -l makes it a LOGIN shell, which discards the inherited PATH and rebuilds
   it from /etc/profile, where ~/.cargo/bin does not appear. cargo is not
   found and the child exits 127 in 0.4s. This breaks any rustup-based CI,
   not just this sandbox. `sh -c`, or resolving cargo through the CARGO env
   var, would fix it.

2. Past that the build runs (88s) and the failure becomes 101.
   libs/makepad_test sets MAKEPAD=headless for the child, but
   platform/src/os/linux/windowing_backend.rs only knows X11 and Wayland -
   there is no headless backend and the env var is not consulted. The app
   selects X11, finds no display, and segfaults (139). This is the real
   Phase 1 fork task: "terminal/standalone mode" needs a backend, not just
   an env var the harness sets.

3. Under xvfb-run the app starts properly and OpenGL initialises, so the
   binary is fine - but the hub spawns its child outside that display.

The markers are restored, with a reason pointing at the status document.
A red suite everyone knows to disregard stops reporting the next real
regression, which is strictly worse than an explicit skip.

Also fixes a latent build break this exposed: the fork's app_main! macro
expands to #[cfg(native_activity)], a cfg this crate never declares, which
is a hard error under -D warnings. Declared as expected-but-unset via
[lints.rust] check-cfg rather than silencing unexpected_cfgs wholesale,
which would also hide our own typos.

One genuine improvement on this rev: pdf-makepad now builds in release
inside the workspace. That was previously blocked by a Makepad os::linux
feature-unification bug.

TEST_TARGET=pdf 606 passing, TEST_TARGET=pdf-ui 651 passing + 6 ignored.
2026-08-16 16:48:02 +00:00

6.3 KiB
Raw Permalink Blame History

Phase 1 status — fork sync + makepad_test enablement

Against NIGIG_PDF_FEATURE_PARITY_PLAN.md §1 Phase 1. Everything below was verified by running it, not by reading code.

Fork rev pinned at time of writing: 5efe6e24c.

Exit criteria

Criterion State Evidence
Workspace green on the new rev TEST_TARGET=pdf 606 passing
rev = bumped in pdf-makepad + map both already at 5efe6e24c
Baseline the gap list vs upstream libs/pdf_parse + pdf_view.rs §2 below
cargo test -p nigig-pdf-makepad --test ui on the desktop, no Studio blocked, see §3
Same suite on an Android device no device in this environment

Two of five criteria are outside what this sandbox can deliver. §3 states precisely where the wall is and what the fix looks like, so the fork work can be picked up without rediscovering it.

1. What changed since the last PDF session

The fork moved from a79f0dce to 5efe6e24c, and the six #[ignore = "needs a Makepad Studio hub"] markers were removed from pdf-makepad/tests/ui.rs. The module docs now claim the suite runs "without a Studio hub".

The markers were removed but the tests do not pass. They fail, which is a worse state than being ignored: TEST_TARGET=pdf-ui is red, so the gate that is supposed to protect the widget now fails for an environmental reason and will be tuned out.

That is not a criticism of the fork work — the failure mode genuinely did change, and it changed for the better (see §3). It just is not finished.

2. Baseline: upstream PDF code vs nigig-pdf

The plan asks for this so we can demonstrate nigig-pdf has superseded the upstream code.

upstream libs/pdf_parse nigig-pdf
Source 4,575 lines 25,845 lines
Writing a PDF ✗ none — no save, write or serialize entry point exists writer.rs, incremental.rs, save.rs
Encryption ✓ RC4 40/128, AES-128, AES-256 (ADR 0005)
Signatures ✓ read + byte-range integrity (ADR 0010)
Structure tree / PDF-UA structure.rs (ADR 0011)
Transparency, ICC, functions transparency.rs, icc.rs, function.rs (ADRs 0006, 0009)
Forms partial ✓ edit, actions, validation (ADRs 0003, 0012)
Annotations partial ✓ edit + save (ADR 0004)

widgets/src/pdf_view.rs is 1,161 lines and view-only: selection, zoom, page caching. pdf-makepad covers that plus form interaction, typed host actions and event routing.

Conclusion: nigig-pdf supersedes both. Nothing in libs/pdf_parse or pdf_view.rs is a capability we lack. This satisfies the plan's baseline requirement.

3. Why the UI suite cannot pass here — three layers, in order

Each was found by fixing the one in front of it. The first two are real bugs worth fixing in the fork; the third is a genuine environment limit.

Layer 1 — sh -lc loses cargo (exit 127)

studio/hub/src/build_manager.rs:398 takes a "direct stdio run" path that spawns the build through:

"/bin/sh".to_string(), vec!["-lc".to_string(), script]

-l makes it a login shell, which discards the inherited PATH and rebuilds it from /etc/profile. A rustup toolchain lives in ~/.cargo/bin, which is not on that path:

$ /bin/sh -c  'command -v cargo'   → /home/user/.cargo/bin/cargo
$ /bin/sh -lc 'command -v cargo'   → not found
$ /bin/sh -lc 'echo $PATH'         → /usr/local/bin:/usr/bin:/bin:...

So cargo is not found and the child exits 127 before any build starts — in 0.4 s, which is the tell.

This hits any CI or container using a rustup toolchain, not just this sandbox. Suggested fix in the fork: use sh -c rather than sh -lc, or resolve cargo to an absolute path (CARGO env var, which cargo sets for its children) instead of relying on the login shell's PATH.

Worked around here by symlinking cargo and rustc into /usr/local/bin.

Layer 2 — no headless backend exists on Linux (exit 101 → 139)

With cargo reachable the build runs (88 s) and the failure becomes 101.

libs/makepad_test/src/runtime.rs:112 sets MAKEPAD=headless for the child. But platform/src/os/linux/windowing_backend.rs only knows two backends:

pub enum WindowingProtocol { X11, Wayland }

There is no headless variant, and MAKEPAD=headless is not consulted in the selection. Running the app with it and no display:

Selected: X11 backend
Reason: Default fallback (no display variables set)
exit=139          ← SIGSEGV

It picks X11, finds no display, and segfaults. This is the substantive Phase 1 fork work: "terminal/standalone mode" as the plan calls it needs an actual headless backend in windowing_backend.rs, not just an env var the test harness sets.

Layer 3 — the sandbox has no display

Under xvfb-run the app starts properly and OpenGL initialises:

DISPLAY: :99 → Selected: X11 backend
Makepad GL: vendor="Mesa" renderer="llvmpipe (LLVM 19.1.7)" ...

The binary is fine. But the hub spawns its own child process outside the xvfb-run wrapper's inherited display in a way I could not thread through, so the suite still reports 101. Past layer 2 this stops mattering, because a real headless backend needs no display at all.

4. Verified state

TEST_TARGET=pdf     606 passing   ✅
TEST_TARGET=pdf-ui  6 failing     ❌  (environmental, layers 13)

One genuine improvement worth recording: pdf-makepad now builds in release inside the workspace. That was previously blocked by a Makepad os::linux feature-unification bug and is fixed on this rev (cargo build --release -p nigig-pdf-makepad succeeds in 1 m 54 s).

5. Recommendation

Phase 1 is not complete, and the remaining work is in the Makepad fork, not in nigig-org:

  1. Fix sh -lcsh -c in build_manager.rs (small, unblocks every rustup-based CI).
  2. Add a real headless backend to windowing_backend.rs honouring MAKEPAD=headless.
  3. Then Android mode, which the plan already scopes.

Until (2) exists, pdf-makepad/tests/ui.rs cannot pass anywhere without a display. The six tests should be #[ignore]d again with a reason pointing at this document rather than left failing — a red suite that everyone knows to disregard is worse than an explicitly skipped one, because it hides the next real regression.