Skip to content

docs(daemon): document task ownership at fire-and-forget spawn sites#305

Merged
githubrobbi merged 1 commit into
mainfrom
docs/phase-10c-task-ownership
May 20, 2026
Merged

docs(daemon): document task ownership at fire-and-forget spawn sites#305
githubrobbi merged 1 commit into
mainfrom
docs/phase-10c-task-ownership

Conversation

@githubrobbi
Copy link
Copy Markdown
Collaborator

What

Phase 10c task-ownership inventory closure. Hand-audit of all 18 prod tokio::spawn( sites found 16 already textbook-clean (named spawn_* constructor with rustdoc, OR inline comments answering all four required facets: owner / shutdown / error obs. / cancel behavior). This PR fills in the remaining 2 gaps with minimal # Task ownership rustdoc additions.

Why

Phase 10 acceptance criterion #2 (playbook §1142) requires that every tokio::spawn( call-site has, at the call-site or enclosing named-spawner function, a comment / rustdoc block answering "who owns / how it's shut down / how errors are observed / what happens on cancellation."

Per-site inventory (all 18 prod sites with full verdicts) lives in docs/dev/baseline/2026-05-19/phase_10_task_ownership_inventory.md (local-only; docs/dev/baseline/ is gitignored).

Sites augmented in this PR

crates/uffs-daemon/src/handler.rs:510 (handle_refresh)

Previously a one-line rustdoc: "spawns refresh in background, returns immediate ack."

That didn't explain:

  • The spawned task is intentionally detached \u2014 the JoinHandle is discarded; the closure captures Arc<IndexManager> to keep the manager alive.
  • The task runs to completion regardless of daemon shutdown \u2014 it has no cooperative cancellation; the watchdog process::exit is the only termination mechanism.
  • The immediate ack asserts scheduling, not refresh success \u2014 clients must poll status for completion.

Added a full # Task ownership block enumerating those.

crates/uffs-daemon/src/lib.rs:697 (Windows named-pipe IPC spawn)

Inline spawn inside spawn_ipc_servers whose asymmetric ownership wasn't called out next to the call-site:

  • The sibling AF_UNIX task IS returned + held + .abort()-ed during graceful shutdown.
  • The named-pipe task is fire-and-forget \u2014 _pipe_task binding drops at end-of-scope; the task itself outlives via Tokio's auto-detach.

Added a // Task ownership (Phase 10c): block explaining the deliberate asymmetry.

Rule-1 adherence

  • Zero behavior change. Documentation-only PR.
  • Zero #[allow(...)] introductions.
  • No suppression hacks, no disabled lints, no skipped tests.
  • Surgical \u2014 minimum text needed to enumerate the four required facets at each site (owner, shutdown, error obs., cancel behavior).

Verification

Local:

  • cargo check -p uffs-daemon \u2014 clean.
  • cargo clippy -p uffs-daemon --all-targets -- -D warnings \u2014 0 warnings.
  • cargo test -p uffs-daemon --lib \u2014 298 passed / 0 failed.
  • scripts/hooks/_lint_fast.sh (pre-commit) \u2014 all 7 stages passed.
  • scripts/hooks/_lint_pre_push.sh \u2014 all 17 stages passed in 83s.

Acceptance against playbook §1142-1146 (Phase 10 §2)

§1142 #2 \u2014 Task lifecycle is explicit.

\u2705 CLOSED for Phase 10c. All 18 prod tokio::spawn( sites now have, at the call-site or enclosing named-spawner function, a comment / rustdoc block answering the four required facets. Inventory will be folded into concurrency_policy.md §'Spawn-site registry' in Phase 10g.

Tracking

Refs #302 (Phase 10 umbrella). Follow-on PRs:

  • 10d (backpressure) \u2014 audit of 4 unbounded channels.
  • 10e (timeouts) \u2014 per-boundary timeout coverage.
  • 10f (blocking-IO-in-async) \u2014 std::fs::* inside async fn outside spawn_blocking.
  • 10g (policy doc) \u2014 concurrency_policy.md + per-crate # Concurrency rustdoc.
  • 10h \u2014 CONTRIBUTING cross-link + final report (folded into 10g).

Phase 10c hand-audit of all 18 prod `tokio::spawn(` sites (27 raw
audit-script matches \u2212 9 in-file test-mod matches) found that 16
of 18 already have explicit task-ownership semantics via either a
named `spawn_*` constructor with rustdoc or inline comments
answering all four required facets (owner, shutdown, error obs.,
cancel behavior).

Two sites lacked an explicit `# Task ownership` block:

  * `crates/uffs-daemon/src/handler.rs:510` (`handle_refresh`) \u2014
    fire-and-forget RPC handler whose previous one-line rustdoc
    didn't explain that the spawned task is intentionally
    detached, runs to completion regardless of daemon shutdown,
    and has no upward error propagation (the immediate ack only
    asserts scheduling, not refresh success).
  * `crates/uffs-daemon/src/lib.rs:697` (Windows named-pipe IPC
    spawn) \u2014 inline spawn inside `spawn_ipc_servers` whose
    asymmetric ownership (AF_UNIX held + `.abort()`-ed; named-pipe
    fire-and-forget) wasn't called out next to the call-site.

Both additions are documentation-only \u2014 zero behavior change,
zero source-line changes beyond rustdoc + inline comment blocks.

Full per-site inventory in
`docs/dev/baseline/2026-05-19/phase_10_task_ownership_inventory.md`
(local; gitignored).

## Rule-1 adherence

  * Zero `#[allow(...)]` introductions.
  * No suppression hacks, no skipped tests.
  * Surgical \u2014 minimum text needed to enumerate the four required
    facets at each site.
  * `cargo check -p uffs-daemon` clean.
  * `cargo clippy -p uffs-daemon --all-targets -- -D warnings` clean.
  * `cargo test -p uffs-daemon --lib` \u2014 298 passed / 0 failed.

Refs #302.
@githubrobbi githubrobbi merged commit 64c1d88 into main May 20, 2026
21 checks passed
@githubrobbi githubrobbi deleted the docs/phase-10c-task-ownership branch May 20, 2026 02:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant