@bradheitmann/odin-sentinel 0.4.11 → 0.4.13

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.
Files changed (42) hide show
  1. package/.claude-plugin/marketplace.json +23 -0
  2. package/README.md +20 -16
  3. package/dist/src/mcp/server.js +32 -0
  4. package/dist/src/mcp/server.js.map +1 -1
  5. package/dist/src/protocol/repository.d.ts +6 -0
  6. package/dist/src/protocol/repository.js +12 -2
  7. package/dist/src/protocol/repository.js.map +1 -1
  8. package/dist/src/protocol/service.js +17 -9
  9. package/dist/src/protocol/service.js.map +1 -1
  10. package/dist/src/protocol/version.d.ts +2 -2
  11. package/dist/src/protocol/version.js +2 -2
  12. package/docs/guides/quick-start.md +7 -7
  13. package/docs/guides/quickstart-prompts.md +4 -4
  14. package/docs/reference/client-compatibility.md +1 -1
  15. package/docs/reference/distribution.md +11 -5
  16. package/docs/reference/public-surface-audit.md +2 -2
  17. package/package.json +5 -3
  18. package/plugins/odin-scp/.claude-plugin/plugin.json +25 -0
  19. package/plugins/odin-scp/README.md +62 -0
  20. package/plugins/odin-scp/skills/odin-scp/CHANGELOG.md +25 -0
  21. package/plugins/odin-scp/skills/odin-scp/SKILL.md +1518 -0
  22. package/plugins/odin-scp/skills/odin-scp/agents/openai.yaml +4 -0
  23. package/plugins/odin-scp/skills/odin-scp/references/boot-receipt-examples.md +439 -0
  24. package/plugins/odin-scp/skills/odin-scp/references/canonical-introduction-prompt.md +118 -0
  25. package/plugins/odin-scp/skills/odin-scp/references/harness-skill-targets.md +56 -0
  26. package/plugins/odin-scp/skills/odin-scp/references/team-bootstrap-runbook.md +298 -0
  27. package/plugins/odin-scp/skills/odin-scp/scripts/sync-installations.sh +233 -0
  28. package/protocol/SCP.md +3 -3
  29. package/protocol/bootstrap-skill.md +22 -13
  30. package/protocol/closeout.yaml +1 -1
  31. package/protocol/delegation.yaml +1 -1
  32. package/protocol/model-profiles.yaml +2 -2
  33. package/protocol/receipts/team-manifest.yaml +1 -1
  34. package/protocol/roles.yaml +1 -1
  35. package/protocol/skill-references/boot-receipt-examples.md +439 -0
  36. package/protocol/skill-references/canonical-introduction-prompt.md +118 -0
  37. package/protocol/skill-references/harness-skill-targets.md +56 -0
  38. package/protocol/skill-references/team-bootstrap-runbook.md +298 -0
  39. package/protocol/topology.yaml +1 -1
  40. package/scripts/audit/public-surface.mjs +32 -3
  41. package/scripts/audit/verify-pack.mjs +175 -12
  42. package/templates/team-manifest-template.yaml +6 -6
@@ -0,0 +1,298 @@
1
+ # SCP Team Bootstrap Runbook
2
+
3
+ Use this when a single `EXEC PM` pane must create, operate, and tear down SCP teams in CMUX or another terminal surface manager.
4
+
5
+ ## Required Inputs
6
+
7
+ - Objective and phase boundary.
8
+ - Target repo/worktree/branch/SHA.
9
+ - Pod count, default 3 federated pods unless human operator specifies otherwise.
10
+ - Team exceptions, especially UX/design teams.
11
+ - Allowed harness/model pool and any budget/cost priority.
12
+
13
+ If any input is missing, choose the conservative default and record it in `SCP-TEAM-MANIFEST`. Ask human operator only when missing information changes authority, scope, destructive cleanup, or cost materially.
14
+
15
+ ## Skill Composition
16
+
17
+ - Use `team-composition-patterns` to choose minimum viable pod shape.
18
+ - Use `dispatching-parallel-agents` only after workstreams are independent and write scopes do not conflict.
19
+ - Use `delegate` for harness/model selection, preflight probes, fallback ladder, and instruction bundles.
20
+ - Use `handoff` for parked retained panes.
21
+ - Use `qa-swarm-review` for cleanup or closure review.
22
+ - Use `atlas-synthesis` for post-run SCP improvement packets.
23
+
24
+ ## Default Three-Pod Layout
25
+
26
+ ```yaml
27
+ executive_office:
28
+ - pane: A/EXEC-PM
29
+ role: EXEC PM
30
+ - pane: A/EXEC-ASST
31
+ role: EXEC ASST
32
+ - pane: A/EXEC-RSCH
33
+ role: EXEC RSCH
34
+ - pane: A/EXEC-QA
35
+ role: EXEC QA
36
+ pods:
37
+ - team: B
38
+ panes: [B/TEAM-PM, B/TEAM-SENTINEL, B/DEV-1, B/QA-1, B/SHADOW-1]
39
+ - team: C
40
+ panes: [C/TEAM-PM, C/TEAM-SENTINEL, C/DEV-1, C/QA-1, C/SHADOW-1]
41
+ - team: D
42
+ panes: [D/TEAM-PM, D/TEAM-SENTINEL, D/DEV-1, D/QA-1, D/SHADOW-1]
43
+ floaters:
44
+ - A/INTEGRATION-STEWARD
45
+ - A/QUEUE-TRIAGE
46
+ ```
47
+
48
+ Start smaller when the objective is narrow. Add pods horizontally only when the queue has independent work, non-overlapping write scopes, and enough QA capacity.
49
+
50
+ `TEAM PM` and `TEAM SENTINEL` are separate control roles. `TEAM PM` routes pod assignments and activates workers. `TEAM SENTINEL` watches delivery, scope, role discipline, branch proof, and intervention health. Neither implements or QA-closes by default.
51
+
52
+ ## Terminal Setup Pattern
53
+
54
+ Use live CMUX commands only after identifying the current workspace. If operating in tmux, WezTerm, iTerm2, Ghostty, Warp, Cursor, Zed, VS Code, libghostyy, or another surface manager, capture the equivalent `terminal_locator` fields and mark unsupported fields `unavailable`.
55
+
56
+ If the surface manager exposes libghostty-vt or a congruent terminal-state API, also capture `vt_state_snapshot`. Keep this separate from `terminal_locator`: libghostty-vt models terminal emulator state such as terminal instances, rows/cols, active screen, cursor, scrollback, render dirty state, formatter output, semantic prompt state, and input encoding; it does not by itself define SCP team identity or CMUX-style workspace routing.
57
+
58
+ ```bash
59
+ /Applications/cmux.app/Contents/Resources/bin/cmux --json --id-format both current-workspace
60
+ /Applications/cmux.app/Contents/Resources/bin/cmux --json --id-format both identify --workspace <workspace> --surface <surface>
61
+ /Applications/cmux.app/Contents/Resources/bin/cmux --json --id-format both list-pane-surfaces --workspace <workspace>
62
+ /Applications/cmux.app/Contents/Resources/bin/cmux new-surface --type terminal --workspace <workspace>
63
+ /Applications/cmux.app/Contents/Resources/bin/cmux rename-tab --workspace <workspace> --surface <surface> 'C/TEAM-SENTINEL'
64
+ /Applications/cmux.app/Contents/Resources/bin/cmux send --workspace <workspace> --surface <surface> '<launch command or boot prompt>'
65
+ /Applications/cmux.app/Contents/Resources/bin/cmux send-key --workspace <workspace> --surface <surface> Enter
66
+ /Applications/cmux.app/Contents/Resources/bin/cmux read-screen --workspace <workspace> --surface <surface> --lines 80 --scrollback
67
+ ```
68
+
69
+ Do not claim delivery until send, enter, read-screen, and ack state are recorded in `[SCP-CMUX-DELIVERY]` or `[SCP-TERMINAL-DELIVERY]`.
70
+
71
+ Use these delivery verdicts:
72
+
73
+ - `DELIVERED_ACKED`: send/enter/read-screen completed and ack observed.
74
+ - `DELIVERED_NO_ACK`: message landed but no ack yet; poll again.
75
+ - `INPUT_BAR_ONLY`: text was not submitted; not delivered.
76
+ - `PANE_BLOCKED_ON_PERMISSION`: plan mode, auth, quota, modal, or permission blocker.
77
+ - `PANE_STILL_THINKING`: instruction landed and pane is still processing.
78
+
79
+ ## Fast Bootstrap Mode
80
+
81
+ For initial team creation, do not require every idle pane to emit the full `SCP_BOOT_RECEIPT`. Use `SCP_MIN_BOOT_RECEIPT` to park panes quickly, then require full `SCP_BOOT_RECEIPT` only before activation, dispatch, mutation, QA, commit, push, or closure language.
82
+
83
+ ```yaml
84
+ SCP_MIN_BOOT_RECEIPT:
85
+ agent_id: c-dev-1
86
+ team: C
87
+ role: DEV WORKER
88
+ reports_to: C/TEAM-PM
89
+ cwd: <pwd or EXEC PM supplied>
90
+ branch: <branch or EXEC PM supplied>
91
+ head_sha: <sha or EXEC PM supplied>
92
+ may_implement: false
93
+ may_qa_accept: false
94
+ permission_mode: DEGRADED_READ_ONLY | READ_ONLY | WRITE_WHEN_ACTIVATED
95
+ current_state: BOOTSTRAPPED_IDLE
96
+ ```
97
+
98
+ Minimal boot receipt states:
99
+
100
+ - `BOOTSTRAPPED_IDLE`: pane launched, role acknowledged, no work active.
101
+ - `BOOT_RECEIPT_PARTIAL`: minimal receipt present, full receipt deferred until activation.
102
+ - `BOOT_RECEIPT_BLOCKED`: pane paused on permission, auth, quota, context, or plan-mode issue.
103
+
104
+ When EXEC PM has exact CMUX/tmux/terminal refs, provide them in the boot prompt. Pane self-report is secondary and should not override adapter-captured locator ids.
105
+
106
+ ## Plan-Mode Bootstrap
107
+
108
+ Claude Code and similar harnesses may pause for approval on reads or shell proof. During bootstrap-only runs:
109
+
110
+ - Safe to approve or pre-supply: SCP/AGENTS/handoff reads, `pwd`, `git status --short --branch --untracked-files=all`, `git rev-parse HEAD @{u}`, `cmux identify`, `cmux read-screen`, and receipt acknowledgment.
111
+ - Keep blocked: writes, lifecycle moves, evidence/verdict creation, implementation, QA acceptance, commits, pushes, destructive cleanup, and secret output.
112
+ - If the pane is stuck in plan mode, EXEC PM may supply cwd/branch/SHA/locator proof and request `SCP_MIN_BOOT_RECEIPT` only.
113
+ - Do not dispatch real work to a plan-mode pane until full receipt and activation proof are present.
114
+
115
+ ## SCP-TEAM-MANIFEST
116
+
117
+ Record the manifest before dispatching work.
118
+
119
+ During no-product-work bootstrap, the manifest may remain runtime-only in the EXEC PM transcript, screen report, or status ledger. Before dispatch, mutation, QA activation, commit, push, finish, or clean/ready claims, promote the manifest to a durable handoff, ledger, or branch-visible artifact appropriate to the run.
120
+
121
+ ```yaml
122
+ SCP-TEAM-MANIFEST:
123
+ created_by: A/EXEC-PM
124
+ workspace: <semantic workspace label>
125
+ workspace_ref: <workspace:1 | session name | unavailable>
126
+ workspace_id: <uuid-or-stable-id | unavailable>
127
+ objective: <bounded objective>
128
+ branch_authority: <branch and sha>
129
+ executive_office:
130
+ - pane: A/EXEC-PM
131
+ agent_id: a-exec-pm
132
+ terminal_locator:
133
+ terminal_app: cmux
134
+ terminal_adapter: cmux
135
+ workspace_ref: <workspace:1>
136
+ workspace_id: <uuid>
137
+ window_ref: <window:1>
138
+ window_id: <uuid>
139
+ pane_ref: <pane>
140
+ pane_id: <uuid>
141
+ surface_ref: <surface>
142
+ surface_id: <uuid>
143
+ tab_ref: <tab>
144
+ tab_id: <uuid>
145
+ surface_type: terminal
146
+ title: A/EXEC-PM
147
+ route_command: cmux send --workspace <workspace> --surface <surface>
148
+ locator_source: cmux --json --id-format both identify
149
+ locator_captured_at: <ISO-8601 timestamp>
150
+ vt_state_snapshot:
151
+ vt_provider: unavailable
152
+ vt_api_stability: unknown
153
+ terminal_instance_ref: unavailable
154
+ terminal_instance_id: unavailable
155
+ pty_ref: unavailable
156
+ capture_source: cmux read-screen
157
+ formatter_format: plain
158
+ rows: unavailable
159
+ cols: unavailable
160
+ total_rows: unavailable
161
+ scrollback_rows: unavailable
162
+ width_px: unavailable
163
+ height_px: unavailable
164
+ active_screen: unavailable
165
+ cursor_x: unavailable
166
+ cursor_y: unavailable
167
+ cursor_visible: unavailable
168
+ cursor_pending_wrap: unavailable
169
+ title: A/EXEC-PM
170
+ pwd: unavailable
171
+ render_dirty: unavailable
172
+ semantic_prompt_observed: unavailable
173
+ semantic_input_observed: unavailable
174
+ semantic_output_observed: unavailable
175
+ paste_safety_checked: unavailable
176
+ paste_safe: unavailable
177
+ key_encoding_provider: unavailable
178
+ mouse_encoding_provider: unavailable
179
+ focus_encoding_provider: unavailable
180
+ snapshot_captured_at: <ISO-8601 timestamp>
181
+ role: EXEC PM
182
+ harness_model: <model/harness>
183
+ disposition: retain
184
+ pods:
185
+ - team: C
186
+ purpose: <workstream>
187
+ surfaces:
188
+ - pane: C/TEAM-PM
189
+ terminal_locator: <same schema>
190
+ role: TEAM PM
191
+ harness_model: <model/harness>
192
+ disposition: retain_or_close_on_finish
193
+ - pane: C/TEAM-SENTINEL
194
+ terminal_locator:
195
+ terminal_app: <cmux|tmux|wezterm|iterm2|ghostty|warp|cursor|zed|vscode|unknown>
196
+ terminal_adapter: <cmux|tmux|libghostyy|apple_script|cli|ide_terminal|unavailable>
197
+ workspace_ref: <workspace/session/ref-or-unavailable>
198
+ workspace_id: <uuid-or-stable-id-or-unavailable>
199
+ window_ref: <window-ref-or-unavailable>
200
+ window_id: <uuid-or-stable-id-or-unavailable>
201
+ pane_ref: <pane-ref-or-unavailable>
202
+ pane_id: <uuid-or-stable-id-or-unavailable>
203
+ surface_ref: <surface-ref-or-unavailable>
204
+ surface_id: <uuid-or-stable-id-or-unavailable>
205
+ tab_ref: <tab-ref-or-unavailable>
206
+ tab_id: <uuid-or-stable-id-or-unavailable>
207
+ surface_type: terminal
208
+ title: C/TEAM-SENTINEL
209
+ route_command: <non-secret route command or unavailable>
210
+ locator_source: <command/tool/observation used>
211
+ locator_captured_at: <ISO-8601 timestamp or unavailable>
212
+ vt_state_snapshot:
213
+ vt_provider: <libghostty-vt|terminal-capture|unavailable>
214
+ vt_api_stability: <work_in_progress_unstable|stable|unknown>
215
+ terminal_instance_ref: <GhosttyTerminal handle/ref or unavailable>
216
+ terminal_instance_id: <product-generated id or unavailable>
217
+ pty_ref: <pty/process route or unavailable>
218
+ capture_source: <formatter|render_state|grid_ref|read_screen|unavailable>
219
+ formatter_format: <plain|vt|html|unavailable>
220
+ rows: <rows or unavailable>
221
+ cols: <cols or unavailable>
222
+ total_rows: <total_rows or unavailable>
223
+ scrollback_rows: <scrollback_rows or unavailable>
224
+ width_px: <width_px or unavailable>
225
+ height_px: <height_px or unavailable>
226
+ active_screen: <primary|alternate|unavailable>
227
+ cursor_x: <cursor_x or unavailable>
228
+ cursor_y: <cursor_y or unavailable>
229
+ cursor_visible: <true|false|unavailable>
230
+ cursor_pending_wrap: <true|false|unavailable>
231
+ title: C/TEAM-SENTINEL
232
+ pwd: <pwd or unavailable>
233
+ render_dirty: <false|partial|full|unavailable>
234
+ semantic_prompt_observed: <true|false|unavailable>
235
+ semantic_input_observed: <true|false|unavailable>
236
+ semantic_output_observed: <true|false|unavailable>
237
+ paste_safety_checked: <true|false|unavailable>
238
+ paste_safe: <true|false|unavailable>
239
+ key_encoding_provider: <libghostty-vt|terminal|unavailable>
240
+ mouse_encoding_provider: <libghostty-vt|terminal|unavailable>
241
+ focus_encoding_provider: <libghostty-vt|terminal|unavailable>
242
+ snapshot_captured_at: <ISO-8601 timestamp or unavailable>
243
+ role: TEAM SENTINEL
244
+ harness_model: <model/harness>
245
+ disposition: retain_or_close_on_finish
246
+ - pane: C/DEV-1
247
+ terminal_locator: <same schema>
248
+ role: DEV WORKER
249
+ harness_model: <model/harness>
250
+ disposition: close_on_finish
251
+ exclusions:
252
+ - UX/design teams unless separately profiled
253
+ teardown_policy:
254
+ close_temp_panes_after_finish: true
255
+ retain_dirty_or_blocked_panes: true
256
+ require_approval_for_worktree_delete: true
257
+ ```
258
+
259
+ ## Harness Launch Rules
260
+
261
+ Before launching a harness:
262
+
263
+ 1. Run the `delegate` preflight for that harness/model.
264
+ 2. Prefer cached successful model/harness choices for the same task class.
265
+ 3. Use high-reasoning/costly models for executive, sentinel, architecture, integration, and high-risk QA.
266
+ 4. Use cheaper/bounded models for DEV, routine QA, scans, and shadow review.
267
+ 5. If a harness fails, substitute by role contract, not by pane identity.
268
+
269
+ Each launched pane must receive:
270
+
271
+ - role-specific boot prompt,
272
+ - `SCP_MIN_BOOT_RECEIPT` requirements for initial parking,
273
+ - full `SCP_BOOT_RECEIPT` requirements for activation or mutation,
274
+ - write/read/prohibited scopes,
275
+ - reports-to chain,
276
+ - `may_implement` and `may_qa_accept`,
277
+ - exact current objective,
278
+ - first expected receipt.
279
+
280
+ ## Dispatch Rules
281
+
282
+ `EXEC PM` dispatches to `TEAM PM`; `TEAM PM` activates and routes pod workers; `TEAM SENTINEL` monitors, polls, intervenes, and may relay corrective prompts. Workers do not self-select work.
283
+
284
+ Every downstream assignment requires `[SCP-DELEGATE]` and `[SCP-CMUX-DELIVERY]` or `[SCP-TERMINAL-DELIVERY]` with a delivery verdict. During active work, each sentinel emits `[SCP-POLL]` on the assigned cadence.
285
+
286
+ ## Teardown Rules
287
+
288
+ On `$odin-scp --finish`:
289
+
290
+ 1. `EXEC PM` broadcasts finish to all manifest panes.
291
+ 2. Every pane emits `[SCP-FINISH]` or is recorded as non-responsive.
292
+ 3. `EXEC ASST` captures final read-screen snapshots and pane list.
293
+ 4. `EXEC QA` or a QA swarm reviews cleanup evidence.
294
+ 5. Close only panes marked `close_on_finish` and only after their state is captured.
295
+ 6. Retain UX/design, dirty, blocked, or explicitly parked panes.
296
+ 7. Record a final manifest with closed/retained/deferred disposition.
297
+
298
+ Never delete worktrees or local files during automated teardown unless exact entries were approved and proof was captured.
@@ -0,0 +1,233 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ MASTER="${SCP_SKILL_MASTER:-${HOME}/.agents/skills/odin-scp}"
5
+ VERIFY_ONLY=false
6
+ DRY_RUN=false
7
+ REPORT_PATH=""
8
+
9
+ usage() {
10
+ cat <<'USAGE'
11
+ Usage: sync-installations.sh [--verify-only] [--dry-run] [--emit-report PATH]
12
+
13
+ Syncs the master odin-scp skill to runtime copies and
14
+ verifies required markers. --verify-only checks current copies without writing.
15
+ --dry-run previews rsync changes without writing.
16
+
17
+ Environment overrides:
18
+ SCP_SKILL_MASTER Master skill directory. Defaults to ~/.agents/skills/odin-scp
19
+ SCP_SKILL_TARGETS_FILE Optional newline-delimited native target directory list.
20
+ SCP_ADAPTER_TARGETS_FILE Optional newline-delimited adapter file list.
21
+ USAGE
22
+ }
23
+
24
+ while [[ $# -gt 0 ]]; do
25
+ case "$1" in
26
+ --verify-only)
27
+ VERIFY_ONLY=true
28
+ shift
29
+ ;;
30
+ --dry-run)
31
+ DRY_RUN=true
32
+ shift
33
+ ;;
34
+ --emit-report)
35
+ if [[ $# -lt 2 ]]; then
36
+ echo "--emit-report requires a path" >&2
37
+ exit 2
38
+ fi
39
+ REPORT_PATH="$2"
40
+ shift 2
41
+ ;;
42
+ -h|--help)
43
+ usage
44
+ exit 0
45
+ ;;
46
+ *)
47
+ echo "unknown argument: $1" >&2
48
+ usage >&2
49
+ exit 2
50
+ ;;
51
+ esac
52
+ done
53
+
54
+ if [[ "$VERIFY_ONLY" == true && "$DRY_RUN" == true ]]; then
55
+ echo "--verify-only and --dry-run are mutually exclusive" >&2
56
+ exit 2
57
+ fi
58
+
59
+ if [[ -n "$REPORT_PATH" ]]; then
60
+ mkdir -p "$(dirname "$REPORT_PATH")"
61
+ : > "$REPORT_PATH"
62
+ fi
63
+
64
+ emit() {
65
+ if [[ -n "$REPORT_PATH" ]]; then
66
+ printf '%s\n' "$*" | tee -a "$REPORT_PATH"
67
+ else
68
+ printf '%s\n' "$*"
69
+ fi
70
+ }
71
+
72
+ TARGETS=(
73
+ "${HOME}/.codex/skills/odin-scp"
74
+ "${HOME}/.claude/skills/odin-scp"
75
+ "${HOME}/.config/goose/skills/odin-scp"
76
+ "${HOME}/.config/opencode/skills/odin-scp"
77
+ "${HOME}/.opencode/skills/odin-scp"
78
+ "${HOME}/.crush/skills/odin-scp"
79
+ "${HOME}/.cursor/skills/odin-scp"
80
+ "${HOME}/.cursor/skills-cursor/odin-scp"
81
+ "${HOME}/.kilocode/skills/odin-scp"
82
+ "${HOME}/.openhands/skills/odin-scp"
83
+ "${HOME}/.pi/agent/skills/odin-scp"
84
+ "${HOME}/.zed/skills/odin-scp"
85
+ )
86
+
87
+ ADAPTERS=(
88
+ "${HOME}/.config/droid/prompts/odin-scp.md"
89
+ "${HOME}/.droid/prompts/odin-scp.md"
90
+ "${HOME}/.crush/commands/odin-scp.md"
91
+ )
92
+
93
+ read_targets_file() {
94
+ target_var="$1"
95
+ target_file="$2"
96
+
97
+ if [[ ! -f "$target_file" ]]; then
98
+ echo "missing targets file: $target_file" >&2
99
+ exit 1
100
+ fi
101
+
102
+ eval "$target_var=()"
103
+ while IFS= read -r line || [[ -n "$line" ]]; do
104
+ case "$line" in
105
+ ""|\#*) continue ;;
106
+ ~/*) line="${HOME}/${line#~/}" ;;
107
+ esac
108
+ eval "$target_var+=(\"\$line\")"
109
+ done < "$target_file"
110
+ }
111
+
112
+ if [[ -n "${SCP_SKILL_TARGETS_FILE:-}" ]]; then
113
+ read_targets_file TARGETS "$SCP_SKILL_TARGETS_FILE"
114
+ fi
115
+
116
+ if [[ -n "${SCP_ADAPTER_TARGETS_FILE:-}" ]]; then
117
+ read_targets_file ADAPTERS "$SCP_ADAPTER_TARGETS_FILE"
118
+ fi
119
+
120
+ MARKERS=(
121
+ "SCP_BOOT_RECEIPT"
122
+ "SCP-TEAM-MANIFEST"
123
+ "self-bootstrap"
124
+ "terminal_locator"
125
+ "vt_state_snapshot"
126
+ "terminal_instance_ref"
127
+ "active_screen"
128
+ "cursor_x"
129
+ "cursor_y"
130
+ "scrollback_rows"
131
+ "render_dirty"
132
+ "workspace_ref"
133
+ "workspace_id"
134
+ "pane_ref"
135
+ "pane_id"
136
+ "surface_ref"
137
+ "surface_id"
138
+ "authority_layer"
139
+ "may_implement"
140
+ "worker_exception_authority"
141
+ "control-plane non-implementation"
142
+ "[SCP-DELEGATE]"
143
+ "[SCP-TERMINAL-DELIVERY]"
144
+ "[SCP-CMUX-DELIVERY]"
145
+ "[SCP-COORDINATION]"
146
+ "[SCP-FINISH]"
147
+ "\$odin-scp --finish"
148
+ "HOOK-EXCEPTION"
149
+ "BLOCKED_BY_LIMIT"
150
+ "post-run hygiene reset"
151
+ "active canonical SCP skill directory"
152
+ )
153
+
154
+ if [[ ! -f "$MASTER/SKILL.md" ]]; then
155
+ echo "missing master SKILL.md: $MASTER/SKILL.md" >&2
156
+ exit 1
157
+ fi
158
+
159
+ for marker in "${MARKERS[@]}"; do
160
+ grep -Fq "$marker" "$MASTER/SKILL.md" || {
161
+ echo "missing marker in master SKILL.md: $marker" >&2
162
+ exit 1
163
+ }
164
+ done
165
+
166
+ for adapter in "${ADAPTERS[@]}"; do
167
+ if [[ ! -f "$adapter" ]]; then
168
+ echo "missing adapter: $adapter" >&2
169
+ exit 1
170
+ fi
171
+ for marker in "${MARKERS[@]}"; do
172
+ grep -Fq "$marker" "$adapter" || {
173
+ echo "missing marker in adapter $adapter: $marker" >&2
174
+ exit 1
175
+ }
176
+ done
177
+ done
178
+
179
+ rsync_args=(-a --delete)
180
+ if [[ "$DRY_RUN" == true ]]; then
181
+ rsync_args+=(--dry-run)
182
+ fi
183
+
184
+ if [[ "$VERIFY_ONLY" == false ]]; then
185
+ for target in "${TARGETS[@]}"; do
186
+ mkdir -p "$target"
187
+ if [[ "$DRY_RUN" == true ]]; then
188
+ emit "DRY-RUN target: $target"
189
+ rsync "${rsync_args[@]}" "$MASTER/" "$target/" | while IFS= read -r line; do
190
+ emit " $line"
191
+ done
192
+ else
193
+ rsync "${rsync_args[@]}" "$MASTER/" "$target/"
194
+ fi
195
+ done
196
+ fi
197
+
198
+ master_hash="$(shasum -a 256 "$MASTER/SKILL.md" | awk '{print $1}')"
199
+ hash_mismatch=false
200
+ for target in "${TARGETS[@]}"; do
201
+ if [[ ! -f "$target/SKILL.md" ]]; then
202
+ emit "missing target SKILL.md: $target/SKILL.md"
203
+ hash_mismatch=true
204
+ continue
205
+ fi
206
+ target_hash="$(shasum -a 256 "$target/SKILL.md" | awk '{print $1}')"
207
+ if [[ "$target_hash" != "$master_hash" ]]; then
208
+ emit "hash mismatch: $target/SKILL.md"
209
+ emit " master=$master_hash target=$target_hash"
210
+ hash_mismatch=true
211
+ fi
212
+ done
213
+
214
+ if [[ "$hash_mismatch" == true && "$DRY_RUN" == false ]]; then
215
+ exit 1
216
+ fi
217
+
218
+ mode="sync"
219
+ if [[ "$VERIFY_ONLY" == true ]]; then
220
+ mode="verify-only"
221
+ elif [[ "$DRY_RUN" == true ]]; then
222
+ mode="dry-run"
223
+ fi
224
+
225
+ emit "SCP skill sync verified"
226
+ emit "mode: $mode"
227
+ emit "master: $MASTER"
228
+ emit "skill_sha256: $master_hash"
229
+ emit "native_targets: ${#TARGETS[@]}"
230
+ emit "adapter_targets: ${#ADAPTERS[@]}"
231
+ if [[ -n "$REPORT_PATH" ]]; then
232
+ emit "report: $REPORT_PATH"
233
+ fi
package/protocol/SCP.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # ODIN Sentinel Coordination Protocol
2
2
 
3
- Version: 0.4.11
3
+ Version: 0.4.13
4
4
 
5
- SCP_PUBLIC_VERSION: 0.4.11
5
+ SCP_PUBLIC_VERSION: 0.4.13
6
6
  MIN_COMPATIBLE_CHILD_MCP: 0.4.5
7
7
 
8
8
  ODIN Sentinel is a portable coordination layer for visible multi-agent teams.
@@ -74,7 +74,7 @@ inference credentials (`BLOCKED_BY_API_KEY` / `AUTH_PROVIDER_BLOCKED` / `BLOCKED
74
74
  inference stalls (`MODEL_STALLED` / `MODEL_REASONING_ONLY` / `STREAMING_PROTOCOL_MISMATCH`) before
75
75
  launch. A harness without MCP, native SCP skill, or full injected protocol text is
76
76
  `NON_GOVERNED_ONE_SHOT_ONLY` and must not hold a persistent governed role. Skill-capable harnesses
77
- should install the sentinel-coordination-protocol skill before governed launch. Probe via
77
+ should install the odin-scp skill before governed launch. Probe via
78
78
  `odin.get_harness_probe_matrix` with zero-secret output. Droid exposes `droid mcp` and
79
79
  `--auto <low|medium|high>`: read-only `droid exec` is allowed without write authority, but mission
80
80
  or high-autonomy work requires `--auto high`. Crush has no MCP management command and its auth-header
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: sentinel-coordination-protocol
2
+ name: odin-scp
3
3
  description: "Operate and improve SCP governance for multi-agent teams: self-bootstrap and teardown of federated pods, generic role topology, TEAM PM / TEAM ODIN separation, minimal bootstrap receipts, terminal locator identity, control-plane non-implementation, delegation receipts, terminal/CMUX delivery proof and verdicts, heartbeat cadence, branch-visible claims, adversarial QA, finish audit, and safe skill dissemination. Use when introducing SCP v3.5; installing SCP skills/adapters for Codex, Claude Code, OpenCode, Droid, Crush, OpenHands, Goose, KiloCode, Cursor, Zed, Pi, or other local coding agents; assigning EXEC/TEAM/WORKER roles; or preventing premature activation from an uncommitted draft artifact."
4
4
  version: 3.6.1
5
5
  updated: 2026-05-11
@@ -7,7 +7,7 @@ updated: 2026-05-11
7
7
 
8
8
  # Sentinel Coordination Protocol
9
9
 
10
- SCP_PUBLIC_VERSION: 0.4.11
10
+ SCP_PUBLIC_VERSION: 0.4.13
11
11
  MIN_COMPATIBLE_CHILD_MCP: 0.4.5
12
12
 
13
13
  Public install readiness: configure the ODIN MCP server, install native skill context where supported or use full prompt fallback, keep governed team roles in CMUX, verify auth/account readiness without printing secrets, smoke-test local inference if used, and validate role compatibility before launch. Private local skill copies may differ intentionally; public release checks compare repo-internal public artifacts only.
@@ -20,6 +20,8 @@ Master editable source:
20
20
 
21
21
  - the repository-distributed SCP protocol bundle, or an operator-declared canonical SCP skill source outside this public package.
22
22
 
23
+ The active canonical SCP skill directory is the directory that contains this `SKILL.md` plus its `references/`, `agents/`, and `scripts/` support files.
24
+
23
25
  All installed copies are synchronized runtime snapshots, not independent policy forks. Any agent modifying SCP policy must edit the declared source first, then propagate the full skill/protocol bundle to the installed harness targets and verify matching hashes.
24
26
 
25
27
  Use the operator-declared sync procedure after edits. Do not hand-edit generated runtime copies except as a temporary emergency patch that is immediately backported to the declared source and resynced.
@@ -64,7 +66,7 @@ SCP is a standing control loop, not a one-time boot banner. Read or re-invoke th
64
66
  - before QA activation or QA verdict language,
65
67
  - before any claim, lifecycle mutation, commit, push, or finish report,
66
68
  - when a hook, validator, permission mode, quota limit, dirty state, or branch mismatch appears,
67
- - when `$sentinel-coordination-protocol --finish` or `$sentinel-coordination-protocol --session-closeout` is invoked.
69
+ - when `$odin-scp --finish` or `$odin-scp --session-closeout` is invoked.
68
70
 
69
71
  If an agent cannot state its current SCP role, authority layer, `may_implement`, `may_qa_accept`, reports-to chain, and next receipt type, it must stop and re-emit `SCP_BOOT_RECEIPT`.
70
72
 
@@ -540,7 +542,7 @@ role_model_fallback_ladders:
540
542
  - model: Claude Opus
541
543
  harnesses: [claude]
542
544
  reasoning: high
543
- condition: Brad_authorized_high_risk_exception_only
545
+ condition: operator_authorized_high_risk_exception_only
544
546
 
545
547
  QUEUE_TRIAGE:
546
548
  - model: Kimi K2.6
@@ -561,7 +563,7 @@ model_mix_policy:
561
563
  scarce_quota_pools:
562
564
  - chatgpt_codex
563
565
  - claude_code
564
- locally_disallowed_without_brad_reauth:
566
+ locally_disallowed_without_operator_reauth:
565
567
  - gemini
566
568
  hidden_subagents_allowed: false
567
569
  role_slot_closure_allowed: false
@@ -626,7 +628,7 @@ Some harnesses, especially Claude Code, may enter plan mode or pause for approva
626
628
 
627
629
  Teardown sequence:
628
630
 
629
- 1. Broadcast `$sentinel-coordination-protocol --finish`.
631
+ 1. Broadcast `$odin-scp --finish`.
630
632
  2. Collect `[SCP-FINISH]`, snapshots, handoffs, dirty state, and blocker state.
631
633
  3. Snapshot official topology before cleanup, classify each surface as official role slot vs temporary/ad hoc, and list any proposed closures.
632
634
  4. Run post-run hygiene and cleanup QA.
@@ -1035,7 +1037,7 @@ Required fields:
1035
1037
  - `scope`
1036
1038
  - `duration_or_expiry`
1037
1039
  - `risk_if_not_added`
1038
- - `brad_authorization_required: true`
1040
+ - `operator_authorization_required: true`
1039
1041
 
1040
1042
  ### `[SCP-EXCEPTION]`
1041
1043
 
@@ -1097,14 +1099,14 @@ Required fields:
1097
1099
  - `confidence_downgrade`
1098
1100
  - `corrective_actions`
1099
1101
  - `unresolved_risks`
1100
- - `brad_decisions_needed`
1102
+ - `operator_decisions_needed`
1101
1103
  - `final_claim_allowed: true|false`
1102
1104
 
1103
1105
  Exceptions do not implicitly authorize implementation, QA acceptance, evidence writing, push, merge, cleanup, lifecycle mutation, closure, or finish claims unless those actions are explicitly named.
1104
1106
 
1105
1107
  ## Session Closeout Metrics And Improvement Lifecycle
1106
1108
 
1107
- Session closeout is an explicit SCP lifecycle phase. It begins when objectives are achieved or intentionally paused, branch/repo state is clean or classified, QA/quality gates are complete or blocked with owner, next-session path is clear, and `EXEC PM` is ready to hand off. the user may also trigger closeout with `$sentinel-coordination-protocol --finish` or `$sentinel-coordination-protocol --session-closeout`.
1109
+ Session closeout is an explicit SCP lifecycle phase. It begins when objectives are achieved or intentionally paused, branch/repo state is clean or classified, QA/quality gates are complete or blocked with owner, next-session path is clear, and `EXEC PM` is ready to hand off. the user may also trigger closeout with `$odin-scp --finish` or `$odin-scp --session-closeout`.
1108
1110
 
1109
1111
  At bootstrap, `EXEC PM` must record a `SESSION_OBJECTIVES` contract before broad dispatch:
1110
1112
 
@@ -1174,7 +1176,7 @@ Skill edits are the last closeout action after session data, `EXEC_PM_SESSION_RE
1174
1176
 
1175
1177
  ### `[SCP-FINISH]`
1176
1178
 
1177
- Emit when `$sentinel-coordination-protocol --finish` is invoked or relayed:
1179
+ Emit when `$odin-scp --finish` is invoked or relayed:
1178
1180
 
1179
1181
  - `final_state`
1180
1182
  - `pushed_commits`
@@ -1288,7 +1290,7 @@ Provider/token-pool metrics must record provider, token pool, raw tokens, token
1288
1290
 
1289
1291
  ## Finish And Self-Improvement Loop
1290
1292
 
1291
- `$sentinel-coordination-protocol --finish` starts controlled closeout, not product work.
1293
+ `$odin-scp --finish` starts controlled closeout, not product work.
1292
1294
 
1293
1295
  Close-out is not just cleanup. Close-out must prove the coordination process itself was followed, and must diagnose any agent that failed to deliver what it was told to deliver before declaring the run governed or complete.
1294
1296
 
@@ -1373,7 +1375,7 @@ Allowed pre-acceptance states:
1373
1375
  - `ROLE_SLOT_CLOSURE_VIOLATION`: role-named pane/surface was closed or deleted without explicit the user authorization.
1374
1376
  - `MODEL_MIX_VIOLATION`: active model/harness assignment violates the declared model mix policy.
1375
1377
  - `TOPOLOGY_EXPANSION_REQUESTED`: new role slot, pane, pod, floater, or specialized model/harness has been requested and awaits the user decision.
1376
- - `TOPOLOGY_EXPANSION_BLOCKED_PENDING_BRAD`: topology expansion is blocked until the user explicitly authorizes it.
1378
+ - `TOPOLOGY_EXPANSION_BLOCKED_PENDING_OPERATOR`: topology expansion is blocked until the user explicitly authorizes it.
1377
1379
 
1378
1380
  If repo mechanics require moving a DEV slice to `done/` before independent QA, the handoff and ledger must say `DEV_COMPLETE_QA_PENDING`; it is not lifecycle closure.
1379
1381
 
@@ -1442,7 +1444,7 @@ Before implementation, QA acceptance, or ACTIVE_WATCH work, an activated role mu
1442
1444
 
1443
1445
  ## Harness Readiness Probes
1444
1446
 
1445
- Installed is not provisioned. Probe harnesses before governed launch and record multi-dimensional readiness (`installed_binary`, `authenticated`, `mcp_configured`, `mcp_tool_hydration`, `governed_role_ready`) via `odin.get_harness_probe_matrix`. Classify permission, login, API-key/auth, and local-inference stalls before assigning roles. A harness lacking MCP, native SCP skill, or full injected protocol text is `NON_GOVERNED_ONE_SHOT_ONLY` and must not hold a persistent governed role. Skill-capable harnesses should install the sentinel-coordination-protocol skill before governed launch. Droid: read-only `droid exec` needs no write authority, but mission/high-autonomy requires `--auto high`, and `droid mcp` is required for governed readiness. Crush: no MCP management command (`MCP_UNAVAILABLE`) and auth-header failures (`unauthorized: Authentication parameter not received in Header`) are auth blockers.
1447
+ Installed is not provisioned. Probe harnesses before governed launch and record multi-dimensional readiness (`installed_binary`, `authenticated`, `mcp_configured`, `mcp_tool_hydration`, `governed_role_ready`) via `odin.get_harness_probe_matrix`. Classify permission, login, API-key/auth, and local-inference stalls before assigning roles. A harness lacking MCP, native SCP skill, or full injected protocol text is `NON_GOVERNED_ONE_SHOT_ONLY` and must not hold a persistent governed role. Skill-capable harnesses should install the odin-scp skill before governed launch. Droid: read-only `droid exec` needs no write authority, but mission/high-autonomy requires `--auto high`, and `droid mcp` is required for governed readiness. Crush: no MCP management command (`MCP_UNAVAILABLE`) and auth-header failures (`unauthorized: Authentication parameter not received in Header`) are auth blockers.
1446
1448
 
1447
1449
  ## Core Workflow
1448
1450
 
@@ -1506,4 +1508,11 @@ This recursion is why the same protocol governs both code work and organizationa
1506
1508
  - `references/boot-receipt-examples.md`: canonical `SCP_BOOT_RECEIPT` examples for `EXEC PM`, `TEAM ODIN`, `DEV WORKER`, and `QA WORKER`.
1507
1509
  - `references/team-bootstrap-runbook.md`: terminal/CMUX self-bootstrap, harness launch, pod setup, teardown, and hygiene runbook for one-pane-to-many-pod operation.
1508
1510
 
1511
+ MCP-only or non-native harnesses can load the same material from:
1512
+
1513
+ - `odin://protocol/skill-references/canonical-introduction-prompt`
1514
+ - `odin://protocol/skill-references/harness-skill-targets`
1515
+ - `odin://protocol/skill-references/boot-receipt-examples`
1516
+ - `odin://protocol/skill-references/team-bootstrap-runbook`
1517
+
1509
1518
  Load the prompt reference when the user asks for the official SCP introduction prompt or asks the `EXEC PM` pane to implement/disseminate SCP.