Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 17 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ jobs:
regression:
name: Windows regression (Node ${{ matrix.node }})
runs-on: windows-2025
timeout-minutes: 15
# Cold setup plus the full Node 22 native matrix can exceed 15 minutes.
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
Expand All @@ -43,6 +44,9 @@ jobs:
run: npm ci
- name: Build and verify delivery
run: npm run check
- name: Verify shared cache contracts
if: matrix.node == '22'
run: node scripts/verify-shared-cache.mjs
- name: Verify tool errors and recovery contracts
if: matrix.node == '22'
run: npm run test:error-contracts
Expand All @@ -59,17 +63,28 @@ jobs:
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
npm run test:manual-release
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
- name: Preserve bounded check report
- name: Verify concurrent SDK clients
if: matrix.node == '22'
run: node scripts/verify-multi-agent.mjs --roslyn-only
- name: Verify design-time output ownership
if: matrix.node == '22'
run: node scripts/verify-design-time-concurrency.mjs
- name: Preserve check reports and stage logs
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: check-node-${{ matrix.node }}
path: |
test-tmp/check/**/report.json
test-tmp/check/**/*.log
test-tmp/check/**/*.xml
test-tmp/error-contracts/**/report.json
test-tmp/roslyn-host/**/report.json
test-tmp/roslyn-gateway/**/report.json
test-tmp/owner-death/**/report.json
test-tmp/manual-release/**/report.json
test-tmp/multi-agent/**/report.json
test-tmp/design-time-production/**/report.json
test-tmp/shared-cache/**/report.json
if-no-files-found: warn
retention-days: 7
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# Changelog

## 0.15.0 (unreleased)

- Add per-Host design-time intermediate outputs, original project exclusion/import preservation, conservative generated-input filtering, and owned output cleanup. Internal Host input policy is now 2; missing/old policy handshakes are rejected and their processes reaped. The local 2026-09-11 build passes core regression and real MCP concurrent startup; remote CI and actual consumer rollout for these changes remain pending.
- Preserve `PROJECT_LOAD_FAILED` when original project evaluation rejects malformed project XML. Validate Configuration and TargetFramework as literal directory segments before Host admission, and verify normalized design-time output containment inside the owning UUID namespace.
- Replace the prototype comparison acceptance entry with verification of the current published Host and production client. Use the actual Host UUID for blockers and ownership checks; fail on selected-case errors, empty selection, changed delivery, cleanup failures or surviving observed processes. CI now includes simultaneous A/B/A startup and the production semantic/concurrency/input matrix, including prebuilt custom outputs and two target frameworks.
- Bind cached payload integrity to the namespaced key and validate overflow size/SHA-256 before memory or disk reuse. Rebuild on missing/corrupt attachments, swapped or changed JSON payloads, and older entries without integrity metadata. Keep the existing directory layout, public MCP shape and cleanup ownership.
- Bound JSON reads by the opened file size plus one detection byte and stream attachment checks in 64 KiB chunks within the existing disk budget. Preserve managed metadata for uncacheable attachments so existing capacity/TTL cleanup can reclaim them. Disk limits remain periodic cleanup targets, and returned attachments have no cross-call retention lease.
- Recheck the exact memory entry after asynchronous validation, and invalidate in-flight disk reads across writes, pruning and workspace resets. Drain accepted writes before disk reads and serialize stale-entry cleanup with a state check. Concurrent reads can no longer resurrect cleared/evicted values, overwrite replacements, miscount memory, or unlink newer local writes. Failed attachment validation only removes its own memory entry.
- Add eight real SDK/Gateway shared-cache scenarios and extend the published-Host matrix to 21 scenarios with two peers rejecting old locators after an edit, reloading to updated references and retaining the survivor's snapshot. CI includes both matrices and their failure reports; the current local increment has not been pushed to run remote CI.

- Bound admission to 32 unfinished business calls and four shared lightweight status calls per instance, with 64 KiB raw UTF-8 JSON arguments before normalization. Report SERVER_BUSY before execution; preserve FIFO in existing mutexes, cancellation through actual cleanup, and a deadline that includes queue wait. Do not automatically replay calls or restart a Host on overload.
- Reuse the admitted request's timer when the code operation has the same deadline. Preserve REQUEST_TIMEOUT through shorter adapter queue budgets, reject results completed after the request deadline, and count synchronous deadline failures even before the lease timer runs. Capacity is still returned only after the call finishes its cleanup.
- Remove cancelled startup/recovery waiters, expose admission counters/timings, and keep status available during business saturation. Passive hello uses known cache observations, with explicit unknown/incomplete disk values; diagnosis refreshes disk statistics. Retain manual-release and shutdown barriers through pending work and cleanup.
- Retain the original shared `obj` collision reports and simultaneous same-root startup as regression coverage. The production private-output implementation passes that bounded case; the separated-startup diagnostic mode still cannot establish concurrency safety. Arbitrary target-generated project references, power-loss orphan cleanup, UI concurrency and long-term storage behavior remain unverified.

- Bind each connection to its startup workspace. `workspace_open` now only confirms or recovers that root; other roots return `WORKSPACE_MISMATCH` with the active/requested paths and `select_workspace_connection`. Configure a separate connection for each project. Both the MCP and core entry points reject mismatches before queueing or changing resources.
- Expose `health.workspaceBinding` with the fixed root and binding source. Explicit `--workspace` / `-w` requires an absolute path; omission fixes the launch directory. Validate the existing, link-free root before initializing caches. Preserve healthy same-root Host/snapshot reuse and failure-gated recovery.
- Migrate lifecycle and real Roslyn/UI verification to independent fixed connections, retain same-root fault injection, and add startup, mismatch, relative-path and Windows alias regression coverage. Synchronize managed manuals and native version metadata; native UI inspection behavior is unchanged.

- Preserve failed check-stage exit status, TAP totals, captured logs and native Node JUnit assertions before returning failure; upload these bounded diagnostics in CI. Reject incomplete test summaries and mark interrupted output capture explicitly.
- Register cleanup before resource-owning regression tests start so assertion failures release watchers and allow a complete failure report. Keep the non-Git fixture valid when TEMP is inside the repository by limiting Git discovery in that test process.
- Skip snapshotted resources unregistered before disposal starts, release process listeners on natural exit, and stop probing or signalling retained ChildProcess PIDs after a known exit. Preserve real owned-process cleanup and deadline behavior; OS-level atomic PID identity validation is not added.

## 0.14.0 (unreleased)

- Resolve Git from launch-time installation paths outside the workspace and use absolute argv-based execution. Disable executable fsmonitor configuration, require Git 2.36+, recognize linked worktrees and report unknown status when Git fails.
Expand Down
12 changes: 9 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ npm run delivery:verify

`check` inventories every `*.test.ts`, type-checks, builds the Gateway, restores native dependencies in locked mode, builds the Release Host and console fixtures, runs non-interactive regression and fresh-process stdio checks, then creates and verifies `dist/delivery-manifest.json`. `check:desktop` verifies that delivery, publishes the isolated WPF fixture and runs UI plus UI-to-source tests in an interactive Windows session. `test:all` runs both. Real Roslyn Host and MCP checks run on Node 22 in CI; TavernDesk checks remain opt-in. No check installs global prerequisites or changes client configuration.

Reports and bounded stage logs are under `test-tmp/check/<run>/`. CI uploads only the compact report, including failures; it does not upload local workspaces or screenshots. A passing core check does not establish desktop or real-upstream acceptance.
Reports and bounded stage logs are under `test-tmp/check/<run>/`. CI retains the report, captured stage logs and Node's JUnit test reports for seven days, including failed runs; it does not upload local workspaces or screenshots. Test stages record exit status, TAP totals and the JUnit path before propagating failure, so an early assertion remains available after later passing output. Capture keeps the existing 8 MiB process-output budget; launch, timeout or overflow errors set `outputCaptureComplete=false`, and missing TAP totals cannot pass even with exit code zero. A JUnit path alone does not prove a run completed. A passing core check does not establish desktop or real-upstream acceptance.

`npm run test:roslyn-host` and `npm run test:roslyn-gateway` use generated C# projects and an already installed SDK selected by `scripts/lib/dotnet.mjs`. The gateway check copies the entire published Code Host into a Chinese path with spaces and checks real overloads, stale identities and owned MSBuild descendants. This is not a clean-machine test or verification of the current Codex connection.

Windows CI jobs have a 20-minute overall budget for cold setup and native acceptance. Node 22 runs shared-cache checks early, then gives SDK concurrency and design-time output ownership separate steps. Design-time readiness uses the production Roslyn load budget of 120 seconds; it does not impose an additional cold-start performance target. Production request deadlines remain unchanged.

`npm run test:owner-death` kills only a generated Gateway during confirmed initial MSBuild work and checks all previously observed process identities for survivors. `node scripts/verify-owner-death.mjs --repomix` audits the actual adapter with a controlled Node CLI, without installing Repomix. `check:desktop` also runs the `--desktop` owner-death scenario against the isolated WPF fixture: the UIA Helper must exit while the target remains alive; the fixture is closed separately after recording that result. Reports are kept under `test-tmp/owner-death/`. These checks never identify client applications by process name.

`node scripts/measure-runtime-baseline.mjs` creates a small C# project, runs three fresh stdio clients, measures unused/cold/warm/exit phases, and profiles source Router startup separately. It records snapshots under `test-tmp/runtime-baseline/`, using the existing SDK. Run it without competing check jobs for a comparison; samples share OS/SDK caches and do not establish a p95, a clean-machine benchmark, or installed-client acceptance. Instrumented startup I/O counts cover the selected asynchronous Node filesystem methods and `child_process.spawn`, not all native/kernel I/O.
Expand All @@ -37,12 +39,16 @@ SDK policy follows [Microsoft global.json guidance](https://learn.microsoft.com/

Current implementation is described in the [architecture guide](WinCode-架构与数据流说明.md). Remaining work is maintained in the [active engineering plan](WinCode-下一轮工程化迭代计划书.md); completed work belongs in CHANGELOG and the append-only work log. For documentation-only changes, verify local links, commands, version claims and evidence boundaries; do not claim a new runtime regression without running it. The four managed Skill files are delivery inputs, so regenerate/verify the manifest after updating them; this does not synchronize an installed client Skill or reconnect its MCP process.

Node 22 CI runs `npm run test:error-contracts` and uploads its bounded report. It exercises protocol errors, matching tool-error text/structured payloads, real generated-file trash failures and workspace recovery; injected UI images test serialization only. Run it locally after changes to these boundaries.
Node 22 CI runs `npm run test:error-contracts` and uploads its bounded report. It exercises protocol errors, matching tool-error text/structured payloads, real generated-file trash failures, structured WORKSPACE_MISMATCH and same-root workspace recovery; injected UI images test serialization only. Run it locally after changes to these boundaries.

`npm run test:manual-release` verifies ten actual Roslyn release/reload cycles in generated C# projects, old-location rejection, stable owned resources, retained cache/watcher, edits while cold, rejection of other roots and independent fixed A/B connections. The optional Tray is built and version/fingerprint checked by `check`; `check:desktop` additionally runs `npm run test:tray`, exercising actual WinForms and secured Named Pipes with two isolated stdio MCP clients and simulated Roslyn lifetimes. Reports are under `test-tmp/manual-release/` and `test-tmp/tray/`. UI screenshots are local only; these checks do not enable autostart or alter installed MCP client configuration.

`npm run test:manual-release` verifies ten actual Roslyn release/reload cycles in generated C# projects, old-location rejection, stable owned resources, retained cache/watcher, edits while cold and A/B workspace reuse. The optional Tray is built and version/fingerprint checked by `check`; `check:desktop` additionally runs `npm run test:tray`, exercising actual WinForms and secured Named Pipes with two isolated stdio MCP clients and simulated Roslyn lifetimes. Reports are under `test-tmp/manual-release/` and `test-tmp/tray/`. UI screenshots are local only; these checks do not enable autostart or alter installed MCP client configuration.
The core inventory includes `tests/request-admission.test.ts`: MCP 4/8/16/128-call bursts, UTF-8 argument limits, status saturation, startup/recovery waiting, repeated cancellation and replacement, deadline carry-over and cleanup/shutdown ownership. `scripts/verify-multi-agent.mjs` separately measures production Roslyn across three instances, including accepted/busy/cancelled outcomes and client drain warnings.

The core inventory includes `tests/runtime-cache-regressions.test.ts`: actual input freshness despite same-size/restored-mtime writes, additions/deletions, bounded parsing reuse, missing overflow in memory/disk caches, two actual cache processes, and same-root cancellation/slow-query interleaving. Keep these adversarial cases when changing caching or workspace lifecycle. Process-tree observation also tests PID reuse: every parent edge must respect creation order, so an old system process cannot become a new Helper descendant merely through a recycled PID. A client cancellation may settle before Gateway cleanup; same-root confirmation is not a drain barrier. Observe actual in-flight completion within the existing budget, then retain strict owned-process exit assertions.

`tests/resource-identity.test.ts` separately exercises production cleanup: recheck registration immediately before invoking a snapshotted disposer, and do not probe or signal the retained PID of a ChildProcess whose exit is already known. Natural exit removes both ownership listeners. These intercepted-OS regressions supplement actual owned-child exit checks; they do not establish an atomic Windows process-identity check across a later `taskkill` call.

After a nontrivial test failure, investigate official documentation and relevant real GitHub implementations/issues before choosing a fix. Record the observed failure, applicability of the reference and actual rerun result; do not replace verification with copied examples or arbitrary longer sleeps. Obvious syntax, object-shape and path mistakes can be corrected directly.

`npm run test:tray-workflow` (also in `check:desktop`) uses two compiled stdio MCP instances, real C# fixtures, the native settings handlers and authenticated pipes. It checks warm-state continuity across spaced queries, busy refusal, targeted release/recovery and Tray exit. No active Codex configuration is changed.
Loading