Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6b8311a
OX-02 P14 probe: can a hosted Windows runner drive Visual Studio?
claude Oct 3, 2026
adc6ad4
OX-02 P14 probe: screenshots and window inventory during VS startup
claude Oct 3, 2026
7f0732e
OX-02 P14 probe: create a .sln (the .NET 10 SDK defaults to .slnx)
claude Oct 4, 2026
332b1d9
OX-02 preregistration: one generic Owen.VisualStudio host
claude Oct 4, 2026
421736f
OX-02 P1/P2: the extractor runs in-process over an unsaved-buffer ove…
claude Oct 4, 2026
44a25a2
OX-02: owen serve, the live request, and the generic Owen.VisualStudio
claude Oct 4, 2026
1c2a98e
OX-02 P14: the real Visual Studio acceptance, and the live jobs in CI
claude Oct 4, 2026
5b89a93
OX-02: live-host docs, Snipper reuse inventory, mutation controls M1-M6
claude Oct 4, 2026
bdeb874
OX-02: create the VSIX container (import Microsoft.VsSDK.targets, as …
claude Oct 4, 2026
333262c
OX-02: keep the extractor's disk read sites where P-037 pins them; E3…
claude Oct 4, 2026
4790674
OX-02 P14: dismiss Visual Studio's first-run dialogs; run in the imag…
claude Oct 4, 2026
bd0ef66
OX-02 P14: realize the editor before measuring it
claude Oct 4, 2026
d330abe
OX-02 P14: diagnose why Owen.VisualStudio.dll is not in devenv
claude Oct 4, 2026
4289f6a
OX-02 P14: print the built VSIX's entries and manifest; keep the .vsi…
claude Oct 4, 2026
a28c958
OX-02 P14: rebuild the hive's MEF cache after installing the VSIX
claude Oct 4, 2026
e71027f
OX-02 P14: prove the extension loaded from its own trace, not the mod…
claude Oct 4, 2026
a0c038d
OX-02: TagsChanged on the UI thread; keep the measured editor in front
claude Oct 4, 2026
23d4aeb
OX-02 P14: three driver fixes after the first near-complete Visual St…
claude Oct 4, 2026
2a9944d
OX-02 preregistration Amendment 1: baseline results and what the real…
claude Oct 4, 2026
7cdf529
OX-02 P14: count Owen's tags correctly in Windows PowerShell
claude Oct 4, 2026
90bd419
OX-02 report: draft (Visual Studio results and verdict pending the re…
claude Oct 4, 2026
fbdc978
OX-02 P14: compare the navigated file's path case-insensitively
claude Oct 4, 2026
eb9567d
OX-02: real Visual Studio evidence, report and verdict GO_OWEN_VISUAL…
claude Oct 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ docs/evidence/*.json text eol=lf
# `core.autocrlf=true` would make a correct generator look stale.
samples/OrderBackend/OrderBackend/Domain/Order.Protocol.cs text eol=lf
samples/OrderBackend/evidence/* text eol=lf
docs/notes/evidence/ox02-visual-studio/** -text
81 changes: 81 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3487,6 +3487,87 @@ jobs:
- name: The extension gate (pack, isolated consumer A-H, mutations M1-M7)
run: python scripts/owen_extension_gate.py

# OX-02 (docs/notes/owen-visual-studio-preregistration.md): live Owen diagnostics in the IDE.
# The extractor run in-process over an overlay is byte-identical to the command line; the
# `owen serve` service, as Owen.VisualStudio uses it, answers unsaved edits (K1-K8), agrees
# with `dotnet build` on saved sources (P10), stays inside its latency/memory budget, and its
# client half survives the service dying (K6). Both platforms: the VSIX host is Windows-only,
# the service is not.
owen-live:
name: Owen live service (in-process extractor, owen serve, build/live parity)
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.13"
- uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4
with:
dotnet-version: "8.0.x"
- uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 # master, 2026-07-10
with:
toolchain: stable
- name: The extractor as a library (E1-E4)
run: python tests/check_extractor_in_process.py
- name: The live gate (L0, S, K1-K8, P10, T, C, G)
run: python scripts/owen_live_gate.py

# OX-02 P14: the real Visual Studio run. The hosted image carries Visual Studio with the
# extension workload; the VSIX is built with its MSBuild, installed into a dedicated root
# suffix, and the IDE is driven (DTE for edits, UI Automation for the Error List, Owen's
# opt-in trace for the squiggles) on a solution that is restored and never built.
owen-visual-studio:
name: Owen.VisualStudio in a real Visual Studio (unsaved edit -> squiggle + Error List)
runs-on: windows-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.13"
- uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 # master, 2026-07-10
with:
toolchain: stable
- name: Build the Rust core
shell: bash
run: cargo build -p own-cli --release --manifest-path rust/Cargo.toml
- name: Prepare the solution (packed Owen.Build + Owen.TypedBuilder; restored, not built)
shell: bash
run: python scripts/vs/prepare_vs_fixture.py --out "$RUNNER_TEMP/vsfx" --rust-core "$PWD/rust/target/release/own-cli.exe"
- name: Build the VSIX
shell: powershell
run: |
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
$msbuild = & $vswhere -latest -products * -requires Microsoft.Component.MSBuild -find "MSBuild\**\Bin\MSBuild.exe" | Select-Object -First 1
& $msbuild frontend\roslyn\Owen.VisualStudio\Owen.VisualStudio.csproj /restore /p:Configuration=Release /p:DeployExtension=false /v:m
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
$built = @(Get-ChildItem -Recurse frontend\roslyn\Owen.VisualStudio -Filter Owen.VisualStudio.vsix)
if ($built.Count -eq 0) { Write-Error "no Owen.VisualStudio.vsix was produced"; exit 1 }
$built | ForEach-Object { "$($_.FullName) ($($_.Length) bytes)" }
Add-Type -AssemblyName System.IO.Compression.FileSystem
$zip = [System.IO.Compression.ZipFile]::OpenRead($built[0].FullName)
$zip.Entries | ForEach-Object { " entry: $($_.FullName) ($($_.Length))" }
$m = $zip.GetEntry('extension.vsixmanifest'); $r = New-Object System.IO.StreamReader($m.Open()); $r.ReadToEnd(); $r.Dispose(); $zip.Dispose()
New-Item -ItemType Directory -Force "$env:RUNNER_TEMP\vs-evidence" | Out-Null
Copy-Item $built[0].FullName "$env:RUNNER_TEMP\vs-evidence\"
- name: The acceptance in Visual Studio
shell: powershell
run: |
$vsix = (Get-ChildItem -Recurse frontend\roslyn\Owen.VisualStudio -Filter Owen.VisualStudio.vsix | Select-Object -First 1).FullName
scripts\vs\owen-vs-acceptance.ps1 -Vsix $vsix -Fixture "$env:RUNNER_TEMP\vsfx\fixture.json" -Out "$env:RUNNER_TEMP\vs-evidence" -RootSuffix Exp
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
if: always()
with:
name: owen-visual-studio-evidence
path: ${{ runner.temp }}/vs-evidence/

# Alpha gate A (issue #202): the single delightful command, proven end-to-end
# on a clean runner — install -> check -> findings. Packaging only, no
# analysis-behaviour change: the underlying project stays OwnSharp.Cli
Expand Down
27 changes: 27 additions & 0 deletions docs/howto-visual-studio.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,33 @@ so it never breaks a wrapping build by accident.

## 2. In Visual Studio

### Live: Owen.VisualStudio (OX-02) — for projects that use an Owen extension

If the project references an Owen extension package (for example `Owen.TypedBuilder`, which
brings `Owen.Build`), install the one generic **Owen** VSIX
(`frontend/roslyn/Owen.VisualStudio`, built on Windows with Visual Studio's MSBuild:
`msbuild frontend\roslyn\Owen.VisualStudio\Owen.VisualStudio.csproj /restore /p:Configuration=Release`,
then double-click `Owen.VisualStudio.vsix`). Requirements: Visual Studio 2022 17.14+ or Visual
Studio 2026, and the .NET 8+ runtime that `Owen.Build` already needs. No Python, Rust, checkout
or global `owen` tool.

What you get, while typing and without saving or building:
- Owen's findings as **squiggles**: at the finding's location, and on each witness step the core reports (for a stale state token, the line that uses it again);
- one **Error List** row per finding (Source/Tool `Owen`), double-click to navigate; CS diagnostics stay the compiler's;
- the **Owen** output pane: the live service's own log, including its stderr.

How it works and what it does not do: `docs/notes/owen-visual-studio-preregistration.md`. In
short, the VSIX sends the editor's text to `owen serve` from the project's own `Owen.Build`
package, and the Rust core decides; the VSIX decides nothing. `dotnet build` stays the
authoritative gate, with the same findings (the build/live parity gate holds them equal).

Known limits: a state-protocol finding has no column (the squiggle covers the reported line);
a stale token is reported at the region entry with the stale use as its witness step (#393); a
file that was never saved is not part of the project's input set; live analysis starts after the
project's first design-time build (Visual Studio runs it on load).

### Without an extension

Two approaches, cheapest first.

### Option A — External Tool (on-demand, no build coupling) — recommended
Expand Down
14 changes: 14 additions & 0 deletions docs/notes/alpha-readiness.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,17 @@ until the .NET alpha above is delicious. Do not let the spike exceed 20%.
The standing priority is unchanged: **prove value, don't reshape form**
([consolidation-and-positioning.md](consolidation-and-positioning.md)). This note is
the concrete "what value, packaged how" gate for that.

## Update 2026-10-04: live diagnostics in Visual Studio (OX-02)

`GO_OWEN_VISUAL_STUDIO_ALPHA` (docs/notes/owen-visual-studio-report.md). One generic
`Owen.VisualStudio` VSIX shows every active Owen extension's findings live, unsaved, as
squiggles and Error List rows. It reads the project's `obj/owen/live.txt`, written by
Owen.Build in design-time builds. It talks to `owen serve` from the project's own Owen.Build
package. The extractor runs in-process over the editor's text, and the verdict is the Rust
core's.

- Proven in a real Visual Studio 2026 on CI: 19/19.
- Build/live parity is a gate.
- Extensions ship no IDE code.
- `dotnet build` stays the authoritative gate.
13 changes: 13 additions & 0 deletions docs/notes/evidence/ox02-visual-studio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# OX-02 real Visual Studio evidence

From CI run 37175674769 (job `owen-visual-studio`, head `fbdc978`), Visual Studio Enterprise
2026 18.10.12217.157 on the hosted `windows-2025-vs2026` image, driven by
`scripts/vs/owen-vs-acceptance.ps1`. Kept byte-for-byte as uploaded.

- `acceptance.log`: every check, 19/19 passed.
- `results.json`: the checks and the measurements (edit -> squiggle / disappearance per edit, UI-thread maximum, service timings, working set).
- `trace.jsonl`: Owen.VisualStudio's own trace (`OWEN_LIVE_TRACE`): load, workspace snapshots (unsaved `Use.cs` + Roslyn's in-memory generated documents), publications with the service's timings, the tags the tagger produced per text version, UI-thread maxima.
- `k2-squiggle.png`: `Use.cs*` unsaved; squiggles on `OrderProtocol.WithDraft(order, draft =>` (the finding) and on the inserted `draft.Submit(now);` (its witness step); the Error List row `OWN002 … LiveFixture Use.cs 10`.
- `k2-navigated.png`: after double-clicking the row: caret at 10:9.
- `p9-cs-and-own.png`: CS0029 and OWN002 side by side.
- `k3-gone.png`: after deleting the line: no squiggle, no row.
26 changes: 26 additions & 0 deletions docs/notes/evidence/ox02-visual-studio/acceptance.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[04:03:20.333] Visual Studio: Visual Studio Enterprise 2026 18.10.12217.157 [b61ad8f0]
[04:06:52.917] ok[install-vsix]: VSIXInstaller exit 0 into root suffix Exp
[04:06:52.954] dropped the MEF cache C:\Users\runneradmin\AppData\Local\Microsoft\VisualStudio\18.0_b61ad8f0Exp\ComponentModelCache
[04:07:48.331] devenv /updateconfiguration exit 0
[04:07:48.396] devenv pid 1812
[04:07:58.313] solution open after 9.893 s: D:\a\_temp\vsfx\ws\LiveFixture.sln
[04:08:09.801] active document: D:\a\_temp\vsfx\ws\LiveFixture\Use.cs
[04:08:10.954] ok[vsix-loaded]: Owen.VisualStudio composed in devenv: {"t":1791086890317,"kind":"log","data":{"line":"Owen live analysis loaded"}}
[04:08:11.024] ok[L0-live-request]: the design-time build wrote D:\a\_temp\vsfx\ws\LiveFixture\obj\owen\live.txt (no build was run)
[04:08:30.432] ok[K1-open-clean]: first publication (version 2, 4921 ms in the service): 0 entries, OWN: 0
[04:08:30.437] snapshot: documents D:\a\_temp\vsfx\ws\LiveFixture\Use.cs; generated D:\a\_temp\vsfx\ws\LiveFixture\obj\Debug\net8.0\generated\Owen.TypedBuilder.Generator\Own.TypedBuilder.TypedBuilderGenerator\Order.Protocol.g.cs, D:\a\_temp\vsfx\ws\LiveFixture\obj\Debug\net8.0\generated\Owen.TypedBuilder.Generator\Own.TypedBuilder.TypedBuilderGenerator\Owen.TypedBuilder.Attributes.g.cs
[04:08:31.460] ok[K1-unsaved-clean]: a clean unsaved edit was analysed (version 3) with no OWN entry; document saved=False
[04:08:31.963] ok[K2-squiggle]: tags on Use.cs after the edit: 10:9+39 primary=True 'OrderProtocol.WithDraft(order, draft =>'; 13:13+18 primary=False 'draft.Submit(now);'
[04:08:31.967] ok[K2-unsaved]: Use.cs is unsaved (Saved=False); the disk still has one Submit: True
[04:08:33.309] ok[K2-error-list]: Error List row: OWN002 | IDisposable local 'draft' is used after it is disposed [resource: disposable] | LiveFixture | Use.cs | 10
[04:08:34.933] ok[K2-navigation]: double-click -> 'D:\a\_temp\vsfx\ws\LiveFixture\Use.cs' line 10 column 9; expected 'D:\a\_temp\vsfx\ws\LiveFixture\Use.cs' line 10 column 9 (the core's location, §6)
[04:08:36.475] ok[P9-cs-and-own]: CS0029 row: CS0029 | Cannot implicitly convert type 'string' to 'int' | LiveFixture | Use.cs | 10; OWN002 rows: 1
[04:08:40.340] ok[K3-disappears]: after deleting the line: tags without OWN002 at +344 ms; Error List row gone: True
[04:09:04.176] ok[T-edit-to-squiggle]: edit -> squiggle over 10/10 edits: p95 349 ms (threshold 1000), all: 334, 328, 349, 330, 336, 330, 347, 343, 328, 335
[04:09:04.179] ok[T-edit-to-disappearance]: edit -> disappearance over 10/10 edits: p95 347 ms (threshold 1000), all: 328, 347, 330, 328, 336, 329, 322, 342, 343, 326
[04:09:04.194] ok[T-ui-thread]: longest Owen UI-thread handler: 3.3251 ms (threshold 50)
[04:09:04.202] ok[no-build]: no LiveFixture.dll under bin/ (0), no build-check request: the build host never ran
[04:09:04.204] ok[never-saved]: Use.cs on disk is byte-identical to the fixture
[04:09:04.556] owen serve processes before devenv ends: 5372
[04:09:07.578] ok[no-orphan]: owen serve ran (1 process(es)) and did not outlive a killed devenv (0 left)
[04:09:07.580] VS acceptance: all checks passed
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading