diff --git a/docs/README.md b/docs/README.md index bf7f8ccc..06b92746 100644 --- a/docs/README.md +++ b/docs/README.md @@ -58,7 +58,8 @@ back here. - **[contributing/release-process.md](contributing/release-process.md)** — versioning, tag procedure, Maven Central publication. ### Roadmaps & migrations -- **[roadmaps/v1.6-roadmap.md](roadmaps/v1.6-roadmap.md)** — current development roadmap. +- **[roadmaps/post-2.0-engineering.md](roadmaps/post-2.0-engineering.md)** — forward-looking engineering roadmap: internal refactors, scale, and tooling deferred past the 2.0 line. +- **[roadmaps/v1.6-roadmap.md](roadmaps/v1.6-roadmap.md)** — the v1.6 "expressive" roadmap (shipped). - **[roadmaps/migration-v1-8-to-v1-9.md](roadmaps/migration-v1-8-to-v1-9.md)** — upgrade guide for v1.8 → v1.9. - **[roadmaps/migration-v1-7-to-v1-8.md](roadmaps/migration-v1-7-to-v1-8.md)** — upgrade guide for v1.7 → v1.8. - **[roadmaps/migration-v1-6-to-v1-7.md](roadmaps/migration-v1-6-to-v1-7.md)** — upgrade guide for v1.6 → v1.7. diff --git a/docs/roadmaps/post-2.0-engineering.md b/docs/roadmaps/post-2.0-engineering.md new file mode 100644 index 00000000..1e7ed257 --- /dev/null +++ b/docs/roadmaps/post-2.0-engineering.md @@ -0,0 +1,87 @@ +# Post-2.0 engineering roadmap + +The 2.0 line focused on **packaging and internal hygiene**: splitting the +monolithic jar into per-concern modules, removing the dead legacy +Entity-Component-System code, retiring the deprecated API surface, and +tightening CI. This document tracks the **engineering** work deliberately left +for after 2.0 — internal refactors, scale work, and tooling. None of it changes +the public authoring API (`GraphCompose.document(...)` → `DocumentSession` → +`DocumentDsl`); it is about the health of the engine and the build. + +## Status legend + +| Status | Meaning | +| --- | --- | +| Planned | Shape agreed; not started. | +| Investigating | Being scoped; the approach is not yet fixed. | +| Deferred | Intentionally postponed; captured here so it is not lost. | + +## Engine internals + +### Decompose the layout hot files + +`LayoutCompiler` (~1690 LOC) and `TextFlowSupport` (~1900 LOC) are the two +largest files in `com.demcha.compose.document.layout`, and each carries several +distinct responsibilities. The plan is to split them along their natural seams — +pagination, row distribution, stack / overlay placement, and decoration — into +focused, individually-tested collaborators (the package-private `RowSlots` +extraction is the pattern to follow), with layout output unchanged and covered +by the existing snapshot suite. **Status: Planned.** + +### Retire the internal `Entity` model + +The engine still resolves layout on a legacy `Entity` / `EntityManager` object +model — the live layout coordinate, geometry (`EntityBounds`), and guide helpers +are built on it. The dead ECS *execution* layer around it has been removed; what +remains is genuinely live infrastructure. Fully retiring `Entity` / +`EntityManager` means rebuilding the coordinate / geometry / guide helpers on a +non-`Entity` representation and removing the legacy `engine.debug` snapshot +overloads in `graph-compose-testing` that still reference it. This is a real +engine refactor, sequenced after the module line stabilises. **Status: Deferred.** + +### Fail loudly on non-converged layout + +Some layout passes iterate toward a fixed point. Today a pass that does not +converge silently uses its last iteration. A `FAIL_ON_UNCONVERGED` policy flag +would let a build opt into failing loudly instead, surfacing the rare +non-converging document in tests rather than shipping a subtly-wrong render. +**Status: Planned.** + +## Scale & memory + +### Streaming / bounded-memory rendering + +Rendering currently holds the full layout graph and all page fragments in +memory. Very large documents (thousands of pages) would benefit from a streaming +path that paginates and flushes finalised pages incrementally, bounding peak +memory. This needs a backend seam that can emit pages as they are completed +rather than at the end of the pass. **Status: Investigating.** + +## Tooling & guardrails + +### ArchUnit module-boundary guards + +The canonical / engine / render layering and the module split are guarded today +by targeted tests plus path-based greps that can pass vacuously after a move. +ArchUnit rules would enforce the boundaries structurally at test time (for +example: no `com.demcha.compose.engine.*` import inside the canonical +`document.*` public API, and no cross-module back-edges), replacing the brittle +checks with ones that cannot silently rot. **Status: Planned.** + +### Cross-module coverage aggregation + +The canonical core packages (`document.layout` / `document.dsl` / +`document.backend.fixed`) are exercised mostly by the cross-module `qa` suites, +which depend on the engine at **test** scope — so a single-module coverage +report undercounts, and JaCoCo's `report-aggregate` does not traverse test-scope +dependencies. An accurate report needs a small, dedicated, non-published +aggregation module that compile-depends on the tested modules. The first step is +report-only; thresholds follow after a baseline read. **Status: Planned.** + +### Per-module binary-compatibility baselines + +`japicmp` runs report-only on the 2.0 line — the major intentionally breaks +binary compatibility. Once the 2.0 GA artifacts are published, the gate should +switch to per-module baselines pinned at the GA release and break-on-incompatible +mode, so each published module's public surface is protected from that point on. +**Status: Deferred (post-GA).**