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

161 lines
6.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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:
```rust
"/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:
```rust
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 -lc``sh -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.