Skip to content

feat(ttm-control-plane): H1–H6 spawn-shim plugin + lifecycle receiver - #18858

Closed
ik-svc-oc wants to merge 1 commit into
NousResearch:mainfrom
ik-svc-oc:feat/hermes-run-lifecycle-clean
Closed

feat(ttm-control-plane): H1–H6 spawn-shim plugin + lifecycle receiver#18858
ik-svc-oc wants to merge 1 commit into
NousResearch:mainfrom
ik-svc-oc:feat/hermes-run-lifecycle-clean

Conversation

@ik-svc-oc

Copy link
Copy Markdown

Summary

Adds the TTM control-plane spawn-shim plugin as a first-party dashboard plugin under plugins/ttm-control-plane/. This squash bundles H1–H6 of the Hermes alignment plan (PR-F-H1 through PR-I-H6) against a clean upstream main base with no file conflicts.

Endpoints

Method Path Purpose
POST /runs/dispatch Spawn-on-launch — binds run, spawns headless hermes chat session
GET /runs/{ref}/status Last-known status projection
POST /runs/{ref}/lifecycle H6stop|pause|resume|expand_scope (202 async)
POST /runs/{ref}/stop Compat alias for current TTM adapter
POST /runs/{run_id}/rebind-token Rotate principal token after scope rebind

Lifecycle semantics (H6)

  • stop: SIGTERM process group → 10s wait → SIGKILL; emits task.updated{stopped}; binding kept for TTM-driven closure. Hermes never self-approves run closure.
  • pause: SIGSTOP; saves dossier (pid/lane_id/worktree_id/paused_at); emits task.updated{paused}. Degrades explicitly via runtime.error if SIGSTOP unavailable.
  • resume: SIGCONT from saved dossier; emits task.updated{active}.
  • expand_scope: SIGUSR1 advisory hint; clears principal_token (revoked); awaits rebind-token for new scope_epoch.

tools/ttm_ingress.py

Canonical state writeback skill (PR-F-H2): bind, event/evidence/approval posting, get_run_state, scope epoch tracking. Used by the headless agent process.

Auth & storage

Shared-secret X-TTM-Control-Plane-Secret. SQLite-backed binding registry; principal token never persisted.

Test plan

  • 79 unit tests pass: venv/bin/pytest tests/plugins/test_ttm_control_plane_plugin.py tests/tools/test_ttm_ingress.py -q
  • Wire contract: auth gates, dispatch idempotency, lifecycle action validation (422 on bad action)
  • Stop: SIGTERM→wait→SIGKILL fallback, no SIGKILL when process exits cleanly, no process registered is safe
  • Pause: SIGSTOP + dossier save; explicit degrade via runtime.error when SIGSTOP fails
  • Resume: SIGCONT from dossier; no-op without pause state
  • Expand-scope: SIGUSR1, token revoked, rebind-token transitions scope_expanding→running
  • Token never logged across all event/rebind paths
  • SQLite persistence: bindings survive registry restart; tokens never persist

🤖 Generated with Claude Code

Adds the TTM control-plane spawn-shim plugin (PR-F-H1–H6) as a
dashboard plugin under plugins/ttm-control-plane/. This is the HTTP
face that TTM's HermesAdapter calls to dispatch, monitor, and
control headless Hermes sessions tied to TTM runs.

plugin_api.py — dispatch receiver + lifecycle control
  POST /runs/dispatch          — spawn-on-launch (202, async headless session)
  GET  /runs/{ref}/status      — last-known status projection
  POST /runs/{ref}/lifecycle   — H6: stop|pause|resume|expand_scope (202 async)
  POST /runs/{ref}/stop        — compat alias (current TTM HermesAdapter)
  POST /runs/{run_id}/rebind-token — rotate principal token after rebind

Lifecycle semantics (H6):
  stop:         SIGTERM process group → 10s wait → SIGKILL; emits
                task.updated{stopped}; binding kept for TTM-driven closure.
                Hermes never self-approves run closure.
  pause:        SIGSTOP; saves dossier (pid/lane_id/worktree_id/paused_at);
                emits task.updated{paused}. Degrades explicitly via
                runtime.error if SIGSTOP unavailable.
  resume:       SIGCONT from saved dossier; emits task.updated{active}.
  expand_scope: SIGUSR1 advisory hint; clears principal_token (treat as
                revoked); awaits rebind-token for new epoch.

tools/ttm_ingress.py — canonical state writeback skill (PR-F-H2)
  Bind, event/evidence/approval posting, get_run_state, scope epoch
  tracking. Used by the headless agent process, not the plugin directly.

Auth: shared-secret header X-TTM-Control-Plane-Secret.
Storage: SQLite-backed binding registry (token never persisted).
Tests: 79 unit tests across plugin wire contract, process kill
sequences (SIGTERM→wait→SIGKILL), pause/resume dossier, expand_scope
token revocation, ingress event mocking, ttm_ingress binding lifecycle.
@ik-svc-oc

Copy link
Copy Markdown
Author

Wrong target repo — operator controls the fork at ik-svc-oc/hermes-agent.

@ik-svc-oc ik-svc-oc closed this May 2, 2026
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/plugins Plugin system and bundled plugins labels May 2, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Supersedes #18854 — same TTM control-plane lifecycle work (H1–H6 squash).

1 similar comment
@alt-glitch

Copy link
Copy Markdown
Collaborator

Supersedes #18854 — same TTM control-plane lifecycle work (H1–H6 squash).

@ik-svc-oc
ik-svc-oc deleted the feat/hermes-run-lifecycle-clean branch May 6, 2026 05:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants