@bradheitmann/odin-sentinel 0.4.12 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/README.md +24 -17
- package/dist/src/harness-pacing/index.d.ts +10 -0
- package/dist/src/harness-pacing/index.js +11 -0
- package/dist/src/harness-pacing/index.js.map +1 -0
- package/dist/src/harness-pacing/recommend.d.ts +28 -0
- package/dist/src/harness-pacing/recommend.js +74 -0
- package/dist/src/harness-pacing/recommend.js.map +1 -0
- package/dist/src/harness-pacing/schema.d.ts +28 -0
- package/dist/src/harness-pacing/schema.js +2 -0
- package/dist/src/harness-pacing/schema.js.map +1 -0
- package/dist/src/harness-pacing/storage.d.ts +32 -0
- package/dist/src/harness-pacing/storage.js +74 -0
- package/dist/src/harness-pacing/storage.js.map +1 -0
- package/dist/src/mcp/server.js +29 -2
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/odin-watch/backends/cmux.d.ts +6 -0
- package/dist/src/odin-watch/backends/cmux.js +39 -0
- package/dist/src/odin-watch/backends/cmux.js.map +1 -0
- package/dist/src/odin-watch/backends/tmux.d.ts +6 -0
- package/dist/src/odin-watch/backends/tmux.js +40 -0
- package/dist/src/odin-watch/backends/tmux.js.map +1 -0
- package/dist/src/odin-watch/classifier.d.ts +27 -0
- package/dist/src/odin-watch/classifier.js +182 -0
- package/dist/src/odin-watch/classifier.js.map +1 -0
- package/dist/src/odin-watch/index.d.ts +2 -0
- package/dist/src/odin-watch/index.js +200 -0
- package/dist/src/odin-watch/index.js.map +1 -0
- package/dist/src/odin-watch/snapshotter.d.ts +11 -0
- package/dist/src/odin-watch/snapshotter.js +2 -0
- package/dist/src/odin-watch/snapshotter.js.map +1 -0
- package/dist/src/odin-watch/writers.d.ts +8 -0
- package/dist/src/odin-watch/writers.js +27 -0
- package/dist/src/odin-watch/writers.js.map +1 -0
- package/dist/src/protocol/index.d.ts +3 -1
- package/dist/src/protocol/index.js +4 -1
- package/dist/src/protocol/index.js.map +1 -1
- package/dist/src/protocol/repository.d.ts +14 -0
- package/dist/src/protocol/repository.js +25 -1
- package/dist/src/protocol/repository.js.map +1 -1
- package/dist/src/protocol/schemas.d.ts +144 -0
- package/dist/src/protocol/schemas.js +23 -0
- package/dist/src/protocol/schemas.js.map +1 -1
- package/dist/src/protocol/service.d.ts +19 -2
- package/dist/src/protocol/service.js +89 -3
- package/dist/src/protocol/service.js.map +1 -1
- package/dist/src/protocol/surface-layout.d.ts +20 -0
- package/dist/src/protocol/surface-layout.js +20 -0
- package/dist/src/protocol/surface-layout.js.map +1 -1
- package/dist/src/protocol/version.d.ts +2 -2
- package/dist/src/protocol/version.js +2 -2
- package/dist/src/protocol/version.js.map +1 -1
- package/dist/src/utils/execFileNoThrow.d.ts +5 -0
- package/dist/src/utils/execFileNoThrow.js +18 -0
- package/dist/src/utils/execFileNoThrow.js.map +1 -0
- package/docs/adapters/cmux-adapter.md +168 -0
- package/docs/adapters/herdr-adapter.md +150 -0
- package/docs/adapters/minimux-adapter.md +152 -0
- package/docs/adapters/plain-terminal.md +80 -0
- package/docs/adapters/tmux-adapter.md +150 -0
- package/docs/guides/quick-start.md +7 -7
- package/docs/guides/quickstart-prompts.md +4 -4
- package/docs/lattice/odin-lattice-design.md +555 -0
- package/docs/reference/distribution.md +11 -5
- package/docs/reference/public-surface-audit.md +3 -3
- package/package.json +7 -5
- package/plugins/odin-scp/.claude-plugin/plugin.json +2 -2
- package/plugins/odin-scp/README.md +6 -6
- package/plugins/odin-scp/skills/odin-scp/CHANGELOG.md +12 -0
- package/plugins/odin-scp/skills/odin-scp/SKILL.md +196 -3
- package/plugins/odin-scp/skills/odin-scp/references/canonical-introduction-prompt.md +0 -2
- package/protocol/SCP.md +2 -2
- package/protocol/bootstrap-skill.md +196 -3
- package/protocol/closeout.yaml +1 -1
- package/protocol/delegation.yaml +1 -1
- package/protocol/mission-frontrun/droids-scrutiny-feature-reviewer.md +70 -0
- package/protocol/mission-frontrun/orchestrator-contract.md +70 -0
- package/protocol/mission-frontrun/scrutiny-feature-reviewer-contract.md +73 -0
- package/protocol/mission-frontrun/scrutiny-validator-contract.md +77 -0
- package/protocol/mission-frontrun/worker-contract.md +66 -0
- package/protocol/model-profiles.yaml +8 -1
- package/protocol/receipts/boot-receipt.yaml +13 -0
- package/protocol/role-cards/dev-worker.md +74 -0
- package/protocol/role-cards/exec-asst.md +83 -0
- package/protocol/role-cards/exec-pm.md +66 -0
- package/protocol/role-cards/qa-worker.md +71 -0
- package/protocol/role-cards/team-pm.md +67 -0
- package/protocol/roles.yaml +1 -1
- package/protocol/skill-references/canonical-introduction-prompt.md +0 -2
- package/protocol/topology.yaml +1 -1
- package/scripts/audit/public-surface.mjs +27 -2
- package/scripts/audit/verify-pack.mjs +121 -5
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# herdr Adapter Specification
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
herdr is a third-party Rust TUI agent multiplexer (herdr.dev) that runs inside
|
|
6
|
+
any terminal and provides persistent background sessions with a rich NDJSON
|
|
7
|
+
socket API. It is the **primary tier-3+ substrate** for SSH hosts, Linux
|
|
8
|
+
agents, and non-Mac environments.
|
|
9
|
+
|
|
10
|
+
herdr supports 14+ documented agent integrations as of 2026-06, and its
|
|
11
|
+
persistent background session model means agent processes survive terminal
|
|
12
|
+
disconnects.
|
|
13
|
+
|
|
14
|
+
**SCP Capability Tier: 3+**
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## LICENSE NOTE
|
|
19
|
+
|
|
20
|
+
> **herdr is licensed under AGPL-3.0 with a commercial dual-license option.
|
|
21
|
+
> Any future runtime adapter code included in a distributed package requires
|
|
22
|
+
> legal review to confirm GPL compatibility with the host project's license
|
|
23
|
+
> before distribution.**
|
|
24
|
+
|
|
25
|
+
This document is documentation-only for the current release cycle. No herdr
|
|
26
|
+
dependency has been added to the core protocol package. Legal review must be
|
|
27
|
+
completed before any herdr adapter code is shipped in a distributed artifact.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Capability Matrix
|
|
32
|
+
|
|
33
|
+
| Capability | Supported | Notes |
|
|
34
|
+
|:-------------|:----------|:---------------------------------------------------------|
|
|
35
|
+
| SEND | Yes | workspace/tab/pane/output NDJSON operations |
|
|
36
|
+
| ENTER_PROOF | Yes | `wait` operation confirms delivery |
|
|
37
|
+
| READ_SCREEN | Yes | `pane/output` read operations |
|
|
38
|
+
| WAIT_IDLE | Yes | `wait` operation on pane process state |
|
|
39
|
+
| EVENTS | Yes | Persistent background session with NDJSON event stream |
|
|
40
|
+
| PERSISTENCE | Yes | Persistent background sessions survive disconnects |
|
|
41
|
+
| RECORDING | No | No structured evidence recording primitive |
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## NDJSON Socket API Reference
|
|
46
|
+
|
|
47
|
+
herdr exposes a NDJSON socket API. Each request and response is a single
|
|
48
|
+
JSON object on one line (newline-delimited). The socket path is configurable;
|
|
49
|
+
the default is a Unix domain socket in the user's runtime directory.
|
|
50
|
+
|
|
51
|
+
### SEND — workspace/tab/pane/output
|
|
52
|
+
|
|
53
|
+
Send text to a pane inside a named workspace and tab:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{"op": "pane/send", "workspace": "{workspace_id}", "tab": "{tab_id}", "pane": "{pane_id}", "text": "{text}"}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### ENTER_PROOF — wait
|
|
60
|
+
|
|
61
|
+
Block until the pane reaches an idle or expected-output state:
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{"op": "wait", "workspace": "{workspace_id}", "tab": "{tab_id}", "pane": "{pane_id}", "condition": "idle"}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The response includes a timestamp and the pane's process state at the moment
|
|
68
|
+
the wait condition was satisfied.
|
|
69
|
+
|
|
70
|
+
### READ_SCREEN — pane/output
|
|
71
|
+
|
|
72
|
+
Read the current visible output of a pane:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{"op": "pane/output", "workspace": "{workspace_id}", "tab": "{tab_id}", "pane": "{pane_id}"}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### WAIT_IDLE — wait
|
|
79
|
+
|
|
80
|
+
Same operation as ENTER_PROOF. The `wait` operation serves both synchronization
|
|
81
|
+
and delivery-confirmation roles:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{"op": "wait", "workspace": "{workspace_id}", "tab": "{tab_id}", "pane": "{pane_id}", "condition": "idle", "timeout_ms": 30000}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### EVENTS — persistent session event stream
|
|
88
|
+
|
|
89
|
+
herdr maintains a persistent background session server. Subscribe to a pane's
|
|
90
|
+
event stream to receive real-time output and state change notifications:
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{"op": "subscribe", "workspace": "{workspace_id}", "tab": "{tab_id}", "pane": "{pane_id}"}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Each event is emitted as one NDJSON line. This eliminates polling for
|
|
97
|
+
output detection and state transitions.
|
|
98
|
+
|
|
99
|
+
### PERSISTENCE
|
|
100
|
+
|
|
101
|
+
herdr's background session model keeps agent processes alive after the
|
|
102
|
+
originating terminal disconnects. Sessions are identified by workspace and
|
|
103
|
+
tab IDs and can be reconnected from any terminal on the same host.
|
|
104
|
+
|
|
105
|
+
This makes herdr suitable for long-running agent workloads on SSH hosts where
|
|
106
|
+
terminal disconnects are expected.
|
|
107
|
+
|
|
108
|
+
### RECORDING
|
|
109
|
+
|
|
110
|
+
**Not supported.** herdr has no structured evidence recording primitive at the
|
|
111
|
+
SCP adapter level. If recording is required, redirect pane output to a log file.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Use Case
|
|
116
|
+
|
|
117
|
+
herdr is the recommended substrate for:
|
|
118
|
+
|
|
119
|
+
- **SSH hosts:** Agents running on remote Linux servers where cmux is not
|
|
120
|
+
available.
|
|
121
|
+
- **Linux agents:** Non-Mac environments where a native macOS multiplexer
|
|
122
|
+
cannot be installed.
|
|
123
|
+
- **Non-Mac CI/CD:** Governed agent runs in Linux containers or VMs.
|
|
124
|
+
- **Distributed team setups:** Multiple operators connecting to the same
|
|
125
|
+
persistent agent sessions from different terminals.
|
|
126
|
+
|
|
127
|
+
Its 14+ documented agent integrations and persistent session model make it
|
|
128
|
+
the strongest available tier-3 substrate outside the macOS cmux ecosystem.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Agent Integrations
|
|
133
|
+
|
|
134
|
+
herdr ships with integrations for 14+ agent frameworks as of 2026-06. Refer
|
|
135
|
+
to the herdr documentation at herdr.dev for the current integration catalog.
|
|
136
|
+
The SCP adapter will target the core NDJSON socket API directly and is
|
|
137
|
+
independent of the higher-level agent framework integrations.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Implementation Status
|
|
142
|
+
|
|
143
|
+
The runtime SCP adapter for herdr is **deferred**. Legal review of AGPL-3.0
|
|
144
|
+
compatibility with the host project's license is required before any adapter
|
|
145
|
+
code is distributed. This document specifies the NDJSON socket surface that the
|
|
146
|
+
adapter will use when implemented.
|
|
147
|
+
|
|
148
|
+
When the adapter is implemented, it will be released under a separate adapter
|
|
149
|
+
package and will document the completed legal review outcome. The core package
|
|
150
|
+
remains substrate-agnostic and carries no herdr dependency.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# minimux Adapter Specification
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
minimux is a **headless Zig daemon** and the **highest-capability headless
|
|
6
|
+
substrate** for the Supervised Completion Protocol (SCP). It exposes all seven
|
|
7
|
+
capability flags through a JSON-RPC API, making it the only current substrate
|
|
8
|
+
that reaches **tier 4**.
|
|
9
|
+
|
|
10
|
+
minimux is designed purely for agent workloads. It is never the orchestrator
|
|
11
|
+
and never a multiplexer for humans. Workers run in minimux sessions while a
|
|
12
|
+
human-visible multiplexer (cmux, herdr, or similar) provides the operator view.
|
|
13
|
+
|
|
14
|
+
**SCP Capability Tier: 4**
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## PROTOTYPE STABILITY CAVEAT
|
|
19
|
+
|
|
20
|
+
> **minimux v0.1.1 is prototype software. Protocol guarantees are not
|
|
21
|
+
> production-hardened. Homebrew/npm distribution exists but the runtime adapter
|
|
22
|
+
> for SCP is deferred to a later phase.**
|
|
23
|
+
|
|
24
|
+
Do not use minimux for production governed-team runs until the runtime SCP
|
|
25
|
+
adapter is complete and the stability caveat is lifted. This document is
|
|
26
|
+
documentation-only for the current release cycle.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Capability Matrix
|
|
31
|
+
|
|
32
|
+
| Capability | Supported | Notes |
|
|
33
|
+
|:-------------|:----------|:-------------------------------------------------------------|
|
|
34
|
+
| SEND | Yes | `pane.send` JSON-RPC method |
|
|
35
|
+
| ENTER_PROOF | Yes | `agent.wait_idle` delivery proof primitive |
|
|
36
|
+
| READ_SCREEN | Yes | `pane.snapshot` structured snapshot |
|
|
37
|
+
| WAIT_IDLE | Yes | `agent.wait_idle` blocks until the pane process is idle |
|
|
38
|
+
| EVENTS | Yes | `tap` method — live event stream per session/pane |
|
|
39
|
+
| PERSISTENCE | Yes | Append-only journal + atomic snapshot; kill-9 survivable |
|
|
40
|
+
| RECORDING | Yes | `recordings` evidence primitive |
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## JSON-RPC Method Reference
|
|
45
|
+
|
|
46
|
+
minimux communicates over a local JSON-RPC socket. All methods follow the
|
|
47
|
+
standard JSON-RPC 2.0 envelope (`jsonrpc`, `method`, `params`, `id`).
|
|
48
|
+
|
|
49
|
+
### SEND — `pane.send`
|
|
50
|
+
|
|
51
|
+
Send text to a named pane in a session:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"method": "pane.send",
|
|
56
|
+
"params": { "session": "{session_id}", "pane": "{pane_id}", "text": "{text}" }
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### ENTER_PROOF — `agent.wait_idle`
|
|
61
|
+
|
|
62
|
+
Block until the target pane's process reaches an idle state and return a
|
|
63
|
+
structured delivery proof:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"method": "agent.wait_idle",
|
|
68
|
+
"params": { "session": "{session_id}", "pane": "{pane_id}", "timeout_ms": 30000 }
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The response includes a timestamp, process state, and a journal sequence number
|
|
73
|
+
that serves as the delivery proof artifact.
|
|
74
|
+
|
|
75
|
+
### READ_SCREEN — `pane.snapshot`
|
|
76
|
+
|
|
77
|
+
Return a structured snapshot of the current pane content:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"method": "pane.snapshot",
|
|
82
|
+
"params": { "session": "{session_id}", "pane": "{pane_id}" }
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The snapshot includes full scrollback within the journal window, process state,
|
|
87
|
+
and the sequence number at the time of capture.
|
|
88
|
+
|
|
89
|
+
### WAIT_IDLE — `agent.wait_idle`
|
|
90
|
+
|
|
91
|
+
Same method as ENTER_PROOF. `agent.wait_idle` serves both the "wait until idle"
|
|
92
|
+
and the "proof of delivery" roles because the idle gate is also the delivery
|
|
93
|
+
confirmation boundary.
|
|
94
|
+
|
|
95
|
+
### EVENTS — `tap`
|
|
96
|
+
|
|
97
|
+
Subscribe to a live NDJSON event stream for a session or pane:
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"method": "tap",
|
|
102
|
+
"params": { "session": "{session_id}", "pane": "{pane_id}" }
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The stream emits one JSON object per line as events occur (input, output,
|
|
107
|
+
process state changes, idle transitions). Use this for real-time supervision
|
|
108
|
+
without polling.
|
|
109
|
+
|
|
110
|
+
### PERSISTENCE
|
|
111
|
+
|
|
112
|
+
minimux maintains an **append-only journal** and **atomic snapshots** for each
|
|
113
|
+
session. If the daemon is killed (including `kill -9`), the journal is replayed
|
|
114
|
+
on restart and the session state is recovered automatically.
|
|
115
|
+
|
|
116
|
+
This is the only tier-4 persistence primitive in the current substrate catalog.
|
|
117
|
+
|
|
118
|
+
### RECORDING — `recordings`
|
|
119
|
+
|
|
120
|
+
Retrieve structured recording artifacts for a session or pane:
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"method": "recordings",
|
|
125
|
+
"params": { "session": "{session_id}", "pane": "{pane_id}", "from_seq": 0 }
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Recordings serve as evidence artifacts for audit trails and QA review.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Positioning Note
|
|
134
|
+
|
|
135
|
+
minimux is **never the orchestrator** and **never a multiplexer for humans**.
|
|
136
|
+
|
|
137
|
+
Workers run inside minimux sessions. The human operator views the governed
|
|
138
|
+
workspace through a human-visible multiplexer (cmux on macOS, herdr on Linux
|
|
139
|
+
or SSH hosts). minimux provides the headless execution layer; the human-visible
|
|
140
|
+
layer is a separate substrate.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Implementation Status
|
|
145
|
+
|
|
146
|
+
The runtime SCP adapter for minimux is **deferred**. This document specifies
|
|
147
|
+
the JSON-RPC surface that the adapter will use when implemented. No minimux
|
|
148
|
+
dependency has been added to the core protocol package.
|
|
149
|
+
|
|
150
|
+
When the adapter is implemented, it will be released under a separate adapter
|
|
151
|
+
package that lists minimux as a peer dependency. The core package remains
|
|
152
|
+
substrate-agnostic.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Plain Terminal Adapter Specification
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
A plain terminal (SSH tty, serial console, bare shell, or any environment
|
|
6
|
+
without a multiplexer) is the **lowest-capability substrate** for the
|
|
7
|
+
Supervised Completion Protocol (SCP). Only SEND is available.
|
|
8
|
+
|
|
9
|
+
There is no feedback channel. The agent cannot confirm delivery. The PM cannot
|
|
10
|
+
observe screen content. Polling is impossible. Governance obligations that
|
|
11
|
+
require tier >= 1 cannot be met in a plain terminal environment.
|
|
12
|
+
|
|
13
|
+
**SCP Capability Tier: 0**
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Capability Matrix
|
|
18
|
+
|
|
19
|
+
| Capability | Supported | Notes |
|
|
20
|
+
|:-------------|:--------------|:----------------------------------------------------|
|
|
21
|
+
| SEND | Yes | Write to stdin or the tty device |
|
|
22
|
+
| ENTER_PROOF | NOT SUPPORTED | No screen capture; delivery cannot be confirmed |
|
|
23
|
+
| READ_SCREEN | NOT SUPPORTED | No capture-pane or equivalent primitive |
|
|
24
|
+
| WAIT_IDLE | NOT SUPPORTED | No idle-detection mechanism |
|
|
25
|
+
| EVENTS | NOT SUPPORTED | No hook system or event stream |
|
|
26
|
+
| PERSISTENCE | NOT SUPPORTED | No session journal or crash-recovery primitive |
|
|
27
|
+
| RECORDING | NOT SUPPORTED | No structured evidence recording primitive |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Limitations
|
|
32
|
+
|
|
33
|
+
A plain terminal provides write-only access to the agent process. The
|
|
34
|
+
supervisor has no visibility into what the agent has received, processed, or
|
|
35
|
+
output. Specifically:
|
|
36
|
+
|
|
37
|
+
- **No delivery confirmation:** Once a string is sent to stdin, there is no
|
|
38
|
+
mechanism to verify the agent received or acted on it.
|
|
39
|
+
- **No screen observation:** The PM cannot read the agent's output without an
|
|
40
|
+
out-of-band channel (log file, sidecar process, etc.).
|
|
41
|
+
- **No idle detection:** The supervisor cannot determine when the agent has
|
|
42
|
+
finished responding.
|
|
43
|
+
- **No event callbacks:** There is no hook or notification system to signal
|
|
44
|
+
state transitions.
|
|
45
|
+
- **No persistence:** If the terminal session ends, all state is lost. There
|
|
46
|
+
is no journal to replay.
|
|
47
|
+
- **No recording:** There is no structured artifact capturing the agent's
|
|
48
|
+
activity for later review.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Use Case
|
|
53
|
+
|
|
54
|
+
A plain terminal is the **fallback surface of last resort** for bootstrapping
|
|
55
|
+
in environments where no multiplexer is available. It is appropriate only when:
|
|
56
|
+
|
|
57
|
+
1. No multiplexer (tmux, cmux, minimux, herdr) can be installed on the host.
|
|
58
|
+
2. The operation does not require delivery confirmation, screen observation,
|
|
59
|
+
or governed supervision.
|
|
60
|
+
3. The operator accepts that governance obligations requiring tier >= 1 cannot
|
|
61
|
+
be met and takes responsibility for out-of-band status verification.
|
|
62
|
+
|
|
63
|
+
Typical scenarios: initial provisioning of a new host before a multiplexer is
|
|
64
|
+
installed; serial console access to an embedded device; a minimal container
|
|
65
|
+
environment where process namespace restrictions prevent multiplexer operation.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Operator Responsibilities
|
|
70
|
+
|
|
71
|
+
Because the SCP adapter cannot observe the agent, the operator must:
|
|
72
|
+
|
|
73
|
+
- Use out-of-band channels (log files, sidecar processes, application metrics)
|
|
74
|
+
to verify agent activity.
|
|
75
|
+
- Accept that no boot receipt, delivery proof, or wake-state report can be
|
|
76
|
+
generated for this tier.
|
|
77
|
+
- Treat the plain terminal session as ungoverned and document the exception
|
|
78
|
+
in the session record.
|
|
79
|
+
|
|
80
|
+
Promote the substrate to tier >= 1 (tmux) as soon as the environment permits.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# tmux Adapter Specification
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
tmux is a **tier-2 substrate** for the Supervised Completion Protocol (SCP).
|
|
6
|
+
It provides SEND, ENTER_PROOF, READ_SCREEN, and WAIT_IDLE — a solid mid-tier
|
|
7
|
+
capability set sufficient for governed agent supervision when screen capture and
|
|
8
|
+
idle-wait primitives are required.
|
|
9
|
+
|
|
10
|
+
tmux does **not** have an event hook system comparable to a native GUI
|
|
11
|
+
multiplexer, so all observation must be done via polling rather than
|
|
12
|
+
event-driven interrupts.
|
|
13
|
+
|
|
14
|
+
**SCP Capability Tier: 2**
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Capability Matrix
|
|
19
|
+
|
|
20
|
+
| Capability | Supported | Notes |
|
|
21
|
+
|:-------------|:----------|:------------------------------------------------|
|
|
22
|
+
| SEND | Yes | `tmux send-keys -t {pane} {text} Enter` |
|
|
23
|
+
| ENTER_PROOF | Partial | Send Enter then verify via capture-pane |
|
|
24
|
+
| READ_SCREEN | Yes | `tmux capture-pane -p -t {pane}` (text snapshot)|
|
|
25
|
+
| WAIT_IDLE | Yes | `tmux wait-for {event_name}` blocks until fired |
|
|
26
|
+
| EVENTS | No | No hook system; polling required |
|
|
27
|
+
| PERSISTENCE | No | Sessions survive disconnect but no agent journal|
|
|
28
|
+
| RECORDING | No | No structured evidence primitive |
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Command Reference
|
|
33
|
+
|
|
34
|
+
### SEND
|
|
35
|
+
|
|
36
|
+
Send text to a pane. Use `send-keys` for arbitrary text; include `Enter`
|
|
37
|
+
to submit the line:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
tmux send-keys -t {session}:{window}.{pane} "{text}" Enter
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Pane targets use tmux's `%N` numeric pane IDs or `session:window.pane` syntax.
|
|
44
|
+
|
|
45
|
+
### ENTER_PROOF (Partial)
|
|
46
|
+
|
|
47
|
+
tmux has no native delivery-proof primitive. The pattern is:
|
|
48
|
+
|
|
49
|
+
1. Send the command with `Enter`.
|
|
50
|
+
2. Poll `capture-pane` until the expected prompt or output appears.
|
|
51
|
+
3. Record the capture result as the delivery artifact.
|
|
52
|
+
|
|
53
|
+
This is probabilistic rather than cryptographic; it satisfies tier-2 proof
|
|
54
|
+
requirements but not tier-4 journal-level guarantees.
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
tmux send-keys -t {pane} "{command}" Enter
|
|
58
|
+
# then poll:
|
|
59
|
+
tmux capture-pane -p -t {pane}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### READ_SCREEN
|
|
63
|
+
|
|
64
|
+
Capture the visible text content of a pane as a UTF-8 string:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
tmux capture-pane -p -t {pane}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Requires tmux 2.0 or later for the `-p` (print to stdout) flag.
|
|
71
|
+
|
|
72
|
+
For history beyond the visible viewport:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
tmux capture-pane -p -S -{history-lines} -t {pane}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### WAIT_IDLE
|
|
79
|
+
|
|
80
|
+
Block until a named event fires. The event must be signalled by a shell
|
|
81
|
+
command or wrapper running inside the target pane:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
tmux wait-for {event_name}
|
|
85
|
+
# signal from inside the pane:
|
|
86
|
+
tmux wait-for -S {event_name}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`wait-for` is suitable for synchronizing after long-running commands when
|
|
90
|
+
the inner process can call `tmux wait-for -S`.
|
|
91
|
+
|
|
92
|
+
### EVENTS
|
|
93
|
+
|
|
94
|
+
**Not supported.** tmux has no hook API comparable to a native multiplexer's
|
|
95
|
+
`set-hook` or `notify` system. Supervision logic must poll `capture-pane`
|
|
96
|
+
at a fixed interval; event-driven scheduling is not available.
|
|
97
|
+
|
|
98
|
+
### PERSISTENCE
|
|
99
|
+
|
|
100
|
+
**Not supported at the SCP adapter level.** tmux sessions survive disconnects,
|
|
101
|
+
but there is no append-only journal, atomic snapshot, or crash-recovery
|
|
102
|
+
primitive accessible to the SCP adapter.
|
|
103
|
+
|
|
104
|
+
### RECORDING
|
|
105
|
+
|
|
106
|
+
**Not supported.** tmux has no structured evidence recording primitive. If
|
|
107
|
+
recording is required, redirect output to a log file from within the shell
|
|
108
|
+
session.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Minimum Version Requirements
|
|
113
|
+
|
|
114
|
+
| Requirement | Minimum |
|
|
115
|
+
|:-----------------|:--------|
|
|
116
|
+
| tmux | 2.0 |
|
|
117
|
+
| `capture-pane -p`| tmux 2.0|
|
|
118
|
+
| `wait-for` | tmux 2.2|
|
|
119
|
+
| `%N` pane IDs | tmux 1.6|
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## odin-watch Integration Pattern
|
|
124
|
+
|
|
125
|
+
The `TmuxBackend` uses `capture-pane -p` to read pane state. Because EVENTS
|
|
126
|
+
is not supported, the backend operates in **polling mode only**:
|
|
127
|
+
|
|
128
|
+
1. Read pane content via `capture-pane -p -t {pane}`.
|
|
129
|
+
2. Hash the output to detect changes (`screen_hash`, `screen_changed`).
|
|
130
|
+
3. If the content matches an idle or completion marker, update `WakeState`.
|
|
131
|
+
4. Sleep for the configured `pollIntervalSeconds` and repeat.
|
|
132
|
+
|
|
133
|
+
There is no interrupt mechanism. The poller must run at a fixed cadence.
|
|
134
|
+
Recommended polling interval: 15–30 seconds for routine supervision;
|
|
135
|
+
5 seconds for time-sensitive gates.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Limitations
|
|
140
|
+
|
|
141
|
+
- **No EVENTS:** All observation is poll-based. The backend cannot be
|
|
142
|
+
notified of state changes; it must check on a timer.
|
|
143
|
+
- **No PERSISTENCE:** If the odin-watch process restarts, no journal is
|
|
144
|
+
available to reconstruct prior state. The backend must re-scan pane
|
|
145
|
+
content from scratch.
|
|
146
|
+
- **ENTER_PROOF is probabilistic:** Delivery confirmation relies on
|
|
147
|
+
recognizing expected output in a subsequent `capture-pane`, not on a
|
|
148
|
+
cryptographic or journal-level proof.
|
|
149
|
+
- **Pane content is ephemeral:** The terminal scrollback is finite;
|
|
150
|
+
long-running sessions may lose history unless piped to a file.
|
|
@@ -32,19 +32,19 @@ step. You are still in control.
|
|
|
32
32
|
Recommended zero-install path:
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
|
-
pnpm dlx --package @bradheitmann/odin-sentinel@0.
|
|
35
|
+
pnpm dlx --package @bradheitmann/odin-sentinel@0.5.0 odin-sentinel-mcp
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
Supported npm global install:
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
npm i -g @bradheitmann/odin-sentinel@0.
|
|
41
|
+
npm i -g @bradheitmann/odin-sentinel@0.5.0
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
Supported npx zero-install path:
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
|
-
npx -y -p @bradheitmann/odin-sentinel@0.
|
|
47
|
+
npx -y -p @bradheitmann/odin-sentinel@0.5.0 odin-sentinel-mcp
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
## 3. Configure MCP
|
|
@@ -57,7 +57,7 @@ harness after editing config.
|
|
|
57
57
|
"mcpServers": {
|
|
58
58
|
"odin-sentinel": {
|
|
59
59
|
"command": "pnpm",
|
|
60
|
-
"args": ["dlx", "--package", "@bradheitmann/odin-sentinel@0.
|
|
60
|
+
"args": ["dlx", "--package", "@bradheitmann/odin-sentinel@0.5.0", "odin-sentinel-mcp"]
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -90,10 +90,10 @@ Zero-install smoke test:
|
|
|
90
90
|
|
|
91
91
|
```bash
|
|
92
92
|
printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"0"}}}\n' \
|
|
93
|
-
| pnpm dlx --package @bradheitmann/odin-sentinel@0.
|
|
93
|
+
| pnpm dlx --package @bradheitmann/odin-sentinel@0.5.0 odin-sentinel-mcp
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
Expect `serverInfo.name = odin-sentinel` and `serverInfo.version = 0.
|
|
96
|
+
Expect `serverInfo.name = odin-sentinel` and `serverInfo.version = 0.5.0`.
|
|
97
97
|
Minimum compatible child MCP version: `0.4.5`.
|
|
98
98
|
|
|
99
99
|
## 6. Auth And Provider Readiness
|
|
@@ -191,7 +191,7 @@ occupants until readiness passes or EXEC PM records a waiver/substitution.
|
|
|
191
191
|
| Skill missing | Install the native skill where supported or use `odin.get_bootstrap_skill` as full prompt fallback. |
|
|
192
192
|
| Auth/login required | Ask the user to provision the provider; verify status without printing secrets. |
|
|
193
193
|
| Permission prompt | Stop and route to PM/user; do not bypass silently. |
|
|
194
|
-
| Stale MCP version | Use a pinned `@bradheitmann/odin-sentinel@0.
|
|
194
|
+
| Stale MCP version | Use a pinned `@bradheitmann/odin-sentinel@0.5.0` command, restart host, and confirm `0.5.0`. |
|
|
195
195
|
| Local inference stall | Require visible content within timeout; endpoint-only success is insufficient. |
|
|
196
196
|
| Role refusal | Mark the role `NON_GOVERNED_ONE_SHOT_ONLY` unless MCP/skill/full protocol proof is established. |
|
|
197
197
|
| Missing governed uptake proof | Treat as `FIXABLE_BLOCKED` (MCP/skill presence is not uptake): capture and verify a governed-context proof with `scripts/protocol/verify-governed-context.mjs`. |
|
|
@@ -13,7 +13,7 @@ Set up @bradheitmann/odin-sentinel for this machine.
|
|
|
13
13
|
Rules:
|
|
14
14
|
- Detect first; install only missing prerequisites.
|
|
15
15
|
- Required runtime: Node.js >=22.13.0.
|
|
16
|
-
- Install or use @bradheitmann/odin-sentinel@0.
|
|
16
|
+
- Install or use @bradheitmann/odin-sentinel@0.5.0.
|
|
17
17
|
- Configure only MCP hosts that already exist on this machine.
|
|
18
18
|
- Do not ask me to paste API keys, tokens, or OAuth values.
|
|
19
19
|
- Verify provider/auth status without printing secret values.
|
|
@@ -22,9 +22,9 @@ Rules:
|
|
|
22
22
|
- Print configured hosts, skipped hosts, package version, and warnings.
|
|
23
23
|
|
|
24
24
|
Smoke test:
|
|
25
|
-
printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"0"}}}\n' | odin-sentinel-mcp
|
|
25
|
+
printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"0"}}}\n' | pnpm dlx --package @bradheitmann/odin-sentinel@0.5.0 odin-sentinel-mcp
|
|
26
26
|
|
|
27
|
-
Expected version: 0.
|
|
27
|
+
Expected version: 0.5.0.
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
Restart any host whose MCP config changed.
|
|
@@ -37,7 +37,7 @@ Open CMUX first. Paste into the agent that will act as EXEC PM.
|
|
|
37
37
|
You are A/EXEC-PM. Bootstrap a Sentinel Coordination Protocol governed team in this CMUX workspace.
|
|
38
38
|
|
|
39
39
|
Procedure:
|
|
40
|
-
1. Call odin.get_version and confirm version 0.
|
|
40
|
+
1. Call odin.get_version and confirm version 0.5.0 or newer.
|
|
41
41
|
2. Call odin.get_bootstrap_skill and read the public SCP contract.
|
|
42
42
|
3. Confirm CMUX is active and you are in the same workspace as the team slots.
|
|
43
43
|
4. Compute the target layout with odin.compute_surface_layout using profile=human_cmux_quad.
|