@skill-harness/adapters 0.16.0 → 0.18.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.
Files changed (114) hide show
  1. package/dist/index.d.ts +0 -28
  2. package/dist/index.js +0 -28
  3. package/dist/pi.js +21 -133
  4. package/package.json +2 -3
  5. package/dist/archive-access.d.ts +0 -58
  6. package/dist/archive-access.js +0 -61
  7. package/dist/archive-checkpoint.d.ts +0 -47
  8. package/dist/archive-checkpoint.js +0 -116
  9. package/dist/archive-facts.d.ts +0 -19
  10. package/dist/archive-facts.js +0 -20
  11. package/dist/archive-observer.d.ts +0 -21
  12. package/dist/archive-observer.js +0 -79
  13. package/dist/archive-policy.d.ts +0 -107
  14. package/dist/archive-policy.js +0 -135
  15. package/dist/archive-read-capability.d.ts +0 -49
  16. package/dist/archive-read-capability.js +0 -45
  17. package/dist/archive-retention-policy.d.ts +0 -52
  18. package/dist/archive-retention-policy.js +0 -49
  19. package/dist/archived-work.d.ts +0 -45
  20. package/dist/archived-work.js +0 -78
  21. package/dist/blind-intervention.d.ts +0 -35
  22. package/dist/blind-intervention.js +0 -218
  23. package/dist/codex-diagnostic-model.d.ts +0 -14
  24. package/dist/codex-diagnostic-model.js +0 -39
  25. package/dist/codex-host-observer.d.ts +0 -111
  26. package/dist/codex-host-observer.js +0 -309
  27. package/dist/codex-https.d.ts +0 -7
  28. package/dist/codex-https.js +0 -221
  29. package/dist/codex-model-profile.d.ts +0 -38
  30. package/dist/codex-model-profile.js +0 -54
  31. package/dist/codex-producer-ipc.d.ts +0 -55
  32. package/dist/codex-producer-ipc.js +0 -67
  33. package/dist/codex-sdk-transport.d.ts +0 -50
  34. package/dist/codex-sdk-transport.js +0 -294
  35. package/dist/codex-subscription.d.ts +0 -114
  36. package/dist/codex-subscription.js +0 -268
  37. package/dist/evidence-archive.d.ts +0 -65
  38. package/dist/evidence-archive.js +0 -225
  39. package/dist/execution-projection-schema.d.ts +0 -10
  40. package/dist/execution-projection-schema.js +0 -30
  41. package/dist/execution-retention-archive.d.ts +0 -69
  42. package/dist/execution-retention-archive.js +0 -154
  43. package/dist/generated/retention-v2-contract.d.ts +0 -72
  44. package/dist/generated/retention-v2-contract.js +0 -105
  45. package/dist/generated/retention-v2-json.d.ts +0 -24
  46. package/dist/generated/retention-v2-json.js +0 -268
  47. package/dist/generated/retention-v2-native-json.d.ts +0 -2
  48. package/dist/generated/retention-v2-native-json.js +0 -33
  49. package/dist/generated/retention-v2-native.d.ts +0 -58
  50. package/dist/generated/retention-v2-native.js +0 -155
  51. package/dist/generated/retention-v2-pin.d.ts +0 -2
  52. package/dist/generated/retention-v2-pin.js +0 -4
  53. package/dist/generated/retention-v2-types.d.ts +0 -49
  54. package/dist/generated/retention-v2-types.js +0 -2
  55. package/dist/generated/retention-v2-work-types.d.ts +0 -260
  56. package/dist/generated/retention-v2-work-types.js +0 -13
  57. package/dist/generated/work-v4/execution-id.d.ts +0 -5
  58. package/dist/generated/work-v4/execution-id.js +0 -14
  59. package/dist/generated/work-v4/json.d.ts +0 -24
  60. package/dist/generated/work-v4/json.js +0 -268
  61. package/dist/generated/work-v4/occurrences.d.ts +0 -226
  62. package/dist/generated/work-v4/occurrences.js +0 -116
  63. package/dist/generated/work-v4/pin.d.ts +0 -1
  64. package/dist/generated/work-v4/pin.js +0 -3
  65. package/dist/generated/work-v4/projection.d.ts +0 -294
  66. package/dist/generated/work-v4/projection.js +0 -238
  67. package/dist/generated/work-v4/reader.d.ts +0 -24
  68. package/dist/generated/work-v4/reader.js +0 -109
  69. package/dist/generated/work-v4/snapshot.d.ts +0 -28
  70. package/dist/generated/work-v4/snapshot.js +0 -268
  71. package/dist/generated/work-v4/types.d.ts +0 -260
  72. package/dist/generated/work-v4/types.js +0 -13
  73. package/dist/generated/work-v4/validation.d.ts +0 -13
  74. package/dist/generated/work-v4/validation.js +0 -227
  75. package/dist/installed-review-session.d.ts +0 -28
  76. package/dist/installed-review-session.js +0 -166
  77. package/dist/intervention-run.d.ts +0 -403
  78. package/dist/intervention-run.js +0 -169
  79. package/dist/learning-case.d.ts +0 -12
  80. package/dist/learning-case.js +0 -15
  81. package/dist/learning-journal.d.ts +0 -18
  82. package/dist/learning-journal.js +0 -256
  83. package/dist/learning-lifecycle.d.ts +0 -28
  84. package/dist/learning-lifecycle.js +0 -66
  85. package/dist/learning-trust-setup.d.ts +0 -64
  86. package/dist/learning-trust-setup.js +0 -55
  87. package/dist/learning-workspace.d.ts +0 -930
  88. package/dist/learning-workspace.js +0 -663
  89. package/dist/principal-payload-port.d.ts +0 -25
  90. package/dist/principal-payload-port.js +0 -40
  91. package/dist/producer-product.d.ts +0 -70
  92. package/dist/producer-product.js +0 -186
  93. package/dist/producer-review.d.ts +0 -53
  94. package/dist/producer-review.js +0 -207
  95. package/dist/prompt-capture-extension.d.ts +0 -10
  96. package/dist/prompt-capture-extension.js +0 -26
  97. package/dist/prompt-provenance.d.ts +0 -22
  98. package/dist/prompt-provenance.js +0 -146
  99. package/dist/reviewed-archive-export.d.ts +0 -42
  100. package/dist/reviewed-archive-export.js +0 -78
  101. package/dist/trust-lifecycle.d.ts +0 -152
  102. package/dist/trust-lifecycle.js +0 -209
  103. package/dist/weekly-investigation.d.ts +0 -237
  104. package/dist/weekly-investigation.js +0 -330
  105. package/dist/work-candidates.d.ts +0 -29
  106. package/dist/work-candidates.js +0 -78
  107. package/dist/work-case-archive.d.ts +0 -25
  108. package/dist/work-case-archive.js +0 -63
  109. package/dist/work-case-review.d.ts +0 -45
  110. package/dist/work-case-review.js +0 -220
  111. package/dist/work-signal-cases.d.ts +0 -15
  112. package/dist/work-signal-cases.js +0 -54
  113. package/dist/work-signal-observation.d.ts +0 -23
  114. package/dist/work-signal-observation.js +0 -89
@@ -1,256 +0,0 @@
1
- import { constants, openSync, closeSync, readSync, writeSync, fstatSync, lstatSync, fsyncSync, mkdirSync, unlinkSync } from 'node:fs';
2
- import { createHash, randomUUID } from 'node:crypto';
3
- import { types } from 'node:util';
4
- import { isAbsolute, join, dirname, parse, resolve } from 'node:path';
5
- import { interventionCanonicalJson } from '@skill-harness/core';
6
- export function learningJson(value) {
7
- const limit = 2 * 1024 * 1024, cache = new WeakMap(), visiting = new WeakSet();
8
- const size = (v, depth) => {
9
- if (depth > 16)
10
- throw Error('learning JSON depth bound');
11
- if (v === null || typeof v === 'boolean' || typeof v === 'string' || typeof v === 'number' && Number.isFinite(v)) {
12
- if (typeof v === 'string' && Buffer.byteLength(v) > limit)
13
- throw Error('learning JSON byte bound');
14
- const bytes = Buffer.byteLength(JSON.stringify(v));
15
- if (bytes > limit)
16
- throw Error('learning JSON byte bound');
17
- return { bytes, height: 0 };
18
- }
19
- if (!v || typeof v !== 'object')
20
- throw Error('plain learning JSON required');
21
- if (types.isProxy(v))
22
- throw Error('learning proxy refused');
23
- const old = cache.get(v);
24
- if (old) {
25
- if (depth + old.height > 16)
26
- throw Error('learning JSON depth bound');
27
- return old;
28
- }
29
- if (visiting.has(v))
30
- throw Error('cyclic learning JSON refused');
31
- visiting.add(v);
32
- const array = Array.isArray(v), prototype = Object.getPrototypeOf(v), descriptors = Object.getOwnPropertyDescriptors(v);
33
- if (array ? prototype !== Array.prototype : prototype !== Object.prototype && prototype !== null)
34
- throw Error('plain learning JSON required');
35
- const keys = Reflect.ownKeys(descriptors);
36
- if (array && (v.length > 4096 || keys.length !== v.length + 1))
37
- throw Error('dense bounded learning array required');
38
- const fields = array ? Array.from({ length: v.length }, (_, i) => String(i)) : keys;
39
- let bytes = 2, height = 0;
40
- for (let i = 0; i < fields.length; i++) {
41
- const key = fields[i];
42
- if (typeof key !== 'string')
43
- throw Error('plain learning property required');
44
- const d = descriptors[key];
45
- if (!d || !('value' in d) || !d.enumerable)
46
- throw Error('plain learning property required');
47
- const child = size(d.value, depth + 1);
48
- bytes += child.bytes + (i ? 1 : 0) + (array ? 0 : Buffer.byteLength(JSON.stringify(key)) + 1);
49
- height = Math.max(height, child.height + 1);
50
- if (bytes > limit)
51
- throw Error('learning JSON byte bound');
52
- }
53
- visiting.delete(v);
54
- const result = { bytes, height };
55
- cache.set(v, result);
56
- return result;
57
- };
58
- size(value, 0);
59
- return interventionCanonicalJson(value);
60
- }
61
- export const learningHash = (value) => createHash('sha256').update(learningJson(value)).digest('hex');
62
- export const learningCopy = (value) => JSON.parse(learningJson(value));
63
- const LIMIT = 4 * 1024 * 1024;
64
- function directory(path) {
65
- if (!isAbsolute(path))
66
- throw Error('absolute learning directory required');
67
- for (let p = path;; p = dirname(p)) {
68
- const s = lstatSync(p);
69
- if (!s.isDirectory() || s.isSymbolicLink())
70
- throw Error('learning directory substitution');
71
- if (p === parse(p).root)
72
- break;
73
- }
74
- const s = lstatSync(path);
75
- if ((s.mode & 0o077) || (process.getuid && s.uid !== process.getuid()))
76
- throw Error('private owned learning directory required');
77
- }
78
- function sync(path) { const fd = openSync(path, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW); try {
79
- fsyncSync(fd);
80
- }
81
- finally {
82
- closeSync(fd);
83
- } }
84
- export function learningFile(path, limit = 1024 * 1024) {
85
- if (!constants.O_NOFOLLOW || !constants.O_NONBLOCK)
86
- throw Error('required safe file flags unavailable');
87
- if (!isAbsolute(path))
88
- throw Error('absolute learning file required');
89
- // Reject every symlink ancestor, but do not require public parent directories to be private.
90
- for (let p = dirname(path);; p = dirname(p)) {
91
- const s = lstatSync(p);
92
- if (!s.isDirectory() || s.isSymbolicLink())
93
- throw Error('learning file ancestor substitution');
94
- if (p === parse(p).root)
95
- break;
96
- }
97
- const fd = openSync(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
98
- try {
99
- const s = fstatSync(fd);
100
- if (!s.isFile() || s.nlink !== 1 || s.size > limit)
101
- throw Error('bounded regular learning file required');
102
- const out = Buffer.alloc(limit + 1);
103
- let n = 0;
104
- while (n < out.length) {
105
- const k = readSync(fd, out, n, out.length - n, n);
106
- if (!k)
107
- break;
108
- n += k;
109
- }
110
- if (n > limit)
111
- throw Error('learning file bound exceeded');
112
- return out.subarray(0, n);
113
- }
114
- finally {
115
- closeSync(fd);
116
- }
117
- }
118
- /** Shared durable CAS for the weekly supervisor and trust lifecycle. Trusted cooperative filesystem,
119
- * not hostile same-UID rollback protection. A stranded claim is never automatically recovered. */
120
- export function learningJournal(path, initial) {
121
- if (!constants.O_NOFOLLOW || !constants.O_NONBLOCK || !constants.O_DIRECTORY)
122
- throw Error('required safe journal flags unavailable');
123
- if (initial !== undefined) {
124
- directory(dirname(path));
125
- mkdirSync(path, { mode: 0o700 });
126
- directory(path);
127
- const value = learningCopy(initial), body = { prior: null, value }, record = { ...body, id: learningHash(body) };
128
- const fd = openSync(join(path, 'events.jsonl'), constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
129
- try {
130
- writeAll(fd, Buffer.from(learningJson(record) + '\n'));
131
- fsyncSync(fd);
132
- }
133
- finally {
134
- closeSync(fd);
135
- }
136
- sync(path);
137
- sync(dirname(path));
138
- }
139
- directory(path);
140
- const identity = lstatSync(path), file = join(path, 'events.jsonl');
141
- const check = () => { directory(path); const s = lstatSync(path); if (s.dev !== identity.dev || s.ino !== identity.ino)
142
- throw Error('learning directory identity changed'); };
143
- const read = () => {
144
- check();
145
- const stat = lstatSync(file);
146
- if ((stat.mode & 0o077) || (process.getuid && stat.uid !== process.getuid()))
147
- throw Error('private learning journal required');
148
- const text = learningFile(file, LIMIT).toString('utf8');
149
- if (!text.endsWith('\n'))
150
- throw Error('learning history incomplete');
151
- const lines = text.slice(0, -1).split('\n');
152
- if (!lines.length || lines.length > 4096)
153
- throw Error('learning history bound');
154
- let prior = null;
155
- return lines.map(line => { const r = JSON.parse(line); if (learningJson(r) !== line || Object.keys(r).sort().join() !== 'id,prior,value' || r.prior !== prior || r.id !== learningHash({ prior, value: r.value }))
156
- throw Error('learning history identity mismatch'); prior = r.id; return r; });
157
- };
158
- read();
159
- return { read, append(prior, value) {
160
- check();
161
- const lock = join(path, 'writer.lock'), token = randomUUID();
162
- const fd = openSync(lock, constants.O_RDWR | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600), owned = fstatSync(fd);
163
- let error, result;
164
- try {
165
- writeAll(fd, Buffer.from(token));
166
- fsyncSync(fd);
167
- const history = read();
168
- if (history.at(-1).id !== prior)
169
- throw Error('stale learning CAS');
170
- if (history.length >= 4096)
171
- throw Error('learning history bound');
172
- const body = { prior, value: learningCopy(value) }, event = { ...body, id: learningHash(body) }, line = Buffer.from(learningJson(event) + '\n');
173
- const out = openSync(file, constants.O_WRONLY | constants.O_APPEND | constants.O_NOFOLLOW | constants.O_NONBLOCK);
174
- try {
175
- const s = fstatSync(out);
176
- if (!s.isFile() || s.nlink !== 1 || (s.mode & 0o077) || s.size + line.length > LIMIT)
177
- throw Error('learning append refused');
178
- writeAll(out, line);
179
- fsyncSync(out);
180
- }
181
- finally {
182
- closeSync(out);
183
- }
184
- sync(path);
185
- result = event;
186
- }
187
- catch (e) {
188
- error = e;
189
- }
190
- finally {
191
- try {
192
- const s = lstatSync(lock);
193
- if (s.dev !== owned.dev || s.ino !== owned.ino || learningFile(lock, 128).toString() !== token)
194
- throw Error('learning lock ownership lost');
195
- unlinkSync(lock);
196
- sync(path);
197
- }
198
- catch (e) {
199
- error ??= e;
200
- }
201
- finally {
202
- try {
203
- closeSync(fd);
204
- }
205
- catch (e) {
206
- error ??= e;
207
- }
208
- }
209
- }
210
- if (error)
211
- throw error;
212
- return result;
213
- } };
214
- }
215
- /** One authoritative store per weekly key/policy in this archive; a renamed directory cannot refill it. */
216
- export function registerLearningStore(root, kind, key, target, binding) {
217
- if (!/^[a-f0-9]{64}$/.test(key) || !isAbsolute(target) || !['weekly', 'trust', 'intervention', 'access', 'workspace'].includes(kind))
218
- throw Error('invalid learning registration');
219
- directory(root);
220
- directory(dirname(target));
221
- const parent = join(root, 'learning-stores');
222
- try {
223
- mkdirSync(parent, { mode: 0o700 });
224
- sync(root);
225
- }
226
- catch (e) {
227
- if (e.code !== 'EEXIST')
228
- throw e;
229
- }
230
- directory(parent);
231
- const path = join(parent, `${kind}-${key}`), initial = { type: 'learning-registration-v1', target: resolve(target), binding };
232
- try {
233
- learningJournal(path, initial);
234
- }
235
- catch (e) {
236
- if (e.code !== 'EEXIST')
237
- throw e;
238
- const records = learningJournal(path).read();
239
- if (records.length !== 1 || learningHash(records[0].value) !== learningHash(initial))
240
- throw Error('learning key already bound to another store or input');
241
- }
242
- }
243
- export function verifyLearningStore(root, kind, key, target, binding) {
244
- if (!/^[a-f0-9]{64}$/.test(key) || !isAbsolute(target))
245
- throw Error('invalid learning registration');
246
- const records = learningJournal(join(root, 'learning-stores', `${kind}-${key}`)).read();
247
- if (records.length !== 1 || learningHash(records[0].value) !== learningHash({ type: 'learning-registration-v1', target: resolve(target), binding }))
248
- throw Error('learning store registration mismatch');
249
- }
250
- function writeAll(fd, bytes) { let n = 0; while (n < bytes.length) {
251
- const k = writeSync(fd, bytes, n, bytes.length - n);
252
- if (!k)
253
- throw Error('learning write stalled');
254
- n += k;
255
- } }
256
- //# sourceMappingURL=learning-journal.js.map
@@ -1,28 +0,0 @@
1
- export interface LearningLifecycleInput {
2
- caseManifestId: string;
3
- hypothesisManifestId: string;
4
- comparisonManifestId: string;
5
- choiceManifestId: string | null;
6
- adoptionManifestId: string | null;
7
- rollbackManifestId: string | null;
8
- outcomeManifestIds: string[];
9
- predecessorManifestId: string | null;
10
- }
11
- export type LearningLifecycleState = 'awaiting-human-choice' | 'decision-recorded' | 'adopted-awaiting-outcome' | 'rolled-back' | 'outcome-observed';
12
- export interface LearningLifecycleView {
13
- version: 'retained-learning-lifecycle-v1';
14
- state: LearningLifecycleState;
15
- predecessorManifestId: string | null;
16
- links: {
17
- case: string;
18
- hypothesis: string;
19
- comparison: string;
20
- choice: string | null;
21
- adoption: string | null;
22
- rollback: string | null;
23
- outcomes: string[];
24
- };
25
- }
26
- /** Retains navigation only. Linked artifacts retain their own semantics and authority. */
27
- export declare function retainLearningLifecycle(root: string, input: LearningLifecycleInput): string;
28
- export declare function readLearningLifecycle(root: string, manifestId: string): LearningLifecycleView;
@@ -1,66 +0,0 @@
1
- import { readArchiveSource, retainArchiveSource } from './evidence-archive.js';
2
- const SHA = /^[a-f0-9]{64}$/;
3
- const closed = (value, names) => !!value && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).sort().join() === names.sort().join();
4
- function available(root, id, parser) {
5
- if (!SHA.test(id))
6
- throw Error('invalid retained learning link');
7
- const source = readArchiveSource(root, id);
8
- if (source.status !== 'available' || source.reference.retention !== 'exact' || parser && source.reference.parser.id !== parser)
9
- throw Error('retained learning link unavailable');
10
- return source;
11
- }
12
- function validate(root, input, depth = 0) {
13
- if (depth > 64)
14
- throw Error('learning lifecycle predecessor bound exceeded');
15
- if (!closed(input, ['caseManifestId', 'hypothesisManifestId', 'comparisonManifestId', 'choiceManifestId', 'adoptionManifestId', 'rollbackManifestId', 'outcomeManifestIds', 'predecessorManifestId']) || !Array.isArray(input.outcomeManifestIds) || input.outcomeManifestIds.length > 64 || new Set(input.outcomeManifestIds).size !== input.outcomeManifestIds.length)
16
- throw Error('invalid bounded learning lifecycle');
17
- for (const id of [input.caseManifestId, input.hypothesisManifestId, input.comparisonManifestId])
18
- available(root, id);
19
- for (const id of [input.choiceManifestId, input.adoptionManifestId, input.rollbackManifestId, ...input.outcomeManifestIds])
20
- if (id !== null)
21
- available(root, id);
22
- if (input.adoptionManifestId && !input.choiceManifestId)
23
- throw Error('quality choice required before adoption');
24
- if (input.rollbackManifestId && !input.adoptionManifestId)
25
- throw Error('adoption required before rollback');
26
- if (input.outcomeManifestIds.length && !input.adoptionManifestId)
27
- throw Error('adoption required before outcomes');
28
- if (input.predecessorManifestId) {
29
- const prior = read(root, input.predecessorManifestId, depth + 1);
30
- if (prior.links.case !== input.caseManifestId || prior.links.hypothesis !== input.hypothesisManifestId || prior.links.comparison !== input.comparisonManifestId)
31
- throw Error('learning lifecycle identity changed');
32
- for (const key of ['choice', 'adoption', 'rollback'])
33
- if (prior.links[key] !== null && prior.links[key] !== ({ choice: input.choiceManifestId, adoption: input.adoptionManifestId, rollback: input.rollbackManifestId })[key])
34
- throw Error('learning lifecycle cannot regress or replace decisions');
35
- if (prior.links.outcomes.some((id, index) => input.outcomeManifestIds[index] !== id))
36
- throw Error('learning lifecycle cannot regress or replace outcomes');
37
- }
38
- const state = input.outcomeManifestIds.length ? 'outcome-observed' : input.rollbackManifestId ? 'rolled-back' : input.adoptionManifestId ? 'adopted-awaiting-outcome' : input.choiceManifestId ? 'decision-recorded' : 'awaiting-human-choice';
39
- return { version: 'retained-learning-lifecycle-v1', state, predecessorManifestId: input.predecessorManifestId, links: { case: input.caseManifestId, hypothesis: input.hypothesisManifestId, comparison: input.comparisonManifestId, choice: input.choiceManifestId, adoption: input.adoptionManifestId, rollback: input.rollbackManifestId, outcomes: [...input.outcomeManifestIds] } };
40
- }
41
- /** Retains navigation only. Linked artifacts retain their own semantics and authority. */
42
- export function retainLearningLifecycle(root, input) {
43
- const view = validate(root, input);
44
- return retainArchiveSource(root, { sourceId: `learning-${view.links.comparison.slice(0, 24)}`, parser: { id: 'learning-lifecycle', version: '1' }, retention: 'exact', bytes: Buffer.from(JSON.stringify(view)) }).manifestId;
45
- }
46
- function read(root, manifestId, depth) {
47
- if (depth > 64)
48
- throw Error('learning lifecycle predecessor bound exceeded');
49
- const source = available(root, manifestId, 'learning-lifecycle');
50
- let value;
51
- try {
52
- value = JSON.parse(source.bytes.toString('utf8'));
53
- }
54
- catch {
55
- throw Error('invalid retained learning lifecycle');
56
- }
57
- if (!closed(value, ['version', 'state', 'predecessorManifestId', 'links']) || value.version !== 'retained-learning-lifecycle-v1' || !closed(value.links, ['case', 'hypothesis', 'comparison', 'choice', 'adoption', 'rollback', 'outcomes']))
58
- throw Error('invalid retained learning lifecycle');
59
- const links = value.links;
60
- const rebuilt = validate(root, { caseManifestId: links.case, hypothesisManifestId: links.hypothesis, comparisonManifestId: links.comparison, choiceManifestId: links.choice, adoptionManifestId: links.adoption, rollbackManifestId: links.rollback, outcomeManifestIds: links.outcomes, predecessorManifestId: value.predecessorManifestId }, depth);
61
- if (rebuilt.state !== value.state || JSON.stringify(rebuilt) !== source.bytes.toString('utf8'))
62
- throw Error('retained learning lifecycle changed');
63
- return Object.freeze({ ...rebuilt, links: Object.freeze({ ...rebuilt.links, outcomes: Object.freeze(rebuilt.links.outcomes) }) });
64
- }
65
- export function readLearningLifecycle(root, manifestId) { return read(root, manifestId, 0); }
66
- //# sourceMappingURL=learning-lifecycle.js.map
@@ -1,64 +0,0 @@
1
- import type { CalibrationPrediction, CalibrationSplit, ExposurePolicy } from '@skill-harness/core';
2
- import type { LearningCaseReference } from './learning-case.js';
3
- import { type TrustLifecycleInput } from './trust-lifecycle.js';
4
- export interface LearningTrustSetup {
5
- caseName: string;
6
- detectorId: string;
7
- split: CalibrationSplit;
8
- maxUnflagged: number;
9
- unflagged: {
10
- incidentId: string;
11
- manifestId: string;
12
- split: CalibrationSplit;
13
- }[];
14
- exposure: Omit<ExposurePolicy, 'component' | 'kind' | 'split'> | null;
15
- }
16
- /** Forms construct a frozen cohort from actual selected cases. Repeated observations of the
17
- * same target are ONE incident; a detector nomination never becomes its own reference label. */
18
- export declare function previewLearningTrust(directory: string, raw: LearningTrustSetup): {
19
- input: TrustLifecycleInput;
20
- policyDigest: string;
21
- predictions: CalibrationPrediction[];
22
- nominationCount: number;
23
- independentIncidentCount: number;
24
- caseManifestIds: string[];
25
- labelsCreated: 0;
26
- excludedOtherDetectors: number;
27
- };
28
- export declare function configureLearningTrust(directory: string, options: LearningTrustSetup, authorizedPolicyDigests: readonly string[]): {
29
- policyId: string;
30
- component: import("@skill-harness/core").CalibrationComponent;
31
- calibration: {
32
- version: "factory-calibration-v1";
33
- reports: import("@skill-harness/core").CalibrationReport[];
34
- excludedTuning: number;
35
- referenceBasis: "independently-supplied-host-context";
36
- advisoryOnly: true;
37
- };
38
- sampledIncidentIds: string[];
39
- unflagged: {
40
- sampled: number;
41
- resolved: number;
42
- misses: number;
43
- unresolved: number;
44
- conflicted: number;
45
- };
46
- attentionUsed: number;
47
- retired: boolean;
48
- exposures: {
49
- mode: "ask" | "silent" | "retire";
50
- reason: string;
51
- id: string;
52
- }[];
53
- tip: string;
54
- grantExpansion: false;
55
- };
56
- /** Selected case reference, not a retyped verdict. Separate explicit reference authority is
57
- * still required by linkCaseOutcome; this only supplies the exact preview to the operator. */
58
- export declare function previewLearningCaseLabel(directory: string, reference: LearningCaseReference): {
59
- outcome: import("./trust-lifecycle.js").TrustReferenceOutcome;
60
- caseReference: LearningCaseReference;
61
- digest: string;
62
- tip: string;
63
- predictionId: string;
64
- };
@@ -1,55 +0,0 @@
1
- import { learningCopy, learningHash } from './learning-journal.js';
2
- import { openLearningWorkspace } from './learning-workspace.js';
3
- import { trustPolicyDigest } from './trust-lifecycle.js';
4
- /** Forms construct a frozen cohort from actual selected cases. Repeated observations of the
5
- * same target are ONE incident; a detector nomination never becomes its own reference label. */
6
- export function previewLearningTrust(directory, raw) {
7
- const options = learningCopy(raw), workspace = openLearningWorkspace(directory), config = workspace.configuration();
8
- if (Object.keys(options).sort().join() !== 'caseName,detectorId,exposure,maxUnflagged,split,unflagged' || !['calibration', 'heldout', 'tuning'].includes(options.split) || !Array.isArray(options.unflagged) || options.unflagged.length > 1024)
9
- throw Error('closed trust setup required');
10
- const page = workspace.cases(options.caseName), items = [...page.items];
11
- for (let offset = 5; offset < page.total; offset += 5)
12
- items.push(...workspace.cases(options.caseName, offset).items);
13
- const chosen = items.filter(c => c.candidate.detector.id === options.detectorId);
14
- if (!chosen.length)
15
- throw Error('selected detector has no retained cases');
16
- const component = { kind: 'detector', ...chosen[0].candidate.detector };
17
- if (chosen.some(c => learningHash(c.candidate.detector) !== learningHash(chosen[0].candidate.detector)))
18
- throw Error('detector versions/populations must be calibrated separately');
19
- const binding = workspace.inspect(0).cases.find(b => b.name === options.caseName);
20
- if (!binding || binding.state !== 'ready')
21
- throw Error('case binding unavailable');
22
- const incidents = new Map();
23
- for (const c of chosen) {
24
- const id = learningHash({ target: c.candidate.target, population: component.population });
25
- if (!incidents.has(id))
26
- incidents.set(id, c);
27
- }
28
- const cohort = [...[...incidents].map(([incidentId, c]) => ({ incidentId, manifestId: c.caseManifestId, flagged: true, split: options.split })), ...options.unflagged.map(c => ({ ...c, flagged: false }))];
29
- const input = { archiveRoot: config.archiveRoot, component, seed: learningHash({ scope: config.scopeDigest, component, cohort }), maxUnflagged: options.maxUnflagged, cohort,
30
- exposure: options.exposure ? { ...options.exposure, component, kind: 'positive', split: options.split === 'tuning' ? 'calibration' : options.split } : null };
31
- const predictions = [...incidents].map(([incidentId]) => ({ id: learningHash({ incidentId, component, split: options.split }), incidentId, component, kind: 'positive', split: options.split }));
32
- return { input, policyDigest: trustPolicyDigest(input), predictions, nominationCount: chosen.length, independentIncidentCount: incidents.size,
33
- caseManifestIds: [...incidents.values()].map(c => c.caseManifestId), labelsCreated: 0, excludedOtherDetectors: items.length - chosen.length };
34
- }
35
- export function configureLearningTrust(directory, options, authorizedPolicyDigests) {
36
- const preview = previewLearningTrust(directory, options), workspace = openLearningWorkspace(directory);
37
- workspace.configureTrust(preview.input, authorizedPolicyDigests);
38
- for (const p of preview.predictions)
39
- workspace.trust().predict(p);
40
- return workspace.trust().inspect(0);
41
- }
42
- /** Selected case reference, not a retyped verdict. Separate explicit reference authority is
43
- * still required by linkCaseOutcome; this only supplies the exact preview to the operator. */
44
- export function previewLearningCaseLabel(directory, reference) {
45
- const trust = openLearningWorkspace(directory).trust(), config = trust.configuration();
46
- const row = config.cohort.find(c => c.flagged && c.manifestId === reference.manifestId);
47
- if (!row)
48
- throw Error('case outside frozen calibration cohort');
49
- const predictions = trust.history().filter(e => e.value.type === 'prediction' || e.value.type === 'correction').map(e => e.value.prediction);
50
- const p = predictions.filter(p => p.incidentId === row.incidentId).at(-1);
51
- if (!p)
52
- throw Error('prediction missing');
53
- return { predictionId: p.id, ...trust.previewCaseOutcome(p.id, reference) };
54
- }
55
- //# sourceMappingURL=learning-trust-setup.js.map