@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 @@
|
|
|
1
|
+
{"version":3,"file":"pain-ingress-payload.d.ts","sourceRoot":"","sources":["../../src/runtime-v2/pain-ingress-payload.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,340 @@
|
|
|
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 { normalizePainProvenance } from './admission-gate.js';
|
|
30
|
+
export const PAIN_INGRESS_PAYLOAD_VERSION = 'v1';
|
|
31
|
+
// ── Shared invariants and parsers (ONE implementation for write time AND
|
|
32
|
+
// re-entry) ───────────────────────────────────────────────────────────────
|
|
33
|
+
export function isRecord(value) {
|
|
34
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
35
|
+
}
|
|
36
|
+
function hasOwnString(obj, key) {
|
|
37
|
+
return Object.hasOwn(obj, key) && typeof obj[key] === 'string' && (obj[key]).length > 0;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Sentinel session ids are never real correlations (frozen decision #4).
|
|
41
|
+
* Import this constant instead of re-declaring the set in another module.
|
|
42
|
+
*/
|
|
43
|
+
export const SENTINEL_SESSION_IDS = new Set(['cli', 'unknown']);
|
|
44
|
+
export function isSentinelSessionId(value) {
|
|
45
|
+
return SENTINEL_SESSION_IDS.has(value);
|
|
46
|
+
}
|
|
47
|
+
export function parseOrigin(value) {
|
|
48
|
+
if (!isRecord(value))
|
|
49
|
+
return null;
|
|
50
|
+
if (value.kind === 'owner_manual') {
|
|
51
|
+
const { channel } = value;
|
|
52
|
+
if (channel === 'openclaw_command' || channel === 'cli_explicit_session' || channel === 'external_cli_unbound') {
|
|
53
|
+
return { kind: 'owner_manual', channel };
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
if (value.kind === 'automatic_hook' && typeof value.source === 'string' && value.source.length > 0) {
|
|
58
|
+
return { kind: 'automatic_hook', source: value.source };
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* THE correlation parser — used by report validation (write time) and the
|
|
64
|
+
* persisted-payload validator (re-entry) so sentinel rejection and lineage
|
|
65
|
+
* completeness cannot drift between the two.
|
|
66
|
+
*/
|
|
67
|
+
export function parseCorrelation(value) {
|
|
68
|
+
if (!isRecord(value))
|
|
69
|
+
return { error: 'correlation_invalid' };
|
|
70
|
+
if (value.status === 'unbound') {
|
|
71
|
+
if (value.reason === 'external_cli' || value.reason === 'missing_host_session') {
|
|
72
|
+
return { value: { status: 'unbound', reason: value.reason } };
|
|
73
|
+
}
|
|
74
|
+
return { error: 'correlation_invalid' };
|
|
75
|
+
}
|
|
76
|
+
if (value.status !== 'bound')
|
|
77
|
+
return { error: 'correlation_invalid' };
|
|
78
|
+
if (value.hostKind === 'openclaw') {
|
|
79
|
+
if (!hasOwnString(value, 'sessionId'))
|
|
80
|
+
return { error: 'correlation_invalid' };
|
|
81
|
+
if (isSentinelSessionId(value.sessionId))
|
|
82
|
+
return { error: 'session_sentinel_invalid' };
|
|
83
|
+
const correlation = { status: 'bound', hostKind: 'openclaw', sessionId: value.sessionId };
|
|
84
|
+
if (typeof value.traceId === 'string')
|
|
85
|
+
correlation.traceId = value.traceId;
|
|
86
|
+
return { value: correlation };
|
|
87
|
+
}
|
|
88
|
+
if (value.hostKind === 'codex') {
|
|
89
|
+
if (!hasOwnString(value, 'rootSessionId'))
|
|
90
|
+
return { error: 'codex_lineage_incomplete' };
|
|
91
|
+
if (!hasOwnString(value, 'rolloutIdentity'))
|
|
92
|
+
return { error: 'codex_lineage_incomplete' };
|
|
93
|
+
if (!hasOwnString(value, 'logicalObservationKey'))
|
|
94
|
+
return { error: 'codex_lineage_incomplete' };
|
|
95
|
+
if (!hasOwnString(value, 'hostTurnId'))
|
|
96
|
+
return { error: 'codex_lineage_incomplete' };
|
|
97
|
+
const correlation = {
|
|
98
|
+
status: 'bound',
|
|
99
|
+
hostKind: 'codex',
|
|
100
|
+
rootSessionId: value.rootSessionId,
|
|
101
|
+
rolloutIdentity: value.rolloutIdentity,
|
|
102
|
+
logicalObservationKey: value.logicalObservationKey,
|
|
103
|
+
hostTurnId: value.hostTurnId,
|
|
104
|
+
};
|
|
105
|
+
if (typeof value.traceId === 'string')
|
|
106
|
+
correlation.traceId = value.traceId;
|
|
107
|
+
return { value: correlation };
|
|
108
|
+
}
|
|
109
|
+
return { error: 'correlation_invalid' };
|
|
110
|
+
}
|
|
111
|
+
const EVIDENCE_UNAVAILABLE_REASONS = [
|
|
112
|
+
'trajectory_unavailable',
|
|
113
|
+
'session_not_found',
|
|
114
|
+
'empty_trajectory',
|
|
115
|
+
'evidence_read_failed',
|
|
116
|
+
'evidence_invalid',
|
|
117
|
+
'not_applicable_unbound',
|
|
118
|
+
];
|
|
119
|
+
function isEvidenceUnavailableReason(value) {
|
|
120
|
+
return EVIDENCE_UNAVAILABLE_REASONS.includes(value);
|
|
121
|
+
}
|
|
122
|
+
export function parseEvidence(value) {
|
|
123
|
+
if (!isRecord(value))
|
|
124
|
+
return { error: 'evidence_invalid' };
|
|
125
|
+
if (value.status === 'available') {
|
|
126
|
+
if (!Array.isArray(value.entries) || value.entries.length === 0)
|
|
127
|
+
return { error: 'evidence_invalid' };
|
|
128
|
+
const entries = [];
|
|
129
|
+
for (const entry of value.entries) {
|
|
130
|
+
if (!isRecord(entry))
|
|
131
|
+
return { error: 'evidence_invalid' };
|
|
132
|
+
if (entry.kind !== 'behavior_trace' && entry.kind !== 'system_event')
|
|
133
|
+
return { error: 'evidence_invalid' };
|
|
134
|
+
if (typeof entry.sourceRef !== 'string' || entry.sourceRef.length === 0)
|
|
135
|
+
return { error: 'evidence_invalid' };
|
|
136
|
+
if (typeof entry.note !== 'string')
|
|
137
|
+
return { error: 'evidence_invalid' };
|
|
138
|
+
entries.push({ kind: entry.kind, sourceRef: entry.sourceRef, note: entry.note });
|
|
139
|
+
}
|
|
140
|
+
return { value: { status: 'available', entries: entries } };
|
|
141
|
+
}
|
|
142
|
+
const reasons = EVIDENCE_UNAVAILABLE_REASONS;
|
|
143
|
+
if (value.status === 'unavailable' && reasons.includes(value.reason)) {
|
|
144
|
+
return { value: { status: 'unavailable', reason: value.reason } };
|
|
145
|
+
}
|
|
146
|
+
return { error: 'evidence_invalid' };
|
|
147
|
+
}
|
|
148
|
+
/** rc-3/rc-9: a present-but-invalid score is rejected, not silently dropped. */
|
|
149
|
+
export function parseScore(value) {
|
|
150
|
+
if (value === undefined)
|
|
151
|
+
return { score: undefined };
|
|
152
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value < 0 || value > 100) {
|
|
153
|
+
return { score: undefined, scoreInvalid: true };
|
|
154
|
+
}
|
|
155
|
+
return { score: value };
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Validate an untrusted report (parsed JSON / host payload) into a typed
|
|
159
|
+
* PainIngressReport. Fails loud with a structured reasonCode (rc-3); uses
|
|
160
|
+
* the SAME field parsers and invariant as the persisted-payload validator
|
|
161
|
+
* (rc-1/rc-2/rc-3/rc-4).
|
|
162
|
+
*/
|
|
163
|
+
export function parsePainIngressReport(input) {
|
|
164
|
+
if (!isRecord(input)) {
|
|
165
|
+
return { ok: false, reasonCode: 'report_invalid', message: 'ingress report must be an object' };
|
|
166
|
+
}
|
|
167
|
+
if (!isRecord(input.identity))
|
|
168
|
+
return { ok: false, reasonCode: 'identity_invalid', message: 'identity must be an object' };
|
|
169
|
+
if (input.identity.kind === 'manual_pain_id') {
|
|
170
|
+
if (!hasOwnString(input.identity, 'painId'))
|
|
171
|
+
return { ok: false, reasonCode: 'identity_invalid', message: 'manual_pain_id requires painId' };
|
|
172
|
+
}
|
|
173
|
+
else if (input.identity.kind === 'host_observation') {
|
|
174
|
+
if (!hasOwnString(input.identity, 'observationId'))
|
|
175
|
+
return { ok: false, reasonCode: 'identity_invalid', message: 'host_observation requires observationId' };
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
return { ok: false, reasonCode: 'identity_invalid', message: 'identity.kind must be manual_pain_id or host_observation' };
|
|
179
|
+
}
|
|
180
|
+
const painTypes = ['tool_failure', 'subagent_error', 'user_frustration'];
|
|
181
|
+
if (!painTypes.includes(input.painType)) {
|
|
182
|
+
return { ok: false, reasonCode: 'pain_type_invalid', message: 'painType must be tool_failure | subagent_error | user_frustration' };
|
|
183
|
+
}
|
|
184
|
+
if (!hasOwnString(input, 'source'))
|
|
185
|
+
return { ok: false, reasonCode: 'source_invalid', message: 'source is required' };
|
|
186
|
+
if (!hasOwnString(input, 'reason'))
|
|
187
|
+
return { ok: false, reasonCode: 'reason_invalid', message: 'reason is required' };
|
|
188
|
+
const origin = parseOrigin(input.origin);
|
|
189
|
+
if (origin === null)
|
|
190
|
+
return { ok: false, reasonCode: 'origin_invalid', message: 'origin must be owner_manual{channel} or automatic_hook{source}' };
|
|
191
|
+
const correlation = parseCorrelation(input.correlation);
|
|
192
|
+
if (correlation.error !== undefined) {
|
|
193
|
+
return { ok: false, reasonCode: correlation.error, message: `correlation rejected: ${correlation.error}` };
|
|
194
|
+
}
|
|
195
|
+
const evidence = parseEvidence(input.evidence);
|
|
196
|
+
if (evidence.error !== undefined) {
|
|
197
|
+
return { ok: false, reasonCode: evidence.error, message: `evidence rejected: ${evidence.error}` };
|
|
198
|
+
}
|
|
199
|
+
// rc-3/rc-9: a present-but-invalid score is rejected, not silently dropped.
|
|
200
|
+
const { score, scoreInvalid } = parseScore(input.score);
|
|
201
|
+
if (scoreInvalid) {
|
|
202
|
+
return { ok: false, reasonCode: 'score_invalid', message: 'score must be a number between 0 and 100' };
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
ok: true,
|
|
206
|
+
report: {
|
|
207
|
+
identity: input.identity,
|
|
208
|
+
painType: input.painType,
|
|
209
|
+
source: input.source,
|
|
210
|
+
reason: input.reason,
|
|
211
|
+
score,
|
|
212
|
+
origin,
|
|
213
|
+
correlation: correlation.value,
|
|
214
|
+
evidence: evidence.value,
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Origin/correlation combinations the matrix (SPEC §8.2) declares invalid.
|
|
220
|
+
* Shared by evaluatePainIngress (write time) and parsePainIngressV1Payload
|
|
221
|
+
* (re-entry) so an illegal state can never become legal across a
|
|
222
|
+
* persistence round trip. Returns a reasonCode string when invalid, null
|
|
223
|
+
* when the combination is valid.
|
|
224
|
+
*/
|
|
225
|
+
export function validateOriginCorrelationInvariant(origin, correlation) {
|
|
226
|
+
if (origin.kind !== 'owner_manual')
|
|
227
|
+
return null;
|
|
228
|
+
if (origin.channel === 'external_cli_unbound' && correlation.status === 'bound') {
|
|
229
|
+
return 'origin_correlation_mismatch';
|
|
230
|
+
}
|
|
231
|
+
if (origin.channel === 'cli_explicit_session' && correlation.status === 'unbound') {
|
|
232
|
+
return 'origin_correlation_mismatch';
|
|
233
|
+
}
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Persisted mirror of the write-time evidence bundle classification
|
|
238
|
+
* (PainEvidenceBundle). `available` requires entryCount >= 1 — the same
|
|
239
|
+
* invariant the write-time bundle enforces (a non-empty entries tuple), so
|
|
240
|
+
* an "available with zero entries" state can never pass here.
|
|
241
|
+
*/
|
|
242
|
+
function parseEvidenceClass(value) {
|
|
243
|
+
if (!isRecord(value))
|
|
244
|
+
return null;
|
|
245
|
+
if (value.status === 'available') {
|
|
246
|
+
if (Object.hasOwn(value, 'entryCount') && typeof value.entryCount === 'number' && Number.isInteger(value.entryCount) && value.entryCount >= 1) {
|
|
247
|
+
return { status: 'available', entryCount: value.entryCount };
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
if (value.status === 'unavailable' && isEvidenceUnavailableReason(value.reason)) {
|
|
252
|
+
return { status: 'unavailable', reason: value.reason };
|
|
253
|
+
}
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Runtime validation of an untrusted persisted painIngress block
|
|
258
|
+
* (rc-1/rc-2/rc-3). Shares parseOrigin/parseCorrelation and the
|
|
259
|
+
* origin/correlation invariant with the write-time evaluator, so sentinel
|
|
260
|
+
* sessions, incomplete Codex lineage and impossible combinations are
|
|
261
|
+
* rejected identically at write time and on re-entry.
|
|
262
|
+
*/
|
|
263
|
+
export function parsePainIngressV1Payload(value) {
|
|
264
|
+
if (!isRecord(value))
|
|
265
|
+
return { ok: false, reasonCode: 'ingress_payload_invalid' };
|
|
266
|
+
if (value.version !== PAIN_INGRESS_PAYLOAD_VERSION)
|
|
267
|
+
return { ok: false, reasonCode: 'ingress_payload_version_unsupported' };
|
|
268
|
+
const origin = parseOrigin(value.origin);
|
|
269
|
+
if (origin === null)
|
|
270
|
+
return { ok: false, reasonCode: 'ingress_origin_invalid' };
|
|
271
|
+
const correlation = parseCorrelation(value.correlation);
|
|
272
|
+
if (correlation.error !== undefined)
|
|
273
|
+
return { ok: false, reasonCode: correlation.error };
|
|
274
|
+
const evidenceClass = parseEvidenceClass(value.evidenceClass);
|
|
275
|
+
if (evidenceClass === null)
|
|
276
|
+
return { ok: false, reasonCode: 'ingress_evidence_class_invalid' };
|
|
277
|
+
const invariantViolation = validateOriginCorrelationInvariant(origin, correlation.value);
|
|
278
|
+
if (invariantViolation !== null)
|
|
279
|
+
return { ok: false, reasonCode: invariantViolation };
|
|
280
|
+
return { ok: true, payload: { version: PAIN_INGRESS_PAYLOAD_VERSION, origin, correlation: correlation.value, evidenceClass } };
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Derive the legacy provenance from validated rev-2 facts (SPEC §8.3).
|
|
284
|
+
* Adapters do not supply provenance independently; this is the one
|
|
285
|
+
* derivation shared by writers and re-entry validation.
|
|
286
|
+
*/
|
|
287
|
+
export function deriveProvenanceFromIngressFacts(origin, correlation) {
|
|
288
|
+
if (origin.kind === 'automatic_hook')
|
|
289
|
+
return 'automatic_hook';
|
|
290
|
+
if (correlation.status === 'bound')
|
|
291
|
+
return 'host_context_bound';
|
|
292
|
+
return 'owner_reported_no_host_trace';
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Re-entry consistency check between the nested v1 block and the legacy
|
|
296
|
+
* top-level fields produced by the same builder (SPEC §9, §12.2.4).
|
|
297
|
+
* Returns null when consistent; a reasonCode string otherwise.
|
|
298
|
+
*
|
|
299
|
+
* Coverage (review blocker 2 closure): every dimension of the
|
|
300
|
+
* nested/top-level contract is asserted — provenance, host session id,
|
|
301
|
+
* evidence count, evidence availability class, and host binding
|
|
302
|
+
* state. A v1 block with unavailable evidence cannot coexist with
|
|
303
|
+
* legacy top-level entries; an unbound v1 block cannot coexist with
|
|
304
|
+
* a legacy sessionIdHint.
|
|
305
|
+
*/
|
|
306
|
+
export function checkIngressTopLevelConsistency(input) {
|
|
307
|
+
const { payload, topLevelProvenance, topLevelSessionIdHint, topLevelEvidenceCount } = input;
|
|
308
|
+
const expectedProvenance = deriveProvenanceFromIngressFacts(payload.origin, payload.correlation);
|
|
309
|
+
const actualProvenance = typeof topLevelProvenance === 'string' ? normalizePainProvenance(topLevelProvenance) : undefined;
|
|
310
|
+
if (actualProvenance !== expectedProvenance) {
|
|
311
|
+
return 'ingress_payload_mismatch:provenance';
|
|
312
|
+
}
|
|
313
|
+
// Unbound v1 must not coexist with a non-empty top-level session hint
|
|
314
|
+
// (the host would have inferred a real binding at write time).
|
|
315
|
+
if (payload.correlation.status === 'unbound') {
|
|
316
|
+
if (topLevelSessionIdHint !== null && topLevelSessionIdHint !== undefined && topLevelSessionIdHint !== '') {
|
|
317
|
+
return 'ingress_payload_mismatch:unbound_session_hint';
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// Bound v1 (OpenClaw) → the host and the v1 must agree on the session id.
|
|
321
|
+
if (payload.correlation.status === 'bound' && payload.correlation.hostKind === 'openclaw') {
|
|
322
|
+
if (topLevelSessionIdHint !== payload.correlation.sessionId) {
|
|
323
|
+
return 'ingress_payload_mismatch:session';
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// evidenceClass ↔ top-level evidence count: an unavailable v1 cannot
|
|
327
|
+
// coexist with legacy entries; an available v1 must match the count.
|
|
328
|
+
if (payload.evidenceClass.status === 'unavailable') {
|
|
329
|
+
if (topLevelEvidenceCount !== 0) {
|
|
330
|
+
return 'ingress_payload_mismatch:unavailable_evidence_count';
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
if (payload.evidenceClass.entryCount !== topLevelEvidenceCount) {
|
|
335
|
+
return 'ingress_payload_mismatch:evidence_count';
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
//# sourceMappingURL=pain-ingress-payload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pain-ingress-payload.js","sourceRoot":"","sources":["../../src/runtime-v2/pain-ingress-payload.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { PainIngressV1Payload, PainIngressReport, IngressEvidenceEntry } from './pain-ingress-payload.js';
|
|
2
|
+
import type { PainProvenance } from './admission-gate.js';
|
|
3
|
+
export { SENTINEL_SESSION_IDS, isSentinelSessionId, parsePainIngressReport, validateOriginCorrelationInvariant, } from './pain-ingress-payload.js';
|
|
4
|
+
export type { PainOrigin, PainCorrelation, IngressEvidenceEntry, PainEvidenceBundle, PainEvidenceUnavailableReason, PainIngressReport, PainIngressParseResult, PainIngressV1Payload, } from './pain-ingress-payload.js';
|
|
5
|
+
/**
|
|
6
|
+
* The legacy write-side shape handed to PainToPrincipleService. Derived by
|
|
7
|
+
* the ingress — callers do not assemble provenance/evidence themselves.
|
|
8
|
+
*/
|
|
9
|
+
export interface LegacyPainSubmission {
|
|
10
|
+
painId: string;
|
|
11
|
+
painType: PainIngressReport['painType'];
|
|
12
|
+
source: string;
|
|
13
|
+
reason: string;
|
|
14
|
+
score?: number;
|
|
15
|
+
sessionId?: string;
|
|
16
|
+
agentId?: string;
|
|
17
|
+
traceId?: string;
|
|
18
|
+
provenance: PainProvenance;
|
|
19
|
+
hostKind?: 'openclaw' | 'codex';
|
|
20
|
+
evidence: IngressEvidenceEntry[];
|
|
21
|
+
/** Versioned rev-2 facts persisted beside the legacy top-level fields. */
|
|
22
|
+
painIngress: PainIngressV1Payload;
|
|
23
|
+
}
|
|
24
|
+
export type PainIngressDecision = {
|
|
25
|
+
action: 'submit';
|
|
26
|
+
legacy: LegacyPainSubmission;
|
|
27
|
+
painIngress: PainIngressV1Payload;
|
|
28
|
+
warnings: string[];
|
|
29
|
+
reasonCode?: undefined;
|
|
30
|
+
} | {
|
|
31
|
+
/** Explicit degradation: submission is still allowed (honest empty evidence + warning). */
|
|
32
|
+
action: 'degrade';
|
|
33
|
+
reasonCode: string;
|
|
34
|
+
warning: string;
|
|
35
|
+
nextAction: string;
|
|
36
|
+
legacy: LegacyPainSubmission;
|
|
37
|
+
painIngress: PainIngressV1Payload;
|
|
38
|
+
} | {
|
|
39
|
+
action: 'refuse';
|
|
40
|
+
reasonCode: string;
|
|
41
|
+
warning: string;
|
|
42
|
+
nextAction: string;
|
|
43
|
+
} | {
|
|
44
|
+
/**
|
|
45
|
+
* Automatic signal without binding/evidence — no LLM, no diagnostic
|
|
46
|
+
* task. `legacy` still carries the derived (empty-evidence) submission
|
|
47
|
+
* shape so host funnels can keep their observability projection via
|
|
48
|
+
* the bridge's empty-evidence short-circuit (SPEC §12.2.1/§12.2.2).
|
|
49
|
+
*/
|
|
50
|
+
action: 'observation_only';
|
|
51
|
+
reasonCode: string;
|
|
52
|
+
note: string;
|
|
53
|
+
legacy: LegacyPainSubmission;
|
|
54
|
+
painIngress: PainIngressV1Payload;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Decide the pre-LLM action for a validated report, per SPEC §8.2. Pure —
|
|
58
|
+
* no I/O, no persistence, no identity minting.
|
|
59
|
+
*/
|
|
60
|
+
export declare function evaluatePainIngress(report: PainIngressReport): PainIngressDecision;
|
|
61
|
+
//# sourceMappingURL=pain-ingress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pain-ingress.d.ts","sourceRoot":"","sources":["../../src/runtime-v2/pain-ingress.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EACV,oBAAoB,EACpB,iBAAiB,EAEjB,oBAAoB,EACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI1D,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,kCAAkC,GACnC,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACV,UAAU,EACV,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,6BAA6B,EAC7B,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AAEnC;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,cAAc,CAAC;IAC3B,QAAQ,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAChC,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,0EAA0E;IAC1E,WAAW,EAAE,oBAAoB,CAAC;CACnC;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAC;IAAC,WAAW,EAAE,oBAAoB,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,SAAS,CAAA;CAAE,GACjI;IACE,2FAA2F;IAC3F,MAAM,EAAE,SAAS,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,WAAW,EAAE,oBAAoB,CAAC;CACnC,GACD;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC7E;IACE;;;;;OAKG;IACH,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,oBAAoB,CAAC;IAC7B,WAAW,EAAE,oBAAoB,CAAC;CACnC,CAAC;AAuDN;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,iBAAiB,GAAG,mBAAmB,CAkFlF"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pain Ingress semantic evaluator — PRI-642 SPEC §8. THE single authority
|
|
3
|
+
* for pain ingress semantics across every adapter (OpenClaw funnel, pd-cli,
|
|
4
|
+
* future hosts):
|
|
5
|
+
*
|
|
6
|
+
* origin classification · bound/unbound correlation semantics ·
|
|
7
|
+
* provenance derivation · sentinel handling ·
|
|
8
|
+
* submit / degrade / refuse / observation_only decisions ·
|
|
9
|
+
* painIngress.v1 construction rules
|
|
10
|
+
*
|
|
11
|
+
* Host adapters differ only in ACQUISITION (how they obtain the session,
|
|
12
|
+
* read the trajectory, and build raw evidence); they MUST NOT re-implement
|
|
13
|
+
* the interpretation. Adapters build a PainIngressReport from their
|
|
14
|
+
* host-specific facts and call evaluatePainIngress.
|
|
15
|
+
*
|
|
16
|
+
* The field parsers, the sentinel constant, the origin/correlation
|
|
17
|
+
* invariant and parsePainIngressReport live in pain-ingress-payload.ts and
|
|
18
|
+
* are shared with the persisted-payload validator (re-entry) — one
|
|
19
|
+
* implementation, no drift.
|
|
20
|
+
*
|
|
21
|
+
* Pure module — no I/O, no persistence, no identity minting (SPEC §6: the
|
|
22
|
+
* ingress mints no canonical identity and owns no task store).
|
|
23
|
+
*/
|
|
24
|
+
import { deriveProvenanceFromIngressFacts } from './pain-ingress-payload.js';
|
|
25
|
+
import { PAIN_INGRESS_PAYLOAD_VERSION } from './pain-ingress-payload.js';
|
|
26
|
+
import { validateOriginCorrelationInvariant } from './pain-ingress-payload.js';
|
|
27
|
+
// Single public surface: re-export the shared parsers/invariants so
|
|
28
|
+
// adapters can import the whole ingress family from this module.
|
|
29
|
+
export { SENTINEL_SESSION_IDS, isSentinelSessionId, parsePainIngressReport, validateOriginCorrelationInvariant, } from './pain-ingress-payload.js';
|
|
30
|
+
// ── Evaluation (SPEC §8.2 valid-combination matrix) ────────────────────────
|
|
31
|
+
/**
|
|
32
|
+
* rc-6 lineage consistency: the Codex logical observation key embeds the
|
|
33
|
+
* rollout identity (`codex|<rolloutIdentity>|<turnId>|<kind>`) — identifiers
|
|
34
|
+
* from different events must be rejected, not averaged into one report.
|
|
35
|
+
*/
|
|
36
|
+
function isCodexLineageConsistent(correlation) {
|
|
37
|
+
if (correlation.status !== 'bound' || correlation.hostKind !== 'codex')
|
|
38
|
+
return true;
|
|
39
|
+
const prefix = `codex|${correlation.rolloutIdentity}|`;
|
|
40
|
+
return correlation.logicalObservationKey.startsWith(prefix);
|
|
41
|
+
}
|
|
42
|
+
function buildV1Payload(report) {
|
|
43
|
+
const evidenceClass = report.evidence.status === 'available'
|
|
44
|
+
? { status: 'available', entryCount: report.evidence.entries.length }
|
|
45
|
+
: { status: 'unavailable', reason: report.evidence.reason };
|
|
46
|
+
return {
|
|
47
|
+
version: PAIN_INGRESS_PAYLOAD_VERSION,
|
|
48
|
+
origin: report.origin,
|
|
49
|
+
correlation: report.correlation,
|
|
50
|
+
evidenceClass,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function buildLegacy(report, evidence) {
|
|
54
|
+
const provenance = deriveProvenanceFromIngressFacts(report.origin, report.correlation);
|
|
55
|
+
const legacy = {
|
|
56
|
+
painId: report.identity.kind === 'manual_pain_id' ? report.identity.painId : report.identity.observationId,
|
|
57
|
+
painType: report.painType,
|
|
58
|
+
source: report.source,
|
|
59
|
+
reason: report.reason,
|
|
60
|
+
score: report.score,
|
|
61
|
+
provenance,
|
|
62
|
+
evidence,
|
|
63
|
+
painIngress: buildV1Payload(report),
|
|
64
|
+
};
|
|
65
|
+
if (report.correlation.status === 'bound') {
|
|
66
|
+
legacy.hostKind = report.correlation.hostKind;
|
|
67
|
+
if (report.correlation.hostKind === 'openclaw') {
|
|
68
|
+
legacy.sessionId = report.correlation.sessionId;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Parity with the existing Codex admission path (it passes the root
|
|
72
|
+
// session as the legacy sessionId); the FULL unflattened lineage
|
|
73
|
+
// (rolloutIdentity / logicalObservationKey / hostTurnId) is retained
|
|
74
|
+
// in the versioned painIngress payload (frozen decision #8).
|
|
75
|
+
legacy.sessionId = report.correlation.rootSessionId;
|
|
76
|
+
}
|
|
77
|
+
if (report.correlation.traceId !== undefined)
|
|
78
|
+
legacy.traceId = report.correlation.traceId;
|
|
79
|
+
}
|
|
80
|
+
return legacy;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Decide the pre-LLM action for a validated report, per SPEC §8.2. Pure —
|
|
84
|
+
* no I/O, no persistence, no identity minting.
|
|
85
|
+
*/
|
|
86
|
+
export function evaluatePainIngress(report) {
|
|
87
|
+
const { origin, correlation, evidence } = report;
|
|
88
|
+
// rc-6: lineage identifiers must come from one consistent event.
|
|
89
|
+
if (!isCodexLineageConsistent(correlation)) {
|
|
90
|
+
return {
|
|
91
|
+
action: 'refuse',
|
|
92
|
+
reasonCode: 'lineage_mismatch',
|
|
93
|
+
warning: 'Lineage identifiers disagree (logical observation key does not embed the rollout identity).',
|
|
94
|
+
nextAction: 'Re-emit the observation from the event that owns the full lineage tuple.',
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// Row 7 / row 5: an unbound-channel report may never claim host binding,
|
|
98
|
+
// and an explicit-session channel may never be unbound (shared invariant
|
|
99
|
+
// also enforced by the persisted-payload validator on re-entry).
|
|
100
|
+
const invariantViolation = validateOriginCorrelationInvariant(origin, correlation);
|
|
101
|
+
if (invariantViolation !== null) {
|
|
102
|
+
return {
|
|
103
|
+
action: 'refuse',
|
|
104
|
+
reasonCode: invariantViolation,
|
|
105
|
+
warning: origin.kind === 'owner_manual' && origin.channel === 'external_cli_unbound'
|
|
106
|
+
? 'An external unbound Owner report cannot claim a host-bound correlation.'
|
|
107
|
+
: 'An explicit-session report arrived without a bound session.',
|
|
108
|
+
nextAction: 'Record via /pd-pain or pd pain record --session for a bound report, or keep the report unbound.',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
// Automatic hooks: no evidence or no binding → observation-only, no LLM.
|
|
112
|
+
if (origin.kind === 'automatic_hook') {
|
|
113
|
+
if (correlation.status === 'unbound') {
|
|
114
|
+
const legacy = buildLegacy(report, []);
|
|
115
|
+
return {
|
|
116
|
+
action: 'observation_only',
|
|
117
|
+
reasonCode: correlation.reason,
|
|
118
|
+
note: 'Automatic signal without host binding recorded as observation only; no diagnostic task, no LLM run.',
|
|
119
|
+
legacy,
|
|
120
|
+
painIngress: legacy.painIngress,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if (evidence.status === 'unavailable') {
|
|
124
|
+
const legacy = buildLegacy(report, []);
|
|
125
|
+
return {
|
|
126
|
+
action: 'observation_only',
|
|
127
|
+
reasonCode: evidence.reason,
|
|
128
|
+
note: 'Automatic signal without usable evidence recorded as observation only; no diagnostic task, no LLM run.',
|
|
129
|
+
legacy,
|
|
130
|
+
painIngress: legacy.painIngress,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
const legacy = buildLegacy(report, [...evidence.entries]);
|
|
134
|
+
return { action: 'submit', legacy, painIngress: legacy.painIngress, warnings: [] };
|
|
135
|
+
}
|
|
136
|
+
// Owner manual, bound (openclaw_command / cli_explicit_session).
|
|
137
|
+
if (correlation.status === 'bound') {
|
|
138
|
+
if (evidence.status === 'available') {
|
|
139
|
+
const legacy = buildLegacy(report, [...evidence.entries]);
|
|
140
|
+
return { action: 'submit', legacy, painIngress: legacy.painIngress, warnings: [] };
|
|
141
|
+
}
|
|
142
|
+
const legacy = buildLegacy(report, []);
|
|
143
|
+
return {
|
|
144
|
+
action: 'degrade',
|
|
145
|
+
reasonCode: evidence.reason,
|
|
146
|
+
warning: `Session bound, but trajectory evidence is unavailable (${evidence.reason}); the report is submitted with honest empty evidence and candidates may be gated by the admission threshold.`,
|
|
147
|
+
nextAction: 'Verify the session has recorded turns/tool calls, or re-record when evidence exists.',
|
|
148
|
+
legacy,
|
|
149
|
+
painIngress: legacy.painIngress,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
// Row 6: external unbound Owner report — manual exception with disclosure.
|
|
153
|
+
const legacy = buildLegacy(report, []);
|
|
154
|
+
return {
|
|
155
|
+
action: 'submit',
|
|
156
|
+
legacy,
|
|
157
|
+
painIngress: legacy.painIngress,
|
|
158
|
+
warnings: [
|
|
159
|
+
'context_unbound: no session bound — no trajectory evidence attached; candidates will likely be blocked by the admission gate. Re-run with --session <id> for trace-backed diagnosis.',
|
|
160
|
+
],
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=pain-ingress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pain-ingress.js","sourceRoot":"","sources":["../../src/runtime-v2/pain-ingress.ts"],"names":[],"mappings":"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"}
|