harnery 0.36.0 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commander.js +4 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +87 -46
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +26 -1
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +11 -0
- package/dist/commands/diagnostics.d.ts +4 -0
- package/dist/commands/diagnostics.d.ts.map +1 -0
- package/dist/commands/diagnostics.js +229 -0
- package/dist/commands/files.d.ts +12 -0
- package/dist/commands/files.d.ts.map +1 -1
- package/dist/commands/files.js +54 -1
- package/dist/commands/governor.d.ts.map +1 -1
- package/dist/commands/governor.js +4 -0
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +71 -2
- package/dist/commands/qa-run.d.ts +4 -0
- package/dist/commands/qa-run.d.ts.map +1 -0
- package/dist/commands/qa-run.js +141 -0
- package/dist/commands/resources.d.ts +4 -0
- package/dist/commands/resources.d.ts.map +1 -0
- package/dist/commands/resources.js +29 -0
- package/dist/commands/supervisor.d.ts +4 -0
- package/dist/commands/supervisor.d.ts.map +1 -0
- package/dist/commands/supervisor.js +101 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +17 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +4 -0
- package/dist/core/agents/cli.js +7 -3
- package/dist/core/agents/health.d.ts +17 -0
- package/dist/core/agents/health.d.ts.map +1 -0
- package/dist/core/agents/health.js +109 -0
- package/dist/core/agents/mailbox.d.ts +92 -0
- package/dist/core/agents/mailbox.d.ts.map +1 -0
- package/dist/core/agents/mailbox.js +325 -0
- package/dist/core/agents/reconcile-coordination-v3.d.ts +44 -0
- package/dist/core/agents/reconcile-coordination-v3.d.ts.map +1 -0
- package/dist/core/agents/reconcile-coordination-v3.js +58 -0
- package/dist/core/agents/render/prompt-context.d.ts +5 -0
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +34 -13
- package/dist/core/agents/render/session-context.d.ts +8 -0
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +34 -3
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/commit-conflict.js +50 -1
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +6 -10
- package/dist/core/agents/session-finalizer-v3.js +4 -1
- package/dist/core/artifacts/index.d.ts +26 -1
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +146 -6
- package/dist/core/config.d.ts +12 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +43 -0
- package/dist/core/diagnostics/advice.d.ts +9 -0
- package/dist/core/diagnostics/advice.d.ts.map +1 -0
- package/dist/core/diagnostics/advice.js +112 -0
- package/dist/core/diagnostics/bundle.d.ts +35 -0
- package/dist/core/diagnostics/bundle.d.ts.map +1 -0
- package/dist/core/diagnostics/bundle.js +874 -0
- package/dist/core/diagnostics/comparison.d.ts +5 -0
- package/dist/core/diagnostics/comparison.d.ts.map +1 -0
- package/dist/core/diagnostics/comparison.js +444 -0
- package/dist/core/diagnostics/contract.d.ts +245 -0
- package/dist/core/diagnostics/contract.d.ts.map +1 -0
- package/dist/core/diagnostics/contract.js +18 -0
- package/dist/core/diagnostics/identity.d.ts +3 -0
- package/dist/core/diagnostics/identity.d.ts.map +1 -0
- package/dist/core/diagnostics/identity.js +10 -0
- package/dist/core/diagnostics/index.d.ts +8 -0
- package/dist/core/diagnostics/index.d.ts.map +1 -0
- package/dist/core/diagnostics/index.js +7 -0
- package/dist/core/diagnostics/replay.d.ts +8 -0
- package/dist/core/diagnostics/replay.d.ts.map +1 -0
- package/dist/core/diagnostics/replay.js +213 -0
- package/dist/core/diagnostics/sanitize.d.ts +9 -0
- package/dist/core/diagnostics/sanitize.d.ts.map +1 -0
- package/dist/core/diagnostics/sanitize.js +84 -0
- package/dist/core/events/legacy-storage/compression.d.ts +13 -0
- package/dist/core/events/legacy-storage/compression.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/compression.js +107 -0
- package/dist/core/events/legacy-storage/index.d.ts +1 -0
- package/dist/core/events/legacy-storage/index.d.ts.map +1 -1
- package/dist/core/events/legacy-storage/index.js +1 -0
- package/dist/core/events/v3/archive-retention.d.ts +33 -0
- package/dist/core/events/v3/archive-retention.d.ts.map +1 -0
- package/dist/core/events/v3/archive-retention.js +195 -0
- package/dist/core/events/v3/capabilities.d.ts +1 -1
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +1 -0
- package/dist/core/events/v3/index.d.ts +1 -0
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +1 -0
- package/dist/core/events/v3/live-routing.d.ts.map +1 -1
- package/dist/core/events/v3/live-routing.js +1 -0
- package/dist/core/events/v3/producers/hook-base.d.ts +1 -1
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +13 -2
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +1 -0
- package/dist/core/events/v3/producers/recorder.d.ts +16 -0
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +88 -1
- package/dist/core/hooks/adapter/output.d.ts +8 -0
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +11 -1
- package/dist/core/hooks/cli.js +183 -192
- package/dist/core/hooks/health.d.ts +59 -0
- package/dist/core/hooks/health.d.ts.map +1 -0
- package/dist/core/hooks/health.js +84 -0
- package/dist/core/resources/contract.d.ts +90 -0
- package/dist/core/resources/contract.d.ts.map +1 -0
- package/dist/core/resources/contract.js +2 -0
- package/dist/core/resources/index.d.ts +6 -0
- package/dist/core/resources/index.d.ts.map +1 -0
- package/dist/core/resources/index.js +5 -0
- package/dist/core/resources/sampler.d.ts +27 -0
- package/dist/core/resources/sampler.d.ts.map +1 -0
- package/dist/core/resources/sampler.js +357 -0
- package/dist/core/resources/service-status.d.ts +3 -0
- package/dist/core/resources/service-status.d.ts.map +1 -0
- package/dist/core/resources/service-status.js +48 -0
- package/dist/core/resources/service.d.ts +26 -0
- package/dist/core/resources/service.d.ts.map +1 -0
- package/dist/core/resources/service.js +292 -0
- package/dist/core/resources/storage.d.ts +13 -0
- package/dist/core/resources/storage.d.ts.map +1 -0
- package/dist/core/resources/storage.js +30 -0
- package/dist/core/storage/atomic-json.d.ts +3 -0
- package/dist/core/storage/atomic-json.d.ts.map +1 -0
- package/dist/core/storage/atomic-json.js +15 -0
- package/dist/core/storage/builtins.d.ts.map +1 -1
- package/dist/core/storage/builtins.js +45 -6
- package/dist/core/storage/logger.d.ts +2 -0
- package/dist/core/storage/logger.d.ts.map +1 -1
- package/dist/core/storage/logger.js +2 -0
- package/dist/core/storage/query.d.ts +14 -0
- package/dist/core/storage/query.d.ts.map +1 -1
- package/dist/core/storage/query.js +51 -0
- package/dist/core/supervisor/activity.d.ts +4 -0
- package/dist/core/supervisor/activity.d.ts.map +1 -0
- package/dist/core/supervisor/activity.js +141 -0
- package/dist/core/supervisor/contract.d.ts +268 -0
- package/dist/core/supervisor/contract.d.ts.map +1 -0
- package/dist/core/supervisor/contract.js +35 -0
- package/dist/core/supervisor/explanations.d.ts +4 -0
- package/dist/core/supervisor/explanations.d.ts.map +1 -0
- package/dist/core/supervisor/explanations.js +71 -0
- package/dist/core/supervisor/findings.d.ts +20 -0
- package/dist/core/supervisor/findings.d.ts.map +1 -0
- package/dist/core/supervisor/findings.js +399 -0
- package/dist/core/supervisor/history.d.ts +9 -0
- package/dist/core/supervisor/history.d.ts.map +1 -0
- package/dist/core/supervisor/history.js +46 -0
- package/dist/core/supervisor/hook-health-alerts.d.ts +14 -0
- package/dist/core/supervisor/hook-health-alerts.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health-alerts.js +70 -0
- package/dist/core/supervisor/hook-health-storage.d.ts +5 -0
- package/dist/core/supervisor/hook-health-storage.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health-storage.js +24 -0
- package/dist/core/supervisor/hook-health.d.ts +72 -0
- package/dist/core/supervisor/hook-health.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health.js +203 -0
- package/dist/core/supervisor/hooks.d.ts +10 -0
- package/dist/core/supervisor/hooks.d.ts.map +1 -0
- package/dist/core/supervisor/hooks.js +28 -0
- package/dist/core/supervisor/index.d.ts +15 -0
- package/dist/core/supervisor/index.d.ts.map +1 -0
- package/dist/core/supervisor/index.js +14 -0
- package/dist/core/supervisor/log-feed.d.ts +9 -0
- package/dist/core/supervisor/log-feed.d.ts.map +1 -0
- package/dist/core/supervisor/log-feed.js +103 -0
- package/dist/core/supervisor/service.d.ts +29 -0
- package/dist/core/supervisor/service.d.ts.map +1 -0
- package/dist/core/supervisor/service.js +450 -0
- package/dist/core/supervisor/services.d.ts +11 -0
- package/dist/core/supervisor/services.d.ts.map +1 -0
- package/dist/core/supervisor/services.js +155 -0
- package/dist/core/supervisor/status.d.ts +3 -0
- package/dist/core/supervisor/status.d.ts.map +1 -0
- package/dist/core/supervisor/status.js +48 -0
- package/dist/core/supervisor/storage.d.ts +30 -0
- package/dist/core/supervisor/storage.d.ts.map +1 -0
- package/dist/core/supervisor/storage.js +73 -0
- package/dist/core/supervisor/timeline.d.ts +3 -0
- package/dist/core/supervisor/timeline.d.ts.map +1 -0
- package/dist/core/supervisor/timeline.js +87 -0
- package/dist/core/workflow/admission.d.ts +23 -0
- package/dist/core/workflow/admission.d.ts.map +1 -0
- package/dist/core/workflow/admission.js +136 -0
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +77 -2
- package/dist/core/workflow/index.d.ts +3 -2
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/index.js +2 -1
- package/dist/core/workflow/proof.d.ts +2 -1
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +39 -1
- package/dist/core/workflow/run-state.d.ts +3 -2
- package/dist/core/workflow/run-state.d.ts.map +1 -1
- package/dist/core/workflow/run-state.js +8 -1
- package/dist/core/workflow/types.d.ts +33 -1
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/types.js +2 -1
- package/dist/lib/browser/client.d.ts +5 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +1 -0
- package/dist/lib/browser/index.d.ts +2 -0
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +173 -0
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -0
- package/dist/lib/browser/qa-run-contracts.js +226 -0
- package/dist/lib/browser/qa-run.d.ts +51 -0
- package/dist/lib/browser/qa-run.d.ts.map +1 -0
- package/dist/lib/browser/qa-run.js +684 -0
- package/dist/lib/coord-root-id.d.ts +9 -0
- package/dist/lib/coord-root-id.d.ts.map +1 -0
- package/dist/lib/coord-root-id.js +17 -0
- package/dist/lib/instructions/apply.d.ts +3 -1
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +74 -3
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +6 -0
- package/package.json +12 -1
- package/src/commander.ts +26 -0
- package/src/commands/agents.ts +102 -49
- package/src/commands/artifacts.ts +40 -2
- package/src/commands/browse.ts +15 -0
- package/src/commands/diagnostics.ts +271 -0
- package/src/commands/files.ts +102 -2
- package/src/commands/governor.ts +8 -0
- package/src/commands/ledger-v3.ts +82 -0
- package/src/commands/qa-run.ts +184 -0
- package/src/commands/resources.ts +38 -0
- package/src/commands/supervisor.ts +141 -0
- package/src/commands/web.ts +19 -0
- package/src/commands/workflow.ts +8 -0
- package/src/core/agents/cli.ts +7 -3
- package/src/core/agents/health.ts +142 -0
- package/src/core/agents/mailbox.ts +373 -0
- package/src/core/agents/reconcile-coordination-v3.ts +77 -0
- package/src/core/agents/render/prompt-context.ts +42 -12
- package/src/core/agents/render/session-context.ts +37 -3
- package/src/core/agents/rules/commit-conflict.ts +58 -1
- package/src/core/agents/rules/stop-hook.ts +6 -12
- package/src/core/agents/session-finalizer-v3.ts +4 -1
- package/src/core/artifacts/index.ts +196 -10
- package/src/core/config.ts +111 -2
- package/src/core/diagnostics/advice.ts +147 -0
- package/src/core/diagnostics/bundle.ts +1142 -0
- package/src/core/diagnostics/comparison.ts +565 -0
- package/src/core/diagnostics/contract.ts +311 -0
- package/src/core/diagnostics/identity.ts +11 -0
- package/src/core/diagnostics/index.ts +7 -0
- package/src/core/diagnostics/replay.ts +314 -0
- package/src/core/diagnostics/sanitize.ts +97 -0
- package/src/core/events/legacy-storage/compression.ts +130 -0
- package/src/core/events/legacy-storage/index.ts +1 -0
- package/src/core/events/v3/archive-retention.ts +251 -0
- package/src/core/events/v3/capabilities.ts +2 -0
- package/src/core/events/v3/index.ts +9 -0
- package/src/core/events/v3/live-routing.ts +1 -0
- package/src/core/events/v3/producers/hook-base.ts +14 -2
- package/src/core/events/v3/producers/intake.ts +1 -0
- package/src/core/events/v3/producers/recorder.ts +110 -1
- package/src/core/hooks/adapter/output.ts +12 -1
- package/src/core/hooks/cli.ts +192 -215
- package/src/core/hooks/health.ts +146 -0
- package/src/core/resources/contract.ts +98 -0
- package/src/core/resources/index.ts +5 -0
- package/src/core/resources/sampler.ts +458 -0
- package/src/core/resources/service-status.ts +62 -0
- package/src/core/resources/service.ts +337 -0
- package/src/core/resources/storage.ts +44 -0
- package/src/core/storage/atomic-json.ts +15 -0
- package/src/core/storage/builtins.ts +62 -6
- package/src/core/storage/logger.ts +2 -0
- package/src/core/storage/query.ts +58 -0
- package/src/core/supervisor/activity.ts +193 -0
- package/src/core/supervisor/contract.ts +312 -0
- package/src/core/supervisor/explanations.ts +104 -0
- package/src/core/supervisor/findings.ts +788 -0
- package/src/core/supervisor/history.ts +61 -0
- package/src/core/supervisor/hook-health-alerts.ts +108 -0
- package/src/core/supervisor/hook-health-storage.ts +25 -0
- package/src/core/supervisor/hook-health.ts +301 -0
- package/src/core/supervisor/hooks.ts +35 -0
- package/src/core/supervisor/index.ts +14 -0
- package/src/core/supervisor/log-feed.ts +131 -0
- package/src/core/supervisor/service.ts +511 -0
- package/src/core/supervisor/services.ts +203 -0
- package/src/core/supervisor/status.ts +59 -0
- package/src/core/supervisor/storage.ts +126 -0
- package/src/core/supervisor/timeline.ts +133 -0
- package/src/core/workflow/admission.ts +215 -0
- package/src/core/workflow/engine.ts +93 -1
- package/src/core/workflow/index.ts +10 -0
- package/src/core/workflow/proof.ts +54 -1
- package/src/core/workflow/run-state.ts +13 -1
- package/src/core/workflow/types.ts +39 -1
- package/src/lib/browser/client.ts +6 -0
- package/src/lib/browser/index.ts +29 -0
- package/src/lib/browser/qa-run-contracts.ts +380 -0
- package/src/lib/browser/qa-run.ts +784 -0
- package/src/lib/coord-root-id.ts +23 -0
- package/src/lib/instructions/apply.ts +81 -2
- package/src/lib/instructions/templates.ts +6 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type DiagnosticBundleComparison, type ValidatedDiagnosticBundle } from "./contract.js";
|
|
2
|
+
export declare function compareDiagnosticBundles(repoRoot: string, beforeRef: string, afterRef: string): DiagnosticBundleComparison;
|
|
3
|
+
export declare function compareValidatedDiagnosticBundles(before: ValidatedDiagnosticBundle, after: ValidatedDiagnosticBundle): DiagnosticBundleComparison;
|
|
4
|
+
export declare function renderDiagnosticBundleComparison(comparison: DiagnosticBundleComparison): string;
|
|
5
|
+
//# sourceMappingURL=comparison.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comparison.d.ts","sourceRoot":"","sources":["../../../src/core/diagnostics/comparison.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,0BAA0B,EAY/B,KAAK,yBAAyB,EAC/B,MAAM,eAAe,CAAC;AAMvB,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,0BAA0B,CAK5B;AAED,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,yBAAyB,EACjC,KAAK,EAAE,yBAAyB,GAC/B,0BAA0B,CAiG5B;AAED,wBAAgB,gCAAgC,CAAC,UAAU,EAAE,0BAA0B,GAAG,MAAM,CA0B/F"}
|
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
import { validateDiagnosticBundle } from "./bundle.js";
|
|
2
|
+
import { DIAGNOSTIC_COMPARISON_SCHEMA_VERSION, } from "./contract.js";
|
|
3
|
+
import { canonicalJson, sha256 } from "./replay.js";
|
|
4
|
+
const HOOK_SOURCE = "supervisor.hook-health";
|
|
5
|
+
const ADMISSION_SOURCE = "workflow.diagnostic-admission";
|
|
6
|
+
export function compareDiagnosticBundles(repoRoot, beforeRef, afterRef) {
|
|
7
|
+
return compareValidatedDiagnosticBundles(validateDiagnosticBundle(repoRoot, beforeRef), validateDiagnosticBundle(repoRoot, afterRef));
|
|
8
|
+
}
|
|
9
|
+
export function compareValidatedDiagnosticBundles(before, after) {
|
|
10
|
+
const warnings = [];
|
|
11
|
+
if (before.manifest.threshold_digest !== after.manifest.threshold_digest) {
|
|
12
|
+
warnings.push({
|
|
13
|
+
code: "threshold_digest_changed",
|
|
14
|
+
summary: "Finding thresholds changed between captures.",
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
if (before.manifest.engine_version !== after.manifest.engine_version) {
|
|
18
|
+
warnings.push({
|
|
19
|
+
code: "engine_version_changed",
|
|
20
|
+
summary: "The captures were produced by different Harnery builds.",
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
if (before.manifest.machine_id !== after.manifest.machine_id) {
|
|
24
|
+
warnings.push({
|
|
25
|
+
code: "machine_changed",
|
|
26
|
+
summary: "The captures came from different pseudonymous machines.",
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
if (Date.parse(after.manifest.captured_at) < Date.parse(before.manifest.captured_at)) {
|
|
30
|
+
warnings.push({
|
|
31
|
+
code: "capture_order_reversed",
|
|
32
|
+
summary: "The after capture predates the before capture.",
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
const beforeIndex = indexFindings(before.expected.findings);
|
|
36
|
+
const afterIndex = indexFindings(after.expected.findings);
|
|
37
|
+
if (beforeIndex.duplicateCount + afterIndex.duplicateCount > 0) {
|
|
38
|
+
warnings.push({
|
|
39
|
+
code: "duplicate_fingerprint",
|
|
40
|
+
summary: `${beforeIndex.duplicateCount + afterIndex.duplicateCount} older finding episode(s) shared a fingerprint and were omitted.`,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const capabilities = compareCapabilities(before, after);
|
|
44
|
+
if (capabilities.some((row) => row.change !== "unchanged")) {
|
|
45
|
+
warnings.push({
|
|
46
|
+
code: "source_capability_changed",
|
|
47
|
+
summary: "One or more captured source capabilities changed.",
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const hookHealth = optionalSourceComparison(before, after, HOOK_SOURCE, hookHealthSummary);
|
|
51
|
+
if (!hookHealth.before || !hookHealth.after) {
|
|
52
|
+
warnings.push({
|
|
53
|
+
code: "hook_health_unavailable",
|
|
54
|
+
summary: "Completed-hook comparison is partial because one or both bundles lack hook-health evidence.",
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
const shadowAdmission = optionalSourceComparison(before, after, ADMISSION_SOURCE, shadowAdmissionSummary);
|
|
58
|
+
if (!shadowAdmission.before || !shadowAdmission.after) {
|
|
59
|
+
warnings.push({
|
|
60
|
+
code: "shadow_admission_unavailable",
|
|
61
|
+
summary: "Shadow-admission comparison is partial because one or both bundles lack admission evidence.",
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const rows = compareFindings(beforeIndex.rows, afterIndex.rows);
|
|
65
|
+
const base = {
|
|
66
|
+
schema_version: DIAGNOSTIC_COMPARISON_SCHEMA_VERSION,
|
|
67
|
+
observer_only: true,
|
|
68
|
+
before: bundleRef(before),
|
|
69
|
+
after: bundleRef(after),
|
|
70
|
+
comparability: warnings.length === 0 ? "comparable" : "partial",
|
|
71
|
+
warnings,
|
|
72
|
+
advice: {
|
|
73
|
+
before: before.expected.advice,
|
|
74
|
+
after: after.expected.advice,
|
|
75
|
+
direction: adviceDirection(before.expected.advice.pressure, after.expected.advice.pressure),
|
|
76
|
+
},
|
|
77
|
+
findings: {
|
|
78
|
+
total: rows.length,
|
|
79
|
+
regressions: countImpact(rows, "regression"),
|
|
80
|
+
worsened: countImpact(rows, "worsened"),
|
|
81
|
+
changed: countImpact(rows, "changed"),
|
|
82
|
+
improved: countImpact(rows, "improved"),
|
|
83
|
+
recoveries: countImpact(rows, "recovery"),
|
|
84
|
+
unchanged: countImpact(rows, "unchanged"),
|
|
85
|
+
rows,
|
|
86
|
+
},
|
|
87
|
+
capabilities,
|
|
88
|
+
hook_health: hookHealth,
|
|
89
|
+
shadow_admission: shadowAdmission,
|
|
90
|
+
};
|
|
91
|
+
return {
|
|
92
|
+
...base,
|
|
93
|
+
comparison_digest: sha256(canonicalJson(base)),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export function renderDiagnosticBundleComparison(comparison) {
|
|
97
|
+
const lines = [
|
|
98
|
+
`diagnostic comparison: ${comparison.before.artifact_id} -> ${comparison.after.artifact_id}`,
|
|
99
|
+
`comparability: ${comparison.comparability}; pressure: ${comparison.before.pressure} -> ${comparison.after.pressure} (${comparison.advice.direction})`,
|
|
100
|
+
`findings: ${comparison.findings.regressions} regression, ${comparison.findings.worsened} worsened, ${comparison.findings.changed} changed, ${comparison.findings.improved} improved, ${comparison.findings.recoveries} recovery, ${comparison.findings.unchanged} unchanged`,
|
|
101
|
+
];
|
|
102
|
+
if (comparison.warnings.length > 0) {
|
|
103
|
+
lines.push("warnings:");
|
|
104
|
+
for (const warning of comparison.warnings)
|
|
105
|
+
lines.push(` - ${warning.code}: ${warning.summary}`);
|
|
106
|
+
}
|
|
107
|
+
if (comparison.findings.rows.length > 0) {
|
|
108
|
+
lines.push("signals:");
|
|
109
|
+
for (const row of comparison.findings.rows) {
|
|
110
|
+
const finding = row.after ?? row.before;
|
|
111
|
+
lines.push(` ${row.impact.padEnd(10)} ${finding.finding_kind} ${finding.scope_kind}:${finding.scope_id} (${row.fingerprint})`);
|
|
112
|
+
for (const change of row.field_changes) {
|
|
113
|
+
lines.push(` ${change.field}: ${String(change.before)} -> ${String(change.after)}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
lines.push(`comparison digest: ${comparison.comparison_digest}`);
|
|
118
|
+
lines.push("observer only: no thresholds, processes, hooks, or workflow dispatch changed");
|
|
119
|
+
return `${lines.join("\n")}\n`;
|
|
120
|
+
}
|
|
121
|
+
function bundleRef(bundle) {
|
|
122
|
+
return {
|
|
123
|
+
artifact_id: bundle.manifest.artifact_id,
|
|
124
|
+
captured_at: bundle.manifest.captured_at,
|
|
125
|
+
machine_id: bundle.manifest.machine_id,
|
|
126
|
+
engine_version: bundle.manifest.engine_version,
|
|
127
|
+
threshold_digest: bundle.manifest.threshold_digest,
|
|
128
|
+
finding_count: bundle.expected.findings.length,
|
|
129
|
+
pressure: bundle.expected.advice.pressure,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function indexFindings(findings) {
|
|
133
|
+
const sorted = [...findings].sort((left, right) => Date.parse(right.observed_at) - Date.parse(left.observed_at) ||
|
|
134
|
+
left.id.localeCompare(right.id));
|
|
135
|
+
const rows = new Map();
|
|
136
|
+
let duplicateCount = 0;
|
|
137
|
+
for (const finding of sorted) {
|
|
138
|
+
if (rows.has(finding.fingerprint))
|
|
139
|
+
duplicateCount += 1;
|
|
140
|
+
else
|
|
141
|
+
rows.set(finding.fingerprint, finding);
|
|
142
|
+
}
|
|
143
|
+
return { rows, duplicateCount };
|
|
144
|
+
}
|
|
145
|
+
function compareFindings(before, after) {
|
|
146
|
+
const fingerprints = [...new Set([...before.keys(), ...after.keys()])].sort();
|
|
147
|
+
return fingerprints
|
|
148
|
+
.map((fingerprint) => {
|
|
149
|
+
const previous = before.get(fingerprint);
|
|
150
|
+
const current = after.get(fingerprint);
|
|
151
|
+
if (!previous && current) {
|
|
152
|
+
return {
|
|
153
|
+
fingerprint,
|
|
154
|
+
change_class: "added",
|
|
155
|
+
impact: current.state === "opened" ? "regression" : "changed",
|
|
156
|
+
after: current,
|
|
157
|
+
field_changes: [],
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if (previous && !current) {
|
|
161
|
+
return {
|
|
162
|
+
fingerprint,
|
|
163
|
+
change_class: "resolved",
|
|
164
|
+
impact: previous.state === "opened" ? "recovery" : "changed",
|
|
165
|
+
before: previous,
|
|
166
|
+
field_changes: [],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
const fieldChanges = compareFindingFields(previous, current);
|
|
170
|
+
return {
|
|
171
|
+
fingerprint,
|
|
172
|
+
change_class: "persistent",
|
|
173
|
+
impact: persistentImpact(fieldChanges),
|
|
174
|
+
before: previous,
|
|
175
|
+
after: current,
|
|
176
|
+
field_changes: fieldChanges,
|
|
177
|
+
};
|
|
178
|
+
})
|
|
179
|
+
.sort(compareFindingRows);
|
|
180
|
+
}
|
|
181
|
+
function compareFindingFields(before, after) {
|
|
182
|
+
const rows = [];
|
|
183
|
+
addRankedChange(rows, "severity", before.severity, after.severity, severityRank);
|
|
184
|
+
addRankedChange(rows, "state", before.state, after.state, stateRank);
|
|
185
|
+
addRankedChange(rows, "occurrence_count", before.occurrence_count, after.occurrence_count, numberRank);
|
|
186
|
+
if (before.peak_unit === after.peak_unit &&
|
|
187
|
+
before.peak_observed_value !== undefined &&
|
|
188
|
+
after.peak_observed_value !== undefined) {
|
|
189
|
+
addRankedChange(rows, "peak_observed_value", before.peak_observed_value, after.peak_observed_value, numberRank);
|
|
190
|
+
}
|
|
191
|
+
addChangedField(rows, "owner", owner(before), owner(after));
|
|
192
|
+
addChangedField(rows, "workload_relationship", before.workload_context?.relationship ?? null, after.workload_context?.relationship ?? null);
|
|
193
|
+
return rows;
|
|
194
|
+
}
|
|
195
|
+
function addRankedChange(rows, field, before, after, rank) {
|
|
196
|
+
if (before === after)
|
|
197
|
+
return;
|
|
198
|
+
rows.push({
|
|
199
|
+
field,
|
|
200
|
+
before,
|
|
201
|
+
after,
|
|
202
|
+
impact: rank(after) > rank(before) ? "worsened" : "improved",
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
function addChangedField(rows, field, before, after) {
|
|
206
|
+
if (before === after)
|
|
207
|
+
return;
|
|
208
|
+
rows.push({ field, before, after, impact: "changed" });
|
|
209
|
+
}
|
|
210
|
+
function persistentImpact(changes) {
|
|
211
|
+
if (changes.length === 0)
|
|
212
|
+
return "unchanged";
|
|
213
|
+
const worsened = changes.some((row) => row.impact === "worsened");
|
|
214
|
+
const improved = changes.some((row) => row.impact === "improved");
|
|
215
|
+
const changed = changes.some((row) => row.impact === "changed");
|
|
216
|
+
if (worsened && !improved && !changed)
|
|
217
|
+
return "worsened";
|
|
218
|
+
if (improved && !worsened && !changed)
|
|
219
|
+
return "improved";
|
|
220
|
+
return "changed";
|
|
221
|
+
}
|
|
222
|
+
function compareFindingRows(left, right) {
|
|
223
|
+
const impact = impactRank(left.impact) - impactRank(right.impact);
|
|
224
|
+
if (impact !== 0)
|
|
225
|
+
return impact;
|
|
226
|
+
const leftFinding = left.after ?? left.before;
|
|
227
|
+
const rightFinding = right.after ?? right.before;
|
|
228
|
+
const severity = severityRank(rightFinding.severity) - severityRank(leftFinding.severity);
|
|
229
|
+
return (severity ||
|
|
230
|
+
leftFinding.finding_kind.localeCompare(rightFinding.finding_kind) ||
|
|
231
|
+
leftFinding.scope_kind.localeCompare(rightFinding.scope_kind) ||
|
|
232
|
+
leftFinding.scope_id.localeCompare(rightFinding.scope_id) ||
|
|
233
|
+
left.fingerprint.localeCompare(right.fingerprint));
|
|
234
|
+
}
|
|
235
|
+
function compareCapabilities(before, after) {
|
|
236
|
+
const previous = capabilityMap(before.manifest.capabilities);
|
|
237
|
+
const current = capabilityMap(after.manifest.capabilities);
|
|
238
|
+
const sourceKinds = [...new Set([...previous.keys(), ...current.keys()])].sort();
|
|
239
|
+
return sourceKinds.map((sourceKind) => {
|
|
240
|
+
const left = previous.get(sourceKind);
|
|
241
|
+
const right = current.get(sourceKind);
|
|
242
|
+
return {
|
|
243
|
+
source_kind: sourceKind,
|
|
244
|
+
change: !left
|
|
245
|
+
? "added"
|
|
246
|
+
: !right
|
|
247
|
+
? "removed"
|
|
248
|
+
: sameCapability(left, right)
|
|
249
|
+
? "unchanged"
|
|
250
|
+
: "changed",
|
|
251
|
+
...(left ? { before: left } : {}),
|
|
252
|
+
...(right ? { after: right } : {}),
|
|
253
|
+
};
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
function capabilityMap(rows) {
|
|
257
|
+
return new Map([...rows]
|
|
258
|
+
.sort((a, b) => a.source_kind.localeCompare(b.source_kind))
|
|
259
|
+
.map((row) => [row.source_kind, row]));
|
|
260
|
+
}
|
|
261
|
+
function sameCapability(left, right) {
|
|
262
|
+
return (left.state === right.state &&
|
|
263
|
+
left.reason_code === right.reason_code &&
|
|
264
|
+
left.detail === right.detail);
|
|
265
|
+
}
|
|
266
|
+
function optionalSourceComparison(before, after, sourceKind, parse) {
|
|
267
|
+
const previous = optionalSource(before, sourceKind, parse);
|
|
268
|
+
const current = optionalSource(after, sourceKind, parse);
|
|
269
|
+
return {
|
|
270
|
+
before_capability: previous.capability,
|
|
271
|
+
after_capability: current.capability,
|
|
272
|
+
...(previous.value ? { before: previous.value } : {}),
|
|
273
|
+
...(current.value ? { after: current.value } : {}),
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
function optionalSource(bundle, sourceKind, parse) {
|
|
277
|
+
const source = bundle.observations.sources.find((candidate) => candidate.source_kind === sourceKind);
|
|
278
|
+
if (!source) {
|
|
279
|
+
return {
|
|
280
|
+
capability: {
|
|
281
|
+
source_kind: sourceKind,
|
|
282
|
+
state: "unsupported",
|
|
283
|
+
reason_code: "source_not_captured",
|
|
284
|
+
},
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
const capability = {
|
|
288
|
+
source_kind: sourceKind,
|
|
289
|
+
state: source.capability,
|
|
290
|
+
...(source.reason_code ? { reason_code: source.reason_code } : {}),
|
|
291
|
+
};
|
|
292
|
+
if (source.value === undefined)
|
|
293
|
+
return { capability };
|
|
294
|
+
const value = parse(source.value);
|
|
295
|
+
return value
|
|
296
|
+
? { capability, value }
|
|
297
|
+
: {
|
|
298
|
+
capability: {
|
|
299
|
+
source_kind: sourceKind,
|
|
300
|
+
state: "malformed",
|
|
301
|
+
reason_code: "source_projection_malformed",
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
function hookHealthSummary(value) {
|
|
306
|
+
const record = object(value);
|
|
307
|
+
const summary = object(record?.summary);
|
|
308
|
+
const aggregates = Array.isArray(record?.aggregates) ? record.aggregates : undefined;
|
|
309
|
+
if (!record || !summary || !aggregates)
|
|
310
|
+
return undefined;
|
|
311
|
+
const parsedSummary = integerFields(summary, [
|
|
312
|
+
"invocation_count",
|
|
313
|
+
"degraded_count",
|
|
314
|
+
"faulted_count",
|
|
315
|
+
"slow_count",
|
|
316
|
+
"high_memory_count",
|
|
317
|
+
"retry_count",
|
|
318
|
+
]);
|
|
319
|
+
if (!parsedSummary)
|
|
320
|
+
return undefined;
|
|
321
|
+
const parsedAggregates = [];
|
|
322
|
+
for (const value of aggregates.slice(0, 40)) {
|
|
323
|
+
const row = object(value);
|
|
324
|
+
if (!row)
|
|
325
|
+
return undefined;
|
|
326
|
+
const numbers = integerFields(row, [
|
|
327
|
+
"invocation_count",
|
|
328
|
+
"degraded_count",
|
|
329
|
+
"faulted_count",
|
|
330
|
+
"retry_count",
|
|
331
|
+
"duration_p95_ms",
|
|
332
|
+
"rss_end_max_bytes",
|
|
333
|
+
]);
|
|
334
|
+
if (!numbers ||
|
|
335
|
+
typeof row.key !== "string" ||
|
|
336
|
+
typeof row.hook_name !== "string" ||
|
|
337
|
+
typeof row.adapter !== "string") {
|
|
338
|
+
return undefined;
|
|
339
|
+
}
|
|
340
|
+
parsedAggregates.push({
|
|
341
|
+
key: row.key,
|
|
342
|
+
hook_name: row.hook_name,
|
|
343
|
+
adapter: row.adapter,
|
|
344
|
+
...numbers,
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
...parsedSummary,
|
|
349
|
+
aggregates: parsedAggregates.sort((left, right) => left.key.localeCompare(right.key)),
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function shadowAdmissionSummary(value) {
|
|
353
|
+
const record = object(value);
|
|
354
|
+
const rows = Array.isArray(record?.records) ? record.records : undefined;
|
|
355
|
+
if (!record || !rows)
|
|
356
|
+
return undefined;
|
|
357
|
+
const summary = {
|
|
358
|
+
record_count: rows.length,
|
|
359
|
+
observed_count: 0,
|
|
360
|
+
not_needed_count: 0,
|
|
361
|
+
unavailable_count: 0,
|
|
362
|
+
normal_count: 0,
|
|
363
|
+
elevated_count: 0,
|
|
364
|
+
critical_count: 0,
|
|
365
|
+
unknown_count: 0,
|
|
366
|
+
max_wait_ms: 0,
|
|
367
|
+
};
|
|
368
|
+
for (const value of rows) {
|
|
369
|
+
const row = object(value);
|
|
370
|
+
if (!row || (row.state !== "observed" && row.state !== "not-needed"))
|
|
371
|
+
return undefined;
|
|
372
|
+
if (row.state === "not-needed") {
|
|
373
|
+
summary.not_needed_count += 1;
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
summary.observed_count += 1;
|
|
377
|
+
const pressure = row.pressure;
|
|
378
|
+
if (pressure === "normal")
|
|
379
|
+
summary.normal_count += 1;
|
|
380
|
+
else if (pressure === "elevated")
|
|
381
|
+
summary.elevated_count += 1;
|
|
382
|
+
else if (pressure === "critical")
|
|
383
|
+
summary.critical_count += 1;
|
|
384
|
+
else
|
|
385
|
+
summary.unknown_count += 1;
|
|
386
|
+
if (row.freshness === "unavailable")
|
|
387
|
+
summary.unavailable_count += 1;
|
|
388
|
+
if (typeof row.wait_ms === "number" && Number.isSafeInteger(row.wait_ms) && row.wait_ms >= 0) {
|
|
389
|
+
summary.max_wait_ms = Math.max(summary.max_wait_ms, row.wait_ms);
|
|
390
|
+
}
|
|
391
|
+
else
|
|
392
|
+
return undefined;
|
|
393
|
+
}
|
|
394
|
+
return summary;
|
|
395
|
+
}
|
|
396
|
+
function integerFields(record, keys) {
|
|
397
|
+
const result = {};
|
|
398
|
+
for (const key of keys) {
|
|
399
|
+
const value = record[key];
|
|
400
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)
|
|
401
|
+
return undefined;
|
|
402
|
+
result[key] = value;
|
|
403
|
+
}
|
|
404
|
+
return result;
|
|
405
|
+
}
|
|
406
|
+
function adviceDirection(before, after) {
|
|
407
|
+
if (before === after)
|
|
408
|
+
return "unchanged";
|
|
409
|
+
if (before === "unknown" || after === "unknown")
|
|
410
|
+
return "changed";
|
|
411
|
+
return pressureRank(after) > pressureRank(before) ? "escalated" : "deescalated";
|
|
412
|
+
}
|
|
413
|
+
function countImpact(rows, impact) {
|
|
414
|
+
return rows.filter((row) => row.impact === impact).length;
|
|
415
|
+
}
|
|
416
|
+
function owner(finding) {
|
|
417
|
+
const attribution = finding.attribution;
|
|
418
|
+
if (!attribution)
|
|
419
|
+
return null;
|
|
420
|
+
if (attribution.state === "attributed") {
|
|
421
|
+
return `${attribution.owner_kind ?? "unknown"}:${attribution.owner_id ?? "unknown"}`;
|
|
422
|
+
}
|
|
423
|
+
return `unattributed:${attribution.reason_code ?? "unknown"}`;
|
|
424
|
+
}
|
|
425
|
+
function severityRank(value) {
|
|
426
|
+
return value === "critical" ? 2 : value === "warning" ? 1 : 0;
|
|
427
|
+
}
|
|
428
|
+
function stateRank(value) {
|
|
429
|
+
return value === "opened" ? 1 : 0;
|
|
430
|
+
}
|
|
431
|
+
function numberRank(value) {
|
|
432
|
+
return value;
|
|
433
|
+
}
|
|
434
|
+
function pressureRank(value) {
|
|
435
|
+
return value === "critical" ? 2 : value === "elevated" ? 1 : 0;
|
|
436
|
+
}
|
|
437
|
+
function impactRank(value) {
|
|
438
|
+
return ["regression", "worsened", "changed", "improved", "recovery", "unchanged"].indexOf(value);
|
|
439
|
+
}
|
|
440
|
+
function object(value) {
|
|
441
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
442
|
+
? value
|
|
443
|
+
: undefined;
|
|
444
|
+
}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import type { SupervisorCapability, SupervisorFinding, SupervisorFindingExplanation, SupervisorTimeline } from "../supervisor/contract.js";
|
|
2
|
+
export declare const DIAGNOSTIC_BUNDLE_SCHEMA_VERSION: 3;
|
|
3
|
+
export declare const DIAGNOSTIC_COMMAND_SCHEMA_VERSION: 1;
|
|
4
|
+
export declare const DIAGNOSTIC_INPUT_SCHEMA_VERSION: 2;
|
|
5
|
+
export declare const DIAGNOSTIC_EXPECTED_SCHEMA_VERSION: 3;
|
|
6
|
+
export declare const DIAGNOSTIC_SUMMARY_SCHEMA_VERSION: 1;
|
|
7
|
+
export declare const DIAGNOSTIC_ADVICE_SCHEMA_VERSION: 1;
|
|
8
|
+
export declare const DIAGNOSTIC_COMPARISON_SCHEMA_VERSION: 1;
|
|
9
|
+
export declare const DIAGNOSTIC_ADVICE_LIMITS: {
|
|
10
|
+
readonly max_contributing_findings: 8;
|
|
11
|
+
readonly max_reasons: 4;
|
|
12
|
+
};
|
|
13
|
+
export type DiagnosticPressure = "normal" | "elevated" | "critical" | "unknown";
|
|
14
|
+
export type DiagnosticFanOutRecommendation = "proceed" | "use-caution" | "avoid-new-fan-out" | "unknown";
|
|
15
|
+
export interface DiagnosticAdviceFinding {
|
|
16
|
+
finding_id: string;
|
|
17
|
+
finding_kind: string;
|
|
18
|
+
severity: "warning" | "critical";
|
|
19
|
+
summary: string;
|
|
20
|
+
scope_kind: string;
|
|
21
|
+
scope_id: string;
|
|
22
|
+
occurrence_count: number;
|
|
23
|
+
owner_kind?: "agent" | "service";
|
|
24
|
+
owner_id?: string;
|
|
25
|
+
workload_relationship?: "active-work" | "unexpected-idle-growth" | "unknown";
|
|
26
|
+
}
|
|
27
|
+
export interface DiagnosticAdviceReason {
|
|
28
|
+
code: "critical_findings_active" | "warning_findings_active" | "findings_source_unavailable" | "no_active_pressure_findings";
|
|
29
|
+
summary: string;
|
|
30
|
+
finding_ids: readonly string[];
|
|
31
|
+
}
|
|
32
|
+
export interface DiagnosticAdvice {
|
|
33
|
+
schema_version: typeof DIAGNOSTIC_ADVICE_SCHEMA_VERSION;
|
|
34
|
+
evaluated_at: string;
|
|
35
|
+
pressure: DiagnosticPressure;
|
|
36
|
+
fan_out_recommendation: DiagnosticFanOutRecommendation;
|
|
37
|
+
observer_only: true;
|
|
38
|
+
summary: string;
|
|
39
|
+
source_capability: SupervisorCapability;
|
|
40
|
+
active_finding_count: number;
|
|
41
|
+
contributing_finding_count: number;
|
|
42
|
+
omitted_contributing_finding_count: number;
|
|
43
|
+
contributing_findings: readonly DiagnosticAdviceFinding[];
|
|
44
|
+
reasons: readonly DiagnosticAdviceReason[];
|
|
45
|
+
}
|
|
46
|
+
export declare const DIAGNOSTIC_BUNDLE_FILES: readonly ["diagnostic-manifest.json", "inputs/observations.json", "inputs/thresholds.json", "expected.json", "summary.json"];
|
|
47
|
+
export type DiagnosticBundleFilePath = (typeof DIAGNOSTIC_BUNDLE_FILES)[number];
|
|
48
|
+
export interface DiagnosticBundleFile {
|
|
49
|
+
path: Exclude<DiagnosticBundleFilePath, "diagnostic-manifest.json">;
|
|
50
|
+
media_type: "application/json";
|
|
51
|
+
bytes: number;
|
|
52
|
+
sha256: string;
|
|
53
|
+
}
|
|
54
|
+
export interface DiagnosticBundleSource {
|
|
55
|
+
source_kind: string;
|
|
56
|
+
schema_version?: number;
|
|
57
|
+
capability: SupervisorCapability["state"];
|
|
58
|
+
entry_count: number;
|
|
59
|
+
omitted_count: number;
|
|
60
|
+
file: "inputs/observations.json";
|
|
61
|
+
}
|
|
62
|
+
export interface DiagnosticBundleManifest {
|
|
63
|
+
schema_version: typeof DIAGNOSTIC_BUNDLE_SCHEMA_VERSION;
|
|
64
|
+
artifact_id: string;
|
|
65
|
+
captured_at: string;
|
|
66
|
+
machine_id: string;
|
|
67
|
+
finding_id?: string;
|
|
68
|
+
time_range: {
|
|
69
|
+
start_at: string;
|
|
70
|
+
end_at: string;
|
|
71
|
+
};
|
|
72
|
+
engine_version: string;
|
|
73
|
+
threshold_digest: string;
|
|
74
|
+
sources: readonly DiagnosticBundleSource[];
|
|
75
|
+
capabilities: readonly SupervisorCapability[];
|
|
76
|
+
files: readonly DiagnosticBundleFile[];
|
|
77
|
+
replay: {
|
|
78
|
+
input_file: "inputs/observations.json";
|
|
79
|
+
thresholds_file: "inputs/thresholds.json";
|
|
80
|
+
expected_file: "expected.json";
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
export interface DiagnosticSelection {
|
|
84
|
+
finding_id?: string;
|
|
85
|
+
start_at: string;
|
|
86
|
+
end_at: string;
|
|
87
|
+
}
|
|
88
|
+
export interface DiagnosticCapturedSource {
|
|
89
|
+
source_kind: string;
|
|
90
|
+
capability: SupervisorCapability["state"];
|
|
91
|
+
schema_version?: number;
|
|
92
|
+
observed_at?: string;
|
|
93
|
+
value?: unknown;
|
|
94
|
+
reason_code?: string;
|
|
95
|
+
}
|
|
96
|
+
export interface DiagnosticObservations {
|
|
97
|
+
schema_version: typeof DIAGNOSTIC_INPUT_SCHEMA_VERSION;
|
|
98
|
+
captured_at: string;
|
|
99
|
+
selection: DiagnosticSelection;
|
|
100
|
+
sources: readonly DiagnosticCapturedSource[];
|
|
101
|
+
}
|
|
102
|
+
export interface DiagnosticThresholds {
|
|
103
|
+
schema_version: typeof DIAGNOSTIC_INPUT_SCHEMA_VERSION;
|
|
104
|
+
values: Readonly<Record<string, unknown>>;
|
|
105
|
+
}
|
|
106
|
+
export interface DiagnosticExpected {
|
|
107
|
+
schema_version: typeof DIAGNOSTIC_EXPECTED_SCHEMA_VERSION;
|
|
108
|
+
threshold_digest: string;
|
|
109
|
+
selection: DiagnosticSelection;
|
|
110
|
+
findings: readonly SupervisorFinding[];
|
|
111
|
+
timelines: readonly SupervisorTimeline[];
|
|
112
|
+
explanations: readonly SupervisorFindingExplanation[];
|
|
113
|
+
advice: DiagnosticAdvice;
|
|
114
|
+
}
|
|
115
|
+
export interface DiagnosticSummary {
|
|
116
|
+
schema_version: typeof DIAGNOSTIC_SUMMARY_SCHEMA_VERSION;
|
|
117
|
+
artifact_id: string;
|
|
118
|
+
captured_at: string;
|
|
119
|
+
machine_id: string;
|
|
120
|
+
machine_id_kind: "pseudonymous";
|
|
121
|
+
selection: DiagnosticSelection;
|
|
122
|
+
source_count: number;
|
|
123
|
+
supported_source_count: number;
|
|
124
|
+
sanitized_value_count: number;
|
|
125
|
+
omitted_value_count: number;
|
|
126
|
+
total_bytes: number;
|
|
127
|
+
}
|
|
128
|
+
export interface ValidatedDiagnosticBundle {
|
|
129
|
+
path: string;
|
|
130
|
+
manifest: DiagnosticBundleManifest;
|
|
131
|
+
observations: DiagnosticObservations;
|
|
132
|
+
thresholds: DiagnosticThresholds;
|
|
133
|
+
expected: DiagnosticExpected;
|
|
134
|
+
summary: DiagnosticSummary;
|
|
135
|
+
}
|
|
136
|
+
export interface DiagnosticReplayResult {
|
|
137
|
+
schema_version: typeof DIAGNOSTIC_COMMAND_SCHEMA_VERSION;
|
|
138
|
+
artifact_id: string;
|
|
139
|
+
replayed_at: string;
|
|
140
|
+
matched: boolean;
|
|
141
|
+
threshold_digest: string;
|
|
142
|
+
expected_digest: string;
|
|
143
|
+
actual_digest: string;
|
|
144
|
+
finding_count: number;
|
|
145
|
+
}
|
|
146
|
+
export type DiagnosticComparisonImpact = "regression" | "worsened" | "changed" | "improved" | "recovery" | "unchanged";
|
|
147
|
+
export type DiagnosticFindingChangeClass = "added" | "resolved" | "persistent";
|
|
148
|
+
export interface DiagnosticFindingFieldChange {
|
|
149
|
+
field: "severity" | "state" | "occurrence_count" | "peak_observed_value" | "owner" | "workload_relationship";
|
|
150
|
+
before: string | number | null;
|
|
151
|
+
after: string | number | null;
|
|
152
|
+
impact: "worsened" | "improved" | "changed";
|
|
153
|
+
}
|
|
154
|
+
export interface DiagnosticFindingComparison {
|
|
155
|
+
fingerprint: string;
|
|
156
|
+
change_class: DiagnosticFindingChangeClass;
|
|
157
|
+
impact: DiagnosticComparisonImpact;
|
|
158
|
+
before?: SupervisorFinding;
|
|
159
|
+
after?: SupervisorFinding;
|
|
160
|
+
field_changes: readonly DiagnosticFindingFieldChange[];
|
|
161
|
+
}
|
|
162
|
+
export interface DiagnosticBundleComparisonRef {
|
|
163
|
+
artifact_id: string;
|
|
164
|
+
captured_at: string;
|
|
165
|
+
machine_id: string;
|
|
166
|
+
engine_version: string;
|
|
167
|
+
threshold_digest: string;
|
|
168
|
+
finding_count: number;
|
|
169
|
+
pressure: DiagnosticPressure;
|
|
170
|
+
}
|
|
171
|
+
export interface DiagnosticCapabilityComparison {
|
|
172
|
+
source_kind: string;
|
|
173
|
+
change: "added" | "removed" | "changed" | "unchanged";
|
|
174
|
+
before?: SupervisorCapability;
|
|
175
|
+
after?: SupervisorCapability;
|
|
176
|
+
}
|
|
177
|
+
export interface DiagnosticHookAggregateSummary {
|
|
178
|
+
key: string;
|
|
179
|
+
hook_name: string;
|
|
180
|
+
adapter: string;
|
|
181
|
+
invocation_count: number;
|
|
182
|
+
degraded_count: number;
|
|
183
|
+
faulted_count: number;
|
|
184
|
+
retry_count: number;
|
|
185
|
+
duration_p95_ms: number;
|
|
186
|
+
rss_end_max_bytes: number;
|
|
187
|
+
}
|
|
188
|
+
export interface DiagnosticHookHealthSummary {
|
|
189
|
+
invocation_count: number;
|
|
190
|
+
degraded_count: number;
|
|
191
|
+
faulted_count: number;
|
|
192
|
+
slow_count: number;
|
|
193
|
+
high_memory_count: number;
|
|
194
|
+
retry_count: number;
|
|
195
|
+
aggregates: readonly DiagnosticHookAggregateSummary[];
|
|
196
|
+
}
|
|
197
|
+
export interface DiagnosticShadowAdmissionSummary {
|
|
198
|
+
record_count: number;
|
|
199
|
+
observed_count: number;
|
|
200
|
+
not_needed_count: number;
|
|
201
|
+
unavailable_count: number;
|
|
202
|
+
normal_count: number;
|
|
203
|
+
elevated_count: number;
|
|
204
|
+
critical_count: number;
|
|
205
|
+
unknown_count: number;
|
|
206
|
+
max_wait_ms: number;
|
|
207
|
+
}
|
|
208
|
+
export interface DiagnosticOptionalSourceComparison<T> {
|
|
209
|
+
before_capability: SupervisorCapability;
|
|
210
|
+
after_capability: SupervisorCapability;
|
|
211
|
+
before?: T;
|
|
212
|
+
after?: T;
|
|
213
|
+
}
|
|
214
|
+
export interface DiagnosticComparisonWarning {
|
|
215
|
+
code: "threshold_digest_changed" | "engine_version_changed" | "machine_changed" | "capture_order_reversed" | "duplicate_fingerprint" | "source_capability_changed" | "hook_health_unavailable" | "shadow_admission_unavailable";
|
|
216
|
+
summary: string;
|
|
217
|
+
}
|
|
218
|
+
export interface DiagnosticBundleComparison {
|
|
219
|
+
schema_version: typeof DIAGNOSTIC_COMPARISON_SCHEMA_VERSION;
|
|
220
|
+
observer_only: true;
|
|
221
|
+
before: DiagnosticBundleComparisonRef;
|
|
222
|
+
after: DiagnosticBundleComparisonRef;
|
|
223
|
+
comparability: "comparable" | "partial";
|
|
224
|
+
warnings: readonly DiagnosticComparisonWarning[];
|
|
225
|
+
advice: {
|
|
226
|
+
before: DiagnosticAdvice;
|
|
227
|
+
after: DiagnosticAdvice;
|
|
228
|
+
direction: "escalated" | "deescalated" | "unchanged" | "changed";
|
|
229
|
+
};
|
|
230
|
+
findings: {
|
|
231
|
+
total: number;
|
|
232
|
+
regressions: number;
|
|
233
|
+
worsened: number;
|
|
234
|
+
changed: number;
|
|
235
|
+
improved: number;
|
|
236
|
+
recoveries: number;
|
|
237
|
+
unchanged: number;
|
|
238
|
+
rows: readonly DiagnosticFindingComparison[];
|
|
239
|
+
};
|
|
240
|
+
capabilities: readonly DiagnosticCapabilityComparison[];
|
|
241
|
+
hook_health: DiagnosticOptionalSourceComparison<DiagnosticHookHealthSummary>;
|
|
242
|
+
shadow_admission: DiagnosticOptionalSourceComparison<DiagnosticShadowAdmissionSummary>;
|
|
243
|
+
comparison_digest: string;
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=contract.d.ts.map
|