@principles/core 1.274.4 → 1.275.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/runtime-v2/__tests__/pain-ingress-persistence.test.d.ts +2 -0
- package/dist/runtime-v2/__tests__/pain-ingress-persistence.test.d.ts.map +1 -0
- package/dist/runtime-v2/__tests__/pain-ingress-persistence.test.js +276 -0
- package/dist/runtime-v2/__tests__/pain-ingress-persistence.test.js.map +1 -0
- package/dist/runtime-v2/__tests__/pain-ingress-shared-semantics.test.d.ts +2 -0
- package/dist/runtime-v2/__tests__/pain-ingress-shared-semantics.test.d.ts.map +1 -0
- package/dist/runtime-v2/__tests__/pain-ingress-shared-semantics.test.js +131 -0
- package/dist/runtime-v2/__tests__/pain-ingress-shared-semantics.test.js.map +1 -0
- package/dist/runtime-v2/__tests__/pain-outcome-convergence.test.d.ts +2 -0
- package/dist/runtime-v2/__tests__/pain-outcome-convergence.test.d.ts.map +1 -0
- package/dist/runtime-v2/__tests__/pain-outcome-convergence.test.js +126 -0
- package/dist/runtime-v2/__tests__/pain-outcome-convergence.test.js.map +1 -0
- package/dist/runtime-v2/__tests__/pain-signal-bridge-execute-pending.test.js +95 -0
- package/dist/runtime-v2/__tests__/pain-signal-bridge-execute-pending.test.js.map +1 -1
- package/dist/runtime-v2/activation/__tests__/production-gate-deps.test.js +69 -0
- package/dist/runtime-v2/activation/__tests__/production-gate-deps.test.js.map +1 -1
- package/dist/runtime-v2/activation/production-gate-deps.d.ts.map +1 -1
- package/dist/runtime-v2/activation/production-gate-deps.js +13 -46
- package/dist/runtime-v2/activation/production-gate-deps.js.map +1 -1
- package/dist/runtime-v2/index.d.ts +9 -1
- package/dist/runtime-v2/index.d.ts.map +1 -1
- package/dist/runtime-v2/index.js +6 -0
- package/dist/runtime-v2/index.js.map +1 -1
- package/dist/runtime-v2/internalization/__tests__/adversarial-feedback.test.js +9 -0
- package/dist/runtime-v2/internalization/__tests__/adversarial-feedback.test.js.map +1 -1
- package/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder.test.js +15 -5
- package/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder.test.js.map +1 -1
- package/dist/runtime-v2/internalization/__tests__/evaluator-artificer-repair-replay.test.d.ts +2 -0
- package/dist/runtime-v2/internalization/__tests__/evaluator-artificer-repair-replay.test.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/evaluator-artificer-repair-replay.test.js +413 -0
- package/dist/runtime-v2/internalization/__tests__/evaluator-artificer-repair-replay.test.js.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.js +136 -0
- package/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.js.map +1 -1
- package/dist/runtime-v2/internalization/__tests__/repair-replay-resolver.test.d.ts +2 -0
- package/dist/runtime-v2/internalization/__tests__/repair-replay-resolver.test.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/repair-replay-resolver.test.js +340 -0
- package/dist/runtime-v2/internalization/__tests__/repair-replay-resolver.test.js.map +1 -0
- package/dist/runtime-v2/internalization/adversarial-feedback.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/adversarial-feedback.js +7 -1
- package/dist/runtime-v2/internalization/adversarial-feedback.js.map +1 -1
- package/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts +9 -2
- package/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/artificer-prompt-builder.js +19 -1
- package/dist/runtime-v2/internalization/artificer-prompt-builder.js.map +1 -1
- package/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/artificer-runner.js +84 -7
- package/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-output.d.ts +18 -1
- package/dist/runtime-v2/internalization/evaluator-output.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-output.js +12 -2
- package/dist/runtime-v2/internalization/evaluator-output.js.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-runner.js +99 -5
- package/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
- package/dist/runtime-v2/internalization/refiner-sandbox-wrapper.d.ts +18 -1
- package/dist/runtime-v2/internalization/refiner-sandbox-wrapper.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/refiner-sandbox-wrapper.js +20 -0
- package/dist/runtime-v2/internalization/refiner-sandbox-wrapper.js.map +1 -1
- package/dist/runtime-v2/internalization/repair-replay-resolver.d.ts +112 -0
- package/dist/runtime-v2/internalization/repair-replay-resolver.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/repair-replay-resolver.js +332 -0
- package/dist/runtime-v2/internalization/repair-replay-resolver.js.map +1 -0
- package/dist/runtime-v2/pain-ingress-payload.d.ts +207 -0
- package/dist/runtime-v2/pain-ingress-payload.d.ts.map +1 -0
- package/dist/runtime-v2/pain-ingress-payload.js +340 -0
- package/dist/runtime-v2/pain-ingress-payload.js.map +1 -0
- package/dist/runtime-v2/pain-ingress.d.ts +61 -0
- package/dist/runtime-v2/pain-ingress.d.ts.map +1 -0
- package/dist/runtime-v2/pain-ingress.js +163 -0
- package/dist/runtime-v2/pain-ingress.js.map +1 -0
- package/dist/runtime-v2/pain-signal-bridge.d.ts +39 -1
- package/dist/runtime-v2/pain-signal-bridge.d.ts.map +1 -1
- package/dist/runtime-v2/pain-signal-bridge.js +163 -8
- package/dist/runtime-v2/pain-signal-bridge.js.map +1 -1
- package/dist/runtime-v2/pain-to-principle-service.d.ts +8 -1
- package/dist/runtime-v2/pain-to-principle-service.d.ts.map +1 -1
- package/dist/runtime-v2/pain-to-principle-service.js +3 -0
- package/dist/runtime-v2/pain-to-principle-service.js.map +1 -1
- package/dist/telemetry-event.d.ts +2 -2
- package/dist/telemetry-event.d.ts.map +1 -1
- package/dist/telemetry-event.js +14 -0
- package/dist/telemetry-event.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repair Replay Resolver — PRI-634 PR-A (SPEC Slice B, §23–§30).
|
|
3
|
+
*
|
|
4
|
+
* Resolves the deterministic replay evidence a repair round needs, BY
|
|
5
|
+
* REFERENCE, from the one durable authority: the source Evaluator artifact's
|
|
6
|
+
* runtime-owned `adversarialResult`. The resolved RepairReplayContext exists
|
|
7
|
+
* only in prompt context — it is never persisted, never a second fact store,
|
|
8
|
+
* and RepairPayload stays a bounded control payload.
|
|
9
|
+
*
|
|
10
|
+
* Pipeline:
|
|
11
|
+
* RepairPayload.sourceEvaluatorTaskId
|
|
12
|
+
* → evaluator task's durable completionIntent.sourceRunId (deterministic
|
|
13
|
+
* artifact identity: pi-art-<taskId>-<runId>)
|
|
14
|
+
* → PiArtifactStore.getArtifactById (fallback: listBySourceTaskId when
|
|
15
|
+
* the intent is absent — exactly-one rule, otherwise fail loud)
|
|
16
|
+
* → runtime-validate contentJson.adversarialResult (rc-1/rc-4)
|
|
17
|
+
* → normalize legacy actualDecision=<errorType> representation (SPEC §21)
|
|
18
|
+
* → partition trace failures / system failures / global violations
|
|
19
|
+
* → bounded deterministic stratified selection (SPEC §30)
|
|
20
|
+
*
|
|
21
|
+
* Trust boundary: artifact contentJson is durable-but-untrusted at read time.
|
|
22
|
+
* Every field access uses Object.hasOwn (rc-5) and typeof/Array.isArray
|
|
23
|
+
* guards (rc-4) — no `as` casts. Missing or ambiguous evidence fails loud
|
|
24
|
+
* with a structured reason (rc-3/rc-9) so the caller can refuse a blind
|
|
25
|
+
* repair retry (SPEC §27).
|
|
26
|
+
*/
|
|
27
|
+
import type { TaskRecord } from '../task-status.js';
|
|
28
|
+
import type { PIArtifactStore } from './pi-artifact.js';
|
|
29
|
+
/**
|
|
30
|
+
* Repair-prompt budget cap for replay evidence (SPEC §29): at most this many
|
|
31
|
+
* failure entries enter the Artificer repair prompt. 16 entries × ~30 tokens
|
|
32
|
+
* stays comfortably inside the existing prompt budget.
|
|
33
|
+
*/
|
|
34
|
+
export declare const MAX_REPLAY_FAILURES_IN_REPAIR = 16;
|
|
35
|
+
export interface ReplayFailureEvidence {
|
|
36
|
+
readonly caseId: string;
|
|
37
|
+
readonly attackType?: string;
|
|
38
|
+
readonly expectedDecision?: string;
|
|
39
|
+
/** Real decision the rule returned; absent for timeout/throw failures. */
|
|
40
|
+
readonly actualDecision?: string;
|
|
41
|
+
readonly errorType: string;
|
|
42
|
+
readonly message?: string;
|
|
43
|
+
}
|
|
44
|
+
export interface RepairReplayContext {
|
|
45
|
+
readonly sourceEvaluatorTaskId: string;
|
|
46
|
+
readonly sourceEvaluatorArtifactId: string;
|
|
47
|
+
/** True — the presence of a runtime-owned adversarialResult means replay ran. */
|
|
48
|
+
readonly ran: boolean;
|
|
49
|
+
readonly passed: boolean;
|
|
50
|
+
/** Total durable failures (pre-selection). */
|
|
51
|
+
readonly failedCaseCount: number;
|
|
52
|
+
/** Selected trace-case failures (bounded, mismatch-first stratified). */
|
|
53
|
+
readonly traceFailures: readonly ReplayFailureEvidence[];
|
|
54
|
+
/** Selected system-sentinel failures (bounded; excludes forbidden patterns). */
|
|
55
|
+
readonly systemFailures: readonly ReplayFailureEvidence[];
|
|
56
|
+
/** Selected forbidden-pattern violations (bounded, shared budget). */
|
|
57
|
+
readonly globalViolations: readonly string[];
|
|
58
|
+
/** Total durable forbidden-pattern violations (pre-selection). */
|
|
59
|
+
readonly globalViolationCount: number;
|
|
60
|
+
/** True when bounded selection omitted any durable failure or violation. */
|
|
61
|
+
readonly truncated: boolean;
|
|
62
|
+
}
|
|
63
|
+
export type RepairReplayResolutionFailureReason = 'task_missing' | 'artifact_missing' | 'artifact_ambiguous' | 'adversarial_result_missing' | 'adversarial_result_invalid';
|
|
64
|
+
export type RepairReplayResolution = {
|
|
65
|
+
readonly ok: true;
|
|
66
|
+
readonly context: RepairReplayContext;
|
|
67
|
+
} | {
|
|
68
|
+
readonly ok: false;
|
|
69
|
+
readonly reason: RepairReplayResolutionFailureReason;
|
|
70
|
+
readonly detail: string;
|
|
71
|
+
};
|
|
72
|
+
export interface RepairReplayResolverDeps {
|
|
73
|
+
readonly artifactStore: Pick<PIArtifactStore, 'getArtifactById' | 'listBySourceTaskId'>;
|
|
74
|
+
readonly getTask: (taskId: string) => Promise<TaskRecord | null>;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Bounded deterministic stratified selection (SPEC §30 as tightened by review
|
|
78
|
+
* 2026-09-02). Trace failures, system failures, and global violations share
|
|
79
|
+
* ONE capacity budget — no evidence class can bypass the prompt bound:
|
|
80
|
+
*
|
|
81
|
+
* 1. system failure representatives (stable order);
|
|
82
|
+
* 2. one global-violation representative for the whole violation group;
|
|
83
|
+
* 3. true decision mismatches FIRST by expected axis — at least one
|
|
84
|
+
* expected=allow, one expected=block, one expected=propose_correction
|
|
85
|
+
* representative each (when present) — so low-value runtime failures can
|
|
86
|
+
* never evict every behavioral mismatch from the prompt;
|
|
87
|
+
* 4. remaining errorType × expectedDecision group representatives
|
|
88
|
+
* (stable first-occurrence order, mismatch-preferring);
|
|
89
|
+
* 5. stable-order fill over trace → system → remaining violations;
|
|
90
|
+
* 6. truncated=true when anything was omitted.
|
|
91
|
+
*/
|
|
92
|
+
export declare function selectBoundedReplayFailures(params: {
|
|
93
|
+
traceFailures: readonly ReplayFailureEvidence[];
|
|
94
|
+
systemFailures: readonly ReplayFailureEvidence[];
|
|
95
|
+
globalViolations: readonly string[];
|
|
96
|
+
capacity: number;
|
|
97
|
+
}): {
|
|
98
|
+
readonly selectedTrace: readonly ReplayFailureEvidence[];
|
|
99
|
+
readonly selectedSystem: readonly ReplayFailureEvidence[];
|
|
100
|
+
readonly selectedGlobalViolations: readonly string[];
|
|
101
|
+
readonly truncated: boolean;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Resolve the bounded, normalized replay-evidence context for a repair round.
|
|
105
|
+
* Pure read + transform: no writes, no telemetry side effects — callers own
|
|
106
|
+
* observability.
|
|
107
|
+
*/
|
|
108
|
+
export declare function resolveRepairReplayContext(params: {
|
|
109
|
+
readonly sourceEvaluatorTaskId: string;
|
|
110
|
+
readonly deps: RepairReplayResolverDeps;
|
|
111
|
+
}): Promise<RepairReplayResolution>;
|
|
112
|
+
//# sourceMappingURL=repair-replay-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair-replay-resolver.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/repair-replay-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import { hydratePITaskRecord } from './pitask-metadata.js';
|
|
2
|
+
/** Sandbox error enums that legacy artifacts stored inside actualDecision. */
|
|
3
|
+
const LEGACY_SANDBOX_ERROR_TYPES = new Set([
|
|
4
|
+
'forbidden_pattern',
|
|
5
|
+
'syntax_error',
|
|
6
|
+
'runtime_error',
|
|
7
|
+
'timeout',
|
|
8
|
+
'validation_failed',
|
|
9
|
+
'unknown',
|
|
10
|
+
]);
|
|
11
|
+
/** Real decisions a rule can return — never valid errorType values. */
|
|
12
|
+
const RULEHOST_DECISIONS = new Set([
|
|
13
|
+
'allow',
|
|
14
|
+
'block',
|
|
15
|
+
'requireApproval',
|
|
16
|
+
'auto_correct',
|
|
17
|
+
]);
|
|
18
|
+
/** System sentinel prefix/suffix convention (SPEC §17): `__name__`. */
|
|
19
|
+
function isSystemSentinelCaseId(caseId) {
|
|
20
|
+
return caseId.startsWith('__') && caseId.endsWith('__') && caseId.length > 4;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Repair-prompt budget cap for replay evidence (SPEC §29): at most this many
|
|
24
|
+
* failure entries enter the Artificer repair prompt. 16 entries × ~30 tokens
|
|
25
|
+
* stays comfortably inside the existing prompt budget.
|
|
26
|
+
*/
|
|
27
|
+
export const MAX_REPLAY_FAILURES_IN_REPAIR = 16;
|
|
28
|
+
function isRecord(value) {
|
|
29
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
30
|
+
}
|
|
31
|
+
function optionalNonEmptyString(value) {
|
|
32
|
+
return typeof value === 'string' && value.trim() !== '' ? value : undefined;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Normalize one durable failed-case entry (rc-4: element-level validation).
|
|
36
|
+
*
|
|
37
|
+
* Legacy representation (pre PR-A): `actualDecision` carries a sandbox error
|
|
38
|
+
* enum and no `errorType` exists → errorType moves over, actualDecision is
|
|
39
|
+
* dropped (SPEC §21 — readers normalize, no migration).
|
|
40
|
+
*
|
|
41
|
+
* Current representation: `errorType` is authoritative; `actualDecision`
|
|
42
|
+
* appears only when a real decision mismatched and must not be an error enum.
|
|
43
|
+
* Entries that fail structural validation are invalid — the caller fails
|
|
44
|
+
* loud rather than silently dropping evidence (rc-3).
|
|
45
|
+
*/
|
|
46
|
+
/** Repair-prompt budget cap for a single failure message (SPEC §23). */
|
|
47
|
+
const MAX_EVIDENCE_MESSAGE_LENGTH = 300;
|
|
48
|
+
function boundMessage(message) {
|
|
49
|
+
return message.length > MAX_EVIDENCE_MESSAGE_LENGTH
|
|
50
|
+
? `${message.slice(0, MAX_EVIDENCE_MESSAGE_LENGTH)}…`
|
|
51
|
+
: message;
|
|
52
|
+
}
|
|
53
|
+
function normalizeFailedCaseEntry(entry) {
|
|
54
|
+
if (!isRecord(entry))
|
|
55
|
+
return null;
|
|
56
|
+
const caseId = optionalNonEmptyString(entry.caseId);
|
|
57
|
+
if (caseId === undefined)
|
|
58
|
+
return null;
|
|
59
|
+
const rawErrorType = optionalNonEmptyString(entry.errorType);
|
|
60
|
+
const rawActual = optionalNonEmptyString(entry.actualDecision);
|
|
61
|
+
let errorType = rawErrorType;
|
|
62
|
+
let actualDecision = rawActual;
|
|
63
|
+
if (errorType === undefined && rawActual !== undefined) {
|
|
64
|
+
if (LEGACY_SANDBOX_ERROR_TYPES.has(rawActual)) {
|
|
65
|
+
// Legacy drift: actualDecision held the error classification.
|
|
66
|
+
errorType = rawActual;
|
|
67
|
+
actualDecision = undefined;
|
|
68
|
+
}
|
|
69
|
+
else if (RULEHOST_DECISIONS.has(rawActual)) {
|
|
70
|
+
// Legacy decision-mismatch entry: the mismatch was a validation failure.
|
|
71
|
+
errorType = 'validation_failed';
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
errorType = 'unknown';
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (errorType === undefined)
|
|
78
|
+
errorType = 'unknown';
|
|
79
|
+
// Defense-in-depth on current-shape entries: an errorType value inside
|
|
80
|
+
// actualDecision is always reclassification drift, never a real decision.
|
|
81
|
+
if (actualDecision !== undefined && LEGACY_SANDBOX_ERROR_TYPES.has(actualDecision)) {
|
|
82
|
+
actualDecision = undefined;
|
|
83
|
+
}
|
|
84
|
+
const rationale = optionalNonEmptyString(entry.rationale);
|
|
85
|
+
const message = optionalNonEmptyString(entry.message) ?? rationale;
|
|
86
|
+
return {
|
|
87
|
+
caseId,
|
|
88
|
+
attackType: optionalNonEmptyString(entry.attackType),
|
|
89
|
+
expectedDecision: optionalNonEmptyString(entry.expectedDecision),
|
|
90
|
+
...(actualDecision !== undefined ? { actualDecision } : {}),
|
|
91
|
+
errorType,
|
|
92
|
+
...(message !== undefined ? { message: boundMessage(message) } : {}),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Bounded deterministic stratified selection (SPEC §30 as tightened by review
|
|
97
|
+
* 2026-09-02). Trace failures, system failures, and global violations share
|
|
98
|
+
* ONE capacity budget — no evidence class can bypass the prompt bound:
|
|
99
|
+
*
|
|
100
|
+
* 1. system failure representatives (stable order);
|
|
101
|
+
* 2. one global-violation representative for the whole violation group;
|
|
102
|
+
* 3. true decision mismatches FIRST by expected axis — at least one
|
|
103
|
+
* expected=allow, one expected=block, one expected=propose_correction
|
|
104
|
+
* representative each (when present) — so low-value runtime failures can
|
|
105
|
+
* never evict every behavioral mismatch from the prompt;
|
|
106
|
+
* 4. remaining errorType × expectedDecision group representatives
|
|
107
|
+
* (stable first-occurrence order, mismatch-preferring);
|
|
108
|
+
* 5. stable-order fill over trace → system → remaining violations;
|
|
109
|
+
* 6. truncated=true when anything was omitted.
|
|
110
|
+
*/
|
|
111
|
+
export function selectBoundedReplayFailures(params) {
|
|
112
|
+
const capacity = Math.max(0, params.capacity);
|
|
113
|
+
let remaining = capacity;
|
|
114
|
+
const chosenFailures = new Set();
|
|
115
|
+
const chosenViolations = new Set();
|
|
116
|
+
// Selected failures are recorded in SELECTION PRIORITY order so the repair
|
|
117
|
+
// prompt renders behavioral mismatches before raw structural errors.
|
|
118
|
+
const traceIdentity = new Set(params.traceFailures);
|
|
119
|
+
const orderedSelected = [];
|
|
120
|
+
const takeFailure = (failure) => {
|
|
121
|
+
if (remaining <= 0 || chosenFailures.has(failure))
|
|
122
|
+
return;
|
|
123
|
+
chosenFailures.add(failure);
|
|
124
|
+
orderedSelected.push(failure);
|
|
125
|
+
remaining -= 1;
|
|
126
|
+
};
|
|
127
|
+
const takeViolation = (violation) => {
|
|
128
|
+
if (remaining <= 0 || chosenViolations.has(violation))
|
|
129
|
+
return;
|
|
130
|
+
chosenViolations.add(violation);
|
|
131
|
+
remaining -= 1;
|
|
132
|
+
};
|
|
133
|
+
// 1. system representatives first.
|
|
134
|
+
for (const systemFailure of params.systemFailures) {
|
|
135
|
+
if (remaining <= 0)
|
|
136
|
+
break;
|
|
137
|
+
takeFailure(systemFailure);
|
|
138
|
+
}
|
|
139
|
+
// 2. one global-violation representative.
|
|
140
|
+
const [firstViolation] = params.globalViolations;
|
|
141
|
+
if (firstViolation !== undefined)
|
|
142
|
+
takeViolation(firstViolation);
|
|
143
|
+
// 3. decision mismatches by expected axis (canonical decision order).
|
|
144
|
+
const mismatchByExpected = new Map();
|
|
145
|
+
for (const failure of params.traceFailures) {
|
|
146
|
+
if (failure.actualDecision === undefined)
|
|
147
|
+
continue;
|
|
148
|
+
const key = failure.expectedDecision ?? 'unknown';
|
|
149
|
+
if (!mismatchByExpected.has(key))
|
|
150
|
+
mismatchByExpected.set(key, failure);
|
|
151
|
+
}
|
|
152
|
+
for (const expectedKey of ['allow', 'block', 'propose_correction']) {
|
|
153
|
+
if (remaining <= 0)
|
|
154
|
+
break;
|
|
155
|
+
const representative = mismatchByExpected.get(expectedKey);
|
|
156
|
+
if (representative !== undefined)
|
|
157
|
+
takeFailure(representative);
|
|
158
|
+
}
|
|
159
|
+
// 4. remaining group representatives (mismatch-preferring, stable order).
|
|
160
|
+
const groups = new Map();
|
|
161
|
+
for (const failure of params.traceFailures) {
|
|
162
|
+
const key = `${failure.errorType}×${failure.expectedDecision ?? 'unknown'}`;
|
|
163
|
+
const existing = groups.get(key);
|
|
164
|
+
if (existing === undefined || (existing.actualDecision === undefined && failure.actualDecision !== undefined)) {
|
|
165
|
+
groups.set(key, failure);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
for (const representative of groups.values()) {
|
|
169
|
+
if (remaining <= 0)
|
|
170
|
+
break;
|
|
171
|
+
takeFailure(representative);
|
|
172
|
+
}
|
|
173
|
+
// 5. stable-order fill: trace → system → remaining violations.
|
|
174
|
+
for (const failure of [...params.traceFailures, ...params.systemFailures]) {
|
|
175
|
+
if (remaining <= 0)
|
|
176
|
+
break;
|
|
177
|
+
takeFailure(failure);
|
|
178
|
+
}
|
|
179
|
+
for (const violation of params.globalViolations) {
|
|
180
|
+
if (remaining <= 0)
|
|
181
|
+
break;
|
|
182
|
+
takeViolation(violation);
|
|
183
|
+
}
|
|
184
|
+
const total = params.traceFailures.length + params.systemFailures.length + params.globalViolations.length;
|
|
185
|
+
const selectedCount = chosenFailures.size + chosenViolations.size;
|
|
186
|
+
return {
|
|
187
|
+
selectedTrace: orderedSelected.filter((f) => traceIdentity.has(f)),
|
|
188
|
+
selectedSystem: orderedSelected.filter((f) => !traceIdentity.has(f)),
|
|
189
|
+
selectedGlobalViolations: params.globalViolations.filter((v) => chosenViolations.has(v)),
|
|
190
|
+
truncated: selectedCount < total,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Resolve the authoritative Evaluator artifact for a repair round.
|
|
195
|
+
*
|
|
196
|
+
* Selection authority (SPEC §26, tightened by review 2026-09-02): the
|
|
197
|
+
* evaluator task's durable completionIntent records the exact run that
|
|
198
|
+
* produced the verdict, and the artifact ID is deterministically
|
|
199
|
+
* `pi-art-<taskId>-<runId>`. When the intent exists, that artifact IS the
|
|
200
|
+
* authority — if it is missing we FAIL LOUD; another run's artifact may never
|
|
201
|
+
* become a fallback authority. Only when no intent exists (legacy tasks) does
|
|
202
|
+
* the exactly-one list rule apply: zero or many → fail loud, never a
|
|
203
|
+
* positional pick.
|
|
204
|
+
*/
|
|
205
|
+
async function resolveAuthoritativeEvaluatorArtifact(sourceEvaluatorTaskId, deps) {
|
|
206
|
+
const task = await deps.getTask(sourceEvaluatorTaskId);
|
|
207
|
+
if (!task) {
|
|
208
|
+
return { ok: false, reason: 'task_missing', detail: `evaluator task ${sourceEvaluatorTaskId} not found` };
|
|
209
|
+
}
|
|
210
|
+
const piTask = hydratePITaskRecord(task);
|
|
211
|
+
const intentRunId = piTask?.completionIntent?.sourceRunId;
|
|
212
|
+
if (typeof intentRunId === 'string' && intentRunId.trim() !== '') {
|
|
213
|
+
const artifactId = `pi-art-${sourceEvaluatorTaskId}-${intentRunId}`;
|
|
214
|
+
const artifact = await deps.artifactStore.getArtifactById(artifactId);
|
|
215
|
+
if (artifact) {
|
|
216
|
+
return { ok: true, artifactId: artifact.artifactId, contentJson: artifact.contentJson };
|
|
217
|
+
}
|
|
218
|
+
// The durable authority is KNOWN — a different run's artifact must never
|
|
219
|
+
// be silently promoted into its place (P1 review 2026-09-02).
|
|
220
|
+
return {
|
|
221
|
+
ok: false,
|
|
222
|
+
reason: 'artifact_missing',
|
|
223
|
+
detail: `completionIntent names run ${intentRunId} as authoritative but artifact ${artifactId} does not exist — refusing cross-run fallback`,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
const artifacts = (await deps.artifactStore.listBySourceTaskId(sourceEvaluatorTaskId))
|
|
227
|
+
.filter((a) => a.artifactKind === 'principle');
|
|
228
|
+
if (artifacts.length === 0) {
|
|
229
|
+
return {
|
|
230
|
+
ok: false,
|
|
231
|
+
reason: 'artifact_missing',
|
|
232
|
+
detail: `no principle artifact for evaluator task ${sourceEvaluatorTaskId}`,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
if (artifacts.length > 1) {
|
|
236
|
+
return {
|
|
237
|
+
ok: false,
|
|
238
|
+
reason: 'artifact_ambiguous',
|
|
239
|
+
detail: `evaluator task ${sourceEvaluatorTaskId} has ${artifacts.length} principle artifacts and no resolvable completion intent — authority is ambiguous: ${artifacts.map((a) => a.artifactId).sort().join(', ')}`,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
const [only] = artifacts;
|
|
243
|
+
if (!only) {
|
|
244
|
+
return { ok: false, reason: 'artifact_missing', detail: `no principle artifact for evaluator task ${sourceEvaluatorTaskId}` };
|
|
245
|
+
}
|
|
246
|
+
return { ok: true, artifactId: only.artifactId, contentJson: only.contentJson };
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Resolve the bounded, normalized replay-evidence context for a repair round.
|
|
250
|
+
* Pure read + transform: no writes, no telemetry side effects — callers own
|
|
251
|
+
* observability.
|
|
252
|
+
*/
|
|
253
|
+
export async function resolveRepairReplayContext(params) {
|
|
254
|
+
const { sourceEvaluatorTaskId, deps } = params;
|
|
255
|
+
const artifactResolution = await resolveAuthoritativeEvaluatorArtifact(sourceEvaluatorTaskId, deps);
|
|
256
|
+
if (!artifactResolution.ok) {
|
|
257
|
+
return artifactResolution;
|
|
258
|
+
}
|
|
259
|
+
const { artifactId, contentJson } = artifactResolution;
|
|
260
|
+
let parsed;
|
|
261
|
+
try {
|
|
262
|
+
parsed = JSON.parse(contentJson);
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
return { ok: false, reason: 'adversarial_result_invalid', detail: `evaluator artifact ${artifactId} contentJson is unparseable` };
|
|
266
|
+
}
|
|
267
|
+
if (!isRecord(parsed) || !Object.hasOwn(parsed, 'adversarialResult')) {
|
|
268
|
+
return { ok: false, reason: 'adversarial_result_missing', detail: `evaluator artifact ${artifactId} carries no adversarialResult` };
|
|
269
|
+
}
|
|
270
|
+
const { adversarialResult } = parsed;
|
|
271
|
+
if (!isRecord(adversarialResult) || typeof adversarialResult.passed !== 'boolean') {
|
|
272
|
+
return { ok: false, reason: 'adversarial_result_invalid', detail: `evaluator artifact ${artifactId} adversarialResult is malformed (passed must be a boolean)` };
|
|
273
|
+
}
|
|
274
|
+
if (!Object.hasOwn(adversarialResult, 'failedCases') || !Array.isArray(adversarialResult.failedCases)) {
|
|
275
|
+
return { ok: false, reason: 'adversarial_result_invalid', detail: `evaluator artifact ${artifactId} adversarialResult.failedCases is missing or not an array` };
|
|
276
|
+
}
|
|
277
|
+
// rc-4: validate every element; any structurally invalid entry fails loud —
|
|
278
|
+
// dropping evidence silently would re-create the blind-retry hole.
|
|
279
|
+
const normalized = [];
|
|
280
|
+
for (const [index, entry] of adversarialResult.failedCases.entries()) {
|
|
281
|
+
const normalizedEntry = normalizeFailedCaseEntry(entry);
|
|
282
|
+
if (normalizedEntry === null) {
|
|
283
|
+
return {
|
|
284
|
+
ok: false,
|
|
285
|
+
reason: 'adversarial_result_invalid',
|
|
286
|
+
detail: `evaluator artifact ${artifactId} adversarialResult.failedCases[${index}] is structurally invalid`,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
normalized.push(normalizedEntry);
|
|
290
|
+
}
|
|
291
|
+
// Partition by identity (SPEC §17/§18): real trace IDs vs system sentinels
|
|
292
|
+
// vs code-level global violations. Forbidden-pattern entries are counted
|
|
293
|
+
// ONLY as global violations — never also as system failures (review P2
|
|
294
|
+
// 2026-09-02: no double-count in the prompt) — and share the bounded
|
|
295
|
+
// selection budget with everything else.
|
|
296
|
+
const traceFailures = [];
|
|
297
|
+
const systemFailures = [];
|
|
298
|
+
const globalViolations = [];
|
|
299
|
+
for (const failure of normalized) {
|
|
300
|
+
if (failure.caseId === '__forbidden_pattern__') {
|
|
301
|
+
globalViolations.push(failure.message ?? `forbidden pattern (${failure.errorType})`);
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
if (isSystemSentinelCaseId(failure.caseId)) {
|
|
305
|
+
systemFailures.push(failure);
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
traceFailures.push(failure);
|
|
309
|
+
}
|
|
310
|
+
const selection = selectBoundedReplayFailures({
|
|
311
|
+
traceFailures,
|
|
312
|
+
systemFailures,
|
|
313
|
+
globalViolations,
|
|
314
|
+
capacity: MAX_REPLAY_FAILURES_IN_REPAIR,
|
|
315
|
+
});
|
|
316
|
+
return {
|
|
317
|
+
ok: true,
|
|
318
|
+
context: {
|
|
319
|
+
sourceEvaluatorTaskId,
|
|
320
|
+
sourceEvaluatorArtifactId: artifactId,
|
|
321
|
+
ran: true,
|
|
322
|
+
passed: adversarialResult.passed,
|
|
323
|
+
failedCaseCount: normalized.length,
|
|
324
|
+
traceFailures: selection.selectedTrace,
|
|
325
|
+
systemFailures: selection.selectedSystem,
|
|
326
|
+
globalViolations: selection.selectedGlobalViolations,
|
|
327
|
+
globalViolationCount: globalViolations.length,
|
|
328
|
+
truncated: selection.truncated,
|
|
329
|
+
},
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
//# sourceMappingURL=repair-replay-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair-replay-resolver.js","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/repair-replay-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pain Ingress shared invariants + persisted payload contract — PRI-642.
|
|
3
|
+
*
|
|
4
|
+
* This module is THE single source for:
|
|
5
|
+
* - the report field parsers (origin / correlation / evidence / score)
|
|
6
|
+
* shared by write-time evaluation and persisted-payload re-entry;
|
|
7
|
+
* - the origin/correlation invariant (`validateOriginCorrelationInvariant`)
|
|
8
|
+
* — the valid-combination rules of SPEC §8.2 that must never diverge
|
|
9
|
+
* between write time and re-entry;
|
|
10
|
+
* - the sentinel session constant (frozen decision #4);
|
|
11
|
+
* - the versioned `painIngress.v1` persisted namespace (SPEC §9) written
|
|
12
|
+
* by PainSignalBridge.buildDiagnosticJson beside the legacy top-level
|
|
13
|
+
* fields, and re-validated by executePendingDiagnosis / retry paths.
|
|
14
|
+
*
|
|
15
|
+
* INVARIANT EQUIVALENCE (review blocker 2): re-entry validation is NOT
|
|
16
|
+
* weaker than write-time validation. parsePainIngressV1Payload shares the
|
|
17
|
+
* field parsers and the invariant with evaluatePainIngress
|
|
18
|
+
* (pain-ingress.ts), so every state illegal at write time — sentinel
|
|
19
|
+
* session ids, empty "available" evidence, impossible origin/correlation
|
|
20
|
+
* combinations — is also rejected on re-entry.
|
|
21
|
+
*
|
|
22
|
+
* Legacy compatibility (SPEC §9): payloads WITHOUT a painIngress.v1 block
|
|
23
|
+
* keep the tolerant legacy normalization branch in pain-signal-bridge.ts;
|
|
24
|
+
* this strictness applies only to payloads CLAIMING the v1 namespace.
|
|
25
|
+
*
|
|
26
|
+
* Pure module — no I/O. @principles/host-runtime and other adapters depend
|
|
27
|
+
* on core; core depends on no adapter.
|
|
28
|
+
*/
|
|
29
|
+
import type { PainProvenance } from './admission-gate.js';
|
|
30
|
+
export declare const PAIN_INGRESS_PAYLOAD_VERSION = "v1";
|
|
31
|
+
export type PainIngressOriginV1 = {
|
|
32
|
+
kind: 'owner_manual';
|
|
33
|
+
channel: 'openclaw_command' | 'cli_explicit_session' | 'external_cli_unbound';
|
|
34
|
+
} | {
|
|
35
|
+
kind: 'automatic_hook';
|
|
36
|
+
source: string;
|
|
37
|
+
};
|
|
38
|
+
export type PainIngressCorrelationV1 = {
|
|
39
|
+
status: 'bound';
|
|
40
|
+
hostKind: 'openclaw';
|
|
41
|
+
sessionId: string;
|
|
42
|
+
traceId?: string;
|
|
43
|
+
} | {
|
|
44
|
+
status: 'bound';
|
|
45
|
+
hostKind: 'codex';
|
|
46
|
+
rootSessionId: string;
|
|
47
|
+
rolloutIdentity: string;
|
|
48
|
+
logicalObservationKey: string;
|
|
49
|
+
hostTurnId: string;
|
|
50
|
+
traceId?: string;
|
|
51
|
+
} | {
|
|
52
|
+
status: 'unbound';
|
|
53
|
+
reason: 'external_cli' | 'missing_host_session';
|
|
54
|
+
};
|
|
55
|
+
export type PainIngressEvidenceClassV1 = {
|
|
56
|
+
status: 'available';
|
|
57
|
+
entryCount: number;
|
|
58
|
+
} | {
|
|
59
|
+
status: 'unavailable';
|
|
60
|
+
reason: 'trajectory_unavailable' | 'session_not_found' | 'empty_trajectory' | 'evidence_read_failed' | 'evidence_invalid'
|
|
61
|
+
/** Unbound Owner reports never consult a trajectory — no evidence is sought. */
|
|
62
|
+
| 'not_applicable_unbound';
|
|
63
|
+
};
|
|
64
|
+
export type PainEvidenceUnavailableReason = 'trajectory_unavailable' | 'session_not_found' | 'empty_trajectory' | 'evidence_read_failed' | 'evidence_invalid'
|
|
65
|
+
/** Unbound Owner reports never consult a trajectory — no evidence is sought. */
|
|
66
|
+
| 'not_applicable_unbound';
|
|
67
|
+
export interface IngressEvidenceEntry {
|
|
68
|
+
kind: 'behavior_trace' | 'system_event';
|
|
69
|
+
sourceRef: string;
|
|
70
|
+
note: string;
|
|
71
|
+
}
|
|
72
|
+
export type PainEvidenceBundle = {
|
|
73
|
+
status: 'available';
|
|
74
|
+
entries: readonly [IngressEvidenceEntry, ...IngressEvidenceEntry[]];
|
|
75
|
+
} | {
|
|
76
|
+
status: 'unavailable';
|
|
77
|
+
reason: PainEvidenceUnavailableReason;
|
|
78
|
+
};
|
|
79
|
+
export type PainOrigin = PainIngressOriginV1;
|
|
80
|
+
export type PainCorrelation = PainIngressCorrelationV1;
|
|
81
|
+
export interface PainIngressReport {
|
|
82
|
+
identity: {
|
|
83
|
+
kind: 'manual_pain_id';
|
|
84
|
+
painId: string;
|
|
85
|
+
} | {
|
|
86
|
+
kind: 'host_observation';
|
|
87
|
+
observationId: string;
|
|
88
|
+
};
|
|
89
|
+
painType: 'tool_failure' | 'subagent_error' | 'user_frustration';
|
|
90
|
+
source: string;
|
|
91
|
+
reason: string;
|
|
92
|
+
score?: number;
|
|
93
|
+
origin: PainOrigin;
|
|
94
|
+
correlation: PainCorrelation;
|
|
95
|
+
evidence: PainEvidenceBundle;
|
|
96
|
+
}
|
|
97
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
98
|
+
/**
|
|
99
|
+
* Sentinel session ids are never real correlations (frozen decision #4).
|
|
100
|
+
* Import this constant instead of re-declaring the set in another module.
|
|
101
|
+
*/
|
|
102
|
+
export declare const SENTINEL_SESSION_IDS: ReadonlySet<string>;
|
|
103
|
+
export declare function isSentinelSessionId(value: string): boolean;
|
|
104
|
+
export declare function parseOrigin(value: unknown): PainOrigin | null;
|
|
105
|
+
/**
|
|
106
|
+
* THE correlation parser — used by report validation (write time) and the
|
|
107
|
+
* persisted-payload validator (re-entry) so sentinel rejection and lineage
|
|
108
|
+
* completeness cannot drift between the two.
|
|
109
|
+
*/
|
|
110
|
+
export declare function parseCorrelation(value: unknown): {
|
|
111
|
+
value: PainCorrelation;
|
|
112
|
+
error?: undefined;
|
|
113
|
+
} | {
|
|
114
|
+
value?: undefined;
|
|
115
|
+
error: string;
|
|
116
|
+
};
|
|
117
|
+
export declare function parseEvidence(value: unknown): {
|
|
118
|
+
value: PainEvidenceBundle;
|
|
119
|
+
error?: undefined;
|
|
120
|
+
} | {
|
|
121
|
+
value?: undefined;
|
|
122
|
+
error: string;
|
|
123
|
+
};
|
|
124
|
+
/** rc-3/rc-9: a present-but-invalid score is rejected, not silently dropped. */
|
|
125
|
+
export declare function parseScore(value: unknown): {
|
|
126
|
+
score: number | undefined;
|
|
127
|
+
scoreInvalid?: undefined;
|
|
128
|
+
} | {
|
|
129
|
+
score: undefined;
|
|
130
|
+
scoreInvalid: true;
|
|
131
|
+
};
|
|
132
|
+
export type PainIngressParseResult = {
|
|
133
|
+
ok: true;
|
|
134
|
+
report: PainIngressReport;
|
|
135
|
+
} | {
|
|
136
|
+
ok: false;
|
|
137
|
+
reasonCode: string;
|
|
138
|
+
message: string;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Validate an untrusted report (parsed JSON / host payload) into a typed
|
|
142
|
+
* PainIngressReport. Fails loud with a structured reasonCode (rc-3); uses
|
|
143
|
+
* the SAME field parsers and invariant as the persisted-payload validator
|
|
144
|
+
* (rc-1/rc-2/rc-3/rc-4).
|
|
145
|
+
*/
|
|
146
|
+
export declare function parsePainIngressReport(input: unknown): PainIngressParseResult;
|
|
147
|
+
/**
|
|
148
|
+
* Origin/correlation combinations the matrix (SPEC §8.2) declares invalid.
|
|
149
|
+
* Shared by evaluatePainIngress (write time) and parsePainIngressV1Payload
|
|
150
|
+
* (re-entry) so an illegal state can never become legal across a
|
|
151
|
+
* persistence round trip. Returns a reasonCode string when invalid, null
|
|
152
|
+
* when the combination is valid.
|
|
153
|
+
*/
|
|
154
|
+
export declare function validateOriginCorrelationInvariant(origin: PainOrigin, correlation: PainCorrelation): string | null;
|
|
155
|
+
/**
|
|
156
|
+
* The persisted v1 block. Evidence ENTRIES are intentionally not duplicated
|
|
157
|
+
* here — they remain in the legacy top-level `evidence` field; this block
|
|
158
|
+
* records their validated classification only (SPEC §9: one versioned
|
|
159
|
+
* namespace for the rev-2 facts, legacy fields stay authoritative for
|
|
160
|
+
* their own consumers).
|
|
161
|
+
*/
|
|
162
|
+
export interface PainIngressV1Payload {
|
|
163
|
+
version: typeof PAIN_INGRESS_PAYLOAD_VERSION;
|
|
164
|
+
origin: PainIngressOriginV1;
|
|
165
|
+
correlation: PainIngressCorrelationV1;
|
|
166
|
+
evidenceClass: PainIngressEvidenceClassV1;
|
|
167
|
+
}
|
|
168
|
+
export type PainIngressV1ParseResult = {
|
|
169
|
+
ok: true;
|
|
170
|
+
payload: PainIngressV1Payload;
|
|
171
|
+
} | {
|
|
172
|
+
ok: false;
|
|
173
|
+
reasonCode: string;
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Runtime validation of an untrusted persisted painIngress block
|
|
177
|
+
* (rc-1/rc-2/rc-3). Shares parseOrigin/parseCorrelation and the
|
|
178
|
+
* origin/correlation invariant with the write-time evaluator, so sentinel
|
|
179
|
+
* sessions, incomplete Codex lineage and impossible combinations are
|
|
180
|
+
* rejected identically at write time and on re-entry.
|
|
181
|
+
*/
|
|
182
|
+
export declare function parsePainIngressV1Payload(value: unknown): PainIngressV1ParseResult;
|
|
183
|
+
/**
|
|
184
|
+
* Derive the legacy provenance from validated rev-2 facts (SPEC §8.3).
|
|
185
|
+
* Adapters do not supply provenance independently; this is the one
|
|
186
|
+
* derivation shared by writers and re-entry validation.
|
|
187
|
+
*/
|
|
188
|
+
export declare function deriveProvenanceFromIngressFacts(origin: PainIngressOriginV1, correlation: PainIngressCorrelationV1): PainProvenance;
|
|
189
|
+
/**
|
|
190
|
+
* Re-entry consistency check between the nested v1 block and the legacy
|
|
191
|
+
* top-level fields produced by the same builder (SPEC §9, §12.2.4).
|
|
192
|
+
* Returns null when consistent; a reasonCode string otherwise.
|
|
193
|
+
*
|
|
194
|
+
* Coverage (review blocker 2 closure): every dimension of the
|
|
195
|
+
* nested/top-level contract is asserted — provenance, host session id,
|
|
196
|
+
* evidence count, evidence availability class, and host binding
|
|
197
|
+
* state. A v1 block with unavailable evidence cannot coexist with
|
|
198
|
+
* legacy top-level entries; an unbound v1 block cannot coexist with
|
|
199
|
+
* a legacy sessionIdHint.
|
|
200
|
+
*/
|
|
201
|
+
export declare function checkIngressTopLevelConsistency(input: {
|
|
202
|
+
payload: PainIngressV1Payload;
|
|
203
|
+
topLevelProvenance: unknown;
|
|
204
|
+
topLevelSessionIdHint: unknown;
|
|
205
|
+
topLevelEvidenceCount: number;
|
|
206
|
+
}): string | null;
|
|
207
|
+
//# sourceMappingURL=pain-ingress-payload.d.ts.map
|