Issue #249: in practice the per-bottle `supervise` flag was never
turned off — all bottles should be supervised. Remove the manifest
flag and make the supervise sidecar unconditional, mirroring egress.
- Reject `supervise:` as a removed bottle key with a migration hint.
- Drop the `supervise` field from ManifestBottle and the extends merge.
- prepare_supervise always returns a SupervisePlan; the plan type is
now non-optional and the per-backend `is None` guards are gone, so
the supervise daemon, current-config mount, aliases, and MCP
registration always render.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YcU7nerbg8cVj9R4EkpfLJ
- test_docker_launch_committed_image: replace Manifest.from_json_obj
(nonexistent) with ManifestIndex.from_json_obj; pass manifest= arg
to DockerBottlePlan constructor (required by BottlePlan base class)
- test_macos_container_launch: cast SimpleNamespace stubs to their
expected types (BottleSpec, GitGatePlan, EgressPlan) in _build_plan;
add str type annotations to fake_build parameter signatures
- test_macos_container_util: add str type annotations to fake_build_image
parameter signatures
BottleSpec.manifest was ManifestIndex | Manifest — a union encoding
two lifecycle stages in one field. The union was unjustifiable:
it forced a type-narrowing workaround (loaded_manifest property)
on every consumer.
Clean split:
- BottleSpec.manifest: ManifestIndex (always; CLI-supplied intent)
- BottlePlan.manifest: Manifest (always; loaded by _validate())
_validate() returns the loaded Manifest directly. prepare() passes
it to _resolve_plan(), which stores it on the plan. All provisioner
code now reads plan.manifest.agent / plan.manifest.bottle — no
union, no asserts, no type: ignore.