agentic-engineering-harness 0.6.22 → 0.6.24

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.
@@ -0,0 +1,278 @@
1
+ import crypto from "node:crypto";
2
+ import fs from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { validateAgentOutput } from "../agents/outputContracts.js";
6
+ import { extractMarkedJson, StructuredOutputError } from "../agents/structuredOutput.js";
7
+ import { operationArtifactDir, resolveOperationStateRoot, updateOperationParticipant } from "../operations/state.js";
8
+ const CHANNELS_DIR = "result-channels";
9
+ const RESULTS_DIR = "results";
10
+ const GLOBAL_INDEX_DIR = path.join(".harness", "result-channels", "agents");
11
+ const LOCK_RETRY_MS = 10;
12
+ const LOCK_TIMEOUT_MS = 5_000;
13
+ export async function provisionStructuredResultChannel(root, input) {
14
+ const stateRoot = resolveOperationStateRoot(root);
15
+ const channelId = input.channelId ?? crypto.randomUUID();
16
+ const file = channelFile(stateRoot, input.operationId, channelId);
17
+ try {
18
+ return await readJson(file);
19
+ }
20
+ catch {
21
+ const now = new Date().toISOString();
22
+ const channel = {
23
+ version: 1,
24
+ operationId: input.operationId,
25
+ channelId,
26
+ logicalAgent: input.logicalAgent,
27
+ role: input.role,
28
+ contract: input.contract,
29
+ createdAt: now,
30
+ updatedAt: now,
31
+ sequence: 0
32
+ };
33
+ await writeJsonAtomic(file, channel);
34
+ return channel;
35
+ }
36
+ }
37
+ export async function bindStructuredResultChannel(root, operationId, channelId, agentId) {
38
+ const stateRoot = resolveOperationStateRoot(root);
39
+ const channel = await mutateChannel(stateRoot, operationId, channelId, (current) => ({
40
+ ...current,
41
+ agentId,
42
+ updatedAt: new Date().toISOString()
43
+ }));
44
+ const index = agentIndexFile(stateRoot, agentId);
45
+ await writeJsonAtomic(index, { version: 1, operationId, channelId, agentId });
46
+ return channel;
47
+ }
48
+ export async function activateStructuredResultTurn(root, operationId, channelId, phase) {
49
+ const stateRoot = resolveOperationStateRoot(root);
50
+ const channel = await mutateChannel(stateRoot, operationId, channelId, (current) => {
51
+ const sequence = current.sequence + 1;
52
+ const now = new Date().toISOString();
53
+ return {
54
+ ...current,
55
+ sequence,
56
+ updatedAt: now,
57
+ activeTurn: {
58
+ id: `${String(sequence).padStart(4, "0")}-${crypto.randomUUID()}`,
59
+ sequence,
60
+ contract: current.contract,
61
+ phase,
62
+ status: "PENDING",
63
+ attempts: 0,
64
+ activatedAt: now
65
+ }
66
+ };
67
+ });
68
+ if (!channel.activeTurn)
69
+ throw new Error("AEH_RESULT_CHANNEL_STATE: active result turn was not created.");
70
+ return channel.activeTurn;
71
+ }
72
+ export async function activateStructuredResultTurnForAgent(root, agentId, phase) {
73
+ const binding = await loadAgentChannelBinding(root, agentId);
74
+ if (!binding)
75
+ return undefined;
76
+ return activateStructuredResultTurn(root, binding.operationId, binding.channelId, phase);
77
+ }
78
+ export async function acceptStructuredResult(root, operationId, channelId, payload, source) {
79
+ const stateRoot = resolveOperationStateRoot(root);
80
+ const file = channelFile(stateRoot, operationId, channelId);
81
+ return withFileLock(file, async () => {
82
+ const channel = await readJson(file);
83
+ const turn = channel.activeTurn;
84
+ if (!turn)
85
+ throw new Error("AEH_RESULT_NO_ACTIVE_TURN: result submission has no controller-activated turn.");
86
+ const validation = validateAgentOutput(turn.contract, payload);
87
+ if (!validation.ok) {
88
+ const failure = `SCHEMA_VALIDATION_FAILED: ${validation.issues.join("; ")}`;
89
+ channel.activeTurn = { ...turn, status: "REJECTED", attempts: turn.attempts + 1, error: failure };
90
+ channel.updatedAt = new Date().toISOString();
91
+ await writeJsonAtomic(file, channel);
92
+ throw new Error(failure);
93
+ }
94
+ const normalized = validation.value;
95
+ const canonical = JSON.stringify(normalized);
96
+ const sha256 = crypto.createHash("sha256").update(canonical).digest("hex");
97
+ if (turn.status === "ACCEPTED" && turn.sha256) {
98
+ if (turn.sha256 !== sha256) {
99
+ channel.activeTurn = { ...turn, status: "CONFLICT", attempts: turn.attempts + 1, error: "CONFLICTING_RESULT: a different valid payload was submitted for an already accepted turn." };
100
+ channel.updatedAt = new Date().toISOString();
101
+ await writeJsonAtomic(file, channel);
102
+ throw new Error("CONFLICTING_RESULT: a different valid payload was submitted for an already accepted turn.");
103
+ }
104
+ if (!turn.artifact)
105
+ throw new Error("AEH_RESULT_CHANNEL_STATE: accepted turn is missing its artifact reference.");
106
+ return { artifact: turn.artifact, sha256, payload: normalized, source: turn.source ?? source, turnId: turn.id, channelId };
107
+ }
108
+ const artifactEnvelope = {
109
+ version: 1,
110
+ kind: "agent-result",
111
+ operationId,
112
+ channelId,
113
+ turnId: turn.id,
114
+ sequence: turn.sequence,
115
+ logicalAgent: channel.logicalAgent,
116
+ role: channel.role,
117
+ agentId: channel.agentId,
118
+ contract: turn.contract,
119
+ source,
120
+ createdAt: new Date().toISOString(),
121
+ payloadSha256: sha256,
122
+ payload: normalized
123
+ };
124
+ const artifact = await persistResultArtifact(stateRoot, artifactEnvelope);
125
+ const acceptedAt = new Date().toISOString();
126
+ channel.activeTurn = {
127
+ ...turn,
128
+ status: "ACCEPTED",
129
+ attempts: turn.attempts + 1,
130
+ acceptedAt,
131
+ artifact,
132
+ sha256,
133
+ source,
134
+ error: undefined
135
+ };
136
+ channel.updatedAt = acceptedAt;
137
+ await writeJsonAtomic(file, channel);
138
+ if (channel.agentId) {
139
+ await updateOperationParticipant(stateRoot, operationId, channel.agentId, { resultArtifact: artifact }).catch(() => undefined);
140
+ }
141
+ return { artifact, sha256, payload: normalized, source, turnId: turn.id, channelId };
142
+ });
143
+ }
144
+ export async function acceptedStructuredResultForAgent(root, agentId) {
145
+ const binding = await loadAgentChannelBinding(root, agentId);
146
+ if (!binding)
147
+ return undefined;
148
+ const stateRoot = resolveOperationStateRoot(root);
149
+ const channel = await readJson(channelFile(stateRoot, binding.operationId, binding.channelId)).catch(() => undefined);
150
+ const turn = channel?.activeTurn;
151
+ if (!channel || !turn || turn.status !== "ACCEPTED" || !turn.artifact || !turn.sha256)
152
+ return undefined;
153
+ const envelope = await readJson(path.resolve(stateRoot, turn.artifact));
154
+ return { artifact: turn.artifact, sha256: turn.sha256, payload: envelope.payload, source: turn.source ?? envelope.source, turnId: turn.id, channelId: channel.channelId };
155
+ }
156
+ export async function reconcileStructuredResult(root, input) {
157
+ if (input.agentId) {
158
+ const accepted = await acceptedStructuredResultForAgent(root, input.agentId).catch(() => undefined);
159
+ if (accepted)
160
+ return { ok: true, accepted };
161
+ }
162
+ let payload;
163
+ try {
164
+ payload = extractMarkedJson(input.stdout, input.stderr ?? "");
165
+ }
166
+ catch (error) {
167
+ if (error instanceof StructuredOutputError)
168
+ return { ok: false, failure: `${error.reason}: ${error.message}` };
169
+ return { ok: false, failure: `OUTPUT_CONTRACT_UNKNOWN: ${String(error)}` };
170
+ }
171
+ try {
172
+ const channel = input.agentId
173
+ ? await ensureAgentChannel(root, input)
174
+ : await provisionStructuredResultChannel(root, { operationId: input.operationId, logicalAgent: input.logicalAgent, role: input.role, contract: input.contract });
175
+ if (!channel.activeTurn || channel.activeTurn.status === "ACCEPTED") {
176
+ await activateStructuredResultTurn(root, input.operationId, channel.channelId, input.phase);
177
+ }
178
+ const accepted = await acceptStructuredResult(root, input.operationId, channel.channelId, payload, "captured");
179
+ return { ok: true, accepted };
180
+ }
181
+ catch (error) {
182
+ return { ok: false, failure: error instanceof Error ? error.message : String(error) };
183
+ }
184
+ }
185
+ export async function projectAcceptedStructuredResult(root, agentId, result) {
186
+ const accepted = await acceptedStructuredResultForAgent(root, agentId).catch(() => undefined);
187
+ return accepted ? { ...result, stdout: JSON.stringify(accepted.payload) } : result;
188
+ }
189
+ export async function loadStructuredResultChannel(root, operationId, channelId) {
190
+ return readJson(channelFile(resolveOperationStateRoot(root), operationId, channelId));
191
+ }
192
+ export function resultSinkMcpServerDefinition(root, operationId, channelId) {
193
+ return {
194
+ type: "stdio",
195
+ command: process.execPath,
196
+ args: [fileURLToPath(new URL("./resultSinkMcp.js", import.meta.url))],
197
+ env: {
198
+ AEH_RESULT_CONTROL_ROOT: resolveOperationStateRoot(root),
199
+ AEH_RESULT_OPERATION_ID: operationId,
200
+ AEH_RESULT_CHANNEL_ID: channelId
201
+ },
202
+ alwaysLoad: true
203
+ };
204
+ }
205
+ async function ensureAgentChannel(root, input) {
206
+ if (!input.agentId)
207
+ throw new Error("agentId is required");
208
+ const binding = await loadAgentChannelBinding(root, input.agentId);
209
+ if (binding) {
210
+ const channel = await loadStructuredResultChannel(root, binding.operationId, binding.channelId);
211
+ if (channel.contract !== input.contract)
212
+ throw new Error(`AEH_RESULT_CONTRACT_MISMATCH: channel=${channel.contract} requested=${input.contract}`);
213
+ return channel;
214
+ }
215
+ const channel = await provisionStructuredResultChannel(root, input);
216
+ return bindStructuredResultChannel(root, input.operationId, channel.channelId, input.agentId);
217
+ }
218
+ async function loadAgentChannelBinding(root, agentId) {
219
+ const stateRoot = resolveOperationStateRoot(root);
220
+ return readJson(agentIndexFile(stateRoot, agentId)).catch(() => undefined);
221
+ }
222
+ async function persistResultArtifact(root, envelope) {
223
+ const dir = path.join(operationArtifactDir(root, envelope.operationId), RESULTS_DIR, safe(envelope.logicalAgent));
224
+ await fs.mkdir(dir, { recursive: true });
225
+ const file = path.join(dir, `${String(envelope.sequence).padStart(4, "0")}-${safe(envelope.turnId)}.json`);
226
+ await writeJsonAtomic(file, envelope);
227
+ return path.relative(resolveOperationStateRoot(root), file).replaceAll("\\", "/");
228
+ }
229
+ function channelFile(root, operationId, channelId) {
230
+ return path.join(operationArtifactDir(root, operationId), CHANNELS_DIR, `${safe(channelId)}.json`);
231
+ }
232
+ function agentIndexFile(root, agentId) { return path.resolve(root, GLOBAL_INDEX_DIR, `${safe(agentId)}.json`); }
233
+ function safe(value) { return value.trim().replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "result"; }
234
+ async function mutateChannel(root, operationId, channelId, mutate) {
235
+ const file = channelFile(root, operationId, channelId);
236
+ return withFileLock(file, async () => {
237
+ const current = await readJson(file);
238
+ const next = mutate(current);
239
+ await writeJsonAtomic(file, next);
240
+ return next;
241
+ });
242
+ }
243
+ async function withFileLock(file, action) {
244
+ const lock = `${file}.lock`;
245
+ await fs.mkdir(path.dirname(file), { recursive: true });
246
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
247
+ for (;;) {
248
+ try {
249
+ const handle = await fs.open(lock, "wx");
250
+ try {
251
+ return await action();
252
+ }
253
+ finally {
254
+ await handle.close().catch(() => undefined);
255
+ await fs.rm(lock, { force: true }).catch(() => undefined);
256
+ }
257
+ }
258
+ catch (error) {
259
+ const code = error.code;
260
+ if (code !== "EEXIST" || Date.now() >= deadline)
261
+ throw error;
262
+ await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_MS));
263
+ }
264
+ }
265
+ }
266
+ async function readJson(file) { return JSON.parse(await fs.readFile(file, "utf8")); }
267
+ async function writeJsonAtomic(file, value) {
268
+ await fs.mkdir(path.dirname(file), { recursive: true });
269
+ const temp = `${file}.${process.pid}.${crypto.randomUUID()}.tmp`;
270
+ await fs.writeFile(temp, `${JSON.stringify(value, null, 2)}\n`);
271
+ try {
272
+ await fs.rename(temp, file);
273
+ }
274
+ finally {
275
+ await fs.rm(temp, { force: true }).catch(() => undefined);
276
+ }
277
+ }
278
+ //# sourceMappingURL=resultGateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resultGateway.js","sourceRoot":"","sources":["../../src/workers/resultGateway.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ interface JsonRpcRequest {
2
+ jsonrpc?: string;
3
+ id?: string | number | null;
4
+ method?: string;
5
+ params?: Record<string, unknown>;
6
+ }
7
+ export declare function serveResultSinkMcp(): Promise<void>;
8
+ export declare function handleResultSinkRequest(request: JsonRpcRequest): Promise<Record<string, unknown>>;
9
+ export {};
@@ -0,0 +1,86 @@
1
+ import readline from "node:readline";
2
+ import process from "node:process";
3
+ import { pathToFileURL } from "node:url";
4
+ import { outputJsonSchema } from "../agents/outputContracts.js";
5
+ import { loadStructuredResultChannel } from "./resultGateway.js";
6
+ import { commitStructuredResult } from "./resultCommit.js";
7
+ export async function serveResultSinkMcp() {
8
+ const rl = readline.createInterface({ input: process.stdin, crlfDelay: Infinity });
9
+ for await (const line of rl) {
10
+ if (!line.trim())
11
+ continue;
12
+ let request;
13
+ try {
14
+ request = JSON.parse(line);
15
+ }
16
+ catch {
17
+ continue;
18
+ }
19
+ if (request.id === undefined || request.id === null)
20
+ continue;
21
+ try {
22
+ write({ jsonrpc: "2.0", id: request.id, result: await handleResultSinkRequest(request) });
23
+ }
24
+ catch (error) {
25
+ write({ jsonrpc: "2.0", id: request.id, error: { code: -32603, message: error instanceof Error ? error.message : String(error) } });
26
+ }
27
+ }
28
+ }
29
+ export async function handleResultSinkRequest(request) {
30
+ const root = requiredEnv("AEH_RESULT_CONTROL_ROOT");
31
+ const operationId = requiredEnv("AEH_RESULT_OPERATION_ID");
32
+ const channelId = requiredEnv("AEH_RESULT_CHANNEL_ID");
33
+ const channel = await loadStructuredResultChannel(root, operationId, channelId);
34
+ if (request.method === "initialize") {
35
+ return {
36
+ protocolVersion: typeof request.params?.protocolVersion === "string" ? request.params.protocolVersion : "2025-06-18",
37
+ capabilities: { tools: {} },
38
+ serverInfo: { name: "aeh-result-sink", version: "1" }
39
+ };
40
+ }
41
+ if (request.method === "ping")
42
+ return {};
43
+ if (request.method === "tools/list") {
44
+ return {
45
+ tools: [{
46
+ name: "aeh_submit_result",
47
+ description: `Submit the final ${channel.contract} contract result for the current controller-activated AEH turn. This durable submission is authoritative; operation, agent, contract and destination are controller-bound and cannot be supplied by the caller.`,
48
+ inputSchema: outputJsonSchema(channel.contract) ?? { type: "object", additionalProperties: true }
49
+ }]
50
+ };
51
+ }
52
+ if (request.method === "tools/call") {
53
+ const params = request.params ?? {};
54
+ if (params.name !== "aeh_submit_result")
55
+ throw new Error(`Unknown result sink tool '${String(params.name ?? "")}'.`);
56
+ const payload = object(params.arguments);
57
+ const accepted = await commitStructuredResult(root, operationId, channelId, payload, "mcp");
58
+ return {
59
+ content: [{ type: "text", text: `Accepted ${channel.contract} result ${accepted.sha256.slice(0, 12)} for the active AEH turn.` }],
60
+ structuredContent: {
61
+ status: "ACCEPTED",
62
+ contract: channel.contract,
63
+ artifact: accepted.artifact,
64
+ sha256: accepted.sha256,
65
+ turnId: accepted.turnId
66
+ }
67
+ };
68
+ }
69
+ throw new Error(`Unsupported MCP method: ${request.method ?? "<missing>"}`);
70
+ }
71
+ function requiredEnv(name) {
72
+ const value = process.env[name]?.trim();
73
+ if (!value)
74
+ throw new Error(`${name} is required for the AEH result sink.`);
75
+ return value;
76
+ }
77
+ function object(value) {
78
+ if (!value || typeof value !== "object" || Array.isArray(value))
79
+ throw new Error("aeh_submit_result arguments must be one JSON object matching the active output contract.");
80
+ return value;
81
+ }
82
+ function write(value) { process.stdout.write(`${JSON.stringify(value)}\n`); }
83
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
84
+ serveResultSinkMcp().catch((error) => { process.stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}\n`); process.exitCode = 1; });
85
+ }
86
+ //# sourceMappingURL=resultSinkMcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resultSinkMcp.js","sourceRoot":"","sources":["../../src/workers/resultSinkMcp.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-engineering-harness",
3
- "version": "0.6.22",
3
+ "version": "0.6.24",
4
4
  "description": "OSS-first engineering harness for deterministic, spec-driven, issue-driven, audit-governed and orchestration-first multi-agent software delivery.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,22 +1,23 @@
1
1
  ---
2
2
  name: structured-output-delivery
3
- description: Deliver machine-consumed AEH agent results as valid JSON that satisfies the runtime output contract.
3
+ description: Deliver machine-consumed AEH agent results through the controller-owned structured result channel.
4
4
  license: Apache-2.0
5
5
  ---
6
6
  # Structured Output Delivery
7
7
 
8
- This skill governs delivery format only. It never changes the task conclusion, findings, evidence, or lifecycle authority.
8
+ This skill governs delivery only. It never changes the task conclusion, findings, evidence, or lifecycle authority.
9
9
 
10
10
  When AEH supplies an output contract or JSON Schema:
11
11
 
12
12
  1. Treat the schema as authoritative and machine-consumed.
13
- 2. Return exactly one JSON value matching that schema as the final result.
14
- 3. Use ordinary ASCII JSON syntax. String delimiters must be U+0022 (`"`); never use typographic quotes such as `“` or `”`.
15
- 4. Do not wrap the JSON in Markdown fences, headings, bullets, or explanatory prose.
16
- 5. Do not omit required fields, rename fields, or invent undeclared fields to make serialization easier.
17
- 6. Preserve the semantic result already established by the task. Formatting repair must not add findings, remove findings, rerun tools, or change conclusions.
18
- 7. If the transport cannot return native structured output and AEH explicitly requests the marker fallback, return exactly one line in this form:
13
+ 2. Preserve the semantic result already established by the task. Delivery repair must not add findings, remove findings, rerun tools, or change conclusions.
14
+ 3. If the capability-scoped `aeh_submit_result` tool is available, call it exactly with the final contract object. Do not supply operation ids, agent ids, contract names, paths, or lifecycle state; those are controller-bound.
15
+ 4. A successful `aeh_submit_result` call is the authoritative delivery. Do not call it again with a different payload. If the provider requires a native structured final response, it may repeat the same object only for transport compatibility.
16
+ 5. If the tool rejects the payload, correct only the reported schema/serialization defect and resubmit the same semantic result.
17
+ 6. If no result-sink tool is available, return exactly one JSON value matching the schema. Use ordinary ASCII JSON syntax; string delimiters must be U+0022 (`"`), never typographic quotes.
18
+ 7. Do not wrap JSON in Markdown fences, headings, bullets, or explanatory prose.
19
+ 8. Only when AEH explicitly requests the legacy marker fallback and no result-sink tool is available, return exactly one line:
19
20
 
20
21
  `AEH_RESULT_JSON=<valid compact JSON>`
21
22
 
22
- Before completing the turn, check syntactically that the payload could be parsed by a standard JSON parser and that enum values and required fields match the supplied contract.
23
+ Before completing a fallback delivery, check syntactically that a standard JSON parser can parse the payload and that enum values and required fields match the supplied contract.