@gajae-code/coding-agent 0.12.5 → 0.12.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.
- package/CHANGELOG.md +32 -0
- package/README.md +4 -1
- package/dist/types/eval/backend.d.ts +2 -2
- package/dist/types/exec/bash-executor.d.ts +10 -8
- package/dist/types/extensibility/extensions/runner.d.ts +9 -7
- package/dist/types/gjc-runtime/launch-tmux.d.ts +22 -3
- package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
- package/dist/types/gjc-runtime/team-launch.d.ts +3 -1
- package/dist/types/gjc-runtime/team-runtime.d.ts +14 -2
- package/dist/types/gjc-runtime/team-store.d.ts +0 -4
- package/dist/types/gjc-runtime/team-workers.d.ts +5 -0
- package/dist/types/gjc-runtime/tmux-common.d.ts +1 -0
- package/dist/types/gjc-runtime/tmux-provider-context.d.ts +57 -0
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +8 -1
- package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +3 -0
- package/dist/types/gjc-runtime/ultragoal-review-source.d.ts +83 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +57 -4
- package/dist/types/internal-urls/registry-helpers.d.ts +18 -0
- package/dist/types/modes/components/gjc-bundle-settings.d.ts +1 -0
- package/dist/types/modes/components/plugin-settings.d.ts +2 -0
- package/dist/types/modes/components/settings-selector.d.ts +2 -0
- package/dist/types/sdk/broker/broker.d.ts +18 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +13 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +1 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +4 -3
- package/dist/types/sdk/bus/index.d.ts +4 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +4 -2
- package/dist/types/sdk/bus/telegram-daemon.d.ts +25 -3
- package/dist/types/sdk/bus/topic-registry.d.ts +63 -3
- package/dist/types/sdk/host/host.d.ts +23 -2
- package/dist/types/sdk/host/reverse-leases.d.ts +7 -4
- package/dist/types/session/agent-session.d.ts +5 -4
- package/dist/types/session/artifacts.d.ts +8 -5
- package/dist/types/session/attempt-record-store.d.ts +19 -0
- package/dist/types/session/client-bridge.d.ts +14 -0
- package/dist/types/session/internal/managed-session-storage.d.ts +5 -2
- package/dist/types/session/messages.d.ts +4 -1
- package/dist/types/session/session-manager.d.ts +6 -4
- package/dist/types/session/session-storage.d.ts +8 -0
- package/dist/types/session/streaming-output.d.ts +32 -0
- package/dist/types/task/receipt.d.ts +2 -0
- package/dist/types/task/types.d.ts +178 -0
- package/dist/types/tools/bash.d.ts +1 -1
- package/dist/types/tools/fetch.d.ts +3 -0
- package/dist/types/tools/output-meta.d.ts +37 -5
- package/dist/types/tools/tool-result.d.ts +1 -0
- package/dist/types/utils/artifact-id.d.ts +2 -0
- package/package.json +8 -8
- package/scripts/capture-sticky-viewport-showcase.ts +131 -5
- package/scripts/verify-gjc-sdk-canonicalization.ts +128 -183
- package/scripts/verify-sticky-viewport-showcase.ts +620 -93
- package/src/config/model-profiles.ts +8 -0
- package/src/config/settings-schema.ts +17 -3
- package/src/cursor.ts +20 -13
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +5 -2
- package/src/eval/backend.ts +2 -2
- package/src/exec/bash-executor.ts +425 -151
- package/src/extensibility/extensions/runner.ts +80 -6
- package/src/extensibility/extensions/wrapper.ts +22 -15
- package/src/extensibility/runtime-skill-discovery.ts +4 -6
- package/src/gjc-runtime/launch-tmux.ts +309 -293
- package/src/gjc-runtime/managed-owner-supervisor.ts +6 -2
- package/src/gjc-runtime/psmux-detect.ts +52 -6
- package/src/gjc-runtime/team-launch.ts +50 -2
- package/src/gjc-runtime/team-runtime.ts +716 -251
- package/src/gjc-runtime/team-store.ts +25 -7
- package/src/gjc-runtime/team-workers.ts +161 -1
- package/src/gjc-runtime/tmux-common.ts +16 -4
- package/src/gjc-runtime/tmux-gc.ts +37 -5
- package/src/gjc-runtime/tmux-owner-isolation.ts +2 -0
- package/src/gjc-runtime/tmux-provider-context.ts +451 -0
- package/src/gjc-runtime/tmux-sessions.ts +409 -156
- package/src/gjc-runtime/ultragoal-change-set.ts +90 -44
- package/src/gjc-runtime/ultragoal-receipt-freshness.ts +7 -0
- package/src/gjc-runtime/ultragoal-review-source.ts +378 -0
- package/src/gjc-runtime/ultragoal-runtime.ts +640 -159
- package/src/gjc-runtime/workflow-manifest.generated.json +40 -1
- package/src/gjc-runtime/workflow-manifest.ts +12 -0
- package/src/internal-urls/agent-protocol.ts +98 -38
- package/src/internal-urls/artifact-protocol.ts +28 -17
- package/src/internal-urls/docs-index.generated.ts +5 -5
- package/src/internal-urls/local-protocol.ts +39 -18
- package/src/internal-urls/registry-helpers.ts +62 -0
- package/src/modes/acp/acp-agent.ts +51 -13
- package/src/modes/acp/acp-client-bridge.ts +154 -11
- package/src/modes/components/gjc-bundle-settings.ts +2 -0
- package/src/modes/components/plugin-settings.ts +5 -0
- package/src/modes/components/settings-selector.ts +4 -0
- package/src/modes/controllers/selector-controller.ts +1 -0
- package/src/prompts/tools/bash.md +2 -2
- package/src/prompts/tools/monitor.md +4 -4
- package/src/sdk/acp/adapter.ts +200 -9
- package/src/sdk/broker/broker.ts +93 -10
- package/src/sdk/broker/lifecycle-ledger.ts +227 -11
- package/src/sdk/broker/lifecycle.ts +691 -92
- package/src/sdk/bus/chat-daemon-control.ts +32 -6
- package/src/sdk/bus/index.ts +347 -14
- package/src/sdk/bus/telegram-daemon-contract.ts +4 -2
- package/src/sdk/bus/telegram-daemon.ts +283 -44
- package/src/sdk/bus/topic-registry.ts +133 -10
- package/src/sdk/host/host.ts +187 -9
- package/src/sdk/host/reverse-leases.ts +249 -42
- package/src/sdk/session.ts +7 -6
- package/src/session/agent-session.ts +930 -354
- package/src/session/artifacts.ts +211 -74
- package/src/session/attempt-record-store.ts +106 -0
- package/src/session/client-bridge.ts +15 -0
- package/src/session/internal/managed-session-scope.ts +252 -67
- package/src/session/internal/managed-session-storage.ts +105 -5
- package/src/session/messages.ts +32 -7
- package/src/session/session-manager.ts +19 -21
- package/src/session/session-storage.ts +146 -24
- package/src/session/streaming-output.ts +198 -40
- package/src/task/index.ts +45 -0
- package/src/task/provider-retry-status.ts +4 -1
- package/src/task/receipt.ts +4 -0
- package/src/task/render.ts +30 -0
- package/src/task/types.ts +34 -0
- package/src/tools/bash.ts +818 -239
- package/src/tools/eval.ts +99 -4
- package/src/tools/fetch.ts +77 -15
- package/src/tools/find.ts +7 -3
- package/src/tools/monitor.ts +7 -1
- package/src/tools/output-meta.ts +706 -116
- package/src/tools/search.ts +9 -4
- package/src/tools/tool-result.ts +1 -0
- package/src/utils/artifact-id.ts +6 -0
|
@@ -92,6 +92,13 @@ export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
|
|
|
92
92
|
critic: "openai-codex/gpt-5.6-sol:max",
|
|
93
93
|
architect: "openai-codex/gpt-5.6-sol:xhigh",
|
|
94
94
|
}),
|
|
95
|
+
profile("lunamaxxing", ["openai-codex"], {
|
|
96
|
+
default: "openai-codex/gpt-5.6-luna:medium",
|
|
97
|
+
executor: "openai-codex/gpt-5.6-luna:xhigh",
|
|
98
|
+
planner: "openai-codex/gpt-5.6-luna:max",
|
|
99
|
+
critic: "openai-codex/gpt-5.6-luna:max",
|
|
100
|
+
architect: "openai-codex/gpt-5.6-luna:max",
|
|
101
|
+
}),
|
|
95
102
|
profile("opencodego", ["opencode-go"], {
|
|
96
103
|
default: "opencode-go/kimi-k2.6",
|
|
97
104
|
executor: "opencode-go/deepseek-v4-flash",
|
|
@@ -327,6 +334,7 @@ const PROFILE_PRESENTATION: Record<string, ModelProfilePresentation> = {
|
|
|
327
334
|
"codex-eco": { displayName: "Codex Eco", providerGroup: "CODEX" },
|
|
328
335
|
"codex-medium": { displayName: "Codex Medium", providerGroup: "CODEX" },
|
|
329
336
|
"codex-pro": { displayName: "Codex Pro", providerGroup: "CODEX" },
|
|
337
|
+
lunamaxxing: { displayName: "LunaMaxxing", providerGroup: "CODEX" },
|
|
330
338
|
opencodego: { displayName: "OpenCodeGo", providerGroup: "OPENCODEGO" },
|
|
331
339
|
"claude-opus": { displayName: "Claude Opus", providerGroup: "CLAUDE" },
|
|
332
340
|
"claude-fable": { displayName: "Claude Fable", providerGroup: "CLAUDE" },
|
|
@@ -3744,6 +3744,11 @@ function schemaPaths(value: Record<string, unknown>, prefix = ""): string[] {
|
|
|
3744
3744
|
return paths;
|
|
3745
3745
|
}
|
|
3746
3746
|
|
|
3747
|
+
function validArraySettingValue(value: unknown, allowedValues: readonly string[] | undefined): boolean {
|
|
3748
|
+
if (!Array.isArray(value)) return false;
|
|
3749
|
+
return !allowedValues || value.every(item => typeof item === "string" && allowedValues.includes(item));
|
|
3750
|
+
}
|
|
3751
|
+
|
|
3747
3752
|
function validSettingValue(definition: (typeof SETTINGS_SCHEMA)[SettingPath], value: unknown): boolean {
|
|
3748
3753
|
return (
|
|
3749
3754
|
(definition.type === "boolean" && typeof value === "boolean") ||
|
|
@@ -3755,7 +3760,8 @@ function validSettingValue(definition: (typeof SETTINGS_SCHEMA)[SettingPath], va
|
|
|
3755
3760
|
(definition.type === "enum" &&
|
|
3756
3761
|
typeof value === "string" &&
|
|
3757
3762
|
(definition.values as readonly string[]).includes(value)) ||
|
|
3758
|
-
(definition.type === "array" &&
|
|
3763
|
+
(definition.type === "array" &&
|
|
3764
|
+
validArraySettingValue(value, "items" in definition ? definition.items?.enum : undefined)) ||
|
|
3759
3765
|
(definition.type === "record" && !!value && typeof value === "object" && !Array.isArray(value))
|
|
3760
3766
|
);
|
|
3761
3767
|
}
|
|
@@ -3792,8 +3798,16 @@ export function reconcileSettingsSchema(raw: Record<string, unknown>): {
|
|
|
3792
3798
|
schemaSetAtPath(settings, path, next);
|
|
3793
3799
|
issues.push({ path, kind: "coerced", detail: `Coerced ${typeof value} to ${definition.type}.` });
|
|
3794
3800
|
}
|
|
3795
|
-
if (!validSettingValue(definition, next))
|
|
3796
|
-
|
|
3801
|
+
if (!validSettingValue(definition, next)) {
|
|
3802
|
+
const arrayItemEnum =
|
|
3803
|
+
definition.type === "array" && Array.isArray(next) && "items" in definition
|
|
3804
|
+
? definition.items?.enum
|
|
3805
|
+
: undefined;
|
|
3806
|
+
const detail = arrayItemEnum
|
|
3807
|
+
? `Expected array items to be one of: ${arrayItemEnum.join(", ")}.`
|
|
3808
|
+
: `Expected ${definition.type}.`;
|
|
3809
|
+
issues.push({ path, kind: "invalid", detail });
|
|
3810
|
+
}
|
|
3797
3811
|
if (
|
|
3798
3812
|
definition.type === "record" &&
|
|
3799
3813
|
"valueSchema" in definition &&
|
package/src/cursor.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
ToolResultMessage,
|
|
15
15
|
} from "@gajae-code/ai";
|
|
16
16
|
import { sanitizeText } from "@gajae-code/utils";
|
|
17
|
+
import { finalizeToolResultForDelivery } from "./tools/output-meta";
|
|
17
18
|
import { resolveToCwd } from "./tools/path-utils";
|
|
18
19
|
|
|
19
20
|
interface CursorExecBridgeOptions {
|
|
@@ -48,6 +49,14 @@ function buildToolErrorResult(message: string): AgentToolResult<unknown> {
|
|
|
48
49
|
};
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
async function buildFinalToolErrorResult(
|
|
53
|
+
options: CursorExecBridgeOptions,
|
|
54
|
+
toolName: string,
|
|
55
|
+
message: string,
|
|
56
|
+
): Promise<AgentToolResult<unknown>> {
|
|
57
|
+
return finalizeToolResultForDelivery(buildToolErrorResult(message), toolName, options.getToolContext?.());
|
|
58
|
+
}
|
|
59
|
+
|
|
51
60
|
async function executeTool(
|
|
52
61
|
options: CursorExecBridgeOptions,
|
|
53
62
|
toolName: string,
|
|
@@ -56,11 +65,12 @@ async function executeTool(
|
|
|
56
65
|
): Promise<ToolResultMessage> {
|
|
57
66
|
const tool = options.tools.get(toolName);
|
|
58
67
|
if (!tool) {
|
|
59
|
-
const result =
|
|
68
|
+
const result = await buildFinalToolErrorResult(options, toolName, `Tool "${toolName}" not available`);
|
|
60
69
|
return createToolResultMessage(toolCallId, toolName, result, true);
|
|
61
70
|
}
|
|
62
71
|
|
|
63
72
|
options.emitEvent?.({ type: "tool_execution_start", toolCallId, toolName, args });
|
|
73
|
+
const context = options.getToolContext?.();
|
|
64
74
|
|
|
65
75
|
let result: AgentToolResult<unknown>;
|
|
66
76
|
let isError = false;
|
|
@@ -82,16 +92,10 @@ async function executeTool(
|
|
|
82
92
|
: undefined;
|
|
83
93
|
|
|
84
94
|
try {
|
|
85
|
-
result = await tool.execute(
|
|
86
|
-
toolCallId,
|
|
87
|
-
args as Record<string, unknown>,
|
|
88
|
-
undefined,
|
|
89
|
-
onUpdate,
|
|
90
|
-
options.getToolContext?.(),
|
|
91
|
-
);
|
|
95
|
+
result = await tool.execute(toolCallId, args as Record<string, unknown>, undefined, onUpdate, context);
|
|
92
96
|
} catch (error) {
|
|
93
97
|
const message = error instanceof Error ? error.message : String(error);
|
|
94
|
-
result =
|
|
98
|
+
result = await buildFinalToolErrorResult(options, toolName, message);
|
|
95
99
|
isError = true;
|
|
96
100
|
}
|
|
97
101
|
|
|
@@ -133,6 +137,7 @@ async function executeDelete(options: CursorExecBridgeOptions, pathArg: string,
|
|
|
133
137
|
result = buildToolErrorResult(message);
|
|
134
138
|
isError = true;
|
|
135
139
|
}
|
|
140
|
+
result = await finalizeToolResultForDelivery(result, toolName, options.getToolContext?.());
|
|
136
141
|
|
|
137
142
|
options.emitEvent?.({ type: "tool_execution_end", toolCallId, toolName, result, isError });
|
|
138
143
|
return createToolResultMessage(toolCallId, toolName, result, isError);
|
|
@@ -222,7 +227,9 @@ export class CursorExecHandlers implements ICursorExecHandlers {
|
|
|
222
227
|
const globPath = `${args.path || "."}/${args.glob}`;
|
|
223
228
|
return executeTool(this.#optionsForCall(), "find", toolCallId, { paths: [globPath] });
|
|
224
229
|
}
|
|
225
|
-
const result =
|
|
230
|
+
const result = await buildFinalToolErrorResult(
|
|
231
|
+
this.#optionsForCall(),
|
|
232
|
+
"search",
|
|
226
233
|
"Cursor grep request rejected: pattern must not be empty. Provide a non-empty search pattern.",
|
|
227
234
|
);
|
|
228
235
|
return createToolResultMessage(toolCallId, "search", result, true);
|
|
@@ -272,7 +279,7 @@ export class CursorExecHandlers implements ICursorExecHandlers {
|
|
|
272
279
|
const toolName = "bash";
|
|
273
280
|
const tool = options.tools.get(toolName);
|
|
274
281
|
if (!tool) {
|
|
275
|
-
const result =
|
|
282
|
+
const result = await buildFinalToolErrorResult(options, toolName, `Tool "${toolName}" not available`);
|
|
276
283
|
return createToolResultMessage(toolCallId, toolName, result, true);
|
|
277
284
|
}
|
|
278
285
|
|
|
@@ -331,7 +338,7 @@ export class CursorExecHandlers implements ICursorExecHandlers {
|
|
|
331
338
|
result = await tool.execute(toolCallId, toolArgs, undefined, onUpdate, options.getToolContext?.());
|
|
332
339
|
} catch (error) {
|
|
333
340
|
const message = error instanceof Error ? error.message : String(error);
|
|
334
|
-
result =
|
|
341
|
+
result = await buildFinalToolErrorResult(options, toolName, message);
|
|
335
342
|
isError = true;
|
|
336
343
|
}
|
|
337
344
|
|
|
@@ -381,7 +388,7 @@ export class CursorExecHandlers implements ICursorExecHandlers {
|
|
|
381
388
|
if (!tool) {
|
|
382
389
|
const availableTools = Array.from(options.tools.keys()).filter(name => name.startsWith("mcp__"));
|
|
383
390
|
const message = formatMcpToolErrorMessage(toolName, availableTools);
|
|
384
|
-
const result =
|
|
391
|
+
const result = await buildFinalToolErrorResult(options, toolName, message);
|
|
385
392
|
return createToolResultMessage(toolCallId, toolName, result, true);
|
|
386
393
|
}
|
|
387
394
|
|
|
@@ -295,7 +295,8 @@ The heavyweight gate runs **once per boundary generation**, not once per story a
|
|
|
295
295
|
One generation freezes the change set and reviews it exactly once:
|
|
296
296
|
|
|
297
297
|
1. Run implementation verification for the boundary's cumulative change set.
|
|
298
|
-
2. **Freeze the change set.**
|
|
298
|
+
2. **Freeze the change set.** Use the native coordinator: run `gjc ultragoal review-source freeze --json` before dispatch, then create each lane with `gjc ultragoal review-source dispatch --cohort-id <id> --task-id <id> --lane <cleaner|architect|qa|critic> --rerun-command <command> --json` and pass the returned leader-issued `reviewSource` object to `task`. The runtime derives and persists the canonical source identity; never hand-author or copy a `sourceHash`. Every delivered lane receipt is classified `current`, `stale_review_delivery`, or `invalid_provenance` against the active source, and only current runtime-owned delivery IDs may enter the gate.
|
|
299
|
+
|
|
299
300
|
3. **Run the cohort lanes on the frozen snapshot** — at most one `cleaner`, one `architect`, and one `qa` lane per generation. They may run in parallel because they share the frozen source; a second architect or QA lane in the same generation is rejected. The `cleaner` lane is the internal ai-slop-cleaner skill fragment run over the frozen change set: a read-only detector that emits an `AI SLOP CLEANUP REPORT`, and it still runs and records a passed/no-op report when there are no relevant edits. Its BLOCKING findings join the cohort findings rather than starting their own fix loop; advisory findings are included in the gate report only and are not written to the Ultragoal ledger.
|
|
300
301
|
4. Delegate an `architect` review covering all three lanes:
|
|
301
302
|
- architecture-side: system boundaries, layering, data/control flow, operational risks.
|
|
@@ -309,11 +310,13 @@ One generation freezes the change set and reviews it exactly once:
|
|
|
309
310
|
- API/package surfaces require a real artifact file or typed receipt whose artifact `kind` contains one of `api`, `package`, `consumer`, `black-box`, or `test-report`; examples: `api-package-test-report`, `package-consumer-report`, `black-box-api-receipt`. Algorithm/math surfaces require a real artifact file or typed receipt whose artifact `kind` contains one of `property`, `boundary`, `edge`, `adversarial`, `failure`, `math`, `algorithm`, or `test-report`; examples: `property-test-report`, `algorithm-boundary-report`. Bare `inlineEvidence` text alone is not sufficient for any surface.
|
|
310
311
|
- The mandatory **computer-use** red-team suite (`kill-switch-bypass`, `suspended-enforcement`, `permission-revoked`, …) is conditional, not universal: require it only when computer/desktop control is genuinely part of the product surface being dogfooded. For every other product type, prove the change through the matching live surface instead — browser-use automation for web/GUI, bash/CLI live invocation or argv replay for CLI, and real artifacts or typed receipts for API/package/algorithm/math. Editing docs, prompts, or skills that merely mention computer-use does not by itself make the computer-use suite applicable; pick the red-team surface that matches what the change actually ships.
|
|
311
312
|
7. The executor QA/red-team lane must report a matrix using `executorQa.contractCoverage`, `executorQa.surfaceEvidence`, `executorQa.adversarialCases`, and `executorQa.artifactRefs`. Not-applicable rows are allowed only in `contractCoverage` and `surfaceEvidence`; each `status: "not_applicable"` row requires `contractRef` plus `reason`. `adversarialCases` rows cannot be not-applicable.
|
|
312
|
-
8. **Join before repairing.** Fold all three lane verdicts and the final code review into the strict gate under `iteration.reviewCohort` (`reviewGeneration`, `sourceHash`, `joined: true`, and the three
|
|
313
|
+
8. **Join before repairing.** Fold all three lane verdicts and the final code review into the strict gate under `iteration.reviewCohort` (`cohortId`, `reviewGeneration`, runtime-derived `sourceHash`, `joined: true`, and the three lanes with runtime-issued `deliveryId`). No lane may checkpoint on its own, and no fix work starts until the findings are joined. A `stale_review_delivery` stays visible for audit, is excluded from approval and blocker authority, and must be rerun using the rendered command. Clean means `architectReview.architectureStatus`, `architectReview.productStatus`, and `architectReview.codeStatus` are all `"CLEAR"`, `architectReview.recommendation` is `"APPROVE"`, executor QA statuses are `"passed"`, iteration is `"passed"` with `fullRerun: true`, the cohort is joined with every lane clean and receipt-bound to the active snapshot, every evidence field is non-empty, every required matrix row is present, and every blockers array is empty. `COMMENT`, `WATCH`, `REQUEST CHANGES`, `BLOCK`, stale/invalid provenance, missing evidence, missing or shallow matrix rows, plan/code mismatches, or non-empty blockers are non-clean.
|
|
313
314
|
9. If the joined findings contain any blocker, do **not** checkpoint `complete` and do **not** call `goal({"op":"complete"})`. Record **one consolidated blocker batch** for all findings from the whole cohort instead of one story per lane:
|
|
314
315
|
```sh
|
|
315
316
|
gjc ultragoal record-review-blockers --goal-id <id> --title "Resolve verification blockers" --objective "<blocker-resolution objective>" --evidence "<joined cohort findings>"
|
|
316
317
|
```
|
|
318
|
+
|
|
319
|
+
Review-blocker recursion cap (#3613): `record-review-blockers` dedups identical-objective blockers (same trimmed objective + same blocked goal + open status) and bounds the number of unresolved review_blocker descents per blocked goal to **3**. Descents 1..3 may exist; an attempt to create a 4th throws a typed `review_blocker_recursion_cap` terminal handoff (CLI exit 1, operator-visible marker) — never silently auto-completing findings. When the cap fires, record a human pause/escalation or resolve existing blockers before recording more.
|
|
317
320
|
10. One consolidated fix batch produces exactly **one new generation**. Re-freeze the fixed source as a new `sourceHash`, bump `reviewGeneration`, and set `deltaOnly: true` with `priorGenerationSourceHash` and the `deltaPaths` actually changed. Generation 2+ reviews are **delta-only**: they may not pull in unrelated scope without an explicit `scopeExpansion` carrying `severity`, `novelty`, and `justification`. Repeat until a generation joins clean.
|
|
318
321
|
11. Only after a generation joins clean, checkpoint the story as complete with a structured quality gate. The terminal critic runs **once** on that final joined generation; when `criticReview.sourceHash` is present it must match the cohort's `sourceHash`. The checkpoint creates a receipt in `ledger.jsonl`; `goals.json.status` alone is not proof. In aggregate mode, the final aggregate receipt must exist before the agent calls `goal({"op":"complete"})` to reconcile the inline UX goal state.
|
|
319
322
|
|
package/src/eval/backend.ts
CHANGED
|
@@ -11,8 +11,8 @@ export interface ExecutorBackendExecOptions {
|
|
|
11
11
|
session: ToolSession;
|
|
12
12
|
deadlineMs: number;
|
|
13
13
|
reset: boolean;
|
|
14
|
-
artifactPath
|
|
15
|
-
artifactId
|
|
14
|
+
artifactPath?: string;
|
|
15
|
+
artifactId?: string;
|
|
16
16
|
onChunk: (chunk: string) => void;
|
|
17
17
|
}
|
|
18
18
|
|