@voybio/ace-swarm 2.4.8 → 2.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -14
- package/README.md +14 -10
- package/assets/.agents/ACE/ACE_coders/AGENTS.md +23 -30
- package/assets/.agents/ACE/ACE_coders/INSTRUCTIONS.md +21 -30
- package/assets/.agents/skills/landing-review-watcher/SKILL.md +1 -1
- package/assets/.agents/skills/learn-from-work/SKILL.md +41 -0
- package/assets/agent-state/ACE_WORKFLOW.md +25 -2
- package/assets/agent-state/MODULES/schemas/ACE_RUNTIME_PROFILE.schema.json +143 -2
- package/assets/agent-state/MODULES/schemas/RUNTIME_EXECUTOR_SESSION_REGISTRY.schema.json +2 -2
- package/assets/agent-state/MODULES/schemas/SWARM_HANDOFF.schema.json +10 -0
- package/assets/eval-battery/battery.json +1 -1
- package/assets/instructions/ACE_Coder.instructions.md +9 -13
- package/assets/scripts/ace-hook-dispatch.mjs +16 -411
- package/assets/tasks/SWARM_HANDOFF.example_ui_to_coders.json +1 -2
- package/assets/vendor/README.md +9 -0
- package/assets/vendor/vericify-reader.mjs +272 -0
- package/assets/vendor/vericify-reader.provenance.json +10 -0
- package/dist/ace-autonomy.d.ts +58 -0
- package/dist/ace-autonomy.js +211 -6
- package/dist/ace-internal-tools.d.ts +1 -0
- package/dist/ace-internal-tools.js +3 -3
- package/dist/ace-server-instructions.d.ts +3 -3
- package/dist/ace-server-instructions.js +46 -192
- package/dist/cli.js +44 -6
- package/dist/experience-reflector.d.ts +7 -0
- package/dist/experience-reflector.js +39 -0
- package/dist/goal-engine.d.ts +64 -7
- package/dist/goal-engine.js +197 -41
- package/dist/handoff-registry.d.ts +10 -0
- package/dist/handoff-registry.js +59 -0
- package/dist/helpers/artifacts.d.ts +6 -2
- package/dist/helpers/artifacts.js +8 -6
- package/dist/helpers/bootstrap.js +13 -20
- package/dist/helpers/path-utils.js +2 -0
- package/dist/helpers/store-resolution.js +18 -3
- package/dist/helpers/workspace-root.d.ts +2 -0
- package/dist/helpers/workspace-root.js +9 -0
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +1 -0
- package/dist/hermes/bridge-protocol.d.ts +1 -1
- package/dist/hermes/session-manager.d.ts +17 -0
- package/dist/hermes/session-manager.js +67 -14
- package/dist/host-goal-engine.d.ts +138 -0
- package/dist/host-goal-engine.js +793 -0
- package/dist/host-goal-status.d.ts +113 -0
- package/dist/host-goal-status.js +175 -0
- package/dist/host-learning.d.ts +68 -0
- package/dist/host-learning.js +115 -0
- package/dist/host-observation.d.ts +12 -0
- package/dist/host-observation.js +91 -0
- package/dist/host-plan-revision.d.ts +14 -0
- package/dist/host-plan-revision.js +101 -0
- package/dist/host-verification-job.d.ts +12 -0
- package/dist/host-verification-job.js +183 -0
- package/dist/host-work-context.d.ts +12 -0
- package/dist/host-work-context.js +8 -0
- package/dist/job-scheduler.d.ts +58 -13
- package/dist/job-scheduler.js +298 -48
- package/dist/job-worker.d.ts +3 -1
- package/dist/job-worker.js +10 -3
- package/dist/kanban.d.ts +4 -1
- package/dist/kanban.js +44 -16
- package/dist/learned-artifacts.d.ts +64 -0
- package/dist/learned-artifacts.js +321 -0
- package/dist/learning-controls.d.ts +142 -0
- package/dist/learning-controls.js +135 -0
- package/dist/learning-input-context.d.ts +9 -0
- package/dist/learning-input-context.js +62 -0
- package/dist/learning-lifecycle.d.ts +10 -0
- package/dist/learning-lifecycle.js +11 -0
- package/dist/learning-overlays.d.ts +3 -0
- package/dist/learning-overlays.js +17 -0
- package/dist/learning-policy.d.ts +40 -0
- package/dist/learning-policy.js +38 -0
- package/dist/learning-records.d.ts +35 -0
- package/dist/learning-records.js +17 -0
- package/dist/learning-scorecard.d.ts +82 -0
- package/dist/learning-scorecard.js +86 -0
- package/dist/learning-serving.d.ts +29 -0
- package/dist/learning-serving.js +134 -0
- package/dist/linked-work.d.ts +9 -0
- package/dist/linked-work.js +28 -0
- package/dist/local-model-runtime.js +1 -1
- package/dist/mcp-command-progress.d.ts +16 -0
- package/dist/mcp-command-progress.js +70 -0
- package/dist/model-bridge.d.ts +14 -13
- package/dist/model-bridge.js +73 -41
- package/dist/orchestrator-supervisor.d.ts +111 -6
- package/dist/orchestrator-supervisor.js +67 -43
- package/dist/plan-proposal.js +3 -3
- package/dist/playbook-curator.d.ts +1 -0
- package/dist/playbook-curator.js +11 -9
- package/dist/process-identity.d.ts +8 -0
- package/dist/process-identity.js +38 -0
- package/dist/progress-command.d.ts +34 -0
- package/dist/progress-command.js +153 -0
- package/dist/prompts.js +15 -15
- package/dist/resources.js +2 -2
- package/dist/runtime-command.d.ts +8 -1
- package/dist/runtime-command.js +48 -7
- package/dist/runtime-executor.js +33 -11
- package/dist/runtime-profile-syntax.d.ts +6 -0
- package/dist/runtime-profile-syntax.js +121 -0
- package/dist/runtime-profile.d.ts +37 -5
- package/dist/runtime-profile.js +36 -129
- package/dist/runtime-tool-specs.js +1 -1
- package/dist/safe-edit.d.ts +7 -3
- package/dist/safe-edit.js +40 -47
- package/dist/schemas.js +4 -2
- package/dist/server.d.ts +2 -16
- package/dist/server.js +14 -20
- package/dist/shared.d.ts +2 -0
- package/dist/shared.js +2 -0
- package/dist/skill-auditor.d.ts +19 -0
- package/dist/skill-auditor.js +32 -2
- package/dist/skill-catalog.d.ts +4 -1
- package/dist/skill-catalog.js +6 -5
- package/dist/store/ace-packed-store.d.ts +5 -1
- package/dist/store/ace-packed-store.js +33 -1
- package/dist/store/bootstrap-store.js +19 -12
- package/dist/store/cache-workspace.d.ts +8 -0
- package/dist/store/cache-workspace.js +94 -27
- package/dist/store/importer.js +11 -20
- package/dist/store/knowledge-bake.d.ts +3 -1
- package/dist/store/knowledge-bake.js +10 -1
- package/dist/store/legacy-vericify-posts.d.ts +8 -0
- package/dist/store/legacy-vericify-posts.js +76 -0
- package/dist/store/materializers/hook-context-materializer.d.ts +2 -1
- package/dist/store/materializers/hook-context-materializer.js +6 -2
- package/dist/store/materializers/host-file-materializer.js +2 -2
- package/dist/store/materializers/projection-manager.d.ts +4 -1
- package/dist/store/materializers/projection-manager.js +10 -3
- package/dist/store/materializers/todo-syncer.d.ts +39 -20
- package/dist/store/materializers/todo-syncer.js +208 -110
- package/dist/store/materializers/vericify-projector.js +15 -26
- package/dist/store/repositories/goal-repository.d.ts +51 -2
- package/dist/store/repositories/goal-repository.js +114 -48
- package/dist/store/repositories/playbook-repository.d.ts +41 -3
- package/dist/store/repositories/playbook-repository.js +61 -5
- package/dist/store/repositories/todo-repository.d.ts +8 -2
- package/dist/store/repositories/todo-repository.js +1 -1
- package/dist/store/repositories/vericify-repository.d.ts +4 -0
- package/dist/store/repositories/vericify-repository.js +46 -0
- package/dist/store/skills-install.d.ts +1 -0
- package/dist/store/skills-install.js +20 -16
- package/dist/store/source-preservation.d.ts +24 -0
- package/dist/store/source-preservation.js +79 -0
- package/dist/store/store-artifacts.js +8 -1
- package/dist/store/test-write-boundary.d.ts +16 -0
- package/dist/store/test-write-boundary.js +175 -0
- package/dist/store/types.d.ts +5 -1
- package/dist/store/write-coordinator.js +16 -0
- package/dist/task-plan-context.d.ts +11 -0
- package/dist/task-plan-context.js +59 -0
- package/dist/todo-state.d.ts +19 -9
- package/dist/todo-state.js +204 -321
- package/dist/tools-agent.d.ts +1 -1
- package/dist/tools-agent.js +38 -62
- package/dist/tools-files.d.ts +0 -3
- package/dist/tools-files.js +21 -11
- package/dist/tools-framework.js +16 -25
- package/dist/tools-goal.d.ts +2 -4
- package/dist/tools-goal.js +119 -16
- package/dist/tools-handoff.d.ts +3 -2
- package/dist/tools-handoff.js +53 -23
- package/dist/tools-lifecycle.js +1 -1
- package/dist/tools-memory.d.ts +0 -3
- package/dist/tools-memory.js +51 -6
- package/dist/tools-scheduler.js +20 -17
- package/dist/tools-todo.js +160 -148
- package/dist/vericify-bridge.d.ts +8 -0
- package/dist/vericify-bridge.js +18 -0
- package/dist/vericify-context.d.ts +4 -0
- package/dist/vericify-context.js +26 -5
- package/dist/vericify-native.d.ts +101 -0
- package/dist/vericify-native.js +221 -0
- package/dist/verification-worker.d.ts +2 -0
- package/dist/verification-worker.js +31 -0
- package/docs/mcp-tool-reference.md +50 -10
- package/docs/troubleshooting.md +29 -0
- package/package.json +19 -6
- package/scripts/dev/run-tests-isolated.mjs +165 -0
- package/scripts/dev/run_hermes_crispr_live.mjs +1 -0
- package/scripts/dev/test-isolation-guard.mjs +20 -0
- package/scripts/dev/test-preload.mjs +153 -0
- package/scripts/dev/test-source-inventory.mjs +31 -0
- package/docs/development.md +0 -46
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
4
3
|
import { resolve } from "node:path";
|
|
5
4
|
|
|
6
5
|
const DESTRUCTIVE_COMMAND_PATTERNS = [
|
|
@@ -14,23 +13,8 @@ const DESTRUCTIVE_COMMAND_PATTERNS = [
|
|
|
14
13
|
/\bmkfs\b/i,
|
|
15
14
|
];
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
"agent-state",
|
|
20
|
-
"global-state",
|
|
21
|
-
"venture-state",
|
|
22
|
-
"brand-state",
|
|
23
|
-
"engineering-state",
|
|
24
|
-
];
|
|
25
|
-
const ACE_CORE_FILES = [
|
|
26
|
-
"agent-state/TASK.md",
|
|
27
|
-
"agent-state/STATUS.md",
|
|
28
|
-
"agent-state/SCOPE.md",
|
|
29
|
-
"agent-state/EVIDENCE_LOG.md",
|
|
30
|
-
];
|
|
31
|
-
const STORE_MAGIC = "ACEPACK1";
|
|
32
|
-
const STORE_HEADER_SIZE = 32;
|
|
33
|
-
const HOOK_CONTEXT_STORE_KEY = "state/runtime/hook_context";
|
|
16
|
+
// Replaced with the installed module URL when projected into a workspace.
|
|
17
|
+
const ACE_AUTONOMY_MODULE_URL = "__ACE_AUTONOMY_MODULE_URL__";
|
|
34
18
|
|
|
35
19
|
const PROTECTED_PATH_FRAGMENTS = [
|
|
36
20
|
".github/hooks/",
|
|
@@ -47,15 +31,6 @@ const PROTECTED_PATH_FRAGMENTS = [
|
|
|
47
31
|
".vscode\\settings.json",
|
|
48
32
|
];
|
|
49
33
|
|
|
50
|
-
const ROLE_TOOL_HINTS = {
|
|
51
|
-
orchestrator: ["recall_context", "route_task", "create_handoff", "execute_gates", "emit_status_event"],
|
|
52
|
-
coders: ["read_workspace_file", "safe_edit_file", "run_tests", "git_diff", "execute_gates"],
|
|
53
|
-
qa: ["read_workspace_file", "run_tests", "execute_gates", "git_diff", "append_vericify_process_post"],
|
|
54
|
-
docs: ["read_workspace_file", "write_workspace_file", "git_diff", "append_vericify_process_post"],
|
|
55
|
-
research: ["recall_context", "read_workspace_file", "build_continuity_packet", "append_vericify_process_post"],
|
|
56
|
-
spec: ["read_workspace_file", "write_workspace_file", "execute_gates", "append_vericify_process_post"],
|
|
57
|
-
};
|
|
58
|
-
|
|
59
34
|
function readStdin() {
|
|
60
35
|
return new Promise((resolveStdin, reject) => {
|
|
61
36
|
let input = "";
|
|
@@ -90,345 +65,17 @@ function resolveWorkspaceRoot(payload) {
|
|
|
90
65
|
return resolve(cwd);
|
|
91
66
|
}
|
|
92
67
|
|
|
93
|
-
function
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (normalized === ACE_ROOT || normalized.startsWith(`${ACE_ROOT}/`)) {
|
|
98
|
-
return normalized;
|
|
99
|
-
}
|
|
100
|
-
for (const prefix of ["agent-state", "global-state", "venture-state", "brand-state", "engineering-state"]) {
|
|
101
|
-
if (normalized === prefix || normalized.startsWith(`${prefix}/`)) {
|
|
102
|
-
return `${ACE_ROOT}/${normalized}`;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return normalized;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function resolveAcePath(workspaceRoot, relativePath) {
|
|
109
|
-
const canonical = resolve(workspaceRoot, mapAceRelativePath(relativePath));
|
|
110
|
-
const normalized = String(relativePath).replace(/\\/g, "/").replace(/^\.?\//, "");
|
|
111
|
-
if (normalized && normalized !== mapAceRelativePath(relativePath)) {
|
|
112
|
-
const legacy = resolve(workspaceRoot, normalized);
|
|
113
|
-
if (!existsSync(canonical) && existsSync(legacy)) {
|
|
114
|
-
return legacy;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
return canonical;
|
|
118
|
-
}
|
|
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
|
-
|
|
152
|
-
function readIfPresent(workspaceRoot, relativePath) {
|
|
153
|
-
const absolute = resolveAcePath(workspaceRoot, relativePath);
|
|
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
|
-
}
|
|
175
|
-
try {
|
|
176
|
-
return readFileSync(absolute, "utf8");
|
|
177
|
-
} catch {
|
|
178
|
-
return undefined;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function oneLine(value) {
|
|
183
|
-
return String(value ?? "")
|
|
184
|
-
.replace(/\s+/g, " ")
|
|
185
|
-
.trim();
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
function truncate(value, max = 160) {
|
|
189
|
-
const text = oneLine(value);
|
|
190
|
-
if (text.length <= max) return text;
|
|
191
|
-
return `${text.slice(0, Math.max(0, max - 1)).trimEnd()}…`;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
function extractTaskObjective(workspaceRoot) {
|
|
195
|
-
const raw = readIfPresent(workspaceRoot, "agent-state/TASK.md");
|
|
196
|
-
if (!raw) return undefined;
|
|
197
|
-
const match = raw.match(/## Objective\s+([\s\S]*?)(?:\n## |\n# |$)/);
|
|
198
|
-
if (match?.[1]) {
|
|
199
|
-
return truncate(match[1]);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const bodyLine = raw
|
|
203
|
-
.split(/\r?\n/)
|
|
204
|
-
.map((line) => line.trim())
|
|
205
|
-
.find((line) => line && !line.startsWith("#"));
|
|
206
|
-
if (bodyLine) {
|
|
207
|
-
return truncate(bodyLine);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const heading = raw.match(/^#\s+(.+)$/m)?.[1];
|
|
211
|
-
return heading ? truncate(heading) : undefined;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function extractStatusLine(workspaceRoot, label) {
|
|
215
|
-
const raw = readIfPresent(workspaceRoot, "agent-state/STATUS.md");
|
|
216
|
-
if (!raw) return undefined;
|
|
217
|
-
const pattern = new RegExp(`^- ${label}:\\s*(.+)$`, "m");
|
|
218
|
-
const match = raw.match(pattern);
|
|
219
|
-
return match?.[1] ? truncate(match[1]) : undefined;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
function extractScopeReminder(workspaceRoot) {
|
|
223
|
-
const raw = readIfPresent(workspaceRoot, "agent-state/SCOPE.md");
|
|
224
|
-
if (!raw) return undefined;
|
|
225
|
-
const lines = raw
|
|
226
|
-
.split(/\r?\n/)
|
|
227
|
-
.map((line) => line.trim())
|
|
228
|
-
.filter(Boolean)
|
|
229
|
-
.filter((line) => !line.startsWith("#"));
|
|
230
|
-
if (lines.length === 0) {
|
|
231
|
-
return `ACE scope reminder: review ${ACE_ROOT}/agent-state/SCOPE.md before mutating files or state.`;
|
|
232
|
-
}
|
|
233
|
-
return `ACE scope reminder: ${truncate(lines.slice(0, 4).join(" "), 220)}`;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
function extractRoleHint(payload) {
|
|
237
|
-
const candidates = [
|
|
238
|
-
payload.role,
|
|
239
|
-
payload.agentRole,
|
|
240
|
-
payload.agent_role,
|
|
241
|
-
payload.subagentRole,
|
|
242
|
-
payload.subagent_role,
|
|
243
|
-
payload?.subagent?.role,
|
|
244
|
-
payload?.tool_input?.role,
|
|
245
|
-
];
|
|
246
|
-
for (const candidate of candidates) {
|
|
247
|
-
if (typeof candidate !== "string") continue;
|
|
248
|
-
const normalized = candidate.trim().toLowerCase().replace(/^agent-/, "");
|
|
249
|
-
if (normalized) return normalized;
|
|
250
|
-
}
|
|
251
|
-
return undefined;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
function buildRoleToolHint(role) {
|
|
255
|
-
const tools = ROLE_TOOL_HINTS[role];
|
|
256
|
-
if (!tools || tools.length === 0) return undefined;
|
|
257
|
-
return `Suggested ACE tools for ${role}: ${tools.join(", ")}.`;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Try to read the store-backed hook context snapshot.
|
|
262
|
-
* Returns the parsed snapshot or undefined if not present / unreadable.
|
|
263
|
-
*/
|
|
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
|
-
}
|
|
274
|
-
const snapshotPath = resolve(workspaceRoot, ACE_ROOT, "ace-hook-context.json");
|
|
275
|
-
if (!existsSync(snapshotPath)) return undefined;
|
|
276
|
-
try {
|
|
277
|
-
const raw = readFileSync(snapshotPath, "utf8");
|
|
278
|
-
const parsed = JSON.parse(raw);
|
|
279
|
-
if (parsed?.schema_version !== 1) return undefined;
|
|
280
|
-
return parsed;
|
|
281
|
-
} catch {
|
|
282
|
-
return undefined;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
function aceContext(workspaceRoot) {
|
|
287
|
-
// ── Fast path: store-backed snapshot ────────────────────────────────────
|
|
288
|
-
const snapshot = tryReadHookContextSnapshot(workspaceRoot);
|
|
289
|
-
if (snapshot) {
|
|
290
|
-
const taskObjective = snapshot.task?.content
|
|
291
|
-
? truncate(snapshot.task.content.split("\n").find((l) => l.trim() && !l.startsWith("#")) ?? snapshot.task.content)
|
|
292
|
-
: undefined;
|
|
293
|
-
const scopeContent = snapshot.scope?.content ?? "";
|
|
294
|
-
const scopeLines = scopeContent.split(/\r?\n/).map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
295
|
-
const scopeReminder = scopeLines.length
|
|
296
|
-
? `ACE scope reminder: ${truncate(scopeLines.slice(0, 4).join(" "), 220)}`
|
|
297
|
-
: undefined;
|
|
298
|
-
const hasAgentState =
|
|
299
|
-
existsSync(resolve(workspaceRoot, ACE_ROOT, "agent-state")) ||
|
|
300
|
-
existsSync(resolve(workspaceRoot, "agent-state", "ace-state.ace"));
|
|
301
|
-
const hasSkills = existsSync(resolve(workspaceRoot, ACE_ROOT, "skills")) ||
|
|
302
|
-
existsSync(resolve(workspaceRoot, ".agents", "skills"));
|
|
303
|
-
return {
|
|
304
|
-
coreFiles: [],
|
|
305
|
-
stateDirs: [],
|
|
306
|
-
taskObjective,
|
|
307
|
-
currentPhase: undefined,
|
|
308
|
-
blockers: undefined,
|
|
309
|
-
hasSkills,
|
|
310
|
-
hasAgentState,
|
|
311
|
-
scopeReminder,
|
|
312
|
-
activeAgents: snapshot.active_agents ?? [],
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
// ── Legacy path: read individual markdown files ─────────────────────────
|
|
317
|
-
const stateDirs = ACE_STATE_DIRS
|
|
318
|
-
.map((relPath) => `${ACE_ROOT}/${relPath}`)
|
|
319
|
-
.filter((relPath) => existsSync(resolveAcePath(workspaceRoot, relPath)));
|
|
320
|
-
const coreFiles = ACE_CORE_FILES
|
|
321
|
-
.map((relPath) => `${ACE_ROOT}/${relPath}`)
|
|
322
|
-
.filter((relPath) => existsSync(resolveAcePath(workspaceRoot, relPath)));
|
|
323
|
-
|
|
324
|
-
const taskObjective = extractTaskObjective(workspaceRoot);
|
|
325
|
-
const currentPhase = extractStatusLine(workspaceRoot, "Current phase");
|
|
326
|
-
const blockers = extractStatusLine(workspaceRoot, "Blockers");
|
|
327
|
-
const hasSkills =
|
|
328
|
-
existsSync(resolve(workspaceRoot, ".agents", "ACE", "skills")) ||
|
|
329
|
-
existsSync(resolve(workspaceRoot, ".agents", "skills"));
|
|
330
|
-
const hasAgentState =
|
|
331
|
-
existsSync(resolve(workspaceRoot, ".agents", "ACE", "agent-state")) ||
|
|
332
|
-
existsSync(resolve(workspaceRoot, "agent-state"));
|
|
333
|
-
const scopeReminder = extractScopeReminder(workspaceRoot);
|
|
334
|
-
|
|
335
|
-
return {
|
|
336
|
-
coreFiles,
|
|
337
|
-
stateDirs,
|
|
338
|
-
taskObjective,
|
|
339
|
-
currentPhase,
|
|
340
|
-
blockers,
|
|
341
|
-
hasSkills,
|
|
342
|
-
hasAgentState,
|
|
343
|
-
scopeReminder,
|
|
344
|
-
activeAgents: [],
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
function readAutonomyHint(workspaceRoot) {
|
|
349
|
-
const workflowPath = resolveAcePath(workspaceRoot, "agent-state/ACE_WORKFLOW.md");
|
|
350
|
-
const defaultHint =
|
|
351
|
-
"Runtime autonomy defaults are active: orchestrator preflight, context recall.";
|
|
352
|
-
if (!existsSync(workflowPath)) return defaultHint;
|
|
353
|
-
|
|
354
|
-
let raw = "";
|
|
68
|
+
async function currentWorkContext(workspaceRoot, payload) {
|
|
69
|
+
const moduleUrl = ACE_AUTONOMY_MODULE_URL.startsWith("__")
|
|
70
|
+
? new URL("../../dist/ace-autonomy.js", import.meta.url).href
|
|
71
|
+
: ACE_AUTONOMY_MODULE_URL;
|
|
355
72
|
try {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
return
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
const signals = [];
|
|
362
|
-
if (/^\s*orchestrator_preflight:\s*true\s*$/m.test(raw)) {
|
|
363
|
-
signals.push("orchestrator preflight");
|
|
364
|
-
}
|
|
365
|
-
if (/^\s*recall_context:\s*true\s*$/m.test(raw)) {
|
|
366
|
-
signals.push("context recall");
|
|
367
|
-
}
|
|
368
|
-
const reviewMode = raw.match(/^\s*review_mode:\s*["']?([A-Za-z0-9_-]+)["']?\s*$/m)?.[1];
|
|
369
|
-
if (reviewMode) {
|
|
370
|
-
signals.push(`review mode ${reviewMode}`);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
return signals.length > 0
|
|
374
|
-
? `Runtime autonomy policy is active in ${ACE_ROOT}/agent-state/ACE_WORKFLOW.md: ${signals.join(", ")}.`
|
|
375
|
-
: defaultHint;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
function buildAceMessage(workspaceRoot, options = {}) {
|
|
379
|
-
const context = aceContext(workspaceRoot);
|
|
380
|
-
if (!context.hasAgentState && !context.hasSkills) return "";
|
|
381
|
-
|
|
382
|
-
const parts = [];
|
|
383
|
-
if (context.coreFiles.length > 0) {
|
|
384
|
-
parts.push(`ACE workspace detected. Ground truth lives in ${context.coreFiles.join(", ")}.`);
|
|
385
|
-
} else if (context.hasAgentState) {
|
|
386
|
-
parts.push(`ACE workspace detected. Ground truth lives in ${ACE_ROOT}/agent-state/*.`);
|
|
387
|
-
}
|
|
388
|
-
if (context.taskObjective) {
|
|
389
|
-
parts.push(`Current task: ${context.taskObjective}.`);
|
|
390
|
-
}
|
|
391
|
-
if (context.currentPhase) {
|
|
392
|
-
parts.push(`Current phase: ${context.currentPhase}.`);
|
|
393
|
-
}
|
|
394
|
-
if (context.blockers) {
|
|
395
|
-
parts.push(`Blockers: ${context.blockers}.`);
|
|
396
|
-
}
|
|
397
|
-
if (context.stateDirs.length > 0) {
|
|
398
|
-
parts.push(
|
|
399
|
-
`Persist durable artifacts under ${context.stateDirs.map((dir) => `${dir}/`).join(", ")} rather than editor session caches such as workspaceStorage/.../chat-session-resources/.`
|
|
400
|
-
);
|
|
401
|
-
}
|
|
402
|
-
parts.push(
|
|
403
|
-
"Before major edits, read task, scope, and status artifacts rather than relying on chat history."
|
|
404
|
-
);
|
|
405
|
-
if (context.scopeReminder) {
|
|
406
|
-
parts.push(context.scopeReminder);
|
|
407
|
-
}
|
|
408
|
-
if (context.hasSkills) {
|
|
409
|
-
parts.push(`Workspace skills are available under ${ACE_ROOT}/skills/.`);
|
|
410
|
-
}
|
|
411
|
-
const autonomyHint = readAutonomyHint(workspaceRoot);
|
|
412
|
-
if (autonomyHint) {
|
|
413
|
-
parts.push(autonomyHint);
|
|
414
|
-
}
|
|
415
|
-
const roleHint = extractRoleHint(options.payload ?? {});
|
|
416
|
-
if (roleHint && (options.eventName === "SubagentStart" || options.eventName === "UserPromptSubmit")) {
|
|
417
|
-
parts.push(`Assigned ACE role: ${roleHint}.`);
|
|
418
|
-
const toolHint = buildRoleToolHint(roleHint);
|
|
419
|
-
if (toolHint) {
|
|
420
|
-
parts.push(toolHint);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
const promptText =
|
|
424
|
-
typeof options.payload?.prompt === "string" ? options.payload.prompt.trim() : "";
|
|
425
|
-
if (promptText && options.eventName === "UserPromptSubmit") {
|
|
426
|
-
parts.push(`Latest prompt: ${truncate(promptText, 180)}.`);
|
|
73
|
+
const { resolveCurrentWork, formatCurrentWork } = await import(moduleUrl);
|
|
74
|
+
const work = resolveCurrentWork({ workspaceRoot, goal_id: payload.goal_id, agent: payload.agent_id });
|
|
75
|
+
return formatCurrentWork(work, "block");
|
|
76
|
+
} catch (error) {
|
|
77
|
+
return `ACE current work unavailable: ${error.message}. Use recall_context to recover it.`;
|
|
427
78
|
}
|
|
428
|
-
parts.push(
|
|
429
|
-
`ACE hook policy protects ${ACE_ROOT}/.github/hooks, ${ACE_ROOT}/.vscode/settings.json, and ${ACE_ROOT}/scripts/ace/*hook-dispatch.mjs from silent self-modification.`
|
|
430
|
-
);
|
|
431
|
-
return parts.join(" ");
|
|
432
79
|
}
|
|
433
80
|
|
|
434
81
|
function isCommandTool(toolName) {
|
|
@@ -495,62 +142,20 @@ function resolvePreToolUse(payload, workspaceRoot) {
|
|
|
495
142
|
};
|
|
496
143
|
}
|
|
497
144
|
|
|
498
|
-
const message = buildAceMessage(workspaceRoot, {
|
|
499
|
-
payload,
|
|
500
|
-
eventName: "PreToolUse",
|
|
501
|
-
});
|
|
502
|
-
if (isMutationTool(toolName) && message) {
|
|
503
|
-
return {
|
|
504
|
-
continue: true,
|
|
505
|
-
hookSpecificOutput: {
|
|
506
|
-
hookEventName: "PreToolUse",
|
|
507
|
-
permissionDecision: "allow",
|
|
508
|
-
additionalContext: `${message} Confirm the target stays within scope before mutating files or state, and persist evidence after the change.`,
|
|
509
|
-
},
|
|
510
|
-
};
|
|
511
|
-
}
|
|
512
|
-
|
|
513
145
|
return { continue: true };
|
|
514
146
|
}
|
|
515
147
|
|
|
516
|
-
function
|
|
517
|
-
const toolName = toLowerText(payload.tool_name);
|
|
518
|
-
if (!isMutationTool(toolName)) {
|
|
519
|
-
return { continue: true };
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
const message = buildAceMessage(workspaceRoot, {
|
|
523
|
-
payload,
|
|
524
|
-
eventName: "PostToolUse",
|
|
525
|
-
});
|
|
526
|
-
return {
|
|
527
|
-
continue: true,
|
|
528
|
-
hookSpecificOutput: {
|
|
529
|
-
hookEventName: "PostToolUse",
|
|
530
|
-
additionalContext: message
|
|
531
|
-
? `${message} If project files or state changed, reconcile evidence, run the smallest relevant verification, and call execute_gates before concluding.`
|
|
532
|
-
: "If project files or state changed, run the smallest relevant verification and call execute_gates before concluding.",
|
|
533
|
-
},
|
|
534
|
-
};
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
function resolveSessionContext(payload, workspaceRoot, eventName) {
|
|
538
|
-
const message = buildAceMessage(workspaceRoot, {
|
|
539
|
-
payload,
|
|
540
|
-
eventName,
|
|
541
|
-
});
|
|
542
|
-
if (!message) return { continue: true };
|
|
543
|
-
|
|
148
|
+
async function resolveSessionContext(payload, workspaceRoot, eventName) {
|
|
544
149
|
return {
|
|
545
150
|
continue: true,
|
|
546
151
|
hookSpecificOutput: {
|
|
547
152
|
hookEventName: eventName,
|
|
548
|
-
additionalContext:
|
|
153
|
+
additionalContext: await currentWorkContext(workspaceRoot, payload),
|
|
549
154
|
},
|
|
550
155
|
};
|
|
551
156
|
}
|
|
552
157
|
|
|
553
|
-
function resolveHook(payload) {
|
|
158
|
+
async function resolveHook(payload) {
|
|
554
159
|
const eventName = toLowerText(payload.hookEventName);
|
|
555
160
|
const workspaceRoot = resolveWorkspaceRoot(payload);
|
|
556
161
|
|
|
@@ -571,7 +176,7 @@ function resolveHook(payload) {
|
|
|
571
176
|
}
|
|
572
177
|
|
|
573
178
|
if (eventName === "posttooluse") {
|
|
574
|
-
return
|
|
179
|
+
return { continue: true };
|
|
575
180
|
}
|
|
576
181
|
|
|
577
182
|
if (eventName === "precompact") {
|
|
@@ -589,7 +194,7 @@ async function main() {
|
|
|
589
194
|
try {
|
|
590
195
|
const raw = await readStdin();
|
|
591
196
|
const payload = raw.trim() ? JSON.parse(raw) : {};
|
|
592
|
-
writeJson(resolveHook(payload));
|
|
197
|
+
writeJson(await resolveHook(payload));
|
|
593
198
|
} catch (error) {
|
|
594
199
|
const message = error instanceof Error ? error.message : String(error);
|
|
595
200
|
writeJson({
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
The Vericify native reader is vendored unchanged from the maintained Vericify integration at the commit recorded in `vericify-reader.provenance.json`, which also pins its SHA-256. ACE loads this package asset at runtime; no sibling checkout, source import, store parser, or writable Vericify store is required.
|
|
2
|
+
|
|
3
|
+
ACE uses only the client's `window(...)` query: one bounded native `adapter window` invocation per attempt, inside the configured total deadline. ACE does not traverse `info`/`page` results or join records from different snapshots. The owner returns pending, expired or complete state with an acknowledged `next_after` position; ACE encodes that position in its `vcn1:` cursor and does not walk further windows automatically.
|
|
4
|
+
|
|
5
|
+
Native failures arrive as typed `NativeReadError` codes (`stale_snapshot`, `missing_history`, `incompatible_protocol`, `capacity`, `timeout`, `invalid_query`, `identity_mismatch`, `expired`, `unavailable`) with an owner-set `retryable` flag. Raw native output and process errors are discarded. ACE retries only owner-marked retryable errors and keeps the codes distinct in its sanitized reasons.
|
|
6
|
+
|
|
7
|
+
The native window independently verifies the supplied workspace root against the recorded workspace within its pinned read lifetime. ACE also canonicalizes the configured `workspace_root` and checks the returned `workspace_id`, plus the optional incarnation pin.
|
|
8
|
+
|
|
9
|
+
License: the Vericify owner authorized distribution of `vericify-reader.mjs` alone, inside this package, under the package's Apache-2.0 [`LICENSE`](../../LICENSE) (recorded in the provenance file, 2026-10-21). That authorization covers no other Vericify source, binary or package.
|