Skip to content

Commit f592d90

Browse files
committed
Merge worktree-fr5c-finalize-2026-05-27 — FR5c finalize (reconcile overlay-attr-last-writer-wins across all 4 ports)
2 parents b2ed10a + bf01621 commit f592d90

3 files changed

Lines changed: 20 additions & 5 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"errors": [
3+
{
4+
"code": "ERR_MERGE_CONFLICT",
5+
"source": {
6+
"format": "merged",
7+
"files": [
8+
"meta.commerce.json",
9+
"meta.commerce.overlay.json"
10+
]
11+
}
12+
}
13+
],
14+
"warnings": []
15+
}
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
{
22
"language": "csharp",
33
"_comment": "FR5a envelope-shape gates: TS is the reference port for source.format / source.files / source.jsonPath. C# is now reconciled with TS on the JSON-side FR5a envelopes (parser malformed-JSON catch builds a $-rooted JsonSource with the source-file name; inline-attr loop reports ERR_RESERVED_ATTR / ERR_UNKNOWN_ATTR / ERR_BAD_ATTR_VALUE at the parent's path — not key-deeper). Keep this file as the documented ledger surface.",
4-
"_notes": "FR5c (2026-05-27): ERR_MERGE_CONFLICT now fires when an `overlay: true` reopen sets the same `@attr` to a different non-empty value (cross-port contract per ADR-0009). The `overlay-attr-last-writer-wins` fixture predates FR5c and exercises exactly that case (`@displayName` flips v1→v2 across two files). TS's conformance runner still PASSES this fixture because TS's runner does not gate tree-check on the presence of unexpected errors; C#'s runner DOES gate (matches Java). Listing here documents the cross-port runner-strictness divergence (TS-side runner change is the proper fix; out-of-scope for FR5c port). FR5d (finalized 2026-05-27, all four ports): reference-resolution errors emit format=resolved with referrer + target; the cross-port fixtures now encode the resolved envelope and all four ports load byte-identically.",
5-
"fixtures": [
6-
"overlay-attr-last-writer-wins"
7-
]
4+
"_notes": "FR5c (finalized 2026-05-27, all four ports): merge-phase contributors + ERR_MERGE_CONFLICT envelope + WARN_DUPLICATE_DECLARATION. The `overlay-attr-last-writer-wins` fixture now declares its ERR_MERGE_CONFLICT in `expected-errors.json` and asserts identically across all four ports — no ledger entry needed. FR5d (finalized 2026-05-27, all four ports): reference-resolution errors emit format=resolved with referrer + target; the cross-port fixtures now encode the resolved envelope and all four ports load byte-identically.",
5+
"fixtures": []
86
}

spec/conformance-tests.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,15 @@ Pre-FR5a fixtures using the legacy `[{"code": "..."}]` array shape get only the
116116

117117
### Multi-file load order (FR5c)
118118

119-
When a fixture's `input/` directory contains more than one `meta.*.json` file, every port loads them in **case-sensitive alphabetical order of basename** before merging. This is a cross-port contract — the order determines:
119+
Finalized 2026-05-27 across all four ports (TS / C# / Java / Python). When a fixture's `input/` directory contains more than one `meta.*.json` file, every port loads them in **case-sensitive alphabetical order of basename** before merging. This is a cross-port contract — the order determines:
120120

121121
- which file is the `overlay-base` (alphabetically first) and which are `overlay-extension`s on a merged node's `source.contributors[]`;
122122
- the `files[]` list inside an `ERR_MERGE_CONFLICT` or `WARN_DUPLICATE_DECLARATION` envelope (also alphabetical, byte-identical across ports).
123123

124124
Last-writer-wins still governs non-conflicting attr overlays (one side unset, or both sides set to the same value). When both contributors set the same `@attr` to *different* non-empty values, the loader raises `ERR_MERGE_CONFLICT` with a `format: "merged"` envelope listing both contributors. When two files declare a node and the second contributes no semantic change (per the FR5a `semantic_diff`), the loader emits `WARN_DUPLICATE_DECLARATION` and the merged node's `source` is **not** upgraded to `format: "merged"`.
125125

126+
**WARN envelope-shape assertion**: as of FR5c-finalize the cross-port runners assert envelope shape on `errors[]` but compare `warnings[]` as a flat string list against `expected-warnings.json`. The error-side envelope assertion (code + source.format + source.files + source.jsonPath) is the cross-port contract; lifting the same assertion onto warnings is queued as follow-up work and is gated on a fixture migration from `expected-warnings.json` (string array) to `expected-errors.json#warnings[]` (envelope shape). All four ports currently exercise the FR5c `warning-duplicate-declaration` fixture under the string-list contract.
127+
126128
## TS conformance runner
127129

128130
Lives at `typescript/packages/metadata/test/conformance.test.ts`. Algorithm:

0 commit comments

Comments
 (0)