@skill-harness/adapters 0.12.0 → 0.13.0
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/archive-access.d.ts +58 -0
- package/dist/archive-access.js +61 -0
- package/dist/archive-checkpoint.d.ts +47 -0
- package/dist/archive-checkpoint.js +116 -0
- package/dist/archive-facts.d.ts +19 -0
- package/dist/archive-facts.js +20 -0
- package/dist/archive-observer.d.ts +21 -0
- package/dist/archive-observer.js +79 -0
- package/dist/archive-policy.d.ts +107 -0
- package/dist/archive-policy.js +135 -0
- package/dist/archive-read-capability.d.ts +49 -0
- package/dist/archive-read-capability.js +45 -0
- package/dist/archive-retention-policy.d.ts +52 -0
- package/dist/archive-retention-policy.js +49 -0
- package/dist/archived-work.d.ts +44 -0
- package/dist/archived-work.js +59 -0
- package/dist/blind-intervention.d.ts +29 -0
- package/dist/blind-intervention.js +211 -0
- package/dist/codex-diagnostic-model.d.ts +14 -0
- package/dist/codex-diagnostic-model.js +39 -0
- package/dist/codex-host-observer.d.ts +111 -0
- package/dist/codex-host-observer.js +309 -0
- package/dist/codex-https.d.ts +7 -0
- package/dist/codex-https.js +221 -0
- package/dist/codex-model-profile.d.ts +38 -0
- package/dist/codex-model-profile.js +54 -0
- package/dist/codex-producer-ipc.d.ts +55 -0
- package/dist/codex-producer-ipc.js +67 -0
- package/dist/codex-sdk-transport.d.ts +50 -0
- package/dist/codex-sdk-transport.js +294 -0
- package/dist/codex-subscription.d.ts +114 -0
- package/dist/codex-subscription.js +268 -0
- package/dist/evidence-archive.d.ts +57 -0
- package/dist/evidence-archive.js +221 -0
- package/dist/execution-projection-schema.d.ts +10 -0
- package/dist/execution-projection-schema.js +30 -0
- package/dist/execution-retention-archive.d.ts +69 -0
- package/dist/execution-retention-archive.js +154 -0
- package/dist/generated/retention-v2-contract.d.ts +72 -0
- package/dist/generated/retention-v2-contract.js +105 -0
- package/dist/generated/retention-v2-json.d.ts +24 -0
- package/dist/generated/retention-v2-json.js +268 -0
- package/dist/generated/retention-v2-native-json.d.ts +2 -0
- package/dist/generated/retention-v2-native-json.js +33 -0
- package/dist/generated/retention-v2-native.d.ts +58 -0
- package/dist/generated/retention-v2-native.js +155 -0
- package/dist/generated/retention-v2-pin.d.ts +2 -0
- package/dist/generated/retention-v2-pin.js +4 -0
- package/dist/generated/retention-v2-types.d.ts +49 -0
- package/dist/generated/retention-v2-types.js +2 -0
- package/dist/generated/retention-v2-work-types.d.ts +260 -0
- package/dist/generated/retention-v2-work-types.js +13 -0
- package/dist/generated/work-v4/execution-id.d.ts +5 -0
- package/dist/generated/work-v4/execution-id.js +14 -0
- package/dist/generated/work-v4/json.d.ts +24 -0
- package/dist/generated/work-v4/json.js +268 -0
- package/dist/generated/work-v4/occurrences.d.ts +226 -0
- package/dist/generated/work-v4/occurrences.js +116 -0
- package/dist/generated/work-v4/pin.d.ts +1 -0
- package/dist/generated/work-v4/pin.js +3 -0
- package/dist/generated/work-v4/projection.d.ts +294 -0
- package/dist/generated/work-v4/projection.js +238 -0
- package/dist/generated/work-v4/reader.d.ts +24 -0
- package/dist/generated/work-v4/reader.js +109 -0
- package/dist/generated/work-v4/snapshot.d.ts +28 -0
- package/dist/generated/work-v4/snapshot.js +268 -0
- package/dist/generated/work-v4/types.d.ts +260 -0
- package/dist/generated/work-v4/types.js +13 -0
- package/dist/generated/work-v4/validation.d.ts +13 -0
- package/dist/generated/work-v4/validation.js +227 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +22 -0
- package/dist/installed-review-session.d.ts +28 -0
- package/dist/installed-review-session.js +166 -0
- package/dist/intervention-run.d.ts +403 -0
- package/dist/intervention-run.js +169 -0
- package/dist/learning-case.d.ts +12 -0
- package/dist/learning-case.js +15 -0
- package/dist/learning-journal.d.ts +18 -0
- package/dist/learning-journal.js +256 -0
- package/dist/principal-payload-port.d.ts +25 -0
- package/dist/principal-payload-port.js +40 -0
- package/dist/producer-product.d.ts +70 -0
- package/dist/producer-product.js +186 -0
- package/dist/producer-review.d.ts +53 -0
- package/dist/producer-review.js +207 -0
- package/dist/reviewed-archive-export.d.ts +42 -0
- package/dist/reviewed-archive-export.js +78 -0
- package/dist/trust-lifecycle.d.ts +128 -0
- package/dist/trust-lifecycle.js +200 -0
- package/dist/weekly-investigation.d.ts +237 -0
- package/dist/weekly-investigation.js +330 -0
- package/dist/work-candidates.d.ts +29 -0
- package/dist/work-candidates.js +78 -0
- package/dist/work-case-archive.d.ts +25 -0
- package/dist/work-case-archive.js +63 -0
- package/dist/work-case-review.d.ts +45 -0
- package/dist/work-case-review.js +220 -0
- package/dist/work-signal-cases.d.ts +15 -0
- package/dist/work-signal-cases.js +54 -0
- package/dist/work-signal-observation.d.ts +23 -0
- package/dist/work-signal-observation.js +89 -0
- package/package.json +3 -2
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import { type InterventionDraft, type InterventionQualification, type PanelVote } from '@skill-harness/core';
|
|
2
|
+
type Role = {
|
|
3
|
+
requested: string;
|
|
4
|
+
canonical: string;
|
|
5
|
+
};
|
|
6
|
+
export interface InertModelCatalogueEntry extends Role {
|
|
7
|
+
efforts: string[];
|
|
8
|
+
lineage: string;
|
|
9
|
+
}
|
|
10
|
+
/** Exact retained/inert catalogue lookup; no provider calls, alias heuristics or fallback. */
|
|
11
|
+
export declare function resolveInertRole(catalogue: InertModelCatalogueEntry[], requested: string, effort?: string): Role;
|
|
12
|
+
export interface CastingScope {
|
|
13
|
+
station: string;
|
|
14
|
+
taskClass: string;
|
|
15
|
+
risk: string;
|
|
16
|
+
population: string;
|
|
17
|
+
version: string;
|
|
18
|
+
}
|
|
19
|
+
export interface InterventionRunInput {
|
|
20
|
+
kind: 'inert-retained-v1';
|
|
21
|
+
archiveRoot: string;
|
|
22
|
+
author: string;
|
|
23
|
+
catalogue: InertModelCatalogueEntry[];
|
|
24
|
+
scope: CastingScope;
|
|
25
|
+
draft: InterventionDraft;
|
|
26
|
+
roles: {
|
|
27
|
+
proposer: Role;
|
|
28
|
+
judges: Role[];
|
|
29
|
+
subjects: Record<string, Role & {
|
|
30
|
+
effort: string;
|
|
31
|
+
}>;
|
|
32
|
+
};
|
|
33
|
+
expected: Record<string, string[]>;
|
|
34
|
+
}
|
|
35
|
+
type Retained = {
|
|
36
|
+
configurationDigest: string;
|
|
37
|
+
delivery: 'PASS' | 'NOT-MEASURED' | 'ERROR';
|
|
38
|
+
outputBase64: string;
|
|
39
|
+
cost: number | null;
|
|
40
|
+
};
|
|
41
|
+
type Vote = Omit<PanelVote, 'ordinal'>;
|
|
42
|
+
export type ProducerInterventionRunInput = Omit<InterventionRunInput, 'kind'> & {
|
|
43
|
+
kind: 'producer-ipc-v1';
|
|
44
|
+
};
|
|
45
|
+
export declare function validateProducerInterventionInput(raw: ProducerInterventionRunInput): {
|
|
46
|
+
input: InterventionRunInput | ProducerInterventionRunInput;
|
|
47
|
+
manifest: import("@skill-harness/core").InterventionManifest;
|
|
48
|
+
qualification: InterventionQualification;
|
|
49
|
+
cells: {
|
|
50
|
+
caseId: string;
|
|
51
|
+
repetition: number;
|
|
52
|
+
criteria: number;
|
|
53
|
+
}[];
|
|
54
|
+
};
|
|
55
|
+
export declare function createInterventionRun(path: string, raw: InterventionRunInput): {
|
|
56
|
+
configurations: () => {
|
|
57
|
+
armId: string;
|
|
58
|
+
requested: Record<import("@skill-harness/core").InterventionAxis, string>;
|
|
59
|
+
resolvedDeclaration: Role & {
|
|
60
|
+
effort: string;
|
|
61
|
+
};
|
|
62
|
+
inputDigest: string;
|
|
63
|
+
digest: string;
|
|
64
|
+
catalogueDigest: string;
|
|
65
|
+
lineage: string;
|
|
66
|
+
observedConfiguration: Record<string, unknown>[] | null;
|
|
67
|
+
qualification: string;
|
|
68
|
+
}[];
|
|
69
|
+
recordProducer(arm: string, index: number, hostPath: string, id: string): {
|
|
70
|
+
type: string;
|
|
71
|
+
arm: string;
|
|
72
|
+
index: number;
|
|
73
|
+
hostPath: string;
|
|
74
|
+
id: string;
|
|
75
|
+
planSha256: string;
|
|
76
|
+
configurationDigest: string;
|
|
77
|
+
serializedSha256: string;
|
|
78
|
+
requestSha256: unknown;
|
|
79
|
+
model: any;
|
|
80
|
+
effort: any;
|
|
81
|
+
instructionsSha256: string;
|
|
82
|
+
input: any;
|
|
83
|
+
outputSha256: unknown;
|
|
84
|
+
evidenceKind: string;
|
|
85
|
+
backendIdentity: null;
|
|
86
|
+
backendEffort: null;
|
|
87
|
+
instructionUse: null;
|
|
88
|
+
delivery: string;
|
|
89
|
+
settlementRef: string;
|
|
90
|
+
};
|
|
91
|
+
retain(arm: string, index: number, raw: Retained): void;
|
|
92
|
+
blind(): {
|
|
93
|
+
label: string;
|
|
94
|
+
index: number;
|
|
95
|
+
caseId: string;
|
|
96
|
+
outputBase64: string;
|
|
97
|
+
disclosure: string;
|
|
98
|
+
}[];
|
|
99
|
+
panel(arm: string, index: number, raw: Vote[][]): void;
|
|
100
|
+
finish(): {
|
|
101
|
+
assessment: import("@skill-harness/core").InterventionAssessment;
|
|
102
|
+
blindReviewId: string | null;
|
|
103
|
+
liveQualified: false;
|
|
104
|
+
};
|
|
105
|
+
casting(scope: CastingScope): {
|
|
106
|
+
qualityChoice: import("@skill-harness/core").BlindQualityChoice | null;
|
|
107
|
+
retainedCells: number;
|
|
108
|
+
requiredCells: number;
|
|
109
|
+
panels: (Record<string, unknown> | null)[];
|
|
110
|
+
cost: number | null;
|
|
111
|
+
costUnit: string;
|
|
112
|
+
latency: null;
|
|
113
|
+
measuredAcceptance: null;
|
|
114
|
+
escapes: null;
|
|
115
|
+
measuredSamples: number;
|
|
116
|
+
uncertainty: string;
|
|
117
|
+
revalidateOn: string[];
|
|
118
|
+
routingDefault: null;
|
|
119
|
+
liveQualified: boolean;
|
|
120
|
+
eligibleObserved?: boolean | undefined;
|
|
121
|
+
scope: CastingScope;
|
|
122
|
+
armId: string;
|
|
123
|
+
configuration: {
|
|
124
|
+
armId: string;
|
|
125
|
+
requested: Record<import("@skill-harness/core").InterventionAxis, string>;
|
|
126
|
+
resolvedDeclaration: Role & {
|
|
127
|
+
effort: string;
|
|
128
|
+
};
|
|
129
|
+
inputDigest: string;
|
|
130
|
+
digest: string;
|
|
131
|
+
catalogueDigest: string;
|
|
132
|
+
lineage: string;
|
|
133
|
+
observedConfiguration: Record<string, unknown>[] | null;
|
|
134
|
+
qualification: string;
|
|
135
|
+
};
|
|
136
|
+
conditionalState: "ERROR" | "NOT-MEASURED" | "MEASURED" | "FAILED" | "MISSING" | "UNRESOLVED";
|
|
137
|
+
eligibleInert: boolean;
|
|
138
|
+
}[];
|
|
139
|
+
};
|
|
140
|
+
export declare function createProducerInterventionRun(path: string, raw: ProducerInterventionRunInput, source: {
|
|
141
|
+
planSha256: string;
|
|
142
|
+
material: Record<string, {
|
|
143
|
+
skill: string;
|
|
144
|
+
prompt: string;
|
|
145
|
+
configuration: string;
|
|
146
|
+
}>;
|
|
147
|
+
cellIds: Record<string, string>;
|
|
148
|
+
}): {
|
|
149
|
+
configurations: () => {
|
|
150
|
+
armId: string;
|
|
151
|
+
requested: Record<import("@skill-harness/core").InterventionAxis, string>;
|
|
152
|
+
resolvedDeclaration: Role & {
|
|
153
|
+
effort: string;
|
|
154
|
+
};
|
|
155
|
+
inputDigest: string;
|
|
156
|
+
digest: string;
|
|
157
|
+
catalogueDigest: string;
|
|
158
|
+
lineage: string;
|
|
159
|
+
observedConfiguration: Record<string, unknown>[] | null;
|
|
160
|
+
qualification: string;
|
|
161
|
+
}[];
|
|
162
|
+
recordProducer(arm: string, index: number, hostPath: string, id: string): {
|
|
163
|
+
type: string;
|
|
164
|
+
arm: string;
|
|
165
|
+
index: number;
|
|
166
|
+
hostPath: string;
|
|
167
|
+
id: string;
|
|
168
|
+
planSha256: string;
|
|
169
|
+
configurationDigest: string;
|
|
170
|
+
serializedSha256: string;
|
|
171
|
+
requestSha256: unknown;
|
|
172
|
+
model: any;
|
|
173
|
+
effort: any;
|
|
174
|
+
instructionsSha256: string;
|
|
175
|
+
input: any;
|
|
176
|
+
outputSha256: unknown;
|
|
177
|
+
evidenceKind: string;
|
|
178
|
+
backendIdentity: null;
|
|
179
|
+
backendEffort: null;
|
|
180
|
+
instructionUse: null;
|
|
181
|
+
delivery: string;
|
|
182
|
+
settlementRef: string;
|
|
183
|
+
};
|
|
184
|
+
retain(arm: string, index: number, raw: Retained): void;
|
|
185
|
+
blind(): {
|
|
186
|
+
label: string;
|
|
187
|
+
index: number;
|
|
188
|
+
caseId: string;
|
|
189
|
+
outputBase64: string;
|
|
190
|
+
disclosure: string;
|
|
191
|
+
}[];
|
|
192
|
+
panel(arm: string, index: number, raw: Vote[][]): void;
|
|
193
|
+
finish(): {
|
|
194
|
+
assessment: import("@skill-harness/core").InterventionAssessment;
|
|
195
|
+
blindReviewId: string | null;
|
|
196
|
+
liveQualified: false;
|
|
197
|
+
};
|
|
198
|
+
casting(scope: CastingScope): {
|
|
199
|
+
qualityChoice: import("@skill-harness/core").BlindQualityChoice | null;
|
|
200
|
+
retainedCells: number;
|
|
201
|
+
requiredCells: number;
|
|
202
|
+
panels: (Record<string, unknown> | null)[];
|
|
203
|
+
cost: number | null;
|
|
204
|
+
costUnit: string;
|
|
205
|
+
latency: null;
|
|
206
|
+
measuredAcceptance: null;
|
|
207
|
+
escapes: null;
|
|
208
|
+
measuredSamples: number;
|
|
209
|
+
uncertainty: string;
|
|
210
|
+
revalidateOn: string[];
|
|
211
|
+
routingDefault: null;
|
|
212
|
+
liveQualified: boolean;
|
|
213
|
+
eligibleObserved?: boolean | undefined;
|
|
214
|
+
scope: CastingScope;
|
|
215
|
+
armId: string;
|
|
216
|
+
configuration: {
|
|
217
|
+
armId: string;
|
|
218
|
+
requested: Record<import("@skill-harness/core").InterventionAxis, string>;
|
|
219
|
+
resolvedDeclaration: Role & {
|
|
220
|
+
effort: string;
|
|
221
|
+
};
|
|
222
|
+
inputDigest: string;
|
|
223
|
+
digest: string;
|
|
224
|
+
catalogueDigest: string;
|
|
225
|
+
lineage: string;
|
|
226
|
+
observedConfiguration: Record<string, unknown>[] | null;
|
|
227
|
+
qualification: string;
|
|
228
|
+
};
|
|
229
|
+
conditionalState: "ERROR" | "NOT-MEASURED" | "MEASURED" | "FAILED" | "MISSING" | "UNRESOLVED";
|
|
230
|
+
eligibleInert: boolean;
|
|
231
|
+
}[];
|
|
232
|
+
};
|
|
233
|
+
export declare function openInterventionRun(path: string): {
|
|
234
|
+
configurations: () => {
|
|
235
|
+
armId: string;
|
|
236
|
+
requested: Record<import("@skill-harness/core").InterventionAxis, string>;
|
|
237
|
+
resolvedDeclaration: Role & {
|
|
238
|
+
effort: string;
|
|
239
|
+
};
|
|
240
|
+
inputDigest: string;
|
|
241
|
+
digest: string;
|
|
242
|
+
catalogueDigest: string;
|
|
243
|
+
lineage: string;
|
|
244
|
+
observedConfiguration: Record<string, unknown>[] | null;
|
|
245
|
+
qualification: string;
|
|
246
|
+
}[];
|
|
247
|
+
recordProducer(arm: string, index: number, hostPath: string, id: string): {
|
|
248
|
+
type: string;
|
|
249
|
+
arm: string;
|
|
250
|
+
index: number;
|
|
251
|
+
hostPath: string;
|
|
252
|
+
id: string;
|
|
253
|
+
planSha256: string;
|
|
254
|
+
configurationDigest: string;
|
|
255
|
+
serializedSha256: string;
|
|
256
|
+
requestSha256: unknown;
|
|
257
|
+
model: any;
|
|
258
|
+
effort: any;
|
|
259
|
+
instructionsSha256: string;
|
|
260
|
+
input: any;
|
|
261
|
+
outputSha256: unknown;
|
|
262
|
+
evidenceKind: string;
|
|
263
|
+
backendIdentity: null;
|
|
264
|
+
backendEffort: null;
|
|
265
|
+
instructionUse: null;
|
|
266
|
+
delivery: string;
|
|
267
|
+
settlementRef: string;
|
|
268
|
+
};
|
|
269
|
+
retain(arm: string, index: number, raw: Retained): void;
|
|
270
|
+
blind(): {
|
|
271
|
+
label: string;
|
|
272
|
+
index: number;
|
|
273
|
+
caseId: string;
|
|
274
|
+
outputBase64: string;
|
|
275
|
+
disclosure: string;
|
|
276
|
+
}[];
|
|
277
|
+
panel(arm: string, index: number, raw: Vote[][]): void;
|
|
278
|
+
finish(): {
|
|
279
|
+
assessment: import("@skill-harness/core").InterventionAssessment;
|
|
280
|
+
blindReviewId: string | null;
|
|
281
|
+
liveQualified: false;
|
|
282
|
+
};
|
|
283
|
+
casting(scope: CastingScope): {
|
|
284
|
+
qualityChoice: import("@skill-harness/core").BlindQualityChoice | null;
|
|
285
|
+
retainedCells: number;
|
|
286
|
+
requiredCells: number;
|
|
287
|
+
panels: (Record<string, unknown> | null)[];
|
|
288
|
+
cost: number | null;
|
|
289
|
+
costUnit: string;
|
|
290
|
+
latency: null;
|
|
291
|
+
measuredAcceptance: null;
|
|
292
|
+
escapes: null;
|
|
293
|
+
measuredSamples: number;
|
|
294
|
+
uncertainty: string;
|
|
295
|
+
revalidateOn: string[];
|
|
296
|
+
routingDefault: null;
|
|
297
|
+
liveQualified: boolean;
|
|
298
|
+
eligibleObserved?: boolean | undefined;
|
|
299
|
+
scope: CastingScope;
|
|
300
|
+
armId: string;
|
|
301
|
+
configuration: {
|
|
302
|
+
armId: string;
|
|
303
|
+
requested: Record<import("@skill-harness/core").InterventionAxis, string>;
|
|
304
|
+
resolvedDeclaration: Role & {
|
|
305
|
+
effort: string;
|
|
306
|
+
};
|
|
307
|
+
inputDigest: string;
|
|
308
|
+
digest: string;
|
|
309
|
+
catalogueDigest: string;
|
|
310
|
+
lineage: string;
|
|
311
|
+
observedConfiguration: Record<string, unknown>[] | null;
|
|
312
|
+
qualification: string;
|
|
313
|
+
};
|
|
314
|
+
conditionalState: "ERROR" | "NOT-MEASURED" | "MEASURED" | "FAILED" | "MISSING" | "UNRESOLVED";
|
|
315
|
+
eligibleInert: boolean;
|
|
316
|
+
}[];
|
|
317
|
+
};
|
|
318
|
+
export declare function openProducerInterventionRun(path: string): {
|
|
319
|
+
configurations: () => {
|
|
320
|
+
armId: string;
|
|
321
|
+
requested: Record<import("@skill-harness/core").InterventionAxis, string>;
|
|
322
|
+
resolvedDeclaration: Role & {
|
|
323
|
+
effort: string;
|
|
324
|
+
};
|
|
325
|
+
inputDigest: string;
|
|
326
|
+
digest: string;
|
|
327
|
+
catalogueDigest: string;
|
|
328
|
+
lineage: string;
|
|
329
|
+
observedConfiguration: Record<string, unknown>[] | null;
|
|
330
|
+
qualification: string;
|
|
331
|
+
}[];
|
|
332
|
+
recordProducer(arm: string, index: number, hostPath: string, id: string): {
|
|
333
|
+
type: string;
|
|
334
|
+
arm: string;
|
|
335
|
+
index: number;
|
|
336
|
+
hostPath: string;
|
|
337
|
+
id: string;
|
|
338
|
+
planSha256: string;
|
|
339
|
+
configurationDigest: string;
|
|
340
|
+
serializedSha256: string;
|
|
341
|
+
requestSha256: unknown;
|
|
342
|
+
model: any;
|
|
343
|
+
effort: any;
|
|
344
|
+
instructionsSha256: string;
|
|
345
|
+
input: any;
|
|
346
|
+
outputSha256: unknown;
|
|
347
|
+
evidenceKind: string;
|
|
348
|
+
backendIdentity: null;
|
|
349
|
+
backendEffort: null;
|
|
350
|
+
instructionUse: null;
|
|
351
|
+
delivery: string;
|
|
352
|
+
settlementRef: string;
|
|
353
|
+
};
|
|
354
|
+
retain(arm: string, index: number, raw: Retained): void;
|
|
355
|
+
blind(): {
|
|
356
|
+
label: string;
|
|
357
|
+
index: number;
|
|
358
|
+
caseId: string;
|
|
359
|
+
outputBase64: string;
|
|
360
|
+
disclosure: string;
|
|
361
|
+
}[];
|
|
362
|
+
panel(arm: string, index: number, raw: Vote[][]): void;
|
|
363
|
+
finish(): {
|
|
364
|
+
assessment: import("@skill-harness/core").InterventionAssessment;
|
|
365
|
+
blindReviewId: string | null;
|
|
366
|
+
liveQualified: false;
|
|
367
|
+
};
|
|
368
|
+
casting(scope: CastingScope): {
|
|
369
|
+
qualityChoice: import("@skill-harness/core").BlindQualityChoice | null;
|
|
370
|
+
retainedCells: number;
|
|
371
|
+
requiredCells: number;
|
|
372
|
+
panels: (Record<string, unknown> | null)[];
|
|
373
|
+
cost: number | null;
|
|
374
|
+
costUnit: string;
|
|
375
|
+
latency: null;
|
|
376
|
+
measuredAcceptance: null;
|
|
377
|
+
escapes: null;
|
|
378
|
+
measuredSamples: number;
|
|
379
|
+
uncertainty: string;
|
|
380
|
+
revalidateOn: string[];
|
|
381
|
+
routingDefault: null;
|
|
382
|
+
liveQualified: boolean;
|
|
383
|
+
eligibleObserved?: boolean | undefined;
|
|
384
|
+
scope: CastingScope;
|
|
385
|
+
armId: string;
|
|
386
|
+
configuration: {
|
|
387
|
+
armId: string;
|
|
388
|
+
requested: Record<import("@skill-harness/core").InterventionAxis, string>;
|
|
389
|
+
resolvedDeclaration: Role & {
|
|
390
|
+
effort: string;
|
|
391
|
+
};
|
|
392
|
+
inputDigest: string;
|
|
393
|
+
digest: string;
|
|
394
|
+
catalogueDigest: string;
|
|
395
|
+
lineage: string;
|
|
396
|
+
observedConfiguration: Record<string, unknown>[] | null;
|
|
397
|
+
qualification: string;
|
|
398
|
+
};
|
|
399
|
+
conditionalState: "ERROR" | "NOT-MEASURED" | "MEASURED" | "FAILED" | "MISSING" | "UNRESOLVED";
|
|
400
|
+
eligibleInert: boolean;
|
|
401
|
+
}[];
|
|
402
|
+
};
|
|
403
|
+
export {};
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
2
|
+
import { mkdirSync } from 'node:fs';
|
|
3
|
+
import { freezeIntervention, assertInterventionRoles, assessIntervention, interventionEvidenceDigest, collapseVotePanel } from '@skill-harness/core';
|
|
4
|
+
import { learningJournal, learningCopy, learningHash, registerLearningStore, verifyLearningStore } from './learning-journal.js';
|
|
5
|
+
import { retainArchiveSource, readArchiveSource } from './evidence-archive.js';
|
|
6
|
+
import { retainBlindIntervention, openBlindIntervention } from './blind-intervention.js';
|
|
7
|
+
const sha = (b) => createHash('sha256').update(b).digest('hex');
|
|
8
|
+
/** Exact retained/inert catalogue lookup; no provider calls, alias heuristics or fallback. */
|
|
9
|
+
export function resolveInertRole(catalogue, requested, effort) {
|
|
10
|
+
catalogue = learningCopy(catalogue);
|
|
11
|
+
if (!Array.isArray(catalogue) || catalogue.length > 64 || catalogue.some(r => !r || [r.requested, r.canonical, r.lineage].some(s => typeof s !== 'string' || !s.length || s.length > 512) || !Array.isArray(r.efforts) || r.efforts.length > 16 || r.efforts.some(e => typeof e !== 'string' || !e.length || e.length > 128)) || new Set(catalogue.map(r => r.requested)).size !== catalogue.length)
|
|
12
|
+
throw Error('invalid inert role catalogue');
|
|
13
|
+
const match = catalogue.find(r => r.requested === requested);
|
|
14
|
+
if (!match || effort !== undefined && !match.efforts.includes(effort))
|
|
15
|
+
throw Error('unresolved role/effort; no fallback');
|
|
16
|
+
return { requested, canonical: match.canonical };
|
|
17
|
+
}
|
|
18
|
+
export function validateProducerInterventionInput(raw) { return admit(raw, true); }
|
|
19
|
+
function admit(raw, producer = false) {
|
|
20
|
+
const input = learningCopy(raw);
|
|
21
|
+
if (input.kind !== (producer ? 'producer-ipc-v1' : 'inert-retained-v1'))
|
|
22
|
+
throw Error('only explicit inert retained or opt-in producer transport supported');
|
|
23
|
+
if (typeof input.author !== 'string' || !input.author.length || input.author.length > 512)
|
|
24
|
+
throw Error('explicit operator required');
|
|
25
|
+
const manifest = freezeIntervention(input.draft), roles = input.roles;
|
|
26
|
+
if (manifest.arms.length > 4 || manifest.cases.reduce((n, c) => n + c.reps, 0) > 64)
|
|
27
|
+
throw Error('bounded inert charter required');
|
|
28
|
+
if (!input.scope || Object.keys(input.scope).sort().join() !== 'population,risk,station,taskClass,version' || Object.values(input.scope).some(v => typeof v !== 'string' || !v.length || v.length > 512))
|
|
29
|
+
throw Error('closed casting scope required');
|
|
30
|
+
if (!roles || !Array.isArray(roles.judges) || roles.judges.length !== 3)
|
|
31
|
+
throw Error('three declared independent panel roles required');
|
|
32
|
+
const qualification = { manifestId: manifest.id, proposer: roles.proposer, judge: roles.judges[0], subjects: Object.fromEntries(Object.entries(roles.subjects).map(([id, r]) => [id, { requested: r.requested, canonical: r.canonical }])), evidenceDigests: {}, artifacts: new Map() };
|
|
33
|
+
assertInterventionRoles(manifest, qualification);
|
|
34
|
+
for (const r of [roles.proposer, ...roles.judges, ...Object.values(roles.subjects)]) {
|
|
35
|
+
const resolved = resolveInertRole(input.catalogue, r.requested, 'effort' in r ? String(r.effort) : undefined);
|
|
36
|
+
if (resolved.canonical !== r.canonical)
|
|
37
|
+
throw Error('role declaration differs from exact catalogue resolution');
|
|
38
|
+
}
|
|
39
|
+
const reserved = new Set([roles.proposer.canonical, ...roles.judges.map(j => j.canonical)]);
|
|
40
|
+
if (reserved.size !== 4 || roles.judges.some(j => [j.requested, j.canonical].some(s => typeof s !== 'string' || !s.length || s.length > 512 || /[\u0000-\u001f\u007f]/.test(s))) || manifest.arms.some(a => reserved.has(roles.subjects[a.id].canonical) || roles.subjects[a.id].effort !== a.configuration.effort))
|
|
41
|
+
throw Error('panel role conflict or unresolved effort');
|
|
42
|
+
const cells = manifest.cases.flatMap(c => Array.from({ length: c.reps }, (_, repetition) => ({ caseId: c.id, repetition, criteria: c.criteria })));
|
|
43
|
+
if (Object.keys(input.expected).sort().join() !== manifest.arms.map(a => a.id).sort().join() || manifest.arms.some(a => input.expected[a.id]?.length !== cells.length || input.expected[a.id].some(h => !/^[a-f0-9]{64}$/.test(h))))
|
|
44
|
+
throw Error('frozen objective hashes required for every cell');
|
|
45
|
+
return { input, manifest, qualification, cells };
|
|
46
|
+
}
|
|
47
|
+
export function createInterventionRun(path, raw) { return createRun(path, raw); }
|
|
48
|
+
export function createProducerInterventionRun(path, raw, source) { return createRun(path, raw, learningCopy(source)); }
|
|
49
|
+
function createRun(path, raw, source) {
|
|
50
|
+
const { input, manifest, cells } = admit(raw, !!source); // No archive, directory, output or panel effect before role admission.
|
|
51
|
+
if (source) {
|
|
52
|
+
const keys = manifest.arms.flatMap(a => cells.map((_, i) => `${a.id}:${i}`)).sort();
|
|
53
|
+
if (Object.keys(source).sort().join() !== 'cellIds,material,planSha256' || !/^[a-f0-9]{64}$/.test(source.planSha256) || Object.keys(source.cellIds).sort().join() !== keys.join() || new Set(Object.values(source.cellIds)).size !== keys.length || Object.values(source.cellIds).some(id => !/^[a-zA-Z0-9_-]{1,64}$/.test(id)) || Object.keys(source.material).sort().join() !== manifest.arms.map(a => a.id).sort().join() || manifest.arms.some(a => { const m = source.material[a.id]; return !m || Object.keys(m).sort().join() !== 'configuration,prompt,skill' || Object.values(m).some(v => typeof v !== 'string') || sha(m.skill) !== a.configuration.skill || sha(m.prompt) !== a.configuration.prompt || sha(m.configuration) !== a.configuration.configuration; }))
|
|
54
|
+
throw Error('frozen producer source binding required');
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
mkdirSync(input.archiveRoot, { mode: 0o700 });
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
if (e.code !== 'EEXIST')
|
|
61
|
+
throw e;
|
|
62
|
+
}
|
|
63
|
+
const binding = learningHash(source ? { input, source } : input);
|
|
64
|
+
registerLearningStore(input.archiveRoot, 'intervention', manifest.id, path, binding);
|
|
65
|
+
learningJournal(path, { type: source ? 'producer-intervention-run-v1' : 'intervention-run-v1', input, ...(source ? { source } : {}), seed: randomBytes(32).toString('hex') });
|
|
66
|
+
return openRun(path, !!source);
|
|
67
|
+
}
|
|
68
|
+
export function openInterventionRun(path) { return openRun(path); }
|
|
69
|
+
export function openProducerInterventionRun(path) { return openRun(path, true); }
|
|
70
|
+
function openRun(path, producer = false) {
|
|
71
|
+
const store = learningJournal(path), initial = store.read()[0].value;
|
|
72
|
+
if (initial.type !== (producer ? 'producer-intervention-run-v1' : 'intervention-run-v1') || typeof initial.seed !== 'string' || !/^[a-f0-9]{64}$/.test(initial.seed))
|
|
73
|
+
throw Error('invalid intervention owner');
|
|
74
|
+
const { input, manifest, qualification, cells } = admit(initial.input, producer);
|
|
75
|
+
const artifacts = new Map();
|
|
76
|
+
qualification.artifacts = artifacts;
|
|
77
|
+
const history = () => { verifyLearningStore(input.archiveRoot, 'intervention', manifest.id, path, learningHash(producer ? { input, source: initial.source } : input)); return store.read(); };
|
|
78
|
+
const append = (prior, value) => store.append(prior, value);
|
|
79
|
+
const configurations = () => manifest.arms.map(a => ({ armId: a.id, requested: learningCopy(a.configuration), resolvedDeclaration: learningCopy(input.roles.subjects[a.id]), inputDigest: manifest.inputDigest, digest: learningHash({ configuration: a.configuration, inputDigest: manifest.inputDigest }), catalogueDigest: learningHash(input.catalogue), lineage: input.catalogue.find(r => r.requested === a.configuration.model).lineage, observedConfiguration: producer ? history().filter(e => e.value.type === 'producer-configuration' && e.value.arm === a.id).map(e => e.value) : null, qualification: producer ? 'original-producer-sdk-observed; backend facts unknown' : 'inert-host-declaration-only' }));
|
|
80
|
+
const find = (type, arm, index) => history().find(e => e.value.type === type && e.value.arm === arm && e.value.index === index)?.value;
|
|
81
|
+
const check = (arm, index) => { if (!manifest.arms.some(a => a.id === arm) || !Number.isSafeInteger(index) || !cells[index])
|
|
82
|
+
throw Error('unfrozen arm/cell'); };
|
|
83
|
+
const label = (arm) => sha(String(initial.seed) + ':' + arm).slice(0, 24);
|
|
84
|
+
const bytes = (record) => { const read = readArchiveSource(input.archiveRoot, String(record.manifestId)); if (read.status !== 'available' || !read.bytes || sha(read.bytes) !== record.artifactSha256)
|
|
85
|
+
throw Error('retained arm artifact missing or changed'); return read.bytes; };
|
|
86
|
+
const api = { configurations,
|
|
87
|
+
recordProducer(arm, index, hostPath, id) {
|
|
88
|
+
if (!producer)
|
|
89
|
+
throw Error('producer observation requires opt-in owner');
|
|
90
|
+
check(arm, index);
|
|
91
|
+
if (find('producer-configuration', arm, index))
|
|
92
|
+
throw Error('configuration already observed');
|
|
93
|
+
const rows = learningJournal(hostPath).read(), values = rows.map(r => r.value), source = initial.source, cfg = manifest.arms.find(a => a.id === arm).configuration;
|
|
94
|
+
const observed = values.find(v => v.type === 'observation' && v.id === id), wire = values.find(v => v.type === 'sdk-wire-observed' && v.id === id), bound = values.find(v => v.type === 'producer-ipc-bound' && v.id === id), settled = values.find(v => v.type === 'producer-ipc-settled' && v.id === id);
|
|
95
|
+
if (source.cellIds[`${arm}:${index}`] !== id || !observed || !wire || !bound || !settled || bound.bindingHash !== settled.bindingHash || bound.binding.charterSha256 !== source.planSha256)
|
|
96
|
+
throw Error('original settled serializer evidence required');
|
|
97
|
+
const body = JSON.parse(Buffer.from(String(wire.serializedBase64), 'base64').toString('utf8')), instructions = source.material[arm].skill + '\n' + source.material[arm].prompt;
|
|
98
|
+
if (body.model !== cfg.model || body.reasoning?.effort !== cfg.effort || body.instructions !== instructions)
|
|
99
|
+
throw Error('actual serialized arm differs from frozen material');
|
|
100
|
+
const receipt = { type: 'producer-configuration', arm, index, hostPath, id, planSha256: source.planSha256, configurationDigest: configurations().find(c => c.armId === arm).digest, serializedSha256: sha(Buffer.from(String(wire.serializedBase64), 'base64')), requestSha256: wire.requestSha256, model: body.model, effort: body.reasoning.effort, instructionsSha256: sha(instructions), input: body.input, outputSha256: observed.outputSha256, evidenceKind: 'sdk-serialized-request', backendIdentity: null, backendEffort: null, instructionUse: null, delivery: 'PASS', settlementRef: rows.find(r => r.value === settled).id };
|
|
101
|
+
append(history().at(-1).id, receipt);
|
|
102
|
+
return receipt;
|
|
103
|
+
},
|
|
104
|
+
retain(arm, index, raw) {
|
|
105
|
+
check(arm, index);
|
|
106
|
+
const request = learningCopy(raw), records = history();
|
|
107
|
+
if (find('retained', arm, index) || find('retain-claimed', arm, index))
|
|
108
|
+
throw Error('arm cell already claimed; no automatic retry');
|
|
109
|
+
if (request.configurationDigest !== configurations().find(c => c.armId === arm).digest || !['PASS', 'NOT-MEASURED', 'ERROR'].includes(request.delivery) || !(request.cost === null || Number.isFinite(request.cost) && request.cost >= 0) || typeof request.outputBase64 !== 'string' || request.outputBase64.length > 87384)
|
|
110
|
+
throw Error('configuration/delivery/retained input mismatch');
|
|
111
|
+
const output = Buffer.from(request.outputBase64, 'base64');
|
|
112
|
+
if (output.toString('base64') !== request.outputBase64 || output.length > 65536)
|
|
113
|
+
throw Error('bounded canonical output required');
|
|
114
|
+
if (producer && request.delivery === 'PASS' && find('producer-configuration', arm, index)?.outputSha256 !== sha(output))
|
|
115
|
+
throw Error('retained output lacks original settled source');
|
|
116
|
+
const claim = append(records.at(-1).id, { type: 'retain-claimed', arm, index, requestDigest: learningHash(request) });
|
|
117
|
+
const source = retainArchiveSource(input.archiveRoot, { sourceId: `${producer ? 'producer' : 'inert'}-${manifest.id}-${arm}-${index}`, parser: { id: producer ? 'producer-variant-output' : 'inert-variant-output', version: '1' }, retention: 'exact', bytes: output });
|
|
118
|
+
append(claim.id, { type: 'retained', arm, index, manifestId: source.manifestId, artifactSha256: sha(output), configurationDigest: request.configurationDigest, delivery: request.delivery, objective: request.delivery === 'NOT-MEASURED' ? 'NOT-MEASURED' : request.delivery === 'ERROR' ? 'ERROR' : sha(output) === input.expected[arm][index] ? 'PASS' : 'FAIL', cost: request.cost });
|
|
119
|
+
},
|
|
120
|
+
blind() { return manifest.arms.flatMap(a => cells.flatMap((c, index) => { const r = find('retained', a.id, index); return r?.delivery === 'PASS' && r.objective === 'PASS' ? [{ label: label(a.id), index, caseId: c.caseId, outputBase64: Buffer.from(bytes(r)).toString('base64'), disclosure: producer ? 'artifact content may reveal identity; original source observations, not live blinding qualification' : 'artifact content may reveal identity; fixture transport, not live blinding qualification' }] : []; })).sort((a, b) => a.label.localeCompare(b.label) || a.index - b.index); },
|
|
121
|
+
panel(arm, index, raw) {
|
|
122
|
+
check(arm, index);
|
|
123
|
+
const records = history(), r = find('retained', arm, index);
|
|
124
|
+
if (!r || r.delivery !== 'PASS' || r.objective !== 'PASS')
|
|
125
|
+
throw Error('objective/delivery gate blocks panel');
|
|
126
|
+
bytes(r);
|
|
127
|
+
if (find('panel', arm, index))
|
|
128
|
+
throw Error('panel already recorded');
|
|
129
|
+
const votes = learningCopy(raw);
|
|
130
|
+
if (!Array.isArray(votes) || votes.length !== cells[index].criteria)
|
|
131
|
+
throw Error('criterion panel cardinality');
|
|
132
|
+
const panels = votes.map(row => { if (!Array.isArray(row) || ![2, 3].includes(row.length) || row.some(v => Object.keys(v).sort().join() !== 'suspect,verdict' || typeof v.suspect !== 'boolean' || !['PASS', 'FAIL', 'ERROR', 'NOT-MEASURED', 'JUDGE-AMBIGUOUS'].includes(v.verdict)))
|
|
133
|
+
throw Error('invalid retained votes'); const ranked = row.map((v, i) => ({ ...v, ordinal: i + 1 })); const split = collapseVotePanel(ranked.slice(0, 2)).split; if (split !== (row.length === 3))
|
|
134
|
+
throw Error('tie-break required exactly for clean split'); return { votes: ranked.map((v, i) => ({ ...v, role: input.roles.judges[i] })), collapse: collapseVotePanel(ranked) }; });
|
|
135
|
+
append(records.at(-1).id, { type: 'panel', arm, index, label: label(arm), panels });
|
|
136
|
+
},
|
|
137
|
+
finish() {
|
|
138
|
+
if (producer && (!history().some(e => e.value.type === 'producer-plan-settled') || history().some(e => e.value.type === 'producer-plan-failed')))
|
|
139
|
+
throw Error('whole producer plan unsettled');
|
|
140
|
+
const evidence = manifest.arms.flatMap(a => {
|
|
141
|
+
const retained = cells.map((_, i) => find('retained', a.id, i));
|
|
142
|
+
if (retained.some(r => !r))
|
|
143
|
+
return [];
|
|
144
|
+
return [{ armId: a.id, inputDigest: manifest.inputDigest, artifactDigests: [...new Set(retained.map(r => String(r.artifactSha256)))], cost: retained.some(r => r.cost === null) ? null : retained.reduce((n, r) => n + Number(r.cost), 0), costUnit: manifest.resourceMetric, cells: retained.map((r, i) => { artifacts.set(String(r.artifactSha256), bytes(r)); const panel = find('panel', a.id, i); return { ...cells[i], criteria: r.objective === 'PASS' ? Array.from({ length: cells[i].criteria }, (_, k) => panel?.panels?.[k]?.collapse.verdict ?? 'UNKNOWN') : [], delivery: r.delivery, objective: r.objective, suspect: false, artifactSha256: String(r.artifactSha256) }; }) }];
|
|
145
|
+
});
|
|
146
|
+
qualification.evidenceDigests = Object.fromEntries(evidence.map(e => [e.armId, interventionEvidenceDigest(e)]));
|
|
147
|
+
const assessment = assessIntervention(manifest, evidence, qualification), records = history();
|
|
148
|
+
const old = records.find(e => e.value.type === 'finished');
|
|
149
|
+
if (old)
|
|
150
|
+
return learningCopy(old.value.result);
|
|
151
|
+
const result = { assessment, blindReviewId: null, liveQualified: false };
|
|
152
|
+
if (assessment.complete) {
|
|
153
|
+
if (records.some(e => e.value.type === 'finish-claimed'))
|
|
154
|
+
throw Error('finish pending or unknown; no automatic retry');
|
|
155
|
+
const claim = append(records.at(-1).id, { type: 'finish-claimed' });
|
|
156
|
+
if (assessment.arms.some(a => a.eligible))
|
|
157
|
+
result.blindReviewId = retainBlindIntervention(input.archiveRoot, manifest, evidence, qualification, input.author);
|
|
158
|
+
append(claim.id, { type: 'finished', result });
|
|
159
|
+
}
|
|
160
|
+
return result;
|
|
161
|
+
},
|
|
162
|
+
casting(scope) { if (learningHash(scope) !== learningHash(input.scope))
|
|
163
|
+
throw Error('casting scope/version requires revalidation'); const result = api.finish(); if (!result.blindReviewId)
|
|
164
|
+
throw Error('complete quality choice required before casting'); const blind = openBlindIntervention(input.archiveRoot, result.blindReviewId, input.author); if (!blind.quality())
|
|
165
|
+
throw Error('quality choice required before casting reveal'); blind.reveal(); return result.assessment.arms.map(arm => ({ scope: learningCopy(scope), armId: arm.armId, configuration: configurations().find(c => c.armId === arm.armId), conditionalState: arm.state, eligibleInert: !producer && arm.eligible, ...(producer ? { eligibleObserved: arm.eligible } : {}), qualityChoice: blind.quality(), retainedCells: cells.filter((_, i) => find('retained', arm.armId, i)).length, requiredCells: cells.length, panels: cells.map((_, i) => find('panel', arm.armId, i) ?? null), cost: arm.cost, costUnit: arm.costUnit, latency: null, measuredAcceptance: null, escapes: null, measuredSamples: 0, uncertainty: 'unqualified inert/retained protocol; panel agreement is not accuracy', revalidateOn: ['scope', 'model/effort/skill/prompt/configuration', 'rubric/judge policy', 'independent labels', 'delivery/effect transport'], routingDefault: null, liveQualified: false })); }
|
|
166
|
+
};
|
|
167
|
+
return api;
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=intervention-run.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface LearningCaseReference {
|
|
2
|
+
version: 2 | 3;
|
|
3
|
+
batchId: string;
|
|
4
|
+
manifestId: string;
|
|
5
|
+
decisionId: string;
|
|
6
|
+
}
|
|
7
|
+
/** Reads the actual selected-batch decision writer, not a caller-authored confirmation boolean. */
|
|
8
|
+
export declare function readLearningCase(root: string, input: LearningCaseReference): {
|
|
9
|
+
candidate: import("@skill-harness/core").WorkCaptureCaseV2 | import("@skill-harness/core").WorkCaptureCaseV3;
|
|
10
|
+
current: import("@skill-harness/core").WorkCaseDecision | null;
|
|
11
|
+
matched: boolean;
|
|
12
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createWorkCaseReviewer, createWorkSignalReviewer } from './work-case-review.js';
|
|
2
|
+
import { readWorkCandidate } from './work-case-archive.js';
|
|
3
|
+
import { readWorkSignalCase } from './work-signal-cases.js';
|
|
4
|
+
import { learningCopy } from './learning-journal.js';
|
|
5
|
+
/** Reads the actual selected-batch decision writer, not a caller-authored confirmation boolean. */
|
|
6
|
+
export function readLearningCase(root, input) {
|
|
7
|
+
const c = learningCopy(input);
|
|
8
|
+
if (Object.keys(c).sort().join() !== 'batchId,decisionId,manifestId,version' || (c.version !== 2 && c.version !== 3))
|
|
9
|
+
throw Error('explicit selected case reference required');
|
|
10
|
+
const review = c.version === 3 ? createWorkSignalReviewer(root, c.batchId, 'learning-reader') : createWorkCaseReviewer(root, c.batchId, 'learning-reader');
|
|
11
|
+
const current = review.history(c.manifestId).at(-1) ?? null;
|
|
12
|
+
const candidate = c.version === 3 ? readWorkSignalCase(root, c.manifestId).candidate : readWorkCandidate(root, c.manifestId);
|
|
13
|
+
return { candidate, current, matched: current?.id === c.decisionId };
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=learning-case.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare function learningJson(value: unknown): string;
|
|
2
|
+
export declare const learningHash: (value: unknown) => string;
|
|
3
|
+
export declare const learningCopy: <T>(value: T) => T;
|
|
4
|
+
export interface LearningEvent {
|
|
5
|
+
id: string;
|
|
6
|
+
prior: string | null;
|
|
7
|
+
value: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export declare function learningFile(path: string, limit?: number): Buffer;
|
|
10
|
+
/** Shared durable CAS for the weekly supervisor and trust lifecycle. Trusted cooperative filesystem,
|
|
11
|
+
* not hostile same-UID rollback protection. A stranded claim is never automatically recovered. */
|
|
12
|
+
export declare function learningJournal(path: string, initial?: Record<string, unknown>): {
|
|
13
|
+
read: () => LearningEvent[];
|
|
14
|
+
append(prior: string, value: Record<string, unknown>): LearningEvent;
|
|
15
|
+
};
|
|
16
|
+
/** One authoritative store per weekly key/policy in this archive; a renamed directory cannot refill it. */
|
|
17
|
+
export declare function registerLearningStore(root: string, kind: 'weekly' | 'trust' | 'intervention' | 'access', key: string, target: string, binding: string): void;
|
|
18
|
+
export declare function verifyLearningStore(root: string, kind: 'weekly' | 'trust' | 'intervention' | 'access', key: string, target: string, binding: string): void;
|