Skip to content

Commit ccac9b6

Browse files
authored
Merge pull request #298 from PhysShell/claude/own251-p022-reconcile
docs(P-022): #251 — reconcile roadmap and crate status after #214/#249
2 parents a7d8499 + 3909f98 commit ccac9b6

2 files changed

Lines changed: 78 additions & 25 deletions

File tree

‎docs/proposals/P-022-rust-core-migration.md‎

Lines changed: 77 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,47 @@
11
# P-022 — Rust core migration: bird's-eye architecture
22

3-
Status: **draft / exploratory** (design only — no Rust code committed yet; the
4-
Python core stays the reference implementation and the oracle until parity holds).
5-
Revised per the post-merge review in
3+
Status: **in execution** (strangler-fig underway; the Python core stays the
4+
reference implementation and the oracle until the explicit cutover). The design
5+
rationale below is historical and unchanged; the live sequencing is the #250
6+
child-issue DAG. Revised per the post-merge review in
67
[`docs/notes/p022-review-notes.md`](../notes/p022-review-notes.md).
78

9+
### Implementation status (reconciled after #214/#249 — see #250/#251)
10+
11+
**Implemented** (workspace members in `rust/Cargo.toml`, parity-gated by
12+
`scripts/oracle_exact.py` and the shared fixtures in `tests/fixtures/`):
13+
14+
- `own-ir` — OwnIR serde + schema round-trip (step 1);
15+
- `own-syntax` — parser, error-text parity (step 2);
16+
- `own-cfg` — lowering + the canonical CFG-JSON seam, replaying
17+
`tests/fixtures/cfg_parity.json` (steps 0/3; the seam the strategy below
18+
said "still needs building" **is built** — `python -m ownlang cfg --format
19+
json` + the `--write`-regenerated parity fixtures);
20+
- `own-diagnostics` — the data-only diagnostics layer;
21+
- `own-analysis` — the worklist solver + ownership/lifetime/buffer/effect/DI
22+
analyses (step 4; the **analysis-heart milestone**, completed in #214 /
23+
PR #249, replaying `diag_parity.json` and the DI/effect fact-parity
24+
fixtures).
25+
26+
**Next steps — each owned by exactly one child issue under #250:**
27+
28+
| Step | Deliverable | Issue |
29+
|---|---|---|
30+
| 5a | diagnostic messages + ordered Evidence parity | #255 |
31+
| 5b | `.ownreport.json` + SARIF projection, canonical parity | #256 |
32+
| 5c | `own-codegen` (analysis-independent sibling) | #257 |
33+
| 6a | OwnIR **bridge semantics formalized** before the port | #258 (deliverable written — `spec/Bridge.md` + `spec/BridgeBehaviorMatrix.md` **land with PR #297**, in independent review; not on `main` yet) |
34+
| 6b | Rust `own-bridge`, layered OwnIR parity | #259 |
35+
| 7a | dual-engine shadow mode + zero-diff reproduction artifacts | #260 (supported by #269 — normalized `AnalysisTrace` + first-divergence minimizer) |
36+
| 7b | Rust `own-cli`: command/output/exit-code parity | #261 |
37+
| 8 | Rust-default **cutover**, rollback gate, Python distribution removal | #262 |
38+
39+
The Datalog/Ascent rule layer stays strictly **post-cutover** (strategy step 8
40+
below) and deliberately has no issue yet. Throughout: Python remains
41+
authoritative until #262's cutover gate passes; a feature-freeze on
42+
verdict-changing inference holds until then
43+
([`interprocedural-roadmap.md`](../notes/interprocedural-roadmap.md)).
44+
845
## Why
946

1047
The primary trigger is the **IDE extension** — Gate B of
@@ -477,37 +514,50 @@ SARIF/JSON shapes. So:
477514
misses.
478515

479516
**Per-layer seams.** SARIF is the verdict-layer seam and already exists. A **CFG-layer
480-
seam does not** — today `python -m ownlang cfg` prints a *human* dump (`_print_cfg`),
481-
not a contract. So a prerequisite of diffing CFGs is to first **add and freeze a
482-
canonical `cfg --format json` export on the Python side**; mirroring the debug text
483-
dump would bake a non-contract format into the ratchet. Treat "CFG JSON seam" as work
484-
to build, not an existing contract. With SARIF (verdict) present and CFG-JSON added,
485-
a divergence can be bisected to the crate that introduced it.
517+
seam did not** (at writing) — `python -m ownlang cfg` printed a *human* dump
518+
(`_print_cfg`), not a contract. So a prerequisite of diffing CFGs was to first **add
519+
and freeze a canonical `cfg --format json` export on the Python side**; mirroring the
520+
debug text dump would bake a non-contract format into the ratchet. With SARIF (verdict)
521+
present and CFG-JSON added, a divergence can be bisected to the crate that introduced
522+
it. *(Status per #251: built and frozen — `cfg --format json` +
523+
`tests/fixtures/cfg_parity.json`, replayed by `own-cfg`'s parity tests.)*
486524

487525
Because the oracle compares *contracts we froze and tested*, the recent evidence/SARIF
488-
hardening is what makes the verdict seam cheap — the CFG seam still needs building.
526+
hardening is what made the verdict seam cheap — and the CFG seam has since been built
527+
(step 0 ✅ above).
489528

490529
## Migration strategy (strangler-fig, bottom-up, oracle-gated)
491530

492-
0. **Add the missing Python seams first**: a canonical `cfg --format json` export
493-
(and the exact diff harness). Without these the ratchet has nothing to compare the
494-
CFG layer against.
495-
1. **Stand up the workspace + `own-ir`** (serde round-trips the existing OwnIR
531+
*(Status markers reconciled per #251; the plan text is otherwise as designed.)*
532+
533+
0. ✅ **Add the missing Python seams first**: a canonical `cfg --format json` export
534+
(and the exact diff harness, `scripts/oracle_exact.py`). Without these the ratchet
535+
has nothing to compare the CFG layer against.
536+
1. ✅ **Stand up the workspace + `own-ir`** (serde round-trips the existing OwnIR
496537
fixtures — first parity check, at the seam).
497-
2. **`own-syntax`**: port the parser; diff the AST/`cfg` dump against Python.
498-
3. **`own-cfg`**: port lowering; diff the frozen CFG JSON (from step 0).
499-
4. **`own-analysis`**: port the worklist + ownership first, then lifetime/effect/DI;
538+
2. ✅ **`own-syntax`**: port the parser; diff the AST/`cfg` dump against Python.
539+
3. ✅ **`own-cfg`**: port lowering; diff the frozen CFG JSON (from step 0).
540+
4. ✅ **`own-analysis`**: port the worklist + ownership first, then lifetime/effect/DI;
500541
diff diagnostics (no evidence) → then evidence → then SARIF, layer by layer.
501-
5. **`own-diagnostics` + `own-codegen`**: SARIF/report/text and C# `emit`; diff each.
542+
(#214 / PR #249 — the analysis heart; `own-diagnostics` shipped as its
543+
data-only layer.)
544+
5. **`own-diagnostics` (messages/Evidence — #255), report/SARIF (#256) +
545+
`own-codegen` (#257)**: SARIF/report/text and C# `emit`; diff each.
502546
6. **`own-bridge`**: port the OwnIR bridge — facts→core lowering, the MOS
503547
interprocedural inference, verdict mapping. **Prerequisite:** the normative
504548
write-up of the inference semantics (consume/borrow/fresh/alias/overwrite rules)
505549
from the tech-debt register, so the port has a spec and not just
506-
`test_ownir.py` examples. Diff on the OwnIR fixtures + `ownir --format sarif`.
507-
7. **`own-cli`**: cut over once corpus parity is ~100%. Keep Python frozen as the
550+
`test_ownir.py` examples — written as `spec/Bridge.md` +
551+
`spec/BridgeBehaviorMatrix.md` (#258, composing `spec/Inference.md`),
552+
landing with PR #297 after independent review; implementation is #259 and
553+
starts only after that review gate. Diff on the OwnIR fixtures +
554+
`ownir --format sarif`.
555+
7. **`own-cli`**: cut over once corpus parity is ~100% (shadow mode #260 with
556+
#269's AnalysisTrace, then the CLI #261). Keep Python frozen as the
508557
oracle/spec.
509558
8. **Only then** revisit the rule layer as Datalog/Ascent (ADR §8: "core moves to
510-
Rust" trigger now satisfied) — natively, not as a Python detour.
559+
Rust" trigger now satisfied) — natively, not as a Python detour. The formal
560+
cutover + rollback gate + Python-distribution removal is #262.
511561

512562
Throughout, Python stays authoritative; the Rust crates light up behind the ratchet.
513563

@@ -541,6 +591,9 @@ Throughout, Python stays authoritative; the Rust crates light up behind the ratc
541591

542592
## Placement
543593

544-
This document lives in `PhysShell/Own.NET/docs/proposals/`. It is design-only; the
545-
first code deliverable is the workspace skeleton + `own-ir` round-trip + the oracle
546-
harness, on its own branch, gated by the differential ratchet from commit one.
594+
This document lives in `PhysShell/Own.NET/docs/proposals/`. The document is
595+
design + status; the first code deliverable it called for — the workspace
596+
skeleton + `own-ir` round-trip + the oracle harness, gated by the differential
597+
ratchet from commit one — has shipped (`rust/`, `scripts/oracle_exact.py`; see
598+
the implementation-status block at the top). The monorepo layout it recommends
599+
is the one in effect.

‎docs/proposals/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ proposal is marked `done` with a pointer.
4141
| [P-017](P-017-multi-stack-frontends.md) | Multi-stack frontends (OwnTS / OwnJVM: OwnJava + OwnKotlin) | draft |
4242
| [P-020](P-020-ownts-react-effects.md) | OwnTS React effects profile (`Own.React`) — the effect-storm angle | draft |
4343
| [P-021](P-021-async-audit-pack.md) | Async audit pack (`Own.Async`) | draft |
44-
| [P-022](P-022-rust-core-migration.md) | Rust core migration: crate DAG, patterns, prior art, differential oracle (Python = golden) | draft / exploratory |
44+
| [P-022](P-022-rust-core-migration.md) | Rust core migration: crate DAG, patterns, prior art, differential oracle (Python = golden) | in execution — steps 0–4 built (`own-ir`/`own-syntax`/`own-cfg`/`own-diagnostics`/`own-analysis`, #214/#249); remaining steps = the #250 child-issue DAG (#255–#262); Python authoritative until cutover |
4545
| [P-023](P-023-architecture-guard.md) | Architecture guard (`Own.Arch`): rules.yaml intent model + dependency-graph gate + baseline ratchet | draft |
4646
| [P-024](P-024-security-audit-profile.md) | Security audit profile (external tools + SARIF adapters; rejects own scanner engine) | draft |
4747
| [P-025](P-025-obligation-protocols.md) | Obligation protocols (`Own.Protocols`): barrier-sensitive project invariants (OBL001–005) | first slice built (core + bridge + fixtures; extractor pending) |

0 commit comments

Comments
 (0)