feat(ttm-control-plane): H1–H6 spawn-shim plugin + lifecycle receiver - #18858
Closed
ik-svc-oc wants to merge 1 commit into
Closed
feat(ttm-control-plane): H1–H6 spawn-shim plugin + lifecycle receiver#18858ik-svc-oc wants to merge 1 commit into
ik-svc-oc wants to merge 1 commit into
Conversation
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.
Author
|
Wrong target repo — operator controls the fork at ik-svc-oc/hermes-agent. |
Collaborator
|
Supersedes #18854 — same TTM control-plane lifecycle work (H1–H6 squash). |
1 similar comment
Collaborator
|
Supersedes #18854 — same TTM control-plane lifecycle work (H1–H6 squash). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 upstreammainbase with no file conflicts.Endpoints
POST/runs/dispatchhermes chatsessionGET/runs/{ref}/statusPOST/runs/{ref}/lifecyclestop|pause|resume|expand_scope(202 async)POST/runs/{ref}/stopPOST/runs/{run_id}/rebind-tokenLifecycle semantics (H6)
task.updated{stopped}; binding kept for TTM-driven closure. Hermes never self-approves run closure.task.updated{paused}. Degrades explicitly viaruntime.errorif SIGSTOP unavailable.task.updated{active}.principal_token(revoked); awaitsrebind-tokenfor new scope_epoch.tools/ttm_ingress.pyCanonical 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
venv/bin/pytest tests/plugins/test_ttm_control_plane_plugin.py tests/tools/test_ttm_ingress.py -qruntime.errorwhen SIGSTOP failsscope_expanding→running🤖 Generated with Claude Code