You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Persistence: `fixtures/persistence-conformance/`. **Query** scenarios run on every port (TS / C# / Java / Kotlin / Python), each provisioning its test DB by executing the committed, TS-produced `canonical/schema.postgres.sql` (Postgres only — Derby dropped for the cross-port query corpus, ADR-0015). The **migration** scenarios are exercised by **TS only** (TS owns schema migrations).
35
+
- Persistence: `fixtures/persistence-conformance/`. **Query** scenarios run on every port (TS / C# / Java / Kotlin / Python), each provisioning its test DB by executing the committed, TS-produced `canonical/schema.postgres.sql` (Postgres only — Derby dropped for the cross-port query corpus, ADR-0015). The **migration** scenarios are exercised by **TS only** (TS owns schema migrations). **The corpus now gates WRITES, not just reads (SP-H):** an `op: roundtrip` scenario type INSERTs through each port's runtime/ORM write codec (NOT raw SQL), reads the row back, and asserts the wire-normalized value. The `AllTypes` entity (`roundtrip-all-types.yaml`) carries one field of **every** persistable `field.*` subtype — string/int/long/double/float/decimal/boolean/date/time/timestamp(+tz)/currency/enum/uuid/object — so every subtype write+read round-trips through every port against Testcontainers PG. (`field.byte`/`field.short`/`field.class` were cut as non-functional registration-only stubs — the matrix tracks only genuinely-supported subtypes; see `fixtures/registry-conformance/README.md` → "Per-subtype write-round-trip matrix".)
36
36
- API-contract: `fixtures/api-contract-conformance/`. TS / C# / Java / Kotlin / Python all 20/20 — each port runs **two lanes**: a hand-rolled reference server AND its **generated** API artifact booted over HTTP (the deployed controller/routes; TS+C# full-stack vs Testcontainers PG, Java/Kotlin/Python generated controller + in-memory repo behind the consumer seam). The generated fan-out found 10 real deployment bugs golden snapshots missed.
37
37
- YAML / verify corpora green across the ports that ship those layers.
38
38
39
-
**Key cross-language features shipped:** FR5 family (a/b/c/d/e + WARN envelope-shape — actionable loader errors per ADR-0009); FR-003 (Java RDB runtime persistence + projections; schema migrations are TS-only — the Java migration engine was removed); FR-006 (template.output parser-on-receipt codegen per ADR-0010 in all 5 ports); FR-008 + FR-009 (cross-port REST API contract + 10 filter operators); FR-018 (M:N relationship codegen in all 5 ports — entity navigation + idiomatic ORM wiring [Drizzle m2m / EF Core `UsingEntity` / Spring repo+JPA / Exposed / Pydantic+route as the SQLAlchemy-secondary equivalent] + REST traversal `GET /<source-plural>/{id}/<relation>` + Tier-2 docs, gated by the shared api-contract m2m corpus in both lanes + persistence-conformance; the TanStack M:N client hook is a deferred client-ergonomics follow-up); source v2 paradigm (ADR-0007); metadata-ktx Kotlin facade; per-target output directories (TS codegen).
39
+
**Key cross-language features shipped:** FR5 family (a/b/c/d/e + WARN envelope-shape — actionable loader errors per ADR-0009); FR-003 (Java RDB runtime persistence + projections; schema migrations are TS-only — the Java migration engine was removed); FR-006 (template.output parser-on-receipt codegen per ADR-0010 in all 5 ports); FR-008 + FR-009 (cross-port REST API contract + 10 filter operators); FR-018 (M:N relationship codegen in all 5 ports — entity navigation + idiomatic ORM wiring [Drizzle m2m / EF Core `UsingEntity` / Spring repo+JPA / Exposed / Pydantic+route as the SQLAlchemy-secondary equivalent] + REST traversal `GET /<source-plural>/{id}/<relation>` + Tier-2 docs, gated by the shared api-contract m2m corpus in both lanes + persistence-conformance; the TanStack M:N client hook is a deferred client-ergonomics follow-up); SP-H (field-subtype end-to-end hardening: every concrete `field.*` subtype write+read round-trips cross-port via the persistence `op: roundtrip` gate; cut `field.byte`/`field.short`/`field.class` non-functional stubs; cross-port filter-op reconciliation for uuid/currency); source v2 paradigm (ADR-0007); metadata-ktx Kotlin facade; per-target output directories (TS codegen).
40
40
41
41
**Current release line.**`0.7.0-rc.2` accumulates the 0.6.x → 0.7.0 consumer-friction batch (stock `promptRender()` generator, `db`-parameter generated repo helpers per ADR-0008, Cloudflare Workers deploy recipe, CHANGELOG backfill + naming-convention docs) plus the FR5 + FR-003 Plan 4 + FR-006 Java work. GA promotion is the next release move.
**Status:** Designed (from the cross-port field-subtype audit; awaiting spec review before planning/execution)
4
+
**Status:****Phases 1-3 COMPLETE on branch `sp-g-registry-conformance` (Phase 4 finishing).** Cut `field.class` + `field.byte`/`field.short` (all ports + canonical); the persistence corpus now WRITES (`op: roundtrip`, `AllTypes` covers every persistable subtype) and is green on all 5 ports against Testcontainers PG; filter-op bands reconciled cross-port (uuid/currency) + a loader guard for `@filterable`-without-op-band + a filter-allowlist fixture; Java write-codecs (timestamp/currency/enum/native-uuid/time) + Spring `field.time` arm; TS decimal string-exact dataType; Kotlin runs the shared metamodel corpus + a mapper-`else` negative test; bare `field.object` rejected at load. Phase 4 (this unit): per-subtype matrix confirmed (every concrete `field.*` × metamodel / persistence-write-round-trip / codegen, all 5 ports — no residual hole) + docs.
5
+
6
+
**Validation — the write-gate (Theme 2) was the right call.** Making the corpus WRITE (not just read) is what surfaced the latent breakage "all corpora green" had masked, exactly as the spec predicted. The keystone (`op: roundtrip`) caught, per port: a **TS** enum-CHECK write defect; **Java** timestamp-write (generic `ObjectCodec` rejected `java.util.Date`), native-`uuid`-write, `field.time`-write, and jsonb-write hazards; a **Kotlin**`LocalTime`-write gap; a **C#** read-back-caching defect; and the **uuid/currency filter-op divergences** (filterable in TS, silently dropped elsewhere). None of these had a failing test before the write-gate existed — the structural complement to SP-G (which gated vocabulary) was the missing axis.
5
7
**Relates to:** the `field.byte`/`field.short` finding (a registration-only stub that worked nowhere — Kotlin codegen threw, Python mis-typed to `str`, TS emitted a `text` DB column, Java had no JDBC codec, zero functional tests; cut in `29057ad5`). The audit that followed proved byte/short was the canary, not the exception.
Copy file name to clipboardExpand all lines: spec/roadmap.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -60,6 +60,8 @@ _Last refreshed 2026-05-30._
60
60
-**OMDB Spring Boot 3 starter** (shipped 2026-05-30). Autoconfiguration wires a `DataSource` → `ObjectManagerDB` with Spring-tx; closes the OMDB-modernization open question (jOOQ migration ruled out as a non-goal).
61
61
-**FR-008/FR-009 — Cross-port REST API contract + 10 filter operators.** Shipped in all 5 ports.
62
62
-**FR-018 — Many-to-many relationships.** Shipped in all 5 ports. Slim vocabulary (`@through`/`@sourceRefField`/`@symmetric`, with `@joinEntity`/`@joinFields` removed; FK fields derived from the junction's `identity.reference` SSOT) + a generic runtime M:N resolver (TS / Java / Kotlin / Python / C#) + codegen (entity navigation + idiomatic ORM wiring [Drizzle m2m / EF Core `UsingEntity` / Spring repo+JPA / Exposed / Pydantic+route as the SQLAlchemy-secondary equivalent]) + REST traversal (`GET /<source-plural>/{id}/<relation>`) + Tier-2 docs. Gated by the shared api-contract m2m corpus in both lanes (reference-server + generated-artifact-over-HTTP) + persistence-conformance, across hetero / directed-self-join / symmetric modes. Remaining: a typed TanStack M:N client hook (client-ergonomics follow-up). Designed in `docs/superpowers/specs/2026-06-02-fr-018-many-to-many-relationship-design.md`.
63
+
-**SP-G — registry-conformance gate.** Shipped in all 5 ports (TS / C# / Java / Kotlin / Python, live + green). A structural enforcer of the "metamodel subtype vocabularies must be identical across languages" contract: each port emits its registry as a canonical, fully-sorted, byte-stable JSON manifest matched to the single committed `fixtures/registry-conformance/expected-registry.json`. Reconciled the Java/Kotlin registries at source (the JVM runners compose from the defined metamodel provider set so codegen/om SPI doesn't pollute the measured vocabulary). Plus an untested-vocabulary coverage report (`coverage-report.json`) surfacing every registered `(type, subType)`/attr no fixture exercises. See `fixtures/registry-conformance/README.md`.
64
+
- **SP-H — field-subtype end-to-end hardening + write-path conformance.** Shipped in all 5 ports. Every concrete `field.*` subtype now write+read round-trips through each port's runtime/ORM, gated cross-port: the persistence corpus gained an `op: roundtrip` scenario type (INSERT via the port's write codec, NOT raw SQL → read-back → assert wire-normalized value) whose `AllTypes` entity carries one field of every persistable subtype against Testcontainers PG — the structural complement to SP-G (which gated vocabulary). Cut `field.byte`/`field.short`/`field.class` as non-functional registration-only stubs; reconciled uuid/currency filter-op bands cross-port + a loader guard for `@filterable`-without-op-band; Java write-codecs (timestamp/currency/enum/native-uuid/time) + Spring `field.time` arm; TS decimal string-exact dataType; Kotlin runs the shared metamodel corpus + a mapper-`else` negative test; bare `field.object` rejected at load (ADR-0013). The write-gate surfaced + drove latent breakage "all corpora green" had masked (TS enum-CHECK, Java timestamp/native-uuid/time/jsonb writes, Kotlin LocalTime-write, C# read-back-caching, the filter-op divergences). Designed in `docs/superpowers/specs/2026-06-03-sp-h-field-subtype-hardening-design.md`.
63
65
-**Per-target output directories (TS codegen).** Each generator routes to a named output target (`{ outDir, importBase?, outputLayout?, dbImport? }`).
64
66
-**0.6.x → 0.7.0 consumer-friction batch.** Stock `promptRender()` generator; `db`-parameter generated repo helpers (ADR-0008); Cloudflare Workers deploy recipe; CHANGELOG.md backfill + camelCase ↔ snake_case docs. (Currently published as `0.7.0-rc.2`; GA promotion is the next release move.)
0 commit comments