Commit Graph
2 Commits
Author SHA1 Message Date
samiandClaude Sonnet 5 e0edf7a084 daemon: file capture.offer/getRules in deferrals (D7/D8); close settings.get/set (D9)
Rebased lane/daemon onto main first — fast-forward, no conflicts (lane/daemon was
already fully merged; main has since taken lane/gui, lane/pkg-qa, lane/proto).

1. capture.offer and capture.getRules were stubs, buried inside D3's generic stub list
   with no flag for how load-bearing capture.offer is: it's a CLAUDE.md §4
   non-negotiable (750ms deadline, fails open) and AGENT-DAEMON.md build step 6, and
   against the real daemon it 500s to -32603 every time — the extension captures
   nothing, not "falls through to Firefox on a slow path." Split into their own D7/D8
   rows so they stop being invisible.

2. settings.get/settings.set (D9, closed). Four pointer-to-member tables in
   dispatcher.cpp (bool / ranged int / plain string / string array), five enum-typed
   keys handled individually since parse_XXX already validates those — covers all 43
   SettingKeys without ~40 repetitive hand blocks. store::Settings::kDefaults grew from
   14 entries to 43 (the schema itself carries no "default" keyword anywhere, so these
   are hand-chosen — conservative for the ones ADR 0012 doesn't speak to;
   capture.monitoredExtensions defaults to the union of every builtin category's
   extensions rather than an arbitrary list of its own).

   settings.set validates every field before writing any of them: numeric min/max
   (hand-checked — the generated parser only checks JSON type, not schema
   constraints) and saveTo.* paths via fs::resolve_target/canonicalize_root (-32011) —
   allowedRoots entries checked as roots in their own right, defaultDir/tempDir checked
   as paths resolving inside the (possibly just-updated, same call) root list. Reports
   exactly the keys whose effective value actually changed, publishes
   event.settings.changed with that list, and calls the scheduler's reload_config()
   when a connection.* key took effect — live, not on next restart.

   Verified against real veloxd: all 43 keys round-trip with defaults, a keys subset
   filters, an out-of-range value rejects the whole call, a bad saveTo.defaultDir is
   -32011, allowedRoots+defaultDir set together cross-validate against the new roots,
   event.settings.changed fires over a live subscription. New dispatcher_settings_test
   covers the same ground without a socket. Full ctest: 53/53 (excluding a pre-existing,
   unrelated conformance failure — see below).

Also found, not fixed (not this lane): tests/conformance/run.sh's live-veloxd leg fails
"pairing failed: no token issued" reproducibly, isolated, on main before any of this
session's changes — it launches the isolated veloxd without VELOX_PAIR_AUTO=1, so
EnvAutoApprover denies every session.pair and the WS leg's session.hello never gets a
token. tests/conformance/ is PROTO/QA-owned; flagging rather than editing across the
lane boundary.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01GRDjHGgpYmMoPE2UFbe7pP
2026-09-12 13:42:45 +04:00
samiandClaude Sonnet 5 6787784936 daemon: store/ query layer — tasks + settings (prep for the download.add vertical slice)
The read/write surface the dispatcher handlers need, so download.add
persists and download.list / download.get project real rows when the
engine lands.

- store/tasks — TaskRow (1:1 with the schema), insert / get / remove /
  set_state / count, and list(filter, sort, offset, limit) that does
  all the WHERE / ORDER BY / LIMIT in SQL (M1 DoD: a 1000-row list
  never materialised client-side). Filter covers states / category /
  queue / case-insensitive filename+url substring / date range; sort
  is a whitelisted column + direction with NULLs last, default
  newest-first; the enum spellings in a state IN (...) come from
  proto::to_string, never from user text. to_summary() projects a row
  onto proto::TaskSummary including the flattened error block when the
  task failed / retry_wait / auto-paused.
- store/settings — key -> JSON-text with a built-in default table
  mirroring Settings.schema.json / ADR 0012; get_raw / set_raw /
  overrides plus typed get_int / get_string / get_string_array for the
  governor config and saveTo.allowedRoots. Full settings.get/set wire
  projection lands with those handlers.
- veloxd_store now links velox::proto + nlohmann_json for the
  projection.

Test veloxd.store_tasks: insert/get round trip, PK duplicate rejected,
the error-block projection, list total+paging+sort+every filter,
set_state pause_reason clear-on-unpause, remove, and settings default
vs override. ASan+UBSan and TSan clean; 34 daemon/cli tests green.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Upd9WhG9oppieig5nRDLig
2026-09-10 19:43:13 +04:00