fix(daemon): refuse leased requests that name no session at admission

AI
11h ago
+809-69

Summary

The CLI requires a named session on a leased remote connection, but a direct RPC, socket, or Node client caller could omit it and land on the shared default session. Against a real daemon, an unnamed leases.allocate allocated a proxy lease.

One intake helper now decides this for the socket and every HTTP builder. A request names no session when its session is missing or blank, or when meta.sessionExplicit is false with no flags.session. Admission refuses it with REMOTE_SESSION_REQUIRED when it would allocate or act through a provider lease. Lease RPC params now carry sessionExplicit, so namesSessionExplicitly moved to kernel/record to keep lease-scope's eager closure flat.

Breaking for callers: unnamed Node and MCP clients on a provider lease, and unnamed doctor and capabilities on a leased session, are refused. Six docs pages showed such clients and now name a session.

Closes #4171.

Validation

Tested fac7ed586. pnpm check:affected --run --head fac7ed586: all selected checks passed (11 passed, 7 skipped). A real-client test covers the reproduction. Not device-facing. Earlier 8c6183747 gate failures were outside this diff, cause unproven. Apple Smoke: capture-close hit the swiftc 30s timeout, also on main 7b3f63fea.

Unresolved:

  • Needs maintainer sign-off on refusing meta.sessionExplicit: false.
  • Released HTTP clients send no sessionExplicit on the lease RPC, so their unnamed lease calls still pass.
  • The ledger uses a compatible-change ack, not a protocol bump.
  • Latest review read the code at 071a06ed2 and ran nothing.

🤖 Generated with Claude Code