@voybio/ace-swarm 0.2.5 → 2.4.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.
Files changed (115) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/README.md +20 -13
  3. package/assets/agent-state/EVIDENCE_LOG.md +1 -1
  4. package/assets/agent-state/MODULES/roles/capability-framework.json +41 -0
  5. package/assets/agent-state/MODULES/roles/capability-git.json +33 -0
  6. package/assets/agent-state/MODULES/roles/capability-safety.json +37 -0
  7. package/assets/agent-state/MODULES/schemas/ACE_RUNTIME_PROFILE.schema.json +21 -0
  8. package/assets/agent-state/MODULES/schemas/RUNTIME_EXECUTOR_SESSION_REGISTRY.schema.json +43 -0
  9. package/assets/agent-state/MODULES/schemas/WORKSPACE_SESSION_REGISTRY.schema.json +11 -0
  10. package/assets/agent-state/STATUS.md +2 -2
  11. package/assets/scripts/ace-hook-dispatch.mjs +70 -6
  12. package/assets/scripts/render-mcp-configs.sh +19 -5
  13. package/dist/ace-context.js +22 -1
  14. package/dist/ace-server-instructions.js +3 -3
  15. package/dist/ace-state-resolver.js +5 -3
  16. package/dist/astgrep-index.d.ts +9 -1
  17. package/dist/astgrep-index.js +14 -3
  18. package/dist/cli.js +27 -20
  19. package/dist/handoff-registry.js +5 -5
  20. package/dist/helpers/artifacts.d.ts +19 -0
  21. package/dist/helpers/artifacts.js +152 -0
  22. package/dist/helpers/bootstrap.d.ts +24 -0
  23. package/dist/helpers/bootstrap.js +894 -0
  24. package/dist/helpers/constants.d.ts +53 -0
  25. package/dist/helpers/constants.js +288 -0
  26. package/dist/helpers/drift.d.ts +13 -0
  27. package/dist/helpers/drift.js +45 -0
  28. package/dist/helpers/path-utils.d.ts +17 -0
  29. package/dist/helpers/path-utils.js +104 -0
  30. package/dist/helpers/store-resolution.d.ts +19 -0
  31. package/dist/helpers/store-resolution.js +301 -0
  32. package/dist/helpers/workspace-root.d.ts +3 -0
  33. package/dist/helpers/workspace-root.js +80 -0
  34. package/dist/helpers.d.ts +8 -125
  35. package/dist/helpers.js +8 -1768
  36. package/dist/job-scheduler.js +3 -3
  37. package/dist/local-model-runtime.js +12 -1
  38. package/dist/model-bridge.d.ts +7 -0
  39. package/dist/model-bridge.js +75 -5
  40. package/dist/orchestrator-supervisor.d.ts +14 -0
  41. package/dist/orchestrator-supervisor.js +72 -1
  42. package/dist/run-ledger.js +3 -3
  43. package/dist/runtime-command.d.ts +8 -0
  44. package/dist/runtime-command.js +38 -6
  45. package/dist/runtime-executor.d.ts +14 -0
  46. package/dist/runtime-executor.js +669 -171
  47. package/dist/runtime-profile.d.ts +32 -0
  48. package/dist/runtime-profile.js +89 -13
  49. package/dist/runtime-tool-specs.d.ts +21 -0
  50. package/dist/runtime-tool-specs.js +78 -3
  51. package/dist/safe-edit.d.ts +7 -0
  52. package/dist/safe-edit.js +163 -37
  53. package/dist/schemas.js +19 -0
  54. package/dist/shared.d.ts +2 -2
  55. package/dist/status-events.js +9 -6
  56. package/dist/store/ace-packed-store.d.ts +3 -2
  57. package/dist/store/ace-packed-store.js +188 -110
  58. package/dist/store/bootstrap-store.d.ts +1 -1
  59. package/dist/store/bootstrap-store.js +94 -81
  60. package/dist/store/cache-workspace.js +11 -5
  61. package/dist/store/materializers/context-snapshot-materializer.js +6 -2
  62. package/dist/store/materializers/hook-context-materializer.d.ts +6 -9
  63. package/dist/store/materializers/hook-context-materializer.js +11 -21
  64. package/dist/store/materializers/host-file-materializer.js +6 -0
  65. package/dist/store/materializers/projection-manager.d.ts +0 -1
  66. package/dist/store/materializers/projection-manager.js +5 -13
  67. package/dist/store/materializers/scheduler-projection-materializer.js +1 -1
  68. package/dist/store/materializers/vericify-projector.d.ts +7 -7
  69. package/dist/store/materializers/vericify-projector.js +11 -11
  70. package/dist/store/repositories/local-model-runtime-repository.d.ts +120 -3
  71. package/dist/store/repositories/local-model-runtime-repository.js +242 -6
  72. package/dist/store/skills-install.d.ts +4 -0
  73. package/dist/store/skills-install.js +21 -12
  74. package/dist/store/state-reader.d.ts +2 -0
  75. package/dist/store/state-reader.js +20 -0
  76. package/dist/store/store-artifacts.d.ts +7 -0
  77. package/dist/store/store-artifacts.js +27 -1
  78. package/dist/store/store-authority-audit.d.ts +18 -1
  79. package/dist/store/store-authority-audit.js +115 -5
  80. package/dist/store/store-snapshot.d.ts +3 -0
  81. package/dist/store/store-snapshot.js +22 -2
  82. package/dist/store/workspace-store-paths.d.ts +39 -0
  83. package/dist/store/workspace-store-paths.js +94 -0
  84. package/dist/store/write-coordinator.d.ts +65 -0
  85. package/dist/store/write-coordinator.js +386 -0
  86. package/dist/todo-state.js +5 -5
  87. package/dist/tools-agent.js +268 -14
  88. package/dist/tools-discovery.js +1 -1
  89. package/dist/tools-files.d.ts +7 -0
  90. package/dist/tools-files.js +299 -10
  91. package/dist/tools-framework.js +25 -5
  92. package/dist/tools-handoff.js +2 -2
  93. package/dist/tools-lifecycle.js +4 -4
  94. package/dist/tools-memory.js +6 -6
  95. package/dist/tools-todo.js +2 -2
  96. package/dist/tracker-adapters.d.ts +1 -1
  97. package/dist/tracker-adapters.js +13 -18
  98. package/dist/tracker-sync.js +5 -3
  99. package/dist/tui/agent-runner.js +3 -1
  100. package/dist/tui/chat.js +103 -7
  101. package/dist/tui/dashboard.d.ts +1 -0
  102. package/dist/tui/dashboard.js +43 -0
  103. package/dist/tui/layout.d.ts +20 -0
  104. package/dist/tui/layout.js +31 -1
  105. package/dist/tui/local-model-contract.d.ts +6 -2
  106. package/dist/tui/local-model-contract.js +16 -3
  107. package/dist/vericify-bridge.d.ts +5 -0
  108. package/dist/vericify-bridge.js +27 -3
  109. package/dist/workspace-manager.d.ts +30 -3
  110. package/dist/workspace-manager.js +257 -27
  111. package/package.json +1 -2
  112. package/dist/internal-tool-runtime.d.ts +0 -21
  113. package/dist/internal-tool-runtime.js +0 -136
  114. package/dist/store/workspace-snapshot.d.ts +0 -26
  115. package/dist/store/workspace-snapshot.js +0 -107
package/CHANGELOG.md CHANGED
@@ -35,9 +35,19 @@
35
35
  - Expanded hook dispatch context to emit role-aware ACE tool hints from session, subagent, and tool lifecycle events.
36
36
  - Updated bootstrap and config rendering to generate multi-host hook artifacts under `.vscode`, `.cursor`, and `.mcp-config`.
37
37
 
38
+ **Store-Unity Migration:**
39
+ - Added `src/store/workspace-store-paths.ts` as the canonical resolver for the canonical/legacy ACE store transition. Every command that opens ACEPACK now uses this shared module; no command assembles `.agents/ACE/ace-state.ace` by hand.
40
+ - `agent-state/ace-state.ace` is the canonical store for new and adopted workspaces. `.agents/ACE/ace-state.ace` is retained as a supported legacy input and fallback — not a second active write target.
41
+ - Added `ensureCanonicalWorkspaceStore()`: legacy-only workspaces are atomically adopted into the canonical path on the first mutating operation (bootstrap, install, repair, compact, preconfig). The legacy file is preserved as a fallback after adoption.
42
+ - Dual-store conflicts (both files exist with different content) surface an explicit warning and halt mutating commands rather than silently merging or overwriting.
43
+ - Added `resolveWorkspaceStorePath()` for read-only resolution: returns the active path and mode without writing anything.
44
+ - Bootstrap, skill install/list, repair, compact, and preconfig all updated to use the shared resolver.
45
+ - CLI help text, doctor messages, and run-ledger artifacts updated to describe `agent-state/ace-state.ace` as canonical.
46
+ - Added `test/store-unity-release.test.mjs` as a dedicated release gate covering legacy adoption, dual-store conflict, canonical-only skill install/repair/compact, and a source-scan guard that fails on new hard-coded legacy path references outside the resolver module.
47
+
38
48
  ### Validation
39
49
 
40
- - Verified `208/208` tests passing (up from 202) with full orchestrator supervisor, model bridge, and compliance enforcement coverage.
50
+ - Verified `319/319` tests passing (up from 208) with full orchestrator supervisor, model bridge, compliance enforcement, and store-unity migration coverage.
41
51
 
42
52
  ## [2.2.0] - 2026-03-26
43
53
 
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Autonomous Coding Entity (ACE) is a local MCP server and CLI for agent-assisted coding.
4
4
 
5
- `ace-swarm` provides Claude Code, Codex, Cursor, VS Code, and provider-backed workflows with a shared runtime: durable workspace state, typed handoffs, scheduler support, change intelligence, and operator tooling. All state lives in a single binary file — `.agents/ACE/ace-state.ace` so the workspace keeps one source of truth instead of a forest of generated state files.
5
+ `ace-swarm` provides Claude Code, Codex, Cursor, GitHub Copilot CLI, VS Code, and provider-backed workflows with a shared runtime: durable workspace state, typed handoffs, scheduler support, change intelligence, and operator tooling. All state lives in a single binary file — `agent-state/ace-state.ace` — with `.agents/ACE/ace-state.ace` kept only as a legacy fallback for older workspaces.
6
6
 
7
7
  Modern coding agents can already read files, write code, run commands, and call tools. The missing layer is coordination that survives restarts, model switches, and multi-agent work. ACE keeps the workflow in the store and projects only the files external clients still need. For provider-backed runs, ACE provides task context, tool surfaces, status events, evidence trails, and resumable state.
8
8
 
@@ -13,7 +13,7 @@ Modern coding agents can already read files, write code, run commands, and call
13
13
  - Shared workflow state should live in the workspace, not only in chat history.
14
14
  - ACE-Orchestrator is the default entrypoint, and every provider can delegate through the full agent set.
15
15
  - Provider-backed runs should get the same structure and observability.
16
- - Bootstrap should be contained and reversible: ACE writes into `.agents/ACE/ace-state.ace`.
16
+ - Bootstrap should be contained and reversible: ACE writes into `agent-state/ace-state.ace`, with legacy fallback reads from `.agents/ACE/ace-state.ace` where needed.
17
17
 
18
18
  ### Serving model providers
19
19
 
@@ -21,6 +21,8 @@ ACE provides model providers with the context they cannot infer on their own: ta
21
21
 
22
22
  - `ace init --llm <provider>` records the selected runtime profile in the store.
23
23
  - `ace doctor` validates local or hosted runtime wiring, checks the selected model when the provider exposes listings, and keeps the runtime honest.
24
+ - `ace doctor --scan` probes common Ollama and llama.cpp endpoints and writes the selected profile back into the store.
25
+ - `ace tui` is provider-aware for `ollama`, `llama.cpp`, `codex`, `claude`, `gemini`, and `copilot` when credentials or base URLs are configured.
24
26
  - `ace mcp` and `ace tui` expose the same workspace truth to the host, the terminal, and the model.
25
27
 
26
28
  ## Why This Exists Now
@@ -38,7 +40,7 @@ ACE also provides scheduler primitives for queued work, dependency gates, leases
38
40
 
39
41
  ## ACEPACK State Model
40
42
 
41
- ACE uses a custom binary format called ACEPACK to present `.agents/ACE/ace-state.ace` as a structured single-file store. The file has three regions:
43
+ ACE uses a custom binary format called ACEPACK to present `agent-state/ace-state.ace` as a structured single-file store. Existing workspaces that still carry `.agents/ACE/ace-state.ace` are read through the legacy fallback path. The file has three regions:
42
44
 
43
45
  ```
44
46
  ace-state.ace
@@ -80,7 +82,7 @@ Every `appendEntry()` call — handoffs, status events, ledger entries, session
80
82
  - Per-event overhead is ~19 bytes fixed vs ~150 bytes for equivalent JSON.
81
83
  - At 100,000 events, the fixed columns are ~1.9 MB; a full JSON log would be ~15 MB.
82
84
 
83
- Events accumulate for the workspace lifetime and survive `compact()`. Full historical replay is always available. See `HOT_COLD_EVENT_TIERING.md` for the future branch that adds compressed batch archiving for very long-lived workspaces.
85
+ Events accumulate for the workspace lifetime and survive `compact()`. Full historical replay is always available.
84
86
 
85
87
  ### Why one state file
86
88
 
@@ -98,7 +100,7 @@ The store holds runtime state, agent instructions, skills, topology, schemas, an
98
100
  Bootstrap a workspace:
99
101
 
100
102
  ```bash
101
- npx -y ace-swarm turnkey --project "My Project"
103
+ npx -y @voybio/ace-swarm turnkey --project "My Project"
102
104
  ace mcp
103
105
  ```
104
106
 
@@ -111,7 +113,7 @@ initiate ACE
111
113
  Local-model path with Ollama:
112
114
 
113
115
  ```bash
114
- npx -y ace-swarm turnkey --project "My Project" --llm ollama --model llama3.1:8b --base-url http://localhost:11434
116
+ npx -y @voybio/ace-swarm turnkey --project "My Project" --llm ollama --model llama3.1:8b --base-url http://localhost:11434
115
117
  ollama serve
116
118
  ollama pull llama3.1:8b
117
119
  ace doctor --llm ollama --model llama3.1:8b --base-url http://localhost:11434
@@ -121,7 +123,7 @@ ace mcp
121
123
  Local-model path with llama.cpp:
122
124
 
123
125
  ```bash
124
- npx -y ace-swarm turnkey --project "My Project" --llm llama.cpp --model local-model --base-url http://localhost:8080
126
+ npx -y @voybio/ace-swarm turnkey --project "My Project" --llm llama.cpp --model local-model --base-url http://localhost:8080
125
127
  llama-server -m /path/to/model.gguf --port 8080
126
128
  ace doctor --llm llama.cpp --model local-model --base-url http://localhost:8080
127
129
  ace mcp
@@ -132,7 +134,7 @@ If you already have a local runtime running, `ace doctor --scan` will probe comm
132
134
  Hosted provider path with Codex:
133
135
 
134
136
  ```bash
135
- npx -y ace-swarm turnkey --project "My Project" --llm codex --model gpt-5
137
+ npx -y @voybio/ace-swarm turnkey --project "My Project" --llm codex --model gpt-5
136
138
  export OPENAI_API_KEY=...
137
139
  ace doctor --llm codex --model gpt-5
138
140
  ace mcp
@@ -140,9 +142,10 @@ ace mcp
140
142
 
141
143
  ## What Bootstrap Writes
142
144
 
143
- ACE bootstrap is intentionally contained. The store is authoritative at `.agents/ACE/ace-state.ace`; only a few host-facing files land in the workspace when requested.
145
+ ACE bootstrap is intentionally contained. The store is authoritative at `agent-state/ace-state.ace`; only a few host-facing files land in the workspace when requested.
144
146
 
145
- - `.agents/ACE/ace-state.ace` — runtime state, agent instructions, skills, topology, schemas, and the event log
147
+ - `agent-state/ace-state.ace` — runtime state, agent instructions, skills, topology, schemas, and the event log
148
+ - `.agents/ACE/ace-state.ace` — legacy fallback for existing workspaces
146
149
  - `.agents/ACE/ace-hook-context.json` — compact hook snapshot for external clients
147
150
  - `.agents/ACE/tasks/todo.md` — human-facing todo surface
148
151
  - Optional workspace-root stubs — `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, `.github/copilot-instructions.md`, and `.vscode/mcp.json`
@@ -159,6 +162,11 @@ Developer or MCP host
159
162
  | |
160
163
  | `-- calls ace-swarm over MCP
161
164
  |
165
+ +-- agent-state/
166
+ | |
167
+ | +-- ace-state.ace
168
+ | +-- STATUS.md / TASK.md / HANDOFF.json projections
169
+ |
162
170
  +-- ace mcp
163
171
  | |
164
172
  | +-- tools, prompts, resources
@@ -168,7 +176,6 @@ Developer or MCP host
168
176
  |
169
177
  +-- .agents/ACE/
170
178
  | |
171
- | +-- ace-state.ace
172
179
  | +-- ace-hook-context.json
173
180
  | +-- tasks/todo.md
174
181
  | `-- host config bundles
@@ -190,7 +197,7 @@ Developer or MCP host
190
197
  | Runtime roles | swarm and composable runtime roles |
191
198
  | Skills | packaged skills |
192
199
  | MCP server | stdio surface for tools, prompts, resources, and workflows |
193
- | Durable state | single .ace authority for handoffs, status events, todos, run ledger, job queue, and discovery |
200
+ | Durable state | single `agent-state/ace-state.ace` authority for handoffs, status events, todos, run ledger, job queue, and discovery |
194
201
  | Projections | hook context, todo surface, and host config bundles |
195
202
  | Coordination | scheduler queues, dependency gates, leases, and resource locks |
196
203
  | Change intelligence | delta scan, semantic snapshots, drift reports, rewrite hints |
@@ -215,7 +222,7 @@ In that setup, the host remains the interface. ACE becomes the state contract un
215
222
 
216
223
  Local models are good at generating text. They usually need help seeing the workspace, hearing the handoff trail, and remembering what changed two turns ago. ACE closes that gap.
217
224
 
218
- - `ace init --llm <provider>` seeds the profile inside `.agents/ACE/ace-state.ace`.
225
+ - `ace init --llm <provider>` seeds the profile inside `agent-state/ace-state.ace`.
219
226
  - `ace doctor` verifies that the selected runtime is configured and, when possible, reachable.
220
227
  - `ace tui` can talk to either local runtime and surface the same workspace state the MCP server sees.
221
228
  - The ACE model bridge gives local runs tool selection, execution flow, and persisted state instead of a fragile one-shot chat loop.
@@ -4,4 +4,4 @@ Append-only chain-of-custody for checks, decisions, and execution proofs.
4
4
 
5
5
  ## Entries
6
6
 
7
- - {{BOOTSTRAP_TIMESTAMP}} | bootstrap initialized | evidence_ref: `EVIDENCE_LOG.md#ts:{{BOOTSTRAP_TIMESTAMP}}`
7
+ - 2026-03-03T00:00:00Z | bootstrap initialized | evidence_ref: `EVIDENCE_LOG.md#ts:2026-03-03T00:00:00Z`
@@ -0,0 +1,41 @@
1
+ {
2
+ "id": "capability-framework",
3
+ "version": "1.0.0",
4
+ "objective": "Validate ACE framework contracts, execute gate bundles, and enforce state integrity checks",
5
+ "permissions": [
6
+ "allow_file_io",
7
+ "allow_shell_exec"
8
+ ],
9
+ "inputs": [
10
+ {
11
+ "file": "TEAL_CONFIG.md",
12
+ "critical": true
13
+ },
14
+ {
15
+ "file": "QUALITY_GATES.md",
16
+ "critical": true
17
+ },
18
+ {
19
+ "file": "HANDOFF.json",
20
+ "critical": true
21
+ },
22
+ {
23
+ "file": "MODULES/registry.json",
24
+ "critical": true
25
+ }
26
+ ],
27
+ "outputs": [
28
+ {
29
+ "file": "EVIDENCE_LOG.md",
30
+ "validation_gate": "gate-completeness"
31
+ },
32
+ {
33
+ "file": "STATUS_EVENTS.ndjson",
34
+ "validation_gate": "gate-autonomy"
35
+ }
36
+ ],
37
+ "failure_routing": {
38
+ "missing_input": "BLOCK_AND_REQUEST_INFO",
39
+ "gate_failure": "ESCALATE_TO_CAPABILITY_OPS"
40
+ }
41
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "id": "capability-git",
3
+ "version": "1.0.0",
4
+ "objective": "Execute repository initialization and commit operations with traceable evidence",
5
+ "permissions": [
6
+ "allow_file_io",
7
+ "allow_shell_exec"
8
+ ],
9
+ "inputs": [
10
+ {
11
+ "file": "STATUS.md",
12
+ "critical": false
13
+ },
14
+ {
15
+ "file": "EVIDENCE_LOG.md",
16
+ "critical": true
17
+ }
18
+ ],
19
+ "outputs": [
20
+ {
21
+ "file": "EVIDENCE_LOG.md",
22
+ "validation_gate": "gate-completeness"
23
+ },
24
+ {
25
+ "file": "STATUS_EVENTS.ndjson",
26
+ "validation_gate": "gate-autonomy"
27
+ }
28
+ ],
29
+ "failure_routing": {
30
+ "missing_input": "BLOCK_AND_REQUEST_INFO",
31
+ "gate_failure": "ESCALATE_TO_CAPABILITY_OPS"
32
+ }
33
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "id": "capability-safety",
3
+ "version": "1.0.0",
4
+ "objective": "Apply safety checks and fail-closed validation before mutating critical ACE artifacts",
5
+ "permissions": [
6
+ "allow_file_io",
7
+ "allow_shell_exec"
8
+ ],
9
+ "inputs": [
10
+ {
11
+ "file": "HANDOFF.json",
12
+ "critical": false
13
+ },
14
+ {
15
+ "file": "QUALITY_GATES.md",
16
+ "critical": true
17
+ },
18
+ {
19
+ "file": "EVIDENCE_LOG.md",
20
+ "critical": true
21
+ }
22
+ ],
23
+ "outputs": [
24
+ {
25
+ "file": "EVIDENCE_LOG.md",
26
+ "validation_gate": "gate-completeness"
27
+ },
28
+ {
29
+ "file": "STATUS_EVENTS.ndjson",
30
+ "validation_gate": "gate-autonomy"
31
+ }
32
+ ],
33
+ "failure_routing": {
34
+ "missing_input": "BLOCK_AND_REQUEST_INFO",
35
+ "gate_failure": "BLOCK_AND_ESCALATE"
36
+ }
37
+ }
@@ -145,6 +145,27 @@
145
145
  "registry_path": {
146
146
  "type": "string",
147
147
  "minLength": 1
148
+ },
149
+ "surgical_read_budgets": {
150
+ "type": "object",
151
+ "additionalProperties": false,
152
+ "properties": {
153
+ "small_local": {
154
+ "type": "integer",
155
+ "minimum": 1
156
+ },
157
+ "mid": {
158
+ "type": "integer",
159
+ "minimum": 1
160
+ },
161
+ "frontier": {
162
+ "type": [
163
+ "integer",
164
+ "null"
165
+ ],
166
+ "minimum": 1
167
+ }
168
+ }
148
169
  }
149
170
  }
150
171
  },
@@ -163,6 +163,46 @@
163
163
  "items": {
164
164
  "$ref": "#/$defs/tool_call"
165
165
  }
166
+ },
167
+ "turn_outcome": {
168
+ "type": "string",
169
+ "enum": [
170
+ "no_op_success",
171
+ "meaningful_completion",
172
+ "escalation_blocker"
173
+ ]
174
+ },
175
+ "outcome_reason": {
176
+ "type": "string"
177
+ }
178
+ }
179
+ },
180
+ "output_policy": {
181
+ "type": "object",
182
+ "additionalProperties": false,
183
+ "required": [
184
+ "emit_to",
185
+ "silent_unless_blocked",
186
+ "require_approval_before_emit"
187
+ ],
188
+ "properties": {
189
+ "emit_to": {
190
+ "type": "array",
191
+ "items": {
192
+ "type": "string",
193
+ "enum": [
194
+ "tui",
195
+ "tracker",
196
+ "handoff",
197
+ "vericify"
198
+ ]
199
+ }
200
+ },
201
+ "silent_unless_blocked": {
202
+ "type": "boolean"
203
+ },
204
+ "require_approval_before_emit": {
205
+ "type": "boolean"
166
206
  }
167
207
  }
168
208
  },
@@ -278,6 +318,9 @@
278
318
  "failed"
279
319
  ]
280
320
  },
321
+ "output_policy": {
322
+ "$ref": "#/$defs/output_policy"
323
+ },
281
324
  "turns": {
282
325
  "type": "array",
283
326
  "items": {
@@ -72,6 +72,17 @@
72
72
  "last_error": {
73
73
  "type": "string"
74
74
  },
75
+ "hook_health": {
76
+ "type": "string",
77
+ "enum": [
78
+ "ok",
79
+ "degraded",
80
+ "failed"
81
+ ]
82
+ },
83
+ "hook_summary": {
84
+ "type": "string"
85
+ },
75
86
  "created_at": {
76
87
  "type": "string",
77
88
  "format": "date-time"
@@ -1,8 +1,8 @@
1
1
  # STATUS
2
2
 
3
- - Current role: `ace-orchestrator`
3
+ - Current role: `capability-skeptic`
4
4
  - Current phase: `STATE_ANALYSIS`
5
5
  - Active pipeline: `standard`
6
6
  - Blockers: `none`
7
7
  - Current objective delta: `bootstrap complete, awaiting first scoped objective`
8
- - Last update: `{{BOOTSTRAP_TIMESTAMP}}`
8
+ - Last update: `2026-03-03T00:00:00Z`
@@ -28,6 +28,9 @@ const ACE_CORE_FILES = [
28
28
  "agent-state/SCOPE.md",
29
29
  "agent-state/EVIDENCE_LOG.md",
30
30
  ];
31
+ const STORE_MAGIC = "ACEPACK1";
32
+ const STORE_HEADER_SIZE = 32;
33
+ const HOOK_CONTEXT_STORE_KEY = "state/runtime/hook_context";
31
34
 
32
35
  const PROTECTED_PATH_FRAGMENTS = [
33
36
  ".github/hooks/",
@@ -114,9 +117,61 @@ function resolveAcePath(workspaceRoot, relativePath) {
114
117
  return canonical;
115
118
  }
116
119
 
120
+ function getWorkspaceStorePath(workspaceRoot) {
121
+ const canonical = resolve(workspaceRoot, "agent-state", "ace-state.ace");
122
+ if (existsSync(canonical)) return canonical;
123
+ return resolve(workspaceRoot, ACE_ROOT, "ace-state.ace");
124
+ }
125
+
126
+ function readStoreUint64(buffer, offset) {
127
+ return buffer.readUInt32BE(offset) * 2 ** 32 + buffer.readUInt32BE(offset + 4);
128
+ }
129
+
130
+ function readStoreBlob(workspaceRoot, key) {
131
+ const storePath = getWorkspaceStorePath(workspaceRoot);
132
+ if (!existsSync(storePath)) return undefined;
133
+ try {
134
+ const file = readFileSync(storePath);
135
+ if (file.length < STORE_HEADER_SIZE) return undefined;
136
+ if (file.subarray(0, 8).toString("utf8") !== STORE_MAGIC) return undefined;
137
+ const indexOffset = readStoreUint64(file, 16);
138
+ const indexLength = readStoreUint64(file, 24);
139
+ const index = JSON.parse(file.subarray(indexOffset, indexOffset + indexLength).toString("utf8"));
140
+ const entry = index?.[key];
141
+ if (!entry || typeof entry.offset !== "number" || typeof entry.length !== "number") {
142
+ return undefined;
143
+ }
144
+ const start = entry.offset + 4;
145
+ const end = start + entry.length;
146
+ return file.subarray(start, end).toString("utf8");
147
+ } catch {
148
+ return undefined;
149
+ }
150
+ }
151
+
117
152
  function readIfPresent(workspaceRoot, relativePath) {
118
153
  const absolute = resolveAcePath(workspaceRoot, relativePath);
119
- if (!existsSync(absolute)) return undefined;
154
+ if (!existsSync(absolute)) {
155
+ const normalized = String(relativePath).replace(/\\/g, "/").replace(/^\.?\//, "");
156
+ const logicalPath = normalized.startsWith(`${ACE_ROOT}/`)
157
+ ? normalized.slice(`${ACE_ROOT}/`.length)
158
+ : normalized;
159
+ const rel = logicalPath.startsWith("agent-state/") ? logicalPath.slice("agent-state/".length) : "";
160
+ const keys = [];
161
+ if (rel) {
162
+ keys.push(`state/artifacts/agent-state/${rel}`);
163
+ keys.push(`knowledge/agent-state/${rel}`);
164
+ if (rel === "ACE_WORKFLOW.md") {
165
+ keys.unshift("knowledge/runtime/ACE_WORKFLOW.md");
166
+ keys.push("knowledge/kernel/ACE_WORKFLOW.md");
167
+ }
168
+ }
169
+ for (const key of keys) {
170
+ const blob = readStoreBlob(workspaceRoot, key);
171
+ if (typeof blob === "string") return blob;
172
+ }
173
+ return undefined;
174
+ }
120
175
  try {
121
176
  return readFileSync(absolute, "utf8");
122
177
  } catch {
@@ -203,12 +258,19 @@ function buildRoleToolHint(role) {
203
258
  }
204
259
 
205
260
  /**
206
- * Try to read the store-materialized hook context snapshot.
261
+ * Try to read the store-backed hook context snapshot.
207
262
  * Returns the parsed snapshot or undefined if not present / unreadable.
208
- * When present this is the single authoritative source; the dispatcher
209
- * never needs to open the .ace store directly.
210
263
  */
211
264
  function tryReadHookContextSnapshot(workspaceRoot) {
265
+ const storeRaw = readStoreBlob(workspaceRoot, HOOK_CONTEXT_STORE_KEY);
266
+ if (typeof storeRaw === "string") {
267
+ try {
268
+ const parsed = JSON.parse(storeRaw);
269
+ if (parsed?.schema_version === 1) return parsed;
270
+ } catch {
271
+ // Fall through to legacy file compatibility.
272
+ }
273
+ }
212
274
  const snapshotPath = resolve(workspaceRoot, ACE_ROOT, "ace-hook-context.json");
213
275
  if (!existsSync(snapshotPath)) return undefined;
214
276
  try {
@@ -222,7 +284,7 @@ function tryReadHookContextSnapshot(workspaceRoot) {
222
284
  }
223
285
 
224
286
  function aceContext(workspaceRoot) {
225
- // ── Fast path: store-materialized snapshot ──────────────────────────────
287
+ // ── Fast path: store-backed snapshot ────────────────────────────────────
226
288
  const snapshot = tryReadHookContextSnapshot(workspaceRoot);
227
289
  if (snapshot) {
228
290
  const taskObjective = snapshot.task?.content
@@ -233,7 +295,9 @@ function aceContext(workspaceRoot) {
233
295
  const scopeReminder = scopeLines.length
234
296
  ? `ACE scope reminder: ${truncate(scopeLines.slice(0, 4).join(" "), 220)}`
235
297
  : undefined;
236
- const hasAgentState = existsSync(resolve(workspaceRoot, ACE_ROOT, "agent-state"));
298
+ const hasAgentState =
299
+ existsSync(resolve(workspaceRoot, ACE_ROOT, "agent-state")) ||
300
+ existsSync(resolve(workspaceRoot, "agent-state", "ace-state.ace"));
237
301
  const hasSkills = existsSync(resolve(workspaceRoot, ACE_ROOT, "skills")) ||
238
302
  existsSync(resolve(workspaceRoot, ".agents", "skills"));
239
303
  return {
@@ -12,6 +12,9 @@ CURSOR_DIR="${ACE_ROOT}/.cursor"
12
12
  VSCODE_DIR="${ACE_ROOT}/.vscode"
13
13
  HOOK_COMMAND="node ./.agents/ACE/scripts/ace/ace-hook-dispatch.mjs"
14
14
  HOOK_COMMAND_WINDOWS="node .\\\\.agents\\\\ACE\\\\scripts\\\\ace\\\\ace-hook-dispatch.mjs"
15
+ NODE_BIN_DIR="$(dirname -- "$(command -v node)")"
16
+ CLI_ENTRY="${WORKSPACE_ROOT}/dist/cli.js"
17
+ MCP_LAUNCH="export PATH=\"${NODE_BIN_DIR}:\$PATH\" && if ! command -v node >/dev/null 2>&1; then [ -s \"\$HOME/.zprofile\" ] && . \"\$HOME/.zprofile\"; [ -s \"\$HOME/.zshrc\" ] && . \"\$HOME/.zshrc\"; fi && cd \"${WORKSPACE_ROOT}\" && ACE_WORKSPACE_ROOT=\"${WORKSPACE_ROOT}\" node \"${CLI_ENTRY}\" mcp"
15
18
 
16
19
  mkdir -p "${MCP_CONFIG_DIR}"
17
20
  mkdir -p "${GITHUB_DIR}/hooks"
@@ -25,7 +28,18 @@ cat > "${MCP_CONFIG_DIR}/vscode.mcp.json" <<JSON
25
28
  "ace-swarm": {
26
29
  "type": "stdio",
27
30
  "command": "/bin/zsh",
28
- "args": ["-lc", "cd \"${WORKSPACE_ROOT}\" && ACE_WORKSPACE_ROOT=\"${WORKSPACE_ROOT}\" npx -y ace-swarm mcp"]
31
+ "args": ["-lc", "${MCP_LAUNCH}"]
32
+ }
33
+ }
34
+ }
35
+ JSON
36
+
37
+ cat > "${WORKSPACE_ROOT}/.mcp.json" <<JSON
38
+ {
39
+ "mcpServers": {
40
+ "ace-swarm": {
41
+ "command": "/bin/zsh",
42
+ "args": ["-lc", "${MCP_LAUNCH}"]
29
43
  }
30
44
  }
31
45
  }
@@ -36,7 +50,7 @@ cat > "${MCP_CONFIG_DIR}/cursor.mcp.json" <<JSON
36
50
  "mcpServers": {
37
51
  "ace-swarm": {
38
52
  "command": "/bin/zsh",
39
- "args": ["-lc", "cd \"${WORKSPACE_ROOT}\" && ACE_WORKSPACE_ROOT=\"${WORKSPACE_ROOT}\" npx -y ace-swarm mcp"]
53
+ "args": ["-lc", "${MCP_LAUNCH}"]
40
54
  }
41
55
  }
42
56
  }
@@ -47,7 +61,7 @@ cat > "${MCP_CONFIG_DIR}/claude_desktop_config.json" <<JSON
47
61
  "mcpServers": {
48
62
  "ace-swarm": {
49
63
  "command": "/bin/zsh",
50
- "args": ["-lc", "cd \"${WORKSPACE_ROOT}\" && ACE_WORKSPACE_ROOT=\"${WORKSPACE_ROOT}\" npx -y ace-swarm mcp"]
64
+ "args": ["-lc", "${MCP_LAUNCH}"]
51
65
  }
52
66
  }
53
67
  }
@@ -58,7 +72,7 @@ cat > "${MCP_CONFIG_DIR}/antigravity.mcp.json" <<JSON
58
72
  "mcpServers": {
59
73
  "ace-swarm": {
60
74
  "command": "/bin/zsh",
61
- "args": ["-lc", "cd \"${WORKSPACE_ROOT}\" && ACE_WORKSPACE_ROOT=\"${WORKSPACE_ROOT}\" npx -y ace-swarm mcp"]
75
+ "args": ["-lc", "${MCP_LAUNCH}"]
62
76
  }
63
77
  }
64
78
  }
@@ -68,7 +82,7 @@ cat > "${MCP_CONFIG_DIR}/codex.config.toml" <<TOML
68
82
  # ACE instructions are scaffolded into .agents/ACE/AGENTS.md during bootstrap.
69
83
  [mcp_servers.ace-swarm]
70
84
  command = "/bin/zsh"
71
- args = ["-lc", "cd \"${WORKSPACE_ROOT}\" && ACE_WORKSPACE_ROOT=\"${WORKSPACE_ROOT}\" npx -y ace-swarm mcp"]
85
+ args = ["-lc", "${MCP_LAUNCH}"]
72
86
  TOML
73
87
 
74
88
  cat > "${ACE_ROOT}/CLAUDE.md" <<MD
@@ -1,6 +1,6 @@
1
1
  import { buildAceContinuityPacket, buildAceRecallContext, formatAceContinuityPacketMarkdown, formatAceRecallMarkdown, normalizeAutonomyPolicy, normalizeContinuityPolicy, } from "./ace-autonomy.js";
2
2
  import { listAceInternalToolCatalog, } from "./ace-internal-tools.js";
3
- import { ALL_AGENTS, readAgentInstructions } from "./helpers.js";
3
+ import { ALL_AGENTS, listAvailableSkills, readAgentInstructions } from "./helpers.js";
4
4
  import { readRuntimeProfileState, renderRuntimePrompt } from "./runtime-profile.js";
5
5
  const ROLE_TOOL_DEFAULTS = {
6
6
  orchestrator: [
@@ -156,6 +156,23 @@ function buildPlanningCatalog(role, task, tier) {
156
156
  .slice(0, limit)
157
157
  .map((entry) => entry.tool);
158
158
  }
159
+ function inferRelevantSkills(task) {
160
+ const lowered = task.toLowerCase();
161
+ const skillSignals = [
162
+ { name: "state-auditor", pattern: /\b(state|drift|authority|audit)\b/ },
163
+ { name: "handoff-lint", pattern: /\b(handoff|transition|payload)\b/ },
164
+ { name: "schema-forge", pattern: /\b(schema|contract|interface)\b/ },
165
+ { name: "release-sentry", pattern: /\b(ship|release|promotion|rollback)\b/ },
166
+ { name: "risk-quant", pattern: /\b(risk|blocker|severity)\b/ },
167
+ { name: "eval-harness", pattern: /\b(eval|regression|verify|validation)\b/ },
168
+ { name: "incident-commander", pattern: /\b(incident|outage|blocker storm)\b/ },
169
+ { name: "problem-triage", pattern: /\b(triage|classify|scope)\b/ },
170
+ ];
171
+ const available = new Set(listAvailableSkills().map((skill) => skill.name));
172
+ return skillSignals
173
+ .filter((signal) => signal.pattern.test(lowered) && available.has(signal.name))
174
+ .map((signal) => signal.name);
175
+ }
159
176
  export function buildToolPlan(options) {
160
177
  const tier = options.tier ?? "compressed";
161
178
  const catalog = Array.isArray(options.tools) && options.tools.length > 0
@@ -211,6 +228,7 @@ export function renderAceContext(options) {
211
228
  const roleInstructions = resolveRoleInstructions(options.role);
212
229
  const toolCatalog = renderToolCatalogMarkdown(tools, tier);
213
230
  const stateDigest = recall.task_contract.summary;
231
+ const relevantSkills = inferRelevantSkills(options.task);
214
232
  const systemPrompt = [
215
233
  runtimePrompt,
216
234
  "",
@@ -223,6 +241,9 @@ export function renderAceContext(options) {
223
241
  "## Tool Scope",
224
242
  toolCatalog || "- No ACE tools available.",
225
243
  "",
244
+ "## Relevant Skills",
245
+ relevantSkills.length > 0 ? `- ${relevantSkills.join(", ")}` : "- No task-specific skill hint matched.",
246
+ "",
226
247
  "## Compact Guardrails",
227
248
  "- Stop if you are about to claim tested, verified, or passed without evidence.",
228
249
  "- If ACE state is thin or contradictory, call recall_context or validate_framework before improvising.",
@@ -229,10 +229,10 @@ export function buildHostInstructionText(host, workspaceRoot) {
229
229
  "3. Prefer ACE prompts/resources (`ace-orchestrator`, `get_task_pack`, `get_skill_instructions`) over relying on this file.",
230
230
  "",
231
231
  "Ground truth:",
232
- "- `agent-state/*` is the logical state surface; the resolver reads it from top-level, nested, or store-backed layouts.",
233
- "- `.agents/ACE/ace-state.ace` remains the canonical store-backed projection when that layout is used.",
232
+ "- `agent-state/*` is the visible runtime state surface for this workspace.",
233
+ "- `agent-state/ace-state.ace` is the canonical store path; legacy nested store layouts are compatibility fallback only.",
234
234
  "- `.agents/ACE/tasks/todo.md` is the human-facing todo surface.",
235
- "- `.agents/ACE/ace-hook-context.json` is the compact hook snapshot.",
235
+ "- Hook context is store-backed in `agent-state/ace-state.ace` and consumed without extra workspace projections.",
236
236
  "",
237
237
  `Workspace digest hint: ${buildAceDigest(workspaceRoot)}.`,
238
238
  ].join("\n");
@@ -95,9 +95,11 @@ export function resolveAceStateLayout(workspaceRoot) {
95
95
  scopePath: resolveAceLogicalPath(workspaceRoot, "agent-state/SCOPE.md"),
96
96
  evidencePath: resolveAceLogicalPath(workspaceRoot, "agent-state/EVIDENCE_LOG.md"),
97
97
  storePath: storePresent ? storePath : undefined,
98
- hookSnapshotPath: existsSync(nestedAcePath(workspaceRoot, "ace-hook-context.json"))
99
- ? nestedAcePath(workspaceRoot, "ace-hook-context.json")
100
- : undefined,
98
+ hookSnapshotPath: readStoreBlobSync(workspaceRoot, "state/runtime/hook_context") != null
99
+ ? toVirtualStorePath(storePath, "state/runtime/hook_context")
100
+ : existsSync(nestedAcePath(workspaceRoot, "ace-hook-context.json"))
101
+ ? nestedAcePath(workspaceRoot, "ace-hook-context.json")
102
+ : undefined,
101
103
  isAcePresent: physicalMode !== "missing" ||
102
104
  CRITICAL_LOGICAL_PATHS.some((relativePath) => typeof readAceLogicalFile(workspaceRoot, relativePath) === "string"),
103
105
  missingCriticalArtifacts,