Files
vdm/daemon/docs/core-requests-m1.md
T
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

3.6 KiB

DAEMON → CORE — the engine API sched/ needs before it can be written

Status: resolved. CORE answered in full: core/docs/adr-0011-core-response.md (lane/core, commit 7bf5cb5). Kept as a record of what was asked and the shape of the answer; the API itself is now specified in docs/adr/0011-admission-control-and-the-segment-budget.md §"Engine API sched/ is built against". sched/ may be written against it.

Ranking followed contracts/README.md rule 4 conventions even though this wasn't a contracts/ change: new API surface = cheap, land anytime; a behavioural promise (min-1 fairness) = needed CORE's explicit sign-off before DAEMON built on the assumption. That sign-off is in.


C1. Occupancy read-out, not inference — resolved

Requested budget(), segments_active(TaskId), on_budget_changed. CORE's answer adds starved_tasks() and starved_since(TaskId) (amendment A3) and pins two definitions: segments_active(id) counts a segment in connecting state as held (it is progress, not starvation), and tasks_starved counts only segments_active == 0. See ADR 0011 §3.6.

C2. set_max_active_segments(uint32_t) live-apply — resolved: drain, never kill

Confirmed DAEMON's assumption. Lowering runs in-flight segments to their next boundary; no new segment starts while over the new ceiling; nothing is aborted, no partial range lost. If the new ceiling is below the running-task count, CORE honours min-1 for the top-priority subset and reports the rest via tasks_starved — DAEMON's governor must reconcile and pause the lowest-priority excess itself (CORE does not auto-pause). See ADR 0011 §2.

C3. set_host_segment_cap(host, uint32_t)resolved, confirmed as proposed

CORE keeps the host → cap map and derives a task's host from its URL/mirror set; DAEMON owns the table and pushes it. See ADR 0011 §4.

C4. Contract gap: connection.maxActiveSegmentsresolved by PROTO

PROTO landed it (ADR 0012, connection.maxActiveSegments default 32, connection.maxTotalBufferBytes default 128 MiB, TaskDetail.effectiveBufferBytes) while this was in flight. No daemon-local stopgap needed — sched/ reads the wire field directly. See ADR 0011 §6.

C5. Fairness rule sign-off — resolved, with two amendments

CORE confirmed min-1-before-seconds is implementable without a priority-inversion at slot release (two-pass allocator: guarantee pass over zero-slot tasks in DAEMON's priority order, then a growth pass; a released slot always re-enters the pool at pass 1, never handed back locally). Two amendments to what DAEMON assumed:

  • A1 — "steal" (slot-neutral, unchanged) isn't the whole mechanism; "yield" is the slot-transfer operation that actually satisfies min-1 out of a full budget: an over-quota task releases one slot at its next segment boundary, bounded by that segment's remaining bytes.
  • A2 — "admission implies progress" is bounded-delay, not immediate: time_to_first_slot ≤ min(next yield boundary, low_speed_secs) + connect_timeout, not "connect timeout + per-host cap" alone. DAEMON's starvation-invariant assertion window widened from the originally proposed 2 s to low_speed_secs + connect_timeout (~45 s) accordingly.

Priority order (open item 4) is an ordered TaskId list pushed via set_task_order on change — not an integer, not per-tick. See ADR 0011 §3.

C6. Probe pool sized outside the segment budget — resolved, confirmed

Dedicated pool, default size 4, set_probe_pool_size(uint32_t), independent of maxActiveSegments; probe cancellation is immediate. DAEMON still bounds probe submission on its own side. See ADR 0011 §5.