@quantiya/codevibe-core 1.0.23 → 2.0.1
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/dist/__tests__/cp-5-baseline-invariants.test.d.ts +1 -0
- package/dist/adapter/__tests__/capabilities.test.d.ts +1 -0
- package/dist/adapter/__tests__/contract-conformance.test.d.ts +1 -0
- package/dist/adapter/__tests__/packets.test.d.ts +1 -0
- package/dist/adapter/__tests__/progress.test.d.ts +1 -0
- package/dist/adapter/__tests__/registry.test.d.ts +1 -0
- package/dist/adapter/__tests__/smoke/claude.smoke.test.d.ts +1 -0
- package/dist/adapter/__tests__/smoke/codex.smoke.test.d.ts +1 -0
- package/dist/adapter/__tests__/smoke/gemini.smoke.test.d.ts +1 -0
- package/dist/adapter/capabilities.d.ts +68 -0
- package/dist/adapter/index.d.ts +7 -0
- package/dist/adapter/packets.d.ts +129 -0
- package/dist/adapter/progress.d.ts +93 -0
- package/dist/adapter/registry.d.ts +24 -0
- package/dist/adapter/types.d.ts +22 -0
- package/dist/appsync/__tests__/appsync-client-apply-user-decision.test.d.ts +1 -0
- package/dist/appsync/__tests__/appsync-client-classb.test.d.ts +1 -0
- package/dist/appsync/__tests__/appsync-client-planner.test.d.ts +1 -0
- package/dist/appsync/__tests__/appsync-client.test.d.ts +1 -0
- package/dist/appsync/appsync-client.d.ts +278 -1
- package/dist/appsync/index.d.ts +1 -1
- package/dist/appsync/queries.d.ts +8 -0
- package/dist/audit-keys/__tests__/audit-keys-parity.test.d.ts +1 -0
- package/dist/audit-keys/index.d.ts +41 -0
- package/dist/auth/__tests__/auth-telemetry.test.d.ts +1 -0
- package/dist/auth/auth-telemetry.d.ts +29 -8
- package/dist/companion-mode/__tests__/persist-preference.test.d.ts +1 -0
- package/dist/companion-mode/__tests__/resolve-agent.test.d.ts +1 -0
- package/dist/companion-mode/agent-picker.d.ts +9 -0
- package/dist/companion-mode/index.d.ts +55 -0
- package/dist/companion-mode/persist-preference.d.ts +24 -0
- package/dist/companion-mode/resolve-agent.d.ts +41 -0
- package/dist/index.d.ts +13 -1
- package/dist/index.js +253 -33
- package/dist/local-executor/__tests__/authority-symlink-fixture.d.ts +15 -0
- package/dist/local-executor/__tests__/authority.test.d.ts +1 -0
- package/dist/local-executor/__tests__/class-a-emit.test.d.ts +1 -0
- package/dist/local-executor/__tests__/class-b-consumer.integration.test.d.ts +1 -0
- package/dist/local-executor/__tests__/class-b-consumer.test.d.ts +1 -0
- package/dist/local-executor/__tests__/hook-bridge.test.d.ts +1 -0
- package/dist/local-executor/__tests__/local-executor.integration.test.d.ts +1 -0
- package/dist/local-executor/__tests__/spawn.test.d.ts +1 -0
- package/dist/local-executor/__tests__/verification-runner.test.d.ts +1 -0
- package/dist/local-executor/authority.d.ts +29 -0
- package/dist/local-executor/class-a-emit.d.ts +138 -0
- package/dist/local-executor/class-b-consumer.d.ts +121 -0
- package/dist/local-executor/hook-bridge.d.ts +36 -0
- package/dist/local-executor/index.d.ts +8 -0
- package/dist/local-executor/local-executor-impl.d.ts +83 -0
- package/dist/local-executor/spawn.d.ts +6 -0
- package/dist/local-executor/types.d.ts +183 -0
- package/dist/local-executor/verification-gates/build.d.ts +6 -0
- package/dist/local-executor/verification-gates/deploy-preflight.d.ts +6 -0
- package/dist/local-executor/verification-gates/diff-sanity.d.ts +6 -0
- package/dist/local-executor/verification-gates/hostile-grep.d.ts +6 -0
- package/dist/local-executor/verification-gates/lint.d.ts +6 -0
- package/dist/local-executor/verification-gates/shell-runner.d.ts +40 -0
- package/dist/local-executor/verification-gates/source-traceability.d.ts +6 -0
- package/dist/local-executor/verification-gates/tests.d.ts +6 -0
- package/dist/local-executor/verification-gates/typecheck.d.ts +6 -0
- package/dist/local-executor/verification-runner.d.ts +28 -0
- package/dist/orchestration/__tests__/setup-bootstrap.test.d.ts +1 -0
- package/dist/orchestration/__tests__/setup-failure-recourse.test.d.ts +1 -0
- package/dist/orchestration/__tests__/setup-save.test.d.ts +1 -0
- package/dist/orchestration/__tests__/setup-seat-picker.test.d.ts +1 -0
- package/dist/orchestration/__tests__/setup-telemetry.test.d.ts +1 -0
- package/dist/orchestration/__tests__/setup-test-agents.test.d.ts +1 -0
- package/dist/orchestration/__tests__/setup-types.test.d.ts +1 -0
- package/dist/orchestration/__tests__/setup-wizard.test.d.ts +1 -0
- package/dist/orchestration/__tests__/v1-options.test.d.ts +1 -0
- package/dist/orchestration/detect-agents.d.ts +57 -0
- package/dist/orchestration/index.d.ts +3 -0
- package/dist/orchestration/orchestration-cli.d.ts +12 -0
- package/dist/orchestration/setup-bootstrap.d.ts +146 -0
- package/dist/orchestration/setup-failure-recourse.d.ts +23 -0
- package/dist/orchestration/setup-save.d.ts +47 -0
- package/dist/orchestration/setup-seat-picker.d.ts +72 -0
- package/dist/orchestration/setup-telemetry.d.ts +54 -0
- package/dist/orchestration/setup-test-agents.d.ts +108 -0
- package/dist/orchestration/setup-types.d.ts +140 -0
- package/dist/orchestration/setup-wizard.d.ts +57 -0
- package/dist/orchestration/v1-options.d.ts +97 -0
- package/dist/orchestration-shell/__tests__/cli-authority-bridge.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/cli-planner-stack.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/cli-singleton-enforcement.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/cli-stub-session-adapter.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/components.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/emit-shell-event.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/gate-prompts.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/hostile-grep.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/mode-selection.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/process-markers.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/reducer.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/runOrchestrationShell-classify-dispatch.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/runOrchestrationShell-planner-wiring.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/runOrchestrationShell-signal.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/runOrchestrationShell.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/slash-router.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/sticky-preference.test.d.ts +1 -0
- package/dist/orchestration-shell/cli.d.ts +96 -0
- package/dist/orchestration-shell/cli.js +8309 -0
- package/dist/orchestration-shell/cohort-flag.d.ts +16 -0
- package/dist/orchestration-shell/components/CodeVibeLogo.d.ts +2 -0
- package/dist/orchestration-shell/components/ConversationPane.d.ts +7 -0
- package/dist/orchestration-shell/components/GatePromptEntry.d.ts +9 -0
- package/dist/orchestration-shell/components/InputBar.d.ts +41 -0
- package/dist/orchestration-shell/components/OrchestrationApp.d.ts +63 -0
- package/dist/orchestration-shell/components/StatusBar.d.ts +7 -0
- package/dist/orchestration-shell/components/nodes/AdvisoryEntry.d.ts +8 -0
- package/dist/orchestration-shell/components/nodes/GateStatusNode.d.ts +8 -0
- package/dist/orchestration-shell/components/nodes/PlannerDecisionEntry.d.ts +8 -0
- package/dist/orchestration-shell/components/nodes/ReviewerQuorumStatusNode.d.ts +8 -0
- package/dist/orchestration-shell/components/nodes/SlashOutputEntry.d.ts +8 -0
- package/dist/orchestration-shell/components/nodes/SubagentEventEntry.d.ts +8 -0
- package/dist/orchestration-shell/components/nodes/UserMessageEntry.d.ts +8 -0
- package/dist/orchestration-shell/emit-shell-event.d.ts +64 -0
- package/dist/orchestration-shell/gate-prompts.d.ts +123 -0
- package/dist/orchestration-shell/index.d.ts +100 -0
- package/dist/orchestration-shell/ink-runtime.d.ts +64 -0
- package/dist/orchestration-shell/mode-selection.d.ts +46 -0
- package/dist/orchestration-shell/non-tty-fallback.d.ts +46 -0
- package/dist/orchestration-shell/process-markers.d.ts +12 -0
- package/dist/orchestration-shell/reducer.d.ts +8 -0
- package/dist/orchestration-shell/slash-router.d.ts +45 -0
- package/dist/orchestration-shell/sticky-preference.d.ts +24 -0
- package/dist/orchestration-shell/store.d.ts +17 -0
- package/dist/orchestration-shell/types.d.ts +417 -0
- package/dist/planner/__tests__/cache-clarification-bypass.test.d.ts +1 -0
- package/dist/planner/__tests__/cache.test.d.ts +1 -0
- package/dist/planner/__tests__/client.test.d.ts +1 -0
- package/dist/planner/__tests__/health-machine-transitions.test.d.ts +1 -0
- package/dist/planner/__tests__/types-zod.test.d.ts +1 -0
- package/dist/planner/adapter.d.ts +16 -0
- package/dist/planner/cache.d.ts +35 -0
- package/dist/planner/client.d.ts +103 -0
- package/dist/planner/health-state.d.ts +24 -0
- package/dist/planner/index.d.ts +5 -0
- package/dist/planner/types.d.ts +113 -0
- package/dist/reviewer/__tests__/integration.test.d.ts +1 -0
- package/dist/reviewer/__tests__/mocks.test.d.ts +1 -0
- package/dist/reviewer/__tests__/output-parser.test.d.ts +1 -0
- package/dist/reviewer/__tests__/registry.test.d.ts +1 -0
- package/dist/reviewer/__tests__/subprocess.test.d.ts +1 -0
- package/dist/reviewer/index.d.ts +15 -0
- package/dist/reviewer/mocks.d.ts +80 -0
- package/dist/reviewer/output-parser.d.ts +95 -0
- package/dist/reviewer/provider.d.ts +153 -0
- package/dist/reviewer/providers/__tests__/claude-live-smoke.test.d.ts +1 -0
- package/dist/reviewer/providers/__tests__/claude.test.d.ts +1 -0
- package/dist/reviewer/providers/__tests__/codex-live-smoke.test.d.ts +1 -0
- package/dist/reviewer/providers/__tests__/codex.test.d.ts +1 -0
- package/dist/reviewer/providers/__tests__/gemini-live-smoke.test.d.ts +1 -0
- package/dist/reviewer/providers/__tests__/gemini.test.d.ts +1 -0
- package/dist/reviewer/providers/claude.d.ts +59 -0
- package/dist/reviewer/providers/codex.d.ts +67 -0
- package/dist/reviewer/providers/common.d.ts +25 -0
- package/dist/reviewer/providers/gemini.d.ts +108 -0
- package/dist/reviewer/registry.d.ts +87 -0
- package/dist/reviewer/subprocess.d.ts +117 -0
- package/dist/reviewer/types.d.ts +101 -0
- package/dist/session/__tests__/session-resume-service-keys.test.d.ts +1 -0
- package/dist/session/session-resume.d.ts +24 -0
- package/dist/structural-summary/__tests__/__fixtures__/fixture-helpers.d.ts +11 -0
- package/dist/structural-summary/__tests__/assembler.test.d.ts +1 -0
- package/dist/structural-summary/__tests__/generator.test.d.ts +1 -0
- package/dist/structural-summary/__tests__/language-detect.test.d.ts +1 -0
- package/dist/structural-summary/__tests__/manifest-parsers/cargo.test.d.ts +1 -0
- package/dist/structural-summary/__tests__/manifest-parsers/gomod.test.d.ts +1 -0
- package/dist/structural-summary/__tests__/manifest-parsers/gradle.test.d.ts +1 -0
- package/dist/structural-summary/__tests__/manifest-parsers/index.test.d.ts +1 -0
- package/dist/structural-summary/__tests__/manifest-parsers/npm.test.d.ts +1 -0
- package/dist/structural-summary/__tests__/manifest-parsers/podfile.test.d.ts +1 -0
- package/dist/structural-summary/__tests__/manifest-parsers/pyproject.test.d.ts +1 -0
- package/dist/structural-summary/__tests__/opt-in-store.test.d.ts +1 -0
- package/dist/structural-summary/__tests__/privacy-filter.test.d.ts +1 -0
- package/dist/structural-summary/__tests__/safe-file-read.test.d.ts +1 -0
- package/dist/structural-summary/__tests__/user-ignore-matcher.test.d.ts +1 -0
- package/dist/structural-summary/__tests__/walker.test.d.ts +1 -0
- package/dist/structural-summary/generator.d.ts +8 -0
- package/dist/structural-summary/index.d.ts +7 -0
- package/dist/structural-summary/manifest-parsers/cargo.d.ts +3 -0
- package/dist/structural-summary/manifest-parsers/index.d.ts +7 -0
- package/dist/structural-summary/manifest-parsers/npm.d.ts +3 -0
- package/dist/structural-summary/manifest-parsers/other.d.ts +17 -0
- package/dist/structural-summary/opt-in-store.d.ts +24 -0
- package/dist/structural-summary/privacy-filter.d.ts +110 -0
- package/dist/structural-summary/safe-file-read.d.ts +11 -0
- package/dist/structural-summary/types.d.ts +215 -0
- package/dist/structural-summary/user-ignore-matcher.d.ts +9 -0
- package/dist/structural-summary/walker.d.ts +20 -0
- package/dist/types/events.d.ts +17 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/reviewer.d.ts +67 -0
- package/dist/types/session.d.ts +16 -0
- package/package.json +22 -5
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { PlannerInput, PlannerDecision, PlannerProbeResult, Tier } from './types';
|
|
2
|
+
import type { PlannerAdapter } from './adapter';
|
|
3
|
+
import type { PlannerCacheLayer } from './cache';
|
|
4
|
+
import type { PlannerHealthMachine } from './health-state';
|
|
5
|
+
/**
|
|
6
|
+
* AppSync transport interface. Minimal shape so unit tests can inject
|
|
7
|
+
* a stub without mounting the full @quantiya/codevibe-core AppSyncClient.
|
|
8
|
+
*/
|
|
9
|
+
export interface PlannerAppSyncTransport {
|
|
10
|
+
classifyPlannerPrompt(input: {
|
|
11
|
+
sessionId: string;
|
|
12
|
+
prompt: string;
|
|
13
|
+
clarifications: string;
|
|
14
|
+
sessionContext: string;
|
|
15
|
+
budgetHint: string;
|
|
16
|
+
}): Promise<{
|
|
17
|
+
decision: string;
|
|
18
|
+
cacheHit: boolean;
|
|
19
|
+
cacheKind: string | null;
|
|
20
|
+
serverLatencyMs: number;
|
|
21
|
+
providerUsed: string;
|
|
22
|
+
}>;
|
|
23
|
+
pingPlanner(input: {
|
|
24
|
+
sessionId: string;
|
|
25
|
+
}): Promise<{
|
|
26
|
+
ok: boolean;
|
|
27
|
+
ms: number;
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Crypto bridge — `encryptString` + `encryptJson` + `decryptJson`
|
|
32
|
+
* variants the adapter needs. Mirrors the existing
|
|
33
|
+
* codevibe-core CryptoService surface; injectable for tests.
|
|
34
|
+
*/
|
|
35
|
+
export interface PlannerCryptoBridge {
|
|
36
|
+
/** Encrypt a UTF-8 string to base64 AES-GCM ciphertext. */
|
|
37
|
+
encryptString(plaintext: string, sessionKeyB64: string): string;
|
|
38
|
+
/** Decrypt base64 AES-GCM → UTF-8 string. */
|
|
39
|
+
decryptString(ciphertextB64: string, sessionKeyB64: string): string;
|
|
40
|
+
/** Encrypt JSON-serializable value → base64 ciphertext. */
|
|
41
|
+
encryptJson(obj: unknown, sessionKeyB64: string): string;
|
|
42
|
+
}
|
|
43
|
+
export interface SessionKeyResolver {
|
|
44
|
+
getSessionKey(sessionId: string): Promise<string | null>;
|
|
45
|
+
}
|
|
46
|
+
export interface ShellEventEmit {
|
|
47
|
+
sessionId: string;
|
|
48
|
+
type: 'PLANNER_DECISION' | 'PLANNER_CACHE_HIT' | 'PLANNER_DEGRADED' | 'PLANNER_OUTAGE' | 'PLANNER_RECOVERED';
|
|
49
|
+
metadata?: Record<string, unknown>;
|
|
50
|
+
}
|
|
51
|
+
export type EmitShellEventFn = (args: ShellEventEmit) => Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* CP-1.b Stage 2 r2 M-3 — Typed errors that must NOT degrade health.
|
|
54
|
+
*
|
|
55
|
+
* The Lambda surfaces tier-gate / budget rejections as named-error
|
|
56
|
+
* GraphQL responses. Stage 2 r1's catch block recorded EVERY failure
|
|
57
|
+
* as a provider-health failure via `health.recordCall(elapsed, false)`,
|
|
58
|
+
* incorrectly driving the health machine toward Degraded/Outage on
|
|
59
|
+
* what are user-tier policy events (not provider outages). The
|
|
60
|
+
* client now classifies errors and ONLY records provider failures
|
|
61
|
+
* against health; tier/budget rejections emit NOTIFICATION events
|
|
62
|
+
* and throw without touching the machine.
|
|
63
|
+
*/
|
|
64
|
+
export declare class PlannerBudgetExceededError extends Error {
|
|
65
|
+
constructor(msg: string);
|
|
66
|
+
}
|
|
67
|
+
export declare class PlannerTierGateRejectedError extends Error {
|
|
68
|
+
constructor(msg: string);
|
|
69
|
+
}
|
|
70
|
+
export declare class BackendPlannerClient implements PlannerAdapter {
|
|
71
|
+
private transport;
|
|
72
|
+
private cache;
|
|
73
|
+
private health;
|
|
74
|
+
private crypto;
|
|
75
|
+
private sessionKeyResolver;
|
|
76
|
+
private emitShellEvent;
|
|
77
|
+
/** Shell-side tier-change detection (LOCK #30). */
|
|
78
|
+
lastClassifyTier: Tier | null;
|
|
79
|
+
/**
|
|
80
|
+
* CP-1.b Stage 2 r2 M-4 — Active session for probe(). The probe
|
|
81
|
+
* mutation requires a sessionId for ownership check; carrying the
|
|
82
|
+
* session in client state lets callers use the canonical
|
|
83
|
+
* `PlannerAdapter.probe()` contract. Set via `setActiveSession()`
|
|
84
|
+
* by orchestration-shell on session start.
|
|
85
|
+
*/
|
|
86
|
+
private activeSessionId;
|
|
87
|
+
constructor(transport: PlannerAppSyncTransport, cache: PlannerCacheLayer, health: PlannerHealthMachine, crypto: PlannerCryptoBridge, sessionKeyResolver: SessionKeyResolver, emitShellEvent: EmitShellEventFn);
|
|
88
|
+
/**
|
|
89
|
+
* CP-1.b Stage 2 r2 M-4 — Set the active session ID used by
|
|
90
|
+
* `probe()`. Called by the orchestration-shell on session start
|
|
91
|
+
* (and cleared to `null` on session end).
|
|
92
|
+
*/
|
|
93
|
+
setActiveSession(sessionId: string | null): void;
|
|
94
|
+
classify(input: PlannerInput): Promise<PlannerDecision>;
|
|
95
|
+
/**
|
|
96
|
+
* CP-1.b Stage 2 r2 M-4 — Honor the `PlannerAdapter.probe()`
|
|
97
|
+
* contract by reading the session from client state (set via
|
|
98
|
+
* `setActiveSession()`). Stage 2 r1 threw unconditionally and
|
|
99
|
+
* required callers to use the now-removed `probeWithSession()`
|
|
100
|
+
* method, which violated the adapter interface.
|
|
101
|
+
*/
|
|
102
|
+
probe(): Promise<PlannerProbeResult>;
|
|
103
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { PlannerHealthState, PlannerHealthTransition } from './types';
|
|
2
|
+
export type { PlannerHealthState, PlannerHealthTransition };
|
|
3
|
+
export declare class PlannerHealthMachine {
|
|
4
|
+
private emitFn;
|
|
5
|
+
state: PlannerHealthState;
|
|
6
|
+
consecutiveFailures: number;
|
|
7
|
+
consecutiveSuccesses: number;
|
|
8
|
+
recentLatenciesMs: number[];
|
|
9
|
+
private readonly URGENT_FAILURE_FOR_DEGRADE;
|
|
10
|
+
private readonly P95_DEGRADE_THRESHOLD_MS;
|
|
11
|
+
private readonly P95_RECOVER_THRESHOLD_MS;
|
|
12
|
+
private readonly DEGRADED_TO_OUTAGE_FAILURES;
|
|
13
|
+
private readonly RECOVER_SUCCESSES_NEEDED;
|
|
14
|
+
private readonly RING_BUFFER_SIZE;
|
|
15
|
+
private readonly DEGRADED_PROBE_INTERVAL_MS;
|
|
16
|
+
private readonly OUTAGE_PROBE_INTERVAL_MS;
|
|
17
|
+
private lastProbeAt;
|
|
18
|
+
constructor(emitFn: (transition: PlannerHealthTransition) => void);
|
|
19
|
+
recordCall(latencyMs: number, success: boolean): PlannerHealthState;
|
|
20
|
+
shouldProbe(): boolean;
|
|
21
|
+
markProbeFired(): void;
|
|
22
|
+
private deriveNextState;
|
|
23
|
+
private p95Of;
|
|
24
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * from './types';
|
|
2
|
+
export * from './adapter';
|
|
3
|
+
export { PlannerCacheLayer } from './cache';
|
|
4
|
+
export { PlannerHealthMachine } from './health-state';
|
|
5
|
+
export { BackendPlannerClient, PlannerBudgetExceededError, PlannerTierGateRejectedError, type PlannerAppSyncTransport, type PlannerCryptoBridge, type SessionKeyResolver, type ShellEventEmit, type EmitShellEventFn, } from './client';
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export type Tier = 'FREE' | 'PRO' | 'MAX';
|
|
3
|
+
export interface SessionContext {
|
|
4
|
+
sessionId: string;
|
|
5
|
+
userId: string;
|
|
6
|
+
tier: Tier;
|
|
7
|
+
currentTaskState: 'none' | 'in_progress' | 'awaiting_user' | 'awaiting_review' | 'merge_gate_pending';
|
|
8
|
+
structuralSummaryDigest: string;
|
|
9
|
+
recentEventCount: number;
|
|
10
|
+
}
|
|
11
|
+
export declare const SessionContextSchema: z.ZodObject<{
|
|
12
|
+
sessionId: z.ZodString;
|
|
13
|
+
userId: z.ZodString;
|
|
14
|
+
tier: z.ZodEnum<["FREE", "PRO", "MAX"]>;
|
|
15
|
+
currentTaskState: z.ZodEnum<["none", "in_progress", "awaiting_user", "awaiting_review", "merge_gate_pending"]>;
|
|
16
|
+
structuralSummaryDigest: z.ZodString;
|
|
17
|
+
recentEventCount: z.ZodNumber;
|
|
18
|
+
}, "strip", z.ZodTypeAny, {
|
|
19
|
+
sessionId: string;
|
|
20
|
+
userId: string;
|
|
21
|
+
structuralSummaryDigest: string;
|
|
22
|
+
tier: "FREE" | "PRO" | "MAX";
|
|
23
|
+
currentTaskState: "none" | "merge_gate_pending" | "in_progress" | "awaiting_user" | "awaiting_review";
|
|
24
|
+
recentEventCount: number;
|
|
25
|
+
}, {
|
|
26
|
+
sessionId: string;
|
|
27
|
+
userId: string;
|
|
28
|
+
structuralSummaryDigest: string;
|
|
29
|
+
tier: "FREE" | "PRO" | "MAX";
|
|
30
|
+
currentTaskState: "none" | "merge_gate_pending" | "in_progress" | "awaiting_user" | "awaiting_review";
|
|
31
|
+
recentEventCount: number;
|
|
32
|
+
}>;
|
|
33
|
+
export interface BudgetHint {
|
|
34
|
+
wallClockMsRemaining: number;
|
|
35
|
+
reviseAttempts: number;
|
|
36
|
+
}
|
|
37
|
+
export declare const BudgetHintSchema: z.ZodObject<{
|
|
38
|
+
wallClockMsRemaining: z.ZodNumber;
|
|
39
|
+
reviseAttempts: z.ZodNumber;
|
|
40
|
+
}, "strip", z.ZodTypeAny, {
|
|
41
|
+
wallClockMsRemaining: number;
|
|
42
|
+
reviseAttempts: number;
|
|
43
|
+
}, {
|
|
44
|
+
wallClockMsRemaining: number;
|
|
45
|
+
reviseAttempts: number;
|
|
46
|
+
}>;
|
|
47
|
+
export interface Clarification {
|
|
48
|
+
question: string;
|
|
49
|
+
answer: string;
|
|
50
|
+
}
|
|
51
|
+
export declare const ClarificationSchema: z.ZodObject<{
|
|
52
|
+
question: z.ZodString;
|
|
53
|
+
answer: z.ZodString;
|
|
54
|
+
}, "strip", z.ZodTypeAny, {
|
|
55
|
+
question: string;
|
|
56
|
+
answer: string;
|
|
57
|
+
}, {
|
|
58
|
+
question: string;
|
|
59
|
+
answer: string;
|
|
60
|
+
}>;
|
|
61
|
+
export interface PlannerInput {
|
|
62
|
+
prompt: string;
|
|
63
|
+
clarifications: Clarification[];
|
|
64
|
+
sessionContext: SessionContext;
|
|
65
|
+
budgetHint: BudgetHint;
|
|
66
|
+
}
|
|
67
|
+
export interface PlannerDecision {
|
|
68
|
+
action: 'start_task' | 'summarize_current_status' | 'advisory_response' | 'ask_user' | 'refuse';
|
|
69
|
+
rationale: string;
|
|
70
|
+
clarifying_question?: string;
|
|
71
|
+
advisory_summary?: string;
|
|
72
|
+
/** Opaque per parent §6 lines 967-972; CP-1 NEVER inspects fields. */
|
|
73
|
+
gateRequest?: Record<string, unknown>;
|
|
74
|
+
}
|
|
75
|
+
export declare const PlannerDecisionSchema: z.ZodObject<{
|
|
76
|
+
action: z.ZodEnum<["start_task", "summarize_current_status", "advisory_response", "ask_user", "refuse"]>;
|
|
77
|
+
rationale: z.ZodString;
|
|
78
|
+
clarifying_question: z.ZodOptional<z.ZodString>;
|
|
79
|
+
advisory_summary: z.ZodOptional<z.ZodString>;
|
|
80
|
+
gateRequest: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
81
|
+
}, "strip", z.ZodTypeAny, {
|
|
82
|
+
action: "start_task" | "summarize_current_status" | "advisory_response" | "ask_user" | "refuse";
|
|
83
|
+
rationale: string;
|
|
84
|
+
clarifying_question?: string | undefined;
|
|
85
|
+
advisory_summary?: string | undefined;
|
|
86
|
+
gateRequest?: Record<string, unknown> | undefined;
|
|
87
|
+
}, {
|
|
88
|
+
action: "start_task" | "summarize_current_status" | "advisory_response" | "ask_user" | "refuse";
|
|
89
|
+
rationale: string;
|
|
90
|
+
clarifying_question?: string | undefined;
|
|
91
|
+
advisory_summary?: string | undefined;
|
|
92
|
+
gateRequest?: Record<string, unknown> | undefined;
|
|
93
|
+
}>;
|
|
94
|
+
export interface PlannerProbeResult {
|
|
95
|
+
ok: boolean;
|
|
96
|
+
latencyMs: number;
|
|
97
|
+
errorClass?: 'timeout' | 'rate_limited' | 'unreachable' | 'malformed_response' | 'auth_failed';
|
|
98
|
+
}
|
|
99
|
+
export type ClassificationKind = 'workflow_status_query' | 'workflow_audit_query' | 'workflow_review_query' | 'workflow_continuation_query' | 'advisory_response_safe' | 'ask_user_clarification';
|
|
100
|
+
export interface CachedClassification {
|
|
101
|
+
kind: ClassificationKind;
|
|
102
|
+
clarifyingQuestion?: string;
|
|
103
|
+
advisorySummary?: string;
|
|
104
|
+
}
|
|
105
|
+
export type PlannerHealthState = 'Available' | 'Degraded' | 'Outage';
|
|
106
|
+
export interface PlannerHealthTransition {
|
|
107
|
+
newState: PlannerHealthState;
|
|
108
|
+
fromState: PlannerHealthState;
|
|
109
|
+
reason: string;
|
|
110
|
+
consecutiveFailures: number;
|
|
111
|
+
consecutiveSuccesses: number;
|
|
112
|
+
p95Ms: number;
|
|
113
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type { AgentKind, ReviewerRole, ReviewerVerdict, VerdictId, VerdictKind, } from './types.js';
|
|
2
|
+
export type { ReviewerError, ReviewerProvider, ReviewerSpec, } from './provider.js';
|
|
3
|
+
export { ReviewerErrorClass } from './provider.js';
|
|
4
|
+
export type { ParseResult, ParsedVerdict, VerdictParseError, } from './output-parser.js';
|
|
5
|
+
export { parseVerdictOutput, VerdictParseErrorClass } from './output-parser.js';
|
|
6
|
+
export type { RunReviewerOptions, SubprocessError, SubprocessOutcome, } from './subprocess.js';
|
|
7
|
+
export { runReviewer, SubprocessErrorClass } from './subprocess.js';
|
|
8
|
+
export type { ClaudeReviewerProviderOptions } from './providers/claude.js';
|
|
9
|
+
export { ClaudeReviewerProvider } from './providers/claude.js';
|
|
10
|
+
export type { GeminiEnvelope, GeminiModelStats, GeminiReviewerProviderOptions, GeminiStats, } from './providers/gemini.js';
|
|
11
|
+
export { GeminiReviewerProvider } from './providers/gemini.js';
|
|
12
|
+
export type { CodexReviewerProviderOptions } from './providers/codex.js';
|
|
13
|
+
export { CodexReviewerProvider } from './providers/codex.js';
|
|
14
|
+
export { ReviewerRegistry, createSubprocessReviewerRegistry, } from './registry.js';
|
|
15
|
+
export { MockReviewerSpawner, StaticReviewerMock } from './mocks.js';
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { type ReviewerProvider, type ReviewerSpec } from './provider.js';
|
|
2
|
+
import type { AgentKind, ReviewerVerdict, VerdictKind } from './types.js';
|
|
3
|
+
import { type ReviewerError } from './provider.js';
|
|
4
|
+
/**
|
|
5
|
+
* Scripted `ReviewerProvider` for tests. Each `evaluate(spec, gateId)`
|
|
6
|
+
* pops the next response from the FIFO queue keyed by
|
|
7
|
+
* `(spec.agent, gateId)`. If no script remains, returns a SpawnFailed
|
|
8
|
+
* error with a diagnostic so test setup bugs surface loudly.
|
|
9
|
+
*
|
|
10
|
+
* Use the `script_*` methods to queue responses before tests call
|
|
11
|
+
* `evaluate`.
|
|
12
|
+
*/
|
|
13
|
+
export declare class MockReviewerSpawner implements ReviewerProvider {
|
|
14
|
+
private readonly scripts;
|
|
15
|
+
private static key;
|
|
16
|
+
/**
|
|
17
|
+
* Script a verdict (with empty `suggested_changes`) for the next
|
|
18
|
+
* `evaluate(agent, gateId)` call. Use `scriptVerdictWithChanges`
|
|
19
|
+
* when `kind === 'REVISE'` (the parser-locked invariant requires
|
|
20
|
+
* non-empty changes for REVISE).
|
|
21
|
+
*/
|
|
22
|
+
scriptVerdict(agent: AgentKind, gateId: string, kind: VerdictKind, reasoning: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* Script a verdict with explicit `suggested_changes`. Required when
|
|
25
|
+
* `kind === 'REVISE'`.
|
|
26
|
+
*/
|
|
27
|
+
scriptVerdictWithChanges(agent: AgentKind, gateId: string, kind: VerdictKind, reasoning: string, suggested_changes: string[]): void;
|
|
28
|
+
/** Script an error to return on the next `evaluate(agent, gateId)` call. */
|
|
29
|
+
scriptError(agent: AgentKind, gateId: string, error: ReviewerError): void;
|
|
30
|
+
/**
|
|
31
|
+
* How many scripted responses remain for the given key. Useful for
|
|
32
|
+
* test post-conditions ("all scripts were consumed").
|
|
33
|
+
*/
|
|
34
|
+
remaining(agent: AgentKind, gateId: string): number;
|
|
35
|
+
evaluate(spec: ReviewerSpec, gateId: string): Promise<ReviewerVerdict>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Stateless `ReviewerProvider` for engine-level integration tests and
|
|
39
|
+
* smoke tests. Ignores `gateId`; returns a fixed verdict per agent
|
|
40
|
+
* (or a global default).
|
|
41
|
+
*
|
|
42
|
+
* Construct via static factories:
|
|
43
|
+
* - `StaticReviewerMock.allApprove()` / `.allReject()` / `.allRevise(changes)`
|
|
44
|
+
* / `.allEscalate()` — global default, every agent returns the same.
|
|
45
|
+
* - `StaticReviewerMock.allError(err)` — every agent returns the same error.
|
|
46
|
+
*
|
|
47
|
+
* Stack per-agent overrides on top:
|
|
48
|
+
* - `.withAgentVerdict(agent, kind)` — override one agent's verdict.
|
|
49
|
+
* - `.withAgentError(agent, err)` — override one agent's error.
|
|
50
|
+
*
|
|
51
|
+
* Stacking models mixed-verdict scenarios: e.g.
|
|
52
|
+
* `StaticReviewerMock.allApprove().withAgentVerdict('gemini', 'REJECT')`
|
|
53
|
+
* → Claude approves + Gemini rejects + Codex approves → engine escalates.
|
|
54
|
+
*/
|
|
55
|
+
export declare class StaticReviewerMock implements ReviewerProvider {
|
|
56
|
+
private defaultResponse;
|
|
57
|
+
private readonly perAgent;
|
|
58
|
+
/** Empty mock. Returns SpawnFailed with a diagnostic on every
|
|
59
|
+
* `evaluate` call until a default or per-agent override is set. */
|
|
60
|
+
static new(): StaticReviewerMock;
|
|
61
|
+
/** All reviewers return APPROVE. */
|
|
62
|
+
static allApprove(): StaticReviewerMock;
|
|
63
|
+
/** All reviewers return REJECT. */
|
|
64
|
+
static allReject(): StaticReviewerMock;
|
|
65
|
+
/** All reviewers return REVISE with the given suggested changes.
|
|
66
|
+
* Empty `changes` falls back to a placeholder. */
|
|
67
|
+
static allRevise(changes: string[]): StaticReviewerMock;
|
|
68
|
+
/** All reviewers return ESCALATE. */
|
|
69
|
+
static allEscalate(): StaticReviewerMock;
|
|
70
|
+
/** All reviewers return the given error. */
|
|
71
|
+
static allError(err: ReviewerError): StaticReviewerMock;
|
|
72
|
+
/**
|
|
73
|
+
* Override the response for one agent. Stacks on top of whatever
|
|
74
|
+
* default was configured. Returns `this` for fluent chaining.
|
|
75
|
+
*/
|
|
76
|
+
withAgentVerdict(agent: AgentKind, kind: VerdictKind): this;
|
|
77
|
+
/** Override to return an error for one specific agent. */
|
|
78
|
+
withAgentError(agent: AgentKind, err: ReviewerError): this;
|
|
79
|
+
evaluate(spec: ReviewerSpec, gateId: string): Promise<ReviewerVerdict>;
|
|
80
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { VerdictKind } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Successfully parsed reviewer reply. The engine's fan-out layer lifts
|
|
4
|
+
* these fields into a `ReviewerVerdict` alongside telemetry (agent, tokens,
|
|
5
|
+
* latency, model) supplied by the subprocess layer.
|
|
6
|
+
*/
|
|
7
|
+
export interface ParsedVerdict {
|
|
8
|
+
/** The verdict the reviewer returned. */
|
|
9
|
+
kind: VerdictKind;
|
|
10
|
+
/**
|
|
11
|
+
* Free-form reasoning text (joined with blank-line paragraph separators
|
|
12
|
+
* preserved). Never empty by the time we reach here — reviewers that
|
|
13
|
+
* return only a verdict line fail parsing via `reasoning_missing`.
|
|
14
|
+
*/
|
|
15
|
+
reasoning: string;
|
|
16
|
+
/**
|
|
17
|
+
* Ordered list of specific changes. Always non-empty when
|
|
18
|
+
* `kind === 'REVISE'`; always empty otherwise (enforced by the parser
|
|
19
|
+
* via `revise_missing_changes` / `suggested_changes_require_revise`).
|
|
20
|
+
*/
|
|
21
|
+
suggested_changes: string[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Why a reviewer's reply failed the locked-format check. Discriminated
|
|
25
|
+
* union; the subprocess layer maps any of these into `ReviewerError` with
|
|
26
|
+
* `kind: 'parse_failure'` and the raw output attached.
|
|
27
|
+
*
|
|
28
|
+
* Mirrors Rust's `VerdictParseError` enum 1:1.
|
|
29
|
+
*/
|
|
30
|
+
export type VerdictParseError = {
|
|
31
|
+
/** The entire reply was whitespace or empty. A reviewer that wrote
|
|
32
|
+
* nothing has effectively timed out. */
|
|
33
|
+
kind: 'empty_output';
|
|
34
|
+
} | {
|
|
35
|
+
/**
|
|
36
|
+
* The first non-blank line did not start with one of the four
|
|
37
|
+
* verdict keywords (case-insensitive). Includes any leading markdown
|
|
38
|
+
* formatting, quotation, or `VERDICT:` prefix that makes the line
|
|
39
|
+
* diverge from the locked contract.
|
|
40
|
+
*
|
|
41
|
+
* Also fired when a non-blank, non-indented line of prose appears
|
|
42
|
+
* after the bullet section starts (the format reserves post-bullet
|
|
43
|
+
* lines for blank lines or indented continuations only).
|
|
44
|
+
*/
|
|
45
|
+
kind: 'invalid_verdict';
|
|
46
|
+
/** The offending line, trimmed but otherwise verbatim. */
|
|
47
|
+
found: string;
|
|
48
|
+
} | {
|
|
49
|
+
/** Verdict was parsed but no reasoning followed. The locked contract
|
|
50
|
+
* requires reasoning text so the audit record and user-facing
|
|
51
|
+
* disagreement UI have something to show; a bare APPROVE / REJECT
|
|
52
|
+
* line is a parse failure. */
|
|
53
|
+
kind: 'reasoning_missing';
|
|
54
|
+
} | {
|
|
55
|
+
/** Verdict was REVISE but no bulleted suggested-changes list followed.
|
|
56
|
+
* Design-locked: REVISE requires at least one concrete change. */
|
|
57
|
+
kind: 'revise_missing_changes';
|
|
58
|
+
} | {
|
|
59
|
+
/** A non-REVISE verdict was followed by a bulleted list, which the
|
|
60
|
+
* locked contract reserves for REVISE only. */
|
|
61
|
+
kind: 'suggested_changes_require_revise';
|
|
62
|
+
/** The non-REVISE verdict that erroneously had bullets. */
|
|
63
|
+
found: VerdictKind;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Class wrapper around a `VerdictParseError` so callers can `throw`/`catch`
|
|
67
|
+
* structured errors via JS idioms. `.detail` carries the discriminated
|
|
68
|
+
* union; `Error.message` is a human-readable formatting.
|
|
69
|
+
*/
|
|
70
|
+
export declare class VerdictParseErrorClass extends Error {
|
|
71
|
+
readonly detail: VerdictParseError;
|
|
72
|
+
constructor(detail: VerdictParseError);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Result type for `parseVerdictOutput`. Discriminated by `ok`. Mirrors
|
|
76
|
+
* Rust's `Result<ParsedVerdict, VerdictParseError>` without forcing TS
|
|
77
|
+
* callers to `try/catch` — most call sites want to inspect failure types
|
|
78
|
+
* directly to feed the audit log.
|
|
79
|
+
*/
|
|
80
|
+
export type ParseResult = {
|
|
81
|
+
ok: true;
|
|
82
|
+
verdict: ParsedVerdict;
|
|
83
|
+
} | {
|
|
84
|
+
ok: false;
|
|
85
|
+
error: VerdictParseError;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Parse a reviewer reply. Strict: any deviation from the locked format
|
|
89
|
+
* returns `{ ok: false, error: ... }` which the subprocess layer routes to
|
|
90
|
+
* a parse-failure `ReviewerError`.
|
|
91
|
+
*
|
|
92
|
+
* Mirrors Rust's `parse_verdict_output` byte-for-byte. Test coverage
|
|
93
|
+
* matches the Rust unit-test set verbatim.
|
|
94
|
+
*/
|
|
95
|
+
export declare function parseVerdictOutput(raw: string): ParseResult;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type { AgentKind, ReviewerRole, ReviewerVerdict } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Spec for spawning one reviewer at one gate. Constructed by the engine
|
|
4
|
+
* from `ReviewerAgentSpec` (from `PolicySnapshot`) + the context bundle for
|
|
5
|
+
* the gate.
|
|
6
|
+
*
|
|
7
|
+
* # Identity
|
|
8
|
+
*
|
|
9
|
+
* Per the 2026-04-23 seat/role pivot, the spec's primary identity is
|
|
10
|
+
* `seat_id` — position in the review panel — NOT `agent`. `agent` may
|
|
11
|
+
* repeat across seats within a single gate (single-vendor case: two Claude
|
|
12
|
+
* seats with different roles). Downstream consensus + verdict validation
|
|
13
|
+
* dedup on `seat_id`, never on `agent`. Providers echo `seat_id` + `role`
|
|
14
|
+
* back on the returned `ReviewerVerdict` so the audit trail can attribute
|
|
15
|
+
* verdicts by lens rather than by agent kind.
|
|
16
|
+
*/
|
|
17
|
+
export interface ReviewerSpec {
|
|
18
|
+
/**
|
|
19
|
+
* Position in the review panel, 0-indexed. For an N-seat policy this is
|
|
20
|
+
* in `0..N`. The primary identity key for this reviewer across the
|
|
21
|
+
* engine, audit log, and FFI — providers MUST echo this value back on
|
|
22
|
+
* the produced `ReviewerVerdict.seat_id`.
|
|
23
|
+
*/
|
|
24
|
+
seat_id: number;
|
|
25
|
+
/**
|
|
26
|
+
* The lens this seat reviews through — Architecture / Correctness /
|
|
27
|
+
* Security for code; Accuracy / Clarity / Completeness for docs;
|
|
28
|
+
* composites for mixed. Drives the role-specific prompt prefix and is
|
|
29
|
+
* echoed back on the verdict for audit attribution. Unique within a
|
|
30
|
+
* policy (a duplicate role defeats the orthogonality purpose).
|
|
31
|
+
*/
|
|
32
|
+
role: ReviewerRole;
|
|
33
|
+
/**
|
|
34
|
+
* Which agent to spawn. MAY repeat across seats when roles differ — the
|
|
35
|
+
* single-vendor case the 2026-04-23 pivot enables.
|
|
36
|
+
*/
|
|
37
|
+
agent: AgentKind;
|
|
38
|
+
/**
|
|
39
|
+
* Tool names the reviewer is allowed to invoke. Typically
|
|
40
|
+
* `["Read", "Grep", "Glob"]` per the read-only reviewer invariant. Shape
|
|
41
|
+
* is agent-agnostic here; each provider enforces the sandbox in its own
|
|
42
|
+
* way:
|
|
43
|
+
* - Claude: `--allowed-tools Read,Grep,Glob` CLI flag.
|
|
44
|
+
* - Gemini: `--approval-mode plan` (Gemini's first-class read-only mode).
|
|
45
|
+
* The `tool_allowlist` is intentionally unused by the Gemini provider;
|
|
46
|
+
* plan mode is the sandbox contract. 2.0.x task #62 tracks adding
|
|
47
|
+
* `--policy <tempfile>` as defense-in-depth.
|
|
48
|
+
* - Codex: `--sandbox read-only --skip-git-repo-check` flags + per-spawn
|
|
49
|
+
* ephemeral output file.
|
|
50
|
+
*/
|
|
51
|
+
tool_allowlist: string[];
|
|
52
|
+
/**
|
|
53
|
+
* Pre-rendered reviewer prompt. Engine renders per artifact type
|
|
54
|
+
* (code / docs / mixed) with a role-specific prefix prepended before
|
|
55
|
+
* calling `evaluate`.
|
|
56
|
+
*/
|
|
57
|
+
prompt_template: string;
|
|
58
|
+
/**
|
|
59
|
+
* Wall-clock timeout for one reviewer's verdict. After this elapses the
|
|
60
|
+
* provider should throw `ReviewerError` with `kind: 'timeout'` and
|
|
61
|
+
* cancel the underlying process.
|
|
62
|
+
*/
|
|
63
|
+
timeout_ms: number;
|
|
64
|
+
/**
|
|
65
|
+
* Optional per-reviewer model preference. `null` defers to the agent's
|
|
66
|
+
* CLI default.
|
|
67
|
+
*/
|
|
68
|
+
model_hint: string | null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Typed error thrown by `ReviewerProvider.evaluate`. Discriminated union
|
|
72
|
+
* matching Rust's `#[serde(tag = "kind", rename_all = "snake_case")]` enum.
|
|
73
|
+
*
|
|
74
|
+
* The engine's consensus path treats any thrown error as equivalent to a
|
|
75
|
+
* `VerdictKind::Escalate` for routing (so safety-defaults-to-escalation
|
|
76
|
+
* holds), but the distinct variants matter for the audit log and the
|
|
77
|
+
* user-facing error message.
|
|
78
|
+
*/
|
|
79
|
+
export type ReviewerError = {
|
|
80
|
+
/** Reviewer exceeded its `timeout_ms` budget. */
|
|
81
|
+
kind: 'timeout';
|
|
82
|
+
/** Which agent timed out (carried so the audit entry can attribute
|
|
83
|
+
* cost / reliability back to the specific agent). */
|
|
84
|
+
agent: AgentKind;
|
|
85
|
+
/** Wall-clock ms elapsed before timeout fired. */
|
|
86
|
+
elapsed_ms: number;
|
|
87
|
+
} | {
|
|
88
|
+
/** Reviewer process could not be launched (CLI missing, spawn syscall
|
|
89
|
+
* failed, etc.). */
|
|
90
|
+
kind: 'spawn_failed';
|
|
91
|
+
agent: AgentKind;
|
|
92
|
+
/** Human-readable cause. */
|
|
93
|
+
reason: string;
|
|
94
|
+
} | {
|
|
95
|
+
/** Reviewer returned but its output couldn't be parsed into a valid
|
|
96
|
+
* verdict. Raw output is preserved for the audit log. */
|
|
97
|
+
kind: 'parse_failure';
|
|
98
|
+
agent: AgentKind;
|
|
99
|
+
/** Raw output (truncated to a reasonable length by the caller if
|
|
100
|
+
* needed). */
|
|
101
|
+
raw_output: string;
|
|
102
|
+
} | {
|
|
103
|
+
/** Reviewer was cancelled by the engine before completing (e.g.,
|
|
104
|
+
* user abort, a sibling reviewer already hard-rejected). No
|
|
105
|
+
* per-agent attribution because cancellation can fire on any
|
|
106
|
+
* reviewer in flight. */
|
|
107
|
+
kind: 'cancelled';
|
|
108
|
+
} | {
|
|
109
|
+
/** A reviewer's task panicked or was aborted before returning a
|
|
110
|
+
* verdict. Mirror of the Rust `InternalJoinFailure` variant. The
|
|
111
|
+
* variant deliberately has no `agent` field — attributing a panic
|
|
112
|
+
* to a specific agent would be a telemetry lie. */
|
|
113
|
+
kind: 'internal_join_failure';
|
|
114
|
+
reason: string;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Class wrapper around a `ReviewerError` so callers can `throw` typed
|
|
118
|
+
* errors and `try { ... } catch (e) { if (e instanceof ReviewerErrorClass) {
|
|
119
|
+
* /* type-narrow on e.detail.kind *\/ } }` from JS-idiom code paths.
|
|
120
|
+
*
|
|
121
|
+
* The `.detail` property carries the discriminated union; `Error.message`
|
|
122
|
+
* is a human-readable formatting matching Rust's `#[error(...)]` strings.
|
|
123
|
+
*/
|
|
124
|
+
export declare class ReviewerErrorClass extends Error {
|
|
125
|
+
/** The structured error detail. Use `.kind` to narrow. */
|
|
126
|
+
readonly detail: ReviewerError;
|
|
127
|
+
constructor(detail: ReviewerError);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Engine's contract with reviewer implementations.
|
|
131
|
+
*
|
|
132
|
+
* **Engine owns lifecycle:** implementations must spawn, await verdict,
|
|
133
|
+
* enforce timeout, cancel, and capture logs internally. The engine calls
|
|
134
|
+
* `evaluate` and awaits — it never holds a handle that could outlive the
|
|
135
|
+
* call.
|
|
136
|
+
*
|
|
137
|
+
* Errors are thrown as `ReviewerErrorClass` instances; callers narrow via
|
|
138
|
+
* the `.detail.kind` discriminator.
|
|
139
|
+
*/
|
|
140
|
+
export interface ReviewerProvider {
|
|
141
|
+
/**
|
|
142
|
+
* Spawn one reviewer per the spec, collect its verdict, enforce timeout.
|
|
143
|
+
*
|
|
144
|
+
* @param spec - the reviewer to spawn (seat_id + role + agent + prompt + timeout)
|
|
145
|
+
* @param gateId - the `ReviewGate` UUID this verdict attaches to. Stored
|
|
146
|
+
* on the returned `ReviewerVerdict.gate_id`.
|
|
147
|
+
* @returns the parsed `ReviewerVerdict` on success.
|
|
148
|
+
* @throws `ReviewerErrorClass` on timeout, spawn failure, parse failure,
|
|
149
|
+
* cancellation, or internal join failure. Use `e.detail.kind` to
|
|
150
|
+
* narrow.
|
|
151
|
+
*/
|
|
152
|
+
evaluate(spec: ReviewerSpec, gateId: string): Promise<ReviewerVerdict>;
|
|
153
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|