Implement Spike E: the two-process model from ADR-0004 (§2.1), the one thing the plan says is genuinely painful to retrofit, de-risked at M0. Sandbox.cpp: seccomp-bpf allow-list filter for the document process. Default-deny (SCMP_ACT_KILL_PROCESS), permit only memory/thread-sync/the already-open IPC socket fds/exit. DENIED: open, socket, connect, fork, exec — the document process cannot reach the network or filesystem and cannot spawn children. A forbidden syscall kills the process loudly. DocumentProcess.cpp + UIProcess.cpp: the sandboxed child and the UI process over a socketpair, with a trivial length-prefixed binary IPC protocol ([u64 id][u64 len][payload] -> [u64 id][u64 count][u8 ok]). The UI validates every response field (ADR-0004: bidirectional trust boundary); the child bounds-checks every request length. main.cpp forks, sets up the socketpair, measures round-trip latency. Gate MET: 1000/1000 requests round-trip under the sandbox, avg 18us (sandbox OFF: 20us — no measurable overhead). Verified clean under ASan+UBSan. Result and findings in docs/spike-results/0004-spike-e-sandbox.md. Key finding: Cap'n Proto two-party RPC over a socketpair stalled in this environment (server processed requests but responses never reached the client; reproduced with the sandbox disabled, so it's an RPC integration issue not a sandbox issue). Recorded for M2 to debug with the full event- loop integration. The spike uses a raw protocol to measure the channel cost without that blocker; the ipc.capnp schema is kept for M2. The process split cost is ~tens of us/request, far under the §5 budget. CI: add Spike E to the spike-gates job (libseccomp-dev); fails the build on regression, sandbox must be ON (no env override in CI). Signed-off-by: ai-ad4 <ai-ad4@users.noreply.gitea.lm.je> |
||
|---|---|---|
| .gitea/workflows | ||
| LICENSES | ||
| ci | ||
| cmake | ||
| docs | ||
| packaging | ||
| spike | ||
| src | ||
| test | ||
| .clang-format | ||
| .clang-tidy | ||
| .editorconfig | ||
| .gitattributes | ||
| .gitignore | ||
| .gitleaks.toml | ||
| .pre-commit-config.yaml | ||
| CMakeLists.txt | ||
| CMakePresets.json | ||
| CODEOWNERS | ||
| CONTRIBUTING.md | ||
| README.md | ||
| REUSE.toml | ||
| SECURITY.md | ||
| TRADEMARK.md | ||
| vcpkg-configuration.json | ||
| vcpkg.json | ||
README.md
FreePDFEditor
A cross-platform native desktop PDF editor with a true WYSIWYG interface and full content editing: edit existing text with reflow, replace images, manipulate vector objects, plus annotations, forms, signatures, and page assembly.
- Stack: C++20, Qt 6.7 (Widgets shell, custom canvas), CMake, vcpkg.
- License: GPL-3.0-or-later (see
LICENSES/GPL-3.0-or-later.txt). Qt is dynamically linked under LGPL-3.0. - Targets: Windows 10+, macOS 12+ (Intel + Apple Silicon), Linux (X11/Wayland).
This repository contains the source and build infrastructure. The full engineering plan and
roadmap live in docs/plan.md; architecture decision records are under
docs/adr/.
Status
Pre-M0. This is the initial repository scaffold described in §14 of the plan: CMake + vcpkg skeleton, governance docs, CI matrix, packaging pipeline, an empty-window application shell, the pixel-diff harness scaffolding, and the Spike A (QPDF verbatim round-trip) harness. The feasibility spikes that gate the project run on top of this scaffolding.
Building
cmake --preset default
cmake --build --preset default
ctest --preset default
See CONTRIBUTING.md for the full build setup, gate matrix, and coding
standard.
Source control
All code is developed on the project Gitea instance at https://gitea.lm.je/ai-ad4/freepdfeditor
per docs/plan.md §13. See SECURITY.md for vulnerability reporting.