Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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.

Expand Down
24 changes: 12 additions & 12 deletions docs/contributing/extension-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -140,7 +140,7 @@ backend:
1. Implement `PdfFragmentRenderHandler<YourPayloadType>`. 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.
Expand Down Expand Up @@ -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.
Expand All @@ -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.
42 changes: 21 additions & 21 deletions docs/contributing/implementation-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@ types.

### Use `EmptyBox<T>` 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.

Expand All @@ -76,26 +76,26 @@ features such as `guideLines(true)` are not routed through `EntityManager`.

### Use `ShapeBuilderBase<T>` 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
- corner radius

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<T>` 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.

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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)

Expand Down