Files
alkgen/tasks/implementation/w3-release-readiness.md
T

11 KiB

id, name, status, depends_on, scope, risk, impact, level
id name status depends_on scope risk impact level
w3-release-readiness Wave 3: release readiness (README, CHANGELOG, rustdoc, package posture, freeze inventory) completed
moderate low phase implementation

Description

Everything v0.1.0 needs to be publish-honest except the publish itself. The crate's code surface is frozen (waves 1 and 2 landed it and the reviews passed clean); this task is the surface a reader, a downloader, and the gate meet.

  • README rewrite (the plan's wave-3 bullet; the current README still carries the pre-plan framing: the codegen-engine status line and the alktype dependency reference, both stale since the consumer steer and w1-manifest): the engine framing (ADR-001: handlebars templates over serde-serializable contexts, strict, deterministic, synchronous, wasm-clean, library-only ADR-010), the one-registry-per-set surface (TemplateSet, EscapePolicy, Error) with usage examples (kept honest with the crate docs: compile-checked doctests in src/lib.rs), the integration-pattern section (emit.md: posture-B usage for alkforge's SSR, the documented posture-A build-script pattern per ADR-010, the posture-C note), and the consumer-owned-template-set statement (ADR-008: v0.1.0 ships no engine-owned sets; the ssr-html target is proven in-crate by fixtures, targets.md).
  • CHANGELOG 0.1.0: Keep a Changelog shape (the alkssh precedent), listing the shipped public surface and postures.
  • Public-API rustdoc warning-free: cargo doc --no-deps clean, with the usage examples compile-checked as doctests so the README and the crate docs say the same thing.
  • The package posture: cargo publish --dry-run --allow-dirty plus a cargo package --list check; the exclude list verified against what actually ships (SDD process docs, research, plans, and tasks are working documents, not crate payload: the current list omits docs/plans/ and tasks/; the task fixes the list). The architecture docs ship (the alkssh precedent: they are the crate's design record, not scratch work).
  • The freeze inventory for the gate (the plan's wave-3 bullet; carries wave-1 gate reminder (a)): the public API shape (TemplateSet, EscapePolicy, Error), the strict-mode and determinism postures, the error enum's evolution policy, the handlebars 6.4 pin's behavior; the #[non_exhaustive] question decided explicitly with written rationale, landing as the decision itself in src/error.rs if the decision is to adopt it.

No new engine surface; a freeze decision that touches src/ lands in this task and is re-verified by the full set.

Acceptance Criteria

  • README rewritten on the shipped framing (no stale codegen status, no alktype dependency reference); the integration postures (A documented build-script pattern, B for alkforge, C note) present per the plan
  • CHANGELOG 0.1.0 in place, Keep a Changelog shape
  • cargo doc --no-deps warning-free; usage examples compile-checked as doctests (cargo test runs them)
  • exclude list fixed (docs/plans/, tasks/ added); cargo package --list checked against the package policy and recorded
  • cargo publish --dry-run --allow-dirty clean
  • the freeze inventory recorded for the gate, with the #[non_exhaustive] posture decided explicitly (the decision landed in src/error.rs if adopted) and the evolution policy written down
  • full verification set green: cargo test, cargo test --all-features, cargo clippy --all-targets -- -D warnings, cargo fmt --check, cargo doc --no-deps, cargo build --target wasm32-unknown-unknown --release, taskgraph validate

References

  • docs/plans/implementation.md (wave 3, the release-readiness bullet)
  • docs/architecture/core.md, emit.md (the postures the README documents), targets.md (the activation queue the README reports)
  • docs/architecture/decisions/001-one-core-template-set-targets.md
  • docs/architecture/decisions/003-core-posture-sync-wasm-deterministic.md
  • docs/architecture/decisions/008-template-set-ownership.md
  • docs/architecture/decisions/010-library-only-no-cli.md
  • tasks/implementation/review-wave-1.md (reminder (a): the freeze inventory decides #[non_exhaustive])
  • /workspace/@alkdev/alkssh README.md + CHANGELOG.md (the sibling release-artifact shape this mirrors)

Notes

Landed 2026-11-07, over the wave-2 tree, in four pieces:

  • The freeze decision (wave-1 gate reminder (a), dispositioned): Error is now #[non_exhaustive], with the evolution policy on the public doc comment and in the CHANGELOG. Rationale: the wave-1 gate confirmed the enum's documented evolution is additive (the context-build error arm lands with the first engine-owned set, per ADR-008's consumer-builders-own-their-errors line), non- exhaustiveness makes that future addition non-breaking for downstream match sites, and the posture had to land at the freeze itself (flipping an exhaustive enum to non-exhaustive post-publish is itself a breaking change for exhaustive matchers). The cost is the standard wildcard arm. EscapePolicy deliberately stays exhaustive: ADR-005 fixes the policy set at two, the expected consumer interaction is construction (an argument to TemplateSet::new), not matching, and a new policy is a new ADR arriving pre-1.0 if ever. This is the only src/ change in the task; no behavior change (in-crate matching is unaffected; all 53 tests pass).
  • README rewrite: full replacement on the shipped engine framing. The old text's stale claims (codegen-engine status line, alktype as a dependency reference, phase-0 status) are gone. New: the engine contract (seven bullets, each traceable to code or a pinned test), a usage example with the Ok::<(), alkgen::Error> return shape (mirrored by the crate docs' doctests so both stay honest), the three integration postures per emit.md (build-script with the emit-layer banner convention; SSR for alkforge with the determinism-underwrites-caching note; the render-to-compile note), an explicit "what 0.1.0 does not ship" section (no engine-owned sets; bast-codegen gates nothing; the ADR-008 fixture-proven posture stated), and the design-record pointer (docs/architecture/ ships in the package).
  • CHANGELOG 0.1.0: Keep a Changelog shape: Added (the public surface, itemized against the actual code), Guarantees (the determinism/strict-mode/wasm postures as standing verification rows), and the error-evolution-policy paragraph. Links the 0.1.0 tag.
  • Package posture: exclude fixed to add docs/plans/ and tasks/ (both were shipping before; the package now carries only src, tests + fixtures, the architecture docs, README, CHANGELOG, both licenses, and the manifests, verified by cargo package --list --allow-dirty; no AGENTS.md, .opencode/, docs/research/, docs/sdd_process.md, docs/reviews/, docs/plans/, or tasks/). The dry-run is clean: 48 files, 199.6KiB, package compile verification passed.
  • Rustdoc: two usage doctests added in the crate docs (the String sink and the write sink, each with assertions); cargo doc --no-deps warning-free; doctests run in cargo test (19 lib + 13 conformance + 7 code_proof + 4 ssr_proof + 5 code_fixtures + 3 ssr_fixtures + 2 doctests = 53 passing).

Verification run on the final readiness tree (all green): cargo test (53), cargo test --all-features (identical; the coincide holds), cargo clippy --all-targets -- -D warnings (clean), cargo fmt --check (clean), cargo doc --no-deps (warning-free), cargo build --target wasm32-unknown-unknown --release (clean), taskgraph validate (21 tasks valid), the standing em-dash grep (zero hits), the tree inspection (handlebars v6.4.4 default only, no dir_source, no script_helper).

The freeze inventory for the gate:

  • Public API shape (frozen): TemplateSet (new(EscapePolicy), register_template(&str, &str) -> Result<(), Error>, register_partial(&str, &str) -> Result<(), Error>, register_helper(&str, Box<dyn HelperDef + Send + Sync>), is_template(&str) -> bool, render<T: Serialize>(&str, &T) -> Result<String, Error>, render_to_write<T: Serialize, W: Write>), EscapePolicy (Html, NoOp, exhaustive, derives Clone/Copy/Debug/PartialEq/Eq), Error (non-exhaustive; Registration(TemplateError), Render(RenderError), both From. Variant additions: semver-minor, non-breaking for match sites by the non-exhaustive posture; variant removals or signature changes: semver-major). No other public items.
  • Strict-mode posture (frozen): forced on at construction, not parameterizable; a missing variable is a typed Error::Render in both sinks, never silent output. Backed by tests/conformance.rs's strict-mode matrix.
  • Determinism posture (frozen): byte-identical across repeated renders, registry rebuilds, registration orders, fresh contexts, and sinks. Backed by the conformance battery and unit tests. This is the surface alkforge's caching and any consumer's regression pin stand on.
  • Purity posture (frozen): no panics through the API (malformed input is data), no filesystem, no threads, no time, no environment reads; wasm-clean under ADR-003 as a standing verification gate.
  • The handlebars 6.4 pin's behavior (frozen surface): strict-mode semantics, default HTML escaper, TemplateError/RenderError reachable through Error's source chain, helpers via HelperDef, the no-atomicity streaming write sink, and the recorded substrate observation that the expression name raw is keyword-shaped (rendered empty even in strict mode; documented in the battery's Notes as data, with the avoidance reason in its doc comment). The 6.4 requirement is a caret requirement: ADR-002's recorded behavior is pinned against 6.4.x; a substrate major bump that changes any frozen behavior above is a semver event for this crate.
  • Context posture (frozen): serde_json preserve_order load-bearing and pinned by the code proof; context field order drives packed output order for code-shaped sets.

Summary

Release readiness landed: README rewritten on the shipped framing with all three integration postures, CHANGELOG 0.1.0 in the Keep a Changelog shape, two compile-checked usage doctests in the crate docs, the package exclude list fixed so only intended payload ships (dry-run clean, 48 files), and the freeze inventory recorded with the carried #[non_exhaustive] reminder dispositioned: adopted on Error (landing in src, no behavior change), declined on EscapePolicy, both argued. Full verification set green including wasm and the tree inspection. review-wave-3 is unblocked.