Skip to content

feat(lib): lib/supervise — observer-native supervision (#409)#527

Merged
InauguralPhysicist merged 1 commit into
mainfrom
feat/lib-supervise-409
Jul 9, 2026
Merged

feat(lib): lib/supervise — observer-native supervision (#409)#527
InauguralPhysicist merged 1 commit into
mainfrom
feat/lib-supervise-409

Conversation

@InauguralPhysicist

Copy link
Copy Markdown
Collaborator

What

A supervisor over the #408 cooperative task layer that, beyond BEAM-style crash-restart, also catches the silently wedged worker — alive, not crashed, never timing out, but no longer making progress — a signal BEAM structurally cannot see (its processes carry no free per-value trajectory measurement). This generalizes the EigenOS window-manager red-title pattern.

Model

Share-nothing messages are unnecessary here — cooperative tasks share the module-global heap on one thread:

API: supervisor_new / supervise of [sup, fn, slot] / supervise_step / supervise_run of [sup, max_ticks]. Deterministic by construction. Eight slots (a list element has no observer trajectory, #262, so the signals need named scalars).

Verification

  • examples/supervisor_tree.eigs — a 3-worker pool where one wedges mid-run and is detected + restarted; byte-identical across runs.
  • tests/test_supervise.eigs (6 asserts): wedged-detected-and-restarted-exactly-once, healthy-never-restarted, wedged-recovers; crash-restart (exit 0, not fatal); restart-intensity cap honored.
  • Full suite green release AND ASan (detect_leaks=1): 2703/2703, 0 failed, no leak-tally increase (task kill/respawn is leak-clean).

Forcing-function gap surfaced (not worked around)

A task cannot learn its own id (no task_self), so the BEAM-style message-link supervision variant the issue sketches isn't expressible — the shared-heap model is used instead (idiomatic for this runtime). Filed as #526.

Docs

  • docs/STDLIB.md: lib/supervise.eigs section (satisfies the discoverability gate).
  • CHANGELOG.md: entry under [Unreleased] → Added.

Closes #409

🤖 Generated with Claude Code

Comment thread src/lint.c Fixed
A supervisor over the #408 cooperative task layer that, beyond BEAM-style
crash-restart, also catches the silently WEDGED worker — alive, not
crashed, never timing out, but no longer making progress — a signal BEAM
structurally cannot see (its processes carry no free per-value trajectory
measurement). This is the EigenOS window-manager red-title pattern
generalized.

Model (no share-nothing messages needed — cooperative tasks share the
module-global heap on one thread):
  - workers publish raw progress with `heartbeat of [slot, value]`;
  - the SUPERVISOR samples each alive worker every tick and feeds a BOUNDED
    signature (1.5 + v % 8 — never a raw counter, which hits the #294
    flat-entropy blind spot) into that slot's observer trajectory. Sampling
    on the supervisor side is what makes a wedge visible: a frozen worker
    stops heart-beating, so only the poller keeps adding the now-constant
    samples that read `stable`;
  - a worker that returns normally is `done`; one that raises is caught by
    the wrapper as `crashed` (so a supervised crash never fails the process,
    #493);
  - wedged (alive + stable after a warm-up window) and crashed workers are
    restarted from their spec, each up to a per-worker restart-intensity cap.

API: supervisor_new / supervise of [sup, fn, slot] / supervise_step /
supervise_run of [sup, max_ticks]. Deterministic by construction. Eight
slots (the WM/task-table precedent; a list element has no observer
trajectory, #262, so the signals need named scalars).

Flagship example examples/supervisor_tree.eigs (byte-identical across runs).
Regression tests/test_supervise.eigs: wedged-detected-and-restarted-once,
healthy-never-restarted, crash-restart (exit 0, not fatal), restart cap.

Forcing-function gap surfaced (not worked around): a task cannot learn its
own id (no task_self), so the message-link supervision variant isn't
expressible — filed as #526.

Full suite green release + ASan (leaks on), 2703/2703, no leak-tally
increase (task kill/respawn clean).

Closes #409

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@InauguralPhysicist InauguralPhysicist merged commit c8abb71 into main Jul 9, 2026
17 checks passed
@InauguralPhysicist InauguralPhysicist deleted the feat/lib-supervise-409 branch July 9, 2026 22:47
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.

lib/supervise.eigs — observer-native supervision: predictive, not crash-reactive (blocked on the task layer)

2 participants