Conflict: doc-budgets manifest — master raised the AGENTS.md ceiling to 1600
(superseding this branch's 1377 bump for the native/ line), take master's
values.
The ::warning:: wrapper kept the lane job green on failure — honest
about not gating merges, but a Windows regression was visible only as
an annotation buried in the run summary. GitHub has no yellow job
state, so the choice is green+annotation (too hidden) or a red X on a
non-required job (visible, still non-blocking). Take the red X:
job-level continue-on-error, plain 'Run gates' step, one less wrapper.
The step stays on the runner's native pwsh — never shell: bash — per
the MSYS-parent leak recorded in the windows-support RFC.
Also remove the temporary Windows-only failing demo test that
exercised the wrapper's annotation path (REVERT ME commit a496b9ae).
Conflicts: AGENTS.md repository-layout block (keep master's examples/ wording,
keep this branch's native/ line) and the AGENTS.md word-budget ceiling
(master's copy grew too; ceiling now 1377 for the +5-word native/ line).
The lane-split merge moved the Run gates step to `shell: bash`, which
broke it twice over. First, GHA's bash shell runs with -e, so a failing
gate aborted the step before the ::warning::/exit 0 lines — the lane
went red X instead of the intended yellow warning. Second, and worse,
Git Bash as the PARENT of the gate run leaks MSYS environment into the
suite itself, producing 8 real test failures the pwsh-launched runs
(and the DSec VM runs) never saw:
- bash exports PWD; the MSYS runtime rewrites it to Windows form for
native children, dsh-bash-local's adaptEnv passes it through, and the
executor's MSYS bash adopts it — `pwd` prints `D:/a/...` where the
tests (and the executor's MSYS dialect) expect `/d/a/...` (7 tests).
- cygwin enables SeBackupPrivilege on the runner's admin token; children
inherit the enabled state, and libuv's FILE_FLAG_BACKUP_SEMANTICS read
opens then pierce the dwShareMode=0 lock the jsonl EBUSY test holds —
loadLive resolves instead of rejecting (1 test).
Evidence: run 28918325498 (pwsh step, pre-merge) failed only the two
hooks dispose tests since fixed by f8fd8c00; run 28921741006 (bash
step) fixed those and failed exactly the 8 above, with zero relevant
source diff between them.
Fix: run the wrapper in pwsh — a native command's failure doesn't abort
pwsh, so $LASTEXITCODE capture + ::warning:: + exit 0 works without an
errexit dance, and the gates start from a native Windows shell as they
do everywhere else Windows CI has been validated.
Docs: the windows-support RFC drops the stale continue-on-error wording
(replaced by the warning wrapper) and records the launch-environment
limitation — native shell required today; making an MSYS parent a
supported launch environment (PWD scrub in adaptEnv, privilege-explicit
tests) is a future improvement direction.
The Windows CI was a single job running the full ci-windows inventory
(check:ci:windows), while Linux splits into 5 lanes (static/lint/coverage/
snapshot/artifacts) per the parallel-gates RFC. The single-job shape was a
transitional artifact from when Windows CI was added as a non-required
observation lane; its rationale ('keep gate parallelism modest so coverage
is not starved') conflated run-gates intra-job concurrency
(DSH_GATE_CONCURRENCY) with GitHub job fan-out — orthogonal concerns.
Split Windows into 4 lanes mirroring Linux (snapshot absent: its goldens
are Linux-recorded and self-skip on Windows). Each lane is a separate
GitHub job so a Windows regression is attributable to one lane, not
buried in one job's log. Concurrency is NOT throttled versus Linux: the
lane is non-blocking (continue-on-error), and the observational stance
is to actively expose Windows-arm issues rather than hide them behind
reduced parallelism.
- scripts/run-gates.ts: add ci-windows:static/lint/coverage/artifacts
modes; ci-windows (full inventory) is retained as the local one-process
entry, symmetric with Linux's ci-primary.
- .github/workflows/ci.yml: windows job becomes a matrix over the 4 lanes.
- package.json: check:ci:windows:{static,lint,coverage,artifacts} scripts.
- AGENTS.md + windows-support RFC: document the per-lane, non-blocking,
unthrottled stance.
Verified: scripts/caohuanqi-private/run-ci.py --windows (full
check:ci:windows) — all gates green except the known hooks-claude
bridge.spec waitFor timeout (pre-existing Windows subprocess-timing
flake, unrelated).
Add a Windows CI job alongside the existing Linux checks. Runs the full
test suite (without the Linux-only coverage gate) plus typecheck, lint,
doc-sync, build, hygiene, and demo smoke under PowerShell. Developer
Mode is enabled via registry for symlink support (fs-local tests,
verify-node-next-types).
Per the windows-support RFC transition plan: step (2) — non-required
Windows CI job to observe stability.
Runs `pnpm install` + `pnpm run build` (tsc -b + tsdown) on windows-2025,
and is listed in all-checks-passed `needs` so a Windows build regression
cannot land silently. Windows path/shell support is still partial, so this
lane covers the build surface only; tests and gates are not run here yet.
Bring the node-addon-landlock-run tree (tag v0.0.1, commit 614f7fd) into
native/landlock-run as its source of record: launcher development happens
here, next to the harness consumers, and the standalone repository becomes
the release mirror the tree is exported to for packing and publishing
(procedure in native/README.md). The subtree keeps its own pnpm workspace
and lockfile and is NOT added to the harness workspace: harness installs,
gates, and CI never touch it. The mirror's .github/ stays out of the
subtree; a separate manually-dispatched workflow
(.github/workflows/landlock-run.yml) runs the subtree's CI legs — the
per-architecture native builds, real-kernel launcher proofs, and pack
rehearsal — adapted with working-directory/cache paths.
eslint ignores the subtree like vendor/; AGENTS.md gains the native/
layout line (+5 words on its budget ceiling).
The existing assertion-only executable smoke proved selected outputs but could not detect drift across the integrated Python SDK, JSON-RPC notification stream, and persisted session shape.
Keep this separate from ACP snapshots because it must launch the actual platform-native packaged executable through the Python SDK. The deterministic model drives Cordis dynamic tool mounting, a Code Mode worker dispatch, direct spawn delegation, workflow-worker delegation, plugin disposal, and the parent/child persistence lineage.
Commit four portable goldens for the SDK result and three JSONL logs. Normalize timestamps, temporary paths, opaque session and agent identifiers, and bulky request headers while retaining ordering, tool names and arguments, header deltas, results, lineage, and final responses so all native build legs compare the same behavior.
Run the comparison in the label-gated executable build workflow and document the current coverage in the paired implemented RFC.