SIGN IN SIGN UP

fix(task): scope parent kernel tools to the child's effective tool set

A child whose own policy takes a write-capable tool away could still receive
a parent kernel tool, and the closure's nested host calls then ran with the
PARENT's permissions. The guard tested `toolAllowlist.length > 0`, so an EMPTY
allowlist - the most restrictive shape, and what `tools: { write: false }`
resolves to - slipped through, and omo's planner never forwarded the denylist
at all.

The rule is now computed from the child's RESOLVED EFFECTIVE tool set (shared
parent tools plus the engine's write-capable builtins, minus UI-only names,
minus the task/team family, minus the denylist, intersected with the allowlist
whenever one is DEFINED) and refuses the grant with a typed `tools_unavailable`
whenever a write-capable tool the closure can reach is missing from it. The
decision moved to the tool layer, so a refusal leaves no task record, no child
session and no closure invocation; the runner floor keeps the same rule as
defense in depth and its failures now carry a typed code to the caller.

Also: bind a child's runtime grant only after its session exists and release it
on any start failure; release a pool's binding on cancel, close-completion and
engine disposal; forward `toolDenylist` from omo's planner; refuse a team-member
spec that carries a grant before a record exists; and report `kernel_tools` as
granted/refused/not_delivered instead of claiming a grant for a spawn that
never started.
Y
YeonGyu-Kim committed
a7d978c58daebfcb82aab426b2ca12bf7379eb0d
Parent: b32e537