Skip to content

Commit 4f2d459

Browse files
dmealingclaude
andcommitted
Merge R6 Plan 1: cross-port float/double fidelity (field.float → REAL)
field.float now emits SQL REAL (float4, single precision), distinct from field.double → DOUBLE PRECISION (float8), across all five ports (TS/C#/Java/ Python/Kotlin), with a REAL/DOUBLE plain-decimal wire-normalization rule. Verified end-to-end: the new Measurement persistence-conformance entity round-trips REAL/DOUBLE byte-identically across all five ports against Testcontainers Postgres, with DDL-level "tempC" REAL / "massKg" DOUBLE PRECISION type assertions gating the REAL-vs-DOUBLE distinction (the dyadic round-trip values alone cannot). R6 Plan 2 (uuid + @dbColumnType + timestamptz + jsonb) remains. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2 parents 9b5fa91 + b96f70a commit 4f2d459

54 files changed

Lines changed: 752 additions & 30 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/superpowers/specs/2026-05-29-conformance-hardening-review.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Siblings of the CLI gap — a port can silently lack or diverge on these and sta
6969
| R3 | **Refresh `spec/conformance-tests.md`** — 5 ports, 7 corpora, fix Java-verify + Drizzle/jOOQ staleness, reclassify codegen as "semantic parity, byte-equivalence excluded" | 4 | doc edit | low — do early; it's the governing contract |
7070
| R4 |**DONE (2026-05-29, `cc69ced0`).** `integration-tests.yml` now runs the persistence + api-contract matrix (all 5 ports) on every `pull_request` to `main`, not just release tags / opt-in label — so drift can't merge to main green. | 1 | CI wiring | done |
7171
| R5 |**DONE (2026-05-29, ADR-0014).** Fixed at the core: Java `addChild` now validates against the owning loader's registry (not the global singleton); runner composes a per-fixture registry. Multi-tenant correctness fix, not just a test cleanup. | 1 | core change + runner refactor | done |
72-
| R6 | **Define the float/double normalization rule**, then add float + uuid persistence + loader fixtures | 3 | `normalization.md` rule + fixtures + a uuid in the canonical entity | med — R6a (rule) blocks R6b (fixtures) |
72+
| R6 | **Plan 1 (float/double fidelity) DONE (2026-05-29).** `normalization.md` REAL/DOUBLE plain-decimal rule + loader fixtures + `field.float`→REAL (float4) distinct from `field.double`→DOUBLE PRECISION in all 5 ports + the `Measurement` persistence entity (cross-port round-trip **and** DDL `REAL`/`DOUBLE PRECISION` type assertions). Commits `4e4a7253` (Java), `163ef5a6` (Kotlin), `fdafa1eb` (Measurement), + earlier TS/C#/Python on the branch. **Plan 2 (uuid fixtures + `@dbColumnType` + timestamptz + jsonb) still pending.** | 3 | `normalization.md` rule + fixtures + uuid | float done; **uuid/`@dbColumnType` → Plan 2** |
7373
| R7 | **Kotlin render runner** (or drop Kotlin from the byte-identical claim in CLAUDE.md) | 1/2 | new Kotlin render-conformance test, or doc edit | low-med |
7474
| R8 | **Register `WARN_*` codes** in `ERROR-CODES.json`; migrate the 3 legacy string-list warnings to FR5c envelope shape | 3 | fixtures + ERROR-CODES.json | low |
7575
| R9 | **Add missing negative fixtures** for the live ERR codes (finding #14), starting with `ERR_SUBTYPE_RULE_VIOLATION` | 3 | fixtures | med |
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme",
4+
"children": [
5+
{
6+
"object.entity": {
7+
"name": "Reading",
8+
"children": [
9+
{
10+
"field.long": {
11+
"name": "id"
12+
}
13+
},
14+
{
15+
"field.decimal": {
16+
"name": "amount",
17+
"@precision": 12,
18+
"@scale": 2
19+
}
20+
},
21+
{
22+
"identity.primary": {
23+
"@fields": [
24+
"id"
25+
]
26+
}
27+
}
28+
]
29+
}
30+
}
31+
]
32+
}
33+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme",
4+
"children": [
5+
{
6+
"object.entity": {
7+
"name": "Reading",
8+
"children": [
9+
{ "field.long": { "name": "id" } },
10+
{ "field.decimal": { "name": "amount", "@precision": 12, "@scale": 2 } },
11+
{ "identity.primary": { "@fields": "id" } }
12+
]
13+
}
14+
}
15+
]
16+
}
17+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme",
4+
"children": [
5+
{
6+
"object.entity": {
7+
"name": "Reading",
8+
"children": [
9+
{
10+
"field.long": {
11+
"name": "id"
12+
}
13+
},
14+
{
15+
"field.double": {
16+
"name": "amounts",
17+
"isArray": true
18+
}
19+
},
20+
{
21+
"identity.primary": {
22+
"@fields": [
23+
"id"
24+
]
25+
}
26+
}
27+
]
28+
}
29+
}
30+
]
31+
}
32+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme",
4+
"children": [
5+
{
6+
"object.entity": {
7+
"name": "Reading",
8+
"children": [
9+
{ "field.long": { "name": "id" } },
10+
{ "field.double": { "name": "amounts", "isArray": true } },
11+
{ "identity.primary": { "@fields": "id" } }
12+
]
13+
}
14+
}
15+
]
16+
}
17+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme",
4+
"children": [
5+
{
6+
"object.entity": {
7+
"name": "Reading",
8+
"children": [
9+
{
10+
"field.long": {
11+
"name": "id"
12+
}
13+
},
14+
{
15+
"field.double": {
16+
"name": "amount"
17+
}
18+
},
19+
{
20+
"identity.primary": {
21+
"@fields": [
22+
"id"
23+
]
24+
}
25+
}
26+
]
27+
}
28+
}
29+
]
30+
}
31+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme",
4+
"children": [
5+
{
6+
"object.entity": {
7+
"name": "Reading",
8+
"children": [
9+
{ "field.long": { "name": "id" } },
10+
{ "field.double": { "name": "amount" } },
11+
{ "identity.primary": { "@fields": "id" } }
12+
]
13+
}
14+
}
15+
]
16+
}
17+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme",
4+
"children": [
5+
{
6+
"object.entity": {
7+
"name": "Reading",
8+
"children": [
9+
{
10+
"field.long": {
11+
"name": "id"
12+
}
13+
},
14+
{
15+
"field.float": {
16+
"name": "amount"
17+
}
18+
},
19+
{
20+
"identity.primary": {
21+
"@fields": [
22+
"id"
23+
]
24+
}
25+
}
26+
]
27+
}
28+
}
29+
]
30+
}
31+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme",
4+
"children": [
5+
{
6+
"object.entity": {
7+
"name": "Reading",
8+
"children": [
9+
{ "field.long": { "name": "id" } },
10+
{ "field.float": { "name": "amount" } },
11+
{ "identity.primary": { "@fields": "id" } }
12+
]
13+
}
14+
}
15+
]
16+
}
17+
}

fixtures/persistence-conformance/canonical/meta.fitness.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@
2727
{ "identity.reference": { "name": "fkProgram", "@fields": "programId", "@references": "Program" } }
2828
]
2929
}},
30+
{ "object.entity": {
31+
"name": "Measurement",
32+
"children": [
33+
{ "source.rdb": { "@table": "measurements" } },
34+
{ "field.long": { "name": "id" } },
35+
{ "field.float": { "name": "tempC", "@required": true } },
36+
{ "field.double": { "name": "massKg", "@required": true } },
37+
{ "identity.primary": { "@fields": "id", "@generation": "increment" } }
38+
]
39+
}},
3040
{ "object.entity": {
3141
"name": "ProgramView",
3242
"children": [

0 commit comments

Comments
 (0)