diff --git a/CHANGELOG.md b/CHANGELOG.md index a6f19ad3..ae820fab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,39 @@ JitPack continue to resolve through the existing coordinates. Method-level `@since` backfill for the ~380 public methods in these packages is intentionally out of scope here and tracked separately. +### Public API + +- **New `@Beta` annotation** (Track H2). Companion to the existing + [`@Internal`](src/main/java/com/demcha/compose/document/api/Internal.java) + marker: + [`com.demcha.compose.document.api.Beta`](src/main/java/com/demcha/compose/document/api/Beta.java) + signals an **Extension SPI** or **Experimental** surface — a + deliberately-exposed seam library users can implement or call, but + whose shape may still evolve between minor releases per the + [API stability policy](docs/api-stability.md) § 1. First application: + [`com.demcha.compose.document.layout.NodeDefinition`](src/main/java/com/demcha/compose/document/layout/NodeDefinition.java) + — the canonical custom-node-type seam, carved out of the otherwise + `@Internal` `document.layout` package. New + `BetaAnnotationDocumentationTest` pins the annotation's retention / + target / `@Documented`-ness / source-Javadoc contract in the same + shape `InternalAnnotationDocumentationTest` already pins for + `@Internal`. Additional Extension SPI surfaces (render-handler + interfaces, fragment-payload interfaces) will gain the marker + incrementally as their contract solidifies. + +### Documentation + +- **`docs/architecture/package-map.md` updated** alongside H2. A new + intro paragraph documents the stability-marker convention (Stable + default; engine packages are package-level `@Internal`; individual + Extension SPI seams carved out of `@Internal` packages carry + `@Beta`), and the `document.layout` row calls out `NodeDefinition` + as the current `@Beta` seam. +- **`docs/api-stability.md` revised** alongside H2 — `@Beta` annotation + reference cells in §1 are no longer hedged as "pending"; the + associated quote block lists both annotations side-by-side with the + guard tests that pin them. + ### Engine internals (no behaviour change) - **`RowSlots` helper extracted** from `LayoutCompiler` and diff --git a/docs/api-stability.md b/docs/api-stability.md index 6a053cbc..46e0b3af 100644 --- a/docs/api-stability.md +++ b/docs/api-stability.md @@ -30,18 +30,22 @@ matrix. |---|---|---|---| | **Stable** | _(default — no annotation)_ | The canonical authoring surface that user code is meant to call: `GraphCompose.document(...)`, `DocumentSession`, `DocumentDsl`, `RowBuilder` / `SectionBuilder` / `ParagraphBuilder` and friends, `DocumentInsets` / `DocumentColor` / `DocumentTextStyle`, the `BusinessTheme` and `CvTheme` factories, the recommended template presets in `cv.v2.*` and `coverletter.v2.*`. | **Major releases only.** | | **Supported** | _(no annotation; called out in the page's Javadoc)_ | A canonical surface that ships through 1.x but won't be in 2.0 — its replacement is already the Stable path. The `cv.presets.*` "classic" CV preset surface is the only Supported tier in 1.x today (replaced by `cv.v2.*` per [`which-template-system.md`](templates/which-template-system.md)). Bug fixes + behaviour-preserving refactors only. | **Minor releases for behaviour-preserving refactors; removed wholesale in 2.0.** | -| **Extension SPI** | `@Beta` _(annotation arriving in a near-term 1.6.x release; this row already describes the policy that will apply)_ | Public extension points that authors are expected to **implement**, not only call: render-handler interfaces, `NodeDefinition`, custom `Theme` subtype contracts, fragment payload interfaces designed for extension. | Minor releases, with a one-minor deprecation window where possible. | -| **Experimental** | `@Beta` _(same annotation as Extension SPI; the distinction lives in the docstring)_ | A brand-new public type shipping in its first minor release before its contract has stabilised. The contract is in active flux. | Any minor release, including removal. No deprecation window. | +| **Extension SPI** | [`@Beta`](../src/main/java/com/demcha/compose/document/api/Beta.java) | Public extension points that authors are expected to **implement**, not only call: render-handler interfaces, [`NodeDefinition`](../src/main/java/com/demcha/compose/document/layout/NodeDefinition.java), custom `Theme` subtype contracts, fragment payload interfaces designed for extension. | Minor releases, with a one-minor deprecation window where possible. | +| **Experimental** | [`@Beta`](../src/main/java/com/demcha/compose/document/api/Beta.java) _(same annotation as Extension SPI; the distinction lives in the docstring on the annotated element)_ | A brand-new public type shipping in its first minor release before its contract has stabilised. The contract is in active flux. | Any minor release, including removal. No deprecation window. | | **Internal** | [`@Internal`](../src/main/java/com/demcha/compose/document/api/Internal.java) (per-element or per-package) | Engine surface: everything in `com.demcha.compose.document.layout.*`, `com.demcha.compose.engine.*`, render-pipeline payload records, `LayoutCompiler`, `NodeDefinitionSupport`, the placement / measure / split contracts. Technically `public` for cross-package collaboration; not part of the contract. Canonical list lives in [ADR-0003](adr/0003-api-stability-and-internal-marker.md) § *Coverage*. | **Any release.** No deprecation window, no CHANGELOG entry required. | | **Legacy** | _(no annotation today; flagged in [`which-template-system.md`](templates/which-template-system.md) § 4 and in CHANGELOG `### Deprecations`)_ | Pre-rebuild surface kept only so downstream callers from before the v1.6 rebuild keep compiling: `com.demcha.templates.*` (the original `MainPageCV` / `MainPageCvDTO` / `ModuleYml` / `TemplateBuilder` family), `com.demcha.compose.v2.*` (the original engine-direct builders). Frozen — bug fixes only. | **Removed in 2.0**; no patch / minor changes other than security fixes. | -> The repo's [`@Internal`](../src/main/java/com/demcha/compose/document/api/Internal.java) -> annotation already exists and is enforced by -> [`InternalAnnotationCoverageTest`](../src/test/java/com/demcha/documentation/InternalAnnotationCoverageTest.java) -> and `InternalAnnotationDocumentationTest`. The `@Beta` annotation is -> still pending — until it lands, Extension SPI and Experimental tiers -> are signalled in Javadoc prose only; this page describes the policy -> the annotation will encode once it ships. +> Both marker annotations +> ([`@Internal`](../src/main/java/com/demcha/compose/document/api/Internal.java) +> and [`@Beta`](../src/main/java/com/demcha/compose/document/api/Beta.java)) +> live in the public `document.api` package and are pinned by +> [`InternalAnnotationCoverageTest`](../src/test/java/com/demcha/documentation/InternalAnnotationCoverageTest.java), +> `InternalAnnotationDocumentationTest`, and `BetaAnnotationDocumentationTest`. +> The Extension SPI seam currently carrying `@Beta` is +> [`NodeDefinition`](../src/main/java/com/demcha/compose/document/layout/NodeDefinition.java); +> additional Extension SPI surfaces (render-handler interfaces, +> fragment-payload interfaces designed for extension) will gain the +> marker incrementally as their contract solidifies. ### What each tier promises diff --git a/docs/architecture/package-map.md b/docs/architecture/package-map.md index becd8093..fdf3f786 100644 --- a/docs/architecture/package-map.md +++ b/docs/architecture/package-map.md @@ -2,6 +2,17 @@ This document is the source of truth for production package ownership in the canonical engine branch. +**Stability markers.** Public packages default to the **Stable** tier of the +[API stability policy](../api-stability.md). Engine packages (`com.demcha.compose.engine.*`, +`com.demcha.compose.document.layout`, render-pipeline internals) carry the +[`@Internal`](../../src/main/java/com/demcha/compose/document/api/Internal.java) +marker at the package level; individual types deliberately exposed as +Extension SPI inside an `@Internal` package carry +[`@Beta`](../../src/main/java/com/demcha/compose/document/api/Beta.java) +on the type itself (`NodeDefinition` is the current example). The +"Extension rule" column below names the extension seam where one is +intended. + ## Public Authoring Surface | Package | Responsibility | Extension rule | @@ -20,7 +31,7 @@ This document is the source of truth for production package ownership in the can | Package | Responsibility | Extension rule | | --- | --- | --- | -| `com.demcha.compose.document.layout` | Semantic layout compiler, node definitions, fragments, split/measure contracts, and layout graph. | New node behavior must be deterministic and covered by layout or render tests. | +| `com.demcha.compose.document.layout` (`@Internal` at package level) | Semantic layout compiler, node definitions, fragments, split/measure contracts, and layout graph. | `NodeDefinition` is `@Beta` — Extension SPI for custom node types. New node behavior must be deterministic and covered by layout or render tests. | | `com.demcha.compose.document.backend.fixed` | Backend-neutral fixed-layout rendering contract. | Keep it independent from PDFBox and semantic template data. | | `com.demcha.compose.document.backend.fixed.pdf` | Canonical fixed-layout PDF backend, fragment handlers, PDF-specific options, and PDF-backed measurement resources. | Keep PDFBox lifecycle internal; normal callers should use `DocumentSession` and default PDF convenience methods. | | `com.demcha.compose.document.dsl.internal` | Internal helpers for public DSL builders such as semantic name normalization and builder callback application. | Do not expose these helpers in examples; move reusable authoring concepts to public builder classes instead. | diff --git a/src/main/java/com/demcha/compose/document/api/Beta.java b/src/main/java/com/demcha/compose/document/api/Beta.java new file mode 100644 index 00000000..15ac146b --- /dev/null +++ b/src/main/java/com/demcha/compose/document/api/Beta.java @@ -0,0 +1,58 @@ +package com.demcha.compose.document.api; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks a public API element as an Extension SPI or + * Experimental surface — a deliberately-exposed seam that + * library users can implement or call, but whose shape may still change + * between minor releases. + * + *
Elements annotated {@code @Beta} carry the policy spelled out in + * + * the API stability policy § 1 — broadly:
+ * + *The distinction between the two usages lives in the element's own + * Javadoc, not in this annotation. The annotation itself just signals + * "policy applies — read the page before depending on this".
+ * + *If your use case requires a stable contract over an + * {@code @Beta}-marked element, please open an issue at + * the + * GraphCompose tracker so the stabilisation can be prioritised.
+ * + *Architecture guard tests may consume this annotation reflectively; + * the runtime retention is intentional.
+ * + * @see Internal + * @since 1.6.6 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ + ElementType.TYPE, + ElementType.METHOD, + ElementType.FIELD, + ElementType.CONSTRUCTOR, + ElementType.PACKAGE, +}) +public @interface Beta { +} diff --git a/src/main/java/com/demcha/compose/document/layout/NodeDefinition.java b/src/main/java/com/demcha/compose/document/layout/NodeDefinition.java index 9347f290..e4e253d2 100644 --- a/src/main/java/com/demcha/compose/document/layout/NodeDefinition.java +++ b/src/main/java/com/demcha/compose/document/layout/NodeDefinition.java @@ -1,5 +1,6 @@ package com.demcha.compose.document.layout; +import com.demcha.compose.document.api.Beta; import com.demcha.compose.document.node.DocumentNode; import java.util.List; @@ -7,8 +8,21 @@ /** * Prepare, split, and fragment emission contract for a semantic node type. * + *Extension SPI seam. This interface is the deliberately-public + * extension point inside the otherwise {@link com.demcha.compose.document.api.Internal + * @Internal} {@code document.layout} package: library users implementing + * custom node types reach for it. The implementation contract — the + * shape of {@link PrepareContext}, {@link FragmentContext}, + * {@link BoxConstraints}, {@link MeasureResult}, and friends — may + * evolve in a minor release, with a one-minor deprecation window where + * possible. See the + * API stability policy + * § 1 (Extension SPI row) for the full contract.
+ * * @param