Implements an unbreakable hard interrupt for agentic systems. **Core module (nexus/stop_protocol.py):** - Pre-tool-check gate: blocks tool execution when a stop is active (raises StopInterrupt) - STOP_ACK logging: append-only JSONL at ~/.hermes/stop_ack_log.jsonl - Hands-off registry: time-bounded locks at ~/.hermes/hands_off_registry.json (default 24h, auto-expires) - Full stop: atomic ack + hands-off in one call - Graceful handling of corrupted registry (starts empty, does not crash) **Compliance tests (tests/test_stop_protocol.py):** - 20 tests covering pre-tool-check gate, STOP_ACK logging, hands-off registry, full stop, edge cases, and invalid-state recovery - 100% compliance verification: test_all_stop_paths_covered **Documentation (docs/stop-protocol.md):** - Usage examples, component descriptions, and local test command Closes #844
1.5 KiB
M1: The Stop Protocol
Refs: the-nexus #844, Epic #842
Purpose
Make Stop an unbreakable hard interrupt for all agentic systems in the fleet.
Components
1. Pre-tool-check gate
Every tool execution must pass through StopProtocol.pre_tool_check(session_id).
If a stop command is active for that session, StopInterrupt is raised and the
tool call is blocked.
2. STOP_ACK logging
Every stop command is durably logged to ~/.hermes/stop_ack_log.jsonl with:
- timestamp (ISO-8601 UTC)
- source (who issued the stop)
- session_id
- reason
The log is append-only and readable via read_ack_log().
3. Hands-off registry
Stopped entities are added to ~/.hermes/hands_off_registry.json with a
time-bounded lock (default 24 hours). Any attempt to modify a hands-off entity
must first check is_hands_off(entity).
The registry auto-expires entries when their lock time passes.
4. Full stop
full_stop(session_id, entity) combines ack + hands-off in one atomic call.
Usage
from nexus.stop_protocol import StopProtocol
sp = StopProtocol()
# Before every tool call:
sp.pre_tool_check(session_id="sess_123")
# When user says "Stop":
sp.full_stop(session_id="sess_123", entity="ezra", reason="explicit halt")
# Before modifying any system:
if sp.is_hands_off("ezra"):
raise HandsOffError("ezra is locked — do not touch.")
Compliance
100% test coverage enforced by tests/test_stop_protocol.py (20 tests).
Run locally:
python3 -m pytest tests/test_stop_protocol.py -v