selfware 0.6.7

Your personal AI workshop — software you own, software that lasts
Documentation
{
  "component": "supervision",
  "tier": "tooling",
  "loop_stage": "control",
  "summary": "The supervision component is the oversight layer of the loop. It tracks agent runs as durable RunRecords in a RunRegistry (start/list/abort with liveness detection), drives child tasks through a Supervisor state machine with RestartPolicy and BackoffStrategy, guards flaky downstream calls with a CircuitBreaker, and watches liveness with HealthMonitor checks. It sits at the control stage: it does not do the work, it decides which runs live, restart, back off, or abort, reshaping the loop's top-level state machine and budget.",
  "loop_objects": ["RunRecord", "RunRegistry", "RunId", "RunStatus", "AbortOutcome", "Supervisor", "ChildState", "RestartPolicy", "BackoffStrategy", "CircuitState", "HealthStatus", "OverallHealth"],
  "context_basis": "Recommendations were formed reading src/supervision/ (run_registry, run_supervisor, mod Supervisor, circuit_breaker, health) in the context of the full engine at a ~600k budget framing, where supervision wraps the top-level Planning->Executing->Completed/Failed run.",
  "examples": [
    {
      "id": "supervision-01",
      "title": "Register a run before it starts",
      "loop_stage": "control",
      "pattern": "durable-run-handle",
      "intent": "Give every agent run a persistent, addressable identity in the RunRegistry.",
      "how_it_shapes_the_loop": "Writes a RunRecord with a process-unique id at loop start, so the run is listable and abortable across restarts of the driver.",
      "loop_objects_touched": ["RunRecord", "RunRegistry", "RunStatus"],
      "wiring": {"inputs_from": ["task description", "process pid"], "outputs_to": ["RunRegistry JSONL", "list/abort commands"]},
      "touch_interaction": {"gesture": "tap", "canvas_action": "Tap the supervision node to spawn a new run card seeded with the task and a fresh RunId.", "visual": "A new card slides in with a spinning 'Running' badge and the pid-scoped id in monospace."},
      "mini_scenario": "The user starts a task; RunRegistry.write persists a RunRecord with status Running before the executor takes its first step.",
      "pitfall": "Persist the record before executing; a crash before the write leaves an untracked, unabortable run."
    },
    {
      "id": "supervision-02",
      "title": "List runs with liveness truth",
      "loop_stage": "perceive",
      "pattern": "liveness-aware-listing",
      "intent": "Show accurate run status even when a process died without updating its record.",
      "how_it_shapes_the_loop": "RunRecord.effective_status reports Stale for a Running record whose pid is gone, so the control view perceives reality, not the last write.",
      "loop_objects_touched": ["RunRecord", "RunRegistry", "RunStatus"],
      "wiring": {"inputs_from": ["RunRegistry.list", "pid_alive probe"], "outputs_to": ["run list UI", "reclaim decision"]},
      "touch_interaction": {"gesture": "flick", "canvas_action": "Flick down on the supervision node to refresh the run list; each card re-probes liveness.", "visual": "Live runs pulse green, terminal runs are gray, Stale runs flash a yellow ghost badge."},
      "mini_scenario": "A run's process was killed; list() calls effective_status, which sees the pid is dead and reports Stale instead of Running.",
      "pitfall": "Trust effective_status over the raw field; a stored Running status can outlive its process on any platform."
    },
    {
      "id": "supervision-03",
      "title": "Abort a run cleanly",
      "loop_stage": "control",
      "pattern": "explicit-abort-outcome",
      "intent": "Stop a running agent and record a definite AbortOutcome.",
      "how_it_shapes_the_loop": "RunRegistry.abort signals the run and transitions its RunStatus to Aborted, forcing the loop's state machine to a terminal state.",
      "loop_objects_touched": ["RunRegistry", "AbortOutcome", "RunStatus"],
      "wiring": {"inputs_from": ["abort command + RunId"], "outputs_to": ["RunRecord status update", "process signal"]},
      "touch_interaction": {"gesture": "long-press", "canvas_action": "Long-press a run card to reveal an Abort action; confirm to signal the owning process.", "visual": "The card shakes then settles into a red 'Aborted' state with a stop-hand glyph."},
      "mini_scenario": "The user long-presses a stuck run; abort() returns an AbortOutcome describing whether the pid was signaled or already gone.",
      "pitfall": "Handle the not-alive AbortOutcome; aborting a dead pid must update the record, not error out."
    },
    {
      "id": "supervision-04",
      "title": "Reclaim stale run records",
      "loop_stage": "learn",
      "pattern": "garbage-collect-orphans",
      "intent": "Clean up records left Running by crashed processes.",
      "how_it_shapes_the_loop": "A stale record detected via effective_status is updated to a terminal status, keeping the registry an accurate ledger over many loop runs.",
      "loop_objects_touched": ["RunRecord", "RunRegistry", "RunStatus"],
      "wiring": {"inputs_from": ["Stale RunRecords", "pid_alive"], "outputs_to": ["RunRegistry update_status", "cleaned list"]},
      "touch_interaction": {"gesture": "flick", "canvas_action": "Flick a stale ghost card off the canvas to reclaim and remove it.", "visual": "The ghost card dissolves; a small 'reclaimed' toast confirms the registry update."},
      "mini_scenario": "During list, a Stale record is found and update_status marks it Failed so it no longer masquerades as active.",
      "pitfall": "Only reclaim records whose pid is genuinely gone; racing a slow-starting process can kill a live run."
    },
    {
      "id": "supervision-05",
      "title": "Restart a failed child on policy",
      "loop_stage": "control",
      "pattern": "policy-driven-restart",
      "intent": "Automatically restart a supervised child that exits abnormally.",
      "how_it_shapes_the_loop": "The Supervisor applies RestartPolicy to a child ExitReason, re-entering the child into the Running ChildState instead of failing the whole loop.",
      "loop_objects_touched": ["Supervisor", "ChildState", "RestartPolicy"],
      "wiring": {"inputs_from": ["ChildEvent exit", "RestartPolicy"], "outputs_to": ["child re-spawn", "ParentNotification"]},
      "touch_interaction": {"gesture": "double-tap", "canvas_action": "Double-tap the supervisor node to expand its child tree and per-child restart counters.", "visual": "A restarting child pulses amber then green; its restart tally increments in a corner badge."},
      "mini_scenario": "A worker child panics; the Supervisor's RestartPolicy permits a restart, so it respawns and the parent loop continues.",
      "pitfall": "Bound restarts within a window; unbounded restart-on-crash turns a bad child into a busy-loop."
    },
    {
      "id": "supervision-06",
      "title": "Back off between restart attempts",
      "loop_stage": "control",
      "pattern": "exponential-backoff",
      "intent": "Space out repeated restart attempts to avoid hammering a broken dependency.",
      "how_it_shapes_the_loop": "BackoffStrategy.duration(attempt) inserts an increasing delay into the control loop before each re-spawn.",
      "loop_objects_touched": ["BackoffStrategy", "RestartPolicy", "ChildState"],
      "wiring": {"inputs_from": ["restart attempt count"], "outputs_to": ["delayed re-spawn"]},
      "touch_interaction": {"gesture": "pinch", "canvas_action": "Pinch the restart edge to inspect and tune the backoff curve on a mini timeline.", "visual": "The re-spawn edge stretches longer with each attempt; a countdown ring shows the current delay."},
      "mini_scenario": "The third restart of a child waits longer than the first because BackoffStrategy.duration grows with the attempt number.",
      "pitfall": "Cap the maximum backoff; an unbounded curve can effectively stall the loop for hours."
    },
    {
      "id": "supervision-07",
      "title": "Trip a circuit breaker on failures",
      "loop_stage": "control",
      "pattern": "circuit-open-on-threshold",
      "intent": "Stop calling a failing downstream after a failure threshold is hit.",
      "how_it_shapes_the_loop": "CircuitBreaker moves from Closed to Open, short-circuiting subsequent calls so the loop fails fast instead of blocking.",
      "loop_objects_touched": ["CircuitState", "CircuitBreakerConfig"],
      "wiring": {"inputs_from": ["downstream call failures", "CircuitBreakerConfig threshold"], "outputs_to": ["fast-fail path", "CircuitBreakerMetrics"]},
      "touch_interaction": {"gesture": "tap", "canvas_action": "Tap the breaker node to see its state (Closed/Open/HalfOpen) and failure count.", "visual": "Closed is green, Open is red with a broken-circuit icon, HalfOpen amber and probing."},
      "mini_scenario": "After N consecutive endpoint failures the breaker trips Open; the next call returns immediately without touching the dead endpoint.",
      "pitfall": "Count only relevant failures toward the threshold; folding user cancellations into the count trips the breaker spuriously."
    },
    {
      "id": "supervision-08",
      "title": "Probe recovery with a half-open circuit",
      "loop_stage": "verify",
      "pattern": "half-open-probe",
      "intent": "Test whether a recovered downstream is healthy before fully reopening traffic.",
      "how_it_shapes_the_loop": "After a cooldown the CircuitBreaker enters HalfOpen and allows one probe; success returns to Closed, failure back to Open.",
      "loop_objects_touched": ["CircuitState", "CircuitBreakerMetrics"],
      "wiring": {"inputs_from": ["cooldown timer", "probe call result"], "outputs_to": ["Closed or Open transition"]},
      "touch_interaction": {"gesture": "double-tap", "canvas_action": "Double-tap the amber breaker to send a manual probe through the half-open gate.", "visual": "A single probe pulse travels the edge; green settles the node Closed, red snaps it back Open."},
      "mini_scenario": "The cooldown elapses, one probe call succeeds, and current_state transitions the breaker back to Closed, resuming normal calls.",
      "pitfall": "Allow only one probe in HalfOpen; flooding probes defeats the point and can re-overwhelm the recovering service."
    },
    {
      "id": "supervision-09",
      "title": "Watch liveness with HealthMonitor",
      "loop_stage": "perceive",
      "pattern": "periodic-health-check",
      "intent": "Continuously sample subsystem health on an interval.",
      "how_it_shapes_the_loop": "HealthMonitor runs registered checks each interval and aggregates them into OverallHealth that the control layer can act on.",
      "loop_objects_touched": ["HealthStatus", "HealthCheckResult", "OverallHealth"],
      "wiring": {"inputs_from": ["registered HealthChecks"], "outputs_to": ["OverallHealth", "control abort/degrade decisions"]},
      "touch_interaction": {"gesture": "spread", "canvas_action": "Spread the health node to fan out each registered check as its own status dial.", "visual": "Each check dial reads Healthy/Degraded/Unhealthy; the aggregate ring shows OverallStatus."},
      "mini_scenario": "The monitor ticks, GpuHealthCheck reports Degraded, and OverallHealth downgrades so the loop can shed load.",
      "pitfall": "Set a sane interval and failure_threshold; too-frequent checks add overhead, too-lax miss real degradation."
    },
    {
      "id": "supervision-10",
      "title": "Detect a dead agent via heartbeat",
      "loop_stage": "perceive",
      "pattern": "heartbeat-timeout",
      "intent": "Flag an agent that has stopped emitting heartbeats as unhealthy.",
      "how_it_shapes_the_loop": "AgentHealthCheck compares last record_heartbeat against a heartbeat_timeout, transitioning the run toward abort if it stalls.",
      "loop_objects_touched": ["HealthStatus", "HealthCheckResult"],
      "wiring": {"inputs_from": ["record_heartbeat timestamps"], "outputs_to": ["HealthCheckResult", "supervisor abort"]},
      "touch_interaction": {"gesture": "tap", "canvas_action": "Tap an agent node to see its last-heartbeat age against the timeout budget.", "visual": "A heartbeat waveform animates; when the gap exceeds the timeout it flatlines red."},
      "mini_scenario": "An agent hangs and stops calling record_heartbeat; after the timeout AgentHealthCheck returns Unhealthy and the supervisor intervenes.",
      "pitfall": "Emit heartbeats from the work loop, not a background timer, or a stuck worker still looks alive."
    },
    {
      "id": "supervision-11",
      "title": "Shed load on memory pressure",
      "loop_stage": "control",
      "pattern": "resource-threshold-guard",
      "intent": "Degrade or pause the loop when memory crosses a critical threshold.",
      "how_it_shapes_the_loop": "MemoryHealthCheck warning/critical thresholds feed OverallHealth, letting control reduce concurrency before an OOM kills the run.",
      "loop_objects_touched": ["HealthStatus", "OverallHealth"],
      "wiring": {"inputs_from": ["MemoryHealthCheck thresholds"], "outputs_to": ["concurrency throttle", "control decision"]},
      "touch_interaction": {"gesture": "long-press", "canvas_action": "Long-press the memory dial to adjust warning and critical thresholds inline.", "visual": "The dial fills toward red as usage rises; crossing critical pulses the whole health ring."},
      "mini_scenario": "Memory hits the critical threshold; MemoryHealthCheck flips Unhealthy and the supervisor pauses new child spawns.",
      "pitfall": "Act on the warning tier, not just critical; waiting for critical often leaves no headroom to recover."
    },
    {
      "id": "supervision-12",
      "title": "Guard disk before a write-heavy act",
      "loop_stage": "verify",
      "pattern": "precondition-health-gate",
      "intent": "Refuse write-heavy work when disk space is low.",
      "how_it_shapes_the_loop": "DiskHealthCheck gates the act stage so a run that would ENOSPC is degraded before it corrupts partial output.",
      "loop_objects_touched": ["HealthStatus", "HealthCheckResult"],
      "wiring": {"inputs_from": ["DiskHealthCheck"], "outputs_to": ["act stage gate"]},
      "touch_interaction": {"gesture": "tap", "canvas_action": "Tap the disk dial before launching a build to confirm free-space headroom.", "visual": "A fuel-gauge style dial; low free space glows red and disables the launch button."},
      "mini_scenario": "Before a large artifact write, DiskHealthCheck reports Unhealthy so the supervisor blocks the act and warns the user.",
      "pitfall": "Check free space, not total; a full disk on a large volume still fails the write."
    },
    {
      "id": "supervision-13",
      "title": "Notify the parent on child events",
      "loop_stage": "learn",
      "pattern": "upward-event-propagation",
      "intent": "Surface child lifecycle events to the parent supervisor for oversight.",
      "how_it_shapes_the_loop": "ChildEvent and ParentNotification let the parent observe exits and restarts, informing higher-level control without polling.",
      "loop_objects_touched": ["Supervisor", "ChildState"],
      "wiring": {"inputs_from": ["ChildEvent stream"], "outputs_to": ["ParentNotification channel"]},
      "touch_interaction": {"gesture": "draw-connection", "canvas_action": "Draw an edge from a child node up to the parent supervisor to route its notifications.", "visual": "Events travel the upward edge as small pulses tinted by event type."},
      "mini_scenario": "A child transitions to Terminated; a ParentNotification fires so the parent updates its aggregate view.",
      "pitfall": "Do not block child progress on notification delivery; a slow parent consumer must not stall the child."
    },
    {
      "id": "supervision-14",
      "title": "Choose a supervision strategy for a group",
      "loop_stage": "reason",
      "pattern": "one-for-one-vs-all",
      "intent": "Decide whether one failing child restarts alone or restarts the whole group.",
      "how_it_shapes_the_loop": "SupervisionStrategy determines the blast radius of a failure, shaping how many children re-enter the loop on one crash.",
      "loop_objects_touched": ["Supervisor", "SupervisionStrategy", "ChildState"],
      "wiring": {"inputs_from": ["SupervisorBuilder.with_strategy"], "outputs_to": ["restart scope"]},
      "touch_interaction": {"gesture": "two-finger-rotate", "canvas_action": "Rotate the strategy dial on the supervisor between OneForOne and OneForAll.", "visual": "OneForOne highlights just the failing child; OneForAll shades the whole sibling cluster."},
      "mini_scenario": "With OneForAll, one child's crash restarts every sibling to restore a consistent group state.",
      "pitfall": "Match strategy to coupling; OneForAll on loosely-coupled children wastes work restarting healthy siblings."
    },
    {
      "id": "supervision-15",
      "title": "Build a supervisor with a builder",
      "loop_stage": "foundation",
      "pattern": "declarative-supervision-tree",
      "intent": "Assemble the child specs, strategy, and policy before the loop runs.",
      "how_it_shapes_the_loop": "SupervisorBuilder composes ChildSpecs, RestartPolicy, and parent channel into a Supervisor that defines the control substrate for the run.",
      "loop_objects_touched": ["Supervisor", "RestartPolicy", "SupervisionStrategy"],
      "wiring": {"inputs_from": ["ChildSpec factories", "RestartPolicy"], "outputs_to": ["running Supervisor", "SupervisorHandle"]},
      "touch_interaction": {"gesture": "drag", "canvas_action": "Drag child factory chips into the supervisor container to declare the tree, then tap build.", "visual": "Dropped children snap into a tree layout under the supervisor with connecting spokes."},
      "mini_scenario": "The builder adds two children with a shared RestartPolicy, then build() produces the Supervisor and its handle.",
      "pitfall": "Configure strategy and policy before build; the tree is fixed once built and cannot be re-wired live."
    },
    {
      "id": "supervision-16",
      "title": "Read circuit breaker metrics",
      "loop_stage": "perceive",
      "pattern": "observe-breaker-health",
      "intent": "Expose breaker success/failure counts for oversight dashboards.",
      "how_it_shapes_the_loop": "CircuitBreakerMetrics feed observability so the control layer can see how close a downstream is to tripping.",
      "loop_objects_touched": ["CircuitBreakerMetrics", "CircuitState"],
      "wiring": {"inputs_from": ["CircuitBreaker.metrics"], "outputs_to": ["observability dashboard"]},
      "touch_interaction": {"gesture": "spread", "canvas_action": "Spread the breaker node to reveal a sparkline of recent successes and failures.", "visual": "A rolling bar chart of green successes and red failures with the current state overlaid."},
      "mini_scenario": "Metrics show failures climbing toward the threshold; an operator preemptively scales the downstream before it trips.",
      "pitfall": "Read metrics as a snapshot; they lag live state, so do not gate control decisions solely on stale counters."
    },
    {
      "id": "supervision-17",
      "title": "Map RunStatus to loop terminality",
      "loop_stage": "control",
      "pattern": "terminal-state-detection",
      "intent": "Know when a run has definitively finished.",
      "how_it_shapes_the_loop": "RunStatus.is_terminal tells the control loop whether to keep supervising or release the run's resources.",
      "loop_objects_touched": ["RunStatus", "RunRecord"],
      "wiring": {"inputs_from": ["RunStatus"], "outputs_to": ["resource release", "list filtering"]},
      "touch_interaction": {"gesture": "tap", "canvas_action": "Tap a run card to see whether its status is terminal and eligible for cleanup.", "visual": "Terminal cards dim and gain a checkmark or cross; active cards stay bright."},
      "mini_scenario": "A run reaches Completed; is_terminal returns true so the supervisor stops probing its liveness.",
      "pitfall": "Only Completed/Failed/Aborted are terminal; treating Running or Stale as terminal drops still-live oversight."
    },
    {
      "id": "supervision-18",
      "title": "Confirm a pid belongs to selfware",
      "loop_stage": "verify",
      "pattern": "ownership-verified-abort",
      "intent": "Avoid signaling an unrelated process that reused a recorded pid.",
      "how_it_shapes_the_loop": "pid_is_selfware verifies ownership before abort, preventing the control layer from killing a foreign process.",
      "loop_objects_touched": ["RunRecord", "RunRegistry", "AbortOutcome"],
      "wiring": {"inputs_from": ["RunRecord.pid", "process introspection"], "outputs_to": ["safe abort signal"]},
      "touch_interaction": {"gesture": "long-press", "canvas_action": "Long-press abort to run an ownership check before the signal is sent.", "visual": "A shield check flashes green before the abort proceeds, or red to cancel it."},
      "mini_scenario": "An abort targets a pid that the OS recycled; pid_is_selfware returns false so the supervisor skips the signal and just marks the record.",
      "pitfall": "Always verify ownership before signaling; recorded pids can be reused by unrelated processes after death."
    },
    {
      "id": "supervision-19",
      "title": "Expose a health endpoint for external oversight",
      "loop_stage": "foundation",
      "pattern": "external-health-probe",
      "intent": "Let an orchestrator poll the loop's health from outside.",
      "how_it_shapes_the_loop": "maybe_start_health_endpoint and set_global_healthy publish OverallHealth so external supervision can decide to restart the whole run.",
      "loop_objects_touched": ["OverallHealth", "HealthStatus"],
      "wiring": {"inputs_from": ["set_global_healthy", "HealthMonitor aggregate"], "outputs_to": ["HTTP health endpoint"]},
      "touch_interaction": {"gesture": "tap", "canvas_action": "Tap the endpoint node to copy its probe URL or toggle the global healthy flag.", "visual": "A signal-tower icon broadcasts green when healthy, red when the global flag is down."},
      "mini_scenario": "An external orchestrator polls the health endpoint; a red response triggers it to restart the selfware run.",
      "pitfall": "Keep the global healthy flag honest; leaving it true during a known-bad state hides failures from external oversight."
    },
    {
      "id": "supervision-20",
      "title": "Compose supervision as the loop's control shell",
      "loop_stage": "control",
      "pattern": "oversight-shell",
      "intent": "Wrap the whole Planning->Executing->Completed loop in registry, supervisor, breaker, and health.",
      "how_it_shapes_the_loop": "Layers RunRegistry (identity), Supervisor (restart), CircuitBreaker (fast-fail), and HealthMonitor (liveness) around the run so oversight is continuous end to end.",
      "loop_objects_touched": ["RunRecord", "Supervisor", "CircuitState", "OverallHealth"],
      "wiring": {"inputs_from": ["run start", "child events", "health checks"], "outputs_to": ["abort/restart/degrade control decisions"]},
      "touch_interaction": {"gesture": "pinch", "canvas_action": "Pinch to collapse the four supervision sub-nodes into one oversight shell around the run.", "visual": "Collapsed it draws a containing ring around the whole loop with a composite status badge; spread reveals registry, supervisor, breaker, and health."},
      "mini_scenario": "A run starts (registered), a child crashes (restarted with backoff), the endpoint flaps (breaker trips), and memory spikes (health degrades) all under one oversight shell.",
      "pitfall": "Order the layers: identity first, then supervision and breaker, with health cross-cutting; a breaker without a registered run cannot be attributed."
    }
  ]
}