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
40 changes: 40 additions & 0 deletions acceptance-register.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Real-world validation that cannot run at development stage, and the human prereq
| AR-18 | A Windows node identifies a running WSL VM's worker process (`vmmem` or `vmmemWSL`) as one `GUEST_VM` consumer in unmanaged load, never controlled, and never presents the VM's Linux processes as its own (ArcForges-Design 03 §1, §2, §9; A-L01, AD-0018 §2). Procedure: on Windows 11 with WSL2 and one distribution installed, (1) start the distribution outside ArcForges (`wsl -d <distro> -e sleep 600`); (2) run a native node; (3) `arcforges ps --label guest --json` lists the VM worker with label `PROCESS_LABEL_GUEST_VM`, no task, and a memory figure close to Task Manager's for that process, and no Linux process of the distribution appears; (4) allocate about 2 GiB inside the distribution (for example `python3 -c "b=bytearray(2<<30); import time; time.sleep(60)"`): `arcforges resources --json` shows unmanaged memory rising and the memory budget falling by about that amount within about 10 s; (5) a task running `wsl.exe -d <distro> -e sleep 30` has every process flagged `crossesVmBoundary`, and `ps --label managed` lists only Windows processes of its job; (6) run `ArcForges.ClosedLoop.Tests -method *ATaskThatRunsWsl*` there and keep the VM workers it prints | WSL is not installed on the workstation, so no VM worker runs there; the `crosses_vm_boundary` flag itself is proven with the inbox `wsl.exe` (AF-RES-01) | A Windows 11 machine with WSL2 and one distribution (user-provided; installing WSL is the user's step) | AF-RES-01 | Open |
| AR-19 | Successful Windows process adoption (ArcForges-Design 04 §10; `ResourceService.AdoptProcess`): a same-user process outside every job is adopted into the root job and a nested adoption job (the root job's limits apply, V-W01), appears as an `ADOPTED` task with label `ADOPTED`, its existing children follow, it can be terminated through `process.terminate`, and it ends `LOST` ("no exit status: the node is not the adopted process's parent") when it exits; after a node restart an adoption job the node cannot reopen (L-14) ends the task `LOST` through `container_missing`. Procedure: on a Windows 11 machine where a process created through WMI `Win32_Process.Create` is outside every job (check with `IsProcessInJob`), run `Node.Platform.Windows.Tests -method *AdoptionTests.AProcessOutsideAnyJobIsAdoptedWithItsChildrenAndTerminated` and `Node.Core.Tests -method *AdoptionLifecycleTests.AnAdoptedProcessThatEndsByItselfEndsItsTaskLostWithoutAnExitStatus` and `-method *AdoptionLifecycleTests.AnAdoptionContainerTheNodeCannotReopenAfterARestartIsLost`; none may skip with the "already in a job" reason | On the workstation every user process, a WMI-created one included, is already in a job (ArcForges-Design register L-30), so 04 §10 refuses every candidate and the capability `adopt` reports `LIMITED`; the refusal path is proven there (AF-SEC-01) | A Windows 11 machine or VM where a WMI-created process is outside every job (user-provided) | AF-SEC-01 | Open |
| AR-20 | MR-07: establish the cause of the Windows supervisor test's unexplained node stop exit 75 and verify a discriminating repair if required | The historical failure has not recurred with the retained diagnostics; non-recurrence cannot establish its cause or prove a fix | A captured native Windows recurrence with verbose transport/descriptor/node/supervisor evidence, or a proven causal reproduction; the Windows MCP venue is already available, no new human provisioning | AF-NODE-01 | Open; unresolved observation, not a passed check or task block |
| AR-21 | MR-11: a non-elevated Windows node and an elevated client of the same user: user-SID pipe ownership succeeds, but an unidentifiable elevated peer is refused before API execution | Existing automated ownership tests do not create two processes at different integrity levels; owner deferred full end-to-end testing on 2026-10-15 (ledger 30) | User-performed Windows 11 cross-integrity run at final end-to-end acceptance; no automatic elevation or re-request now | AF-NODE-01 | Open; deferred validation, no task block |

## 2. Human prerequisites

Expand Down Expand Up @@ -90,3 +91,42 @@ When a recurrence is observed during authorized maintenance:
Do not assign the old RECOVERING/INTERNAL race as the cause of the different pipe-missing exit 75 without evidence.
5. Close only with a proven cause and a discriminating regression/repair where required, reviewed and verified at its final pushed
commit on the required native hosts. More silent runs alone never close this entry. No retry-count increase or weakened assertion.

### AR-21: MR-11 same-user cross-integrity client

Current development evidence: the user-SID ownership fix and three `PipeOwnershipTests` already exist in ArcForges main
`5eaee92a4a964469bad41dad28dad9787b7552cf`; the fix was introduced by `3c323b2` during AF-NODE-01. `OwnerIsUser` rejects another
user, BUILTIN\Administrators, SYSTEM and absent SIDs. A real user-owned pipe carries a byte after the owner check; a pipe owned by
the token's default owner is accepted only when that owner is the user. The retained Windows CI leg at reviewed head
`8fe744ffee80f24b59f835af60ba43e4a5163391` ran Client.Tests 102/102, no skips. This is existing evidence, not a new cross-integrity
run. No missing ownership test or source repair was found. DesktopPlatform's separate transport is MR-12, not resolved here.

The two checks differ: the client checks the server pipe's user SID; the node must also identify its peer. Current NodeClient turns
three dropped hellos into AccessDenied and explains that an elevated client of a non-elevated node is refused. A successful pipe
ownership test does not prove successful node Hello across integrity levels. This acceptance expects that refusal, not privilege
support or node elevation. The real pair remains unverified; the owner's ledger-30 deferral is retained without re-asking.

User-performed procedure at final end-to-end acceptance (not run in this maintenance pass):
1. Record the source revision, matching Release binary paths, Windows version and whether each shell is elevated. In an ordinary
shell and then in the user's elevated shell run the already built ownership tests:
`dotnet test --project tests/ArcForges.Client.Tests -c Release --no-build --filter-class ArcForges.Client.Tests.PipeOwnershipTests --minimum-expected-tests 3 --output Detailed`.
Preserve the test output identifying the token-owner relation; both runs must pass all three tests without skips. The SID rule
tests alone are not a substitute for the next two-process case.
2. In the ordinary shell prepare a unique temporary test root, its `config/node.json` containing a `dataRoot` inside that root, and a
unique pipe name. Set `ARCFORGES_CONFIG_DIR` to that config directory, `ARCFORGES_ENDPOINT` to that pipe name and
`ARCFORGES_TEST_MACHINE=isolated`; unset `ARCFORGES_OS_SECRET_STORE_TESTS`. Use `--test-mode` on every invocation, as the existing
ClosedLoop TestNode fixture does, so the node data key uses the isolated file-backed store. Never select a real credential store.
Run `<matching arcforges.exe> node run --test-mode` there. In another ordinary shell with the same three test-environment values,
run `<matching arcforges.exe> node wait-ready --test-mode`, then `<matching arcforges.exe> status --json --test-mode` as baseline.
3. In the user's elevated shell set the same isolated test-environment values and no OS-store opt-in. Run
`<matching arcforges.exe> status --json --verbose --test-mode` with a 30 s external bound. Preserve exit/stdout/stderr and the
node log. Require the client ownership check to accept the user-owned pipe, then AccessDenied/refusal when the ordinary node
cannot identify the elevated peer; no successful Hello, privileged API action, replacement node or elevation by ArcForges.
If the OS permits peer resolution instead, preserve that evidence and review the stated expectation before closing this entry.
4. Re-run ordinary-shell status to prove the original node remains usable; stop it from that ordinary shell with
`<matching arcforges.exe> node stop --test-mode`. Preserve process identities, endpoint descriptor and logs before disposing only
this temporary environment. No managed privileged task, second account, device-policy change or real credential cleanup is needed.

Residual risk: no retained run proves the actual ordinary-node/elevated-client peer-resolution/refusal combination. Close only with
that two-process evidence and review of the observed result. AR-02 second-account isolation and the deferred positive auto-start leg
remain separate and open; this entry neither proves nor changes them.
3 changes: 2 additions & 1 deletion delivery-graph.json
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,8 @@
"F-N02"
],
"acceptance_register": [
"AR-02"
"AR-02",
"AR-21"
],
"human_prerequisites": [],
"risks": [
Expand Down
1 change: 1 addition & 0 deletions ledger/ledger.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,4 @@
{"at": "2026-10-25T16:20:01Z", "task": "AF-SEC-01", "kind": "note", "text": "MR-08 resolved in the delivered gate: TaskGate maps nonterminal ADOPTED CancelTask to process.terminate (introduced cd0bb00a, delivered ArcForges#31 merge 2180053; both ancestors of freshly fetched main 5eaee92). REMOTE is DENY and approval cannot bypass it; settled/replay paths cannot issue a new stop. Existing adopted gate/audit and per-origin matrix tests retained, included in verified head 8fe744f; no new runtime verification claimed. See maintenance/2026-10-25-mr08-permission.md."}
{"at": "2026-10-25T16:20:01Z", "task": "AF-CLD-05", "kind": "note", "text": "MR-08 future obligation assigned in acceptance while task stays planned: on the real signed remote-to-node path, REMOTE cancel_task of a nonterminal ADOPTED task must be denied as process.terminate before any stop, leave the process running and audit denial; medium risk, step-up and approval cannot bypass REMOTE DENY. The delivered local gate is already correct; real remote integration is not implemented or claimed verified in this maintenance pass."}
{"at": "2026-10-25T16:22:16Z", "task": "AF-AI-01", "kind": "note", "text": "MR-09 assigned, not implemented: re-read ledger 88, current ClientSessions/empty AgentRoots and Design 11 section 1 at main c36bf89. AF-AI-01 acceptance now requires registered-root verified CLI descendants to stay AGENT despite pty/console, with effective permission/approval coverage on native Windows and Linux (F-A02). Added the security Design reference and notes describing the pre-registration HUMAN consequence and residual missing-root/escaped-ancestry same-user bypasses; no hostile-agent isolation claim, no real-client validation claimed, task stays planned. No feature implementation or task activation."}
{"at": "2026-10-25T16:26:12Z", "task": "AF-NODE-01", "kind": "note", "text": "MR-11 deferred validation AR-21, not a new runtime repair: current ArcForges main 5eaee92 retains user-SID pipe owner check introduced 3c323b2 and three PipeOwnershipTests, rejecting other user/group/SYSTEM/null owners. Retained native Windows CI at reviewed head 8fe744f passed Client.Tests 102/102 without skips; no fresh cross-integrity evidence claimed. Client pipe ownership and node peer resolution are separate: current NodeClient refuses after three dropped hellos with AccessDenied and elevated-client guidance. Actual non-elevated-node/elevated-client combination remains unproven and follows owner ledger-30 final end-to-end deferral, without re-asking or elevating here. AR-21 now records evidence, isolated test-mode procedure, expected fail-closed peer refusal and closure limits, linked from AF-NODE-01; task remains delivered, no task block. MR-12 DesktopPlatform, AR-02 second-account and positive auto-start remain separate. No real credential-store operation or privileged managed task."}
2 changes: 1 addition & 1 deletion maintenance/2026-10-24-repair-list.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ managed tasks, no option that disables protection to enable elevation. The stop
| MR-08 | Remote `CancelTask` (REMOTE, medium) would reach ADOPTED tasks, terminating an adopted process although the matrix marks terminating a process D for REMOTE. | 59 (4), 65 | ArcForges, Plan | No REMOTE caller exists before AF-CLD-04/05 *(confirm the gate's ADOPTED handling)* | fix in the gate if the delivered matrix already decides it; otherwise assign to AF-CLD-05 with the obligation in its record | resolved in delivered gate: AF-SEC-01/ArcForges#31 (merge 2180053; TaskGate branch introduced cd0bb00a) maps ADOPTED cancellation to process.terminate, REMOTE DENY; unchanged current main 5eaee92 and existing gate/matrix coverage checked; real remote-path refusal now explicit in planned AF-CLD-05 acceptance, not claimed verified; [evidence](2026-10-25-mr08-permission.md); ledger AF-SEC-01 and AF-CLD-05 notes |
| MR-09 | An agent CLI with a pseudo-terminal is classified HUMAN until agent roots are registered (documented bypass, Design 11 §1). | 88 | Plan | AF-AI-01 acceptance names agent-root identification (F-A02) but not this consequence | assign: AF-AI-01 record names the obligation | assigned: AF-AI-01 acceptance now requires registered-root CLI descendants with a pty/console to remain AGENT, including effective permission/approval coverage on Windows and Linux (F-A02); notes name the current missing-root consequence and residual same-user bypasses, Design 11 reference added; task stays planned, no implementation or real-client validation claimed; ledger AF-AI-01 note |
| MR-10 | The interim origin trusted a self-declared client kind. | 59 (1), 64 | ArcForges | AF-SEC-01 verifies client kinds against the peer's executable (ArcForges#31; ledger 87) | resolved | resolved: ArcForges#31 (merge 2180053); `ClientSessions` assigns the origin from the client kind verified against the peer's executable (`ClientImages.Verifies`); ledger AF-SEC-01 delivered |
| MR-11 | Cross-integrity case: a non-elevated node with an elevated same-user client (resolution and acceptance entry). | 20, 30 | ArcForges, Plan | ArcForges.Client owner-SID check fixed in AF-NODE-01; no acceptance-register entry *(confirm)* | fix: test if missing; acceptance-register entry for the real elevated case (deferred validation) | open |
| MR-11 | Cross-integrity case: a non-elevated node with an elevated same-user client (resolution and acceptance entry). | 20, 30 | ArcForges, Plan | ArcForges.Client owner-SID check fixed in AF-NODE-01; no acceptance-register entry *(confirm)* | fix: test if missing; acceptance-register entry for the real elevated case (deferred validation) | deferred validation (AR-21): ArcForges.Client user-SID repair and three existing ownership tests confirmed (retained Client.Tests 102/102 at 8fe744f); real non-elevated-node/elevated-client peer identification/refusal remains unproven, owner final end-to-end deferral retained; procedure and AF-NODE-01 register link added, no elevation performed; DesktopPlatform MR-12 separate; ledger AF-NODE-01 note |
| MR-12 | DesktopPlatform `LocalRpcClientChannel` CurrentUserOnly check refuses an elevated same-user client (the defect ArcForges.Client fixed locally). | 30 | DesktopPlatform | *(confirm in DesktopPlatform main)* | fix in DesktopPlatform; adoption by ArcForges recorded separately (MR-43) | open |
| MR-92 | Lost `JobRemoved` signal: `SystemdManager`'s handler looked for the job's waiter and recorded the result only when it found none, while `WaitJob` registers its waiter and then reads the record; a wait registering in between missed the end and ran to its timeout although the job had finished (seen as a 10 s adoption refusal in `AdoptionTests`; an attempt's 90 s start wait could record 'did not start' for a running attempt). | found in MR-76 (Linux leg at bbd4ddb) | ArcForges | live-manager probe: 68 of 20,800 waits missed on main, 0 of 28,800 with the fix | fix | fixed: ArcForges#40 (merge 64e9f7c); ledger AF-EXEC-02 note |
| MR-95 | Timeouts and CPU-time limits never fire for an attempt recovered STARTING: the supervisor's timeout and CPU-time checks require `attempt.StartedTimestamp`, which only the change to RUNNING sets, and recovery reads `row.StartedAt`, so a command that a recovered launch starts (during the node gap or after) runs without `timeout_ms` or a CPU-time limit, contrary to 04 section 6 and section 9. | found in MR-89 review (ArcForges#42) | ArcForges | `ExecutionSupervisor.cs` timeout/CPU check and recovery (lines cited in #42's review record) | fix: give a recovered STARTING attempt a start time once its command is known to run; fault test with a restart in a launch step | open |
Expand Down