Commit Graph
3 Commits
Author SHA1 Message Date
samiandClaude Sonnet 5 e60d6669d8 daemon: rpc/ — Unix-socket transport + generated dispatch wiring (build step 1)
First real code in daemon/. veloxd now listens on
$XDG_RUNTIME_DIR/velox/velox.sock (0600, SO_PEERCRED same-UID check),
frames NDJSON, and routes every method through the generated
velox::proto::dispatch(). The CLI and GUI have a server to talk to.

Modules:
- rpc/ndjson.hpp    — newline-delimited framing, 8 MiB frame cap, CRLF-
                       tolerant, partial-tail buffering. Header-only, tested.
- rpc/event_loop    — single-threaded poll(2) reactor; never blocks the
                       loop. stop()/wake() are async-signal-safe (eventfd).
- rpc/runtime_dir   — $XDG_RUNTIME_DIR/velox resolution, 0700, owner-checked;
                       refuses an insecure fallback rather than using /tmp.
- rpc/uds_server    — listener + non-blocking per-conn read/write with
                       backpressure; handles session.hello (protocol-major
                       check -> -32001, sessionId, transport=uds) and
                       session.subscribe in the server layer; routes the
                       rest through dispatch().
- rpc/dispatcher    — VeloxDispatcher : proto::Dispatcher, all 39 methods.
                       download.list answers an empty table; the rest return
                       "not implemented" (-> -32603) until the store lands.
- main.cpp          — abstract-namespace single-instance lock, signal ->
                       clean shutdown, socket unlinked on exit.

Tests (ASan+UBSan and TSan clean):
- veloxd.ndjson         — framing edge cases
- veloxd.uds_roundtrip  — real socket: hello ok / version mismatch / empty
                          list / -32601 / -32700 / pipelined requests, and a
                          guard on the -32603 collapse documented in P1.

Known gap, filed not worked around: daemon/docs/proto-requests-m1.md P1 —
the generated Dispatcher has no error channel below -32603, so handlers
cannot yet return -32010/-32011/-32013 with their data payloads. The
server layer handles -32001/-32002/-32003 around dispatch(); genuine
in-handler errors collapse to -32603 until PROTO gives handlers a real
error return. Three error fixtures are non-conformant until then.

Not in this drop: rpc/ws_server (next; needs the store for hashed pairing
tokens), store/, sched/, cli/. WS reuses this event loop.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Upd9WhG9oppieig5nRDLig
2026-09-10 15:27:20 +04:00
samiandClaude Sonnet 5 67b7b75336 daemon: accept ADR 0011 with CORE's sign-off; land the engine API
CORE reviewed and accepted (core/docs/adr-0011-core-response.md,
lane/core@7bf5cb5), with three amendments folded in:

- yield (slot transfer at the next segment boundary) as the mechanism
  that satisfies min-1-before-seconds out of a full budget; steal
  stays slot-neutral as originally written.
- "admission implies progress" is bounded-delay
  (min(next yield boundary, low_speed_secs) + connect_timeout), not
  immediate — widens the starvation-assertion window from 2s to
  ~low_speed_secs + connect_timeout (45s).
- starved_tasks()/starved_since(TaskId) added to the accessor set;
  segments_active() and tasks_starved definitions pinned (a
  'connecting' segment counts as held, not starved).

All five open questions answered (min-1 buildable without inversion,
probe pool size 4 outside the budget, drain-not-kill live-apply,
ordered TaskId list for priority, 4Hz + starved-edge callback
coalescing). Section 6 rewritten: connection.maxActiveSegments landed
on the wire in PROTO's ADR 0012 while this was in flight, so the
daemon-local stopgap is dropped.

daemon/src/sched/ is unblocked. Both docs updated in the rebased
vdm-daemon worktree against the frozen 1.0.0 contract.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Upd9WhG9oppieig5nRDLig
2026-09-09 23:24:39 +04:00
samiandClaude Sonnet 5 ecedfac903 daemon: propose ADR 0011 — admission control vs. the segment budget
Settles the open interface question in AGENT-DAEMON.md before sched/ is
written: DAEMON's concurrency governor (global/per-queue/per-host, task
units) and CORE's maxActiveSegments (segment units) are two governors on
two axes with non-overlapping enforcement — each lane enforces exactly
the ceilings counted in the units it owns, with one narrow task-unit
clamp against maxActiveSegments. Records the fairness rule DAEMON needs
from CORE (min-1-before-seconds) so admission implies progress even
when one download could otherwise hold the entire segment budget.

Companion daemon/docs/core-requests-m1.md is the concrete engine API
ask (budget()/segments_active()/on_budget_changed, live-apply semantics
for set_max_active_segments, set_host_segment_cap, probe pool sizing)
plus one contract gap for PROTO (connection.maxActiveSegments missing
from Settings.schema.json).

Status: proposed, pending CORE sign-off on the five open items at the
end of the ADR. daemon/src/sched/ does not land until that lands.

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