Commit 434f738
Merge worktree-fr5a-python-2026-05-26 — FR5a (loader error envelope + source-on-node) for Python
Per ADR-0009 + FR5a spec
(docs/superpowers/specs/2026-05-25-fr5a-json-shape-loader-errors.md).
Python is the fourth and final port to land FR5a's per-port runtime +
API work. The conformance fixture migration to the
{ errors: [...envelopes], warnings: [...] } shape is now unblocked and
becomes the next cross-port step.
Branch commits:
c163bae feat(python): FR5a foundation — ErrorSource hierarchy, JsonPath, SemanticDiff
fd03b22 feat(python): FR5a — thread source through parser + validation + MetaData.source
78ff0b8 fix(python): pre-merge review — complete FR5a envelope coverage
2a48841 chore(python): pre-merge simplifier pass — FR5a polish
What FR5a delivers in Python:
- New metaobjects.source package: @DataClass(frozen=True) discriminated
union (ErrorSource abstract base + JsonSource / YamlSource /
MergedSource / ResolvedSource / DatabaseSource / CodeSource) +
Contributor / NodeContext / YamlPosition / DbLocation / LoaderError /
LoaderWarning. Each variant carries a `format` ClassVar discriminant
matching TS/C#/Java strings. JsonSource enforces the FR5a length-1
invariant in __post_init__.
- metaobjects.source.json_path — canonical JSONPath builder matching
TS + C# + Java byte-for-byte (identifier-safe → dot; otherwise
single-quoted bracket with `'` escape; `[N]` indices; root `$`).
- metaobjects.source.semantic_diff — both JSON-value and (MetaData,
MetaData) entry points; lazy MetaData import resolves the
source ↔ meta_data module cycle.
- MetaData._source attribute (default CodeSource.DEFAULT) with the
existing _require_mutable() freeze guard reused for set_source.
- MetaError carries an optional envelope: ErrorSource | None alongside
legacy source / path (conformance adapter only inspects code).
- parser.py threads a JsonPathBuilder through parse_document → _build
→ _parse_attr_child. Every constructed node + every parser-built
MetaAttribute child (inline @-attrs AND typed attr.* children) gets
set_source(JsonSource(...)). Every error site passes envelope.
- validation_passes.py — all 29 MetaError sites pass envelope (28
initially, plus ERR_PROVIDER_ATTR_CONFLICT fixed in the review pass).
Pre-merge gate: code-reviewer flagged the parser-attr source-tagging
gap, a `<inline>` source-id carve-out inconsistent with mid-tree
envelope construction, and one missing-envelope site. All three fixed
in 78ff0b8. Simplifier unquoted two now-redundant string annotations
(with __future__ annotations at the top of both files).
Verification: 496 Python tests green (was 466 baseline, +30 new FR5a
tests for JsonPath edges, SemanticDiff smoke, source-on-node, parser
attr source-tagging). Conformance fixture corpus stays in the OLD
{ "code": "ERR_*" } shape — Python's conformance_adapter continues to
extract code from envelopes for the cross-port assertion.
What stays unchanged:
- Conformance fixtures still in the OLD shape (cross-port artifact);
fixture rewrite is now the next coordinated step across all 4 ports.
- No new ERR_* codes; existing codes get richer envelopes.
With this merge, FR5a per-port runtime + API work is COMPLETE across
TS / C# / Java / Python. ADR-0009 envelope shape is consistent on the
wire end-to-end.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>13 files changed
Lines changed: 1149 additions & 24 deletions
File tree
- server/python
- src/metaobjects
- loader
- meta
- source
- tests/source
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
5 | 9 | | |
6 | 10 | | |
7 | 11 | | |
| |||
47 | 51 | | |
48 | 52 | | |
49 | 53 | | |
50 | | - | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
51 | 62 | | |
52 | 63 | | |
53 | 64 | | |
54 | 65 | | |
55 | 66 | | |
56 | 67 | | |
57 | 68 | | |
| 69 | + | |
58 | 70 | | |
59 | 71 | | |
60 | 72 | | |
61 | 73 | | |
62 | 74 | | |
| 75 | + | |
63 | 76 | | |
64 | 77 | | |
65 | 78 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| 30 | + | |
30 | 31 | | |
31 | 32 | | |
32 | 33 | | |
| |||
139 | 140 | | |
140 | 141 | | |
141 | 142 | | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
142 | 154 | | |
143 | 155 | | |
144 | 156 | | |
145 | | - | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
146 | 160 | | |
147 | 161 | | |
148 | 162 | | |
149 | 163 | | |
150 | 164 | | |
151 | 165 | | |
152 | 166 | | |
153 | | - | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
154 | 170 | | |
155 | 171 | | |
156 | 172 | | |
157 | 173 | | |
158 | 174 | | |
159 | | - | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
160 | 179 | | |
161 | 180 | | |
0 commit comments