Repository navigation
Description
Context
The full UI-server suite fails a first strict admission refreshes sealed inputs only after trusted scratch creation (packages/ui-server/tests/native-worker-startup-order.test.ts:8-27). At line 21 the strict hold's scratch mount is read-only: expected true, received false.
Observed while proving #3000 at head 5196925299f7b46114227c7743f17bde39ea2cbc, based on c47483196f02c1098128207ce68c4f0de6b571ab: 4097 tests passed, this case failed in 5.96 ms, and all 14 new Action-notice tests passed. The failing case executes before the new test file. This PR does not edit the startup-order test, brain/governed-turn.ts or the SDK scratch validator.
The same failure appears in an earlier #2994 receipt at head d5423301b, before #3000, in 7.18 ms. That older complete command later ended with exit 137, so it is evidence of this assertion failing, not a passing package receipt.
On pristine main c47483196f02c1098128207ce68c4f0de6b571ab, the case passes alone (1 test, 7 assertions). A five-file comparison including provider continuation, sync runtime, inbox runtime, host Git credentials and this case also passes all 42 tests. The exact 22-file preceding-prefix comparison on that pristine main also passes all 234 tests and 1536 assertions (201.34 seconds of tests). The state or ordering dependency is not identified yet; this is not a claim that the full current main suite was reproduced failing.
Additional full-suite evidence (2026-10-26): the corrected root run at the same #3000 head passes 1964 tests and fails the two Claude interactive/voice policy-boundary cases at tests/policy-write-boundary.test.ts:80 (AREAS_WRITABLE: expected [true, true], received [false, true]). Those two cases passed in the preceding root run on the identical source head. On pristine main, the complete policy-boundary file passes all 19 cases and 587 assertions with the same offline, keyless environment. This has the same read-only-scratch symptom as the startup-order failure; a shared cause has not been established. The scratch/Git predicate is scratchIgnoredByGit in packages/ui-sdk/src/server/worker-sandbox.ts:409-423. No assertion or production guard has been changed.
Out of scope
Changing Action-notice writes, production scratch authority, native storage rules, the writable-mount assertion or runtime deadlines.
Scope
Attribute the strict scratch-writability failure at the actual scratch/Git/access/mount boundary, without assuming a fixture-only cause or one cause shared by the startup-order and policy-boundary observations. If the evidence identifies fixture lifetime, leaked state or ordering, make that fixture self-contained or restore its owned state while retaining real admission/startup-view assertions. A demonstrated production mechanism gets a separately scoped correction; this investigation does not authorize weaker scratch authority or native-storage policy.
Acceptance criteria
- Reproduce the named scratch-writable failure on current main with a recorded command, source identity and ordering; update this body's reproduction accordingly.
- Identify the responsible boundary with same-failure scratch resolution, Git-ignore, mount and access evidence. Repair an attributed fixture/state defect, or file the exact bounded production correction if the mechanism is outside this test-isolation scope; preserve production validation and the assertions at lines 21–26.
- Show a failing-first or mutation receipt on the assertion protecting the repaired state boundary.
- The focused reproduction, isolated cases, complete UI-server package suite and root
./testssuite pass with the ordinary offline guards intact.
Verification
scripts/test-offline.sh -- bun run test packages/ui-server/tests/native-worker-startup-order.test.ts
scripts/test-offline.sh -- bun run test packages/ui-server
scripts/test-offline.sh -- bun run test ./tests
Contract impact
None expected; this is a test-isolation investigation. Keep needs: repro until a current-main reproduction and the responsible state boundary are established.
2026-10-26: added the passing exact current-main prefix comparison and the root policy-boundary full-suite/isolated receipts. The full-suite state dependency is still unidentified.
2026-10-26 triage at main 2f10e0407769b685083c17a1c90bb43a060b94a0: Classified as priority: p2 (wanted, unscheduled work; no release commitment inferred). The recorded controls do not establish the missing cause; retain needs: repro. The closest general verification epic #736 is at its direct-child limit, so this investigation remains standalone by reference.
Completed comparison evidence — 2026-10-26
Reporter evidence from the completed comparison:
Additional completed controls while proving #3001, with Bun 1.4.2 and frozen dependencies:
- Full head
b9b7d099ba362838f22407902c9d3a4b9fc70cc6, based onc47483196f02c1098128207ce68c4f0de6b571ab:bun run test ./testsfailed 1963 pass / 3 fail, 74210 assertions, 848.55 seconds. The failures are the Claude interactive, Claude voice and pi interactive cases attests/policy-write-boundary.test.ts:80:AREAS_WRITABLE, expected[true, true], received[false, true]. - The complete isolated policy-boundary file passed on that merged base and on the unchanged head: 19 pass / 0 fail, 587 assertions each.
- Full merged-base root suite passed 1966/1966, 74412 assertions, 909.12 seconds.
- An unchanged full-head root retry in the same checkout passed 1966/1966, 74414 assertions, 743.99 seconds. The failed full-head receipt remains retained. No source, assertion, timeout, scratch rule or offline guard changed between the failed and passing head runs. All full-suite commands used the shared heavy-command slots.
These controls establish variability, not its cause or a repair. They do not reproduce a failing full current-main invocation. The missing correlation remains the failed request/worker's scratch resolution, Git-ignore result, mount facts and access result; the full-suite failure shares the symptom recorded here, with the voice and pi interactive observations also tracked by #2923 and #2987.
Reporter evidence from the completed comparison:
Additional evidence from #3003 (2026-10-26):
- Full root command at head
942897313c06a31499c2509cbc3357598aaa436d, merged basec47483196f02c1098128207ce68c4f0de6b571ab: 1965 pass / 1 fail, 74319 assertions. The Claude interactive policy-boundary case failsAREAS_WRITABLE, expected[true, true], received[false, true](executorsHeld,tests/policy-write-boundary.test.ts:71-83). The schedules changes do not edit that test, scratch qualification or the worker sandbox. - After the coordinator-requested refresh, the complete isolated policy-boundary file passes on pristine main
07fbce896099b87903bb994e3b6a939f232669fdand on schedules head7405e78084f4138eee9362df96f94dc92a3efbe0: 19 pass / 0 fail, 587 assertions each. - The refreshed full root suite is submitted through the shared heavy-command wrapper. The earlier failed full receipt remains retained. No assertion, timeout, scratch rule or offline guard was changed.
This matches the recorded scratch-writability symptom. The isolated controls do not reproduce a failing full current-main invocation or identify a cause or repair.
Current-main complete release-proof recurrence — 2026-10-27
The complete pre-version bun run check:pr --all for #3030 has naturally reproduced the exact startup-order assertion on reviewed main 5eebfc6289f07f11106de5c6aec9b5abd9355358: at packages/ui-server/tests/native-worker-startup-order.test.ts:21, scratch writable expected true, received false; case elapsed 4.40 ms. The later checkpoint sequence, replacement-view identity/removal and gate-release assertions were not reached. This is a failed current-main invocation with the full default-discovery order, rather than an isolated passing comparison. Its complete command is still collecting final counts and a full log; those will be added when it finishes.
Bun 1.4.2, frozen copyfile dependencies, SDK 0.3.293 and unchanged lock SHA-256 5bbd5f6651f111db3fcfabeda512d44a21163cba54c58993f8878012d548cc14 are retained. The only tracked edit is the Claude pricing check date. The invocation separately has eight ledger setup failures because its isolated default ledger directory was created with mode 0755 rather than the required 0700, plus #3038's distinct geo cancellation assertion. Those observations do not establish this scratch failure's cause; no guard, fixture, timeout or source correction was made during the run. The current fixture has its own real temporary brain, genuine Git-ignore qualification and startup-view assertions.
No unchanged full retry or passing isolated control replaces this evidence. The responsible scratch/Git/access state boundary is still unidentified. Parent release coordination owns the bounded investigation, reviewed correction and integration before new complete release proof. Retain needs: repro. Milestone 0.45.0 is preserved rather than silently retargeted; the actual failed 0.44.0 release gate requires parent scheduling reconciliation. Raise priority to p1 because this actual gate failure blocks p1 #3030, as required by the dependency-priority rule. No fix or acceptance waiver is claimed.
2026-10-27 correction: added the actual current-main complete-discovery recurrence, separate setup caveat and release-blocker priority context; historical controls and the existing release milestone remain intact.
The final root policy-boundary group also fails Claude interactive (2236.53 ms) and Pi interactive (3388.59 ms) at tests/policy-write-boundary.test.ts:80, AREAS_WRITABLE: expected [true, true], received [false, true]. Claude voice instead fails its added-count assertion at line 216 and is recorded separately on #3019. No common cause is established by these scratch symptoms.
Final retained round-5 invocation — 2026-10-27
The complete pre-version bun run check:pr --all finished with exit 1: 16,368 pass / 28 expected skip / 27 fail, two snapshots, 607,298 assertions, 16,423 tests across 1,265 files in 3,918.90 seconds. Head and fetched main both remain 5eebfc6289f07f11106de5c6aec9b5abd9355358; only the Claude pricing check date is edited. Bun 1.4.2, SDK 0.3.293, independently copied frozen dependencies and lock SHA-256 5bbd5f6651f111db3fcfabeda512d44a21163cba54c58993f8878012d548cc14 are unchanged. Complete log SHA-256: b894c1b32b57d47530eb2cdc1d2d6cc84d671679ffbdd2dc10ce0406708a0d59.
The 28 skips are 24 opt-in paid image cases and four inverse sqlite-vec placeholders; real vector cases passed. Two planned failed diagnostic workers passed their parent evidence-handoff test and are not additional outer failures. No paid inference call or registry mutation was made. Setup/lint/leakage, metadata, pinned fonts and the first real Chrome launch/render passed. The standalone pinned browser/layout/endurance, editorial reproducibility, native probes and packed consumer stages did not execute after the failed unit tier. No versioning, post-version proof, experiment receipt or release PR exists.
The isolated ledger's original mode 0755 is retained as a preparation error. Native controls establish its exact guard refusal at 0755 and successful admission/release at 0700; they do not constitute a passing release gate or attribute unrelated symptoms. Full failure contexts and source/environment identities are retained. No unchanged full retry, assertion/deadline change or waiver replaced the failure. Parent coordination must reconcile the setup error and actual failures, preserve current scheduling rulings, and select any supported separately reviewed correction before authorizing new complete proof. Historical attribution remains open.
Final explicit bun run typecheck on the unchanged failed-proof source also exits 0 (strict tsc --noEmit); this focused result does not replace the failed complete gate. Log SHA-256: 8366207267355d3e3d5bf3bf6e8c94c5f93f6078c34f08973fa2b38cdda6cc92.
2026-11-02 source/evidence review at main a84d9bfbcb4e608b504aa0a9feb1144ad9a0b77e: Reverified the actual startup-order assertion and scratchIgnoredByGit predicate. The October 27 complete-main recurrence supplies a historical failure, while same-failure scratch/Git/access/mount attribution is still missing. Removed the unsupported assumption that its owner must be a fixture, and retained the bounded test-isolation correction boundary. The old release-gate timing/scheduling paragraphs are historical now that 0.44.0 is published; publication does not resolve the scratch cause. The startup-order fixture uses its existing owned startup-view double and can run without native storage; the companion full worker-policy cases need a qualified native profile unavailable here. Earlier passing isolated controls do not supply the failed scratch/Git/access/mount tuple, and no fresh same-failure reproduction is claimed. Preserve needs: repro, p1, standalone membership and milestone 0.45.0.
Recurrence check and loaded control — 2026-11-03
Main CI recurrence check (2026-11-03): in the window 2026-10-26 18:00 UTC to 2026-11-03 08:00 UTC, main CI ran 116 times; 97 runs were green and the failed-job logs of the other 19 contain no failure of the startup-order case (trusted scratch creation) or of AREAS_WRITABLE. Main CI selects affected suites, so this loosely bounds hosted recurrence; it is not a flake rate, a reproduction or a repair. The worker scratch area is read-only this turn: git could not confirm .brain/scratch/ is gitignored notice appears in many passing main CI jobs too, so its presence is not attribution (as #3007 also records).
Loaded local control at main 3d3516a02, Bun 1.4.2, offline frozen install in an isolated worktree, unchanged source: bun run test ./packages/ui-server/tests/native-worker-startup-order.test.ts passed unloaded (192 ms), then 10 of 10 times beside 96 owned busy-loop processes on a 32-CPU host (0.95 to 1.05 s). CPU load alone does not make the isolated case fail. That is consistent with the recorded ordering or state dependency, but does not identify it.
Triage 2026-11-03: added main-CI recurrence check and loaded isolated non-reproduction; needs: repro, p1 and milestone unchanged.
Latest bounded investigation and remaining evidence — reconciled 2026-11-05
The 2026-11-04 investigator receipt records the following; this triage did not rerun it.
At 53b862123d7b8e4c9d039859fabdc9fc6ad4cd36, the investigator completed one observed startup pass, 50 unchanged repetitions, and combined real own/parent-repository Git controls. The observed startup fixture used the no-repository branch (Git exit 128), with writable scratch and replacement-view assertions passing. The full policy case stopped at nested-namespace setup before in-worker access. None supplies the failed same-request scratch/Git/mount/access tuple or full-ordering attribution. Distinguish no-repository qualification from repository check-ignore, and setup refusal from false in-worker access. The current startup assertion is at expect(hold.sandbox.areas.find, packages/ui-server/tests/native-worker-startup-order.test.ts:23. Current labels rank the remainder p2 with milestone 0.45.0; needs: repro remains.
Historical failures and controls retain their original identities. Keep needs: repro and no agent-ready; no new causal repair, full-suite qualification or provider/device result is claimed.
Activity
[-]ui-server: strict startup-order test fails only in the package suite[/-][+]tests: full suites intermittently lose writable scratch[/+]schlessera commentedon Oct 26, 2026
Additional completed controls while proving #3001, with Bun 1.4.2 and frozen dependencies:
b9b7d099ba362838f22407902c9d3a4b9fc70cc6, based onc47483196f02c1098128207ce68c4f0de6b571ab:bun run test ./testsfailed 1963 pass / 3 fail, 74210 assertions, 848.55 seconds. The failures are the Claude interactive, Claude voice and pi interactive cases attests/policy-write-boundary.test.ts:80:AREAS_WRITABLE, expected[true, true], received[false, true].These controls establish variability, not its cause or a repair. They do not reproduce a failing full current-main invocation. The missing correlation remains the failed request/worker's scratch resolution, Git-ignore result, mount facts and access result; the full-suite failure shares the symptom recorded here, with the voice and pi interactive observations also tracked by #2923 and #2987.
schlessera commentedon Oct 26, 2026
Additional evidence from #3003 (2026-10-26):
942897313c06a31499c2509cbc3357598aaa436d, merged basec47483196f02c1098128207ce68c4f0de6b571ab: 1965 pass / 1 fail, 74319 assertions. The Claude interactive policy-boundary case failsAREAS_WRITABLE, expected[true, true], received[false, true](executorsHeld,tests/policy-write-boundary.test.ts:71-83). The schedules changes do not edit that test, scratch qualification or the worker sandbox.07fbce896099b87903bb994e3b6a939f232669fdand on schedules head7405e78084f4138eee9362df96f94dc92a3efbe0: 19 pass / 0 fail, 587 assertions each.This matches the recorded scratch-writability symptom. The isolated controls do not reproduce a failing full current-main invocation or identify a cause or repair.
schlessera commentedon Nov 4, 2026
Reproduction triage — 2026-11-04: inconclusive; retain
needs: repro.Inspected and executed unchanged HEAD
53b862123d7b8e4c9d039859fabdc9fc6ad4cd36, matchingorigin/mainat the initial fetch. Linux x86_64, kernel7.0.0-42-generic, UID/GID 1001/1001, Bun1.4.4 (38afee6c8), Git2.53.0, bubblewrap0.11.1, Python3.14.4, Node26.13.0, libseccomp; temporary fixture filesystem: tmpfs. Dependencies were initially absent;bun install --offline --frozen-lockfile --backend=copyfile --ignore-scriptsunder umask 022 installed 922 packages from the existing cache. Lock SHA-256 remainedecf6986227406c1fd9d835ae3c119d561e012df5a1bedcae599907332fc20a3e. Runtime commands used an empty environment plus explicit PATH, temporary HOME/XDG directories, UTC and C.UTF-8; no provider credentials, model calls or deployments.Read the entire issue and both comments through all comment pages, the no-parent response, the relevant historical reports (#2994/#3000/#3001/#3003, #2923/#2987/#3007/#3019, #3030) and the binding writable-area, worker-isolation, startup-view/native-storage and testing guidance. The parent endpoint confirms HTTP 404 “No parent issue found”; #736 is a related epic, not this issue's parent. Later #3314 adds the test's managed-view stand-in; it does not remove scratch validation. Current navigation: the original scratch-writable assertion is now at
expect(hold.sandbox.areas.find,packages/ui-server/tests/native-worker-startup-order.test.ts:23;scratchIgnoredByGitremains atpackages/ui-sdk/src/server/worker-sandbox.ts:409-423. The native access assertion remainsAREAS_WRITABLE,tests/policy-write-boundary.test.ts:80.Completed bounded runtime controls, with original assertions and preload guards intact:
--rerun-each=50in one Bun test processAREAS_WRITABLEThe passing observed startup invocation produced this tuple for both sandbox resolutions: scratch is a canonical real directory, mode 0700, no mount points at/below it, host
accessSync(W_OK)succeeds, and the resulting scratch plan haswritable: true. The first captured startup view lacks scratch; the refreshed view contains it. The test's original checkpoint, replacement-view cleanup and gate-release assertions all pass.The actual credential-free maintenance queries are
git rev-parse --git-dir, exit 128 both times; the fixture has no.git. A separate same-shape query throughrunMaintenanceWorkerSyncreturned exit 128 withfatal: not a git repository (or any of the parent directories): .git; direct fixture Git also returned 128. This exercises the expected no-repository branch, notcheck-ignorefor a repository. The two companion existing SDK controls independently pass the ignored/unignored assertions for brains with their own and a parent repository. Host W_OK here is not an in-agent access measurement.Harness limits and excluded attempts:
scripts/test-offline.sh -- bun run test ./packages/ui-server/tests/native-worker-startup-order.test.tsrefuses before test discovery:unshare: write failed /proc/self/uid_map: Operation not permitted.expect(exit, err || out).toBe(0),tests/policy-write-boundary.test.ts:30: expected 0, received 1, withbwrap: No permissions to create a new namespace. A separate nestedbwrap ... bwrap ... /bin/truecontrol produces the same setup refusal. This is a host prerequisite failure, not the reported scratch-false failure.Reusable diagnostic/control recipe (from the inspected checkout; all added files stay outside authored source). The executable lookup below assumes mise supplies Bun/Node; use their real executable paths instead on another host. The observation wrappers only delegate to the original functions and restore themselves; they do not inject a refusal or alter assertions.
Retained corrected-control log SHA-256 values: startup observation
3eec0346e05c62dba0c5c9718f7d14550287b8abbd3d6dd1ac2741a6843ddc3d; 50-repeat controlcb93005a9167dfca0daf60349e9833e3e64d6bea441b8bd164ab39c03650bd81; Git controlsdd82082e4c4e615ec745f2a7fb624c61c3b942e95bae29723275118362554df4; native setup refusala990e8f5ee4f94dbacecf9599766f8256ad0705ed8e14a0f3b346b4e62944624. These identify local receipts, not a passing full-suite proof.Next step: on a host that qualifies the required nested native boundary, retain the first naturally failing package/root ordering with pass-through capture of the same request's resolved scratch reason, Git command/exit/stderr, topology/mount facts and in-worker W_OK result. Distinguish startup's no-repository query from repository
check-ignore, and distinguish an admission refusal from false in-worker access. Do not force a bad ledger, stub Git to fail, or treat a namespace refusal as the original reproduction. The historical linkage to other scratch symptoms remains unproven.No source fix, mutation, commit, PR, push, closure or assignment change. Checkout remains clean at the tested SHA. During triage the tracking ref advanced to
1398da138c7a9d6a58b01e935da151c981c92bf7; only the worker-var-sockets fixture/test differ from the tested snapshot, and these controls are not relabeled as a run on that newer SHA.Read-back labels are
type: test,area: ui-server,priority: p2,needs: repro; no label changes. Milestone0.45.0, open state and empty assignments are preserved. Keepagent-readyabsent: same-failure scratch/Git/access/mount attribution is still missing.