Skip to content

docs(api): add API stability policy (G3)#88

Merged
DemchaAV merged 1 commit into
developfrom
docs/api-stability-policy
May 31, 2026
Merged

docs(api): add API stability policy (G3)#88
DemchaAV merged 1 commit into
developfrom
docs/api-stability-policy

Conversation

@DemchaAV
Copy link
Copy Markdown
Owner

Summary

Wires up Track G3 (docs/api-stability-policy) from the 1.6.5→1.7 readiness taskboard — the third and final onboarding-clarity PR for the 1.6.6 Maven Central debut (after G1 #86 which-template-system and G2 #87 examples-maturity).

ADR-0003 defines the @Internal annotation mechanism, but there has been no user-facing policy that tells callers:

  • What "Stable" actually promises across patch / minor / major.
  • Where Extension SPI sits and what @Beta will mean once it lands.
  • That sealed hierarchies in Stable types can grow new permits in minor releases — and what that means for exhaustive switch code.
  • How long a @Deprecated element stays before it's removed.
  • Which package belongs to which tier without reading Javadoc per element.

The new page — docs/api-stability.md

Section What it answers
§1 Stability tiers The four tiers (Stable / Extension SPI / Internal / Experimental) with marker, scope, breaking-change rules, and the explicit promise each tier carries.
§2 Sealed hierarchy policy Additive permits in Stable sealed types must degrade gracefully (no default-branch failures); the CHANGELOG names every new public permit; @Internal sealed types are explicitly outside the policy. Pinned to the actual sealed types in repo.
§3 Deprecation window ≥ 1 minor release with @Deprecated for Stable / Extension SPI; removed in next major (Stable) or next minor with CHANGELOG callout (Extension SPI). Internal / Experimental: no window required. Worked example with pdf(Path) deprecation.
§4 Per-package tier Lookup table covering com.demcha.compose.* plus the legacy com.demcha.templates.* / com.demcha.compose.v2.* packages.
§5 What we don't promise No pixel-stable PDFs, no bit-stable artefact bytes, no sealed-permit exhaustiveness across minor releases for Stable hierarchies. Calls out the mismatchedPixelBudget(>0) discipline.
§6 References Cross-links to ADR-0003 / 0004 / 0011 / 0015 and the architecture guard tests that pin the policy in code.

Self-review caught two fixes before commit

Ran the senior-review lens over the draft before opening the PR. Two findings worth applying:

  1. "Track H2" references removed — the doc originally said "the @Beta annotation is planned for 1.6.6 — Track H2" four times. Internal taskboard terminology that a public reader doesn't know. Replaced with "near-term release" / "still pending" prose.
  2. §2 sealed list cleaned up — original lumped ParagraphSpan (@Internal) and PlacementContext (Internal) in with the Stable sealed types, contradicting the §4 tier mapping. Now §2 lists only the public sealed types (each marked with its tier) and explicitly excludes the Internal ones.

Guard allowlist change

CanonicalSurfaceGuardTest.publicMarkdownDocsShouldAvoidLegacySurfaceOutsideHistoricalAuditNotes scans public docs for legacy API tokens. The §4 tier table and §3 deprecation example name retired types on purpose (same audit-log precedent the v1.5→v1.6 migration log and the G1 which-template-system page already set). Adding docs/api-stability.md to PUBLIC_MARKDOWN_ALLOWLIST with the in-code comment explaining why.

Verification

$ ./mvnw -B -ntp test -pl . \
    -Dtest='CanonicalSurfaceGuardTest,DocumentationCoverageTest,DocumentationExamplesTest,VersionConsistencyGuardTest'
Tests run: 30, Failures: 0, Errors: 0, Skipped: 0

The taskboard G3 gate is doc-guard; green.

CHANGELOG entry added to v1.6.6 — Planned under the existing ### Documentation subsection alongside G1 and G2.

Test plan

  • Doc guards green
  • §4 tier mapping and §2 sealed list are internally consistent (no Internal sealed types listed under Stable policy)
  • All cross-links to ADR-0003 / 0004 / 0011 / 0015 / Internal.java / guard tests resolve on disk
  • CI green on PR
  • Reviewer skim — §1 tier matrix, §2 sealed policy, §3 deprecation table, §4 package lookup are the load-bearing sections
  • (Out of scope) follow-up: when @Beta lands in a future PR, drop the "near-term release" hedge in §1 and §2 and add the annotation to the appropriate Extension SPI types — coordinate updates to this page in the same commit

Wires up Track G3 from the v1.6.5→1.7 readiness taskboard — the third
and final onboarding-clarity PR for the 1.6.6 Maven Central debut
(after G1 which-template-system #86 and G2 examples-maturity #87).

ADR-0003 defines the @internal annotation mechanism, but there has
been no user-facing policy that tells callers:

- What "Stable" actually promises across patch / minor / major.
- Where Extension SPI sits and what the @beta annotation will mean
  once it lands.
- That sealed hierarchies in Stable types can grow new permits in
  minor releases — and what that means for exhaustive switch code.
- How long a @deprecated element stays before it goes away.
- Which package belongs to which tier without reading Javadoc per
  element.

docs/api-stability.md is the user-facing policy:

  §1 Stability tiers     — Stable / Extension SPI / Internal / Experimental
                           with marker, scope, breaking-change rules, and
                           the explicit promise each tier carries.
  §2 Sealed hierarchies  — additive permits must degrade gracefully
                           without default-branch failures; CHANGELOG
                           names every new public permit; @internal
                           sealed types are explicitly outside the policy.
  §3 Deprecation window  — ≥ 1 minor release with @deprecated for
                           Stable / Extension SPI; removed in next
                           major (Stable) or next minor with CHANGELOG
                           callout (Extension SPI). Internal /
                           Experimental: no window required.
  §4 Per-package tier    — lookup table covering com.demcha.compose.*
                           plus the legacy packages.
  §5 Anti-policy         — what we explicitly do NOT promise (pixel-
                           stable PDFs, bit-stable bytes, sealed-permit
                           exhaustiveness in Stable across minor
                           releases).
  §6 References          — cross-links to ADR-0003 / 0004 / 0011 / 0015
                           and the architecture guard tests that pin
                           the policy in code.

CanonicalSurfaceGuardTest.PUBLIC_MARKDOWN_ALLOWLIST gains a new entry
for docs/api-stability.md (same audit-log precedent as the G1
which-template-system page and the v1.5→v1.6 migration log) — the
§4 tier table and §3 deprecation example name retired legacy types
on purpose.

Cross-links from §1 and §4 point at G1's which-template-system page
for the template-surface migration path; the two pages reference
each other naturally (templates page covers template surfaces; this
page covers everything else).

Verification:
- ./mvnw -B -ntp test -pl . -Dtest='CanonicalSurfaceGuardTest,DocumentationCoverageTest,DocumentationExamplesTest,VersionConsistencyGuardTest'
  -> 30 tests, 0 failures, 0 errors (~19s)

CHANGELOG entry added to v1.6.6 — Planned under the existing
### Documentation subsection alongside G1 and G2.
@DemchaAV DemchaAV force-pushed the docs/api-stability-policy branch from cf62726 to 9f7c2ae Compare May 31, 2026 11:25
@DemchaAV DemchaAV merged commit f4b16db into develop May 31, 2026
9 checks passed
@DemchaAV DemchaAV deleted the docs/api-stability-policy branch May 31, 2026 11:28
DemchaAV added a commit that referenced this pull request May 31, 2026
)

Wires up Track H2 from the v1.6.5->1.7 readiness taskboard. Adds the @beta annotation that the G3 stability policy (#88) referenced as the planned Extension SPI / Experimental marker, applies it to the first concrete Extension SPI seam, and lifts the 'pending' hedges in the policy doc.

Changes:

- New com.demcha.compose.document.api.Beta annotation, sibling to @internal. Same retention/target/contract shape as @internal so guard tests handle both uniformly; lives next to @internal so IDE autocomplete surfaces both markers.

- @beta applied to com.demcha.compose.document.layout.NodeDefinition - the canonical custom-node-type seam carved out of the otherwise @internal document.layout package. The interface Javadoc now explains the Extension SPI contract and links the stability policy.

- BetaAnnotationDocumentationTest pins the annotation contract (retention, @documented, target set, source-Javadoc invariants, same-package-as-@internal) in the same shape InternalAnnotationDocumentationTest pins @internal.

- docs/api-stability.md: @beta annotation reference cells in section 1 are no longer hedged as 'pending'; the associated quote block lists both markers side-by-side with the guard tests.

- docs/architecture/package-map.md: new intro paragraph documents the stability-marker convention; document.layout row now calls out NodeDefinition as the current @beta seam.

Suite: 1029 tests, 0 failures, 0 errors (+5 from BetaAnnotationDocumentationTest).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant