@openclawbrain/cli 0.4.25 → 0.4.27
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/cli.js +199 -14
- package/dist/src/daemon.d.ts +2 -0
- package/dist/src/daemon.js +19 -0
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.js +9 -3
- package/dist/src/learning-spine.d.ts +2 -1
- package/dist/src/local-learner.d.ts +17 -1
- package/dist/src/local-learner.js +109 -13
- package/dist/src/openclaw-hook-truth.d.ts +22 -0
- package/dist/src/openclaw-hook-truth.js +117 -0
- package/dist/src/proof-command.js +43 -4
- package/dist/src/status-learning-path.js +130 -0
- package/dist/src/teacher-labeler.d.ts +1 -1
- package/dist/src/teacher-labeler.js +4 -1
- package/dist/src/traced-learning-bridge.js +165 -2
- package/package.json +1 -1
|
@@ -455,6 +455,98 @@ function normalizeTeacherSupervisionArtifacts(artifacts) {
|
|
|
455
455
|
.filter((artifact) => !artifact.sourceEventIds.some((eventId) => supersededEventIds.has(eventId)))
|
|
456
456
|
.sort(compareTeacherSupervisionArtifacts);
|
|
457
457
|
}
|
|
458
|
+
function normalizeServeTimeDecisionStringArray(values) {
|
|
459
|
+
if (!Array.isArray(values)) {
|
|
460
|
+
return [];
|
|
461
|
+
}
|
|
462
|
+
return values.filter((value) => typeof value === "string" && value.length > 0);
|
|
463
|
+
}
|
|
464
|
+
function normalizeServeTimeDecisionScore(score) {
|
|
465
|
+
if (score === null || typeof score !== "object" || Array.isArray(score)) {
|
|
466
|
+
return null;
|
|
467
|
+
}
|
|
468
|
+
if (typeof score.blockId !== "string" || score.blockId.length === 0) {
|
|
469
|
+
return null;
|
|
470
|
+
}
|
|
471
|
+
return {
|
|
472
|
+
blockId: score.blockId,
|
|
473
|
+
selected: score.selected === true,
|
|
474
|
+
actionScore: Number.isFinite(score.actionScore) ? score.actionScore : 0,
|
|
475
|
+
actionProbability: Number.isFinite(score.actionProbability) ? score.actionProbability : 0,
|
|
476
|
+
...(Array.isArray(score.compactedFrom) ? { compactedFrom: normalizeServeTimeDecisionStringArray(score.compactedFrom) } : {}),
|
|
477
|
+
...(Array.isArray(score.matchedTokens) ? { matchedTokens: normalizeServeTimeDecisionStringArray(score.matchedTokens) } : {}),
|
|
478
|
+
...(Array.isArray(score.routingChannels) ? { routingChannels: normalizeServeTimeDecisionStringArray(score.routingChannels) } : {})
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
function normalizeServeTimeDecisionLogEntry(decision) {
|
|
482
|
+
if (decision === null || typeof decision !== "object" || Array.isArray(decision)) {
|
|
483
|
+
return null;
|
|
484
|
+
}
|
|
485
|
+
const selectedKernelContextIds = normalizeServeTimeDecisionStringArray(decision.selectedKernelContextIds);
|
|
486
|
+
const selectedBrainContextIds = normalizeServeTimeDecisionStringArray(decision.selectedBrainContextIds);
|
|
487
|
+
return {
|
|
488
|
+
...decision,
|
|
489
|
+
candidateSetIds: normalizeServeTimeDecisionStringArray(decision.candidateSetIds),
|
|
490
|
+
chosenContextIds: normalizeServeTimeDecisionStringArray(decision.chosenContextIds),
|
|
491
|
+
candidateScores: Array.isArray(decision.candidateScores)
|
|
492
|
+
? decision.candidateScores.map((score) => normalizeServeTimeDecisionScore(score)).filter((score) => score !== null)
|
|
493
|
+
: [],
|
|
494
|
+
kernelContextCount: Number.isInteger(decision.kernelContextCount) && decision.kernelContextCount >= 0
|
|
495
|
+
? decision.kernelContextCount
|
|
496
|
+
: selectedKernelContextIds.length,
|
|
497
|
+
brainContextCount: Number.isInteger(decision.brainContextCount) && decision.brainContextCount >= 0
|
|
498
|
+
? decision.brainContextCount
|
|
499
|
+
: selectedBrainContextIds.length,
|
|
500
|
+
selectedKernelContextIds,
|
|
501
|
+
selectedBrainContextIds
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
function normalizeServeTimeDecisionsForLearner(serveTimeDecisions) {
|
|
505
|
+
if (serveTimeDecisions === undefined) {
|
|
506
|
+
return undefined;
|
|
507
|
+
}
|
|
508
|
+
if (!Array.isArray(serveTimeDecisions)) {
|
|
509
|
+
return [];
|
|
510
|
+
}
|
|
511
|
+
return serveTimeDecisions
|
|
512
|
+
.map((decision) => normalizeServeTimeDecisionLogEntry(decision))
|
|
513
|
+
.filter((decision) => decision !== null);
|
|
514
|
+
}
|
|
515
|
+
function projectServeTimeDecisionForRoutingSeed(decision) {
|
|
516
|
+
return {
|
|
517
|
+
recordId: typeof decision.recordId === "string" ? decision.recordId : null,
|
|
518
|
+
recordedAt: typeof decision.recordedAt === "string" ? decision.recordedAt : null,
|
|
519
|
+
sessionId: typeof decision.sessionId === "string" ? decision.sessionId : null,
|
|
520
|
+
channel: typeof decision.channel === "string" ? decision.channel : null,
|
|
521
|
+
turnCompileEventId: typeof decision.turnCompileEventId === "string" ? decision.turnCompileEventId : null,
|
|
522
|
+
turnCreatedAt: typeof decision.turnCreatedAt === "string" ? decision.turnCreatedAt : null,
|
|
523
|
+
activePackId: typeof decision.activePackId === "string" ? decision.activePackId : null,
|
|
524
|
+
activePackGraphChecksum: typeof decision.activePackGraphChecksum === "string" ? decision.activePackGraphChecksum : null,
|
|
525
|
+
routerIdentity: typeof decision.routerIdentity === "string" ? decision.routerIdentity : null,
|
|
526
|
+
selectionDigest: typeof decision.selectionDigest === "string" ? decision.selectionDigest : null,
|
|
527
|
+
usedLearnedRouteFn: decision.usedLearnedRouteFn === true,
|
|
528
|
+
fallbackReason: typeof decision.fallbackReason === "string" ? decision.fallbackReason : null,
|
|
529
|
+
candidateSetIds: decision.candidateSetIds,
|
|
530
|
+
chosenContextIds: decision.chosenContextIds,
|
|
531
|
+
candidateScores: decision.candidateScores.map((score) => ({
|
|
532
|
+
blockId: score.blockId,
|
|
533
|
+
selected: score.selected,
|
|
534
|
+
actionScore: score.actionScore,
|
|
535
|
+
actionProbability: score.actionProbability,
|
|
536
|
+
compactedFrom: score.compactedFrom ?? []
|
|
537
|
+
})),
|
|
538
|
+
kernelContextCount: decision.kernelContextCount,
|
|
539
|
+
brainContextCount: decision.brainContextCount,
|
|
540
|
+
selectedKernelContextIds: decision.selectedKernelContextIds,
|
|
541
|
+
selectedBrainContextIds: decision.selectedBrainContextIds
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
function checksumServeTimeDecisionsForRoutingSeed(serveTimeDecisions) {
|
|
545
|
+
if (serveTimeDecisions === undefined) {
|
|
546
|
+
return null;
|
|
547
|
+
}
|
|
548
|
+
return checksumJsonPayload(serveTimeDecisions.map((decision) => projectServeTimeDecisionForRoutingSeed(decision)));
|
|
549
|
+
}
|
|
458
550
|
function teacherSupervisionContentForInteraction(event) {
|
|
459
551
|
const message = event.messageId === undefined ? "" : ` Message: ${event.messageId}.`;
|
|
460
552
|
const pack = event.packId === undefined ? "" : ` Pack: ${event.packId}.`;
|
|
@@ -893,7 +985,7 @@ function buildAlwaysOnLearningMaterializationJob(input, current, selectedSlices,
|
|
|
893
985
|
...(input.sparseFeedback !== undefined ? { sparseFeedback: input.sparseFeedback } : {}),
|
|
894
986
|
principalBacklog,
|
|
895
987
|
...(input.pgVersion !== undefined ? { pgVersion: input.pgVersion } : {}),
|
|
896
|
-
...(input.serveTimeDecisions !== undefined ? { serveTimeDecisions:
|
|
988
|
+
...(input.serveTimeDecisions !== undefined ? { serveTimeDecisions: normalizeServeTimeDecisionsForLearner(input.serveTimeDecisions) } : {}),
|
|
897
989
|
...(input.baselineState !== undefined ? { baselineState: { ...input.baselineState } } : {}),
|
|
898
990
|
...(input.activationRoot !== undefined ? { activationRoot: input.activationRoot } : {})
|
|
899
991
|
};
|
|
@@ -1049,7 +1141,7 @@ export function buildCandidatePackFromNormalizedEventExportSlice(input) {
|
|
|
1049
1141
|
...(input.sparseFeedback !== undefined ? { sparseFeedback: input.sparseFeedback } : {}),
|
|
1050
1142
|
...(input.principalBacklog !== undefined ? { principalBacklog: input.principalBacklog } : {}),
|
|
1051
1143
|
...(input.pgVersion !== undefined ? { pgVersion: input.pgVersion } : {}),
|
|
1052
|
-
...(input.serveTimeDecisions !== undefined ? { serveTimeDecisions:
|
|
1144
|
+
...(input.serveTimeDecisions !== undefined ? { serveTimeDecisions: normalizeServeTimeDecisionsForLearner(input.serveTimeDecisions) } : {}),
|
|
1053
1145
|
...(input.baselineState !== undefined ? { baselineState: { ...input.baselineState } } : {})
|
|
1054
1146
|
});
|
|
1055
1147
|
}
|
|
@@ -1080,7 +1172,7 @@ export function buildCandidatePackBundleFromNormalizedEventExportBridge(input) {
|
|
|
1080
1172
|
...(input.sparseFeedback !== undefined ? { sparseFeedback: input.sparseFeedback } : {}),
|
|
1081
1173
|
...(input.principalBacklog !== undefined ? { principalBacklog: input.principalBacklog } : {}),
|
|
1082
1174
|
...(input.pgVersion !== undefined ? { pgVersion: input.pgVersion } : {}),
|
|
1083
|
-
...(input.serveTimeDecisions !== undefined ? { serveTimeDecisions:
|
|
1175
|
+
...(input.serveTimeDecisions !== undefined ? { serveTimeDecisions: normalizeServeTimeDecisionsForLearner(input.serveTimeDecisions) } : {}),
|
|
1084
1176
|
...(input.baselineState !== undefined ? { baselineState: { ...input.baselineState } } : {})
|
|
1085
1177
|
})
|
|
1086
1178
|
};
|
|
@@ -3565,7 +3657,8 @@ function remapServeTimeDecisionToGraph(decision, resolveBlockId) {
|
|
|
3565
3657
|
const remappedSelectedBrainContextIds = remapIds(decision.selectedBrainContextIds);
|
|
3566
3658
|
const chosenSet = new Set(remappedChosenContextIds);
|
|
3567
3659
|
const remappedScoresByBlockId = new Map();
|
|
3568
|
-
|
|
3660
|
+
const candidateScores = Array.isArray(decision.candidateScores) ? decision.candidateScores : [];
|
|
3661
|
+
for (const score of candidateScores) {
|
|
3569
3662
|
const resolvedBlockId = resolveBlockId(score.blockId);
|
|
3570
3663
|
if (resolvedBlockId === null) {
|
|
3571
3664
|
continue;
|
|
@@ -4540,13 +4633,15 @@ function buildGraphLocalActionSetFromScores(nodeBlockId, neighborBlockIds, graph
|
|
|
4540
4633
|
* Traces through the graph starting from the highest-scoring selected block.
|
|
4541
4634
|
*/
|
|
4542
4635
|
export function reconstructTrajectoryFromServeDecision(decision, graph, vectors, adjacency, tau, outcome, baselineValue) {
|
|
4543
|
-
const
|
|
4636
|
+
const chosenContextIds = Array.isArray(decision.chosenContextIds) ? decision.chosenContextIds : [];
|
|
4637
|
+
const candidateScores = Array.isArray(decision.candidateScores) ? decision.candidateScores : [];
|
|
4638
|
+
const chosenSet = new Set(chosenContextIds);
|
|
4544
4639
|
const candidateScoresMap = new Map();
|
|
4545
|
-
for (const cs of
|
|
4640
|
+
for (const cs of candidateScores) {
|
|
4546
4641
|
candidateScoresMap.set(cs.blockId, cs.actionScore);
|
|
4547
4642
|
}
|
|
4548
4643
|
// Sort chosen blocks by score descending to find entry point
|
|
4549
|
-
const chosenWithScores =
|
|
4644
|
+
const chosenWithScores = chosenContextIds
|
|
4550
4645
|
.map((blockId) => ({ blockId, score: candidateScoresMap.get(blockId) ?? 0 }))
|
|
4551
4646
|
.sort((a, b) => b.score - a.score);
|
|
4552
4647
|
const steps = [];
|
|
@@ -4679,7 +4774,7 @@ function createRouterArtifactV2(packId, builtAt, graph, vectors, eventExport, se
|
|
|
4679
4774
|
// 1. Build adjacency map from graph
|
|
4680
4775
|
const adjacency = buildAdjacencyMap(graph);
|
|
4681
4776
|
const resolveBlockId = buildGraphBlockIdResolver(graph);
|
|
4682
|
-
const remappedServeTimeDecisions = serveTimeDecisions.map((decision) => remapServeTimeDecisionToGraph(decision, resolveBlockId));
|
|
4777
|
+
const remappedServeTimeDecisions = (serveTimeDecisions ?? []).map((decision) => remapServeTimeDecisionToGraph(decision, resolveBlockId));
|
|
4683
4778
|
// 2. Join serve-time decisions with explicit feedback first, then let teacher-v2 observations override when available.
|
|
4684
4779
|
const outcomeMap = joinDecisionsWithFeedback(remappedServeTimeDecisions, eventExport);
|
|
4685
4780
|
const teacherObservationBindings = joinDecisionsWithTeacherObservationOutcomes(remappedServeTimeDecisions, teacherObservationOutcomes);
|
|
@@ -4710,7 +4805,7 @@ function createRouterArtifactV2(packId, builtAt, graph, vectors, eventExport, se
|
|
|
4710
4805
|
`traj-${stableHash(checksumJsonPayload({ decisionId: d.recordId, steps: trajectory.steps.map((s) => s.nodeBlockId) }))}` === trajectory.trajectoryId);
|
|
4711
4806
|
const candidateScoresMap = new Map();
|
|
4712
4807
|
if (decision !== undefined) {
|
|
4713
|
-
for (const cs of decision.candidateScores) {
|
|
4808
|
+
for (const cs of decision.candidateScores ?? []) {
|
|
4714
4809
|
candidateScoresMap.set(cs.blockId, cs.actionScore);
|
|
4715
4810
|
}
|
|
4716
4811
|
}
|
|
@@ -5000,7 +5095,8 @@ export function buildCandidatePack(input) {
|
|
|
5000
5095
|
});
|
|
5001
5096
|
const learningSurface = eventExport?.provenance.learningSurface ?? defaultLearningSurface(workspace, offlineArtifacts, workspaceInit);
|
|
5002
5097
|
const sparseFeedback = normalizeSparseFeedbackPolicy(input.sparseFeedback);
|
|
5003
|
-
const
|
|
5098
|
+
const serveTimeDecisions = normalizeServeTimeDecisionsForLearner(input.serveTimeDecisions);
|
|
5099
|
+
const decisionLogCount = serveTimeDecisions?.length ?? 0;
|
|
5004
5100
|
const useV2 = input.pgVersion === "v2" && decisionLogCount > 0;
|
|
5005
5101
|
const fallbackReason = !input.learnedRouting
|
|
5006
5102
|
? null
|
|
@@ -5010,7 +5106,7 @@ export function buildCandidatePack(input) {
|
|
|
5010
5106
|
const routingSeed = input.learnedRouting && (input.pgVersion === "v2" || decisionLogCount > 0 || input.baselineState !== undefined)
|
|
5011
5107
|
? {
|
|
5012
5108
|
pgVersionRequested: input.pgVersion ?? "v1",
|
|
5013
|
-
serveTimeDecisionDigest:
|
|
5109
|
+
serveTimeDecisionDigest: checksumServeTimeDecisionsForRoutingSeed(serveTimeDecisions),
|
|
5014
5110
|
baselineState: input.baselineState ?? null
|
|
5015
5111
|
}
|
|
5016
5112
|
: null;
|
|
@@ -5048,7 +5144,7 @@ export function buildCandidatePack(input) {
|
|
|
5048
5144
|
: loadTeacherObservationOutcomesFromActivation(input.activationRoot);
|
|
5049
5145
|
if (input.learnedRouting) {
|
|
5050
5146
|
if (useV2) {
|
|
5051
|
-
const v2Result = createRouterArtifactV2(packId, builtAt, graph, vectors, eventExport,
|
|
5147
|
+
const v2Result = createRouterArtifactV2(packId, builtAt, graph, vectors, eventExport, serveTimeDecisions ?? [], input.baselineState ?? initBaseline(), input.sparseFeedback, input.principalBacklog, teacherObservationOutcomes);
|
|
5052
5148
|
router = v2Result.artifact;
|
|
5053
5149
|
updatedBaseline = v2Result.updatedBaseline;
|
|
5054
5150
|
observationBindingStats = v2Result.observationBindingStats;
|
|
@@ -5211,7 +5307,7 @@ export function buildCandidatePackFromNormalizedEventExport(input) {
|
|
|
5211
5307
|
...(input.sparseFeedback !== undefined ? { sparseFeedback: input.sparseFeedback } : {}),
|
|
5212
5308
|
...(input.principalBacklog !== undefined ? { principalBacklog: input.principalBacklog } : {}),
|
|
5213
5309
|
...(input.pgVersion !== undefined ? { pgVersion: input.pgVersion } : {}),
|
|
5214
|
-
...(input.serveTimeDecisions !== undefined ? { serveTimeDecisions:
|
|
5310
|
+
...(input.serveTimeDecisions !== undefined ? { serveTimeDecisions: normalizeServeTimeDecisionsForLearner(input.serveTimeDecisions) } : {}),
|
|
5215
5311
|
...(input.baselineState !== undefined ? { baselineState: { ...input.baselineState } } : {}),
|
|
5216
5312
|
...(input.activationRoot !== undefined ? { activationRoot: input.activationRoot } : {})
|
|
5217
5313
|
};
|
|
@@ -16,6 +16,7 @@ export interface OpenClawBrainHookInspection {
|
|
|
16
16
|
manifestId: string | null;
|
|
17
17
|
installId: string | null;
|
|
18
18
|
packageName: string | null;
|
|
19
|
+
packageVersion: string | null;
|
|
19
20
|
installLayout: OpenClawBrainInstallLayout | null;
|
|
20
21
|
additionalInstallCount: number;
|
|
21
22
|
installState: OpenClawBrainHookInstallState;
|
|
@@ -31,9 +32,30 @@ export interface OpenClawBrainHookLoadSummary extends OpenClawBrainHookInspectio
|
|
|
31
32
|
guardSummary: string;
|
|
32
33
|
guardAction: string;
|
|
33
34
|
}
|
|
35
|
+
export interface OpenClawBrainDaemonRuntimeSurfaceInspection {
|
|
36
|
+
configuredRuntimePath: string | null;
|
|
37
|
+
configuredRuntimePackageSpec?: string | null;
|
|
38
|
+
configuredRuntimePackageName?: string | null;
|
|
39
|
+
configuredRuntimePackageVersion?: string | null;
|
|
40
|
+
}
|
|
41
|
+
export interface OpenClawBrainHotfixBoundarySummary {
|
|
42
|
+
boundary: string;
|
|
43
|
+
skew: string;
|
|
44
|
+
daemonPath: string | null;
|
|
45
|
+
hookPath: string | null;
|
|
46
|
+
runtimeGuardPath: string | null;
|
|
47
|
+
daemonPackage: string | null;
|
|
48
|
+
hookPackage: string | null;
|
|
49
|
+
guidance: string;
|
|
50
|
+
detail: string;
|
|
51
|
+
}
|
|
34
52
|
export declare function inspectOpenClawBrainPluginAllowlist(openclawHome: string): {
|
|
35
53
|
state: Exclude<OpenClawBrainPluginAllowlistState, "unverified">;
|
|
36
54
|
detail: string;
|
|
37
55
|
};
|
|
38
56
|
export declare function inspectOpenClawBrainHookStatus(openclawHome: string | null | undefined): OpenClawBrainHookInspection;
|
|
39
57
|
export declare function summarizeOpenClawBrainHookLoad(inspection: OpenClawBrainHookInspection, statusProbeReady: boolean): OpenClawBrainHookLoadSummary;
|
|
58
|
+
export declare function describeOpenClawBrainHotfixBoundary(input: {
|
|
59
|
+
hookInspection: OpenClawBrainHookInspection;
|
|
60
|
+
daemonInspection?: OpenClawBrainDaemonRuntimeSurfaceInspection | null;
|
|
61
|
+
}): OpenClawBrainHotfixBoundarySummary;
|
|
@@ -35,6 +35,37 @@ function shortenPath(fullPath) {
|
|
|
35
35
|
}
|
|
36
36
|
return fullPath;
|
|
37
37
|
}
|
|
38
|
+
function readInstalledHookPackageVersion(packageJsonPath) {
|
|
39
|
+
if (typeof packageJsonPath !== "string" || packageJsonPath.trim().length === 0) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
44
|
+
return typeof parsed?.version === "string" && parsed.version.trim().length > 0
|
|
45
|
+
? parsed.version.trim()
|
|
46
|
+
: null;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function formatPackageIdentity(packageName, packageVersion, packageSpec = null) {
|
|
53
|
+
if (typeof packageSpec === "string" && packageSpec.trim().length > 0) {
|
|
54
|
+
return packageSpec.trim();
|
|
55
|
+
}
|
|
56
|
+
if (typeof packageName !== "string" || packageName.trim().length === 0) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const normalizedName = packageName.trim();
|
|
60
|
+
return typeof packageVersion === "string" && packageVersion.trim().length > 0
|
|
61
|
+
? `${normalizedName}@${packageVersion.trim()}`
|
|
62
|
+
: normalizedName;
|
|
63
|
+
}
|
|
64
|
+
function normalizeSurfacePath(filePath) {
|
|
65
|
+
return typeof filePath === "string" && filePath.trim().length > 0
|
|
66
|
+
? path.resolve(filePath)
|
|
67
|
+
: null;
|
|
68
|
+
}
|
|
38
69
|
function inspectInstalledHookActivationRoot(loaderEntryPath) {
|
|
39
70
|
let content;
|
|
40
71
|
try {
|
|
@@ -147,6 +178,7 @@ export function inspectOpenClawBrainHookStatus(openclawHome) {
|
|
|
147
178
|
manifestId: null,
|
|
148
179
|
installId: null,
|
|
149
180
|
packageName: null,
|
|
181
|
+
packageVersion: null,
|
|
150
182
|
installLayout: null,
|
|
151
183
|
additionalInstallCount: 0,
|
|
152
184
|
installState: "unverified",
|
|
@@ -173,6 +205,7 @@ export function inspectOpenClawBrainHookStatus(openclawHome) {
|
|
|
173
205
|
manifestId: incompleteInstall?.manifestId ?? null,
|
|
174
206
|
installId: incompleteInstall?.installId ?? null,
|
|
175
207
|
packageName: incompleteInstall?.packageName ?? null,
|
|
208
|
+
packageVersion: readInstalledHookPackageVersion(incompleteInstall?.packageJsonPath ?? null),
|
|
176
209
|
installLayout: incompleteInstall?.installLayout ?? null,
|
|
177
210
|
additionalInstallCount: installedPlugin.additionalInstalls.length,
|
|
178
211
|
installState: "not_installed",
|
|
@@ -189,6 +222,7 @@ export function inspectOpenClawBrainHookStatus(openclawHome) {
|
|
|
189
222
|
const allowlist = inspectOpenClawBrainPluginAllowlist(resolvedHome);
|
|
190
223
|
const layoutLabel = describeOpenClawBrainInstallLayout(selectedInstall.installLayout);
|
|
191
224
|
const identityDetail = describeOpenClawBrainInstallIdentity(selectedInstall);
|
|
225
|
+
const packageVersion = readInstalledHookPackageVersion(selectedInstall.packageJsonPath);
|
|
192
226
|
const activationRootState = inspectInstalledHookActivationRoot(selectedInstall.loaderEntryPath);
|
|
193
227
|
if (allowlist.state === "blocked") {
|
|
194
228
|
return {
|
|
@@ -202,6 +236,7 @@ export function inspectOpenClawBrainHookStatus(openclawHome) {
|
|
|
202
236
|
manifestId: selectedInstall.manifestId,
|
|
203
237
|
installId: selectedInstall.installId,
|
|
204
238
|
packageName: selectedInstall.packageName,
|
|
239
|
+
packageVersion,
|
|
205
240
|
installLayout: selectedInstall.installLayout,
|
|
206
241
|
additionalInstallCount: installedPlugin.additionalInstalls.length,
|
|
207
242
|
installState: "blocked_by_allowlist",
|
|
@@ -224,6 +259,7 @@ export function inspectOpenClawBrainHookStatus(openclawHome) {
|
|
|
224
259
|
manifestId: selectedInstall.manifestId,
|
|
225
260
|
installId: selectedInstall.installId,
|
|
226
261
|
packageName: selectedInstall.packageName,
|
|
262
|
+
packageVersion,
|
|
227
263
|
installLayout: selectedInstall.installLayout,
|
|
228
264
|
additionalInstallCount: installedPlugin.additionalInstalls.length,
|
|
229
265
|
installState: "blocked_by_allowlist",
|
|
@@ -246,6 +282,7 @@ export function inspectOpenClawBrainHookStatus(openclawHome) {
|
|
|
246
282
|
manifestId: selectedInstall.manifestId,
|
|
247
283
|
installId: selectedInstall.installId,
|
|
248
284
|
packageName: selectedInstall.packageName,
|
|
285
|
+
packageVersion,
|
|
249
286
|
installLayout: selectedInstall.installLayout,
|
|
250
287
|
additionalInstallCount: installedPlugin.additionalInstalls.length,
|
|
251
288
|
installState: "installed",
|
|
@@ -266,6 +303,7 @@ export function inspectOpenClawBrainHookStatus(openclawHome) {
|
|
|
266
303
|
manifestId: selectedInstall.manifestId,
|
|
267
304
|
installId: selectedInstall.installId,
|
|
268
305
|
packageName: selectedInstall.packageName,
|
|
306
|
+
packageVersion,
|
|
269
307
|
installLayout: selectedInstall.installLayout,
|
|
270
308
|
additionalInstallCount: installedPlugin.additionalInstalls.length,
|
|
271
309
|
installState: "installed",
|
|
@@ -284,4 +322,83 @@ export function summarizeOpenClawBrainHookLoad(inspection, statusProbeReady) {
|
|
|
284
322
|
: "not_ready"
|
|
285
323
|
};
|
|
286
324
|
}
|
|
325
|
+
export function describeOpenClawBrainHotfixBoundary(input) {
|
|
326
|
+
const hookInspection = input.hookInspection;
|
|
327
|
+
const daemonInspection = input.daemonInspection ?? null;
|
|
328
|
+
const daemonPath = normalizeSurfacePath(daemonInspection?.configuredRuntimePath ?? null);
|
|
329
|
+
const hookPath = normalizeSurfacePath(hookInspection.hookPath);
|
|
330
|
+
const runtimeGuardPath = normalizeSurfacePath(hookInspection.runtimeGuardPath);
|
|
331
|
+
const daemonPackage = formatPackageIdentity(daemonInspection?.configuredRuntimePackageName ?? null, daemonInspection?.configuredRuntimePackageVersion ?? null, daemonInspection?.configuredRuntimePackageSpec ?? null);
|
|
332
|
+
const hookPackage = formatPackageIdentity(hookInspection.packageName, hookInspection.packageVersion);
|
|
333
|
+
if (hookInspection.scope === "activation_root_only") {
|
|
334
|
+
return {
|
|
335
|
+
boundary: "hook_surface_unverified",
|
|
336
|
+
skew: "unverified",
|
|
337
|
+
daemonPath,
|
|
338
|
+
hookPath: null,
|
|
339
|
+
runtimeGuardPath: null,
|
|
340
|
+
daemonPackage,
|
|
341
|
+
hookPackage: null,
|
|
342
|
+
guidance: "Pin --openclaw-home before patching the installed hook/runtime-guard surface; activation-root-only status does not prove which OpenClaw install you would be changing.",
|
|
343
|
+
detail: daemonPath === null
|
|
344
|
+
? "activation-root-only status does not expose the installed hook/runtime-guard surface."
|
|
345
|
+
: `daemon runtime path ${shortenPath(daemonPath)} is visible, but activation-root-only status still does not expose the installed hook/runtime-guard surface.`
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
if (hookPath === null && runtimeGuardPath === null) {
|
|
349
|
+
return {
|
|
350
|
+
boundary: "hook_surface_unverified",
|
|
351
|
+
skew: "unverified",
|
|
352
|
+
daemonPath,
|
|
353
|
+
hookPath: null,
|
|
354
|
+
runtimeGuardPath: null,
|
|
355
|
+
daemonPackage,
|
|
356
|
+
hookPackage,
|
|
357
|
+
guidance: daemonPath === null
|
|
358
|
+
? "Repair or reinstall the installed hook surface before patching OpenClaw load behavior."
|
|
359
|
+
: "Patch the daemon runtime path for background watch fixes, but repair or reinstall the installed hook/runtime-guard surface before patching OpenClaw load behavior.",
|
|
360
|
+
detail: daemonPath === null
|
|
361
|
+
? "no verified daemon runtime path or installed hook/runtime-guard path is visible from this status snapshot."
|
|
362
|
+
: `daemon runtime path ${shortenPath(daemonPath)} is visible, but the installed hook/runtime-guard surface is not yet loadable.`
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
if (daemonPath === null) {
|
|
366
|
+
return {
|
|
367
|
+
boundary: "daemon_surface_only",
|
|
368
|
+
skew: "unverified",
|
|
369
|
+
daemonPath: null,
|
|
370
|
+
hookPath,
|
|
371
|
+
runtimeGuardPath,
|
|
372
|
+
daemonPackage: null,
|
|
373
|
+
hookPackage,
|
|
374
|
+
guidance: "Patch the installed hook/runtime-guard surface for OpenClaw load fixes. No configured daemon runtime path is visible from status.",
|
|
375
|
+
detail: `installed hook loads from ${hookPath === null ? "unverified" : shortenPath(hookPath)}${runtimeGuardPath === null ? "" : ` with runtime-guard ${shortenPath(runtimeGuardPath)}`}, but no configured daemon runtime path is visible.`
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
const samePath = daemonPath === hookPath || daemonPath === runtimeGuardPath;
|
|
379
|
+
const daemonVersion = daemonInspection?.configuredRuntimePackageVersion ?? null;
|
|
380
|
+
const hookVersion = hookInspection.packageVersion ?? null;
|
|
381
|
+
const skew = samePath
|
|
382
|
+
? "same_path"
|
|
383
|
+
: daemonVersion !== null && hookVersion !== null
|
|
384
|
+
? daemonVersion === hookVersion
|
|
385
|
+
? "split_path_same_version"
|
|
386
|
+
: "split_path_version_skew"
|
|
387
|
+
: "split_path_version_unverified";
|
|
388
|
+
return {
|
|
389
|
+
boundary: samePath ? "same_surface" : "split_surfaces",
|
|
390
|
+
skew,
|
|
391
|
+
daemonPath,
|
|
392
|
+
hookPath,
|
|
393
|
+
runtimeGuardPath,
|
|
394
|
+
daemonPackage,
|
|
395
|
+
hookPackage,
|
|
396
|
+
guidance: samePath
|
|
397
|
+
? "Daemon and installed hook paths currently collapse to the same file; verify both surfaces before patching anyway."
|
|
398
|
+
: "Patch the daemon runtime path for background watch/learner fixes. Patch the installed hook/runtime-guard paths for OpenClaw load fixes.",
|
|
399
|
+
detail: samePath
|
|
400
|
+
? `daemon runtime path ${shortenPath(daemonPath)} currently resolves to the same file as the installed OpenClaw hook surface.`
|
|
401
|
+
: `daemon background watch runs from ${shortenPath(daemonPath)}${daemonPackage === null ? "" : ` (${daemonPackage})`}; OpenClaw loads the installed hook from ${hookPath === null ? "unverified" : shortenPath(hookPath)}${hookPackage === null ? "" : ` (${hookPackage})`}${runtimeGuardPath === null ? "" : ` and runtime-guard ${shortenPath(runtimeGuardPath)}`}.`
|
|
402
|
+
};
|
|
403
|
+
}
|
|
287
404
|
//# sourceMappingURL=openclaw-hook-truth.js.map
|
|
@@ -546,7 +546,7 @@ function buildVerdict({ steps, gatewayStatus, pluginInspect, statusSignals, brea
|
|
|
546
546
|
};
|
|
547
547
|
}
|
|
548
548
|
|
|
549
|
-
function buildSummary({ options, steps, verdict, gatewayStatusText, pluginInspectText, statusSignals, breadcrumbs, runtimeLoadProofSnapshot, guardLine, feedbackLine, attributionLine, attributionCoverageLine, learningPathLine, coverageSnapshot, hardeningSnapshot }) {
|
|
549
|
+
function buildSummary({ options, steps, verdict, gatewayStatusText, pluginInspectText, statusSignals, breadcrumbs, runtimeLoadProofSnapshot, surfaceLine, surfacesLine, hotfixLine, guardLine, feedbackLine, attributionLine, attributionCoverageLine, learningPathLine, learningFlowLine, learningHealthLine, coverageSnapshot, hardeningSnapshot }) {
|
|
550
550
|
const passed = [];
|
|
551
551
|
const missing = [];
|
|
552
552
|
const warnings = Array.isArray(verdict.warnings) ? verdict.warnings : [];
|
|
@@ -602,11 +602,33 @@ function buildSummary({ options, steps, verdict, gatewayStatusText, pluginInspec
|
|
|
602
602
|
"## Warnings",
|
|
603
603
|
...(warnings.length === 0 ? ["- none"] : warnings.map((item) => `- ${item}`)),
|
|
604
604
|
"",
|
|
605
|
+
"## Hotfix Boundary",
|
|
606
|
+
...(surfaceLine === null
|
|
607
|
+
? ["- hotfix boundary line not reported by detailed status"]
|
|
608
|
+
: [`- ${surfaceLine}`]),
|
|
609
|
+
...(surfacesLine === null
|
|
610
|
+
? ["- hotfix paths line not reported by detailed status"]
|
|
611
|
+
: [`- ${surfacesLine}`]),
|
|
612
|
+
...(hotfixLine === null
|
|
613
|
+
? ["- hotfix guidance line not reported by detailed status"]
|
|
614
|
+
: [`- ${hotfixLine}`]),
|
|
615
|
+
"",
|
|
605
616
|
"## Runtime Guard",
|
|
606
617
|
...(guardLine === null
|
|
607
618
|
? ["- runtime guard line not reported by detailed status"]
|
|
608
619
|
: [`- ${guardLine}`]),
|
|
609
620
|
"",
|
|
621
|
+
"## Learning Flow",
|
|
622
|
+
...(learningPathLine === null
|
|
623
|
+
? ["- learning path line not reported by detailed status"]
|
|
624
|
+
: [`- ${learningPathLine}`]),
|
|
625
|
+
...(learningFlowLine === null
|
|
626
|
+
? ["- learning flow line not reported by detailed status"]
|
|
627
|
+
: [`- ${learningFlowLine}`]),
|
|
628
|
+
...(learningHealthLine === null
|
|
629
|
+
? ["- learning health line not reported by detailed status"]
|
|
630
|
+
: [`- ${learningHealthLine}`]),
|
|
631
|
+
"",
|
|
610
632
|
"## Learning Attribution",
|
|
611
633
|
...(feedbackLine === null
|
|
612
634
|
? ["- feedback line not reported by detailed status"]
|
|
@@ -617,9 +639,6 @@ function buildSummary({ options, steps, verdict, gatewayStatusText, pluginInspec
|
|
|
617
639
|
...(attributionCoverageLine === null
|
|
618
640
|
? ["- attribution coverage line not reported by detailed status"]
|
|
619
641
|
: [`- ${attributionCoverageLine}`]),
|
|
620
|
-
...(learningPathLine === null
|
|
621
|
-
? []
|
|
622
|
-
: [`- ${learningPathLine}`]),
|
|
623
642
|
"",
|
|
624
643
|
"## Coverage snapshot",
|
|
625
644
|
`- attached profiles: ${coverageSnapshot.attachedProfileCount}`,
|
|
@@ -916,11 +935,16 @@ export function captureOperatorProofBundle(options) {
|
|
|
916
935
|
const gatewayLogPath = extractGatewayLogPath(gatewayStatusCapture.stdout);
|
|
917
936
|
const activationRoot = extractActivationRoot(statusCapture.stdout, options.activationRoot ?? null);
|
|
918
937
|
const statusSignals = extractStatusSignals(statusCapture.stdout);
|
|
938
|
+
const surfaceLine = extractDetailedStatusLine(statusCapture.stdout, "surface");
|
|
939
|
+
const surfacesLine = extractDetailedStatusLine(statusCapture.stdout, "surfaces");
|
|
940
|
+
const hotfixLine = extractDetailedStatusLine(statusCapture.stdout, "hotfix");
|
|
919
941
|
const attachTruthLine = extractDetailedStatusLine(statusCapture.stdout, "attachTruth");
|
|
920
942
|
const attachedSetLine = extractDetailedStatusLine(statusCapture.stdout, "attachedSet");
|
|
921
943
|
const serveLine = extractDetailedStatusLine(statusCapture.stdout, "serve");
|
|
922
944
|
const routeFnLine = extractDetailedStatusLine(statusCapture.stdout, "routeFn");
|
|
923
945
|
const guardLine = extractDetailedStatusLine(statusCapture.stdout, "guard");
|
|
946
|
+
const learningFlowLine = extractDetailedStatusLine(statusCapture.stdout, "learnFlow");
|
|
947
|
+
const learningHealthLine = extractDetailedStatusLine(statusCapture.stdout, "health");
|
|
924
948
|
const feedbackLine = extractDetailedStatusLine(statusCapture.stdout, "feedback");
|
|
925
949
|
const attributionLine = extractDetailedStatusLine(statusCapture.stdout, "attribution");
|
|
926
950
|
const attributionCoverageLine = extractDetailedStatusLine(statusCapture.stdout, "attrCover");
|
|
@@ -978,7 +1002,12 @@ export function captureOperatorProofBundle(options) {
|
|
|
978
1002
|
},
|
|
979
1003
|
runtimeLoadProofPath,
|
|
980
1004
|
runtimeLoadProofError: runtimeLoadProofSnapshot.error,
|
|
1005
|
+
surfaceLine,
|
|
1006
|
+
surfacesLine,
|
|
1007
|
+
hotfixLine,
|
|
981
1008
|
guardLine,
|
|
1009
|
+
learningFlowLine,
|
|
1010
|
+
learningHealthLine,
|
|
982
1011
|
feedbackLine,
|
|
983
1012
|
attributionLine,
|
|
984
1013
|
attributionCoverageLine,
|
|
@@ -994,7 +1023,12 @@ export function captureOperatorProofBundle(options) {
|
|
|
994
1023
|
statusSignals,
|
|
995
1024
|
breadcrumbs,
|
|
996
1025
|
runtimeLoadProofSnapshot,
|
|
1026
|
+
surfaceLine,
|
|
1027
|
+
surfacesLine,
|
|
1028
|
+
hotfixLine,
|
|
997
1029
|
guardLine,
|
|
1030
|
+
learningFlowLine,
|
|
1031
|
+
learningHealthLine,
|
|
998
1032
|
feedbackLine,
|
|
999
1033
|
attributionLine,
|
|
1000
1034
|
attributionCoverageLine,
|
|
@@ -1015,7 +1049,12 @@ export function captureOperatorProofBundle(options) {
|
|
|
1015
1049
|
hardeningSnapshot,
|
|
1016
1050
|
verdict,
|
|
1017
1051
|
statusSignals,
|
|
1052
|
+
surfaceLine,
|
|
1053
|
+
surfacesLine,
|
|
1054
|
+
hotfixLine,
|
|
1018
1055
|
guardLine,
|
|
1056
|
+
learningFlowLine,
|
|
1057
|
+
learningHealthLine,
|
|
1019
1058
|
feedbackLine,
|
|
1020
1059
|
attributionLine,
|
|
1021
1060
|
attributionCoverageLine,
|