blun-king-cli 9.1.562 → 9.1.564

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.
@@ -8,9 +8,12 @@ import {
8
8
  recordActivity, resolveAttention, upsertAttention
9
9
  } from "./lib/attention.js";
10
10
  import {
11
- addLearningEvidence, configureLearning, deleteLearning, evaluateLearning,
11
+ addLearningEvidence, beginLearningRevalidation, configureLearning, deleteLearning, evaluateLearning,
12
12
  learningContext, learningOutcomeStatus, loadLearning, proposeLearning,
13
- recordLearningOutcome, reviewLearning, rollbackLearning
13
+ purgeStaleLearningApplications, purgeStaleLearningMeasurements, recordLearningMeasurement,
14
+ recordLearningOutcome, registerLearningEvaluation, registerLearningEvaluator, renewLearningValidation, revokeLearningEvaluator,
15
+ reviewLearning, revokeLearningApplication, revokeLearningDelivery, revokeLearningEvaluation, revokeLearningEvidence, revokeLearningMeasurement, revokeLearningOutcome, revokeLearningTrialFailure, revokeLearningValidation,
16
+ rollbackLearning
14
17
  } from "./lib/learning.js";
15
18
  import { configureContinuity, loadContinuity, purgeContinuity } from "./lib/continuity.js";
16
19
  import {
@@ -109,6 +112,14 @@ function hasLearningScope(flags) {
109
112
  return ["persona", "user", "tenant", "project", "group", "task"].some((name) => flags[name] !== undefined);
110
113
  }
111
114
 
115
+ function evaluatorRootsFlag(value) {
116
+ return String(value || "").split(",").filter(Boolean).map((entry) => {
117
+ const separator = entry.lastIndexOf("=");
118
+ if (separator <= 0) throw new Error("evaluator roots must use evaluator-id=sha256 entries");
119
+ return { evaluatorId: entry.slice(0, separator), principalDigest: entry.slice(separator + 1) };
120
+ });
121
+ }
122
+
112
123
  function help() {
113
124
  return `AgentSpine ${VERSION}
114
125
 
@@ -134,11 +145,27 @@ Usage:
134
145
  agentspine attention-config [root] [--enabled true|false] [--quiet-start 22 --quiet-end 7 --utc-offset 120]
135
146
  agentspine learn-propose [id] --kind preference|behavior --claim text --evidence text [--persona id --user id --tenant id --project id --group id --task id]
136
147
  agentspine learn-evidence <id> --summary text [--type interaction] [--source path.md]
148
+ agentspine learn-evidence-revoke <learning-id> --evidence-id id --reason-code retracted|source-invalid|measurement-invalid|duplicate|other --reason text --confirm-local-evidence
137
149
  agentspine learn-review <id> --decision accept|reject --reason text [--confirmed-by-user]
138
150
  agentspine learn-context [root] [--group id] [--include-private] [--kind preference,goal]
139
151
  agentspine learn-evaluate [root]
140
- agentspine learn-outcome <id> --phase before|after --metric name --direction higher|lower --value 0..1 --evaluator id --measurement objective|user-feedback|model-suggestion [--blocking-defects n]
152
+ agentspine learn-evaluator-register <id> --principal-digest sha256 --confirm-local-evaluator
153
+ agentspine learn-evaluator-revoke <id> --reason text --confirm-local-evaluator
154
+ agentspine learn-evaluation <id> --learning id --metric name --direction higher|lower --task-digest sha256 --dataset-digest sha256 --protocol-digest sha256 --min-cases n --evaluators id,id --evaluator-roots id=sha256,id=sha256 [--expires-at date] [--retry-trial-failure id --confirm-local-trial-retry] --confirm-local-evaluation
155
+ agentspine learn-evaluation-revoke <evaluation-id> --reason-code benchmark-invalid|protocol-invalid|scope-invalid|threshold-invalid|duplicate|other --reason text --confirm-local-evaluation-revocation
156
+ agentspine learn-validation-revoke <validation-lease-id> --reason-code decision-invalid|cohort-invalid|binding-invalid|scope-invalid|duplicate|other --reason text --confirm-local-validation-revocation
157
+ agentspine learn-trial-failure-revoke <trial-failure-id> --reason-code clock-invalid|host-invalid|receipt-invalid|scope-invalid|duplicate|other --reason text --confirm-local-trial-failure-revocation
158
+ agentspine learn-revalidation-start <learning-id> --confirm-local-validation
159
+ agentspine learn-revalidate <learning-id> --measurements id,id --applications id,id --deliveries id,id --confirm-local-validation
160
+ agentspine learn-measurement <id> --learning id --evaluation id --phase before|after --metric name --direction higher|lower --value 0..1 --measurement objective|user-feedback|model-suggestion --evaluator id --run id --source-digest sha256 --dataset-digest sha256 --case-count n --confirm-local-measurement
161
+ agentspine learn-measurement-revoke <measurement-id> --reason-code source-invalid|evaluator-invalid|protocol-invalid|duplicate|other --reason text --confirm-local-measurement-revocation
162
+ agentspine learn-application-revoke <application-id> --reason-code preflight-invalid|scope-invalid|projection-invalid|duplicate|other --reason text --confirm-local-application-revocation
163
+ agentspine learn-delivery-revoke <delivery-id> --reason-code host-invalid|session-invalid|hook-invalid|duplicate|other --reason text --confirm-local-delivery-revocation
164
+ agentspine learn-outcome-revoke <outcome-id> --reason-code binding-invalid|phase-invalid|scope-invalid|duplicate|other --reason text --confirm-local-outcome-revocation
165
+ agentspine learn-outcome <learning-id> --id id --evaluation id --measurement-receipt id [--application id --delivery id]
141
166
  agentspine learn-status [root] [--persona id --user id --tenant id --project id --group id --task id]
167
+ agentspine learn-delivery-purge [root] --confirm-local-purge
168
+ agentspine learn-measurement-purge [root] --confirm-local-purge
142
169
  agentspine learn-rollback <id> --reason text
143
170
  agentspine learn-delete <id>
144
171
  agentspine learn-config [root] [--auto-promote true|false] [--min-confidence 0.85] [--min-outcomes 2 --min-improvement 0.05 --canary-receipts 2 --canary-ttl-days 14]
@@ -429,6 +456,15 @@ export async function run(argv = process.argv.slice(2)) {
429
456
  }), json);
430
457
  }
431
458
 
459
+ if (command === "learn-evidence-revoke") {
460
+ return output(await revokeLearningEvidence({
461
+ root: flags.root || process.cwd(), learningId: positional[0], evidenceId: flags["evidence-id"],
462
+ reasonCode: flags["reason-code"], reason: flags.reason,
463
+ confirmation: booleanFlag(flags["confirm-local-evidence"])
464
+ ? "local-evidence-revocation-confirmed" : null
465
+ }), json);
466
+ }
467
+
432
468
  if (command === "learn-review") {
433
469
  return output(await reviewLearning({
434
470
  root: flags.root || process.cwd(), id: positional[0], decision: flags.decision,
@@ -451,11 +487,147 @@ export async function run(argv = process.argv.slice(2)) {
451
487
  return output(await evaluateLearning({ root: positional[0] || process.cwd() }), json);
452
488
  }
453
489
 
490
+ if (command === "learn-evaluator-register") {
491
+ return output(await registerLearningEvaluator({
492
+ root: flags.root || process.cwd(), id: positional[0], principalDigest: flags["principal-digest"],
493
+ confirmLocalEvaluator: booleanFlag(flags["confirm-local-evaluator"])
494
+ }), json);
495
+ }
496
+
497
+ if (command === "learn-evaluator-revoke") {
498
+ return output(await revokeLearningEvaluator({
499
+ root: flags.root || process.cwd(), id: positional[0], reason: flags.reason,
500
+ confirmLocalEvaluator: booleanFlag(flags["confirm-local-evaluator"])
501
+ }), json);
502
+ }
503
+
504
+ if (command === "learn-evaluation") {
505
+ return output(await registerLearningEvaluation({
506
+ root: flags.root || process.cwd(), id: positional[0], learningId: flags.learning,
507
+ scope: learningScope(flags), metric: { name: flags.metric, direction: flags.direction },
508
+ benchmark: {
509
+ taskDigest: flags["task-digest"], datasetDigest: flags["dataset-digest"],
510
+ protocolDigest: flags["protocol-digest"], minCases: Number(flags["min-cases"])
511
+ },
512
+ evaluatorIds: String(flags.evaluators || "").split(",").filter(Boolean),
513
+ evaluatorRoots: evaluatorRootsFlag(flags["evaluator-roots"]),
514
+ expiresAt: flags["expires-at"] || null,
515
+ retryTrialFailureId: flags["retry-trial-failure"] || null,
516
+ confirmLocalTrialRetry: booleanFlag(flags["confirm-local-trial-retry"]),
517
+ confirmLocalEvaluation: booleanFlag(flags["confirm-local-evaluation"])
518
+ }), json);
519
+ }
520
+
521
+ if (command === "learn-revalidation-start") {
522
+ return output(await beginLearningRevalidation({
523
+ root: flags.root || process.cwd(), learningId: positional[0],
524
+ confirmLocalValidation: booleanFlag(flags["confirm-local-validation"])
525
+ }), json);
526
+ }
527
+
528
+ if (command === "learn-revalidate") {
529
+ const measurements = String(flags.measurements || "").split(",").filter(Boolean);
530
+ const applications = String(flags.applications || "").split(",").filter(Boolean);
531
+ const deliveries = String(flags.deliveries || "").split(",").filter(Boolean);
532
+ if (!measurements.length || measurements.length !== applications.length || measurements.length !== deliveries.length) {
533
+ throw new Error("revalidation requires equally sized measurement, application, and delivery lists");
534
+ }
535
+ return output(await renewLearningValidation({
536
+ root: flags.root || process.cwd(), learningId: positional[0],
537
+ evidence: measurements.map((measurementId, index) => ({ measurementId,
538
+ applicationId: applications[index], deliveryId: deliveries[index] })),
539
+ confirmLocalValidation: booleanFlag(flags["confirm-local-validation"])
540
+ }), json);
541
+ }
542
+
543
+ if (command === "learn-measurement") {
544
+ return output(await recordLearningMeasurement({
545
+ root: flags.root || process.cwd(), id: positional[0], learningId: flags.learning,
546
+ evaluationId: flags.evaluation, phase: flags.phase, scope: learningScope(flags),
547
+ metric: {
548
+ name: flags.metric, direction: flags.direction, value: Number(flags.value),
549
+ blockingDefects: Number(flags["blocking-defects"] ?? 0)
550
+ },
551
+ measurement: {
552
+ kind: flags.measurement || "objective", evaluatorId: flags.evaluator,
553
+ runId: flags.run, sourceDigest: flags["source-digest"]
554
+ },
555
+ coverage: { datasetDigest: flags["dataset-digest"], caseCount: Number(flags["case-count"]) },
556
+ measuredAt: flags.at,
557
+ confirmLocalMeasurement: booleanFlag(flags["confirm-local-measurement"])
558
+ }), json);
559
+ }
560
+
561
+ if (command === "learn-measurement-revoke") {
562
+ return output(await revokeLearningMeasurement({
563
+ root: flags.root || process.cwd(), measurementId: positional[0], reasonCode: flags["reason-code"],
564
+ reason: flags.reason,
565
+ confirmation: booleanFlag(flags["confirm-local-measurement-revocation"])
566
+ ? "local-measurement-revocation-confirmed" : null
567
+ }), json);
568
+ }
569
+
570
+ if (command === "learn-evaluation-revoke") {
571
+ return output(await revokeLearningEvaluation({
572
+ root: flags.root || process.cwd(), evaluationId: positional[0], reasonCode: flags["reason-code"],
573
+ reason: flags.reason,
574
+ confirmation: booleanFlag(flags["confirm-local-evaluation-revocation"])
575
+ ? "local-evaluation-revocation-confirmed" : null
576
+ }), json);
577
+ }
578
+
579
+ if (command === "learn-validation-revoke") {
580
+ return output(await revokeLearningValidation({
581
+ root: flags.root || process.cwd(), validationLeaseId: positional[0], reasonCode: flags["reason-code"],
582
+ reason: flags.reason,
583
+ confirmation: booleanFlag(flags["confirm-local-validation-revocation"])
584
+ ? "local-validation-revocation-confirmed" : null
585
+ }), json);
586
+ }
587
+
588
+ if (command === "learn-trial-failure-revoke") {
589
+ return output(await revokeLearningTrialFailure({
590
+ root: flags.root || process.cwd(), trialFailureId: positional[0], reasonCode: flags["reason-code"],
591
+ reason: flags.reason,
592
+ confirmation: booleanFlag(flags["confirm-local-trial-failure-revocation"])
593
+ ? "local-trial-failure-revocation-confirmed" : null
594
+ }), json);
595
+ }
596
+
597
+ if (command === "learn-application-revoke") {
598
+ return output(await revokeLearningApplication({
599
+ root: flags.root || process.cwd(), applicationId: positional[0], reasonCode: flags["reason-code"],
600
+ reason: flags.reason,
601
+ confirmation: booleanFlag(flags["confirm-local-application-revocation"])
602
+ ? "local-application-revocation-confirmed" : null
603
+ }), json);
604
+ }
605
+
606
+ if (command === "learn-delivery-revoke") {
607
+ return output(await revokeLearningDelivery({
608
+ root: flags.root || process.cwd(), deliveryId: positional[0], reasonCode: flags["reason-code"],
609
+ reason: flags.reason,
610
+ confirmation: booleanFlag(flags["confirm-local-delivery-revocation"])
611
+ ? "local-delivery-revocation-confirmed" : null
612
+ }), json);
613
+ }
614
+
615
+ if (command === "learn-outcome-revoke") {
616
+ return output(await revokeLearningOutcome({
617
+ root: flags.root || process.cwd(), outcomeId: positional[0], reasonCode: flags["reason-code"],
618
+ reason: flags.reason,
619
+ confirmation: booleanFlag(flags["confirm-local-outcome-revocation"])
620
+ ? "local-outcome-revocation-confirmed" : null
621
+ }), json);
622
+ }
623
+
454
624
  if (command === "learn-outcome") {
625
+ const lineage = flags["measurement-receipt"] || null;
455
626
  return output(await recordLearningOutcome({
456
627
  root: flags.root || process.cwd(), learningId: positional[0], id: flags.id,
457
- phase: flags.phase, scope: learningScope(flags),
458
- metric: {
628
+ evaluationId: flags.evaluation, measurementReceiptId: lineage,
629
+ applicationId: flags.application || null, deliveryId: flags.delivery || null,
630
+ ...(lineage ? {} : { phase: flags.phase, scope: learningScope(flags), metric: {
459
631
  name: flags.metric, direction: flags.direction, value: Number(flags.value),
460
632
  blockingDefects: Number(flags["blocking-defects"] ?? 0)
461
633
  },
@@ -463,7 +635,11 @@ export async function run(argv = process.argv.slice(2)) {
463
635
  kind: flags.measurement || "objective", evaluatorId: flags.evaluator,
464
636
  sourceDigest: flags["source-digest"] || null
465
637
  },
466
- measuredAt: flags.at
638
+ coverage: {
639
+ datasetDigest: flags["dataset-digest"],
640
+ caseCount: Number(flags["case-count"])
641
+ },
642
+ measuredAt: flags.at })
467
643
  }), json);
468
644
  }
469
645
 
@@ -473,6 +649,20 @@ export async function run(argv = process.argv.slice(2)) {
473
649
  }), json);
474
650
  }
475
651
 
652
+ if (command === "learn-delivery-purge") {
653
+ return output(await purgeStaleLearningApplications({
654
+ root: positional[0] || process.cwd(),
655
+ confirmation: booleanFlag(flags["confirm-local-purge"]) ? "local-user-purge-confirmed" : null
656
+ }), json);
657
+ }
658
+
659
+ if (command === "learn-measurement-purge") {
660
+ return output(await purgeStaleLearningMeasurements({
661
+ root: positional[0] || process.cwd(),
662
+ confirmation: booleanFlag(flags["confirm-local-purge"]) ? "local-user-purge-confirmed" : null
663
+ }), json);
664
+ }
665
+
476
666
  if (command === "learn-rollback") {
477
667
  return output(await rollbackLearning({
478
668
  root: flags.root || process.cwd(), id: positional[0], reason: flags.reason
@@ -496,6 +686,9 @@ export async function run(argv = process.argv.slice(2)) {
496
686
  if (flags["outcome-max-age-days"] !== undefined) config.outcomeMaxAgeDays = Number(flags["outcome-max-age-days"]);
497
687
  if (flags["canary-receipts"] !== undefined) config.canaryReceipts = Number(flags["canary-receipts"]);
498
688
  if (flags["canary-ttl-days"] !== undefined) config.canaryTtlDays = Number(flags["canary-ttl-days"]);
689
+ if (flags["initial-trial-outcome-timeout-minutes"] !== undefined) {
690
+ config.initialTrialOutcomeTimeoutMinutes = Number(flags["initial-trial-outcome-timeout-minutes"]);
691
+ }
499
692
  if (!Object.keys(config).length) return output((await loadLearning(root)).learning.config, json);
500
693
  return output(await configureLearning({ root, config }), json);
501
694
  }
@@ -1005,12 +1198,202 @@ export async function run(argv = process.argv.slice(2)) {
1005
1198
  let learningOutcomes;
1006
1199
  try {
1007
1200
  const status = await learningOutcomeStatus({ root: positional[0] || process.cwd() });
1201
+ const unboundAfterReceipts = status.records.reduce((sum, item) => sum + item.afterReceipts - item.boundAfterReceipts, 0);
1202
+ const undeliveredAfterReceipts = status.records.reduce((sum, item) => sum + item.afterReceipts - item.deliveredAfterReceipts, 0);
1203
+ const stalePendingApplications = status.records.reduce((sum, item) => sum + item.stalePendingApplications, 0);
1204
+ const totalOutcomeReceipts = status.records.reduce((sum, item) => sum + item.beforeReceipts + item.afterReceipts, 0);
1205
+ const plannedOutcomeReceipts = status.records.reduce((sum, item) => sum + item.plannedOutcomeReceipts, 0);
1206
+ const coverageBoundReceipts = status.records.reduce((sum, item) => sum + item.coverageBoundReceipts, 0);
1207
+ const legacyCoverageReceipts = status.records.reduce((sum, item) => sum + item.legacyCoverageReceipts, 0);
1208
+ const provenanceBoundReceipts = status.records.reduce((sum, item) => sum + item.provenanceBoundReceipts, 0);
1209
+ const legacyProvenanceReceipts = status.records.reduce((sum, item) => sum + item.legacyProvenanceReceipts, 0);
1210
+ const measurementReceipts = status.records.reduce((sum, item) => sum + item.measurementReceipts, 0);
1211
+ const measurementLineageReceipts = status.records.reduce((sum, item) => sum + item.measurementLineageReceipts, 0);
1212
+ const consumedMeasurementReceipts = status.records.reduce((sum, item) => sum + item.consumedMeasurementReceipts, 0);
1213
+ const staleUnconsumedMeasurements = status.records.reduce((sum, item) => sum + item.staleUnconsumedMeasurements, 0);
1214
+ const lineageBoundReceipts = status.records.reduce((sum, item) => sum + item.lineageBoundReceipts, 0);
1215
+ const pairedOutcomeReceipts = status.records.reduce((sum, item) => sum + item.pairedOutcomeReceipts, 0);
1216
+ const pairedEvaluatorPairs = status.records.reduce((sum, item) => sum + item.pairedEvaluatorPairs, 0);
1217
+ const evaluatorRootBoundReceipts = status.records.reduce((sum, item) => sum + item.evaluatorRootBoundReceipts, 0);
1218
+ const independentEvaluatorRoots = status.records.reduce((sum, item) => sum + item.independentEvaluatorRoots, 0);
1219
+ const evaluatorRegistryContracts = status.records.reduce((sum, item) => sum + item.evaluatorRegistryContracts, 0);
1220
+ const inactiveEvaluatorRegistryContracts = status.records.reduce((sum, item) => sum + item.inactiveEvaluatorRegistryContracts, 0);
1221
+ const currentValidatedLessons = status.records.filter((item) => item.validationLeaseStatus === "current-validated").length;
1222
+ const staleValidatedLessons = status.records.filter((item) => item.validationLeaseStatus === "stale-validated").length;
1223
+ const unprovenValidatedLessons = status.records.filter((item) => item.validationLeaseStatus === "unproven-validated").length;
1224
+ const revokedValidatedLessons = status.records.filter((item) => item.validationLeaseStatus === "revoked-validated").length;
1225
+ const renewedValidationLeases = status.records.filter((item) =>
1226
+ ["agentspine.learning-validation/v2", "agentspine.learning-validation/v3",
1227
+ "agentspine.learning-validation/v4", "agentspine.learning-validation/v5"].includes(item.validationLeaseSchema)).length;
1228
+ const fixedCohortValidationLeases = status.records.filter((item) =>
1229
+ ["agentspine.learning-validation/v3", "agentspine.learning-validation/v4",
1230
+ "agentspine.learning-validation/v5"]
1231
+ .includes(item.validationLeaseSchema)).length;
1232
+ const admissionBoundValidationLeases = status.records.filter((item) =>
1233
+ ["agentspine.learning-validation/v4", "agentspine.learning-validation/v5"]
1234
+ .includes(item.validationLeaseSchema)).length;
1235
+ const trialBoundValidationLeases = status.records.filter((item) =>
1236
+ item.validationLeaseSchema === "agentspine.learning-validation/v5").length;
1237
+ const activeRevalidations = status.records.filter((item) => item.revalidationStatus === "active").length;
1238
+ const staleRevalidations = status.records.filter((item) => item.revalidationStatus === "stale").length;
1239
+ const fixedCohortRevalidations = status.records.filter((item) =>
1240
+ item.revalidationStatus === "active"
1241
+ && ["first-completed-turns", "first-admitted-turns",
1242
+ "first-admitted-trials"].includes(item.revalidationSelectionMode)).length;
1243
+ const admissionBoundRevalidations = status.records.filter((item) =>
1244
+ item.revalidationStatus === "active" && ["first-admitted-turns", "first-admitted-trials"]
1245
+ .includes(item.revalidationSelectionMode)).length;
1246
+ const trialBoundRevalidations = status.records.filter((item) =>
1247
+ item.revalidationStatus === "active" && item.revalidationSelectionMode === "first-admitted-trials").length;
1248
+ const requiredRevalidationDeliveries = status.records.reduce((sum, item) =>
1249
+ sum + item.revalidationRequiredDeliveries, 0);
1250
+ const completedRevalidationDeliveries = status.records.reduce((sum, item) =>
1251
+ sum + item.revalidationCompletedDeliveries, 0);
1252
+ const admittedRevalidationApplications = status.records.reduce((sum, item) =>
1253
+ sum + item.revalidationAdmittedApplications, 0);
1254
+ const initialTrialContracts = status.records.filter((item) => item.initialTrialMode === "first-admitted-trials").length;
1255
+ const requiredInitialTrials = status.records.reduce((sum, item) => sum + item.initialTrialSlots, 0);
1256
+ const admittedInitialApplications = status.records.reduce((sum, item) =>
1257
+ sum + item.initialAdmittedApplications, 0);
1258
+ const completedInitialDeliveries = status.records.reduce((sum, item) =>
1259
+ sum + item.initialCompletedDeliveries, 0);
1260
+ const incompleteInitialAdmissions = status.records.reduce((sum, item) =>
1261
+ sum + item.incompleteInitialAdmissions, 0);
1262
+ const targetBoundEvaluationContracts = status.records.reduce((sum, item) =>
1263
+ sum + item.targetBoundEvaluationContracts, 0);
1264
+ const targetBoundApplications = status.records.reduce((sum, item) =>
1265
+ sum + item.targetBoundApplications, 0);
1266
+ const deadlineBoundEvaluationContracts = status.records.reduce((sum, item) =>
1267
+ sum + item.deadlineBoundEvaluationContracts, 0);
1268
+ const stalenessBoundEvaluationContracts = status.records.reduce((sum, item) =>
1269
+ sum + item.stalenessBoundEvaluationContracts, 0);
1270
+ const promotionBoundEvaluationContracts = status.records.reduce((sum, item) =>
1271
+ sum + item.promotionBoundEvaluationContracts, 0);
1272
+ const candidateAdmissionEvaluationContracts = status.records.reduce((sum, item) =>
1273
+ sum + item.candidateAdmissionEvaluationContracts, 0);
1274
+ const candidateEvidenceCohortEvaluationContracts = status.records.reduce((sum, item) =>
1275
+ sum + item.candidateEvidenceCohortEvaluationContracts, 0);
1276
+ const blockingDefectBoundEvaluationContracts = status.records.reduce((sum, item) =>
1277
+ sum + item.blockingDefectBoundEvaluationContracts, 0);
1278
+ const evidenceSourceBoundEvaluationContracts = status.records.reduce((sum, item) =>
1279
+ sum + item.evidenceSourceBoundEvaluationContracts, 0);
1280
+ const blockingDefectOutcomeReceipts = status.records.reduce((sum, item) =>
1281
+ sum + item.blockingDefectOutcomeReceipts, 0);
1282
+ const deadlineBoundApplications = status.records.reduce((sum, item) =>
1283
+ sum + item.deadlineBoundApplications, 0);
1284
+ const trialRetryEvaluationContracts = status.records.reduce((sum, item) =>
1285
+ sum + item.trialRetryEvaluationContracts, 0);
1286
+ const comparableTrialRetryEvaluationContracts = status.records.reduce((sum, item) =>
1287
+ sum + item.comparableTrialRetryEvaluationContracts, 0);
1288
+ const boundedTrialRetryEvaluationContracts = status.records.reduce((sum, item) =>
1289
+ sum + item.boundedTrialRetryEvaluationContracts, 0);
1290
+ const trialRetryExhaustionReceipts = status.records.reduce((sum, item) =>
1291
+ sum + item.trialRetryExhaustionReceipts, 0);
1292
+ const trialFailureReceipts = status.records.reduce((sum, item) => sum + item.trialFailureReceipts, 0);
1293
+ const trialFailureRevocationReceipts = status.records.reduce((sum, item) =>
1294
+ sum + item.trialFailureRevocationReceipts, 0);
1295
+ const evaluationRevocationReceipts = status.records.reduce((sum, item) => sum + item.evaluationRevocationReceipts, 0);
1296
+ const validationRevocationReceipts = status.records.reduce((sum, item) => sum + item.validationRevocationReceipts, 0);
1297
+ const evidenceRevocationReceipts = status.records.reduce((sum, item) => sum + item.evidenceRevocationReceipts, 0);
1298
+ const measurementRevocationReceipts = status.records.reduce((sum, item) => sum + item.measurementRevocationReceipts, 0);
1299
+ const applicationRevocationReceipts = status.records.reduce((sum, item) => sum + item.applicationRevocationReceipts, 0);
1300
+ const deliveryRevocationReceipts = status.records.reduce((sum, item) => sum + item.deliveryRevocationReceipts, 0);
1301
+ const outcomeRevocationReceipts = status.records.reduce((sum, item) => sum + item.outcomeRevocationReceipts, 0);
1302
+ const deliveryTimeoutFailures = status.records.reduce((sum, item) => sum + item.deliveryTimeoutFailures, 0);
1303
+ const outcomeTimeoutFailures = status.records.reduce((sum, item) => sum + item.outcomeTimeoutFailures, 0);
1304
+ const pendingInitialOutcomes = status.records.reduce((sum, item) => sum + item.pendingInitialOutcomes, 0);
1305
+ const staleInitialOutcomes = status.records.reduce((sum, item) => sum + item.staleInitialOutcomes, 0);
1306
+ const unplannedOutcomeReceipts = totalOutcomeReceipts - plannedOutcomeReceipts;
1008
1307
  learningOutcomes = {
1009
- status: status.records.some((item) => item.canaryStatus === "stale") ? "degraded" : "healthy",
1308
+ status: status.records.some((item) => ["stale", "revoked", "revoked-evaluation", "revoked-validation", "revoked-evidence", "revoked-measurement", "revoked-application", "revoked-delivery", "revoked-outcome", "unproven", "failed-trial"].includes(item.canaryStatus))
1309
+ || unboundAfterReceipts > 0 || undeliveredAfterReceipts > 0 || unplannedOutcomeReceipts > 0
1310
+ || stalePendingApplications > 0 || staleUnconsumedMeasurements > 0
1311
+ || inactiveEvaluatorRegistryContracts > 0 || staleRevalidations > 0
1312
+ || staleInitialOutcomes > 0 || trialFailureRevocationReceipts > 0 ? "degraded" : "healthy",
1010
1313
  candidates: status.records.length,
1011
1314
  activeCanaries: status.records.filter((item) => item.canaryStatus === "active").length,
1012
1315
  validatedCanaries: status.records.filter((item) => item.canaryStatus === "validated").length,
1013
1316
  staleCanaries: status.records.filter((item) => item.canaryStatus === "stale").length,
1317
+ awaitingApplication: status.records.filter((item) => item.canaryStatus === "active" && item.applicationReceipts === 0).length,
1318
+ applicationReceipts: status.records.reduce((sum, item) => sum + item.applicationReceipts, 0),
1319
+ deliveryReceipts: status.records.reduce((sum, item) => sum + item.deliveryReceipts, 0),
1320
+ pendingApplications: status.records.reduce((sum, item) => sum + item.pendingApplications, 0),
1321
+ stalePendingApplications,
1322
+ evaluationContracts: status.records.reduce((sum, item) => sum + item.evaluationContracts, 0),
1323
+ targetBoundEvaluationContracts,
1324
+ targetBoundApplications,
1325
+ deadlineBoundEvaluationContracts,
1326
+ stalenessBoundEvaluationContracts,
1327
+ promotionBoundEvaluationContracts,
1328
+ candidateAdmissionEvaluationContracts,
1329
+ candidateEvidenceCohortEvaluationContracts,
1330
+ blockingDefectBoundEvaluationContracts,
1331
+ evidenceSourceBoundEvaluationContracts,
1332
+ blockingDefectOutcomeReceipts,
1333
+ deadlineBoundApplications,
1334
+ trialRetryEvaluationContracts,
1335
+ comparableTrialRetryEvaluationContracts,
1336
+ boundedTrialRetryEvaluationContracts,
1337
+ trialRetryExhaustionReceipts,
1338
+ trialFailureReceipts,
1339
+ trialFailureRevocationReceipts,
1340
+ evaluationRevocationReceipts,
1341
+ validationRevocationReceipts,
1342
+ evidenceRevocationReceipts,
1343
+ measurementRevocationReceipts,
1344
+ applicationRevocationReceipts,
1345
+ deliveryRevocationReceipts,
1346
+ outcomeRevocationReceipts,
1347
+ deliveryTimeoutFailures,
1348
+ outcomeTimeoutFailures,
1349
+ pendingInitialOutcomes,
1350
+ staleInitialOutcomes,
1351
+ plannedOutcomeReceipts,
1352
+ coverageBoundReceipts,
1353
+ legacyCoverageReceipts,
1354
+ provenanceBoundReceipts,
1355
+ legacyProvenanceReceipts,
1356
+ measurementReceipts,
1357
+ measurementLineageReceipts,
1358
+ consumedMeasurementReceipts,
1359
+ staleUnconsumedMeasurements,
1360
+ lineageBoundReceipts,
1361
+ pairedOutcomeReceipts,
1362
+ pairedEvaluatorPairs,
1363
+ evaluatorRootBoundReceipts,
1364
+ independentEvaluatorRoots,
1365
+ activeEvaluatorRoots: status.evaluatorRegistry.active,
1366
+ revokedEvaluatorRoots: status.evaluatorRegistry.revoked,
1367
+ evaluatorRegistryBindings: status.evaluatorRegistry.bindings,
1368
+ validationLeases: status.evaluatorRegistry.validationLeases,
1369
+ renewedValidationLeases,
1370
+ fixedCohortValidationLeases,
1371
+ admissionBoundValidationLeases,
1372
+ trialBoundValidationLeases,
1373
+ initialTrialContracts,
1374
+ requiredInitialTrials,
1375
+ admittedInitialApplications,
1376
+ completedInitialDeliveries,
1377
+ incompleteInitialAdmissions,
1378
+ activeRevalidations,
1379
+ staleRevalidations,
1380
+ fixedCohortRevalidations,
1381
+ admissionBoundRevalidations,
1382
+ trialBoundRevalidations,
1383
+ requiredRevalidationDeliveries,
1384
+ admittedRevalidationApplications,
1385
+ completedRevalidationDeliveries,
1386
+ currentValidatedLessons,
1387
+ staleValidatedLessons,
1388
+ unprovenValidatedLessons,
1389
+ revokedValidatedLessons,
1390
+ evaluatorRegistryContracts,
1391
+ inactiveEvaluatorRegistryContracts,
1392
+ unplannedOutcomeReceipts,
1393
+ boundAfterReceipts: status.records.reduce((sum, item) => sum + item.boundAfterReceipts, 0),
1394
+ unboundAfterReceipts,
1395
+ deliveredAfterReceipts: status.records.reduce((sum, item) => sum + item.deliveredAfterReceipts, 0),
1396
+ undeliveredAfterReceipts,
1014
1397
  contradictions: status.records.filter((item) => item.conflictsWith.length > 0).length,
1015
1398
  authority: "context-only"
1016
1399
  };