@gajae-code/coding-agent 0.11.6 → 0.11.7
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 +37 -0
- package/dist/types/capability/index.d.ts +10 -20
- package/dist/types/capability/types.d.ts +3 -0
- package/dist/types/commands/daemon.d.ts +2 -2
- package/dist/types/commands/sdk.d.ts +20 -2
- package/dist/types/config/keybindings.d.ts +1 -1
- package/dist/types/config/settings-schema.d.ts +56 -6
- package/dist/types/eval/py/runner-artifact.d.ts +8 -0
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +5 -5
- package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +20 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +19 -5
- package/dist/types/main.d.ts +24 -1
- package/dist/types/modes/components/btw-panel.d.ts +1 -0
- package/dist/types/modes/components/model-selector.d.ts +2 -0
- package/dist/types/modes/components/tool-status-header.d.ts +1 -0
- package/dist/types/modes/controllers/btw-controller.d.ts +5 -0
- package/dist/types/modes/interactive-mode.d.ts +2 -0
- package/dist/types/modes/types.d.ts +1 -0
- package/dist/types/runtime-mcp/content-limits.d.ts +7 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +2 -1
- package/dist/types/sdk/bus/index.d.ts +1 -1
- package/dist/types/sdk/bus/lifecycle-commands.d.ts +5 -4
- package/dist/types/sdk/bus/notification-service.d.ts +34 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +8 -3
- package/dist/types/sdk/bus/telegram-daemon.d.ts +61 -3
- package/dist/types/sdk/bus/topic-registry.d.ts +88 -2
- package/dist/types/sdk/client/discovery.d.ts +2 -0
- package/dist/types/sdk/client/liveness.d.ts +7 -0
- package/dist/types/sdk/transport/auth-preface.d.ts +9 -0
- package/dist/types/sdk/transport/index.d.ts +12 -0
- package/dist/types/sdk/transport/relay.d.ts +43 -0
- package/dist/types/sdk/transport/serve-cli.d.ts +4 -0
- package/dist/types/sdk/transport/socket.d.ts +7 -0
- package/dist/types/sdk/transport/stdio.d.ts +3 -0
- package/dist/types/session/agent-session.d.ts +28 -5
- package/dist/types/session/btw-contract.d.ts +16 -0
- package/dist/types/session/internal/managed-session-scope.d.ts +21 -7
- package/dist/types/session/internal/managed-session-storage.d.ts +10 -8
- package/dist/types/session/session-manager.d.ts +25 -4
- package/dist/types/setup/credential-import.d.ts +5 -1
- package/dist/types/setup/provider-onboarding.d.ts +2 -0
- package/dist/types/ssh/utils.d.ts +1 -0
- package/dist/types/task/discovery.d.ts +3 -1
- package/dist/types/tools/fetch.d.ts +5 -8
- package/dist/types/tools/image-gen.d.ts +16 -0
- package/dist/types/tools/skill-discovery.d.ts +7 -0
- package/dist/types/tools/sqlite-reader.d.ts +7 -0
- package/dist/types/utils/shell-snapshot.d.ts +12 -0
- package/dist/types/web/insane/bridge.d.ts +1 -0
- package/dist/types/web/insane/url-guard.d.ts +17 -0
- package/package.json +8 -8
- package/scripts/generate-sdk-operation-inventory.ts +2 -0
- package/src/capability/index.ts +50 -42
- package/src/capability/types.ts +3 -0
- package/src/cli/setup-cli.ts +10 -4
- package/src/cli.ts +34 -9
- package/src/commands/daemon.ts +22 -5
- package/src/commands/sdk.ts +42 -9
- package/src/config/keybindings.ts +1 -1
- package/src/config/model-profiles.ts +18 -0
- package/src/config/settings-schema.ts +57 -6
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +42 -1
- package/src/discovery/ssh.ts +12 -1
- package/src/eval/py/kernel.ts +1 -21
- package/src/eval/py/runner-artifact.ts +84 -0
- package/src/extensibility/plugins/marketplace/fetcher.ts +191 -7
- package/src/gjc-runtime/ultragoal-guard.ts +88 -10
- package/src/gjc-runtime/ultragoal-receipt-freshness.ts +103 -0
- package/src/gjc-runtime/ultragoal-runtime.ts +275 -12
- package/src/gjc-runtime/workflow-manifest.generated.json +58 -0
- package/src/gjc-runtime/workflow-manifest.ts +23 -0
- package/src/internal-urls/docs-index.generated.ts +8 -7
- package/src/internal-urls/local-protocol.ts +32 -6
- package/src/main.ts +86 -27
- package/src/modes/action-registry.ts +1 -1
- package/src/modes/components/btw-panel.ts +82 -16
- package/src/modes/components/model-selector.ts +31 -3
- package/src/modes/components/tool-status-header.ts +6 -1
- package/src/modes/controllers/btw-controller.ts +119 -36
- package/src/modes/controllers/input-controller.ts +31 -0
- package/src/modes/controllers/selector-controller.ts +106 -12
- package/src/modes/interactive-mode.ts +16 -7
- package/src/modes/types.ts +1 -0
- package/src/prompts/system/btw-user.md +3 -8
- package/src/prompts/tools/skill-discovery.md +1 -0
- package/src/runtime-mcp/client.ts +41 -55
- package/src/runtime-mcp/content-limits.ts +71 -0
- package/src/runtime-mcp/json-rpc.ts +23 -9
- package/src/runtime-mcp/transports/http.ts +50 -16
- package/src/sdk/bus/chat-daemon-control.ts +4 -3
- package/src/sdk/bus/index.ts +4 -5
- package/src/sdk/bus/lifecycle-commands.ts +16 -7
- package/src/sdk/bus/notification-service.ts +41 -18
- package/src/sdk/bus/telegram-daemon-contract.ts +8 -3
- package/src/sdk/bus/telegram-daemon-control.ts +2 -2
- package/src/sdk/bus/telegram-daemon.ts +1663 -375
- package/src/sdk/bus/topic-registry.ts +451 -12
- package/src/sdk/client/discovery.ts +19 -3
- package/src/sdk/client/liveness.ts +49 -0
- package/src/sdk/protocol/operation-inventory.generated.json +11 -0
- package/src/sdk/session.ts +29 -5
- package/src/sdk/transport/auth-preface.ts +82 -0
- package/src/sdk/transport/index.ts +18 -0
- package/src/sdk/transport/relay.ts +252 -0
- package/src/sdk/transport/serve-cli.ts +105 -0
- package/src/sdk/transport/socket.ts +197 -0
- package/src/sdk/transport/stdio.ts +17 -0
- package/src/session/agent-session.ts +240 -149
- package/src/session/blob-store.ts +19 -6
- package/src/session/btw-contract.ts +59 -0
- package/src/session/internal/managed-session-scope.ts +313 -57
- package/src/session/internal/managed-session-storage.ts +146 -35
- package/src/session/session-manager.ts +319 -85
- package/src/setup/credential-import.ts +28 -3
- package/src/setup/provider-onboarding.ts +30 -1
- package/src/setup/provider-presets.json +2 -1
- package/src/slash-commands/builtin-registry.ts +1 -1
- package/src/ssh/utils.ts +14 -0
- package/src/task/discovery.ts +8 -2
- package/src/tools/ask.ts +1 -1
- package/src/tools/fetch.ts +13 -131
- package/src/tools/image-gen.ts +301 -20
- package/src/tools/read.ts +2 -0
- package/src/tools/skill-discovery.ts +39 -3
- package/src/tools/sqlite-reader.ts +63 -5
- package/src/utils/pasted-image-path.ts +15 -6
- package/src/utils/shell-snapshot.ts +173 -63
- package/src/web/insane/bridge.ts +5 -1
- package/src/web/insane/url-guard.ts +138 -27
- package/src/web/scrapers/types.ts +19 -49
- package/src/web/scrapers/utils.ts +12 -26
|
@@ -6,15 +6,37 @@ import { buildUltragoalHudSummary as buildWorkflowUltragoalHudSummary } from "..
|
|
|
6
6
|
import { renderCliWriteReceipt } from "./cli-write-receipt";
|
|
7
7
|
import { DEFAULT_ULTRAGOAL_OBJECTIVE } from "./goal-mode-request";
|
|
8
8
|
import {
|
|
9
|
+
CRITIC_GATE_HARD_STOP_EVENT,
|
|
10
|
+
CRITIC_GATE_OVERRIDE_EVENT,
|
|
11
|
+
CRITIC_VERDICT_EVENT,
|
|
12
|
+
type CriticVerdict,
|
|
13
|
+
computeCriticVerdictPlanGeneration,
|
|
9
14
|
computeUltragoalPlanGeneration,
|
|
15
|
+
countNonOkayTerminalCriticVerdicts,
|
|
10
16
|
findFreshBatchCloseReceipt,
|
|
11
17
|
findLedgerReceiptEvent,
|
|
18
|
+
isCleanPauseCriticVerdictShape,
|
|
12
19
|
requiredUltragoalGoals,
|
|
20
|
+
TERMINAL_CRITIC_CEILING,
|
|
21
|
+
terminalCriticCeilingReached,
|
|
22
|
+
terminalCriticGateOverridden,
|
|
23
|
+
terminalCriticHardStopReached,
|
|
13
24
|
validateDeferredMemberReceiptFresh,
|
|
14
25
|
validateReceiptFreshBase,
|
|
15
26
|
} from "./ultragoal-receipt-freshness";
|
|
16
27
|
|
|
17
|
-
export {
|
|
28
|
+
export {
|
|
29
|
+
CRITIC_GATE_HARD_STOP_EVENT,
|
|
30
|
+
CRITIC_GATE_OVERRIDE_EVENT,
|
|
31
|
+
CRITIC_VERDICT_EVENT,
|
|
32
|
+
type CriticVerdict,
|
|
33
|
+
computeUltragoalPlanGeneration,
|
|
34
|
+
countTerminalCriticVerdicts,
|
|
35
|
+
receiptRelevantGoals,
|
|
36
|
+
TERMINAL_CRITIC_CEILING,
|
|
37
|
+
terminalCriticCeilingReached,
|
|
38
|
+
terminalCriticGateOverridden,
|
|
39
|
+
} from "./ultragoal-receipt-freshness";
|
|
18
40
|
|
|
19
41
|
import { gjcRoot, sessionUltragoalDir } from "./session-layout";
|
|
20
42
|
import {
|
|
@@ -427,7 +449,6 @@ export const DEFAULT_ULTRAGOAL_NUDGE_BUDGET = 10;
|
|
|
427
449
|
export function countUltragoalNudges(ledger: readonly UltragoalLedgerEvent[], goalId: string): number {
|
|
428
450
|
return ledger.filter(event => event.event === "nudge" && event.goalId === goalId).length;
|
|
429
451
|
}
|
|
430
|
-
|
|
431
452
|
function parseNudgeBudgetValue(value: unknown): number | null {
|
|
432
453
|
return typeof value === "number" && Number.isFinite(value) && Number.isInteger(value) && value >= 0 ? value : null;
|
|
433
454
|
}
|
|
@@ -2514,12 +2535,23 @@ async function validateCompletionQualityGate(
|
|
|
2514
2535
|
} = {},
|
|
2515
2536
|
): Promise<void> {
|
|
2516
2537
|
const batchMode = options.goal?.validationBatch;
|
|
2538
|
+
const receiptKind =
|
|
2539
|
+
options.plan && options.goal && options.ledger
|
|
2540
|
+
? chooseReceiptKind(options.plan, options.ledger, options.goal, "complete")
|
|
2541
|
+
: undefined;
|
|
2542
|
+
const isFinalAggregate = receiptKind === "final-aggregate";
|
|
2517
2543
|
if (batchMode && options.goal && options.goal.id !== batchMode.finalGoalId) {
|
|
2518
2544
|
validateDeferredCompletionQualityGate(gate, options.goal, batchMode, options.changeSet);
|
|
2519
2545
|
return;
|
|
2520
2546
|
}
|
|
2521
2547
|
if (batchMode && options.goal && options.goal.id === batchMode.finalGoalId) {
|
|
2522
|
-
const allowedKeys = new Set([
|
|
2548
|
+
const allowedKeys = new Set([
|
|
2549
|
+
"architectReview",
|
|
2550
|
+
"executorQa",
|
|
2551
|
+
"iteration",
|
|
2552
|
+
"validationBatchClose",
|
|
2553
|
+
"criticReview",
|
|
2554
|
+
]);
|
|
2523
2555
|
const unsupportedKeys = Object.keys(gate).filter(key => !allowedKeys.has(key));
|
|
2524
2556
|
if (unsupportedKeys.length > 0)
|
|
2525
2557
|
throw new Error(`qualityGate contains unsupported keys: ${unsupportedKeys.join(", ")}`);
|
|
@@ -2534,8 +2566,8 @@ async function validateCompletionQualityGate(
|
|
|
2534
2566
|
}
|
|
2535
2567
|
const allowedKeys = new Set(
|
|
2536
2568
|
batchMode
|
|
2537
|
-
? ["architectReview", "executorQa", "iteration", "validationBatchClose"]
|
|
2538
|
-
: ["architectReview", "executorQa", "iteration"],
|
|
2569
|
+
? ["architectReview", "executorQa", "iteration", "validationBatchClose", "criticReview"]
|
|
2570
|
+
: ["architectReview", "executorQa", "iteration", "criticReview"],
|
|
2539
2571
|
);
|
|
2540
2572
|
const unsupportedKeys = Object.keys(gate).filter(key => !allowedKeys.has(key));
|
|
2541
2573
|
if (unsupportedKeys.length > 0) {
|
|
@@ -2547,6 +2579,25 @@ async function validateCompletionQualityGate(
|
|
|
2547
2579
|
if (!architectReview || !executorQa || !iteration) {
|
|
2548
2580
|
throw new Error("qualityGate requires architectReview, executorQa, and iteration objects");
|
|
2549
2581
|
}
|
|
2582
|
+
if (isFinalAggregate) {
|
|
2583
|
+
if (
|
|
2584
|
+
options.ledger &&
|
|
2585
|
+
terminalCriticCeilingReached(options.ledger) &&
|
|
2586
|
+
!terminalCriticGateOverridden(options.ledger)
|
|
2587
|
+
) {
|
|
2588
|
+
throw new Error(
|
|
2589
|
+
"checkpoint --status complete blocked: terminal-critic ceiling reached; requires human/leader gjc ultragoal record-critic-gate-override before completion",
|
|
2590
|
+
);
|
|
2591
|
+
}
|
|
2592
|
+
const criticReview = qualityGateObject(gate.criticReview);
|
|
2593
|
+
if (criticReview?.verdict !== "OKAY") {
|
|
2594
|
+
throw new Error(
|
|
2595
|
+
"checkpoint --status complete (final aggregate) requires criticReview with verdict OKAY, non-empty evidence, and empty blockers",
|
|
2596
|
+
);
|
|
2597
|
+
}
|
|
2598
|
+
requireNonEmptyString(criticReview.evidence, "criticReview.evidence");
|
|
2599
|
+
requireEmptyBlockers(criticReview.blockers, "criticReview.blockers");
|
|
2600
|
+
}
|
|
2550
2601
|
if (
|
|
2551
2602
|
architectReview.architectureStatus !== CLEAN_ARCHITECT_STATUS ||
|
|
2552
2603
|
architectReview.productStatus !== CLEAN_ARCHITECT_STATUS ||
|
|
@@ -3550,10 +3601,10 @@ export async function recordUltragoalReviewBlockers(input: {
|
|
|
3550
3601
|
export type UltragoalBlockerClassification = "human_blocked" | "resolvable";
|
|
3551
3602
|
|
|
3552
3603
|
/**
|
|
3553
|
-
* Record an audited blocker triage classification in the durable ledger.
|
|
3554
|
-
* `
|
|
3555
|
-
*
|
|
3556
|
-
* audit note and never unblocks pause.
|
|
3604
|
+
* Record an audited blocker triage classification in the durable ledger. Pause
|
|
3605
|
+
* requires the latest `blocker_classified` event to be `human_blocked` and a
|
|
3606
|
+
* later clean pause terminal critic verdict bound to that classification; `resolvable`
|
|
3607
|
+
* is an audit note and never unblocks pause.
|
|
3557
3608
|
*/
|
|
3558
3609
|
export async function recordUltragoalBlockerClassification(input: {
|
|
3559
3610
|
cwd: string;
|
|
@@ -3574,6 +3625,130 @@ export async function recordUltragoalBlockerClassification(input: {
|
|
|
3574
3625
|
});
|
|
3575
3626
|
}
|
|
3576
3627
|
|
|
3628
|
+
export async function recordUltragoalCriticVerdict(input: {
|
|
3629
|
+
cwd: string;
|
|
3630
|
+
terminus: "completion" | "pause";
|
|
3631
|
+
verdict: CriticVerdict;
|
|
3632
|
+
evidence: string;
|
|
3633
|
+
blockers?: string[];
|
|
3634
|
+
goalId?: string;
|
|
3635
|
+
classificationEventId?: string;
|
|
3636
|
+
}): Promise<UltragoalLedgerEvent> {
|
|
3637
|
+
const evidence = input.evidence.trim();
|
|
3638
|
+
if (!evidence) throw new Error("record-critic-verdict --evidence is required");
|
|
3639
|
+
if (input.terminus !== "completion" && input.terminus !== "pause") {
|
|
3640
|
+
throw new Error('record-critic-verdict --terminus must be "completion" or "pause"');
|
|
3641
|
+
}
|
|
3642
|
+
if (input.verdict !== "OKAY" && input.verdict !== "ITERATE" && input.verdict !== "REJECT") {
|
|
3643
|
+
throw new Error("record-critic-verdict --verdict must be OKAY, ITERATE, or REJECT");
|
|
3644
|
+
}
|
|
3645
|
+
const blockers = stringArray(input.blockers ?? []);
|
|
3646
|
+
if (!blockers) throw new Error("record-critic-verdict --blockers-json must be a JSON string array");
|
|
3647
|
+
if (input.terminus === "completion" && input.verdict === "OKAY" && blockers.length > 0) {
|
|
3648
|
+
throw new Error("OKAY critic verdict must have empty blockers");
|
|
3649
|
+
}
|
|
3650
|
+
const classificationEventId = input.classificationEventId?.trim();
|
|
3651
|
+
if (input.terminus === "pause" && !classificationEventId) {
|
|
3652
|
+
throw new Error("record-critic-verdict --classification-event-id is required for pause verdicts");
|
|
3653
|
+
}
|
|
3654
|
+
const resolvedSessionId = resolveGjcSessionForWrite(input.cwd, {
|
|
3655
|
+
envSessionId: process.env.GJC_SESSION_ID,
|
|
3656
|
+
}).gjcSessionId;
|
|
3657
|
+
const paths = getUltragoalPaths(input.cwd, resolvedSessionId);
|
|
3658
|
+
return withWorkflowStateLock(
|
|
3659
|
+
paths.ledgerPath,
|
|
3660
|
+
async () => {
|
|
3661
|
+
const plan = await readUltragoalPlan(input.cwd, resolvedSessionId);
|
|
3662
|
+
if (!plan) throw new Error("record-critic-verdict requires an active ultragoal plan");
|
|
3663
|
+
const ledger = await readUltragoalLedger(input.cwd, resolvedSessionId);
|
|
3664
|
+
if (input.terminus === "pause") {
|
|
3665
|
+
const latestClassification = [...ledger].reverse().find(event => event.event === "blocker_classified");
|
|
3666
|
+
if (
|
|
3667
|
+
latestClassification?.classification !== "human_blocked" ||
|
|
3668
|
+
latestClassification.eventId !== classificationEventId
|
|
3669
|
+
) {
|
|
3670
|
+
throw new Error(
|
|
3671
|
+
"record-critic-verdict pause requires --classification-event-id to name the latest human_blocked classification",
|
|
3672
|
+
);
|
|
3673
|
+
}
|
|
3674
|
+
}
|
|
3675
|
+
const planGeneration = computeCriticVerdictPlanGeneration(plan);
|
|
3676
|
+
if (
|
|
3677
|
+
input.terminus === "pause" &&
|
|
3678
|
+
input.verdict === "OKAY" &&
|
|
3679
|
+
!isCleanPauseCriticVerdictShape(
|
|
3680
|
+
{
|
|
3681
|
+
event: CRITIC_VERDICT_EVENT,
|
|
3682
|
+
terminus: input.terminus,
|
|
3683
|
+
verdict: input.verdict,
|
|
3684
|
+
evidence,
|
|
3685
|
+
blockers,
|
|
3686
|
+
planGeneration,
|
|
3687
|
+
classificationEventId,
|
|
3688
|
+
},
|
|
3689
|
+
planGeneration,
|
|
3690
|
+
classificationEventId!,
|
|
3691
|
+
)
|
|
3692
|
+
) {
|
|
3693
|
+
throw new Error("OKAY critic verdict must have empty blockers");
|
|
3694
|
+
}
|
|
3695
|
+
const criticVerdict = await appendLedger(
|
|
3696
|
+
input.cwd,
|
|
3697
|
+
{
|
|
3698
|
+
event: CRITIC_VERDICT_EVENT,
|
|
3699
|
+
terminus: input.terminus,
|
|
3700
|
+
verdict: input.verdict,
|
|
3701
|
+
evidence,
|
|
3702
|
+
blockers,
|
|
3703
|
+
planGeneration,
|
|
3704
|
+
...(classificationEventId ? { classificationEventId } : {}),
|
|
3705
|
+
...(input.goalId?.trim() ? { goalId: input.goalId.trim() } : {}),
|
|
3706
|
+
},
|
|
3707
|
+
resolvedSessionId,
|
|
3708
|
+
);
|
|
3709
|
+
const updatedLedger = [...ledger, criticVerdict];
|
|
3710
|
+
const count = countNonOkayTerminalCriticVerdicts(updatedLedger);
|
|
3711
|
+
if (count >= TERMINAL_CRITIC_CEILING && !terminalCriticHardStopReached(updatedLedger)) {
|
|
3712
|
+
await appendLedger(
|
|
3713
|
+
input.cwd,
|
|
3714
|
+
{
|
|
3715
|
+
event: CRITIC_GATE_HARD_STOP_EVENT,
|
|
3716
|
+
planGeneration,
|
|
3717
|
+
reason: "Terminal critic verdict ceiling reached.",
|
|
3718
|
+
count,
|
|
3719
|
+
},
|
|
3720
|
+
resolvedSessionId,
|
|
3721
|
+
);
|
|
3722
|
+
}
|
|
3723
|
+
return criticVerdict;
|
|
3724
|
+
},
|
|
3725
|
+
{ cwd: input.cwd },
|
|
3726
|
+
);
|
|
3727
|
+
}
|
|
3728
|
+
|
|
3729
|
+
export async function recordUltragoalCriticGateOverride(input: {
|
|
3730
|
+
cwd: string;
|
|
3731
|
+
evidence: string;
|
|
3732
|
+
}): Promise<UltragoalLedgerEvent> {
|
|
3733
|
+
const evidence = input.evidence.trim();
|
|
3734
|
+
if (!evidence) throw new Error("record-critic-gate-override --evidence is required");
|
|
3735
|
+
const resolvedSessionId = resolveGjcSessionForWrite(input.cwd, {
|
|
3736
|
+
envSessionId: process.env.GJC_SESSION_ID,
|
|
3737
|
+
}).gjcSessionId;
|
|
3738
|
+
const paths = getUltragoalPaths(input.cwd, resolvedSessionId);
|
|
3739
|
+
return withWorkflowStateLock(
|
|
3740
|
+
paths.ledgerPath,
|
|
3741
|
+
async () => {
|
|
3742
|
+
const ledger = await readUltragoalLedger(input.cwd, resolvedSessionId);
|
|
3743
|
+
if (!terminalCriticHardStopReached(ledger)) {
|
|
3744
|
+
throw new Error("record-critic-gate-override requires a durably recorded terminal critic hard stop");
|
|
3745
|
+
}
|
|
3746
|
+
return appendLedger(input.cwd, { event: CRITIC_GATE_OVERRIDE_EVENT, evidence }, resolvedSessionId);
|
|
3747
|
+
},
|
|
3748
|
+
{ cwd: input.cwd },
|
|
3749
|
+
);
|
|
3750
|
+
}
|
|
3751
|
+
|
|
3577
3752
|
type UltragoalReviewMode = "review-only" | "review-start";
|
|
3578
3753
|
type UltragoalReviewContractStrength = "strong" | "thin-derived";
|
|
3579
3754
|
|
|
@@ -3972,7 +4147,7 @@ function renderUltragoalHelp(args: readonly string[]): string | null {
|
|
|
3972
4147
|
" $ gjc ultragoal classify-blocker --classification <human_blocked|resolvable> --evidence <text> [FLAGS]",
|
|
3973
4148
|
"",
|
|
3974
4149
|
"FLAGS",
|
|
3975
|
-
" --classification=<value> Required. human_blocked
|
|
4150
|
+
" --classification=<value> Required. human_blocked must be the latest blocker_classified event; pause also requires a later bound clean pause terminal critic OKAY verdict; resolvable never authorizes pause",
|
|
3976
4151
|
" --evidence=<value> Required. Specific blocker evidence; must name the human-only dependency for human_blocked",
|
|
3977
4152
|
" --goal-id=<value> Optional durable .gjc/ultragoal goal id, e.g. G001",
|
|
3978
4153
|
" --json Output a machine-readable receipt",
|
|
@@ -3983,6 +4158,44 @@ function renderUltragoalHelp(args: readonly string[]): string | null {
|
|
|
3983
4158
|
"",
|
|
3984
4159
|
].join("\n");
|
|
3985
4160
|
}
|
|
4161
|
+
if (subject === "record-critic-verdict") {
|
|
4162
|
+
return [
|
|
4163
|
+
"Run native GJC Ultragoal workflow commands",
|
|
4164
|
+
"",
|
|
4165
|
+
"USAGE",
|
|
4166
|
+
" $ gjc ultragoal record-critic-verdict --terminus <completion|pause> --verdict <OKAY|ITERATE|REJECT> --evidence <text> [--blockers-json <json>] [--goal-id <id>] [--classification-event-id <id>]",
|
|
4167
|
+
"",
|
|
4168
|
+
"FLAGS",
|
|
4169
|
+
" --terminus=<value> Required. completion or pause",
|
|
4170
|
+
" --verdict=<value> Required. OKAY, ITERATE, or REJECT",
|
|
4171
|
+
" --evidence=<value> Required. Specific evidence supporting the verdict",
|
|
4172
|
+
" --blockers-json=<value> Optional JSON string array of blockers",
|
|
4173
|
+
" --goal-id=<value> Optional durable .gjc/ultragoal goal id, e.g. G001",
|
|
4174
|
+
" --classification-event-id=<id> Required for pause verdicts; binds the human_blocked classification",
|
|
4175
|
+
" --json Output a machine-readable receipt",
|
|
4176
|
+
"",
|
|
4177
|
+
"EXAMPLES",
|
|
4178
|
+
' $ gjc ultragoal record-critic-verdict --terminus completion --verdict OKAY --evidence "all final-aggregate checkpoint evidence is current"',
|
|
4179
|
+
"",
|
|
4180
|
+
].join("\n");
|
|
4181
|
+
}
|
|
4182
|
+
if (subject === "record-critic-gate-override") {
|
|
4183
|
+
return [
|
|
4184
|
+
"Run native GJC Ultragoal workflow commands",
|
|
4185
|
+
"",
|
|
4186
|
+
"USAGE",
|
|
4187
|
+
" $ gjc ultragoal record-critic-gate-override --evidence <text> [--json]",
|
|
4188
|
+
"",
|
|
4189
|
+
"FLAGS",
|
|
4190
|
+
" --evidence=<value> Required. Human/leader authorization evidence for the terminal-critic ceiling override",
|
|
4191
|
+
" --json Output a machine-readable receipt",
|
|
4192
|
+
"",
|
|
4193
|
+
"EXAMPLES",
|
|
4194
|
+
' $ gjc ultragoal record-critic-gate-override --evidence "leader approved another terminal attempt after reviewing all five findings"',
|
|
4195
|
+
"",
|
|
4196
|
+
].join("\n");
|
|
4197
|
+
}
|
|
4198
|
+
|
|
3986
4199
|
return [
|
|
3987
4200
|
"Run native GJC Ultragoal workflow commands",
|
|
3988
4201
|
"",
|
|
@@ -3998,11 +4211,14 @@ function renderUltragoalHelp(args: readonly string[]): string | null {
|
|
|
3998
4211
|
" steer",
|
|
3999
4212
|
" record-review-blockers",
|
|
4000
4213
|
" classify-blocker",
|
|
4214
|
+
" record-critic-verdict",
|
|
4215
|
+
" record-critic-gate-override",
|
|
4216
|
+
|
|
4001
4217
|
" start-pipeline-overlap",
|
|
4002
4218
|
" join-pipeline-overlap",
|
|
4003
4219
|
" rebaseline-pipeline-overlap",
|
|
4004
4220
|
"",
|
|
4005
|
-
"Run `gjc ultragoal checkpoint --help`, `gjc ultragoal review --help`,
|
|
4221
|
+
"Run `gjc ultragoal checkpoint --help`, `gjc ultragoal review --help`, `gjc ultragoal classify-blocker --help`, `gjc ultragoal record-critic-verdict --help`, or `gjc ultragoal record-critic-gate-override --help` for command-specific requirements.",
|
|
4006
4222
|
"",
|
|
4007
4223
|
].join("\n");
|
|
4008
4224
|
}
|
|
@@ -4354,8 +4570,53 @@ async function dispatchUltragoalCommand(args: string[], cwd: string): Promise<Ul
|
|
|
4354
4570
|
ok: true,
|
|
4355
4571
|
event: "blocker_classified",
|
|
4356
4572
|
classification: event.classification,
|
|
4573
|
+
event_id: event.eventId,
|
|
4574
|
+
})
|
|
4575
|
+
: `Recorded blocker classification: ${String(event.classification)} event-id=${String(event.eventId)}.\n`,
|
|
4576
|
+
};
|
|
4577
|
+
}
|
|
4578
|
+
case "record-critic-verdict": {
|
|
4579
|
+
const blockersJson = flagValue(args, "--blockers-json");
|
|
4580
|
+
const blockers =
|
|
4581
|
+
blockersJson === undefined ? undefined : stringArray(await readStructuredValue(cwd, blockersJson));
|
|
4582
|
+
if (blockersJson !== undefined && !blockers) {
|
|
4583
|
+
throw new Error("record-critic-verdict --blockers-json must be a JSON string array");
|
|
4584
|
+
}
|
|
4585
|
+
const event = await recordUltragoalCriticVerdict({
|
|
4586
|
+
cwd,
|
|
4587
|
+
terminus: (flagValue(args, "--terminus") ?? "") as "completion" | "pause",
|
|
4588
|
+
verdict: (flagValue(args, "--verdict") ?? "") as CriticVerdict,
|
|
4589
|
+
evidence: flagValue(args, "--evidence") ?? "",
|
|
4590
|
+
blockers: blockers ?? undefined,
|
|
4591
|
+
goalId: flagValue(args, "--goal-id"),
|
|
4592
|
+
classificationEventId: flagValue(args, "--classification-event-id"),
|
|
4593
|
+
});
|
|
4594
|
+
return {
|
|
4595
|
+
status: 0,
|
|
4596
|
+
stdout: json
|
|
4597
|
+
? renderCliWriteReceipt({
|
|
4598
|
+
ok: true,
|
|
4599
|
+
event: CRITIC_VERDICT_EVENT,
|
|
4600
|
+
terminus: event.terminus,
|
|
4601
|
+
verdict: event.verdict,
|
|
4602
|
+
})
|
|
4603
|
+
: `Recorded critic verdict: ${String(event.verdict)} (${String(event.terminus)}).\n`,
|
|
4604
|
+
};
|
|
4605
|
+
}
|
|
4606
|
+
case "record-critic-gate-override": {
|
|
4607
|
+
const event = await recordUltragoalCriticGateOverride({
|
|
4608
|
+
cwd,
|
|
4609
|
+
evidence: flagValue(args, "--evidence") ?? "",
|
|
4610
|
+
});
|
|
4611
|
+
return {
|
|
4612
|
+
status: 0,
|
|
4613
|
+
stdout: json
|
|
4614
|
+
? renderCliWriteReceipt({
|
|
4615
|
+
ok: true,
|
|
4616
|
+
event: CRITIC_GATE_OVERRIDE_EVENT,
|
|
4617
|
+
event_id: event.eventId,
|
|
4357
4618
|
})
|
|
4358
|
-
: `Recorded
|
|
4619
|
+
: `Recorded terminal critic gate override event-id=${String(event.eventId)}.\n`,
|
|
4359
4620
|
};
|
|
4360
4621
|
}
|
|
4361
4622
|
case "start-pipeline-overlap": {
|
|
@@ -4435,6 +4696,8 @@ const RECONCILE_COMMANDS = new Set([
|
|
|
4435
4696
|
"record-review-blockers",
|
|
4436
4697
|
"review",
|
|
4437
4698
|
"classify-blocker",
|
|
4699
|
+
"record-critic-verdict",
|
|
4700
|
+
"record-critic-gate-override",
|
|
4438
4701
|
"start-pipeline-overlap",
|
|
4439
4702
|
"join-pipeline-overlap",
|
|
4440
4703
|
"rebaseline-pipeline-overlap",
|
|
@@ -1515,12 +1515,60 @@
|
|
|
1515
1515
|
"record-review-blockers",
|
|
1516
1516
|
"steer",
|
|
1517
1517
|
"classify-blocker",
|
|
1518
|
+
"record-critic-verdict",
|
|
1519
|
+
"record-critic-gate-override",
|
|
1518
1520
|
"rebaseline-pipeline-overlap"
|
|
1519
1521
|
],
|
|
1520
1522
|
"name": "evidence",
|
|
1521
1523
|
"required": true,
|
|
1522
1524
|
"type": "string"
|
|
1523
1525
|
},
|
|
1526
|
+
{
|
|
1527
|
+
"appliesToVerbs": [
|
|
1528
|
+
"record-critic-verdict"
|
|
1529
|
+
],
|
|
1530
|
+
"enumValues": [
|
|
1531
|
+
"completion",
|
|
1532
|
+
"pause"
|
|
1533
|
+
],
|
|
1534
|
+
"name": "terminus",
|
|
1535
|
+
"required": true,
|
|
1536
|
+
"type": "enum"
|
|
1537
|
+
},
|
|
1538
|
+
{
|
|
1539
|
+
"appliesToVerbs": [
|
|
1540
|
+
"record-critic-verdict"
|
|
1541
|
+
],
|
|
1542
|
+
"enumValues": [
|
|
1543
|
+
"OKAY",
|
|
1544
|
+
"ITERATE",
|
|
1545
|
+
"REJECT"
|
|
1546
|
+
],
|
|
1547
|
+
"name": "verdict",
|
|
1548
|
+
"required": true,
|
|
1549
|
+
"type": "enum"
|
|
1550
|
+
},
|
|
1551
|
+
{
|
|
1552
|
+
"appliesToVerbs": [
|
|
1553
|
+
"record-critic-verdict"
|
|
1554
|
+
],
|
|
1555
|
+
"name": "blockers-json",
|
|
1556
|
+
"type": "string"
|
|
1557
|
+
},
|
|
1558
|
+
{
|
|
1559
|
+
"appliesToVerbs": [
|
|
1560
|
+
"record-critic-verdict"
|
|
1561
|
+
],
|
|
1562
|
+
"name": "goal-id",
|
|
1563
|
+
"type": "string"
|
|
1564
|
+
},
|
|
1565
|
+
{
|
|
1566
|
+
"appliesToVerbs": [
|
|
1567
|
+
"record-critic-verdict"
|
|
1568
|
+
],
|
|
1569
|
+
"name": "classification-event-id",
|
|
1570
|
+
"type": "string"
|
|
1571
|
+
},
|
|
1524
1572
|
{
|
|
1525
1573
|
"appliesToVerbs": [
|
|
1526
1574
|
"create-goals"
|
|
@@ -1743,6 +1791,8 @@
|
|
|
1743
1791
|
"record-review-blockers",
|
|
1744
1792
|
"steer",
|
|
1745
1793
|
"classify-blocker",
|
|
1794
|
+
"record-critic-verdict",
|
|
1795
|
+
"record-critic-gate-override",
|
|
1746
1796
|
"start-pipeline-overlap",
|
|
1747
1797
|
"join-pipeline-overlap",
|
|
1748
1798
|
"rebaseline-pipeline-overlap"
|
|
@@ -1830,6 +1880,14 @@
|
|
|
1830
1880
|
"name": "classify-blocker",
|
|
1831
1881
|
"surface": "command-positional"
|
|
1832
1882
|
},
|
|
1883
|
+
{
|
|
1884
|
+
"name": "record-critic-verdict",
|
|
1885
|
+
"surface": "command-positional"
|
|
1886
|
+
},
|
|
1887
|
+
{
|
|
1888
|
+
"name": "record-critic-gate-override",
|
|
1889
|
+
"surface": "command-positional"
|
|
1890
|
+
},
|
|
1833
1891
|
{
|
|
1834
1892
|
"name": "start-pipeline-overlap",
|
|
1835
1893
|
"surface": "command-positional"
|
|
@@ -255,6 +255,8 @@ export const WORKFLOW_MANIFEST: Record<CanonicalGjcWorkflowSkill, SkillManifest>
|
|
|
255
255
|
"record-review-blockers",
|
|
256
256
|
"steer",
|
|
257
257
|
"classify-blocker",
|
|
258
|
+
"record-critic-verdict",
|
|
259
|
+
"record-critic-gate-override",
|
|
258
260
|
"start-pipeline-overlap",
|
|
259
261
|
"join-pipeline-overlap",
|
|
260
262
|
"rebaseline-pipeline-overlap",
|
|
@@ -290,9 +292,28 @@ export const WORKFLOW_MANIFEST: Record<CanonicalGjcWorkflowSkill, SkillManifest>
|
|
|
290
292
|
"record-review-blockers",
|
|
291
293
|
"steer",
|
|
292
294
|
"classify-blocker",
|
|
295
|
+
"record-critic-verdict",
|
|
296
|
+
"record-critic-gate-override",
|
|
293
297
|
"rebaseline-pipeline-overlap",
|
|
294
298
|
],
|
|
295
299
|
},
|
|
300
|
+
{
|
|
301
|
+
name: "terminus",
|
|
302
|
+
type: "enum",
|
|
303
|
+
enumValues: ["completion", "pause"],
|
|
304
|
+
required: true,
|
|
305
|
+
appliesToVerbs: ["record-critic-verdict"],
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
name: "verdict",
|
|
309
|
+
type: "enum",
|
|
310
|
+
enumValues: ["OKAY", "ITERATE", "REJECT"],
|
|
311
|
+
required: true,
|
|
312
|
+
appliesToVerbs: ["record-critic-verdict"],
|
|
313
|
+
},
|
|
314
|
+
{ name: "blockers-json", type: "string", appliesToVerbs: ["record-critic-verdict"] },
|
|
315
|
+
{ name: "goal-id", type: "string", appliesToVerbs: ["record-critic-verdict"] },
|
|
316
|
+
{ name: "classification-event-id", type: "string", appliesToVerbs: ["record-critic-verdict"] },
|
|
296
317
|
{
|
|
297
318
|
name: "goal-metadata-json",
|
|
298
319
|
type: "string",
|
|
@@ -403,6 +424,8 @@ export const WORKFLOW_MANIFEST: Record<CanonicalGjcWorkflowSkill, SkillManifest>
|
|
|
403
424
|
"record-review-blockers",
|
|
404
425
|
"steer",
|
|
405
426
|
"classify-blocker",
|
|
427
|
+
"record-critic-verdict",
|
|
428
|
+
"record-critic-gate-override",
|
|
406
429
|
"start-pipeline-overlap",
|
|
407
430
|
"join-pipeline-overlap",
|
|
408
431
|
"rebaseline-pipeline-overlap",
|