feat(issue-18): decide liveness and delivery by the event protocol, not the screen
Contract (no new event types): heartbeat every N s (automatic timer), unresponsive after K x N s without an event, `started` within T s of the injection, retained per-job state, and a remote transport. - registry: heartbeat_sec / heartbeat_misses / ack_timeout_sec / transport fields; idle_timeout_sec derives K x N unless explicit (defaults 30/4/60 keep the historical 120 s idle window). - heartbeat.py + publish_event --heartbeat N: detached fixed-cadence timer publishing signed `progress` heartbeats (threaded wire publish, local record first); stopped by the terminal event via pidfile, by re-dispatch and by lifetime. Terminal events refuse --heartbeat. - publish_event: retained `<prefix>/state` (status, last_event, seq, HMAC) sent on the same connection after every event (--no-state to skip); publisher.publish_raw takes extra messages. - job_subscriber: subscribes the state topic, recovers terminal status from retained state, resets idle on any accepted message, records seq_gap and reconnected in the audit log, idle budget before the first event is T + K x N (--ack-timeout), --remote mirrors started/terminal events into the registry through the transition boundary. - lib.sh send_keys_safe: an accepted-but-unconfirmed submission is confirmed by agent_status working or the job's own `started` (_sks_job_started); pane change and busy token are no longer delivery signals. - wrapper: --heartbeat/--heartbeat-misses/--ack-timeout (MAM_* env), injected start command arms the timer, brief states the contract, _wait_started (registry / events.log / subscriber log, bounded by T and the wall clock) replaces the 10 s inject grace, R1 grace uses only the on-disk event age (herdr/pane logged once as a diagnostic), remote:<name> sessions skip preflight/idle/pane and dispatch over the broker (remote_dispatch). - remote.py (+ scripts shim): signed retained dispatch (MAM_DISPATCH_SECRET) and a runner that mirrors the job into its own registry with the orchestrator's identity, publishes started --heartbeat, runs --exec and publishes the terminal event. - loop runner: passes MAM_HEARTBEAT_SEC / MAM_HEARTBEAT_MISSES / MAM_ACK_TIMEOUT_S through; YAML rows with transport: remote delegate as remote:<name>. - docs: MESSAGING.md 2.5 contract + remote transport, delegate-job SKILL.md, registry.md, loop SKILL.md. - tests: tests/test_issue18_liveness_contract.py (16); issue 14 pane-signal tests flipped to started-based; issue 6 working-agent tests acknowledge with started; CLI snapshot/help captures refreshed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
This commit is contained in:
1 parent
139bdd4b4c
commit
897b505266
21 files changed
+1989
-129
No files matched your search
+5
-1
@@ -2,7 +2,7 @@ usage: job_subscriber.py [-h] (--job JOB | --wait-any) [--timeout TIMEOUT]
|
||||
[--idle-timeout IDLE_TIMEOUT] [--expect-retention]
|
||||
[--expect-dispatch-token EXPECT_DISPATCH_TOKEN]
|
||||
[--attempt-id ATTEMPT_ID]
|
||||
[--registry-dir REGISTRY_DIR] [-v]
|
||||
[--registry-dir REGISTRY_DIR] [--remote] [-v]
|
||||
|
||||
Subscribe to Job events on MQTT
|
||||
|
||||
@@ -21,4 +21,8 @@ optional arguments:
|
||||
--attempt-id ATTEMPT_ID
|
||||
minimum attempt id to accept events for
|
||||
--registry-dir REGISTRY_DIR
|
||||
--remote the agent shares no disk with this registry: mirror
|
||||
started/terminal events into the job record (Issue
|
||||
#18; automatic for jobs registered with --transport
|
||||
remote)
|
||||
-v, --verbose
|
||||
+7
-1
@@ -6,7 +6,8 @@ usage: publish_event.py [-h] (--job JOB | --pick-pending)
|
||||
[--finalize-report PATH]
|
||||
[--side-effect KIND=REFERENCE]
|
||||
[--attempt-id ATTEMPT_ID]
|
||||
[--expect-dispatch-token EXPECT_DISPATCH_TOKEN] [-v]
|
||||
[--expect-dispatch-token EXPECT_DISPATCH_TOKEN]
|
||||
[--heartbeat N] [--no-state] [-v]
|
||||
|
||||
Publish a Job event to MQTT
|
||||
|
||||
@@ -33,4 +34,9 @@ optional arguments:
|
||||
job's current iteration)
|
||||
--expect-dispatch-token EXPECT_DISPATCH_TOKEN
|
||||
expected dispatch token for CAS verification
|
||||
--heartbeat N after publishing, start a detached timer that
|
||||
publishes a `progress` heartbeat every N seconds until
|
||||
the job ends (Issue #18; not with a terminal event)
|
||||
--no-state do not publish the retained <topic_prefix>/state
|
||||
message
|
||||
-v, --verbose
|
||||
Reference in new issue
Block a user