@fro.bot/systematic 3.5.4 → 3.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +892 -150
- package/dist/lib/opencode-operation-observer.d.ts +22 -0
- package/dist/lib/opencode-workflow-guard.d.ts +18 -1
- package/dist/lib/receipt-ledger.d.ts +13 -6
- package/dist/lib/receipt-readback.d.ts +23 -11
- package/dist/lib/workflow-guard.d.ts +2 -1
- package/package.json +3 -3
- package/skills/ce-review/references/subagent-template.md +4 -0
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
export type OperationObserverReasonCode = 'target-unavailable' | 'command-failed' | 'command-timeout' | 'command-output-limit' | 'file-limit' | 'file-output-limit' | 'file-read-failed' | 'remote-command-failed' | 'remote-command-output-limit' | 'remote-invalid-json' | 'remote-missing-field' | 'remote-item-limit' | 'remote-not-advanced' | 'commit-not-closed';
|
|
2
|
+
export interface RegisteredWorktreeParentIdentity {
|
|
3
|
+
readonly targetRoot: string;
|
|
4
|
+
readonly gitDir: string;
|
|
5
|
+
readonly commonDir: string;
|
|
6
|
+
readonly registeredWorktreeRoots: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
export interface RegisteredWorktreeValidationOptions {
|
|
9
|
+
readonly commandRunner?: OperationObserverCommandRunner;
|
|
10
|
+
readonly limits?: OperationObserverLimits;
|
|
11
|
+
readonly realPath?: (filePath: string) => string;
|
|
12
|
+
}
|
|
13
|
+
export type RegisteredWorktreeValidationResult = {
|
|
14
|
+
readonly status: 'ok';
|
|
15
|
+
readonly targetRoot: string;
|
|
16
|
+
readonly gitDir: string;
|
|
17
|
+
readonly commonDir: string;
|
|
18
|
+
} | {
|
|
19
|
+
readonly status: 'error';
|
|
20
|
+
readonly reasonCode: OperationObserverReasonCode;
|
|
21
|
+
};
|
|
2
22
|
export type RemoteOperation = 'push' | 'pr-creation' | 'check-readback' | 'review-readback';
|
|
3
23
|
export type RemoteReadbackPhase = 'before' | 'after';
|
|
4
24
|
export interface OperationObserverSnapshot {
|
|
@@ -73,7 +93,9 @@ export interface OpencodeOperationObserverOptions {
|
|
|
73
93
|
}
|
|
74
94
|
export interface OpencodeOperationObserver {
|
|
75
95
|
readonly targetDigest: string;
|
|
96
|
+
validateRegisteredWorktree(candidateDirectory: string): RegisteredWorktreeValidationResult;
|
|
76
97
|
snapshot(): Promise<OperationObserverResult>;
|
|
77
98
|
remoteSnapshot?(operation: RemoteOperation, phase: RemoteReadbackPhase): Promise<OperationObserverRemoteResult>;
|
|
78
99
|
}
|
|
100
|
+
export declare function validateRegisteredWorktree(candidateDirectory: string, parentIdentity: RegisteredWorktreeParentIdentity, options?: RegisteredWorktreeValidationOptions): RegisteredWorktreeValidationResult;
|
|
79
101
|
export declare function createOpencodeOperationObserver(options: OpencodeOperationObserverOptions): OpencodeOperationObserver;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ToolDefinition } from '@opencode-ai/plugin';
|
|
2
|
-
import type { OpencodeOperationObserver } from './opencode-operation-observer.js';
|
|
2
|
+
import type { OpencodeOperationObserver, RegisteredWorktreeValidationResult } from './opencode-operation-observer.js';
|
|
3
3
|
import type { ReceiptClassifier } from './receipt-classifier.js';
|
|
4
4
|
import { type ReceiptLedger, type ReceiptOperation } from './receipt-ledger.js';
|
|
5
5
|
import { type EvidenceObservationResult, type RuntimeUnitPolicy, type TransitionPrepareResult, type WorkflowReasonCode, type WorkflowStatus } from './workflow-guard.js';
|
|
@@ -26,6 +26,8 @@ export interface OpencodeWorkflowGuardOptions {
|
|
|
26
26
|
hostReadback?: OpencodeWorkflowHostReadback;
|
|
27
27
|
readonly registrationIdentity?: string;
|
|
28
28
|
readonly sessionSalt?: Uint8Array;
|
|
29
|
+
readonly targetDirectory?: string;
|
|
30
|
+
readonly sessionLocation?: string;
|
|
29
31
|
}
|
|
30
32
|
export interface OpencodeWorkflowChildSession {
|
|
31
33
|
readonly sessionId: string;
|
|
@@ -50,5 +52,20 @@ export interface OpencodeWorkflowGuard {
|
|
|
50
52
|
prepareTransition(sessionID: unknown, input: unknown): TransitionPrepareResult;
|
|
51
53
|
startUnit(sessionID: unknown, input: unknown, policy?: RuntimeUnitPolicy): unknown;
|
|
52
54
|
}
|
|
55
|
+
export type LocalOperationTool = 'write' | 'edit' | 'apply_patch' | 'bash';
|
|
56
|
+
export interface OpencodeOperationTargetDerivationOptions {
|
|
57
|
+
readonly parentTargetRoot: string;
|
|
58
|
+
readonly sessionLocation?: string;
|
|
59
|
+
readonly validateRegisteredWorktree: (candidateDirectory: string) => RegisteredWorktreeValidationResult;
|
|
60
|
+
readonly realPath?: (filePath: string) => string;
|
|
61
|
+
}
|
|
62
|
+
export type OpencodeOperationTargetDerivationResult = {
|
|
63
|
+
readonly status: 'available';
|
|
64
|
+
readonly targetRoot: string;
|
|
65
|
+
} | {
|
|
66
|
+
readonly status: 'unavailable';
|
|
67
|
+
readonly reasonCode: 'target-unavailable';
|
|
68
|
+
};
|
|
69
|
+
export declare function deriveOpencodeOperationTarget(tool: LocalOperationTool, args: unknown, options: OpencodeOperationTargetDerivationOptions): OpencodeOperationTargetDerivationResult;
|
|
53
70
|
export declare function createOpencodeWorkflowGuard(options: OpencodeWorkflowGuardOptions): OpencodeWorkflowGuard;
|
|
54
71
|
export {};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ReceiptDigestDomain, ReceiptReadbackFailureCategory, ReceiptReadbackProgression } from './receipt-readback.js';
|
|
2
|
-
export declare const RECEIPT_SCHEMA_VERSION:
|
|
3
|
-
export declare const RECEIPT_PROTOCOL_VERSION:
|
|
2
|
+
export declare const RECEIPT_SCHEMA_VERSION: 2;
|
|
3
|
+
export declare const RECEIPT_PROTOCOL_VERSION: 2;
|
|
4
|
+
declare const LEGACY_RECEIPT_SCHEMA_VERSION: 1;
|
|
5
|
+
declare const LEGACY_RECEIPT_PROTOCOL_VERSION: 1;
|
|
4
6
|
export type ReceiptOperation = 'implementation' | 'verification' | 'commit' | 'push' | 'pr-creation' | 'check-readback' | 'review-readback';
|
|
5
7
|
export type ReceiptClassificationOutcome = 'accepted' | 'rejected' | 'unavailable';
|
|
6
8
|
export type ReceiptAttribution = 'runtime-verified' | 'unattributed';
|
|
@@ -24,12 +26,14 @@ export interface ReceiptContext {
|
|
|
24
26
|
workspaceIdentity: string;
|
|
25
27
|
repositoryIdentity?: string;
|
|
26
28
|
worktreeIdentity?: string;
|
|
29
|
+
operationTargetIdentity?: string;
|
|
27
30
|
resourceIdentity?: string;
|
|
28
31
|
}
|
|
29
32
|
export interface ReceiptObservationAfter {
|
|
30
33
|
workspaceIdentity: string;
|
|
31
34
|
repositoryIdentity?: string;
|
|
32
35
|
worktreeIdentity?: string;
|
|
36
|
+
operationTargetIdentity?: string;
|
|
33
37
|
resourceIdentity?: string;
|
|
34
38
|
}
|
|
35
39
|
export interface TerminalObservation {
|
|
@@ -57,6 +61,7 @@ export interface CanonicalReceiptFields {
|
|
|
57
61
|
workspaceDigest: string;
|
|
58
62
|
repositoryDigest?: string;
|
|
59
63
|
worktreeDigest?: string;
|
|
64
|
+
operationTargetIdentity?: string;
|
|
60
65
|
resourceDigest?: string;
|
|
61
66
|
operation: ReceiptOperation;
|
|
62
67
|
result: 'success';
|
|
@@ -65,8 +70,8 @@ export interface CanonicalReceiptFields {
|
|
|
65
70
|
timestamp: number;
|
|
66
71
|
}
|
|
67
72
|
export interface ReceiptEnvelope {
|
|
68
|
-
schemaVersion: typeof RECEIPT_SCHEMA_VERSION;
|
|
69
|
-
protocolVersion: typeof RECEIPT_PROTOCOL_VERSION;
|
|
73
|
+
schemaVersion: typeof RECEIPT_SCHEMA_VERSION | typeof LEGACY_RECEIPT_SCHEMA_VERSION;
|
|
74
|
+
protocolVersion: typeof RECEIPT_PROTOCOL_VERSION | typeof LEGACY_RECEIPT_PROTOCOL_VERSION;
|
|
70
75
|
registrationDigest: string;
|
|
71
76
|
capabilityFlags: readonly string[];
|
|
72
77
|
compatibility: 'compatible';
|
|
@@ -128,12 +133,14 @@ export interface ReceiptLedger {
|
|
|
128
133
|
finalizeObservation(input: unknown): FinalizeObservationResult;
|
|
129
134
|
abandonObservation(input: unknown): AbandonObservationResult;
|
|
130
135
|
consumeReceipt(receiptId: unknown, context: unknown): ConsumeReceiptResult;
|
|
131
|
-
recoverReceipt(input: unknown): RecoverReceiptResult;
|
|
132
|
-
recoverReadback(input: readonly unknown[]): RecoverReadbackResult;
|
|
136
|
+
recoverReceipt(input: unknown, operationTargetIdentity?: string): RecoverReceiptResult;
|
|
137
|
+
recoverReadback(input: readonly unknown[], operationTargetIdentity?: string): RecoverReadbackResult;
|
|
133
138
|
getProgressionState(): ReceiptReadbackProgression;
|
|
134
139
|
validateEnvelope(input: unknown): EnvelopeValidationResult;
|
|
135
140
|
getEnvelope(receiptId: unknown): ReceiptEnvelope | undefined;
|
|
136
141
|
listReceipts(): readonly ReceiptEnvelope[];
|
|
137
142
|
getSessionSalt(): Uint8Array;
|
|
138
143
|
}
|
|
144
|
+
export declare function isLocalOperation(operation: ReceiptOperation): operation is 'implementation' | 'verification' | 'commit';
|
|
139
145
|
export declare function createReceiptLedger(options?: ReceiptLedgerOptions): ReceiptLedger;
|
|
146
|
+
export {};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ReceiptEnvelope, ReceiptLedgerMetadata, ReceiptOperation } from './receipt-ledger.js';
|
|
2
|
-
export declare const RECEIPT_READBACK_SCHEMA_VERSION:
|
|
3
|
-
export declare const RECEIPT_READBACK_PROTOCOL_VERSION:
|
|
2
|
+
export declare const RECEIPT_READBACK_SCHEMA_VERSION: 2;
|
|
3
|
+
export declare const RECEIPT_READBACK_PROTOCOL_VERSION: 2;
|
|
4
|
+
declare const LEGACY_RECEIPT_READBACK_SCHEMA_VERSION: 1;
|
|
5
|
+
type ReceiptReadbackVersion = typeof RECEIPT_READBACK_SCHEMA_VERSION | typeof LEGACY_RECEIPT_READBACK_SCHEMA_VERSION;
|
|
4
6
|
export type ReceiptDigestDomain = 'repository' | 'worktree' | 'resource' | 'workspace' | 'epoch' | 'unit' | 'call' | 'registration';
|
|
5
7
|
export type ReceiptProgressionStateName = 'started' | 'completed';
|
|
6
8
|
export type ReceiptEpochFamily = 'work' | 'shipping';
|
|
@@ -11,16 +13,16 @@ export interface ReceiptResourceScope {
|
|
|
11
13
|
export type ReceiptReadbackFailureCategory = 'malformed' | 'forbidden-field' | 'unknown-kind' | 'unknown-schema' | 'unknown-protocol' | 'unknown-capability' | 'integrity-mismatch' | 'missing-mint' | 'control-before-mint' | 'conflicting-marker' | 'out-of-order' | 'cross-registration' | 'capability-mismatch' | 'salt-mismatch' | 'receipt-mismatch' | 'progression-mismatch' | 'inconsistent-evidence' | 'missing-internal-id' | 'identity-digest-mismatch' | 'conflicting-seed' | 'missing-seed';
|
|
12
14
|
export interface ReceiptMintMarker {
|
|
13
15
|
readonly kind: 'mint';
|
|
14
|
-
readonly schemaVersion:
|
|
15
|
-
readonly protocolVersion:
|
|
16
|
+
readonly schemaVersion: ReceiptReadbackVersion;
|
|
17
|
+
readonly protocolVersion: ReceiptReadbackVersion;
|
|
16
18
|
readonly envelope: ReceiptEnvelope;
|
|
17
19
|
readonly sessionSalt: string;
|
|
18
20
|
readonly integrity: string;
|
|
19
21
|
}
|
|
20
22
|
export interface ReceiptConsumeMarker {
|
|
21
23
|
readonly kind: 'control';
|
|
22
|
-
readonly schemaVersion:
|
|
23
|
-
readonly protocolVersion:
|
|
24
|
+
readonly schemaVersion: ReceiptReadbackVersion;
|
|
25
|
+
readonly protocolVersion: ReceiptReadbackVersion;
|
|
24
26
|
readonly registrationDigest: string;
|
|
25
27
|
readonly capabilityFlags: readonly string[];
|
|
26
28
|
readonly control: 'consume';
|
|
@@ -31,8 +33,8 @@ export interface ReceiptConsumeMarker {
|
|
|
31
33
|
}
|
|
32
34
|
export interface ReceiptEpochProgressionMarker {
|
|
33
35
|
readonly kind: 'control';
|
|
34
|
-
readonly schemaVersion:
|
|
35
|
-
readonly protocolVersion:
|
|
36
|
+
readonly schemaVersion: ReceiptReadbackVersion;
|
|
37
|
+
readonly protocolVersion: ReceiptReadbackVersion;
|
|
36
38
|
readonly registrationDigest: string;
|
|
37
39
|
readonly capabilityFlags: readonly string[];
|
|
38
40
|
readonly control: 'progression';
|
|
@@ -48,8 +50,8 @@ export interface ReceiptEpochProgressionMarker {
|
|
|
48
50
|
}
|
|
49
51
|
export interface ReceiptUnitProgressionMarker {
|
|
50
52
|
readonly kind: 'control';
|
|
51
|
-
readonly schemaVersion:
|
|
52
|
-
readonly protocolVersion:
|
|
53
|
+
readonly schemaVersion: ReceiptReadbackVersion;
|
|
54
|
+
readonly protocolVersion: ReceiptReadbackVersion;
|
|
53
55
|
readonly registrationDigest: string;
|
|
54
56
|
readonly capabilityFlags: readonly string[];
|
|
55
57
|
readonly control: 'progression';
|
|
@@ -61,6 +63,7 @@ export interface ReceiptUnitProgressionMarker {
|
|
|
61
63
|
readonly family: ReceiptEpochFamily;
|
|
62
64
|
readonly requiredOperations: readonly ReceiptOperation[];
|
|
63
65
|
readonly resourceScopes: readonly ReceiptResourceScope[];
|
|
66
|
+
readonly pinnedOperationTargetIdentity?: string;
|
|
64
67
|
readonly state: ReceiptProgressionStateName;
|
|
65
68
|
readonly transitionDigest: string;
|
|
66
69
|
readonly timestamp: number;
|
|
@@ -85,6 +88,7 @@ export type ReceiptProgressionMarkerInput = {
|
|
|
85
88
|
readonly family: ReceiptEpochFamily;
|
|
86
89
|
readonly requiredOperations: readonly ReceiptOperation[];
|
|
87
90
|
readonly resourceScopes: readonly ReceiptResourceScope[];
|
|
91
|
+
readonly pinnedOperationTargetIdentity?: string;
|
|
88
92
|
readonly transitionDigest: string;
|
|
89
93
|
readonly timestamp?: number;
|
|
90
94
|
};
|
|
@@ -98,6 +102,12 @@ export interface ReceiptReadbackExpectation {
|
|
|
98
102
|
readonly capabilityFlags: readonly string[];
|
|
99
103
|
readonly sessionSalt: Uint8Array;
|
|
100
104
|
readonly source?: 'runtime-verified';
|
|
105
|
+
/**
|
|
106
|
+
* When present, legacy v1 mint markers are rejected because they cannot
|
|
107
|
+
* authenticate a foreign/worktree target. Absence retains the narrow v1
|
|
108
|
+
* parent-target recovery shim; callers must validate that parent separately.
|
|
109
|
+
*/
|
|
110
|
+
readonly operationTargetIdentity?: string;
|
|
101
111
|
}
|
|
102
112
|
export type ReceiptEpochProgressionSnapshot = {
|
|
103
113
|
readonly target: 'epoch';
|
|
@@ -117,6 +127,7 @@ export type ReceiptUnitProgressionSnapshot = {
|
|
|
117
127
|
readonly family: ReceiptEpochFamily;
|
|
118
128
|
readonly requiredOperations: readonly ReceiptOperation[];
|
|
119
129
|
readonly resourceScopes: readonly ReceiptResourceScope[];
|
|
130
|
+
readonly pinnedOperationTargetIdentity?: string;
|
|
120
131
|
readonly transitionDigest: string;
|
|
121
132
|
};
|
|
122
133
|
export type ReceiptProgressionSnapshot = ReceiptEpochProgressionSnapshot | ReceiptUnitProgressionSnapshot;
|
|
@@ -171,4 +182,5 @@ export declare function projectReceiptMintMarker(receipt: unknown, sessionSalt:
|
|
|
171
182
|
export declare function projectReceiptConsumptionMarker(receipt: unknown, transitionDigest: string, timestamp?: number): ReceiptConsumeMarker | undefined;
|
|
172
183
|
export declare function projectReceiptProgressionMarker(source: ReceiptProgressionProjectionSource, input: ReceiptProgressionMarkerInput): ReceiptProgressionMarker | undefined;
|
|
173
184
|
export declare function foldReceiptReadback(inputs: readonly unknown[], expectation: ReceiptReadbackExpectation): ReceiptReadbackResult;
|
|
174
|
-
export declare function receiptReadbackExpectationFromMetadata(metadata: ReceiptLedgerMetadata, sessionSalt: Uint8Array): ReceiptReadbackExpectation;
|
|
185
|
+
export declare function receiptReadbackExpectationFromMetadata(metadata: ReceiptLedgerMetadata, sessionSalt: Uint8Array, operationTargetIdentity?: string): ReceiptReadbackExpectation;
|
|
186
|
+
export {};
|
|
@@ -6,7 +6,7 @@ export type WorkflowState = 'protected' | 'waiting' | 'rejected' | 'disabled' |
|
|
|
6
6
|
export type RepairKind = 'fresh-readback' | 'rerun-operation' | 'question-attestation';
|
|
7
7
|
export type TransitionTarget = 'unit' | 'epoch';
|
|
8
8
|
export type EpochFamily = 'work' | 'shipping';
|
|
9
|
-
export type WorkflowReasonCode = 'abandoned-transition' | 'call-context-conflict' | 'cancelled-operation' | 'consumed-receipt' | 'disabled' | 'epoch-completed' | 'epoch-mismatch' | 'failed-operation' | 'family-conflict' | 'finalization-failed' | 'foreign-registration' | 'forbidden-field' | 'guard-unavailable' | 'incompatible-receipt' | 'invalid-configuration' | 'invalid-control' | 'invalid-receipt' | 'invalid-transition' | 'missing-evidence' | 'no-supported-repair' | 'no-active-epoch' | 'no-active-unit' | 'no-op-operation' | 'operation-not-required' | 'receipt-mismatch' | 'rejected-operation' | 'resource-mismatch' | 'running-operation' | 'stale-receipt' | 'transition-finalized' | 'transition-terminal' | 'transition-replayed' | 'unattributed-operation' | 'unit-active' | 'unit-completed' | 'unit-incomplete' | 'unit-mismatch' | 'unit-ready' | 'workspace-mismatch' | 'runtime-scope-conflict' | 'invalid-recovery' | 'recovery-conflict' | 'fork-copy-not-lineage';
|
|
9
|
+
export type WorkflowReasonCode = 'abandoned-transition' | 'call-context-conflict' | 'cancelled-operation' | 'consumed-receipt' | 'disabled' | 'epoch-completed' | 'epoch-mismatch' | 'failed-operation' | 'family-conflict' | 'finalization-failed' | 'foreign-registration' | 'forbidden-field' | 'guard-unavailable' | 'incompatible-receipt' | 'invalid-configuration' | 'invalid-control' | 'invalid-receipt' | 'invalid-transition' | 'missing-evidence' | 'no-supported-repair' | 'no-active-epoch' | 'no-active-unit' | 'no-op-operation' | 'operation-not-required' | 'operation-target-mismatch' | 'receipt-mismatch' | 'rejected-operation' | 'resource-mismatch' | 'running-operation' | 'stale-receipt' | 'transition-finalized' | 'transition-terminal' | 'transition-replayed' | 'unattributed-operation' | 'unit-active' | 'unit-completed' | 'unit-incomplete' | 'unit-mismatch' | 'unit-ready' | 'workspace-mismatch' | 'runtime-scope-conflict' | 'invalid-recovery' | 'recovery-conflict' | 'fork-copy-not-lineage';
|
|
10
10
|
export interface WorkflowGuardOptions {
|
|
11
11
|
ledger: ReceiptLedger;
|
|
12
12
|
classifier?: ReceiptClassifier;
|
|
@@ -36,6 +36,7 @@ export interface UnitSnapshot {
|
|
|
36
36
|
requiredOperations: readonly ReceiptOperation[];
|
|
37
37
|
requiredResourceOperations: readonly ReceiptOperation[];
|
|
38
38
|
resourceScopes: readonly ReceiptResourceScope[];
|
|
39
|
+
pinnedOperationTargetIdentity?: string;
|
|
39
40
|
}
|
|
40
41
|
export interface CurrentOperationContext {
|
|
41
42
|
readonly workspaceIdentity: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fro.bot/systematic",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.6",
|
|
4
4
|
"description": "Compound-engineering loops for OpenCode, Pi, and Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://fro.bot/systematic",
|
|
@@ -93,8 +93,8 @@
|
|
|
93
93
|
"devDependencies": {
|
|
94
94
|
"@biomejs/biome": "2.5.6",
|
|
95
95
|
"@earendil-works/pi-coding-agent": "0.80.10",
|
|
96
|
-
"@opencode-ai/plugin": "1.18.
|
|
97
|
-
"@opencode-ai/sdk": "1.18.
|
|
96
|
+
"@opencode-ai/plugin": "1.18.10",
|
|
97
|
+
"@opencode-ai/sdk": "1.18.10",
|
|
98
98
|
"@semantic-release/exec": "7.1.0",
|
|
99
99
|
"@tintinweb/pi-subagents": "0.14.3",
|
|
100
100
|
"@types/bun": "latest",
|
|
@@ -17,6 +17,10 @@ You are a specialist code reviewer.
|
|
|
17
17
|
{diff_scope_rules}
|
|
18
18
|
</scope-rules>
|
|
19
19
|
|
|
20
|
+
<bounded-investigation>
|
|
21
|
+
The supplied diff is the primary source of truth. Use the supplied paths and line numbers, and read each unresolved surrounding range or symbol once. Re-read only when a concrete ambiguity remains or the file changed since the prior read. Stop and return a finding or verdict once the evidence is sufficient. If evidence cannot be obtained within this bounded pass, return an explicit blocker or residual risk instead of broadening the investigation indefinitely.
|
|
22
|
+
</bounded-investigation>
|
|
23
|
+
|
|
20
24
|
<output-contract>
|
|
21
25
|
You produce up to two outputs depending on whether a run ID was provided:
|
|
22
26
|
|