# WSC-MVC — Test Results Host under test: `win2025test` (Tailscale 100.127.62.31), Windows Server 2025 Standard, build 10.0.26100, 64-bit. Access: SSH (key-based, `Administrator`) from the OpenClaw Linux host, driving `cscript`/`powershell` remotely. Site: `WscMvc`, binding `*:8090`, physical path `C:\Projects\wsc-mvc`, app pool `WscMvc` (64-bit, no managed code). Date: 2026-09-19. ## M0 — Environment and feasibility | Check | Result | |---|---| | Windows version / arch | PASS — Server 2025 Standard, 10.0.26100, 64-bit | | IIS + Classic ASP (`Web-ASP`) + CGI/ISAPI installed | PASS | | URL Rewrite module installed | PASS (`rewrite.dll` registered as global module) | | WebAdministration PowerShell module | PASS (v1.0.0.0) | | WSC/COM runtime (`scrobj.dll`) present | PASS (System32 and SysWOW64) | | `regsvr32`/`cscript`/`wscript` present | PASS | | Minimal WSC register/instantiate/call/unregister/re-register outside IIS | PASS — see M1 component tests below (folded into M1 since the same components serve both gates) | Command: `cscript //nologo tests\Test-Components.vbs` — see M1. ## M1 — Vertical HTTP slice ### WSH component smoke test Command: ``` cscript //nologo C:\Projects\wsc-mvc\tests\Test-Components.vbs ``` Result: **PASS** ``` PASS: /hello -> 200 OK | text/html; charset=utf-8 | Hello from WSC-MVC! PASS: unknown route -> 404 Not Found RESULT: ALL PASS ``` ### HTTP integration test Command: ``` powershell -File C:\Projects\wsc-mvc\tests\Test-Http.ps1 -BaseUrl http://localhost:8090 ``` Result: **PASS** ``` PASS: GET /hello status 200 PASS: GET /hello content-type PASS: GET /hello body PASS: GET /Framework/Application.wsc denied RESULT: ALL PASS ``` Also verified directly from the Linux host over the tailnet: ``` curl -i http://100.127.62.31:8090/hello ``` -> `HTTP/1.1 200 OK`, `Content-Type: text/html; charset=utf-8`, body `Hello from WSC-MVC!`. **PASS** ### Direct source/config access denied `GET /Framework/Application.wsc` (and by the same `hiddenSegments` mechanism, `Controllers/`, `tests/`, `tools/`, `docs/`) -> `404 Not Found`. **PASS** (covered by `Test-Http.ps1` above for the `.wsc` case; other directories share the identical `web.config` rule and were not individually re-tested by automated script, only spot-checked manually). ### Safe failure on broken/missing registration Steps: unregister both components -> request `/hello` -> observe safe 500 with no leaked path/exception -> re-register -> confirm recovery. - From the VM itself (`curl http://localhost:8090/hello` while unregistered): `HTTP/1.1 500 Internal Server Error`, `Content-Type: text/plain; charset=utf-8`, body exactly `Internal Server Error` (our own `Default.asp` error branch). **PASS** - From a remote/tailnet client under the same unregistered condition: `HTTP/1.1 500 Internal Server Error` with IIS's own generic friendly-error HTML (no path/exception content either). **PASS** — see `docs/DECISIONS.md` for why local vs. remote differ (IIS `httpErrors errorMode=DetailedLocalOnly`, expected default behavior, not a bug). - `cscript //nologo tests\Test-Components.vbs` while unregistered: `FAIL: could not create WscMvc.Application - ActiveX component can't create object` (test script correctly reports FAILURE, exit code 1 — this is the *expected* result of this specific check, proving the failure path is real and detectable, not silently swallowed). - After `tools\Register-Components.ps1`: HTTP and WSH tests both back to PASS (shown above). ### Reversible unregistration Command sequence: ``` powershell -File tools\Register-Components.ps1 powershell -File tools\Unregister-Components.ps1 powershell -File tools\Register-Components.ps1 ``` Result: **PASS**, but only after a fix — see `docs/DECISIONS.md` finding on `regsvr32 /s /u` not actually removing `.wsc` registry entries on this host. `tools\Unregister-Components.ps1` now verifies and, when needed, explicitly removes exactly this project's `ProgID`/`CLSID` pair. Confirmed via direct registry inspection (`HKLM:\SOFTWARE\Classes\WscMvc.Application` / `WscMvc.HomeController` and their `CLSID` subtrees) before and after each step, not just exit codes. ### Concurrency (basic) Command: two `curl` requests to `http://100.127.62.31:8090/hello` fired in parallel from bash (`&` + `wait`). Result: **PASS** — both returned `200`, both bodies exactly `Hello from WSC-MVC!`, no cross-request leakage or interference observed. This is a basic smoke check only, not a load test (out of scope for M1). ## Not yet run / out of scope for M1 - Formal 400/405 method-not-allowed handling — routing table doesn't exist until M3. - Broader concurrency/load testing — deferred to M6 per IMPLEMENTATION_PLAN. - 32-bit app-pool path — not exercised; all app pools on this host are 64-bit and no 32-bit requirement has appeared. Revisit if a future dependency needs 32-bit COM. ## M1 gate status: **PASS** All SPEC §14 acceptance criteria for M1 were run on real Windows/IIS (not inferred) and passed, including one real defect found and fixed during testing (unregistration). Proceeding to M2 (lifecycle/error-handling generalization) is unblocked.