daemon: fold CORE's confirms into the engine-API review

CORE resolved all four (lane/core@3da4cd6): vdm::TaskId is hashable and
DAEMON never constructs one; DAEMON mkdir -p's save_path's parent
(engine -> Error::path_rejected if missing); sha512 added as the 4th
Checksum::Algo so no -32602 at the RPC edge; on_state(cancelled) then
on_finished(Err{Error::canceled}) -- note the one-L spelling in the
error taxonomy. Also notes rate/token_bucket + Engine::rate_limiter()
for the limiter.set wiring.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Upd9WhG9oppieig5nRDLig
This commit is contained in:
2026-09-10 15:51:16 +04:00
co-authored by Claude Sonnet 5
parent 207acb0c00
commit ea8fd7ca8f
+21 -17
View File
@@ -62,24 +62,28 @@ and it is already `DownloadSpec.mirrors` + the segmenter's 3-failure requeue, no
segments to the new URL from their current offsets; if they don't match, surface it segments to the new URL from their current offsets; if they don't match, surface it
(`on_decision_needed` or a `refresh_url` error) rather than silently restarting. (`on_decision_needed` or a `refresh_url` error) rather than silently restarting.
## To confirm — none block sign-off ## Confirmed by CORE (`lane/core@3da4cd6`)
1. **`vdm::TaskId` ↔ wire UUID.** `sched/` keeps a `vdm::TaskId → wire taskId` map, keyed 1. **`vdm::TaskId`** — cheap-copy and `std::hash`-able; DAEMON never constructs one, only
off `handle.id()` at `start()`. Confirm `vdm::TaskId` is cheap to copy and hashable receives it from `start()` / callbacks and passes it back to `set_task_order()`.
(`std::unordered_map` key), and that DAEMON is never expected to *construct* one — it `sched/` keeps the `vdm::TaskId → wire taskId` map keyed off `handle.id()`.
only ever receives them from `start()` / callbacks and passes them back to 2. **Parent directory** — DAEMON `mkdir -p`s `save_path`'s parent before `start()`; the
`set_task_order()`. engine opens the file and fails the task with `Error::path_rejected` if it is missing.
2. **Parent directory creation.** The engine "never canonicalises or root-checks" Now explicit on `DownloadSpec`'s doc comment.
`save_path` — does it `mkdir -p` the parent (the category folder may not exist yet), or 3. **`sha512`** — added as the fourth `Checksum::Algo`, matching the wire set. No `-32602`
must DAEMON ensure the directory exists before `start()`? DAEMON assumes the latter at the RPC edge; DAEMON passes it straight through.
(it owns category/path logic) unless you say otherwise. 4. **Cancel ordering**`on_state(_, cancelled, nullopt)` then `on_finished`, always in
3. **`Checksum::Algo` has no `sha512`**, but `Checksum.schema.json` accepts it (PROTO F3). that order. Note the taxonomy value is spelled `canceled` (one L): the finish is
DAEMON will reject `algorithm: "sha512"` at the RPC edge with `-32602` before `start()` `on_finished(Err{Error::canceled})`, `error.code == canceled`. `sched/` keys on that
unless CORE would rather carry a fourth enum value. Either is fine; say which. to write a `cancelled` history row rather than a user-facing failure. (The wire
4. **`on_finished(Err{cancelled})`** — DAEMON keys on `ErrorInfo.code == cancelled` to `TaskState` / `EngineState` spelling stays `cancelled`; only `vdm::Error` is one-L.)
write a `cancelled` history row rather than surfacing it as a user-facing failure.
Confirm `cancelled` is the code and that `on_state(_, cancelled, nullopt)` always ## Related, landed the same pass
precedes it (the §4 table implies this).
`rate/token_bucket` — the global → queue → task speed-limiter hierarchy (`docs/04` §6),
reached via `Engine::rate_limiter()`. DAEMON's `limiter.set {globalBps, enabled}` maps to
`rate_limiter().set_global_limit(...)`; `limiter.get` reads it back. Wire this alongside
the `download.add``start()` glue.
## Integration timing ## Integration timing