Skip to content

Commit 5479a51

Browse files
committed
docs(owen-ext): OX-01 report and verdict (GO_OWEN_EXTENSION_ALPHA)
Official runs (local clean worktree 55/55; server CI Linux and Windows 55/55 each on 48c71e6, the first Windows run failing on a gate path bug fixed in 89bdb86), counts, mutations, kept TB-MVP guarantees, foundation diff, Owen.Cli payload, Snipper/diagnostics/IDE summaries and findings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011ZFvhLx1fM9Gerg4dKsZcL
1 parent 48c71e6 commit 5479a51

1 file changed

Lines changed: 169 additions & 0 deletions

File tree

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
# OX-01 — Owen extension substrate with Typed Builder as extension #1: report
2+
3+
**VERDICT: `GO_OWEN_EXTENSION_ALPHA`.**
4+
5+
| | commit |
6+
|---|---|
7+
| base (`main`, TB-MVP-01 merged, #391) | `88cb8cc31c49d730290613208947102d0737cad2` |
8+
| preregistration + Snipper audit | `49f5493` ([`owen-extension-alpha-preregistration.md`](owen-extension-alpha-preregistration.md)) |
9+
| implementation + Amendment 1 (before any official run) | `6e65bfb` |
10+
| gate fix (Windows: paths on two drives; gate mechanics only) | `89bdb86` |
11+
| notes, E2 spike | `48c71e6` |
12+
| this report | the head of the PR |
13+
14+
## What a user does now
15+
16+
```
17+
dotnet new web -n OrderBackend
18+
dotnet add package Owen.TypedBuilder --version 0.1.0
19+
dotnet build
20+
```
21+
22+
1. **Generation.** The typed API is generated on every compilation by a Roslyn incremental generator: `DraftOrder.Submit`, `OrderProtocol.WithDraft`, `Order.Create().Customer(…).Build()`.
23+
2. **Compiler errors.** An illegal transition is a compiler error: `CS1061 'DraftOrder' does not contain a definition for 'Approve'`.
24+
3. **Owen findings on build.** A stale state token is an Owen finding, reported by the build in the canonical MSBuild form and so in Visual Studio's Error List:
25+
`…/C8_stale_draft.cs(18): warning OWN002: …`
26+
It is a `warning` by default and an `error` with `OwenSeverity=error`.
27+
4. **The project names its extensions** in `obj/owen/extensions.json`.
28+
29+
None of it needs Python, a Rust toolchain, a global `owen`, a checkout, an environment
30+
variable, or a PATH lookup of an Owen binary.
31+
32+
## Architecture as built
33+
34+
```
35+
Owen.TypedBuilder (package, extension #1)
36+
├─ analyzers/: Owen.TypedBuilder.Generator — Roslyn incremental generator
37+
│ (shares TypedBuilderCore.cs with the CLI generator: one model, one renderer)
38+
├─ build*/: owen-extension.json + <OwenExtensionDescriptor> item
39+
└─ depends on ─────────────────────────────┐
40+
▼
41+
Owen.Build (package, the GENERIC host: names no extension)
42+
├─ build*/Owen.Build.targets: after the build → `owen build-check`
43+
└─ tools/net8.0/any/: the Owen.Cli program + bundled extractor + rust-core/<platform>/own-cli
44+
│
45+
▼
46+
the authoritative Rust core (`own-cli ownir --format msbuild`)
47+
```
48+
49+
- **No `Owen.Toolchain` or `Owen.CoreAssets`.** `Owen.Build` is the one host package. It exists because a tool package cannot be a `PackageReference` (NU1212, observed) and because every extension must share one engine.
50+
- **The platform inventory** lives in one `frontend/roslyn/OwenRustCore.props`, imported by both `Owen.Cli` and `Owen.Build`.
51+
- **The host entry point** is a new `owen build-check` subcommand of the same program. It reuses `owen check`'s extractor and engine runner; it neither copies them nor renders findings.
52+
- **The contract:** [`spec/OwenExtension.md`](../../spec/OwenExtension.md) and its JSON schema.
53+
- **Generator delivery: A**, a Roslyn incremental generator, chosen on measurement (preregistration K-3). B was absent from the design-time build that Visual Studio's IntelliSense uses.
54+
55+
## Official runs
56+
57+
| run | where | result |
58+
|---|---|---|
59+
| `scripts/owen_extension_gate.py` from a fresh `git worktree` of `6e65bfb` (no `bin/`/`obj/`) | local Linux x64 | **55/55 PASS** |
60+
| the same gate on `6e65bfb` | server CI `owen-extension`, ubuntu-latest | **55/55 PASS** |
61+
| the same gate on `6e65bfb` | server CI `owen-extension`, windows-latest | **FAIL before any check.** The gate's own outside-checkout test called `os.path.commonpath` on a `D:` checkout and a `C:` temp directory and raised. Fixed in `89bdb86`, gate mechanics only. |
62+
| the same gate on `48c71e6` | server CI `owen-extension`, ubuntu-latest | **55/55 PASS** |
63+
| the same gate on `48c71e6` | server CI `owen-extension`, windows-latest | **55/55 PASS**: the `win-x64` core, absolute `C:\…\C8_stale_draft.cs(18)` origins, Exec through `cmd` |
64+
| server CI run 37149198078 (`48c71e6`) | all jobs | **36/36 success**, including `owen CLI (gate A)` on both platforms, `state protocols` on both, lint, tests ×3, rust, formal kernel |
65+
66+
## Counts (Linux official run)
67+
68+
| | |
69+
|---|---|
70+
| packages | 2 shipped (`Owen.Build`, `Owen.TypedBuilder`) + 1 synthetic test extension |
71+
| isolation | consumer PATH = the `dotnet` dir + `sh` only; `python`/`python3`/`py`/`cargo`/`rustc`/`owen` resolve to nothing; fresh `HOME`/`NUGET_PACKAGES`; `Owen.*` mapped to the candidate feed only; the consumer outside the checkout; no checkout path in any build output |
72+
| A | build ok; the generated `Order.Protocol.g.cs` = `#nullable enable\n` + the committed golden (6880 bytes); the manifest lists `Owen.TypedBuilder 0.1.0` with its 4 capabilities; the clean sample has no Owen diagnostic |
73+
| B | `draft.Approve(…)` → CS1061 `'Approve'` |
74+
| C | `OwenSeverity=error` → `…/C8_stale_draft.cs(18): error OWN002: …`, build fails |
75+
| D | the origin is the **absolute** path of the staged file, line 18; the default severity gives the same line as `warning OWN002`, and the build succeeds |
76+
| F | **30/30** corpus cases through the package: compiler-stage CS codes, extractor refusals as `OWENB010`, core refusals as `OWENB011`, verdicts `OWN002`/`OWN005`/`OWN013`, positives clean, the P5/P8 `proven_call` present, K1 `OWN001`, K2 clean |
77+
| G | the TB-MVP acceptance runner against the package-built consumer: **44/44**, transcript **byte-identical** to `samples/OrderBackend/evidence/acceptance.txt` |
78+
| H | `Owen.TestExtension` beside `Owen.TypedBuilder`: the manifest lists both, and the project is analysed once (1 `OWN002`) |
79+
| M1a | the declared descriptor deleted → `OWENB002`, no `OWN002` |
80+
| M1b | the whole declaration deleted → `OWENB001` ("no Owen extension is active"), no `OWN002` |
81+
| M2 | unknown capability `teleportation` → `OWENB004` |
82+
| M3 | the bundled `own-cli` deleted → `OWENB005` (never a clean build) |
83+
| M4 | `requires.ownir: 3` → `OWENB003`; `requires.host: 9.0.0` → `OWENB003` |
84+
| M5 | the host target emptied → no `OWN002`, so the C check catches the absence |
85+
| M6 | consumer with no checkout → E holds |
86+
| M7 | the host sources (`Owen.Build/**`, `BuildCheckCommand.cs`, `OwenRustCore.props`) contain `TypedBuilder` 0 times |
87+
88+
## Existing guarantees kept
89+
90+
On the implementation commit:
91+
- `typed_builder_gate.py --rust`: 8/20/2 corpus, 44 checks ×2, transcript `ba447304cdf957ee`, 0 failures. The CLI generator now runs on the shared core and still writes the golden byte for byte.
92+
- `protocol_gate.py --rust`: 0 failures, 29 documents byte-identical on both CLIs.
93+
- `heap_effects_gate.py`: unchanged; the extractor is untouched.
94+
- `ruff` and `mypy` clean.
95+
96+
**`tests/run_tests.py` locally:**
97+
- `fresh-record-valid` fails only on a dirty tree, by design.
98+
- Two stage-1 controls (`divergence-is-5`, `exec-failure-is-5`) fail **on the owen surface only**, and only once a launcher is built locally. In the base run they were skipped ("no built launcher"). A launcher built from the **base** commit `88cb8cc3` fails them identically, so this is pre-existing and not caused by this change. The server CI is authoritative for it.
99+
100+
**Foundations.**
101+
`git diff --stat 88cb8cc3..HEAD -- ownlang rust spec/OwnIR.md spec/Bridge.md spec/ownir.schema.json frontend/roslyn/OwnSharp.Extractor docs/evidence/calibration scripts/perf_baseline.py`
102+
is **empty**. No OwnIR, ownership, state-protocol, H0/H1, T0, P-022 harness, `OWN` code or core
103+
change.
104+
105+
**`Owen.Cli` payload** (Amendment 1.2), measured against a pack of the base commit with the
106+
same staged core:
107+
- identical **file list**, 109 entries;
108+
- every Roslyn assembly, `deps.json`/`runtimeconfig.json`, vendored `.py` and the Rust core **byte-identical**;
109+
- only `ownsharp.dll`/`.pdb` (gains `build-check`), `ownsharp-extract.dll`/`.pdb` (commit-stamped build metadata; source unchanged) and the nuspec `repository commit` differ.
110+
111+
Gate A (`owen-cli` install → `owen check` → `OWN001`) runs in server CI on both platforms.
112+
113+
## Snipper salvage (P1)
114+
115+
[`owen-extension-snipper-salvage.md`](owen-extension-snipper-salvage.md), read-only at `43b395a`, MIT. **For this slice:**
116+
- **REJECT** its binary discovery (setting → bundled → PATH with silent fall-through), the long-lived VS process lifecycle, and the Roslyn sidecar.
117+
- **ADAPT** pack-time bundling with a hard fail, already `OwenRustCore.props`, and one-shot child discipline. MSBuild's Exec kills the child tree on cancellation; `owen` drains both streams and maps exit codes.
118+
- **Later only:** StreamJsonRpc framing (COPY), mocked-VS and two-pipe fake-server tests, the thin VS Code client shape.
119+
120+
## Diagnostics model (P8)
121+
122+
[`owen-diagnostics-model.md`](owen-diagnostics-model.md). The model already exists:
123+
`own_bridge::Finding` → `render_finding` (human/github/msbuild) / `build_sarif`. No new layer
124+
was built. The host only absolutises the origin path.
125+
126+
**Recorded gaps, not changed:**
127+
- the msbuild line has no column although `Finding` has one;
128+
- the state-protocol wording and line (#393).
129+
130+
## IDE (P9/P10)
131+
132+
[`owen-extension-ide-feasibility.md`](owen-extension-ide-feasibility.md):
133+
- **E1 (generic VSIX): NOT EXECUTED.** There is no Windows or Visual Studio here. It is specified, with its two blockers: extractor overlay input for unsaved buffers, and a resident process.
134+
- **E2 (native Roslyn analyzer): REJECT.** Measured on Linux:
135+
- shadow copy defeats default native resolution;
136+
- only an explicit path through reflection-reached `NativeLibrary` works, and only on .NET-hosted compilers;
137+
- the extractor cannot run inside an analyzer.
138+
- **Invariant:** one `Owen.VisualStudio`, one Owen server, extension ≠ IDE plugin.
139+
140+
## Findings worth carrying forward
141+
142+
1. **Top-level statements.** A region in top-level statements is not modelled by the extractor. The TB-MVP acceptance runner has one, and the host refuses it with `OWENB010` instead of skipping it, which is correct fail-closed behaviour. The gate builds that runner with `OwenEnabled=false`.
143+
2. **`buildTransitive` reach.** It makes every project that references an Owen-enabled project Owen-enabled too. That is intended (the same analysis everywhere) and documented. A project opts out with `OwenEnabled=false`.
144+
3. **A system shell.** MSBuild's `Exec` needs a system shell (`sh` on Unix, `cmd` on Windows). That is not a toolchain dependency, but the isolation harness must provide it.
145+
4. **Windows console encoding.** On Windows the core's em dash in a refusal text reaches the build log as `-`: `build-check` writes through the console encoding. The codes, locations and gate checks are unaffected. The fix is to emit UTF-8 explicitly (`Console.OutputEncoding` plus Exec `StdOutEncoding`); it is left for a follow-up, not changed after the official run.
146+
147+
## Verdict
148+
149+
**`GO_OWEN_EXTENSION_ALPHA`**, on `48c71e6`. Every condition registered for GO holds:
150+
151+
| registered condition | evidence |
152+
|---|---|
153+
| `PackageReference Owen.TypedBuilder` → generated API | A on Linux and Windows: generated text = `#nullable enable` + golden; manifest written |
154+
| → CS diagnostics | B, plus the 10 compiler-stage corpus cases |
155+
| → OWN diagnostics on build | C/D, plus the core-stage corpus cases, as canonical, absolute, navigable MSBuild lines |
156+
| → no external toolchain or setup | E: a stripped PATH, fresh HOME/NuGet, outside the checkout, no checkout path in any output, on both platforms |
157+
| → generic extension discovery proven | H (two extensions, one analysis), M7 (the host names no extension), M1a/M1b/M2/M3/M4/M5 (fail loud) |
158+
| existing TB-MVP guarantees | F (30/30 through the package), G (44/44, transcript byte-identical), `typed_builder_gate` unchanged |
159+
| foundations unchanged | the foundation diff is empty; `protocol_gate`/`heap_effects_gate`/`cargo` green |
160+
| Windows + Linux server CI | 36/36 |
161+
162+
**After GO: STOP.** None of the following is started:
163+
- a production VSIX, LSP or VS Code extension;
164+
- the Memory or TypeDisciplines extensions;
165+
- BCL summaries (#394), typed write targets (#395), affine tokens (#392), diagnostic wording (#393), concurrency (#396);
166+
- a second aggregate;
167+
- a repo-wide rename.
168+
169+
**For publishing:** nothing was pushed to nuget.org. The license blocker that gates `Owen.Cli` gates these two packages too.

0 commit comments

Comments
 (0)