@quantiya/codevibe-core 2.0.8 → 2.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/gate-ux-regressions.test.d.ts +1 -0
- package/dist/appsync/__tests__/appsync-client-flag-locator.test.d.ts +1 -0
- package/dist/appsync/__tests__/dispose-watcher-socket.test.d.ts +1 -0
- package/dist/appsync/appsync-client.d.ts +62 -0
- package/dist/auth/__tests__/keychain-cli-nudge.test.d.ts +1 -0
- package/dist/auth/keychain-cli.d.ts +8 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +523 -351
- package/dist/keychain/__tests__/migrate-nudge.test.d.ts +1 -0
- package/dist/keychain/keychain-migrate.d.ts +17 -0
- package/dist/keychain/migrate-nudge.d.ts +38 -0
- package/dist/local-executor/__tests__/protocol-backlog-wiring.test.d.ts +1 -0
- package/dist/local-executor/__tests__/protocol-backlog.test.d.ts +1 -0
- package/dist/local-executor/__tests__/workspace-cleanup-audit.test.d.ts +1 -0
- package/dist/local-executor/anchored-fs.d.ts +7 -0
- package/dist/local-executor/bounded-directory.d.ts +14 -0
- package/dist/local-executor/process-identity.d.ts +30 -0
- package/dist/local-executor/process-tree.d.ts +1 -1
- package/dist/local-executor/protocol-backlog.d.ts +62 -0
- package/dist/local-executor/workspace-cleanup-audit.d.ts +3 -0
- package/dist/local-executor/workspace-materializer.d.ts +23 -2
- package/dist/local-executor/workspace-shadow.d.ts +9 -0
- package/dist/local-model/manager.d.ts +1 -1
- package/dist/orchestration-shell/__tests__/direct-file-delete.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/flag-command.test.d.ts +1 -0
- package/dist/orchestration-shell/__tests__/halt-message-wire-content.test.d.ts +1 -0
- package/dist/orchestration-shell/audit-browser.d.ts +54 -1
- package/dist/orchestration-shell/audit-runner.d.ts +2 -3
- package/dist/orchestration-shell/cli.d.ts +12 -2
- package/dist/orchestration-shell/cli.js +2867 -1500
- package/dist/orchestration-shell/context-items.d.ts +3 -0
- package/dist/orchestration-shell/direct-file-delete.d.ts +22 -0
- package/dist/orchestration-shell/flag-command.d.ts +81 -0
- package/dist/orchestration-shell/gate-prompts.d.ts +41 -0
- package/dist/orchestration-shell/index.d.ts +31 -6
- package/dist/orchestration-shell/quorum-loop.d.ts +64 -4
- package/dist/orchestration-shell/task-progress.d.ts +6 -0
- package/dist/orchestration-shell/types.d.ts +58 -0
- package/dist/orchestration-shell/workspace-shutdown.d.ts +20 -0
- package/dist/reduced-trust-notice.d.ts +44 -0
- package/dist/reviewer/providers/codex.d.ts +5 -3
- package/dist/reviewer/token-usage.d.ts +41 -12
- package/dist/reviewer/types.d.ts +3 -0
- package/dist/substrate/__tests__/command-runner.test.d.ts +1 -0
- package/dist/substrate/types.d.ts +8 -0
- package/dist/tool-activity/consolidator.d.ts +7 -0
- package/dist/tool-activity/ledger.d.ts +33 -13
- package/dist/track-presentation.d.ts +2 -0
- package/dist/track-presentation.test.d.ts +1 -0
- package/package.json +1 -1
|
@@ -81,6 +81,8 @@ export interface ContextItem {
|
|
|
81
81
|
prev_hash: string | null;
|
|
82
82
|
/** Typed payload per kind. */
|
|
83
83
|
body: unknown;
|
|
84
|
+
/** Non-rendered counters/locator metadata; excluded from semantic content ids. */
|
|
85
|
+
telemetry?: unknown;
|
|
84
86
|
/** ISO timestamp the item was authored (corpus-ready, §4.1). */
|
|
85
87
|
authored_at: string;
|
|
86
88
|
}
|
|
@@ -91,6 +93,7 @@ export interface ContextItemDraft {
|
|
|
91
93
|
sensitivity: ContextItemSensitivity;
|
|
92
94
|
visible_to: ContextItemProjectionRole[];
|
|
93
95
|
body: unknown;
|
|
96
|
+
telemetry?: unknown;
|
|
94
97
|
task_id?: string;
|
|
95
98
|
track_id?: string;
|
|
96
99
|
refs?: string[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface DirectFileDeleteRequest {
|
|
2
|
+
paths: string[];
|
|
3
|
+
}
|
|
4
|
+
export interface DirectFileDeleteResult {
|
|
5
|
+
deleted: string[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Recognize only a closed, deterministic delete request. Anything ambiguous
|
|
9
|
+
* remains on the ordinary planner/implementor path.
|
|
10
|
+
*
|
|
11
|
+
* Supported examples:
|
|
12
|
+
* Delete only a.txt.
|
|
13
|
+
* Please delete only `a file.txt` and `b.txt`.
|
|
14
|
+
* Delete only a.txt. Do not create, modify, or delete any other file.
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseDirectFileDeleteRequest(text: string): DirectFileDeleteRequest | null;
|
|
17
|
+
/**
|
|
18
|
+
* Delete only the explicitly named regular files. All targets are validated
|
|
19
|
+
* before the first mutation; each unlink is bound to the captured parent and
|
|
20
|
+
* file incarnation and directory-fsynced by the anchored helper.
|
|
21
|
+
*/
|
|
22
|
+
export declare function executeDirectFileDelete(cwd: string, request: DirectFileDeleteRequest): Promise<DirectFileDeleteResult>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { AppSyncClient } from '../appsync';
|
|
2
|
+
import { type AuditBrowserModel } from './audit-browser';
|
|
3
|
+
import type { AuditFlagIndex } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Build the session-scoped flag index from a just-rendered `/audit` browser
|
|
6
|
+
* model. Called at the `/audit <task-id>` dispatch site on a successful
|
|
7
|
+
* render; the entrypoint retains the result via `AUDIT_FLAG_INDEX_RETAINED`
|
|
8
|
+
* (last render wins — the reducer carries the `flagged` set forward).
|
|
9
|
+
* Shape-only: coordinates + wire kind + the precomputed flaggable bit; the
|
|
10
|
+
* decrypted payload never leaves the render.
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildAuditFlagIndex(taskId: string, model: AuditBrowserModel): AuditFlagIndex;
|
|
13
|
+
/**
|
|
14
|
+
* The minimal AppSync surface `/flag` needs — the existing
|
|
15
|
+
* `recordExecutionEvent` Class-A method (D4: the full plumbing below it
|
|
16
|
+
* already exists). Narrowed so tests inject a stub without the full client.
|
|
17
|
+
*/
|
|
18
|
+
export type FlagAppSyncClient = Pick<AppSyncClient, 'recordExecutionEvent'>;
|
|
19
|
+
export interface RunFlagCommandDeps {
|
|
20
|
+
/** The authenticated AppSync client. */
|
|
21
|
+
appsyncClient: FlagAppSyncClient;
|
|
22
|
+
/** The retained last-rendered `/audit` index (null → never rendered). */
|
|
23
|
+
index: AuditFlagIndex | null;
|
|
24
|
+
/** The `/flag <entry-id>` argument. */
|
|
25
|
+
entryId: string;
|
|
26
|
+
/** Optional free-text note (encrypted into the flag payload; never logged). */
|
|
27
|
+
note?: string;
|
|
28
|
+
/** The shell session (locator/emit scoping + session-key lookup). */
|
|
29
|
+
sessionId: string;
|
|
30
|
+
/** Test seam — defaults to `keychainManager.getSessionKey(sessionId)`. */
|
|
31
|
+
getSessionKeyFn?: (sessionId: string) => Promise<string | null>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The outcome of a `/flag` run. Every arm carries a ready-to-render `line`;
|
|
35
|
+
* `runFlagCommand` NEVER throws (mirrors `runAuditBrowser`).
|
|
36
|
+
*/
|
|
37
|
+
export type RunFlagCommandResult = {
|
|
38
|
+
kind: 'no_index';
|
|
39
|
+
line: string;
|
|
40
|
+
} | {
|
|
41
|
+
kind: 'unknown_entry';
|
|
42
|
+
line: string;
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'not_flaggable';
|
|
45
|
+
line: string;
|
|
46
|
+
} | {
|
|
47
|
+
kind: 'missing_seq';
|
|
48
|
+
line: string;
|
|
49
|
+
} | {
|
|
50
|
+
kind: 'already_flagged';
|
|
51
|
+
line: string;
|
|
52
|
+
} | {
|
|
53
|
+
kind: 'no_session_key';
|
|
54
|
+
line: string;
|
|
55
|
+
} | {
|
|
56
|
+
kind: 'flagged';
|
|
57
|
+
entryId: string;
|
|
58
|
+
line: string;
|
|
59
|
+
} | {
|
|
60
|
+
kind: 'server_rejected';
|
|
61
|
+
line: string;
|
|
62
|
+
reason: string;
|
|
63
|
+
} | {
|
|
64
|
+
kind: 'error';
|
|
65
|
+
line: string;
|
|
66
|
+
reason: string;
|
|
67
|
+
};
|
|
68
|
+
/** `/flag` before any `/audit <task-id>` render — nothing to resolve against. */
|
|
69
|
+
export declare const FLAG_NO_INDEX_LINE: string;
|
|
70
|
+
/**
|
|
71
|
+
* Run `/flag <entry-id>`: retained-index resolve → client approve-subset
|
|
72
|
+
* check → locator + dedup-key construction → Class-A `FLAG_BAD_APPROVAL`
|
|
73
|
+
* emit with locator forwarding. Returns a discriminated result the shell
|
|
74
|
+
* renders; the CALLER dispatches `AUDIT_FLAG_RECORDED` on the `flagged` arm
|
|
75
|
+
* (the runner stays store-free, like `runAuditBrowser`).
|
|
76
|
+
*/
|
|
77
|
+
export declare function runFlagCommand(deps: RunFlagCommandDeps): Promise<RunFlagCommandResult>;
|
|
78
|
+
/**
|
|
79
|
+
* Render a `RunFlagCommandResult` as the inline `/flag` shell output line.
|
|
80
|
+
*/
|
|
81
|
+
export declare function renderFlagResultText(result: RunFlagCommandResult): string;
|
|
@@ -461,11 +461,32 @@ export interface ReviewSummaryTerminalModel {
|
|
|
461
461
|
};
|
|
462
462
|
readonly tokenUsage: {
|
|
463
463
|
readonly knownTotal: number | null;
|
|
464
|
+
readonly knownInput: number | null;
|
|
465
|
+
readonly knownOutput: number | null;
|
|
466
|
+
readonly knownCachedInput: number | null;
|
|
464
467
|
readonly availability: string;
|
|
465
468
|
readonly unavailableRoles: ReadonlyArray<string>;
|
|
469
|
+
readonly invocations: ReadonlyArray<ReviewSummaryTokenInvocationModel>;
|
|
466
470
|
};
|
|
467
471
|
readonly residualRisks: ReadonlyArray<string>;
|
|
468
472
|
}
|
|
473
|
+
export interface ReviewSummaryTokenInvocationModel {
|
|
474
|
+
readonly role: string;
|
|
475
|
+
readonly agent: string;
|
|
476
|
+
readonly taskId: string | null;
|
|
477
|
+
readonly trackIndex: number | null;
|
|
478
|
+
readonly round: number | null;
|
|
479
|
+
readonly gateId: string | null;
|
|
480
|
+
readonly seatId: number | null;
|
|
481
|
+
readonly reviewerRole: string | null;
|
|
482
|
+
readonly inputTokens: number | null;
|
|
483
|
+
readonly outputTokens: number | null;
|
|
484
|
+
readonly cachedInputTokens: number | null;
|
|
485
|
+
readonly totalTokens: number | null;
|
|
486
|
+
readonly elapsedMs: number | null;
|
|
487
|
+
readonly availability: string;
|
|
488
|
+
readonly unavailableReason: string | null;
|
|
489
|
+
}
|
|
469
490
|
/**
|
|
470
491
|
* The fully-extracted, render-ready per-round review summary model. PURE
|
|
471
492
|
* function of the decrypted summary. `null`-attached (entry has no
|
|
@@ -518,8 +539,28 @@ export interface DecryptedReviewSummaryInput {
|
|
|
518
539
|
};
|
|
519
540
|
readonly tokenUsage?: {
|
|
520
541
|
readonly knownTotal?: number;
|
|
542
|
+
readonly knownInput?: number;
|
|
543
|
+
readonly knownOutput?: number;
|
|
544
|
+
readonly knownCachedInput?: number;
|
|
521
545
|
readonly availability?: string;
|
|
522
546
|
readonly unavailableRoles?: ReadonlyArray<string>;
|
|
547
|
+
readonly invocations?: ReadonlyArray<{
|
|
548
|
+
readonly role?: string;
|
|
549
|
+
readonly agent?: string;
|
|
550
|
+
readonly taskId?: string;
|
|
551
|
+
readonly trackIndex?: number;
|
|
552
|
+
readonly round?: number;
|
|
553
|
+
readonly gateId?: string;
|
|
554
|
+
readonly seatId?: number;
|
|
555
|
+
readonly reviewerRole?: string;
|
|
556
|
+
readonly inputTokens?: number;
|
|
557
|
+
readonly outputTokens?: number;
|
|
558
|
+
readonly cachedInputTokens?: number;
|
|
559
|
+
readonly totalTokens?: number;
|
|
560
|
+
readonly elapsedMs?: number;
|
|
561
|
+
readonly availability?: string;
|
|
562
|
+
readonly unavailableReason?: string;
|
|
563
|
+
}>;
|
|
523
564
|
};
|
|
524
565
|
readonly residualRisks?: ReadonlyArray<string>;
|
|
525
566
|
readonly rounds?: ReadonlyArray<{
|
|
@@ -4,13 +4,14 @@ import { Session } from '../types';
|
|
|
4
4
|
import { OrchestrationStore } from './store';
|
|
5
5
|
import { AdvisoryAttachmentJournal } from './advisory-attachment-journal';
|
|
6
6
|
import type { ImageAttachment } from './types';
|
|
7
|
-
import { type GroupDecisionSubmitDeps } from './gate-decision-submit';
|
|
7
|
+
import { type GateDecisionSubmitDeps, type GroupDecisionSubmitDeps } from './gate-decision-submit';
|
|
8
8
|
import { type ContinuationCliResult, type ContinuationCliDeps } from './slash-routes/continuation';
|
|
9
9
|
import { loadReviewerWizardData } from './slash-routes/reviewers';
|
|
10
10
|
import { createShellEventEmitter } from './emit-shell-event';
|
|
11
11
|
import { type AgentMentionIntent, type CommandIntentTarget } from './command-intent';
|
|
12
12
|
import { type BrainstormPanelActiveAgent } from './brainstorm-quorum';
|
|
13
13
|
import { type RunAuditBrowserResult } from './audit-runner';
|
|
14
|
+
import { type RunFlagCommandResult } from './flag-command';
|
|
14
15
|
import { Tier } from './types';
|
|
15
16
|
import type { ConversationEntry, PendingClarification } from './types';
|
|
16
17
|
import { type GatePromptEnvelope, type DecryptedReviewSummaryInput } from './gate-prompts';
|
|
@@ -23,6 +24,7 @@ import type { LocalGemmaAdvisoryRunner } from '../planner/local-advisory';
|
|
|
23
24
|
import type { LocalExecutor } from '../local-executor';
|
|
24
25
|
import type { WorkItemInput, DisjointnessRejection, RevertManifestStore } from '../local-executor';
|
|
25
26
|
import type { QuorumLoop } from './quorum-loop';
|
|
27
|
+
import { type InvocationUsageSnapshot } from '../reviewer/token-usage';
|
|
26
28
|
import { ensureFreshContextStore } from './context-store';
|
|
27
29
|
import type { EnsureFreshResult } from './context-store';
|
|
28
30
|
import { contextItemOccurrence, type ContextDurabilityReceipt } from './context-items';
|
|
@@ -231,6 +233,7 @@ export { compactSessionContext, maybeFireCompactionSafetyValve, rehydrateSession
|
|
|
231
233
|
export { routeSlashCommand, applySlashOutput, type SlashOutput, type ShellAction, } from './slash-router';
|
|
232
234
|
export { buildAuditBrowserModel, routeAuditEntry, auditKindLabel, auditKindCopy, renderAuditBrowserText, renderAuditEntryText, ENTRY_DETAILS_UNAVAILABLE, NO_AUDIT_ENTRIES, AUDIT_LOG_TOO_LARGE, AUDIT_LOG_TITLE, AUDIT_BROWSER_MAX_HEADLINE, WIRE_PUBLIC_PLAINTEXT_KINDS, type AuditBrowserModel, type AuditEntryModel, type AuditReviewerVerdictModel, type AuditTaskAuthorizedModel, type DecryptContentFn, } from './audit-browser';
|
|
233
235
|
export { runAuditBrowser, renderAuditResultText, AUDIT_BROWSER_UPGRADE_HINT, type RunAuditBrowserResult, type RunAuditBrowserDeps, } from './audit-runner';
|
|
236
|
+
export { buildAuditFlagIndex, runFlagCommand, renderFlagResultText, FLAG_NO_INDEX_LINE, type RunFlagCommandResult, type RunFlagCommandDeps, type FlagAppSyncClient, } from './flag-command';
|
|
234
237
|
export { AuditLogPanel } from './components/AuditLogPanel';
|
|
235
238
|
export { reducer } from './reducer';
|
|
236
239
|
export { createOrchestrationStore, type OrchestrationStore } from './store';
|
|
@@ -385,7 +388,18 @@ export declare function handleSubscribedEvent(event: Event, store: Orchestration
|
|
|
385
388
|
* and DROPS (never crashes the shell, never submits ciphertext). Async — the sync
|
|
386
389
|
* subscription callback fires-and-forgets via `void`; every throw is caught here.
|
|
387
390
|
*/
|
|
388
|
-
export declare function routeMobileUserPrompt(event: Event, sessionKeyResolver: ((sessionId: string) => Promise<string | null>) | undefined, submit: (text: string, images?: string[], options?: ShellSubmitOptions) => Promise<void>, updateEventStatus?: (input: UpdateEventStatusInput) => Promise<unknown>): Promise<
|
|
391
|
+
export declare function routeMobileUserPrompt(event: Event, sessionKeyResolver: ((sessionId: string) => Promise<string | null>) | undefined, submit: (text: string, images?: string[], options?: ShellSubmitOptions) => Promise<void>, updateEventStatus?: (input: UpdateEventStatusInput) => Promise<unknown>): Promise<boolean>;
|
|
392
|
+
/**
|
|
393
|
+
* Route a mobile composer reply through the desktop's canonical gate state
|
|
394
|
+
* machine. Mobile always transports the text as an encrypted `USER_PROMPT`;
|
|
395
|
+
* only the desktop that owns the live prompt interprets it as a numbered
|
|
396
|
+
* option, a required note, `/cancel`, or ordinary free text.
|
|
397
|
+
*
|
|
398
|
+
* Returns `true` only when the active gate consumed the input. A non-numeric
|
|
399
|
+
* line against an awaiting-number gate remains an ordinary prompt and returns
|
|
400
|
+
* `false`, matching the desktop TTY behavior.
|
|
401
|
+
*/
|
|
402
|
+
export declare function routeMobileGatePromptInput(deps: GateDecisionSubmitDeps, text: string): Promise<boolean>;
|
|
389
403
|
/**
|
|
390
404
|
* Build the single `(event) => void` callback the AppSync events subscription
|
|
391
405
|
* invokes. Routes each delivered event to exactly ONE handler:
|
|
@@ -790,6 +804,14 @@ export interface HandleShellUserInputDeps extends StructuralSummaryRunDeps {
|
|
|
790
804
|
* rewrite without live fetch / decrypt.
|
|
791
805
|
*/
|
|
792
806
|
runAuditBrowserFn?: (taskId: string) => Promise<RunAuditBrowserResult>;
|
|
807
|
+
/**
|
|
808
|
+
* O1 C1 (#652) — Test seam for the async `/flag <entry-id>` dispatch.
|
|
809
|
+
* Defaults to `runFlagCommand` over `args.appsyncClient` + the retained
|
|
810
|
+
* `store` flag index + `args.session.sessionId`. Tests inject a stub to
|
|
811
|
+
* drive the PENDING-marker rewrite (+ the `AUDIT_FLAG_RECORDED` dispatch
|
|
812
|
+
* on the `flagged` arm) without live emit / keychain I/O.
|
|
813
|
+
*/
|
|
814
|
+
runFlagCommandFn?: (entryId: string, note?: string) => Promise<RunFlagCommandResult>;
|
|
793
815
|
/**
|
|
794
816
|
* CP-4 §4.2 — Test seam for the pre-classify context-store refresh. Defaults
|
|
795
817
|
* to the real `ensureFreshContextStore` (probe → recompute-if-stale → persist
|
|
@@ -843,10 +865,12 @@ export interface HandleShellUserInputDeps extends StructuralSummaryRunDeps {
|
|
|
843
865
|
* could overlap and interleave the clarification state machine
|
|
844
866
|
* (USER_INPUT bookkeeping + classify + PLANNER_DECISION), corrupting it.
|
|
845
867
|
*
|
|
846
|
-
* Slash commands (`text.startsWith('/')`, matching
|
|
847
|
-
* routing) bypass the queue: they're fast, never
|
|
848
|
-
* never touch clarification state, and include
|
|
849
|
-
* responsive instead of waiting behind a slow/hung
|
|
868
|
+
* Slash commands (`text.trimStart().startsWith('/')`, matching
|
|
869
|
+
* `handleShellUserInput`'s own routing) bypass the queue: they're fast, never
|
|
870
|
+
* trigger a planner classify, never touch clarification state, and include
|
|
871
|
+
* `/quit` — so they must stay responsive instead of waiting behind a slow/hung
|
|
872
|
+
* planner turn. Leading paste whitespace is presentation noise, not permission
|
|
873
|
+
* to reinterpret an explicit command as natural language.
|
|
850
874
|
*
|
|
851
875
|
* The returned function preserves the caller-visible contract: it returns the
|
|
852
876
|
* promise for THIS submission's processing (so an awaiting caller still gets the
|
|
@@ -936,6 +960,7 @@ export interface BrainstormTurnOwnership {
|
|
|
936
960
|
authorAgent: BrainstormPanelActiveAgent;
|
|
937
961
|
status: 'completed' | 'quota_walled' | 'failed';
|
|
938
962
|
boundedBody: string;
|
|
963
|
+
usage: InvocationUsageSnapshot;
|
|
939
964
|
}>;
|
|
940
965
|
prompt: {
|
|
941
966
|
kind: 'legacy_joined';
|
|
@@ -369,8 +369,8 @@ export interface QuorumLoopDeps {
|
|
|
369
369
|
*/
|
|
370
370
|
detectedAgents?: string[];
|
|
371
371
|
/**
|
|
372
|
-
* #585 auto-continuation (Max) — the resolved subscription tier
|
|
373
|
-
*
|
|
372
|
+
* #585 auto-continuation (Max) — the resolved authenticated subscription tier
|
|
373
|
+
* threaded from CLI startup/resume.
|
|
374
374
|
* MAX → a quota-exhausted continuation handoff AUTO-ACCEPTS on the strongest
|
|
375
375
|
* available agent (no prompt). Pro/Free/unresolved/absent → the existing
|
|
376
376
|
* `continuation_offer_handoff` prompt (fail-closed). Auto-continuation only
|
|
@@ -963,6 +963,14 @@ export declare class QuorumLoop {
|
|
|
963
963
|
* This also makes concurrent B.1+B.2 safe (no per-op toggle race).
|
|
964
964
|
*/
|
|
965
965
|
private recoverySeedingDepth;
|
|
966
|
+
/**
|
|
967
|
+
* Recovery B.1 and B.2 can overlap. A per-call two-row batch is therefore
|
|
968
|
+
* insufficient: two concurrent calls could each launch two implementors.
|
|
969
|
+
* These permits are owned by the QuorumLoop/session and cover the complete
|
|
970
|
+
* `launchRecoveredTrack` operation across every recovery entry path.
|
|
971
|
+
*/
|
|
972
|
+
private activeRecoveryRelaunches;
|
|
973
|
+
private readonly recoveryRelaunchWaiters;
|
|
966
974
|
/**
|
|
967
975
|
* Every asynchronously delivered session coroutine that can reach a task
|
|
968
976
|
* workspace: Class-B consumption, shadow recovery, and B.1/B.2 team
|
|
@@ -978,6 +986,10 @@ export declare class QuorumLoop {
|
|
|
978
986
|
private startSessionWork;
|
|
979
987
|
private admittedSessionWorkMayContinue;
|
|
980
988
|
private trackTeamRecovery;
|
|
989
|
+
private acquireRecoveryRelaunchPermit;
|
|
990
|
+
private releaseRecoveryRelaunchPermit;
|
|
991
|
+
private cancelRecoveryRelaunchWaiters;
|
|
992
|
+
private withRecoveryRelaunchPermit;
|
|
981
993
|
/**
|
|
982
994
|
* §4.3 — TEAM Class B packets buffered while the recovery seed barrier is up
|
|
983
995
|
* (`recoverySeedingDepth > 0`). Drained through the normal live handlers AFTER
|
|
@@ -1083,8 +1095,11 @@ export declare class QuorumLoop {
|
|
|
1083
1095
|
* never call each other), so it cannot self-deadlock.
|
|
1084
1096
|
*/
|
|
1085
1097
|
private readonly shadowOpsByTask;
|
|
1098
|
+
/** Abort only the read-only waits owned by non-draining startup recovery. */
|
|
1099
|
+
private readonly backgroundRecoveryAbortControllers;
|
|
1086
1100
|
/** Once set, no new implementor workspace may be created for this session. */
|
|
1087
1101
|
private shuttingDown;
|
|
1102
|
+
private awaitBackgroundRecoveryStep;
|
|
1088
1103
|
/**
|
|
1089
1104
|
* Serialize one shadow lifecycle op for `taskId` behind any in-flight op for
|
|
1090
1105
|
* the same task. The op's result/rejection is returned to ITS caller; a
|
|
@@ -1447,7 +1462,7 @@ export declare class QuorumLoop {
|
|
|
1447
1462
|
* Gemini/Antigravity are out of scope (undefined). NEVER throws — a read/parse
|
|
1448
1463
|
* failure yields `undefined` (segment simply omitted), never breaks the round.
|
|
1449
1464
|
*/
|
|
1450
|
-
private
|
|
1465
|
+
private extractImplementorUsage;
|
|
1451
1466
|
/**
|
|
1452
1467
|
* PHASE-589/469 W1+W2 (LOCK #589-E/F/H) — on a TEAM track local hard-fail (any
|
|
1453
1468
|
* of the 4 closed reasons: `verification_failure` / `out_of_scope_write` /
|
|
@@ -1529,6 +1544,35 @@ export declare class QuorumLoop {
|
|
|
1529
1544
|
* `TaskGroupHalted` convergence is the authoritative group resolution).
|
|
1530
1545
|
*/
|
|
1531
1546
|
reportTeamTrackUserResolved(taskId: string, postAction: PostDecisionAction): void;
|
|
1547
|
+
/**
|
|
1548
|
+
* H3 / Option B (#657) — emit the POSITIVE cancel-confirmation milestone on the
|
|
1549
|
+
* final-approval CANCEL path. Final-approval "Do not apply. Leave the task in its
|
|
1550
|
+
* current state" RETAINS the shadow and mutates nothing, so it triggers NEITHER
|
|
1551
|
+
* the promote (`promoted`) NOR the discard (`discarded`) milestone — the decision
|
|
1552
|
+
* was previously SILENT in non-TTY (a canceling user got no confirmation, and the
|
|
1553
|
+
* E2E harness had no positive signal to assert, so an unwired/hung Cancel was
|
|
1554
|
+
* indistinguishable from a correct one). This emits `not_applied` ("Not applied —
|
|
1555
|
+
* your tree is unchanged") so the user AND the harness get a positive terminal
|
|
1556
|
+
* that the Cancel actually resolved.
|
|
1557
|
+
*
|
|
1558
|
+
* SELF-GUARDING single source of truth: fires ONLY for a `final_approval_resolved`
|
|
1559
|
+
* postAction whose `decision` is NOT `approve` (Approve promotes via the
|
|
1560
|
+
* TaskAuthorized edge → `promoted`; Abort/Reject-restart discard → `discarded`; an
|
|
1561
|
+
* `open_new_round`/`continuation_switch_*` postAction keeps working, no terminal).
|
|
1562
|
+
* Reuses the SAME `approve`-vs-else discriminator the engine's
|
|
1563
|
+
* `handle_final_approval` + `postActionTeamTrackState` use
|
|
1564
|
+
* (`decision.trim().toLowerCase()`), so it can never diverge from the
|
|
1565
|
+
* Passed/Failed track classification.
|
|
1566
|
+
*
|
|
1567
|
+
* Fires for BOTH single-impl and team tracks (unlike the team-only
|
|
1568
|
+
* `reportTeamTrackUserResolved`) — every Cancel deserves the confirmation. Called
|
|
1569
|
+
* by the shell's `onTerminalDecision` (the shared TTY + non-TTY gate-resolution
|
|
1570
|
+
* chokepoint) after a successful `applyUserDecision`. `emitProgress` already wraps
|
|
1571
|
+
* the listener so a throwing consumer can NEVER break the decision path. NO
|
|
1572
|
+
* wire/schema change (progress is desktop-LOCAL) — `not_applied` carries ONLY the
|
|
1573
|
+
* taskId (SECURITY INVARIANT: no user content, mirrors `discarded`).
|
|
1574
|
+
*/
|
|
1575
|
+
reportFinalApprovalCancelled(taskId: string, postAction: PostDecisionAction): void;
|
|
1532
1576
|
/**
|
|
1533
1577
|
* Authoritative TaskGroupHalted bridge from LocalExecutor. Calling this async
|
|
1534
1578
|
* method publishes the terminal group fence synchronously (before its first
|
|
@@ -1777,6 +1821,20 @@ export declare class QuorumLoop {
|
|
|
1777
1821
|
* RUNS (it always runs; the badge only informs the user).
|
|
1778
1822
|
*/
|
|
1779
1823
|
private surfaceReviewerReducedTrust;
|
|
1824
|
+
/**
|
|
1825
|
+
* Local-only shape summary of the review a failing seat was working on.
|
|
1826
|
+
*
|
|
1827
|
+
* 2026-08-22 (dogfood): a reviewer wall-clock expiry told us WHEN it gave up
|
|
1828
|
+
* and nothing about WHAT it faced, so a single load-induced timeout on a
|
|
1829
|
+
* one-file diff looked indistinguishable from a systemic defect. These counts
|
|
1830
|
+
* separate the three candidate causes (big diff / big workspace / saturated
|
|
1831
|
+
* host) on the next occurrence.
|
|
1832
|
+
*
|
|
1833
|
+
* Counts and labels ONLY — never diff content, paths, or agent output. This
|
|
1834
|
+
* feeds a `logger.warn` that stays on the desktop; nothing here reaches the
|
|
1835
|
+
* wire. Fail-soft: diagnostics must never throw inside an error handler.
|
|
1836
|
+
*/
|
|
1837
|
+
private describeReviewShapeForDiagnostics;
|
|
1780
1838
|
/**
|
|
1781
1839
|
* Wave B §2.1 confinement TRI-STATE for a merge-gate model/reviewer invocation
|
|
1782
1840
|
* (LOCK #C14-MOAT). Path A: the CP-7 substrate/broker (not opted out + a Trusted
|
|
@@ -1944,7 +2002,9 @@ export declare class QuorumLoop {
|
|
|
1944
2002
|
* while `pending` and un-expired), so the approved code is never lost; a
|
|
1945
2003
|
* re-delivered packet (or the next live edge) promotes it.
|
|
1946
2004
|
*/
|
|
1947
|
-
recoverShadows(
|
|
2005
|
+
recoverShadows(opts?: {
|
|
2006
|
+
drainOnShutdown?: boolean;
|
|
2007
|
+
}): Promise<void>;
|
|
1948
2008
|
private recoverShadowsOwned;
|
|
1949
2009
|
/**
|
|
1950
2010
|
* Session-exit ownership boundary. Stop future creates, wait behind every
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
* (controlled operational notice text; see the header + the entry's carve-out).
|
|
6
6
|
*/
|
|
7
7
|
export type TaskProgressEvent = ({
|
|
8
|
+
phase: 'preparing_workspace';
|
|
9
|
+
round: number;
|
|
10
|
+
} | {
|
|
8
11
|
phase: 'shadow_created';
|
|
9
12
|
round: number;
|
|
10
13
|
} | {
|
|
@@ -66,6 +69,9 @@ export type TaskProgressEvent = ({
|
|
|
66
69
|
} | {
|
|
67
70
|
phase: 'discarded';
|
|
68
71
|
taskId?: string;
|
|
72
|
+
} | {
|
|
73
|
+
phase: 'not_applied';
|
|
74
|
+
taskId?: string;
|
|
69
75
|
} | {
|
|
70
76
|
phase: 'waiting_user';
|
|
71
77
|
} | {
|
|
@@ -379,6 +379,7 @@ export type ConversationEntry = {
|
|
|
379
379
|
serverDecision: string | null;
|
|
380
380
|
};
|
|
381
381
|
reviewSummary?: ReviewSummaryPanelModel;
|
|
382
|
+
queuedReviewSummaries?: Readonly<Record<string, ReviewSummaryPanelModel>>;
|
|
382
383
|
} | {
|
|
383
384
|
kind: 'gate-panel';
|
|
384
385
|
id: string;
|
|
@@ -667,6 +668,57 @@ export interface OrchestrationState {
|
|
|
667
668
|
* keyboard focus. Non-team / Companion / CP-1.a sessions never open it.
|
|
668
669
|
*/
|
|
669
670
|
reviewerWizard: ReviewerWizardState | null;
|
|
671
|
+
/**
|
|
672
|
+
* `[ADDITIVE WIDENING — O1 C1 (#652)]` per
|
|
673
|
+
* PHASE-O1-C1-SAFETY-OBSERVABILITY-DESIGN.md §3.1 item 1: the shell used to
|
|
674
|
+
* render and DISCARD the `/audit` browser model; `/flag <entry-id>` needs
|
|
675
|
+
* session-scoped retention of the LAST-rendered listing's
|
|
676
|
+
* `entryId → {seqNum, kind, flaggable}` mapping to build the plaintext
|
|
677
|
+
* target locator without re-querying. `null` until the first successful
|
|
678
|
+
* `/audit <task-id>` render. Desktop-local only; row COORDINATES + closed
|
|
679
|
+
* enum labels only — never decrypted payload content.
|
|
680
|
+
*/
|
|
681
|
+
auditFlagIndex: AuditFlagIndex | null;
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* One retained `/audit` listing row, keyed by its audit `entry_id` in
|
|
685
|
+
* {@link AuditFlagIndex.entries}. Shape-only: row coordinates + the plaintext
|
|
686
|
+
* wire kind + the precomputed flag-eligibility bit (derived from the decrypted
|
|
687
|
+
* `gate_resolved` outcome at render time — the decrypted payload itself is
|
|
688
|
+
* NOT retained).
|
|
689
|
+
*/
|
|
690
|
+
export interface AuditFlagEntryRecord {
|
|
691
|
+
/**
|
|
692
|
+
* The flagged row's audit-table sort key — the zero-padded 16-digit
|
|
693
|
+
* `seqNum` string exactly as surfaced by `queryAudit`'s additive
|
|
694
|
+
* `AuditEntryWireRow.seqNum` projection (core-rs `types.rs`), or `null`
|
|
695
|
+
* when the row predates the projection (stale backend) — `/flag` then
|
|
696
|
+
* fails closed with an actionable message.
|
|
697
|
+
*/
|
|
698
|
+
seqNum: string | null;
|
|
699
|
+
/** Plaintext snake_case wire kind (e.g. `gate_resolved`). */
|
|
700
|
+
kind: string;
|
|
701
|
+
/**
|
|
702
|
+
* True iff the entry is a decrypted `gate_resolved` row whose outcome is
|
|
703
|
+
* the quorum's approve consensus (`consensus_approve` / `proceed`) — the
|
|
704
|
+
* client-side defense-in-depth subset check of design §3.1 item 1 (the
|
|
705
|
+
* server independently enforces the same subset, §3.1 item 4).
|
|
706
|
+
*/
|
|
707
|
+
flaggable: boolean;
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* The session-scoped retained `/audit` mapping (design §3.1 item 1). Replaced
|
|
711
|
+
* wholesale on each successful `/audit <task-id>` render (last render wins);
|
|
712
|
+
* `flagged` carries forward across renders so "already flagged" survives
|
|
713
|
+
* re-listing. Lives in {@link OrchestrationState.auditFlagIndex}.
|
|
714
|
+
*/
|
|
715
|
+
export interface AuditFlagIndex {
|
|
716
|
+
/** The task whose listing was rendered — becomes `flaggedTaskId`. */
|
|
717
|
+
taskId: string;
|
|
718
|
+
/** `entryId → record` for every entry in the last-rendered listing. */
|
|
719
|
+
entries: Map<string, AuditFlagEntryRecord>;
|
|
720
|
+
/** Entry ids flagged this session (dedup no-op render on repeat `/flag`). */
|
|
721
|
+
flagged: Set<string>;
|
|
670
722
|
}
|
|
671
723
|
/**
|
|
672
724
|
* Snapshot threaded into the interactive `/reviewer-setup` wizard when it
|
|
@@ -853,6 +905,12 @@ export type OrchestrationAction = {
|
|
|
853
905
|
wizard: ReviewerWizardState;
|
|
854
906
|
} | {
|
|
855
907
|
type: 'REVIEWER_WIZARD_CLOSE';
|
|
908
|
+
} | {
|
|
909
|
+
type: 'AUDIT_FLAG_INDEX_RETAINED';
|
|
910
|
+
index: AuditFlagIndex;
|
|
911
|
+
} | {
|
|
912
|
+
type: 'AUDIT_FLAG_RECORDED';
|
|
913
|
+
entryId: string;
|
|
856
914
|
} | {
|
|
857
915
|
type: 'EXIT';
|
|
858
916
|
};
|
|
@@ -15,6 +15,21 @@ export interface WorkspaceShutdownOperations {
|
|
|
15
15
|
onPlannerFlushFailure?: (error: Error) => void;
|
|
16
16
|
onWorkspaceFailure?: (error: Error) => void;
|
|
17
17
|
}
|
|
18
|
+
export interface StartedWorkspaceShutdown {
|
|
19
|
+
/**
|
|
20
|
+
* Every teardown phase, including best-effort planner flush and hosted
|
|
21
|
+
* retirement. This is the operation governed by the shell's normal/signal
|
|
22
|
+
* responsiveness deadline.
|
|
23
|
+
*/
|
|
24
|
+
completion: Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* The local resource-retirement boundary. A normal process exit must await
|
|
27
|
+
* this even after the broader teardown deadline expires, otherwise a large
|
|
28
|
+
* authenticated snapshot deletion can be killed halfway through and leak its
|
|
29
|
+
* private workspace.
|
|
30
|
+
*/
|
|
31
|
+
resourceRetirement: Promise<void>;
|
|
32
|
+
}
|
|
18
33
|
/**
|
|
19
34
|
* Start every independent shutdown fence before awaiting any one owner.
|
|
20
35
|
*
|
|
@@ -24,4 +39,9 @@ export interface WorkspaceShutdownOperations {
|
|
|
24
39
|
* LocalExecutor drains settle can the durable store be enumerated exactly once
|
|
25
40
|
* without a late publisher recreating a group behind the cleanup pass.
|
|
26
41
|
*/
|
|
42
|
+
export declare function startWorkspaceShutdownOperations(operations: WorkspaceShutdownOperations): StartedWorkspaceShutdown;
|
|
43
|
+
/**
|
|
44
|
+
* Compatibility surface for callers that need the complete shutdown rather
|
|
45
|
+
* than its separately-observable local resource boundary.
|
|
46
|
+
*/
|
|
27
47
|
export declare function runWorkspaceShutdownOperations(operations: WorkspaceShutdownOperations): Promise<void>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-session de-duplication for the CP-7 reduced-trust rationale.
|
|
3
|
+
*
|
|
4
|
+
* WHY (2026-08-22, dogfood): the reduced-trust rationale is ~600 characters and
|
|
5
|
+
* was surfaced in FULL once per agent — implementor, reviewer seat 0, reviewer
|
|
6
|
+
* seat 1 — so a single one-file task printed roughly 1.8 KB of identical
|
|
7
|
+
* boilerplate that buried the actual progress milestones. In the live transcript
|
|
8
|
+
* the banner outweighed every `●` line combined.
|
|
9
|
+
*
|
|
10
|
+
* The rationale is genuinely important the FIRST time: it tells the operator the
|
|
11
|
+
* trusted-execution moat is weakened for this session and why. It carries no new
|
|
12
|
+
* information on the second and third repetition within the same session, where
|
|
13
|
+
* the tier and reason are identical.
|
|
14
|
+
*
|
|
15
|
+
* So: surface the full rationale ONCE per (session, tier, reason), and collapse
|
|
16
|
+
* every later occurrence to a one-line reminder that still names the actor. The
|
|
17
|
+
* WARN log is unaffected — the durable forensic record keeps every occurrence in
|
|
18
|
+
* full; only the user-facing surface is de-duplicated.
|
|
19
|
+
*
|
|
20
|
+
* Keyed on (sessionId, tier, reason) rather than sessionId alone so a session
|
|
21
|
+
* that DEGRADES (e.g. `sandbox_exec` → `none`, or a different reason) surfaces
|
|
22
|
+
* the new rationale in full rather than silently collapsing a more severe
|
|
23
|
+
* posture into a one-liner.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* True the FIRST time this exact (session, tier, reason) rationale is surfaced;
|
|
27
|
+
* false for every later call. Call once per user-facing surfacing decision.
|
|
28
|
+
*/
|
|
29
|
+
export declare function shouldSurfaceFullReducedTrustRationale(sessionId: string, tier: string, reason: string): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Undo a claim (Stage-1 LOW-15). The caller test-and-sets BEFORE surfacing, so
|
|
32
|
+
* a surfacing that then THROWS would otherwise burn the "first" slot: every
|
|
33
|
+
* later actor collapses to "(same posture as above)" pointing at a rationale
|
|
34
|
+
* the operator never saw. Callers that surface fallibly must release on failure.
|
|
35
|
+
*/
|
|
36
|
+
export declare function releaseReducedTrustRationaleClaim(sessionId: string, tier: string, reason: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* The collapsed one-line form for a repeat occurrence. Names the actor so the
|
|
39
|
+
* operator can still see WHICH agent is reduced-trust, and points at the full
|
|
40
|
+
* rationale already in scrollback.
|
|
41
|
+
*/
|
|
42
|
+
export declare function collapsedReducedTrustLine(actor: string): string;
|
|
43
|
+
/** Test-only reset — the Set is module-global and would leak across cases. */
|
|
44
|
+
export declare function __resetReducedTrustNoticesForTest(): void;
|
|
@@ -3,6 +3,7 @@ import { type SubprocessOutcome } from '../subprocess.js';
|
|
|
3
3
|
import type { ReviewerVerdict } from '../types.js';
|
|
4
4
|
import { type VerdictClassifier } from '../verdict-classifier.js';
|
|
5
5
|
import type { BuiltCommand } from './claude.js';
|
|
6
|
+
import { type InvocationUsageSnapshot } from '../token-usage.js';
|
|
6
7
|
/** Construction options. */
|
|
7
8
|
export interface CodexReviewerProviderOptions {
|
|
8
9
|
/** Override the `codex` executable path. Production callers pass nothing
|
|
@@ -58,15 +59,16 @@ export declare function buildCommand(executable: string, spec: ReviewerSpec, las
|
|
|
58
59
|
export declare function buildVerdict(spec: ReviewerSpec, gateId: string, outcome: SubprocessOutcome, lastMessage: string, classifyVerdict?: VerdictClassifier): Promise<ReviewerVerdict>;
|
|
59
60
|
/**
|
|
60
61
|
* Sum `usage.input_tokens + usage.output_tokens` across every
|
|
61
|
-
* `turn.completed` JSONL event in `stdout`. Returns `null` when
|
|
62
|
-
*
|
|
63
|
-
*
|
|
62
|
+
* `turn.completed` JSONL event in `stdout`. Returns `null` when usage is absent,
|
|
63
|
+
* partial, or invalid so legacy call sites do not turn unknown values into a
|
|
64
|
+
* false complete total.
|
|
64
65
|
*
|
|
65
66
|
* Lenient: malformed JSONL lines are silently skipped (Codex's stream is
|
|
66
67
|
* designed to be append-only, so partial flushes during timeout could
|
|
67
68
|
* leave a final truncated line).
|
|
68
69
|
*/
|
|
69
70
|
export declare function sumCodexTokens(stdout: string): number | null;
|
|
71
|
+
export declare function extractCodexUsageSnapshot(stdout: string, elapsedMs?: number | null): InvocationUsageSnapshot;
|
|
70
72
|
/**
|
|
71
73
|
* Generate a unique-per-spawn path for `--output-last-message`. Lives in
|
|
72
74
|
* the OS temp dir; we own its lifecycle (create on codex's side, read +
|