Skip to content

Commit ebb18f7

Browse files
committed
docs(nunit): record Task 8 live verification and remaining P0 gaps
Capture Revit 2023/2026 evidence, Dynamo nunit inventory, async UI deadlock and generation.retained blockers, and link the digest from the agent index.
1 parent 63a9677 commit ebb18f7

3 files changed

Lines changed: 114 additions & 19 deletions

File tree

docs/agents/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Build/deploy traps: `.agents/skills/build/SKILL.md`.
99
|------|------|----------|
1010
| Compile / deploy / verify | `build` skill, `verification.md`, `build-matrix.md`, `known-test-gaps.md` | `source/`, `scripts/`, `tests/` |
1111
| MCP integration testing | `mcp-integration-test.md` | Host + daemon |
12-
| NUnit host testing (experimental) | `nunit-host-testing.md`, `docs/product/nunit-host-testing.md` | `DevTools.NUnit.*` |
12+
| NUnit host testing (experimental) | `nunit-host-testing.md`, `nunit-native-runtime-verification.md`, `docs/product/nunit-host-testing.md` | `DevTools.NUnit.*` |
1313
| MCP agent efficiency | `docs/plans/completed/2026-07-26-mcp-agent-efficiency.md` | `DevTools.Mcp.*`, daemon |
1414
| Execution / MCP / host pipe / logging | Matching `docs/agents/*.md` + `docs/architecture/<Module>/` + `docs/product/` | `DevTools.*`, hosts |
1515
| Revit API + live execute | `revit-developer` skill, `architecture/MCP/workflows.md` | MCP + rvtdocs-mcp |
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# NUnit Native Runtime — Live P0 Verification
2+
3+
Evidence for plan Task 8 (`docs/plans/active/2026-08-12-nunit-native-runtime-mtp.md`).
4+
Raw artifacts: `%LOCALAPPDATA%\RevitDevTool\task8-evidence\`.
5+
6+
## Environment (2026-08-12)
7+
8+
| Host | PID | Build | Notes |
9+
|------|-----|-------|-------|
10+
| Revit 2023 | 45108 | 23.1.90.15 | net48; Dynamo cores loaded |
11+
| Revit 2026 | 43776 | (running) | net8 proxy for plan’s Revit 2025 ALC row (operator decision: same TFM) |
12+
| Revit 2025 ||| Not run; substituted by 2026 |
13+
| Revit 2027 ||| Not installed — environment blocker |
14+
| AutoCAD ||| Not run — optional / blocker |
15+
16+
## Revit 2023 + Dynamo / `nunit.framework`
17+
18+
Dynamo add-in assemblies loaded in-process (13 name matches including `DynamoCore`, `DynamoRevitDS`, …).
19+
20+
**On disk (Dynamo):**
21+
22+
`C:\Program Files\Autodesk\Revit 2023\AddIns\DynamoForRevit\nunit.framework.dll`
23+
`nunit.framework, Version=2.6.3.13283, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77`
24+
25+
**Loaded in AppDomain after Task1 + gen-two runs:** only DevTools generation copies
26+
`nunit.framework, Version=4.6.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb` under
27+
`%TEMP%\…\DevTools\NUnit\Generations\<generation_id>\nunit.framework.dll`
28+
(count grew with generations; Dynamo’s 2.6.3 identity was **not** loaded into the AppDomain during this session).
29+
30+
Coexistence claim for this run: Dynamo is loaded; DevTools owns its private 4.6 generation `nunit.framework` identities; Dynamo’s older framework stays on disk until a Dynamo test path loads it.
31+
32+
## Task 1 fixture (net48) on Revit 2023
33+
34+
- Discover: **31** cases, `generation_id=cd071c38…982e`.
35+
- Sync matrix (exclude `AsyncLifecycleFixture` + `FullSemanticsFixture.AsyncTest_Completes`):
36+
37+
| Outcome | Count |
38+
|---------|-------|
39+
| Passed | 25 |
40+
| Skipped (Ignore/Explicit) | 2 |
41+
| Inconclusive | 1 |
42+
| Error (deliberate unexpected exception) | 1 |
43+
44+
Summary file: `2023-task1-sync-out.json`. Host PID **45108**.
45+
46+
### Async hang (open gap)
47+
48+
Running `AsyncTest_Completes` / `AsyncLifecycleFixture` alone times out: NUnit `Run` is marshaled onto the Revit UI executor (`ExecuteAsync`), so `WaitForCompletion` blocks Idling while async continuations cannot complete → **UI-thread deadlock**. Full Task1 including async is blocked until Run is off-UI or async fixtures are adjusted.
49+
50+
## Generation-two (same Revit 2023 PID)
51+
52+
Without restarting Revit 45108:
53+
54+
| Assembly | Marker output | `generation_id` |
55+
|----------|---------------|-----------------|
56+
| staged `net48-gen1` | (prior sync run) | `cd071c38…982e` |
57+
| staged `net48-gen2` | `generation-marker=generation-two` | `0e48aa2f…039a` |
58+
59+
File: `2023-gen2-marker-out.json`.
60+
61+
## Revit 2026 (net8 / 2025 proxy)
62+
63+
- Sync Task1 matrix: same outcomes as 2023 (`2026-task1-sync-out.json`).
64+
- Gen-two marker: `generation-marker=generation-two`, new `generation_id`.
65+
- ALC unload diagnostic after generation switch: **`generation.retained`**
66+
(`Generation ALC retained after unload verification.`) — observed twice
67+
(`2026-gen2-marker-out.json`, `2026-gen1-again-out.json`).
68+
Generation switch works; clean ALC collect was **not** observed.
69+
70+
## `dotnet test` Revit API smoke (2023)
71+
72+
```powershell
73+
dotnet test samples/DevTools.NUnit.SampleTests/DevTools.NUnit.SampleTests.csproj `
74+
-c Debug.Autodesk.2023 --filter "FullyQualifiedName~Arithmetic_runs_inside_host"
75+
```
76+
77+
- `Arithmetic_runs_inside_host` **Passed**; stdout includes `23.1.90.15` and `host-pid=45108`.
78+
- Adapter still executed sibling sample tests in the same run (`Intentional_failure_for_demo` failed, `Writes_output` passed) — filter/adapter gap; acceptance evidence is the Arithmetic case + PID match.
79+
80+
## Cancel-on-disconnect (related hardening)
81+
82+
Earlier same day: Infinite-sleep CancelProbe entered on PID 45108 → concurrent discover blocked → kill Runner → discover completed ~8.8s → MCP execute responsive. See session notes; not re-run in this evidence pack.
83+
84+
## Task 8 close criteria vs this pack
85+
86+
| Plan item | Status |
87+
|-----------|--------|
88+
| 2023 Dynamo + `nunit.framework` inventory | Done (Dynamo loaded; 2.6.3 on disk; 4.6 generations in AD) |
89+
| 2023 Task1 discover/run | Sync matrix done; **async excluded** (deadlock) |
90+
| 2023 generation-two same PID | Done |
91+
| 2025 ALC unload | **Proxy 2026**: switch OK, diagnostic **`generation.retained`** |
92+
| 2027 live | Blocker — not installed |
93+
| AutoCAD smoke | Blocker / not run |
94+
| `dotnet test` Revit API smoke | Arithmetic Passed on PID 45108 (filter imperfect) |
95+
96+
**Verdict:** do **not** treat Task 8 as fully closed. P0 live path is largely proven on 2023 + 2026, but async UI deadlock, ALC `generation.retained`, and 2027/AutoCAD blockers remain.

docs/plans/active/2026-08-12-nunit-native-runtime-mtp.md

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# NUnit Native Runtime And MTP-First Integration Plan
1+
# NUnit Native Runtime And MTP-First Integration Plan
22

33
**Goal:** Run full NUnit 4.6.1 semantics inside Autodesk hosts through a native
44
framework runtime, with MTP as the sole IDE/Test Explorer compatibility layer.
@@ -16,7 +16,7 @@ Date: 2026-08-12
1616

1717
## Status
1818

19-
Accepted **P0 implementation largely landed in tree; Task 8 live matrix not
19+
Accepted — **P0 implementation largely landed in tree; Task 8 live matrix not
2020
fully closed.** See Progress and Remaining Gaps below. Do not start P1 MTP
2121
work until Task 8 open gaps are resolved or explicitly waived.
2222

@@ -225,7 +225,7 @@ public sealed record NUnitRuntimeEvent(
225225
its reference to `DevTools.NUnit.Core` to the already-loaded host copy so the
226226
cast remains valid across ALC/no-context boundaries.
227227

228-
## P0 Correct NUnit Runtime
228+
## P0 — Correct NUnit Runtime
229229

230230
### Task 0: Correct assembly ownership before extending the runtime
231231

@@ -241,8 +241,7 @@ cast remains valid across ALC/no-context boundaries.
241241
- Test: `tests/DevTools.NUnit.Core.Tests/`
242242
- Test: `tests/DevTools.NUnit.Host.Tests/`
243243

244-
- [ ] Add a failing contract-boundary test proving Core references neither
245-
`DevTools.Ipc` nor `System.Text.Json`.
244+
- [x] Add a failing contract-boundary test proving Core references neither`n ``DevTools.Ipc`` nor ``System.Text.Json``.
246245
- [ ] Make Core contain only plain DTOs, runtime interfaces, protocol constants,
247246
and transport-neutral compatibility data.
248247
- [ ] Keep exactly one loose Core assembly for Host and Runtime type identity.
@@ -313,8 +312,8 @@ and matching PDBs.
313312
- Modify: `tests/DevTools.NUnit.Core.Tests/NUnitProtocolGoldenTests.cs`
314313
- Modify: `tests/DevTools.NUnit.Core.Tests/ProtocolCompatibilityTests.cs`
315314

316-
**Produces:** protocol version `2` and the interfaces listed in “Runtime
317-
Interfaces”.
315+
**Produces:** protocol version `2` and the interfaces listed in “Runtime
316+
Interfaces”.
318317

319318
- [x] First add golden JSON tests for traits/properties, source file/line,
320319
parent test ID, skip reason, attachments, generation ID, and runtime
@@ -618,7 +617,7 @@ P0 live verification does not depend on the later MTP `serve` endpoint.
618617
- Update progress/evidence in this plan after each run.
619618

620619
Evidence pack (2026-08-12): `docs/agents/nunit-native-runtime-verification.md` +
621-
`%LOCALAPPDATA%\RevitDevTool\task8-evidence\`. **Not fully closed** see verdict.
620+
`%LOCALAPPDATA%\RevitDevTool\task8-evidence\`. **Not fully closed** — see verdict.
622621

623622
- [x] Revit 2023: let Runner locate/reuse or launch Revit with the installed
624623
Dynamo add-in loaded; do not start Revit directly. Record the selected PID
@@ -628,7 +627,7 @@ Evidence pack (2026-08-12): `docs/agents/nunit-native-runtime-verification.md` +
628627
Dynamo 2.6.3 on disk under `AddIns\DynamoForRevit`, not loaded this session.)_
629628
- [~] Revit 2023: discover and run the Task 1 net48 fixture; record expanded
630629
cases, lifecycle log, result summary, generation manifest, and host PID.
631-
_(Discover 31 cases; sync matrix 25/2/1/1 async fixtures hang on UI executor.)_
630+
_(Discover 31 cases; sync matrix 25/2/1/1 — async fixtures hang on UI executor.)_
632631
- [x] Revit 2023: rebuild to generation two without restarting Revit and prove
633632
new IL plus generation-specific dependency behavior.
634633
_(gen2 marker on same PID; new `generation_id`.)_
@@ -645,7 +644,7 @@ Evidence pack (2026-08-12): `docs/agents/nunit-native-runtime-verification.md` +
645644
logic in the selected Revit PID. The default P0 bridge is the passing smoke
646645
case in `samples/DevTools.NUnit.SampleTests`; exclude its deliberate demo
647646
failure from the acceptance invocation.
648-
_(Arithmetic Passed, `host-pid=45108`; adapter still ran siblings filter gap.)_
647+
_(Arithmetic Passed, `host-pid=45108`; adapter still ran siblings — filter gap.)_
649648
- [x] Before each deploy, kill Revit and rebuild the add-in for the target year.
650649
After deployment, allow only Runner to establish the live session. Reuse that
651650
session for generation-two proof; do not kill it merely to rebuild a test
@@ -654,7 +653,7 @@ Evidence pack (2026-08-12): `docs/agents/nunit-native-runtime-verification.md` +
654653
- [ ] Stop P1 if Revit 2023 plus Dynamo or Revit 2025 fails. Choose between a
655654
documented net48 host-restart requirement and a reduced support matrix;
656655
never expand reflection emulation.
657-
_(2023+Dynamo coexistence OK for this pack; modern ALC unload not clean
656+
_(2023+Dynamo coexistence OK for this pack; modern ALC unload not clean —
658657
hold P1 on unload/async gaps.)_
659658

660659
Required compile proof follows `.agents/skills/build/SKILL.md`:
@@ -693,13 +692,13 @@ Tracked evidence: [`docs/agents/nunit-native-runtime-verification.md`](../../age
693692
| Modern ALC reports `generation.retained` | **P0 blocker** | Revit 2026 (net8 proxy for 2025) switches generations but unload verifier never sees collect. Diagnose retain roots; do not treat as unload pass. |
694693
| Task1 full suite (incl. async) not green live | P0 | Blocked by async hang; sync matrix already recorded. |
695694
| Adapter/`dotnet test` filter runs sibling sample tests | P1-adjacent | Arithmetic smoke OK on PID; filter still executes demo fail. |
696-
| Revit 2027 live | Env blocker | Not installed record only. |
695+
| Revit 2027 live | Env blocker | Not installed — record only. |
697696
| AutoCAD smoke | Optional / blocker | Not run. |
698697
| Cancel-on-disconnect | Done (hardening) | Pipe CT + RuntimeManager CT; live Infinite-sleep probe on 2023 passed. |
699698

700699
**Hold P1** until async executor + ALC unload gaps are closed or the support matrix is explicitly reduced in ADR/plan.
701700

702-
## P1 MTP-Only IDE Integration
701+
## P1 — MTP-Only IDE Integration
703702

704703
### Task 9: Make Runner the explicit host-process owner
705704

@@ -750,7 +749,7 @@ public sealed record NUnitRunnerHostInfo(
750749
existing explicit launch/cancellation policy. Never terminate a reused host.
751750
- [ ] Add a framed Runner endpoint for hello, discover, run, cancel, and
752751
shutdown. Forward host progress without converting it to console prose.
753-
- [ ] Record the package launcher `Runner serve` boundary in the architecture
752+
- [ ] Record the package launcher → `Runner serve` boundary in the architecture
754753
document. Prove that MTP can neither start nor stop the endpoint and that
755754
endpoint shutdown policy stays with Runner and its external launcher.
756755
- [ ] Include authoritative Autodesk host PID and ownership in every session
@@ -911,7 +910,7 @@ P1 exit gate: Visual Studio MTP run passes on Revit 2024 and 2025, Rider MTP run
911910
passes without native-provider hijack, C# Dev Kit MTP run passes on Revit 2025,
912911
and logs prove MTP delegated process policy to Runner in every case.
913912

914-
## P2 Packaging And Optional Ergonomics
913+
## P2 — Packaging And Optional Ergonomics
915914

916915
### Task 13: Package one consumer surface and retire the emulator
917916

@@ -1031,9 +1030,9 @@ and clean sample restore/run evidence.
10311030
- [x] Prioritized execution plan drafted for review.
10321031
- [x] Plan accepted.
10331032
- [x] On acceptance, mark the 2026-08-10 active plan superseded.
1034-
- [x] Tasks 0–7A implemented in tree (Core/Transport, Runtime, generation
1033+
- [x] Tasks 0–7A implemented in tree (Core/Transport, Runtime, generation
10351034
loading, Host manager, Runner CLI v2, packaging ownership).
1036-
- [~] Task 8 live host matrix partial evidence recorded; **not closed**
1035+
- [~] Task 8 live host matrix — partial evidence recorded; **not closed**
10371036
(async UI deadlock, `generation.retained`, 2027/AutoCAD blockers).
10381037
- [ ] P0 exit gate complete (blocked on Task 8 remaining gaps).
10391038
- [ ] P1 Runner activation/ownership boundary complete.
@@ -1050,7 +1049,7 @@ and clean sample restore/run evidence.
10501049
- Runtime proof: full NUnit semantics fixture, real IL generation change,
10511050
dependency-version change, conflicting NUnit identity, and modern ALC unload.
10521051
- Live proof: Revit 2023 plus Dynamo recorded; Revit 2025 substituted by
1053-
Revit 2026 (net8) per operator unload still `generation.retained`.
1052+
Revit 2026 (net8) per operator — unload still `generation.retained`.
10541053
- Operational live proof: agents use Runner rather than directly starting
10551054
Revit, keep the live lane serialized, record the selected host PID, and kill
10561055
the host before deploying changed add-in binaries.

0 commit comments

Comments
 (0)