@bradheitmann/odin-sentinel 0.4.4 → 0.4.6

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 (57) hide show
  1. package/AGENTS.md +64 -0
  2. package/CLAUDE.md +43 -0
  3. package/README.md +102 -335
  4. package/dist/src/mcp/server.js +43 -12
  5. package/dist/src/mcp/server.js.map +1 -1
  6. package/dist/src/protocol/schemas.d.ts +2529 -4
  7. package/dist/src/protocol/schemas.js +214 -18
  8. package/dist/src/protocol/schemas.js.map +1 -1
  9. package/dist/src/protocol/service.d.ts +96 -2
  10. package/dist/src/protocol/service.js +516 -4
  11. package/dist/src/protocol/service.js.map +1 -1
  12. package/dist/src/protocol/surface-layout.d.ts +40 -1
  13. package/dist/src/protocol/surface-layout.js +98 -1
  14. package/dist/src/protocol/surface-layout.js.map +1 -1
  15. package/dist/src/protocol/validators.d.ts +3 -0
  16. package/dist/src/protocol/validators.js +28 -0
  17. package/dist/src/protocol/validators.js.map +1 -1
  18. package/dist/src/protocol/version.d.ts +3 -0
  19. package/dist/src/protocol/version.js +3 -0
  20. package/dist/src/protocol/version.js.map +1 -1
  21. package/dist/src/telemetry/config.d.ts +8 -0
  22. package/dist/src/telemetry/config.js +24 -0
  23. package/dist/src/telemetry/config.js.map +1 -1
  24. package/dist/src/telemetry/index.d.ts +5 -5
  25. package/dist/src/telemetry/index.js +3 -3
  26. package/dist/src/telemetry/index.js.map +1 -1
  27. package/dist/src/telemetry/redactor.js +25 -7
  28. package/dist/src/telemetry/redactor.js.map +1 -1
  29. package/dist/src/telemetry/report.d.ts +108 -0
  30. package/dist/src/telemetry/report.js +83 -3
  31. package/dist/src/telemetry/report.js.map +1 -1
  32. package/dist/src/telemetry/submit.d.ts +2 -0
  33. package/dist/src/telemetry/submit.js +79 -6
  34. package/dist/src/telemetry/submit.js.map +1 -1
  35. package/docs/guides/quick-start.md +112 -44
  36. package/docs/guides/quickstart-prompts.md +65 -0
  37. package/docs/guides/recommended-starter-team.md +45 -27
  38. package/docs/reference/client-compatibility.md +20 -43
  39. package/docs/reference/cost-and-privacy.md +26 -23
  40. package/docs/reference/distribution.md +40 -55
  41. package/docs/reference/public-surface-audit.md +35 -114
  42. package/package.json +19 -4
  43. package/protocol/SCP.md +8 -1
  44. package/protocol/bootstrap-skill.md +16 -11
  45. package/protocol/closeout.yaml +7 -1
  46. package/protocol/delegation.yaml +1 -1
  47. package/protocol/model-profiles.yaml +55 -1
  48. package/protocol/receipts/boot-receipt.yaml +42 -0
  49. package/protocol/receipts/team-manifest.yaml +41 -0
  50. package/protocol/roles.yaml +69 -1
  51. package/protocol/topology.yaml +78 -36
  52. package/scripts/audit/public-surface.mjs +48 -19
  53. package/scripts/audit/verify-pack.mjs +294 -27
  54. package/templates/dev-slice-template.md +56 -0
  55. package/templates/pm-role-template.md +61 -0
  56. package/templates/qa-slice-template.md +46 -0
  57. package/templates/team-manifest-template.yaml +163 -0
@@ -7,19 +7,24 @@ updated: 2026-05-11
7
7
 
8
8
  # Sentinel Coordination Protocol
9
9
 
10
+ SCP_PUBLIC_VERSION: 0.4.6
11
+ MIN_COMPATIBLE_CHILD_MCP: 0.4.5
12
+
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.
14
+
10
15
  Use this skill for SCP policy introduction, repo landing, adoption-gate proof, controlled dissemination, active multi-agent control loops, and automated team lifecycle management. SCP is a governance layer for multi-team agent operation; it complements other coordination layers and `AGENTS.md` files where present. It sits above them after activation.
11
16
 
12
17
  ## Source Of Truth
13
18
 
14
19
  Master editable source:
15
20
 
16
- - the active canonical SCP skill directory for the local installation, normally `~/.agents/skills/sentinel-coordination-protocol/`.
21
+ - the repository-distributed SCP protocol bundle, or an operator-declared canonical SCP skill source outside this public package.
17
22
 
18
- All other installed copies are synchronized runtime snapshots, not independent policy forks. Any agent modifying this skill must edit the master first, then propagate the full skill directory to the installed harness targets and verify matching hashes.
23
+ 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.
19
24
 
20
- Use `scripts/sync-installations.sh` from the master directory after edits. Do not hand-edit a runtime copy under `~/.codex`, `~/.claude`, `~/.config/goose`, `~/.config/opencode`, `~/.opencode`, `~/.crush`, `~/.cursor`, `~/.kilocode`, `~/.openhands`, `~/.pi`, or `~/.zed` except as a temporary emergency patch that is immediately backported to the master and resynced.
25
+ 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.
21
26
 
22
- Portable curated skill/session records may live under the skill directory, for example `decisions/YYYY-MM-DD-<slug>.md` and optionally `CHANGELOG.md`. Raw evidence belongs under `.odin/local/audit/<session-id>/` or the declared `evidence_path`. Do not create empty folders just to satisfy policy; create `decisions/` only when writing the first curated decision record.
27
+ Portable curated skill/session records may live under the declared source, for example `decisions/YYYY-MM-DD-<slug>.md` and optionally `CHANGELOG.md`. Raw audit evidence belongs under `.odin/audit/<session-id>/` or the declared `evidence_path`. Do not create empty folders just to satisfy policy; create `decisions/` only when writing the first curated decision record.
23
28
 
24
29
  ## Non-Negotiables
25
30
 
@@ -267,7 +272,7 @@ Team PMs and team ODINs may coordinate laterally when needed, but lateral messag
267
272
 
268
273
  ODINs must establish a lateral ODIN mesh at bootstrap. `A/EXEC-ODIN` and each `TEAM ODIN` must exchange a short introduction containing role, team, reports-to/coordinates-with chain, team composition, active agent occupants, model/harness/cost tier, known blockers, and next poll time. This is a meta-communication layer, not command authority.
269
274
 
270
- During active execution, `A/EXEC-ODIN` should run an ODIN round-robin health pass on a declared cadence, default 10 minutes unless the user or `EXEC PM` sets another cadence. The executive ODIN starts with its own executive-office health note, sends it to the first team ODIN, and instructs each team ODIN to append its short team composition/status/health note and forward to the next ODIN. The final team ODIN returns the appended packet to `A/EXEC-ODIN`. `A/EXEC-ODIN` compiles the packet, may ask `EXEC DISPATCH` / `SWITCHBOARD` for outstanding communication or waiting-agent notes, then sends a concise status report to `EXEC PM`.
275
+ During active execution, `A/EXEC-ODIN` should run an ODIN round-robin health pass on a declared cadence, default 30 seconds unless the user or `EXEC PM` sets another cadence. The executive ODIN starts with its own executive-office health note, sends it to the first team ODIN, and instructs each team ODIN to append its short team composition/status/health note and forward to the next ODIN. The final team ODIN returns the appended packet to `A/EXEC-ODIN`. `A/EXEC-ODIN` compiles the packet, may ask `EXEC DISPATCH` / `SWITCHBOARD` for outstanding communication or waiting-agent notes, then sends a concise status report to `EXEC PM`.
271
276
 
272
277
  ODIN mesh reports must stay short by default and include: team, active occupants, provider/model/harness mix, blocked agents, permission waits, plan-mode/quota/provider failures, role breaches, delivery failures, outstanding relays, and recommended intervention. ODINs may request temporary secondment of another control-plane agent through `EXEC PM` when a PM/ODIN lane fails, but they must not directly reassign agents or expand topology without authorization.
273
278
 
@@ -660,7 +665,7 @@ If a control-plane pane begins product/source/test implementation, authors worke
660
665
 
661
666
  Editing canonical skills, adapters, runtime skill copies, sync scripts, lifecycle ledgers, branch state, or policy text is a control-plane governance mutation and requires `[SCP-CONTROL-PLANE-MUTATION]` before or with the mutation. ODIN/control-plane roles must not self-accept governance mutations they authored. Acceptance requires independent QA, user ratification, or explicitly named `EXEC PM` ratification after evidence review. An authorized control-plane mutation may be reported as implemented and validation complete, but remains pending ratification until the named ratifier accepts the evidence.
662
667
 
663
- Canonical SCP audit, research, ODIN, and control-plane outputs must be written under a durable governance path such as `.odin/local/audit/<audit-id>/` or another declared `evidence_path`. `/tmp` may be used for intermediate captures, cache, delivery-proof repair, or mirrors only. Before `[SCP-FINISH]`, any `/tmp` artifact used for a claim must be copied, summarized, hashed, or explicitly declared non-canonical in the durable audit ledger.
668
+ Canonical SCP audit, research, ODIN, and control-plane outputs must be written under a durable governance path such as `.odin/audit/<audit-id>/` or another declared `evidence_path`. `/tmp` may be used for intermediate captures, cache, delivery-proof repair, or mirrors only. Before `[SCP-FINISH]`, any `/tmp` artifact used for a claim must be copied, summarized, hashed, or explicitly declared non-canonical in the durable audit ledger.
664
669
 
665
670
  `repo_clean` must not be used as shorthand for `governance_clean`. Governance-surface mutations outside the active repository require separate reporting: `external_skill_paths_touched`, `runtime_targets`, `hash_before_after_or_current_hash`, `sync_log_path`, `validation_command`, and `unsynced_or_dirty_runtime_paths`. A clean git worktree proves only the repository checkout state. It does not prove canonical skill, Codex skill, Claude skill, adapter, CMUX runtime, or `/tmp` artifact state.
666
671
 
@@ -694,7 +699,7 @@ Continuing past a HALT without remediation is itself a protocol breach. ODIN mus
694
699
 
695
700
  ### Health Escalation
696
701
 
697
- The ODIN mesh runs round-robin health checks per `odin_mesh.health_round_robin_minutes` (default 10). Per-agent escalation ladder:
702
+ The ODIN mesh runs round-robin health checks per `odin_mesh.health_round_robin_seconds` (default 30). Per-agent escalation ladder:
698
703
 
699
704
  - **1 missed heartbeat** — warn the affected agent.
700
705
  - **2 missed heartbeats** — escalate to `A/EXEC-ODIN` via the mesh aggregator.
@@ -1410,7 +1415,7 @@ git diff --cached --name-status
1410
1415
 
1411
1416
  If upstream is not the declared branch authority, stop before mutation. If `HEAD` and `@{u}` differ for a branch-visible closure claim, stop before mutation.
1412
1417
 
1413
- If excluded or out-of-scope debris appears, especially `project/planning/story-reviews/**`, runtime logs, holdout paths, design artifacts, external memory paths, or non-branchable paths, stop and require `EXEC PM` classification before lifecycle mutation or evidence verdict.
1418
+ If excluded or out-of-scope debris appears, especially private story-review planning paths, runtime logs, holdout paths, design artifacts, external memory paths, or non-branchable paths, stop and require `EXEC PM` classification before lifecycle mutation or evidence verdict.
1414
1419
 
1415
1420
  Before any `status: Done`, `PHASE: VERIFIED`, `VERDICT: PASS`, active-to-done move, commit, or push, run the slice/evidence validators required by the dispatch. At minimum for slice/evidence work:
1416
1421
 
@@ -1432,14 +1437,14 @@ If a closure/evidence hook fails after a lifecycle move or verdict attempt, mark
1432
1437
  - Read `00-SCP-protocol.md`, especially sections 0, 6, 7, 8, 10, 18, and 20.
1433
1438
 
1434
1439
  2. Land the package, but do not activate it.
1435
- - Canonical package path: `project/planning/org/agentic-executive-mgmt/`.
1440
+ - Canonical package path: the operator-declared governance planning package path.
1436
1441
  - Package landing branch: use a deterministic ops branch unless the user supplies another branch.
1437
1442
  - Ledger branch: `ops/ledger` for `ledger.yaml`.
1438
1443
  - If branch topology is ambiguous or conflicts with current repo state, stop and ask the user.
1439
1444
 
1440
1445
  3. Create adoption-gate scaffolding.
1441
- - `project/planning/org/agentic-executive-mgmt/artifacts/adoption/adoption-gate.md`
1442
- - `project/planning/org/agentic-executive-mgmt/ledger.yaml`
1446
+ - governance adoption gate artifact
1447
+ - governance ledger artifact
1443
1448
  - `tools/agentic-executive-mgmt/audit/banned-phrases.txt`
1444
1449
  - `tools/agentic-executive-mgmt/qa-review/RUBRIC.md`
1445
1450
  - Other artifact directories required by the SCP package.
@@ -1,4 +1,10 @@
1
- version: 0.2.1
1
+ version: 0.4.6
2
+ active_watch_terminal_states:
3
+ - RELEASED_BY_OPERATOR
4
+ - HANDED_OFF
5
+ - PARKED_IDLE
6
+ - FAILED
7
+ - WATCH_UNSUPPORTED
2
8
  modes:
3
9
  PARK_FOR_CONTINUITY:
4
10
  description: Keep role slots open, park occupants, save handoffs, and preserve continuity.
@@ -1,4 +1,4 @@
1
- version: 0.3.0
1
+ version: 0.4.6
2
2
  delegation_contract:
3
3
  required_fields:
4
4
  - receipt_type
@@ -1,7 +1,61 @@
1
- version: 0.2.1
1
+ version: 0.4.6
2
2
  policy:
3
3
  semantics: Recommended starter profiles, not bundled dependencies or availability guarantees.
4
4
  runtime_requirement: Users must install and configure their own harnesses. Launchers must verify local harness/model availability before dispatch and apply fallbacks when unavailable.
5
+ governed_launch_probe_required: true
6
+ visible_output_timeout_seconds_default: 60
7
+ provisioning_prompt: Are all intended harnesses provisioned with accounts, plans, API keys, or local inference credentials so they will not malfunction when spun up?
8
+ zero_secret_output: true
9
+ secret_provider_status_only:
10
+ - Doppler
11
+ - 1Password CLI (op)
12
+ - environment variable names
13
+ - direnv
14
+ - mise
15
+ - dotenv-style file presence
16
+ - GitHub auth
17
+ - local provider config files
18
+ model_responsiveness_statuses:
19
+ - MODEL_READY
20
+ - MODEL_SLOW
21
+ - MODEL_STALLED
22
+ - MODEL_REASONING_ONLY
23
+ - STREAMING_PROTOCOL_MISMATCH
24
+ - MODEL_UNREACHABLE
25
+ harness_capabilities:
26
+ Codex:
27
+ can_hydrate_deferred_mcp_tools_at_boot: true
28
+ native_skill_invocation: true
29
+ scp_skill_recommended: true
30
+ Claude Code:
31
+ can_hydrate_deferred_mcp_tools_at_boot: true
32
+ native_skill_invocation: true
33
+ scp_skill_recommended: true
34
+ Droid:
35
+ can_hydrate_deferred_mcp_tools_at_boot: true
36
+ native_skill_invocation: false
37
+ scp_skill_recommended: false
38
+ Goose:
39
+ local_inference_smoke_test_required: true
40
+ visible_content_required_within_seconds: 60
41
+ reasoning_content_only_class: MODEL_REASONING_ONLY
42
+ streaming_mismatch_class: STREAMING_PROTOCOL_MISMATCH
43
+ Crush:
44
+ permission_prompt_class: BLOCKED_BY_PERMISSION
45
+ OpenHands:
46
+ missing_inference_credentials_class: BLOCKED_BY_API_KEY
47
+ provider_config_blocker_class: AUTH_PROVIDER_BLOCKED
48
+ KiloCode:
49
+ login_commands:
50
+ - kilo auth login
51
+ - /connect
52
+ login_blocker_class: BLOCKED_BY_LOGIN
53
+ Pi:
54
+ role_compatibility_failure_class: ROLE_COMPATIBILITY_FAILED
55
+ Aider:
56
+ auth_probe_required: true
57
+ NanoCoder:
58
+ auth_probe_required: true
5
59
  profiles:
6
60
  A/EXEC-PM:
7
61
  model: GPT-5.5-class frontier reasoning model
@@ -13,6 +13,42 @@ required_fields:
13
13
  - write_scope
14
14
  - evidence_path
15
15
  - current_task
16
+ receipt_types:
17
+ - SCP_BOOT_RECEIPT
18
+ - SCP_MIN_BOOT_RECEIPT
19
+ minimum_compatible_mcp_version: 0.4.5
20
+ field_types:
21
+ role: string
22
+ authority_layer: string
23
+ team: string
24
+ terminal_locator: string
25
+ branch: string
26
+ cwd: string
27
+ model_harness: string
28
+ permission_mode: string
29
+ may_implement: boolean
30
+ may_qa_accept: boolean
31
+ reports_to: string
32
+ write_scope: string_array
33
+ evidence_path: string
34
+ current_task: string
35
+ write_scope_policy:
36
+ empty_array_valid_for:
37
+ - no current write assignment
38
+ - may_implement false roles
39
+ - DEV roles in BOOTSTRAPPED_IDLE before assignment
40
+ null_policy: invalid; use [] for unassigned scope
41
+ allowed_lifecycle_states:
42
+ - SURFACE_PROVISIONED
43
+ - BOOTSTRAPPED_IDLE
44
+ - ACTIVE_WATCH
45
+ - VACANT_ROLE_SLOT
46
+ - AGENT_SUBSTITUTION_REQUIRED
47
+ - RELEASED_BY_OPERATOR
48
+ - HANDED_OFF
49
+ - PARKED_IDLE
50
+ - FAILED
51
+ - WATCH_UNSUPPORTED
16
52
  recommended_fields:
17
53
  - upstream
18
54
  - head_sha
@@ -25,6 +61,12 @@ recommended_fields:
25
61
  - parent_surface_ref
26
62
  - column_index
27
63
  - team_letter
64
+ - lifecycle_state
65
+ - mcp_version
66
+ - scp_context_source
67
+ receipt_type_policy:
68
+ SCP_BOOT_RECEIPT: full governed occupant receipt after role/context/readiness are known
69
+ SCP_MIN_BOOT_RECEIPT: minimal bootstrap-only receipt for orientation or pre-dispatch identity proof
28
70
  staffing_audit:
29
71
  description: >-
30
72
  For any role outside the executive office (team != "A"), the boot receipt
@@ -7,3 +7,44 @@ required_fields:
7
7
  - model_profile
8
8
  - handoff_sources
9
9
  - startup_objectives
10
+ role_slot_schema:
11
+ required_fields:
12
+ - role_slot
13
+ - harness
14
+ - readiness_status
15
+ - layout_locator
16
+ - scp_context_source
17
+ layout_locator_fields:
18
+ - workspace
19
+ - pane
20
+ - surface
21
+ readiness_statuses:
22
+ - PASS
23
+ - FAIL
24
+ - WAIVED_BY_EXEC_PM
25
+ - SUBSTITUTION_APPROVED_BY_EXEC_PM
26
+ - NON_GOVERNED_ONE_SHOT_ONLY
27
+ - VACANT_ROLE_SLOT
28
+ watcher_assignments:
29
+ A/EXEC-ODIN:
30
+ watches:
31
+ - executive_office
32
+ - team_odins
33
+ - cross_team_drift
34
+ - missing_receipts
35
+ - stale_proof
36
+ TEAM_ODIN:
37
+ watches:
38
+ - own_team_pm
39
+ - own_dev_slots
40
+ - own_qa_slots
41
+ - own_shadow_slots
42
+ A/EXEC-ASST:
43
+ may_maintain:
44
+ - delivery_proof_ledger
45
+ - heartbeat_ledger
46
+ minimum_compatible_mcp_version: 0.4.5
47
+ scp_context_sources:
48
+ - native sentinel-coordination-protocol skill
49
+ - odin-sentinel MCP at or above minimum version
50
+ - full injected SCP protocol text
@@ -1,10 +1,13 @@
1
- version: 0.3.0
1
+ version: 0.4.6
2
2
  roles:
3
3
  EXEC_PM:
4
4
  title: EXEC PM
5
5
  layer: executive
6
6
  may_implement_default: false
7
7
  may_qa_accept_default: false
8
+ must_actively_watch: false
9
+ may_intervene: false
10
+ authority_layer: executive
8
11
  purpose: Intent, priority, authorization, escalation, and claim framing.
9
12
  authority:
10
13
  sole_staffing_authority:
@@ -38,6 +41,28 @@ roles:
38
41
  layer: meta_control
39
42
  may_implement_default: false
40
43
  may_qa_accept_default: false
44
+ must_actively_watch: true
45
+ may_intervene: true
46
+ authority_layer: meta_control
47
+ normal_successor_state_after_receipt: ACTIVE_WATCH
48
+ watch_contract:
49
+ default_poll_interval_seconds: 30
50
+ watch_warn_after_seconds: 300
51
+ stalled_after_seconds: 600
52
+ watches:
53
+ - executive_office_health
54
+ - team_odin_health
55
+ - cross_team_drift
56
+ - stale_proof
57
+ - blocked_panes
58
+ - context_exhaustion
59
+ - missing_receipts
60
+ may_inject_corrective_prompts: true
61
+ forbidden:
62
+ - implement product work
63
+ - QA-accept work
64
+ - route business priorities
65
+ - override EXEC PM launch/activation authority
41
66
  purpose: Governance health, polling, delivery proof, role boundaries, and closeout hygiene.
42
67
  authority:
43
68
  intervention_authority:
@@ -80,24 +105,36 @@ roles:
80
105
  layer: executive_support
81
106
  may_implement_default: false
82
107
  may_qa_accept_default: false
108
+ must_actively_watch: false
109
+ may_intervene: false
110
+ authority_layer: executive_support
83
111
  purpose: Ledger, reminders, pane inventory, artifact index, and delivery checks.
84
112
  EXEC_RSCH:
85
113
  title: EXEC RSCH
86
114
  layer: research
87
115
  may_implement_default: false
88
116
  may_qa_accept_default: false
117
+ must_actively_watch: false
118
+ may_intervene: false
119
+ authority_layer: research
89
120
  purpose: Read-only strategy, alternatives, context recovery, and risk analysis.
90
121
  EXEC_QA:
91
122
  title: EXEC QA
92
123
  layer: quality
93
124
  may_implement_default: false
94
125
  may_qa_accept_default: true
126
+ must_actively_watch: false
127
+ may_intervene: false
128
+ authority_layer: quality
95
129
  purpose: Independent adversarial audit of process, evidence, closure language, and drift.
96
130
  TEAM_PM:
97
131
  title: TEAM PM
98
132
  layer: pod_control
99
133
  may_implement_default: false
100
134
  may_qa_accept_default: false
135
+ must_actively_watch: false
136
+ may_intervene: false
137
+ authority_layer: pod_control
101
138
  purpose: Pod task routing, worker activation, and reporting.
102
139
  forbidden_actions:
103
140
  - spawn agents on own pod or any other pod
@@ -118,6 +155,28 @@ roles:
118
155
  layer: meta_control
119
156
  may_implement_default: false
120
157
  may_qa_accept_default: false
158
+ must_actively_watch: true
159
+ may_intervene: true
160
+ authority_layer: meta_control
161
+ normal_successor_state_after_receipt: ACTIVE_WATCH
162
+ watch_contract:
163
+ default_poll_interval_seconds: 30
164
+ watch_warn_after_seconds: 300
165
+ stalled_after_seconds: 600
166
+ watches:
167
+ - own_team_pm
168
+ - own_dev_slots
169
+ - own_qa_slots
170
+ - own_shadow_slots
171
+ reports_to:
172
+ - own TEAM PM
173
+ - A/EXEC-ODIN
174
+ may_inject_corrective_prompts: true
175
+ forbidden:
176
+ - implement product work
177
+ - QA-accept work
178
+ - route business priorities
179
+ - override EXEC PM launch/activation authority
121
180
  purpose: Pod health monitoring, polling, blockers, freezes, and lateral ODIN mesh awareness.
122
181
  authority:
123
182
  intervention_authority:
@@ -152,16 +211,25 @@ roles:
152
211
  layer: implementation
153
212
  may_implement_default: true
154
213
  may_qa_accept_default: false
214
+ must_actively_watch: false
215
+ may_intervene: false
216
+ authority_layer: implementation
155
217
  purpose: Bounded implementation inside exact write scope with evidence.
156
218
  QA_WORKER:
157
219
  title: QA WORKER
158
220
  layer: quality
159
221
  may_implement_default: false
160
222
  may_qa_accept_default: true
223
+ must_actively_watch: false
224
+ may_intervene: false
225
+ authority_layer: quality
161
226
  purpose: Independent verification of worker evidence and acceptance criteria.
162
227
  SHADOW_REVIEWER:
163
228
  title: SHADOW REVIEWER
164
229
  layer: review
165
230
  may_implement_default: false
166
231
  may_qa_accept_default: false
232
+ must_actively_watch: false
233
+ may_intervene: false
234
+ authority_layer: review
167
235
  purpose: Independent critique, risk surfacing, and second-pass review.
@@ -1,4 +1,4 @@
1
- version: 0.3.0
1
+ version: 0.4.6
2
2
  default_topology:
3
3
  executive_office:
4
4
  team: A
@@ -18,39 +18,81 @@ default_topology:
18
18
  fresh_repo_default_pods: 1
19
19
  odin_mesh:
20
20
  bootstrap_identity_exchange: true
21
- health_round_robin_minutes: 10
21
+ health_round_robin_seconds: 30
22
22
  aggregator: A/EXEC-ODIN
23
- surface_layout:
24
- description: >-
25
- Canonical CMUX surface layout rule for EXEC PM. Teams arrive as letters
26
- (Team A is executive; Team B onward are development pods). Columns are
27
- equal width. Surfaces stack vertically inside a column with at most two
28
- surfaces per column. Team A always occupies column 0. When the team count
29
- is odd and at least 3, column 0 holds only Team A (the "tall column").
30
- rules:
31
- max_surfaces_per_column: 2
32
- column_widths: equal
33
- exec_team_column: 0
34
- tall_column_when_odd_team: A
35
- custodianship:
36
- sole_custodian: A/EXEC-PM
37
- includes:
38
- - cmux new-split
39
- - cmux new-surface
40
- - cmux move-surface
41
- - cmux close-surface
42
- pre_staffing_gate: >-
43
- Before adding any agent beyond A/EXEC, EXEC PM must (1) call
44
- odin.compute_surface_layout for teamCount=N+1, (2) execute the splits
45
- required to reach that layout via cmux, (3) confirm each new surface
46
- is empty and addressable via cmux list-pane-surfaces, and only then
47
- (4) dispatch the spawn to the newly created surface.
48
- reference_layouts:
49
- teams_1: "[A]"
50
- teams_2: "[A] [B]"
51
- teams_3: "[A] [B/C]"
52
- teams_4: "[A/D] [B/C]"
53
- teams_5: "[A] [B/C] [D/E]"
54
- teams_6: "[A/F] [B/C] [D/E]"
55
- teams_7: "[A] [B/C] [D/E] [F/G]"
56
- teams_8: "[A/H] [B/C] [D/E] [F/G]"
23
+ launch_phases:
24
+ - SURFACE_PROVISIONED
25
+ - OCCUPANT_READINESS
26
+ - OCCUPANT_LAUNCH
27
+ - BOOT_RECEIPT_VALIDATION
28
+ - TEAM_ACTIVATION
29
+ - ACTIVE_WATCH
30
+ readiness_gate:
31
+ minimum_mcp_version: 0.4.5
32
+ cmux_required_for_governed_team: true
33
+ occupant_launch_allowed_when:
34
+ - PASS
35
+ - WAIVED_BY_EXEC_PM
36
+ - SUBSTITUTION_APPROVED_BY_EXEC_PM
37
+ team_activation_allowed_states:
38
+ - BOOTSTRAPPED_IDLE
39
+ - ACTIVE_WATCH
40
+ - VACANT_ROLE_SLOT
41
+ - AGENT_SUBSTITUTION_REQUIRED
42
+ safe_auth_failure_outcomes:
43
+ - choose a different harness
44
+ - receive setup guidance without pasting secrets
45
+ - mark slot VACANT_ROLE_SLOT
46
+ - request EXEC PM-approved substitution
47
+ surface_layout:
48
+ description: >-
49
+ Canonical CMUX surface layout rule for EXEC PM. Governed team bootstrap
50
+ uses human_cmux_quad by default: one CMUX workspace with four panes/regions
51
+ (executive office, Team B pod, Team C pod, blockers/status/intake).
52
+ Legacy columns remain available for compatibility but tab-only layout is
53
+ degraded unless explicitly approved.
54
+ canonical_profile: human_cmux_quad
55
+ human_cmux_quad:
56
+ workspace_policy: A/EXEC-PM remains in the same CMUX workspace as all governed teams
57
+ quadrants:
58
+ A: executive office
59
+ B: Team B pod
60
+ C: Team C pod
61
+ D: blockers/status/intake or overflow
62
+ empty_role_slots_before_launch: true
63
+ reject_tab_only_unless_degraded_mode_approved: true
64
+ reject_split_workspace_without_routing_proof: true
65
+ no_cmux_governed_status: NOT_GOVERNED_NO_CMUX
66
+ legacy_columns:
67
+ description: >-
68
+ Teams arrive as letters (Team A is executive; Team B onward are
69
+ development pods). Columns are equal width. Surfaces stack vertically
70
+ inside a column with at most two surfaces per column. Team A always
71
+ occupies column 0.
72
+ rules:
73
+ max_surfaces_per_column: 2
74
+ column_widths: equal
75
+ exec_team_column: 0
76
+ tall_column_when_odd_team: A
77
+ custodianship:
78
+ sole_custodian: A/EXEC-PM
79
+ includes:
80
+ - cmux new-split
81
+ - cmux new-surface
82
+ - cmux move-surface
83
+ - cmux close-surface
84
+ pre_staffing_gate: >-
85
+ Before adding any agent beyond A/EXEC, EXEC PM must (1) call
86
+ odin.compute_surface_layout for teamCount=N+1, (2) execute the splits
87
+ required to reach that layout via cmux, (3) confirm each new surface
88
+ is empty and addressable via cmux list-pane-surfaces, and only then
89
+ (4) dispatch the spawn to the newly created surface.
90
+ reference_layouts:
91
+ teams_1: "[A]"
92
+ teams_2: "[A] [B]"
93
+ teams_3: "[A] [B/C]"
94
+ teams_4: "[A/D] [B/C]"
95
+ teams_5: "[A] [B/C] [D/E]"
96
+ teams_6: "[A/F] [B/C] [D/E]"
97
+ teams_7: "[A] [B/C] [D/E] [F/G]"
98
+ teams_8: "[A/H] [B/C] [D/E] [F/G]"
@@ -1,6 +1,22 @@
1
1
  import { execFileSync } from "node:child_process";
2
2
  import { readdirSync, readFileSync, statSync } from "node:fs";
3
3
  import { join } from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+
6
+ const PUBLIC_ROOTS = [
7
+ "README.md",
8
+ "AGENTS.md",
9
+ "CLAUDE.md",
10
+ "LICENSE",
11
+ "package.json",
12
+ "docs/",
13
+ "protocol/",
14
+ "templates/",
15
+ "plugins/",
16
+ "scripts/audit/"
17
+ ];
18
+
19
+ const EXCLUDED_PREFIXES = [".git/", "dist/", "node_modules/", "project/" + "planning" + "/", "." + "edge-" + "agentic" + "/local/", "tests/"];
4
20
 
5
21
  function walk(dir) {
6
22
  return readdirSync(dir).flatMap((entry) => {
@@ -11,6 +27,11 @@ function walk(dir) {
11
27
  });
12
28
  }
13
29
 
30
+ export function isPublicAuditFile(file) {
31
+ if (EXCLUDED_PREFIXES.some((prefix) => file.startsWith(prefix))) return false;
32
+ return PUBLIC_ROOTS.some((root) => file === root || file.startsWith(root));
33
+ }
34
+
14
35
  function filesToAudit() {
15
36
  try {
16
37
  const tracked = execFileSync("git", ["ls-files"], {
@@ -25,19 +46,16 @@ function filesToAudit() {
25
46
  return `${tracked}\n${untracked}`
26
47
  .split("\n")
27
48
  .filter(Boolean)
28
- .filter((file) => !file.startsWith("pnpm-lock.yaml"));
49
+ .filter((file) => file !== "pnpm-lock.yaml")
50
+ .filter(isPublicAuditFile);
29
51
  } catch {
30
- return walk(".");
52
+ return walk(".").filter(isPublicAuditFile);
31
53
  }
32
54
  }
33
55
 
34
- const publicFiles = filesToAudit();
35
-
36
- // Install and protocol documentation legitimately references agent harness
37
- // config directories and tilde home paths. The path-style rules below skip
38
- // these files; the rest of the rules still apply.
39
56
  const BUNDLED_DOC = new Set([
40
57
  "README.md",
58
+ "docs/guides/quickstart-prompts.md",
41
59
  "protocol/bootstrap-" + "sk" + "ill.md",
42
60
  "plugins/sentinel-coordination-protocol/" + "sk" + "ills/sentinel-coordination-protocol/SK" + "ILL.md"
43
61
  ]);
@@ -46,7 +64,9 @@ const forbidden = [
46
64
  { name: "macOS home path", pattern: new RegExp(`/${"Users"}/[A-Za-z0-9._-]+/`) },
47
65
  { name: "Linux home path", pattern: /\/home\/[A-Za-z0-9._-]+\// },
48
66
  { name: "tilde home path", pattern: /~\//, exemptFiles: BUNDLED_DOC },
49
- { name: "local agent config path", pattern: new RegExp(`\\.${"codex"}|\\.${"claude"}|\\.${"agents"}`, "i"), exemptFiles: BUNDLED_DOC },
67
+ { name: "local agent config path", pattern: new RegExp(`\\.(?:${"codex"}|${"claude"}|${"agents"})(?:/|$)`, "i"), exemptFiles: BUNDLED_DOC },
68
+ { name: "local evidence path", pattern: new RegExp(`\\.${"edge-" + "agentic"}/local`, "i") },
69
+ { name: "private planning path", pattern: new RegExp(`project/${"planning"}/`, "i") },
50
70
  {
51
71
  name: "private project or account marker",
52
72
  pattern: new RegExp(
@@ -57,20 +77,29 @@ const forbidden = [
57
77
  { name: "secret-looking assignment", pattern: /(api[_-]?key|secret|token|password)\s*[:=]\s*["'][^"']+["']/i }
58
78
  ];
59
79
 
60
- const findings = [];
61
-
62
- for (const file of publicFiles) {
63
- const text = readFileSync(file, "utf8");
64
- for (const rule of forbidden) {
65
- if (rule.exemptFiles?.has(file)) continue;
66
- if (rule.pattern.test(text)) {
67
- findings.push(`${file}: ${rule.name}`);
80
+ export function auditPublicSurface(fileTextByPath) {
81
+ const findings = [];
82
+ for (const [file, text] of Object.entries(fileTextByPath)) {
83
+ if (!isPublicAuditFile(file)) continue;
84
+ for (const rule of forbidden) {
85
+ if (rule.exemptFiles?.has(file)) continue;
86
+ if (rule.pattern.test(text)) findings.push(`${file}: ${rule.name}`);
68
87
  }
69
88
  }
89
+ return findings;
70
90
  }
71
91
 
72
- if (findings.length > 0) {
73
- throw new Error(`Public surface audit failed:\n${findings.join("\n")}`);
92
+ export function main() {
93
+ const publicFiles = filesToAudit();
94
+ const findings = auditPublicSurface(Object.fromEntries(publicFiles.map((file) => [file, readFileSync(file, "utf8")])));
95
+
96
+ if (findings.length > 0) {
97
+ throw new Error(`Public surface audit failed:\n${findings.join("\n")}`);
98
+ }
99
+
100
+ console.log(`Public surface audit PASS: ${publicFiles.length} files checked`);
74
101
  }
75
102
 
76
- console.log(`Public surface audit PASS: ${publicFiles.length} files checked`);
103
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
104
+ main();
105
+ }