@unson/brainbase-mcp 0.4.1 → 0.6.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 (36) hide show
  1. package/README.md +13 -5
  2. package/contracts/judgment-dag/digest.json +4 -4
  3. package/contracts/judgment-dag/source-lock.json +65 -1
  4. package/contracts/judgment-value-proof/fixture.json +54 -0
  5. package/contracts/judgment-value-proof/schema.json +163 -0
  6. package/dist/cli.js +17 -0
  7. package/dist/embedding-provider.d.ts +72 -0
  8. package/dist/embedding-provider.js +391 -0
  9. package/dist/graph-retrieval.d.ts +94 -0
  10. package/dist/graph-retrieval.js +443 -0
  11. package/dist/judgment-dag-artifact-store.d.ts +29 -0
  12. package/dist/judgment-dag-artifact-store.js +416 -0
  13. package/dist/judgment-dag-replay-evaluation.d.ts +108 -0
  14. package/dist/judgment-dag-replay-evaluation.js +424 -0
  15. package/dist/judgment-dag.d.ts +4 -0
  16. package/dist/judgment-dag.js +2 -0
  17. package/dist/judgment-value-proof.d.ts +92 -0
  18. package/dist/judgment-value-proof.js +229 -0
  19. package/dist/organization-graph.d.ts +76 -0
  20. package/dist/organization-graph.js +331 -0
  21. package/dist/portable-graph.d.ts +39 -0
  22. package/dist/portable-graph.js +240 -0
  23. package/dist/server.d.ts +42 -3
  24. package/dist/server.js +52 -7
  25. package/docs/management/judgment-dag-milestones.md +31 -1
  26. package/package.json +22 -6
  27. package/ui/icons/mana/LICENSE.tabler.txt +21 -0
  28. package/ui/icons/mana/affiliate.svg +20 -0
  29. package/ui/icons/mana/brand-github.svg +15 -0
  30. package/ui/icons/mana/brand-google-drive.svg +17 -0
  31. package/ui/icons/mana/brand-slack.svg +18 -0
  32. package/ui/icons/mana/cpu.svg +24 -0
  33. package/ui/outcome-knowledge.css +365 -0
  34. package/ui/outcome-knowledge.js +1570 -0
  35. package/ui/outcome-mana.css +255 -0
  36. package/ui/outcome-mana.js +2325 -0
@@ -0,0 +1,424 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { executeJudgmentDAG } from './judgment-dag-runner.js';
3
+ import { computeJudgmentDAGRunArtifactId } from './judgment-dag-artifact-store.js';
4
+ export const JUDGMENT_DAG_OUTCOME_ATTACHMENT_VERSION = 'judgment-dag-outcome.v1';
5
+ export const JUDGMENT_DAG_EVALUATION_EVENT_SET_VERSION = 'judgment-dag-evaluation-event-set.v1';
6
+ const ARTIFACT_ID_PATTERN = /^sha256:[0-9a-f]{64}$/u;
7
+ export class JudgmentDAGReplayEvaluationError extends Error {
8
+ code;
9
+ constructor(code, message) {
10
+ super(message);
11
+ this.name = 'JudgmentDAGReplayEvaluationError';
12
+ this.code = code;
13
+ }
14
+ }
15
+ function fail(code, message) {
16
+ throw new JudgmentDAGReplayEvaluationError(code, message);
17
+ }
18
+ function isPlainObject(value) {
19
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
20
+ return false;
21
+ const prototype = Object.getPrototypeOf(value);
22
+ return prototype === Object.prototype || prototype === null;
23
+ }
24
+ function snapshotJSON(value, label, seen = new WeakSet()) {
25
+ if (value === null || typeof value === 'boolean' || typeof value === 'string')
26
+ return value;
27
+ if (typeof value === 'number') {
28
+ if (!Number.isFinite(value))
29
+ fail('invalid_request', `${label} must contain only finite numbers`);
30
+ return Object.is(value, -0) ? 0 : value;
31
+ }
32
+ if (typeof value !== 'object')
33
+ fail('invalid_request', `${label} must be JSON-compatible`);
34
+ if (seen.has(value))
35
+ fail('invalid_request', `${label} must not contain cycles`);
36
+ seen.add(value);
37
+ try {
38
+ if (Array.isArray(value)) {
39
+ const result = [];
40
+ for (let index = 0; index < value.length; index += 1) {
41
+ if (!Object.hasOwn(value, index))
42
+ fail('invalid_request', `${label} must not contain sparse arrays`);
43
+ result.push(snapshotJSON(value[index], `${label}[${index}]`, seen));
44
+ }
45
+ return result;
46
+ }
47
+ if (!isPlainObject(value))
48
+ fail('invalid_request', `${label} must contain only plain objects`);
49
+ const result = {};
50
+ for (const key of Object.keys(value).sort()) {
51
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
52
+ if (descriptor === undefined || !('value' in descriptor)) {
53
+ fail('invalid_request', `${label}.${key} must be a data property`);
54
+ }
55
+ result[key] = snapshotJSON(descriptor.value, `${label}.${key}`, seen);
56
+ }
57
+ return result;
58
+ }
59
+ finally {
60
+ seen.delete(value);
61
+ }
62
+ }
63
+ function canonicalJSON(value, label) {
64
+ return JSON.stringify(snapshotJSON(value, label));
65
+ }
66
+ function detached(value, label) {
67
+ return JSON.parse(canonicalJSON(value, label));
68
+ }
69
+ function deepFreeze(value) {
70
+ if (value !== null && typeof value === 'object' && !Object.isFrozen(value)) {
71
+ Object.freeze(value);
72
+ for (const child of Object.values(value))
73
+ deepFreeze(child);
74
+ }
75
+ return value;
76
+ }
77
+ function requireNonEmptyString(value, label) {
78
+ if (typeof value !== 'string' || value.trim().length === 0) {
79
+ fail('invalid_request', `${label} must be a non-empty string`);
80
+ }
81
+ return value;
82
+ }
83
+ function requireArtifactId(value, label) {
84
+ if (typeof value !== 'string' || !ARTIFACT_ID_PATTERN.test(value)) {
85
+ fail('invalid_request', `${label} must be a sha256 artifact ID`);
86
+ }
87
+ return value;
88
+ }
89
+ function contentId(value, label) {
90
+ return `sha256:${createHash('sha256').update(canonicalJSON(value, label), 'utf8').digest('hex')}`;
91
+ }
92
+ function detachedRecord(record, label) {
93
+ const snapshot = detached(record, label);
94
+ requireNonEmptyString(snapshot.run_id, `${label}.run_id`);
95
+ return deepFreeze(snapshot);
96
+ }
97
+ function verifiedArtifactRecord(artifactIdValue, recordValue, label) {
98
+ const artifactId = requireArtifactId(artifactIdValue, `${label}.artifact_id`);
99
+ const record = detachedRecord(recordValue, `${label}.record`);
100
+ let expectedArtifactId;
101
+ try {
102
+ expectedArtifactId = computeJudgmentDAGRunArtifactId(record);
103
+ }
104
+ catch {
105
+ fail('invalid_request', `${label}.record is not a valid run artifact record`);
106
+ }
107
+ if (artifactId !== expectedArtifactId) {
108
+ fail('artifact_mismatch', `${label}.artifact_id does not match the run record content`);
109
+ }
110
+ return { artifactId, record };
111
+ }
112
+ function requiredHistoricalVersions(record) {
113
+ const versions = new Map();
114
+ for (const entry of record.runner_versions) {
115
+ if (versions.has(entry.runner_type))
116
+ fail('invalid_request', 'historical runner versions must be unique');
117
+ versions.set(entry.runner_type, requireNonEmptyString(entry.version, 'historical runner version'));
118
+ }
119
+ return versions;
120
+ }
121
+ function captureRunnerRegistrations(request, dag, expectedVersions) {
122
+ try {
123
+ const runnersDescriptor = Object.getOwnPropertyDescriptor(request, 'runners');
124
+ if (runnersDescriptor === undefined || !('value' in runnersDescriptor) ||
125
+ !isPlainObject(runnersDescriptor.value)) {
126
+ fail('invalid_request', 'runners must be an own data property containing a plain object');
127
+ }
128
+ const runners = runnersDescriptor.value;
129
+ const captured = {};
130
+ const runnerTypes = [...new Set(dag.nodes.map((node) => node.runner_type))]
131
+ .sort((left, right) => left.localeCompare(right));
132
+ for (const runnerType of runnerTypes) {
133
+ const registrationDescriptor = Object.getOwnPropertyDescriptor(runners, runnerType);
134
+ if (registrationDescriptor === undefined || !('value' in registrationDescriptor) ||
135
+ !isPlainObject(registrationDescriptor.value)) {
136
+ fail('invalid_request', `runner ${runnerType} must be an own data property`);
137
+ }
138
+ const versionDescriptor = Object.getOwnPropertyDescriptor(registrationDescriptor.value, 'version');
139
+ const runDescriptor = Object.getOwnPropertyDescriptor(registrationDescriptor.value, 'run');
140
+ if (versionDescriptor === undefined || !('value' in versionDescriptor) ||
141
+ runDescriptor === undefined || !('value' in runDescriptor) ||
142
+ typeof runDescriptor.value !== 'function') {
143
+ fail('invalid_request', `runner ${runnerType} must expose version and run as data properties`);
144
+ }
145
+ const version = requireNonEmptyString(versionDescriptor.value, `runner ${runnerType} version`);
146
+ const expectedVersion = expectedVersions?.get(runnerType);
147
+ if (expectedVersion !== undefined && version !== expectedVersion) {
148
+ fail('runner_version_mismatch', `historical runner ${runnerType} must use recorded version ${expectedVersion}`);
149
+ }
150
+ captured[runnerType] = { version, run: runDescriptor.value };
151
+ }
152
+ return Object.freeze(captured);
153
+ }
154
+ catch (error) {
155
+ if (error instanceof JudgmentDAGReplayEvaluationError)
156
+ throw error;
157
+ fail('invalid_request', 'runner registrations could not be captured safely');
158
+ }
159
+ }
160
+ export async function replayJudgmentDAGRun(request) {
161
+ if (!isPlainObject(request) || !isPlainObject(request.source)) {
162
+ fail('invalid_request', 'replay request and source must be plain objects');
163
+ }
164
+ const { artifactId, record: sourceRecord } = verifiedArtifactRecord(request.source.artifact_id, request.source.record, 'source');
165
+ const replayRunId = requireNonEmptyString(request.replay_run_id, 'replay_run_id');
166
+ if (replayRunId === sourceRecord.run_id)
167
+ fail('invalid_request', 'replay_run_id must differ from source run_id');
168
+ if (request.mode !== 'historical' && request.mode !== 'candidate')
169
+ fail('invalid_request', 'mode is invalid');
170
+ let replayDAG;
171
+ let expectedVersions;
172
+ if (request.mode === 'historical') {
173
+ if (request.candidate_dag !== undefined)
174
+ fail('invalid_request', 'historical replay cannot provide candidate_dag');
175
+ expectedVersions = requiredHistoricalVersions(sourceRecord);
176
+ replayDAG = sourceRecord.dag;
177
+ }
178
+ else {
179
+ if (request.candidate_dag === undefined)
180
+ fail('invalid_request', 'candidate replay requires candidate_dag');
181
+ replayDAG = detached(request.candidate_dag, 'candidate_dag');
182
+ }
183
+ const capturedRunners = captureRunnerRegistrations(request, replayDAG, expectedVersions);
184
+ const record = await executeJudgmentDAG({
185
+ run_id: replayRunId,
186
+ dag: replayDAG,
187
+ input: sourceRecord.input,
188
+ runners: capturedRunners
189
+ });
190
+ return deepFreeze({
191
+ source_artifact_id: artifactId,
192
+ source_run_id: sourceRecord.run_id,
193
+ mode: request.mode,
194
+ record
195
+ });
196
+ }
197
+ function normalizedObservations(record, observations) {
198
+ if (!Array.isArray(observations) || observations.length === 0) {
199
+ fail('invalid_request', 'observations must be a non-empty array');
200
+ }
201
+ const nodeIds = new Set(record.nodes.map((node) => node.node_id));
202
+ const identities = new Set();
203
+ return observations.map((raw, index) => {
204
+ if (!isPlainObject(raw))
205
+ fail('invalid_request', `observations[${index}] must be a plain object`);
206
+ const metricId = requireNonEmptyString(raw.metric_id, `observations[${index}].metric_id`);
207
+ if (raw.scope !== 'run' && raw.scope !== 'node')
208
+ fail('invalid_request', 'observation scope is invalid');
209
+ if (typeof raw.value !== 'boolean' && (typeof raw.value !== 'number' || !Number.isFinite(raw.value))) {
210
+ fail('invalid_request', 'observation value must be boolean or a finite number');
211
+ }
212
+ let nodeId;
213
+ if (raw.scope === 'node') {
214
+ nodeId = requireNonEmptyString(raw.node_id, `observations[${index}].node_id`);
215
+ if (!nodeIds.has(nodeId))
216
+ fail('invalid_request', `observation references unknown node ${nodeId}`);
217
+ }
218
+ else if (raw.node_id !== undefined) {
219
+ fail('invalid_request', 'run observation cannot have node_id');
220
+ }
221
+ const identity = `${metricId}\u0000${raw.scope}\u0000${nodeId ?? ''}`;
222
+ if (identities.has(identity))
223
+ fail('invalid_request', 'observations must be unique by metric, scope, and node');
224
+ identities.add(identity);
225
+ return nodeId === undefined
226
+ ? { metric_id: metricId, scope: raw.scope, value: raw.value }
227
+ : { metric_id: metricId, scope: raw.scope, node_id: nodeId, value: raw.value };
228
+ });
229
+ }
230
+ export function createJudgmentDAGOutcomeAttachment(request) {
231
+ if (!isPlainObject(request))
232
+ fail('invalid_request', 'outcome request must be a plain object');
233
+ const { artifactId, record } = verifiedArtifactRecord(request.run_artifact_id, request.record, 'run_artifact');
234
+ const observations = normalizedObservations(record, request.observations);
235
+ const payload = {
236
+ attachment_version: JUDGMENT_DAG_OUTCOME_ATTACHMENT_VERSION,
237
+ run_artifact_id: artifactId,
238
+ run_id: record.run_id,
239
+ observations
240
+ };
241
+ return deepFreeze({ ...payload, attachment_id: contentId(payload, 'outcome attachment') });
242
+ }
243
+ function validateOutcome(outcome, artifactId, record, label) {
244
+ const snapshot = detached(outcome, label);
245
+ if (snapshot.attachment_version !== JUDGMENT_DAG_OUTCOME_ATTACHMENT_VERSION ||
246
+ snapshot.run_artifact_id !== artifactId || snapshot.run_id !== record.run_id) {
247
+ fail('outcome_mismatch', `${label} does not bind to its run artifact`);
248
+ }
249
+ const normalized = createJudgmentDAGOutcomeAttachment({
250
+ run_artifact_id: artifactId,
251
+ record,
252
+ observations: snapshot.observations
253
+ });
254
+ if (normalized.attachment_id !== snapshot.attachment_id) {
255
+ fail('outcome_mismatch', `${label} content identity is invalid`);
256
+ }
257
+ return normalized;
258
+ }
259
+ function normalizedEvaluationRun(value, label) {
260
+ if (!isPlainObject(value))
261
+ fail('invalid_request', `${label} must be a plain object`);
262
+ const { artifactId, record } = verifiedArtifactRecord(value.artifact_id, value.record, label);
263
+ const outcome = validateOutcome(value.outcome, artifactId, record, `${label}.outcome`);
264
+ return { artifact_id: artifactId, record, outcome };
265
+ }
266
+ export function createJudgmentDAGEvaluationEventSet(request) {
267
+ if (!isPlainObject(request) || !Array.isArray(request.events) || request.events.length === 0) {
268
+ fail('invalid_request', 'evaluation event set requires a non-empty events array');
269
+ }
270
+ const eventIds = new Set();
271
+ const events = request.events.map((event, index) => {
272
+ if (!isPlainObject(event))
273
+ fail('invalid_request', `events[${index}] must be a plain object`);
274
+ const typedEvent = event;
275
+ const eventId = requireNonEmptyString(typedEvent.event_id, `events[${index}].event_id`);
276
+ if (eventIds.has(eventId))
277
+ fail('invalid_request', `duplicate event_id ${eventId}`);
278
+ eventIds.add(eventId);
279
+ const baseline = normalizedEvaluationRun(typedEvent.baseline, `events[${index}].baseline`);
280
+ const candidate = normalizedEvaluationRun(typedEvent.candidate, `events[${index}].candidate`);
281
+ if (canonicalJSON(baseline.record.input, 'baseline input') !==
282
+ canonicalJSON(candidate.record.input, 'candidate input')) {
283
+ fail('context_mismatch', `event ${eventId} does not compare the same recorded context`);
284
+ }
285
+ return { event_id: eventId, baseline, candidate };
286
+ });
287
+ const payload = {
288
+ event_set_version: JUDGMENT_DAG_EVALUATION_EVENT_SET_VERSION,
289
+ events
290
+ };
291
+ return deepFreeze({
292
+ ...payload,
293
+ event_set_id: contentId(payload, 'evaluation event set'),
294
+ event_ids: events.map((event) => event.event_id)
295
+ });
296
+ }
297
+ function validateEventSet(eventSet) {
298
+ const rebuilt = createJudgmentDAGEvaluationEventSet({ events: eventSet.events });
299
+ if (eventSet.event_set_version !== JUDGMENT_DAG_EVALUATION_EVENT_SET_VERSION ||
300
+ eventSet.event_set_id !== rebuilt.event_set_id ||
301
+ canonicalJSON(eventSet.event_ids, 'event_ids') !== canonicalJSON(rebuilt.event_ids, 'event_ids')) {
302
+ fail('invalid_request', 'evaluation event set identity is invalid');
303
+ }
304
+ return rebuilt;
305
+ }
306
+ function validateCriterion(value) {
307
+ if (!isPlainObject(value) || !isPlainObject(value.scoring)) {
308
+ fail('invalid_request', 'criterion and scoring must be plain objects');
309
+ }
310
+ const criterionId = requireNonEmptyString(value.criterion_id, 'criterion_id');
311
+ const goal = requireNonEmptyString(value.goal, 'goal');
312
+ const metricId = requireNonEmptyString(value.metric_id, 'metric_id');
313
+ let scoring;
314
+ if (value.scoring.kind === 'numeric') {
315
+ if (value.scoring.direction !== 'higher_is_better' && value.scoring.direction !== 'lower_is_better') {
316
+ fail('invalid_request', 'numeric direction is invalid');
317
+ }
318
+ scoring = { kind: 'numeric', direction: value.scoring.direction };
319
+ }
320
+ else if (value.scoring.kind === 'pass_fail') {
321
+ if (!['eq', 'gte', 'lte'].includes(value.scoring.operator))
322
+ fail('invalid_request', 'pass_fail operator is invalid');
323
+ if (typeof value.scoring.target !== 'boolean' &&
324
+ (typeof value.scoring.target !== 'number' || !Number.isFinite(value.scoring.target))) {
325
+ fail('invalid_request', 'pass_fail target must be boolean or a finite number');
326
+ }
327
+ if (typeof value.scoring.target === 'boolean' && value.scoring.operator !== 'eq') {
328
+ fail('invalid_request', 'boolean pass_fail target only supports eq');
329
+ }
330
+ scoring = { kind: 'pass_fail', operator: value.scoring.operator, target: value.scoring.target };
331
+ }
332
+ else {
333
+ fail('invalid_request', 'scoring kind is invalid');
334
+ }
335
+ return deepFreeze({ criterion_id: criterionId, goal, metric_id: metricId, scoring });
336
+ }
337
+ function scoreValue(value, scoring) {
338
+ if (scoring.kind === 'numeric') {
339
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
340
+ fail('invalid_score', 'numeric scoring requires finite number observations');
341
+ }
342
+ return value;
343
+ }
344
+ if (scoring.operator === 'eq')
345
+ return value === scoring.target ? 1 : 0;
346
+ if (typeof value !== 'number' || typeof scoring.target !== 'number') {
347
+ fail('invalid_score', 'ordered pass_fail scoring requires number observations and target');
348
+ }
349
+ return scoring.operator === 'gte'
350
+ ? (value >= scoring.target ? 1 : 0)
351
+ : (value <= scoring.target ? 1 : 0);
352
+ }
353
+ function observation(attachment, metricId, scope, nodeId) {
354
+ return attachment.observations.find((item) => item.metric_id === metricId && item.scope === scope && item.node_id === nodeId);
355
+ }
356
+ function average(values) {
357
+ return values.reduce((sum, value) => sum + value, 0) / values.length;
358
+ }
359
+ export function evaluateJudgmentDAGVersions(request) {
360
+ if (!isPlainObject(request))
361
+ fail('invalid_request', 'evaluation request must be a plain object');
362
+ const eventSet = validateEventSet(request.event_set);
363
+ const criterion = validateCriterion(request.criterion);
364
+ const baselineOverall = [];
365
+ const candidateOverall = [];
366
+ const allNodeIds = new Set();
367
+ for (const event of eventSet.events) {
368
+ const baselineRun = observation(event.baseline.outcome, criterion.metric_id, 'run');
369
+ const candidateRun = observation(event.candidate.outcome, criterion.metric_id, 'run');
370
+ if (baselineRun === undefined || candidateRun === undefined) {
371
+ fail('outcome_mismatch', `event ${event.event_id} is missing the run observation for ${criterion.metric_id}`);
372
+ }
373
+ baselineOverall.push(scoreValue(baselineRun.value, criterion.scoring));
374
+ candidateOverall.push(scoreValue(candidateRun.value, criterion.scoring));
375
+ for (const node of event.baseline.record.nodes)
376
+ allNodeIds.add(node.node_id);
377
+ for (const node of event.candidate.record.nodes)
378
+ allNodeIds.add(node.node_id);
379
+ }
380
+ const nodeCalibration = [...allNodeIds].sort().map((nodeId) => {
381
+ const baselineScores = [];
382
+ const candidateScores = [];
383
+ let baselinePresent = false;
384
+ let candidatePresent = false;
385
+ for (const event of eventSet.events) {
386
+ baselinePresent ||= event.baseline.record.nodes.some((node) => node.node_id === nodeId);
387
+ candidatePresent ||= event.candidate.record.nodes.some((node) => node.node_id === nodeId);
388
+ const baselineNode = observation(event.baseline.outcome, criterion.metric_id, 'node', nodeId);
389
+ const candidateNode = observation(event.candidate.outcome, criterion.metric_id, 'node', nodeId);
390
+ if (baselineNode !== undefined && candidateNode !== undefined) {
391
+ baselineScores.push(scoreValue(baselineNode.value, criterion.scoring));
392
+ candidateScores.push(scoreValue(candidateNode.value, criterion.scoring));
393
+ }
394
+ }
395
+ if (!baselinePresent) {
396
+ return { node_id: nodeId, status: 'candidate_only', baseline: null, candidate: null, delta: null, event_count: 0 };
397
+ }
398
+ if (!candidatePresent) {
399
+ return { node_id: nodeId, status: 'baseline_only', baseline: null, candidate: null, delta: null, event_count: 0 };
400
+ }
401
+ if (baselineScores.length === 0) {
402
+ return { node_id: nodeId, status: 'no_observation', baseline: null, candidate: null, delta: null, event_count: 0 };
403
+ }
404
+ const baseline = average(baselineScores);
405
+ const candidate = average(candidateScores);
406
+ return {
407
+ node_id: nodeId,
408
+ status: 'comparable',
409
+ baseline,
410
+ candidate,
411
+ delta: candidate - baseline,
412
+ event_count: baselineScores.length
413
+ };
414
+ });
415
+ const baseline = average(baselineOverall);
416
+ const candidate = average(candidateOverall);
417
+ return deepFreeze({
418
+ event_set_id: eventSet.event_set_id,
419
+ event_ids: eventSet.event_ids.slice(),
420
+ criterion,
421
+ overall: { baseline, candidate, delta: candidate - baseline, event_count: eventSet.events.length },
422
+ node_calibration: nodeCalibration
423
+ });
424
+ }
@@ -6,5 +6,9 @@
6
6
  */
7
7
  export { JUDGMENT_DAG_EDGE_RELATIONS, JUDGMENT_DAG_ALLOWED_KEYS, JUDGMENT_DAG_LAYERS, JUDGMENT_DAG_NODE_TYPE_TO_LAYER, JUDGMENT_DAG_NODE_TYPES, JUDGMENT_DAG_RUNNER_TYPES, JUDGMENT_DAG_SCOPE_TYPES, JudgmentDAGValidationError, assertValidJudgmentDAG, validateJudgmentDAG } from './judgment-dag-core.js';
8
8
  export { executeJudgmentDAG, JudgmentDAGExecutionError } from './judgment-dag-runner.js';
9
+ export { computeJudgmentDAGRunArtifactId, JUDGMENT_DAG_RUN_ARTIFACT_VERSION, JudgmentDAGArtifactError, loadJudgmentDAGRunArtifact, saveJudgmentDAGRunArtifact } from './judgment-dag-artifact-store.js';
10
+ export { JUDGMENT_DAG_EVALUATION_EVENT_SET_VERSION, JUDGMENT_DAG_OUTCOME_ATTACHMENT_VERSION, JudgmentDAGReplayEvaluationError, createJudgmentDAGEvaluationEventSet, createJudgmentDAGOutcomeAttachment, evaluateJudgmentDAGVersions, replayJudgmentDAGRun } from './judgment-dag-replay-evaluation.js';
9
11
  export type { JudgmentDAG, JudgmentDAGEdge, JudgmentDAGEdgeRelation, JudgmentDAGLayer, JudgmentDAGMetadata, JudgmentDAGNode, JudgmentDAGNodeType, JudgmentDAGRunnerType, JudgmentDAGScope, JudgmentDAGScopeType, JudgmentDAGValidationCode, JudgmentDAGValidationDetails, JudgmentDAGValidationResult } from './judgment-dag-core.js';
10
12
  export type { JudgmentDAGDependencyOutput, JudgmentDAGExecutionCode, JudgmentDAGExecutionErrorDetails, JudgmentDAGJSONValue, JudgmentDAGNodeRunRecord, JudgmentDAGRunRecord, JudgmentDAGRunRequest, JudgmentDAGRunnerFailureKind, JudgmentDAGRunnerInput, JudgmentDAGRunnerRegistration, JudgmentDAGRunnerVersion } from './judgment-dag-runner.js';
13
+ export type { JudgmentDAGArtifactErrorCode, JudgmentDAGRunArtifactId, JudgmentDAGRunArtifactReceipt, LoadJudgmentDAGRunArtifactRequest, SaveJudgmentDAGRunArtifactRequest } from './judgment-dag-artifact-store.js';
14
+ export type { CreateJudgmentDAGEvaluationEventSetRequest, CreateJudgmentDAGOutcomeAttachmentRequest, EvaluateJudgmentDAGVersionsRequest, JudgmentDAGEvaluationCriterion, JudgmentDAGEvaluationEvent, JudgmentDAGEvaluationEventSet, JudgmentDAGEvaluationRun, JudgmentDAGEvaluationScoring, JudgmentDAGNodeCalibration, JudgmentDAGNodeCalibrationStatus, JudgmentDAGOutcomeAttachment, JudgmentDAGOutcomeObservation, JudgmentDAGReplayEvaluationErrorCode, JudgmentDAGReplayResult, JudgmentDAGRunArtifactReference, JudgmentDAGScoreSummary, JudgmentDAGVersionComparison, ReplayJudgmentDAGRunRequest } from './judgment-dag-replay-evaluation.js';
@@ -6,3 +6,5 @@
6
6
  */
7
7
  export { JUDGMENT_DAG_EDGE_RELATIONS, JUDGMENT_DAG_ALLOWED_KEYS, JUDGMENT_DAG_LAYERS, JUDGMENT_DAG_NODE_TYPE_TO_LAYER, JUDGMENT_DAG_NODE_TYPES, JUDGMENT_DAG_RUNNER_TYPES, JUDGMENT_DAG_SCOPE_TYPES, JudgmentDAGValidationError, assertValidJudgmentDAG, validateJudgmentDAG } from './judgment-dag-core.js';
8
8
  export { executeJudgmentDAG, JudgmentDAGExecutionError } from './judgment-dag-runner.js';
9
+ export { computeJudgmentDAGRunArtifactId, JUDGMENT_DAG_RUN_ARTIFACT_VERSION, JudgmentDAGArtifactError, loadJudgmentDAGRunArtifact, saveJudgmentDAGRunArtifact } from './judgment-dag-artifact-store.js';
10
+ export { JUDGMENT_DAG_EVALUATION_EVENT_SET_VERSION, JUDGMENT_DAG_OUTCOME_ATTACHMENT_VERSION, JudgmentDAGReplayEvaluationError, createJudgmentDAGEvaluationEventSet, createJudgmentDAGOutcomeAttachment, evaluateJudgmentDAGVersions, replayJudgmentDAGRun } from './judgment-dag-replay-evaluation.js';
@@ -0,0 +1,92 @@
1
+ export type JudgmentValueProofIntentState = 'captured' | 'executing' | 'waiting_human' | 'outcome_verified' | 'blocked' | 'unconfirmed';
2
+ export type JudgmentValueProofResolution = 'not_applicable' | 'continued_without_human' | 'human_required';
3
+ export type JudgmentValueProofEvidenceKind = 'judgment_receipt' | 'autonomy_receipt' | 'tool_event' | 'artifact' | 'canonical_readback' | 'human_feedback';
4
+ export interface JudgmentValueProofEvidenceRef {
5
+ kind: JudgmentValueProofEvidenceKind;
6
+ ref: string;
7
+ status: 'verified' | 'unconfirmed';
8
+ label?: string;
9
+ }
10
+ export interface JudgmentValueProofArtifactRef {
11
+ kind: string;
12
+ ref: string;
13
+ label?: string;
14
+ }
15
+ export interface JudgmentValueProofBasis {
16
+ entity_id: string;
17
+ application: string;
18
+ }
19
+ export interface JudgmentValueProofHumanOption {
20
+ id: string;
21
+ label: string;
22
+ impact: string;
23
+ }
24
+ export interface JudgmentValueProof {
25
+ schema_version: 'brainbase-judgment-value-proof-v1';
26
+ intent_id: string;
27
+ decision_attempt_id: string;
28
+ recorded_at: string;
29
+ state: JudgmentValueProofIntentState;
30
+ interruption: {
31
+ resolution: JudgmentValueProofResolution;
32
+ question_display_text: string | null;
33
+ question_digest: string | null;
34
+ reason_code: string | null;
35
+ human_reason: string | null;
36
+ };
37
+ decision: {
38
+ summary: string | null;
39
+ work_impact: string | null;
40
+ basis: JudgmentValueProofBasis[];
41
+ prior_learning_reused: boolean | 'unconfirmed';
42
+ };
43
+ execution: {
44
+ status: 'not_started' | 'executing' | 'completed' | 'blocked';
45
+ summary: string | null;
46
+ artifact_refs: JudgmentValueProofArtifactRef[];
47
+ };
48
+ outcome: {
49
+ status: 'outcome_verified' | 'unconfirmed' | 'not_applicable';
50
+ summary: string | null;
51
+ evidence_refs: JudgmentValueProofEvidenceRef[];
52
+ };
53
+ human_decision: {
54
+ question: string;
55
+ why_human: string;
56
+ options: JudgmentValueProofHumanOption[];
57
+ } | null;
58
+ feedback: {
59
+ status: 'none' | 'pending' | 'accepted' | 'corrected' | 'next_time_ask' | 'reverted';
60
+ summary: string | null;
61
+ evidence_ref: JudgmentValueProofEvidenceRef | null;
62
+ };
63
+ }
64
+ export interface JudgmentValueProofPlacement {
65
+ agent_progress: 'silent' | 'show';
66
+ agent_completion: 'silent' | 'show';
67
+ companion_attention: 'none' | 'human_decision' | 'blocked' | 'outcome_unconfirmed' | 'feedback_requested';
68
+ web_surface: 'none';
69
+ weekly_digest: 'exclude' | 'include';
70
+ }
71
+ export interface JudgmentValueProofCompanionItem {
72
+ schema_version: 'brainbase-judgment-value-proof-attention-v1';
73
+ intent_id: string;
74
+ decision_attempt_id: string;
75
+ kind: Exclude<JudgmentValueProofPlacement['companion_attention'], 'none'>;
76
+ title: string;
77
+ summary: string;
78
+ suggested_actions: string[];
79
+ }
80
+ export interface JudgmentValueProofWeeklyDigestInput {
81
+ period_label: string;
82
+ coverage: 'complete' | 'partial' | 'unavailable';
83
+ proofs: JudgmentValueProof[];
84
+ representative_limit?: number;
85
+ }
86
+ export declare function validateJudgmentValueProof(proof: JudgmentValueProof): JudgmentValueProof;
87
+ export declare function placeJudgmentValueProof(proof: JudgmentValueProof): JudgmentValueProofPlacement;
88
+ export declare function renderJudgmentValueProofProgress(proof: JudgmentValueProof): string | null;
89
+ export declare function renderJudgmentValueProofCompletion(proof: JudgmentValueProof): string | null;
90
+ export declare function renderJudgmentHumanDecisionRequest(proof: JudgmentValueProof): string | null;
91
+ export declare function projectJudgmentValueProofAttention(proof: JudgmentValueProof): JudgmentValueProofCompanionItem | null;
92
+ export declare function renderJudgmentValueProofWeeklyDigest(input: JudgmentValueProofWeeklyDigestInput): string;