diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6a5d917c..96d3b210 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,7 +29,7 @@ When writing new code, avoid Java 21+ APIs and language constructs that don't ex ## Build and test - The blocking validation gate for repository work is `./mvnw -B -ntp clean verify`. -- Run the guard-focused suite with `./mvnw -B -ntp "-Dtest=EnginePdfBoundaryTest,CanonicalTemplateComposerPdfBoundaryTest,PdfRenderInterfaceGuardTest,PdfRenderingSystemECSDispatchTest,DocumentationCoverageTest,DocumentationExamplesTest,CanonicalSurfaceGuardTest" test`. +- Run the guard-focused suite with `./mvnw -B -ntp "-Dtest=EnginePdfBoundaryTest,PdfRenderInterfaceGuardTest,PdfRenderingSystemECSDispatchTest,DocumentationCoverageTest,DocumentationExamplesTest,CanonicalSurfaceGuardTest" test`. - Run a focused documentation sanity check with `./mvnw -B -ntp "-Dtest=DocumentationExamplesTest" test`. - Run the local benchmark wrapper when you change performance-sensitive code or benchmark tooling: `powershell -ExecutionPolicy Bypass -File .\scripts\run-benchmarks.ps1` (Windows). To compare two branches fairly, use `scripts/ab-bench.ps1` (Windows) or the cross-platform `scripts/ab-bench.sh` (Linux/macOS/Git Bash). See [docs/operations/benchmarks.md](./docs/operations/benchmarks.md). @@ -120,7 +120,7 @@ See [docs/contributing/release-process.md](./docs/contributing/release-process.m 2. Keep structural cleanup separate from behavior changes whenever possible. 3. If you touch public examples or screenshots, update the related docs in the same change. 4. Run the smallest relevant tests while iterating, then run `./mvnw -B -ntp clean verify` before opening a pull request. -5. For quick visual iteration on a template, run [GraphComposeDevTool.java](./src/test/java/com/demcha/compose/devtool/GraphComposeDevTool.java) in test scope — it hot-reloads the rendered PDF as you edit your template source. +5. For quick visual iteration on a template, run [GraphComposeDevTool.java](qa/src/test/java/com/demcha/compose/devtool/GraphComposeDevTool.java) in test scope — it hot-reloads the rendered PDF as you edit your template source. ## Contributor architecture rules @@ -205,13 +205,12 @@ The rules above are enforced by tests: [CanonicalSurfaceGuardTest.java](./src/test/java/com/demcha/documentation/CanonicalSurfaceGuardTest.java), [PublicApiNoEngineLeakTest.java](./src/test/java/com/demcha/documentation/PublicApiNoEngineLeakTest.java), [SemanticLayerNoPdfBoxDependencyTest.java](./src/test/java/com/demcha/documentation/SemanticLayerNoPdfBoxDependencyTest.java), - [DocumentationExamplesTest.java](./src/test/java/com/demcha/documentation/DocumentationExamplesTest.java), + [DocumentationExamplesTest.java](qa/src/test/java/com/demcha/documentation/DocumentationExamplesTest.java), [DocumentationCoverageTest.java](./src/test/java/com/demcha/documentation/DocumentationCoverageTest.java) - engine internals guards: [EnginePdfBoundaryTest.java](./src/test/java/com/demcha/compose/engine/architecture/EnginePdfBoundaryTest.java), - [CanonicalTemplateComposerPdfBoundaryTest.java](./src/test/java/com/demcha/compose/document/templates/architecture/CanonicalTemplateComposerPdfBoundaryTest.java), - [PdfRenderInterfaceGuardTest.java](./src/test/java/com/demcha/compose/engine/render/pdf/PdfRenderInterfaceGuardTest.java), - [PdfRenderingSystemECSDispatchTest.java](./src/test/java/com/demcha/compose/engine/render/pdf/ecs/PdfRenderingSystemECSDispatchTest.java) + [PdfRenderInterfaceGuardTest.java](render-pdf/src/test/java/com/demcha/compose/engine/render/pdf/PdfRenderInterfaceGuardTest.java), + [PdfRenderingSystemECSDispatchTest.java](render-pdf/src/test/java/com/demcha/compose/engine/render/pdf/ecs/PdfRenderingSystemECSDispatchTest.java) ## Adding a new feature @@ -321,22 +320,22 @@ low-level test harness. Choose the smallest tests that match the change: - For README or docs examples: - [DocumentationExamplesTest.java](./src/test/java/com/demcha/documentation/DocumentationExamplesTest.java) + [DocumentationExamplesTest.java](qa/src/test/java/com/demcha/documentation/DocumentationExamplesTest.java) - For engine/backend boundary changes: [EnginePdfBoundaryTest.java](./src/test/java/com/demcha/compose/engine/architecture/EnginePdfBoundaryTest.java) - [PdfRenderInterfaceGuardTest.java](./src/test/java/com/demcha/compose/engine/render/pdf/PdfRenderInterfaceGuardTest.java) + [PdfRenderInterfaceGuardTest.java](render-pdf/src/test/java/com/demcha/compose/engine/render/pdf/PdfRenderInterfaceGuardTest.java) - For low-level test harness changes: - [ComponentBuilderTest.java](./src/test/java/com/demcha/compose/engine/components/ComponentBuilderTest.java) + [ComponentBuilderTest.java](qa/src/test/java/com/demcha/compose/engine/components/ComponentBuilderTest.java) - For render-marker dispatch changes: - [PdfRenderingSystemECSDispatchTest.java](./src/test/java/com/demcha/compose/engine/render/pdf/ecs/PdfRenderingSystemECSDispatchTest.java) + [PdfRenderingSystemECSDispatchTest.java](render-pdf/src/test/java/com/demcha/compose/engine/render/pdf/ecs/PdfRenderingSystemECSDispatchTest.java) - For layout/positioning behavior: [ComputedPositionTest.java](./src/test/java/com/demcha/compose/engine/components/layout/ComputedPositionTest.java) - For pagination and multi-page behavior: - [PageBreakerIntegrationTest.java](./src/test/java/com/demcha/compose/engine/integration/PageBreakerIntegrationTest.java) + [PageBreakerIntegrationTest.java](qa/src/test/java/com/demcha/compose/engine/integration/PageBreakerIntegrationTest.java) - For Templates v2 CV / cover-letter presets: - [PresetVisualParityTest.java (CV)](./src/test/java/com/demcha/compose/document/templates/cv/presets/PresetVisualParityTest.java) - [PresetVisualParityTest.java (cover letter)](./src/test/java/com/demcha/compose/document/templates/coverletter/presets/PresetVisualParityTest.java) - [PresetLayoutSnapshotTest.java](./src/test/java/com/demcha/compose/document/templates/cv/presets/PresetLayoutSnapshotTest.java) + [CvV2VisualParityTest.java (CV)](qa/src/test/java/com/demcha/compose/document/templates/cv/presets/CvV2VisualParityTest.java) + [CoverLetterV2VisualParityTest.java (cover letter)](qa/src/test/java/com/demcha/compose/document/templates/coverletter/presets/CoverLetterV2VisualParityTest.java) + and the [per-preset smoke tests](qa/src/test/java/com/demcha/compose/document/templates/cv/presets) If a change affects public docs, examples, or screenshots, update those assets in the same PR so the repository stays internally consistent. diff --git a/docs/contributing/extension-guide.md b/docs/contributing/extension-guide.md index 2af90eb1..08e34b19 100644 --- a/docs/contributing/extension-guide.md +++ b/docs/contributing/extension-guide.md @@ -6,7 +6,7 @@ each with the v1.5 `ShapeContainerNode` work as a worked example so the moving pieces are easy to find in the source tree. If you only need to compose existing primitives, the -[recipes](recipes.md) and the [getting-started](getting-started.md) +[recipes](../recipes.md) and the [getting-started](../getting-started.md) quick-start are enough. Reach for this guide when: - You want a brand-new semantic shape that the DSL can produce. @@ -60,11 +60,11 @@ The Phase B `ShapeContainerNode` is a clean example of all five steps: | Step | Source file | | --- | --- | -| Record | [`ShapeContainerNode.java`](../src/main/java/com/demcha/compose/document/node/ShapeContainerNode.java) | -| NodeDefinition | `ShapeContainerDefinition` (inner class of [`BuiltInNodeDefinitions.java`](../src/main/java/com/demcha/compose/document/layout/BuiltInNodeDefinitions.java)) | +| Record | [`ShapeContainerNode.java`](../../src/main/java/com/demcha/compose/document/node/ShapeContainerNode.java) | +| NodeDefinition | `ShapeContainerDefinition` (inner class of [`BuiltInNodeDefinitions.java`](../../src/main/java/com/demcha/compose/document/layout/BuiltInNodeDefinitions.java)) | | Payloads | `ShapeClipBeginPayload`, `ShapeClipEndPayload` (also inner classes of `BuiltInNodeDefinitions`) | | Registration | `BuiltInNodeDefinitions.registerDefaults(...)` line that calls `.register(new ShapeContainerDefinition())` | -| Render handlers | [`PdfShapeClipBeginRenderHandler.java`](../src/main/java/com/demcha/compose/document/backend/fixed/pdf/handlers/PdfShapeClipBeginRenderHandler.java) and `PdfShapeClipEndRenderHandler.java` | +| Render handlers | [`PdfShapeClipBeginRenderHandler.java`](../../render-pdf/src/main/java/com/demcha/compose/document/backend/fixed/pdf/handlers/PdfShapeClipBeginRenderHandler.java) and `PdfShapeClipEndRenderHandler.java` | The `NodeDefinition` interface has four required methods plus three defaults: @@ -96,10 +96,10 @@ AFTER children). The repo has two architecture-guard tests that pin two invariants for new nodes: -- [`PublicApiNoEngineLeakTest`](../src/test/java/com/demcha/documentation/PublicApiNoEngineLeakTest.java) +- [`PublicApiNoEngineLeakTest`](../../src/test/java/com/demcha/documentation/PublicApiNoEngineLeakTest.java) — `com.demcha.compose.document.*` must not import `com.demcha.compose.engine.*` types. -- [`CanonicalSurfaceGuardTest`](../src/test/java/com/demcha/documentation/CanonicalSurfaceGuardTest.java) +- [`CanonicalSurfaceGuardTest`](../../src/test/java/com/demcha/documentation/CanonicalSurfaceGuardTest.java) — public markdown docs and runnable examples must not reference the retired legacy surface (the v1.0–v1.3 PDF composer entry point and the old templates package). The forbidden token list lives at the @@ -140,7 +140,7 @@ backend: 1. Implement `PdfFragmentRenderHandler`. Two methods: `payloadType()` and `render(fragment, payload, env)`. 2. Register the handler in - [`PdfFixedLayoutBackend.defaultHandlers()`](../src/main/java/com/demcha/compose/document/backend/fixed/pdf/PdfFixedLayoutBackend.java) + [`PdfFixedLayoutBackend.defaultHandlers()`](../../render-pdf/src/main/java/com/demcha/compose/document/backend/fixed/pdf/PdfFixedLayoutBackend.java) (or pass a custom handler list to the package-private constructor). 3. Wrap any graphics-state changes in `saveGraphicsState()` / `restoreGraphicsState()` so the next handler sees a clean slate. @@ -211,7 +211,7 @@ Set-up per node: subsequent runs compare against it. The -[`LayoutSnapshotAssertions`](../src/main/java/com/demcha/compose/testing/layout/LayoutSnapshotAssertions.java) +[`LayoutSnapshotAssertions`](../../testing/src/main/java/com/demcha/compose/testing/layout/LayoutSnapshotAssertions.java) helper class wraps the diff machinery; existing snapshot tests under `src/test/java/com/demcha/compose/document/templates/builtins/` (e.g. `BuiltInTemplateLayoutSnapshotTest`) show the call site shape. @@ -230,18 +230,18 @@ locate the responsible file: | Engine ECS internals | `com.demcha.compose.engine.*` (don't reach in from canonical code) | Detailed ownership lives in -[`docs/architecture/package-map.md`](package-map.md). +[`docs/architecture/package-map.md`](../architecture/package-map.md). ## See also -- [`docs/architecture/overview.md`](architecture.md) — high-level architecture +- [`docs/architecture/overview.md`](../architecture/overview.md) — high-level architecture and the canonical-vs-engine boundary. - [`docs/contributing/implementation-guide.md`](implementation-guide.md) — engine-side ECS extension patterns (component records, system registration, low-level harness builders). -- [`docs/architecture/lifecycle.md`](lifecycle.md) — the session, layout, and +- [`docs/architecture/lifecycle.md`](../architecture/lifecycle.md) — the session, layout, and render flow end-to-end. -- [ADR 0001 — Shape-as-container](adr/0001-shape-as-container.md) — +- [ADR 0001 — Shape-as-container](../adr/0001-shape-as-container.md) — the design rationale that shaped the v1.5 `ShapeContainerNode`, with the alternative considered ("flag on `LayerStackNode`") and why it was rejected. diff --git a/docs/contributing/implementation-guide.md b/docs/contributing/implementation-guide.md index 2d911967..8fc0bf9e 100644 --- a/docs/contributing/implementation-guide.md +++ b/docs/contributing/implementation-guide.md @@ -47,16 +47,16 @@ types. ### Use `EmptyBox` in tests when -Use [EmptyBox.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/container/EmptyBox.java) when the new object is a leaf entity or a small custom object that does not manage children itself. +Use [EmptyBox.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/container/EmptyBox.java) when the new object is a leaf entity or a small custom object that does not manage children itself. Examples in the codebase: -- [TextBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/TextBuilder.java) -- [ImageBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/ImageBuilder.java) -- [CircleBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/CircleBuilder.java) -- [LineBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/LineBuilder.java) -- [LinkBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/LinkBuilder.java) -- [ElementBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/ElementBuilder.java) +- [TextBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/TextBuilder.java) +- [ImageBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/ImageBuilder.java) +- [CircleBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/CircleBuilder.java) +- [LineBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/LineBuilder.java) +- [LinkBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/LinkBuilder.java) +- [ElementBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/ElementBuilder.java) This is the right choice for the exact case you asked about: an object that does not expand into a child-owning container and just needs base entity functionality plus layout/render participation. @@ -76,7 +76,7 @@ features such as `guideLines(true)` are not routed through `EntityManager`. ### Use `ShapeBuilderBase` in tests when -Use [ShapeBuilderBase.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/container/ShapeBuilderBase.java) when the object is still a leaf, but you want common shape helpers such as: +Use [ShapeBuilderBase.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/container/ShapeBuilderBase.java) when the object is still a leaf, but you want common shape helpers such as: - fill color - stroke @@ -84,18 +84,18 @@ Use [ShapeBuilderBase.java](../../src/test/java/com/demcha/compose/testsupport/e Examples: -- [RectangleBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/RectangleBuilder.java) -- [CircleBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/CircleBuilder.java) +- [RectangleBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/RectangleBuilder.java) +- [CircleBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/CircleBuilder.java) ### Use `ContainerBuilder` in tests when -Use [ContainerBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/container/ContainerBuilder.java) when the new object owns child entities and participates in parent/child layout. +Use [ContainerBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/container/ContainerBuilder.java) when the new object owns child entities and participates in parent/child layout. Examples: -- [HContainerBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/HContainerBuilder.java) -- [VContainerBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/VContainerBuilder.java) -- [ModuleBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/ModuleBuilder.java) +- [HContainerBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/HContainerBuilder.java) +- [VContainerBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/VContainerBuilder.java) +- [ModuleBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/ModuleBuilder.java) Use this path when the object should call `addChild(...)` and arrange nested entities. @@ -180,7 +180,7 @@ For measured objects, compute size in `build()` before the entity is registered. Example: -- [TextBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/TextBuilder.java) calls `TextComponent.autoMeasureText(...)` when auto-size is enabled. +- [TextBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/TextBuilder.java) calls `TextComponent.autoMeasureText(...)` when auto-size is enabled. ### Layout components @@ -257,7 +257,7 @@ Why the table uses this contract: Relevant files: -- [TableBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/TableBuilder.java) +- [TableBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/TableBuilder.java) - [TableRow.java](../../src/main/java/com/demcha/compose/engine/components/renderable/TableRow.java) - [TableCellBox.java](../../render-pdf/src/main/java/com/demcha/compose/engine/render/pdf/ecs/helpers/TableCellBox.java) - [TableResolvedCell.java](../../src/main/java/com/demcha/compose/engine/components/content/table/TableResolvedCell.java) @@ -416,7 +416,7 @@ If those components are missing or inconsistent, the renderer cannot save you la ## When to add a method to the test-support `ComponentBuilder` -Add a method to [ComponentBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/ComponentBuilder.java) when: +Add a method to [ComponentBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/ComponentBuilder.java) when: - a low-level engine test needs direct entity assembly - the object is not ready or not appropriate for public canonical authoring @@ -440,13 +440,13 @@ Do not add a method there if the new object is only an internal helper for templ ## Good examples to copy - leaf text with measured size: - [TextBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/TextBuilder.java) + [TextBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/TextBuilder.java) - shape-like object: - [RectangleBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/RectangleBuilder.java) + [RectangleBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/RectangleBuilder.java) - fixed leaf line object: - [LineBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/LineBuilder.java) + [LineBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/LineBuilder.java) - container: - [ModuleBuilder.java](../../src/test/java/com/demcha/compose/testsupport/engine/assembly/ModuleBuilder.java) + [ModuleBuilder.java](../../render-pdf/src/test/java/com/demcha/compose/testsupport/engine/assembly/ModuleBuilder.java) - template-level composition helper: [SectionDispatcher.java](../../templates/src/main/java/com/demcha/compose/document/templates/cv/components/SectionDispatcher.java)