@openclawbrain/openclaw 0.1.9 → 0.1.11

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/src/index.js CHANGED
@@ -910,6 +910,216 @@ function classifyCompileFailure(error, activationRoot) {
910
910
  }
911
911
  return failOpenCompileResult(error, resolvedActivationRoot);
912
912
  }
913
+ function uniqueNotes(notes) {
914
+ return [...new Set(notes.filter((note) => note.length > 0))];
915
+ }
916
+ function clampInteger(value, minimum, maximum) {
917
+ return Math.min(maximum, Math.max(minimum, Math.round(value)));
918
+ }
919
+ export function deriveEmpiricalStructuralBudget(input) {
920
+ const requestedStrategy = input.requestedStrategy ?? "fixed_v1";
921
+ const defaultMaxContextBlocks = input.defaultMaxContextBlocks ?? 4;
922
+ const minimumMaxContextBlocks = input.minimumMaxContextBlocks ?? 2;
923
+ const maximumMaxContextBlocks = input.maximumMaxContextBlocks ?? 6;
924
+ if (input.requestedMaxContextBlocks !== undefined) {
925
+ const maxContextBlocks = clampInteger(input.requestedMaxContextBlocks, 0, Number.MAX_SAFE_INTEGER);
926
+ return {
927
+ requestedStrategy,
928
+ effectiveStrategy: requestedStrategy,
929
+ maxContextBlocks,
930
+ defaultMaxContextBlocks,
931
+ evidence: { split: 0, merge: 0, prune: 0, connect: 0 },
932
+ evidenceTotal: 0,
933
+ tendencies: { split: 0, merge: 0, prune: 0, connect: 0 },
934
+ notes: [
935
+ `requested_budget_strategy=${requestedStrategy}`,
936
+ `requested_max_context_blocks=${maxContextBlocks}`,
937
+ `resolved_budget_strategy=${requestedStrategy}`,
938
+ `resolved_max_context_blocks=${maxContextBlocks}`,
939
+ "structural_budget_source=caller_override"
940
+ ]
941
+ };
942
+ }
943
+ if (requestedStrategy !== "empirical_v1") {
944
+ return {
945
+ requestedStrategy,
946
+ effectiveStrategy: requestedStrategy,
947
+ maxContextBlocks: defaultMaxContextBlocks,
948
+ defaultMaxContextBlocks,
949
+ evidence: { split: 0, merge: 0, prune: 0, connect: 0 },
950
+ evidenceTotal: 0,
951
+ tendencies: { split: 0, merge: 0, prune: 0, connect: 0 },
952
+ notes: [
953
+ `requested_budget_strategy=${requestedStrategy}`,
954
+ `resolved_budget_strategy=${requestedStrategy}`,
955
+ `resolved_max_context_blocks=${defaultMaxContextBlocks}`,
956
+ `structural_budget_source=${requestedStrategy === "fixed_v1" ? "fixed_default" : "fixed_fallback"}`
957
+ ]
958
+ };
959
+ }
960
+ const evidence = {
961
+ split: Math.max(0, input.evolution?.structuralOps.split ?? 0),
962
+ merge: Math.max(0, input.evolution?.structuralOps.merge ?? 0),
963
+ prune: Math.max(0, Math.max(input.evolution?.structuralOps.prune ?? 0, input.evolution?.prunedBlockIds.length ?? 0)),
964
+ connect: Math.max(0, input.evolution?.structuralOps.connect ?? 0)
965
+ };
966
+ const evidenceTotal = evidence.split + evidence.merge + evidence.prune + evidence.connect;
967
+ if (evidenceTotal === 0) {
968
+ return {
969
+ requestedStrategy,
970
+ effectiveStrategy: "fixed_v1",
971
+ maxContextBlocks: defaultMaxContextBlocks,
972
+ defaultMaxContextBlocks,
973
+ evidence,
974
+ evidenceTotal,
975
+ tendencies: { split: 0, merge: 0, prune: 0, connect: 0 },
976
+ notes: [
977
+ `requested_budget_strategy=${requestedStrategy}`,
978
+ "resolved_budget_strategy=fixed_v1",
979
+ `resolved_max_context_blocks=${defaultMaxContextBlocks}`,
980
+ "structural_budget_source=no_evidence_fallback"
981
+ ]
982
+ };
983
+ }
984
+ const tendencies = {
985
+ split: evidence.split / evidenceTotal,
986
+ merge: evidence.merge / evidenceTotal,
987
+ prune: evidence.prune / evidenceTotal,
988
+ connect: evidence.connect / evidenceTotal
989
+ };
990
+ const expansionPressure = tendencies.split + tendencies.connect;
991
+ const contractionPressure = tendencies.merge + tendencies.prune;
992
+ const directionalPressure = expansionPressure - contractionPressure;
993
+ const maxContextBlocks = clampInteger(defaultMaxContextBlocks + directionalPressure * 2, minimumMaxContextBlocks, maximumMaxContextBlocks);
994
+ return {
995
+ requestedStrategy,
996
+ effectiveStrategy: requestedStrategy,
997
+ maxContextBlocks,
998
+ defaultMaxContextBlocks,
999
+ evidence,
1000
+ evidenceTotal,
1001
+ tendencies,
1002
+ notes: [
1003
+ `requested_budget_strategy=${requestedStrategy}`,
1004
+ `resolved_budget_strategy=${requestedStrategy}`,
1005
+ `resolved_max_context_blocks=${maxContextBlocks}`,
1006
+ "structural_budget_source=graph_evolution_empirical_v1",
1007
+ `structural_budget_evidence=split:${evidence.split},merge:${evidence.merge},prune:${evidence.prune},connect:${evidence.connect},total:${evidenceTotal}`,
1008
+ `structural_budget_tendencies=split:${tendencies.split.toFixed(4)},merge:${tendencies.merge.toFixed(4)},prune:${tendencies.prune.toFixed(4)},connect:${tendencies.connect.toFixed(4)}`,
1009
+ `structural_budget_pressures=expand:${expansionPressure.toFixed(4)},contract:${contractionPressure.toFixed(4)},directional:${directionalPressure.toFixed(4)}`
1010
+ ]
1011
+ };
1012
+ }
1013
+ export function deriveEmpiricalStructuralBudgetFromCompileSignals(input) {
1014
+ const requestedStrategy = input.requestedStrategy ?? "fixed_v1";
1015
+ const defaultMaxContextBlocks = input.defaultMaxContextBlocks ?? 4;
1016
+ const minimumMaxContextBlocks = input.minimumMaxContextBlocks ?? 2;
1017
+ const maximumMaxContextBlocks = input.maximumMaxContextBlocks ?? 6;
1018
+ if (input.requestedMaxContextBlocks !== undefined) {
1019
+ const maxContextBlocks = clampInteger(input.requestedMaxContextBlocks, 0, Number.MAX_SAFE_INTEGER);
1020
+ return {
1021
+ requestedStrategy,
1022
+ effectiveStrategy: requestedStrategy,
1023
+ maxContextBlocks,
1024
+ defaultMaxContextBlocks,
1025
+ evidence: { split: 0, merge: 0, prune: 0, connect: 0 },
1026
+ evidenceTotal: 0,
1027
+ tendencies: { split: 0, merge: 0, prune: 0, connect: 0 },
1028
+ notes: [
1029
+ `requested_budget_strategy=${requestedStrategy}`,
1030
+ `requested_max_context_blocks=${maxContextBlocks}`,
1031
+ `resolved_budget_strategy=${requestedStrategy}`,
1032
+ `resolved_max_context_blocks=${maxContextBlocks}`,
1033
+ "structural_budget_source=caller_override"
1034
+ ]
1035
+ };
1036
+ }
1037
+ if (requestedStrategy !== "empirical_v1") {
1038
+ return {
1039
+ requestedStrategy,
1040
+ effectiveStrategy: requestedStrategy,
1041
+ maxContextBlocks: defaultMaxContextBlocks,
1042
+ defaultMaxContextBlocks,
1043
+ evidence: { split: 0, merge: 0, prune: 0, connect: 0 },
1044
+ evidenceTotal: 0,
1045
+ tendencies: { split: 0, merge: 0, prune: 0, connect: 0 },
1046
+ notes: [
1047
+ `requested_budget_strategy=${requestedStrategy}`,
1048
+ `resolved_budget_strategy=${requestedStrategy}`,
1049
+ `resolved_max_context_blocks=${defaultMaxContextBlocks}`,
1050
+ `structural_budget_source=${requestedStrategy === "fixed_v1" ? "fixed_default" : "fixed_fallback"}`
1051
+ ]
1052
+ };
1053
+ }
1054
+ const compileEvidence = {
1055
+ expansionCandidates: Math.max(0, (input.structuralSignals?.matchedCandidateCount ?? 0) - (input.structuralSignals?.selectedMatchedCount ?? 0)),
1056
+ traversalActivations: Math.max(0, input.structuralSignals?.traversalActivatedCount ?? 0),
1057
+ overlapPruned: Math.max(0, input.structuralSignals?.overlapPrunedCount ?? 0)
1058
+ };
1059
+ const evidence = {
1060
+ split: compileEvidence.expansionCandidates,
1061
+ merge: 0,
1062
+ prune: compileEvidence.overlapPruned,
1063
+ connect: compileEvidence.traversalActivations
1064
+ };
1065
+ const evidenceTotal = evidence.split + evidence.merge + evidence.prune + evidence.connect;
1066
+ if (evidenceTotal === 0) {
1067
+ return {
1068
+ requestedStrategy,
1069
+ effectiveStrategy: "fixed_v1",
1070
+ maxContextBlocks: defaultMaxContextBlocks,
1071
+ defaultMaxContextBlocks,
1072
+ evidence,
1073
+ evidenceTotal,
1074
+ tendencies: { split: 0, merge: 0, prune: 0, connect: 0 },
1075
+ notes: [
1076
+ `requested_budget_strategy=${requestedStrategy}`,
1077
+ "resolved_budget_strategy=fixed_v1",
1078
+ `resolved_max_context_blocks=${defaultMaxContextBlocks}`,
1079
+ "structural_budget_source=no_compile_signal_evidence_fallback"
1080
+ ]
1081
+ };
1082
+ }
1083
+ const tendencies = {
1084
+ split: evidence.split / evidenceTotal,
1085
+ merge: 0,
1086
+ prune: evidence.prune / evidenceTotal,
1087
+ connect: evidence.connect / evidenceTotal
1088
+ };
1089
+ const expansionPressure = tendencies.split + tendencies.connect;
1090
+ const contractionPressure = tendencies.prune;
1091
+ const directionalPressure = expansionPressure - contractionPressure;
1092
+ const maxContextBlocks = clampInteger(defaultMaxContextBlocks + directionalPressure * 2, minimumMaxContextBlocks, maximumMaxContextBlocks);
1093
+ return {
1094
+ requestedStrategy,
1095
+ effectiveStrategy: requestedStrategy,
1096
+ maxContextBlocks,
1097
+ defaultMaxContextBlocks,
1098
+ evidence,
1099
+ evidenceTotal,
1100
+ tendencies,
1101
+ notes: [
1102
+ `requested_budget_strategy=${requestedStrategy}`,
1103
+ `resolved_budget_strategy=${requestedStrategy}`,
1104
+ `resolved_max_context_blocks=${maxContextBlocks}`,
1105
+ "structural_budget_source=compile_structural_signals_empirical_v1",
1106
+ `structural_budget_compile_evidence=matched_unselected:${compileEvidence.expansionCandidates},traversal:${compileEvidence.traversalActivations},overlap_pruned:${compileEvidence.overlapPruned},total:${evidenceTotal}`,
1107
+ `structural_budget_tendencies=split:${tendencies.split.toFixed(4)},merge:${tendencies.merge.toFixed(4)},prune:${tendencies.prune.toFixed(4)},connect:${tendencies.connect.toFixed(4)}`,
1108
+ `structural_budget_pressures=expand:${expansionPressure.toFixed(4)},contract:${contractionPressure.toFixed(4)},directional:${directionalPressure.toFixed(4)}`
1109
+ ]
1110
+ };
1111
+ }
1112
+ function resolveCompileBudget(target, input) {
1113
+ const pack = loadPackFromActivation(target.activationRoot, "active");
1114
+ return deriveEmpiricalStructuralBudget({
1115
+ requestedStrategy: input.budgetStrategy ?? "empirical_v1",
1116
+ ...(input.maxContextBlocks !== undefined ? { requestedMaxContextBlocks: input.maxContextBlocks } : {}),
1117
+ ...(pack?.graph.evolution !== undefined ? { evolution: pack.graph.evolution } : {}),
1118
+ defaultMaxContextBlocks: 4,
1119
+ minimumMaxContextBlocks: 2,
1120
+ maximumMaxContextBlocks: 6
1121
+ });
1122
+ }
913
1123
  export function resolveActivePackForCompile(activationRoot) {
914
1124
  const resolvedActivationRoot = path.resolve(normalizeNonEmptyString(activationRoot, "activationRoot"));
915
1125
  const inspection = inspectActivationState(resolvedActivationRoot);
@@ -932,11 +1142,12 @@ export function compileRuntimeContext(input) {
932
1142
  const runtimeHints = normalizeRuntimeHints(input.runtimeHints);
933
1143
  try {
934
1144
  const target = resolveActivePackForCompile(activationRoot);
1145
+ const resolvedBudget = resolveCompileBudget(target, input);
935
1146
  const compile = compileRuntimeFromActivation(activationRoot, {
936
1147
  contract: CONTRACT_IDS.runtimeCompile,
937
1148
  agentId,
938
1149
  userMessage: normalizeNonEmptyString(input.message, "message"),
939
- maxContextBlocks: normalizeNonNegativeInteger(input.maxContextBlocks, "maxContextBlocks", 4),
1150
+ maxContextBlocks: resolvedBudget.maxContextBlocks,
940
1151
  ...(input.maxContextChars !== undefined
941
1152
  ? { maxContextChars: normalizeNonNegativeInteger(input.maxContextChars, "maxContextChars", input.maxContextChars) }
942
1153
  : {}),
@@ -949,7 +1160,7 @@ export function compileRuntimeContext(input) {
949
1160
  ...compile.response,
950
1161
  diagnostics: {
951
1162
  ...compile.response.diagnostics,
952
- notes: [...compile.response.diagnostics.notes, "OpenClaw remains the runtime owner"]
1163
+ notes: uniqueNotes([...compile.response.diagnostics.notes, ...resolvedBudget.notes, "OpenClaw remains the runtime owner"])
953
1164
  }
954
1165
  };
955
1166
  return {
@@ -1147,6 +1358,7 @@ function buildAttachStatusCompileInput(activationRoot, compile) {
1147
1358
  agentId: normalizeOptionalString(compile?.agentId) ?? `${DEFAULT_AGENT_ID}-attach-status`,
1148
1359
  message: normalizeOptionalString(compile?.message) ?? DEFAULT_ATTACH_STATUS_MESSAGE,
1149
1360
  ...(compile?.maxContextBlocks !== undefined ? { maxContextBlocks: compile.maxContextBlocks } : {}),
1361
+ ...(compile?.budgetStrategy !== undefined ? { budgetStrategy: compile.budgetStrategy } : {}),
1150
1362
  ...(compile?.maxContextChars !== undefined ? { maxContextChars: compile.maxContextChars } : {}),
1151
1363
  ...(compile?.mode !== undefined ? { mode: compile.mode } : {}),
1152
1364
  ...(compile?.compactionMode !== undefined ? { compactionMode: compile.compactionMode } : {}),
@@ -1589,6 +1801,7 @@ export function runRuntimeTurn(turn, options = {}) {
1589
1801
  message: normalizeNonEmptyString(turn.userMessage, "userMessage"),
1590
1802
  ...(agentId !== undefined ? { agentId } : {}),
1591
1803
  ...(turn.maxContextBlocks !== undefined ? { maxContextBlocks: turn.maxContextBlocks } : {}),
1804
+ ...(turn.budgetStrategy !== undefined ? { budgetStrategy: turn.budgetStrategy } : {}),
1592
1805
  ...(turn.mode !== undefined ? { mode: turn.mode } : {}),
1593
1806
  ...(turn.runtimeHints !== undefined ? { runtimeHints: turn.runtimeHints } : {})
1594
1807
  };
@@ -2571,6 +2784,54 @@ function summarizeBrainState(active, observability) {
2571
2784
  detail
2572
2785
  };
2573
2786
  }
2787
+ function summarizeGraphObservability(active, observability) {
2788
+ if (active === null) {
2789
+ return {
2790
+ available: false,
2791
+ runtimePlasticitySource: null,
2792
+ structuralOps: null,
2793
+ changed: null,
2794
+ operationsApplied: [],
2795
+ liveBlockCount: null,
2796
+ prunedBlockCount: null,
2797
+ prePruneBlockCount: null,
2798
+ strongestBlockId: null,
2799
+ operatorSummary: null,
2800
+ detail: "no active pack is pinned, so there is no structural graph surface to inspect"
2801
+ };
2802
+ }
2803
+ const graphEvolution = observability.graphEvolutionLog;
2804
+ if (graphEvolution === null) {
2805
+ return {
2806
+ available: false,
2807
+ runtimePlasticitySource: observability.graphDynamics.runtimePlasticitySource,
2808
+ structuralOps: null,
2809
+ changed: null,
2810
+ operationsApplied: [],
2811
+ liveBlockCount: null,
2812
+ prunedBlockCount: null,
2813
+ prePruneBlockCount: null,
2814
+ strongestBlockId: null,
2815
+ operatorSummary: null,
2816
+ detail: "active pack is present, but the graph evolution log is missing from activation observability"
2817
+ };
2818
+ }
2819
+ return {
2820
+ available: true,
2821
+ runtimePlasticitySource: observability.graphDynamics.runtimePlasticitySource,
2822
+ structuralOps: { ...graphEvolution.structuralOps },
2823
+ changed: graphEvolution.structuralEvolutionSummary.changed,
2824
+ operationsApplied: [...graphEvolution.structuralEvolutionSummary.operationsApplied],
2825
+ liveBlockCount: graphEvolution.structuralEvolutionSummary.liveBlockCount,
2826
+ prunedBlockCount: graphEvolution.structuralEvolutionSummary.prunedBlockCount,
2827
+ prePruneBlockCount: graphEvolution.structuralEvolutionSummary.prePruneBlockCount,
2828
+ strongestBlockId: graphEvolution.strongestBlockId,
2829
+ operatorSummary: graphEvolution.structuralEvolutionSummary.operatorSummary,
2830
+ detail: graphEvolution.structuralEvolutionSummary.changed
2831
+ ? graphEvolution.structuralEvolutionSummary.operatorSummary
2832
+ : "active pack graph is stable with no structural evolution beyond the current promoted artifact"
2833
+ };
2834
+ }
2574
2835
  function summarizeServePath(compile) {
2575
2836
  if (compile === null) {
2576
2837
  return {
@@ -2583,6 +2844,12 @@ function summarizeServePath(compile) {
2583
2844
  selectionMode: null,
2584
2845
  refreshStatus: null,
2585
2846
  freshnessChecksum: null,
2847
+ requestedBudgetStrategy: null,
2848
+ resolvedBudgetStrategy: null,
2849
+ resolvedMaxContextBlocks: null,
2850
+ structuralBudgetSource: null,
2851
+ structuralBudgetEvidence: null,
2852
+ structuralBudgetPressures: null,
2586
2853
  contextAttribution: buildContextAttributionSummary({
2587
2854
  fallbackToStaticContext: false,
2588
2855
  hardRequirementViolated: false,
@@ -2603,10 +2870,17 @@ function summarizeServePath(compile) {
2603
2870
  selectionMode: null,
2604
2871
  refreshStatus: null,
2605
2872
  freshnessChecksum: null,
2873
+ requestedBudgetStrategy: null,
2874
+ resolvedBudgetStrategy: null,
2875
+ resolvedMaxContextBlocks: null,
2876
+ structuralBudgetSource: null,
2877
+ structuralBudgetEvidence: null,
2878
+ structuralBudgetPressures: null,
2606
2879
  contextAttribution: compile.contextAttribution,
2607
2880
  error: compile.error
2608
2881
  };
2609
2882
  }
2883
+ const resolvedMaxContextBlocksValue = readDiagnosticNoteValue(compile.notes, "resolved_max_context_blocks=");
2610
2884
  return {
2611
2885
  state: "serving_active_pack",
2612
2886
  fallbackToStaticContext: compile.fallbackToStaticContext,
@@ -2617,6 +2891,13 @@ function summarizeServePath(compile) {
2617
2891
  selectionMode: readDiagnosticNoteValue(compile.notes, "selection_mode="),
2618
2892
  refreshStatus: readDiagnosticNoteValue(compile.notes, "router_refresh_status="),
2619
2893
  freshnessChecksum: readDiagnosticNoteValue(compile.notes, "router_freshness_checksum="),
2894
+ requestedBudgetStrategy: readDiagnosticNoteValue(compile.notes, "requested_budget_strategy="),
2895
+ resolvedBudgetStrategy: readDiagnosticNoteValue(compile.notes, "resolved_budget_strategy="),
2896
+ resolvedMaxContextBlocks: resolvedMaxContextBlocksValue === null ? null : Number.parseInt(resolvedMaxContextBlocksValue, 10),
2897
+ structuralBudgetSource: readDiagnosticNoteValue(compile.notes, "structural_budget_source="),
2898
+ structuralBudgetEvidence: readDiagnosticNoteValue(compile.notes, "structural_budget_compile_evidence=") ??
2899
+ readDiagnosticNoteValue(compile.notes, "structural_budget_evidence="),
2900
+ structuralBudgetPressures: readDiagnosticNoteValue(compile.notes, "structural_budget_pressures="),
2620
2901
  contextAttribution: compile.contextAttribution,
2621
2902
  error: compile.error
2622
2903
  };
@@ -2649,6 +2930,112 @@ function loadOperatorEventExport(input) {
2649
2930
  exportedAt: null
2650
2931
  };
2651
2932
  }
2933
+ function summarizePrincipalItem(event) {
2934
+ if (event.principal === undefined) {
2935
+ return null;
2936
+ }
2937
+ return {
2938
+ eventId: event.eventId,
2939
+ contract: event.contract,
2940
+ kind: event.kind,
2941
+ sequence: event.sequence,
2942
+ createdAt: event.createdAt,
2943
+ teacherIdentity: event.principal.teacherIdentity,
2944
+ teacherAuthority: event.principal.teacherAuthority,
2945
+ priorityClass: event.principal.priorityClass,
2946
+ scopeKind: event.principal.principalScope.kind,
2947
+ supersedes: [...(event.principal.supersedes ?? [])]
2948
+ };
2949
+ }
2950
+ function summarizePrincipalFeedback(event) {
2951
+ const base = summarizePrincipalItem(event);
2952
+ if (base === null) {
2953
+ return null;
2954
+ }
2955
+ return {
2956
+ ...base,
2957
+ content: event.content,
2958
+ relatedInteractionId: event.relatedInteractionId ?? null
2959
+ };
2960
+ }
2961
+ function isPrincipalEvent(event) {
2962
+ return event.principal?.teacherRole === "principal";
2963
+ }
2964
+ function summarizePrincipalObservability(input, active) {
2965
+ const loaded = loadOperatorEventExport(input);
2966
+ if (loaded === null) {
2967
+ return {
2968
+ available: false,
2969
+ sourcePath: null,
2970
+ sourceKind: "missing",
2971
+ latestFeedback: null,
2972
+ latestCorrection: null,
2973
+ pendingCount: null,
2974
+ pendingItems: [],
2975
+ latestPromotion: {
2976
+ known: false,
2977
+ at: null,
2978
+ activePackId: active?.packId ?? null,
2979
+ activeEventRangeEnd: active?.eventRange.end ?? null,
2980
+ includesLatestFeedback: null,
2981
+ includesLatestCorrection: null,
2982
+ note: "no event export path supplied"
2983
+ },
2984
+ servingDownstreamOfLatestCorrection: null,
2985
+ detail: "no event export path supplied"
2986
+ };
2987
+ }
2988
+ const allPrincipalEvents = sortNormalizedEvents([
2989
+ ...loaded.normalizedEventExport.interactionEvents,
2990
+ ...loaded.normalizedEventExport.feedbackEvents
2991
+ ]).filter(isPrincipalEvent);
2992
+ const principalFeedbackEvents = loaded.normalizedEventExport.feedbackEvents
2993
+ .filter((event) => isPrincipalEvent(event))
2994
+ .sort((left, right) => {
2995
+ if (left.sequence !== right.sequence) {
2996
+ return right.sequence - left.sequence;
2997
+ }
2998
+ return right.createdAt.localeCompare(left.createdAt);
2999
+ });
3000
+ const latestFeedbackEvent = principalFeedbackEvents[0] ?? null;
3001
+ const latestCorrectionEvent = principalFeedbackEvents.find((event) => event.kind === "correction") ?? null;
3002
+ const activeEventRangeEnd = active?.eventRange.end ?? null;
3003
+ const pendingEvents = activeEventRangeEnd === null ? allPrincipalEvents : allPrincipalEvents.filter((event) => event.sequence > activeEventRangeEnd);
3004
+ const includesLatestFeedback = latestFeedbackEvent === null ? null : activeEventRangeEnd !== null && latestFeedbackEvent.sequence <= activeEventRangeEnd;
3005
+ const includesLatestCorrection = latestCorrectionEvent === null ? null : activeEventRangeEnd !== null && latestCorrectionEvent.sequence <= activeEventRangeEnd;
3006
+ return {
3007
+ available: true,
3008
+ sourcePath: loaded.sourcePath,
3009
+ sourceKind: loaded.sourceKind,
3010
+ latestFeedback: latestFeedbackEvent === null ? null : summarizePrincipalFeedback(latestFeedbackEvent),
3011
+ latestCorrection: latestCorrectionEvent === null ? null : summarizePrincipalFeedback(latestCorrectionEvent),
3012
+ pendingCount: pendingEvents.length,
3013
+ pendingItems: pendingEvents.map((event) => summarizePrincipalItem(event)).filter((item) => item !== null),
3014
+ latestPromotion: {
3015
+ known: active !== null && active.eventRange.count > 0,
3016
+ at: active?.updatedAt ?? null,
3017
+ activePackId: active?.packId ?? null,
3018
+ activeEventRangeEnd,
3019
+ includesLatestFeedback,
3020
+ includesLatestCorrection,
3021
+ note: active === null
3022
+ ? "no active pack is serving, so principal promotion state is not observable"
3023
+ : active.eventRange.count === 0
3024
+ ? "active pack is still awaiting the first export, so no principal event has been promoted into serving"
3025
+ : includesLatestFeedback === true
3026
+ ? "active serving range already covers the latest principal feedback"
3027
+ : latestFeedbackEvent === null
3028
+ ? "no principal feedback is present in the supplied export"
3029
+ : "latest principal feedback sits ahead of the active serving range"
3030
+ },
3031
+ servingDownstreamOfLatestCorrection: includesLatestCorrection,
3032
+ detail: latestFeedbackEvent === null
3033
+ ? "the supplied export does not contain principal feedback"
3034
+ : pendingEvents.length === 0
3035
+ ? "principal feedback is visible and current serving is caught up to the supplied export"
3036
+ : `${pendingEvents.length} principal item(s) are newer than the active serving range`
3037
+ };
3038
+ }
2652
3039
  function summarizeSupervision(input) {
2653
3040
  const loaded = loadOperatorEventExport(input);
2654
3041
  if (loaded === null) {
@@ -2747,7 +3134,13 @@ function summarizeTeacherLoop(input) {
2747
3134
  detail: "async teacher diagnostics loaded"
2748
3135
  };
2749
3136
  }
2750
- function summarizeAlwaysOnLearning(input) {
3137
+ function summarizeAlwaysOnLearning(input, active) {
3138
+ const unavailableLag = {
3139
+ activeEventRangeEnd: active?.eventRange.end ?? null,
3140
+ latestPrincipalSequence: null,
3141
+ sequenceLag: null,
3142
+ status: "unavailable"
3143
+ };
2751
3144
  const teacherSnapshotPath = normalizeOptionalString(input.teacherSnapshotPath);
2752
3145
  if (teacherSnapshotPath === undefined) {
2753
3146
  return {
@@ -2760,6 +3153,11 @@ function summarizeAlwaysOnLearning(input) {
2760
3153
  pendingBackfill: null,
2761
3154
  pendingTotal: null,
2762
3155
  freshLivePriority: null,
3156
+ principalCheckpointCount: null,
3157
+ pendingPrincipalCount: null,
3158
+ oldestUnlearnedPrincipalEvent: null,
3159
+ principalCheckpoints: [],
3160
+ principalLagToPromotion: unavailableLag,
2763
3161
  learnedRange: null,
2764
3162
  materializationCount: null,
2765
3163
  lastMaterializedAt: null,
@@ -2782,6 +3180,11 @@ function summarizeAlwaysOnLearning(input) {
2782
3180
  pendingBackfill: null,
2783
3181
  pendingTotal: null,
2784
3182
  freshLivePriority: null,
3183
+ principalCheckpointCount: null,
3184
+ pendingPrincipalCount: null,
3185
+ oldestUnlearnedPrincipalEvent: null,
3186
+ principalCheckpoints: [],
3187
+ principalLagToPromotion: unavailableLag,
2785
3188
  learnedRange: null,
2786
3189
  materializationCount: null,
2787
3190
  lastMaterializedAt: null,
@@ -2793,6 +3196,17 @@ function summarizeAlwaysOnLearning(input) {
2793
3196
  };
2794
3197
  }
2795
3198
  const plan = describeAlwaysOnLearningRuntimeState(snapshot.learner.state, snapshot.learner.lastMaterialization);
3199
+ const latestPrincipalSequence = plan.principalBacklog.checkpoints.reduce((latest, checkpoint) => {
3200
+ const candidate = checkpoint.newestPendingSequence ?? checkpoint.learnedThroughSequence;
3201
+ if (candidate === null) {
3202
+ return latest;
3203
+ }
3204
+ return latest === null ? candidate : Math.max(latest, candidate);
3205
+ }, null);
3206
+ const activeEventRangeEnd = active?.eventRange.end ?? null;
3207
+ const sequenceLag = latestPrincipalSequence === null || activeEventRangeEnd === null
3208
+ ? null
3209
+ : Math.max(latestPrincipalSequence - activeEventRangeEnd, 0);
2796
3210
  return {
2797
3211
  available: true,
2798
3212
  sourcePath: path.resolve(teacherSnapshotPath),
@@ -2803,6 +3217,20 @@ function summarizeAlwaysOnLearning(input) {
2803
3217
  pendingBackfill: plan.pending.backfill,
2804
3218
  pendingTotal: plan.pending.total,
2805
3219
  freshLivePriority: plan.pending.freshLivePriority,
3220
+ principalCheckpointCount: plan.principalBacklog.principalCount,
3221
+ pendingPrincipalCount: plan.principalBacklog.pendingEventCount,
3222
+ oldestUnlearnedPrincipalEvent: plan.principalBacklog.oldestUnlearnedEvent,
3223
+ principalCheckpoints: plan.principalBacklog.checkpoints,
3224
+ principalLagToPromotion: {
3225
+ activeEventRangeEnd,
3226
+ latestPrincipalSequence,
3227
+ sequenceLag,
3228
+ status: sequenceLag === null
3229
+ ? "unavailable"
3230
+ : sequenceLag === 0
3231
+ ? "caught_up"
3232
+ : "pending_promotion"
3233
+ },
2806
3234
  learnedRange: plan.learnedRange === null ? null : { ...plan.learnedRange },
2807
3235
  materializationCount: plan.materialization.count,
2808
3236
  lastMaterializedAt: plan.materialization.lastMaterializedAt,
@@ -2849,6 +3277,7 @@ function buildOperatorFindings(report) {
2849
3277
  }
2850
3278
  if (report.servePath.state === "serving_active_pack") {
2851
3279
  push("pass", "serve_path_verified", `serve path compiles from active pack ${report.servePath.activePackId ?? "unknown-pack"}`, `selection=${report.servePath.selectionMode ?? "unknown"}; tiers=${report.servePath.contextAttribution.selectionTiers ?? "unknown"}; router=${report.servePath.routerIdentity ?? "none"}; routeFreshness=${report.servePath.freshnessChecksum ?? "unknown"}`);
3280
+ push("pass", "structural_budget_visible", `structural budget resolves to ${report.servePath.resolvedMaxContextBlocks ?? "unknown"} blocks`, `requested=${report.servePath.requestedBudgetStrategy ?? "unknown"}; resolved=${report.servePath.resolvedBudgetStrategy ?? "unknown"}; source=${report.servePath.structuralBudgetSource ?? "unknown"}; evidence=${report.servePath.structuralBudgetEvidence ?? "none"}; pressures=${report.servePath.structuralBudgetPressures ?? "none"}`);
2852
3281
  }
2853
3282
  else if (report.servePath.state === "fail_open_static_context") {
2854
3283
  push("warn", "serve_path_fail_open", "serve path would fail open to static context", report.servePath.error ?? "compile probe fell back to static context");
@@ -3102,6 +3531,7 @@ export function buildOperatorSurfaceReport(input) {
3102
3531
  candidateAheadBy: summarizeCandidateAheadBy(observability.promotionFreshness.candidateAheadBy)
3103
3532
  },
3104
3533
  brain: summarizeBrainState(active, observability),
3534
+ graph: summarizeGraphObservability(active, observability),
3105
3535
  learnedRouting: {
3106
3536
  required: observability.learnedRouteFn.required,
3107
3537
  available: observability.learnedRouteFn.available,
@@ -3139,8 +3569,9 @@ export function buildOperatorSurfaceReport(input) {
3139
3569
  state: inspection.rollback.allowed ? "ready" : inspection.active === null ? "unknown" : "blocked"
3140
3570
  },
3141
3571
  supervision: summarizeSupervision(input),
3142
- learning: summarizeAlwaysOnLearning(input),
3143
- teacherLoop: summarizeTeacherLoop(input)
3572
+ learning: summarizeAlwaysOnLearning(input, active),
3573
+ teacherLoop: summarizeTeacherLoop(input),
3574
+ principal: summarizePrincipalObservability(input, active)
3144
3575
  };
3145
3576
  const findings = buildOperatorFindings(reportBase);
3146
3577
  return {