Repository navigation
Description
Preflight
- I searched existing issues and discussions for this behavior.
- This report is not an unpatched security vulnerability.
- The report and attachments contain no credentials or private/internal material.
Issue origin
Observed or reproduced in a real environment.
LoopX version or commit
main @ faab5f5c291c — also reproduces at 225698b313
Host or runtime surface
Other: Windows 10.0.26300 x64; Python 3.14.8, Node v26.8.1, LongPathsEnabled=1
LoopX area
Control plane (goals, todos, quota, scheduler, registry, runtime)
Problem
test_portfolio_real_tool_scenarios_choose_from_latest_quota_result fails deterministically on this Windows host (10 runs across the two commits, no pass; run logs retained) and passes on another host at 225698b313 (#7433). Two layers, separated by a control run:
Layer 1 — the reported failure, causally isolated. With the default pytest tmp root, the failing oracle fixture's SQLite authority path is 267 chars — with its -wal sidecar past the 260-char MAX_PATH — and node:sqlite fails to open database files at such path lengths here even with LongPathsEnabled=1 (probe: 250-char path opens, 258–267 all fail with unable to open database file; Node v26.8.1, script in diagnostics; same class as #7888 — the same failure mode is reported for node's DatabaseSync in openclaw#113304 and for bun:sqlite in bun#33336). SqliteAuthorityStore.open(true) fails before the file exists (the oracle runtime has no sqlite file afterwards), and readFailure (sqlite_authority_store.ts:152) collapses the real error into the generic "lock contention" message. Control: re-running with a short --basetemp (path ~200 chars) lets the store create successfully and this payload disappears — confirming path length as the cause of this layer.
Layer 2 — a further host-dependent failure behind it. With the short tmp root, the import succeeds but the test still fails at the portfolio assertion (qualification_passed=False; scenarios report actor_result_invalid, portfolio_aborted_after_actor_error on several turn_* scenarios). So at least one more Windows/environment-dependent problem exists in the real-tool actor path; we have not isolated it yet.
(Update 2026-11-08: layer 2 is now isolated — see the follow-up comment below; it reads as a by-design platform prerequisite: the real-tool arm requires sandbox-exec/bubblewrap, which Windows hosts don't have. Layer 1 stands unchanged.)
Asks: surface the underlying SQLite error in the status; make authority paths work under deep runtime roots on Windows (#7888 class); any pointer on what actor_result_invalid usually indicates in this portfolio would help us dig into layer 2. Filed as the separate report promised on #7403.
Minimal reproduction
python -m pytest -q "tests/control_plane/test_actual_default_model_behavior_portfolio.py::test_portfolio_real_tool_scenarios_choose_from_latest_quota_result"
Node-side minimal repro of the open failure: in diagnostics below.
Expected behavior
The test passes as on the other host; at minimum, a store failure surfaces the actual SQLite error.
Actual behavior
import_fixture_authority raises with the payload below (default tmp root); the failing oracle runtime has no sqlite file afterwards. With a short tmp root the store gets created and the failure moves to the portfolio assertion (layer 2).
Sanitized diagnostics
Exact cold_import payload (verbatim from a failing run):
{"ok":false,"schema_version":"loopx_coordination_shadow_admin_v0","action":"prepare-import","goal_id":"portfolio-goal","executed":false,"cold_import":{"schema_version":"loopx_cold_source_import_result_v0","ok":false,"status":"failed","executed":false,"authority_changed":false,"execution_authority_granted":false,"reason_code":"cold_import_unavailable","reason":"{\"status\":\"unavailable\",\"reason_code\":\"provider_read_unavailable\",\"reason\":\"SQLite authority store could not be read; check database availability and lock contention\"}","legacy_writer_fenced":null,"legacy_fallback_used":false},"decision_read_from_shadow":false}Node-side minimal repro (this host, LongPathsEnabled=1):
import { DatabaseSync } from "node:sqlite";
// build a dir so join(dir, "authority-x.sqlite") has the target length, then:
const db = new DatabaseSync(file); // write-mode open
db.exec("PRAGMA journal_mode=WAL");Results: LEN=250 OPEN_OK; LEN=258/259/260/261/262/267 OPEN_FAIL ERR_SQLITE_ERROR: unable to open database file. Directory creation (mkdirSync recursive) succeeds at those lengths — only the SQLite open fails.
Control run (layer separation): python -m pytest -q <same test> --basetemp=C:/lp/bt — the oracle store is created (authority-*.sqlite + -wal/-shm present), the provider_read_unavailable payload is gone, and the run fails instead at the final assertion: ('turn_required_vision_replan', ['actor_result_invalid'], []), ('turn_scoped_gate_successor_replan', ['portfolio_aborted_after_actor_error'], None) (expanded from a truncated log line), ('turn_quota_hot_path_human_gate_invariance', ['portfolio_aborted_after_actor_error'], None) (log retained).
Elimination notes: PRAGMA busy_timeout = 5000 is set in SqliteAuthorityStore.open; a concurrent holder with an idle connection or open BEGIN IMMEDIATE does not block readers (WAL); the product never sets locking_mode=EXCLUSIVE. npm dev dependencies are not installed here; the runtime path runs TS directly via node --experimental-strip-types, so they appear unrelated (flagged as a difference). The 9 failing runs include a second git worktree at the same commit.
Activity
AronSwan commentedon Nov 7, 2026
Follow-up (TL;DR): layer 2 is isolated — it closes the open question from the report, and reads as a by-design platform prerequisite rather than a bug on this path.
Directly invoking the failing actor outside pytest (
_real_tool_actors(...)["replan_semantic_action_actor"](run_id)) surfaces the raw error that the portfolio collapses intoactor_result_invalid:loopx/control_plane/testing/vision_shell_host.py:36-45—shell_isolation_available()checks darwin +sandbox-execorbwrap; there is no Windows branch, and this host has neither tool.Control runs (short
--basetemp, so layer 1 is bypassed; all three arms fail with the same failure set — untruncated via separate--assert=plainruns: 1actor_result_invalid+ 7portfolio_aborted_after_actor_errorof 22 scenarios, first 14 passing, no other codes — ruling out dev deps and console encoding):npm ci --ignore-scripts→ fail (same set)PYTHONUTF8=1→ fail (same set)Two observations for maintainers:
skipif(the only "skip" in the file is an assertion onskip_count), so on Windows the fail-closedRuntimeErrorsurfaces asactor_result_invalidthree levels down — a reader cannot tell "unsupported platform" from "actor misbehaved". Would a suite-level skip/unsupported marker (or carrying theRuntimeErrormessage into the failure receipt) be considered?node:sqlitefailing to open authority stores on long paths — 258+ chars in our probe) stands independently, and it is the one currently hidden behind the generic SQLite message.Probe transcript and arm logs retained; happy to attach anything useful.