akm-cli 0.9.0-rc.1 → 0.9.0-rc.3
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/CHANGELOG.md +249 -9
- package/SECURITY.md +23 -24
- package/dist/assets/help/help-improve.md +10 -10
- package/dist/assets/hints/cli-hints-full.md +44 -10
- package/dist/assets/hints/cli-hints-short.md +6 -2
- package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/default.json +1 -0
- package/dist/assets/{profiles → improve-strategies}/frequent.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
- package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
- package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +3 -3
- package/dist/assets/{profiles → improve-strategies}/quick.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/recombine-only.json +2 -0
- package/dist/assets/{profiles → improve-strategies}/reflect-distill.json +4 -4
- package/dist/assets/{profiles → improve-strategies}/synthesize.json +2 -0
- package/dist/assets/stash-skeleton/README.md +28 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +12 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +11 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +7 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +7 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +98 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +63 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +127 -0
- package/dist/assets/tasks/core/backup.yml +3 -2
- package/dist/assets/tasks/core/extract.yml +1 -0
- package/dist/assets/tasks/core/improve.yml +1 -0
- package/dist/assets/tasks/core/index-refresh.yml +1 -0
- package/dist/assets/tasks/core/sync.yml +1 -0
- package/dist/assets/tasks/core/version-check.yml +1 -0
- package/dist/assets/tasks/graph-refresh-weekly.yml +4 -4
- package/dist/assets/templates/html/health.html +5 -1
- package/dist/cli/config-migrate.js +547 -126
- package/dist/cli/config-validate.js +10 -8
- package/dist/cli.js +50 -14
- package/dist/commands/agent/agent-dispatch.js +17 -16
- package/dist/commands/agent/agent-support.js +0 -24
- package/dist/commands/agent/contribute-cli.js +5 -15
- package/dist/commands/backup-cli.js +56 -0
- package/dist/commands/config-cli.js +48 -155
- package/dist/commands/env/secret.js +8 -5
- package/dist/commands/feedback-cli.js +24 -7
- package/dist/commands/health/checks.js +200 -74
- package/dist/commands/health/html-report.js +4 -0
- package/dist/commands/health/improve-metrics.js +30 -32
- package/dist/commands/health/llm-usage.js +19 -19
- package/dist/commands/health/md-report.js +4 -0
- package/dist/commands/health/metrics.js +2 -1
- package/dist/commands/health/surfaces.js +7 -5
- package/dist/commands/health.js +1 -1
- package/dist/commands/improve/anti-collapse.js +3 -3
- package/dist/commands/improve/collapse-detector.js +5 -5
- package/dist/commands/improve/consolidate/chunking.js +2 -2
- package/dist/commands/improve/consolidate.js +148 -88
- package/dist/commands/improve/distill/promote-memory.js +13 -18
- package/dist/commands/improve/distill/quality-gate.js +6 -8
- package/dist/commands/improve/distill-guards.js +1 -1
- package/dist/commands/improve/distill-promotion-policy.js +32 -26
- package/dist/commands/improve/distill.js +68 -41
- package/dist/commands/improve/eligibility.js +31 -20
- package/dist/commands/improve/extract-cli.js +47 -19
- package/dist/commands/improve/extract-prompt.js +2 -2
- package/dist/commands/improve/extract.js +153 -73
- package/dist/commands/improve/improve-auto-accept.js +14 -28
- package/dist/commands/improve/improve-cli.js +41 -17
- package/dist/commands/improve/improve-result-file.js +30 -24
- package/dist/commands/improve/improve-strategies.js +138 -0
- package/dist/commands/improve/improve.js +109 -38
- package/dist/commands/improve/locks.js +66 -45
- package/dist/commands/improve/loop-stages.js +86 -39
- package/dist/commands/improve/memory/memory-belief.js +79 -7
- package/dist/commands/improve/memory/memory-contradiction-detect.js +12 -4
- package/dist/commands/improve/preparation.js +122 -90
- package/dist/commands/improve/procedural.js +13 -8
- package/dist/commands/improve/recombine.js +33 -8
- package/dist/commands/improve/reflect.js +143 -228
- package/dist/commands/improve/salience.js +5 -1
- package/dist/commands/improve/shared.js +11 -5
- package/dist/commands/improve/source-identity.js +43 -0
- package/dist/commands/lint/base-linter.js +152 -42
- package/dist/commands/migrate-cli.js +36 -0
- package/dist/commands/mv-cli.js +1198 -0
- package/dist/commands/proposal/drain.js +16 -4
- package/dist/commands/proposal/proposal-cli.js +21 -10
- package/dist/commands/proposal/proposal.js +16 -55
- package/dist/commands/proposal/propose.js +64 -69
- package/dist/commands/proposal/repository.js +664 -58
- package/dist/commands/read/curate.js +4 -2
- package/dist/commands/read/knowledge.js +440 -5
- package/dist/commands/read/remember-cli.js +39 -2
- package/dist/commands/read/search-cli.js +6 -1
- package/dist/commands/read/search.js +6 -2
- package/dist/commands/read/show.js +8 -7
- package/dist/commands/registry-cli.js +29 -14
- package/dist/commands/remember.js +2 -0
- package/dist/commands/sources/init.js +13 -14
- package/dist/commands/sources/schema-repair.js +2 -4
- package/dist/commands/sources/self-update.js +156 -112
- package/dist/commands/sources/source-add.js +62 -73
- package/dist/commands/sources/source-manage.js +50 -46
- package/dist/commands/sources/sources-cli.js +7 -2
- package/dist/commands/sources/stash-cli.js +41 -4
- package/dist/commands/tasks/default-tasks.js +12 -12
- package/dist/commands/tasks/tasks-cli.js +7 -3
- package/dist/commands/tasks/tasks.js +113 -18
- package/dist/commands/wiki-cli.js +9 -10
- package/dist/core/asset/frontmatter.js +12 -2
- package/dist/core/common.js +41 -6
- package/dist/core/config/config-io.js +30 -19
- package/dist/core/config/config-schema.js +373 -69
- package/dist/core/config/config-types.js +3 -3
- package/dist/core/config/config-version.js +29 -0
- package/dist/core/config/config-walker.js +98 -27
- package/dist/core/config/config.js +135 -268
- package/dist/core/config/deep-merge.js +41 -0
- package/dist/core/config/engine-semantics.js +32 -0
- package/dist/core/errors.js +2 -2
- package/dist/core/extra-params.js +61 -0
- package/dist/core/file-lock.js +202 -57
- package/dist/core/improve-result.js +178 -0
- package/dist/core/maintenance-barrier.js +119 -0
- package/dist/core/migration-backup.js +1061 -0
- package/dist/core/migration-operation.js +44 -0
- package/dist/core/paths.js +3 -0
- package/dist/core/redaction.js +358 -0
- package/dist/core/state/migrations.js +15 -3
- package/dist/core/state-db.js +60 -2
- package/dist/core/write-source.js +86 -18
- package/dist/indexer/db/db.js +212 -41
- package/dist/indexer/graph/graph-extraction.js +28 -16
- package/dist/indexer/index-writer-lock.js +59 -51
- package/dist/indexer/index-written-assets.js +75 -49
- package/dist/indexer/indexer.js +52 -3
- package/dist/indexer/passes/memory-inference.js +10 -6
- package/dist/indexer/passes/metadata.js +250 -0
- package/dist/indexer/search/db-search.js +111 -44
- package/dist/indexer/search/fts-query.js +41 -0
- package/dist/indexer/search/ranking-contributors.js +48 -0
- package/dist/indexer/search/ranking.js +36 -23
- package/dist/indexer/search/search-fields.js +11 -1
- package/dist/indexer/search/search-source.js +2 -2
- package/dist/indexer/usage/usage-events.js +8 -2
- package/dist/integrations/agent/builder-shared.js +7 -0
- package/dist/integrations/agent/builders.js +5 -52
- package/dist/integrations/agent/config.js +3 -143
- package/dist/integrations/agent/detect.js +17 -2
- package/dist/integrations/agent/engine-resolution.js +209 -0
- package/dist/integrations/agent/index.js +1 -2
- package/dist/integrations/agent/model-aliases.js +7 -2
- package/dist/integrations/agent/profiles.js +6 -99
- package/dist/integrations/agent/runner-dispatch.js +76 -13
- package/dist/integrations/agent/runner.js +76 -207
- package/dist/integrations/agent/spawn.js +4 -6
- package/dist/integrations/harnesses/aider/agent-builder.js +2 -3
- package/dist/integrations/harnesses/aider/index.js +0 -1
- package/dist/integrations/harnesses/amazonq/agent-builder.js +2 -3
- package/dist/integrations/harnesses/amazonq/index.js +0 -1
- package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
- package/dist/integrations/harnesses/claude/index.js +0 -2
- package/dist/integrations/harnesses/codex/agent-builder.js +2 -3
- package/dist/integrations/harnesses/codex/index.js +0 -1
- package/dist/integrations/harnesses/copilot/agent-builder.js +2 -3
- package/dist/integrations/harnesses/copilot/index.js +0 -1
- package/dist/integrations/harnesses/gemini/agent-builder.js +2 -3
- package/dist/integrations/harnesses/gemini/index.js +0 -1
- package/dist/integrations/harnesses/index.js +1 -24
- package/dist/integrations/harnesses/opencode/agent-builder.js +2 -3
- package/dist/integrations/harnesses/opencode/index.js +0 -6
- package/dist/integrations/harnesses/opencode-sdk/harness.js +1 -6
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
- package/dist/integrations/harnesses/openhands/agent-builder.js +2 -3
- package/dist/integrations/harnesses/openhands/index.js +0 -1
- package/dist/integrations/harnesses/pi/agent-builder.js +2 -3
- package/dist/integrations/harnesses/pi/index.js +0 -1
- package/dist/integrations/harnesses/types.js +1 -32
- package/dist/integrations/lockfile.js +32 -21
- package/dist/llm/client.js +48 -14
- package/dist/llm/feature-gate.js +15 -47
- package/dist/llm/graph-extract.js +1 -1
- package/dist/llm/index-passes.js +8 -42
- package/dist/llm/memory-infer-impl.js +1 -1
- package/dist/llm/usage-persist.js +4 -0
- package/dist/llm/usage-telemetry.js +35 -5
- package/dist/output/shapes/helpers.js +2 -1
- package/dist/output/shapes/passthrough.js +2 -0
- package/dist/output/text/helpers.js +3 -1
- package/dist/schemas/akm-config.json +11013 -8600
- package/dist/schemas/akm-task.json +87 -0
- package/dist/schemas/akm-workflow.json +57 -13
- package/dist/scripts/migrate-storage.js +8502 -543
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +8493 -515
- package/dist/setup/detected-engines.js +136 -0
- package/dist/setup/engine-config.js +99 -0
- package/dist/setup/setup.js +237 -133
- package/dist/setup/steps/connection.js +62 -33
- package/dist/setup/steps/platforms.js +4 -4
- package/dist/setup/steps/tasks.js +1 -1
- package/dist/setup/steps.js +3 -2
- package/dist/sources/providers/git-stash.js +58 -21
- package/dist/sources/providers/git.js +1 -1
- package/dist/storage/database.js +13 -1
- package/dist/storage/engines/sqlite-migrations.js +139 -3
- package/dist/storage/repositories/events-repository.js +24 -0
- package/dist/storage/repositories/improve-runs-repository.js +5 -5
- package/dist/storage/repositories/proposals-repository.js +14 -0
- package/dist/storage/repositories/task-history-repository.js +78 -0
- package/dist/storage/repositories/workflow-runs-repository.js +9 -8
- package/dist/tasks/embedded.js +2 -0
- package/dist/tasks/parser.js +138 -52
- package/dist/tasks/runner.js +71 -75
- package/dist/tasks/schema.js +1 -1
- package/dist/tasks/validator.js +11 -6
- package/dist/wiki/wiki.js +9 -8
- package/dist/workflows/authoring/workflow-program-template.yaml +3 -3
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/db.js +78 -15
- package/dist/workflows/exec/brief.js +18 -24
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +124 -65
- package/dist/workflows/exec/report.js +93 -33
- package/dist/workflows/exec/run-workflow.js +38 -25
- package/dist/workflows/exec/scheduler.js +12 -41
- package/dist/workflows/exec/step-work.js +91 -35
- package/dist/workflows/ir/compile.js +13 -26
- package/dist/workflows/ir/freeze.js +243 -0
- package/dist/workflows/ir/plan-hash.js +40 -5
- package/dist/workflows/ir/schema.js +542 -1
- package/dist/workflows/parser.js +7 -0
- package/dist/workflows/program/parser.js +132 -23
- package/dist/workflows/program/project.js +3 -4
- package/dist/workflows/program/schema.js +2 -2
- package/dist/workflows/resource-limits.js +20 -0
- package/dist/workflows/runtime/plan-classifier.js +187 -0
- package/dist/workflows/runtime/runs.js +54 -47
- package/dist/workflows/runtime/workflow-asset-loader.js +0 -22
- package/dist/workflows/validator.js +49 -2
- package/docs/data-and-telemetry.md +2 -2
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +5 -4
- package/docs/migration/release-notes/0.9.0.md +24 -7
- package/docs/migration/v0.8-to-v0.9.md +506 -0
- package/package.json +4 -2
- package/schemas/akm-config.json +16638 -0
- package/schemas/akm-task.json +87 -0
- package/schemas/akm-workflow.json +372 -0
- package/dist/commands/improve/improve-profiles.js +0 -168
- package/dist/core/config/config-migration.js +0 -602
- package/dist/core/deep-merge.js +0 -38
- package/dist/llm/call-ai.js +0 -62
- package/dist/setup/legacy-config.js +0 -106
- package/docs/README.md +0 -104
- /package/dist/assets/{profiles → improve-strategies}/thorough.json +0 -0
|
@@ -2,111 +2,227 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import { spawnSync } from "node:child_process";
|
|
5
|
+
import { createRequire } from "node:module";
|
|
5
6
|
import { loadConfig } from "../../core/config/config.js";
|
|
6
|
-
import {
|
|
7
|
+
import { resolveEngine } from "../../integrations/agent/engine-resolution.js";
|
|
8
|
+
import { resolveModel } from "../../integrations/agent/model-aliases.js";
|
|
9
|
+
import { resolveImprovePlan } from "../improve/improve-strategies.js";
|
|
7
10
|
import { TASK_FAIL_RATE_WARN, } from "./types.js";
|
|
8
11
|
const ACTIVE_RUN_WARN_MS = 15 * 60 * 1000;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export function runAgentProbe() {
|
|
15
|
-
const config = loadConfig();
|
|
16
|
-
// v2: check profiles.agent first
|
|
17
|
-
if (config.profiles?.agent) {
|
|
18
|
-
const defaultName = config.defaults?.agent;
|
|
19
|
-
const profileCount = Object.keys(config.profiles.agent).length;
|
|
20
|
-
if (profileCount === 0) {
|
|
21
|
-
return {
|
|
22
|
-
name: "agent-profile",
|
|
23
|
-
kind: "deterministic",
|
|
24
|
-
status: "unknown",
|
|
25
|
-
confidence: "high",
|
|
26
|
-
message: "No agent profiles configured in profiles.agent.",
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
const profileName = defaultName ?? Object.keys(config.profiles.agent)[0];
|
|
30
|
-
const profile = config.profiles.agent[profileName];
|
|
12
|
+
function credentialAvailable(credential, env) {
|
|
13
|
+
return !credential?.required || credential.names.some((name) => Boolean(env[name]?.trim()));
|
|
14
|
+
}
|
|
15
|
+
function runConfiguredEngineProbe(checkName, engineName, config, deps) {
|
|
16
|
+
if (!engineName) {
|
|
31
17
|
return {
|
|
32
|
-
name:
|
|
18
|
+
name: checkName,
|
|
33
19
|
kind: "deterministic",
|
|
34
|
-
status: "
|
|
20
|
+
status: "unknown",
|
|
35
21
|
confidence: "high",
|
|
36
|
-
message:
|
|
37
|
-
|
|
22
|
+
message: checkName === "default-llm-engine"
|
|
23
|
+
? "No default LLM engine is configured."
|
|
24
|
+
: "No default engine is configured.",
|
|
38
25
|
};
|
|
39
26
|
}
|
|
40
|
-
|
|
27
|
+
const env = deps.env ?? process.env;
|
|
28
|
+
const configuredEngine = config.engines?.[engineName];
|
|
29
|
+
if (configuredEngine?.kind === "agent" && configuredEngine.platform === "opencode-sdk") {
|
|
30
|
+
let packageAvailable = false;
|
|
31
|
+
try {
|
|
32
|
+
const resolvePackage = deps.resolvePackage ?? ((name) => createRequire(import.meta.url).resolve(name));
|
|
33
|
+
resolvePackage("@opencode-ai/sdk");
|
|
34
|
+
packageAvailable = true;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
packageAvailable = false;
|
|
38
|
+
}
|
|
39
|
+
const binary = configuredEngine.bin ?? "opencode";
|
|
40
|
+
const version = (deps.spawnSync ?? spawnSync)(binary, ["--version"], { encoding: "utf8", timeout: 5_000 });
|
|
41
|
+
const binaryAvailable = (version.status ?? 1) === 0;
|
|
42
|
+
const fallbackEngine = configuredEngine.llmEngine ?? config.defaults?.llmEngine;
|
|
43
|
+
let fallback;
|
|
44
|
+
let fallbackCredential;
|
|
45
|
+
let sdkRunner;
|
|
46
|
+
const resolve = deps.resolveEngine ?? resolveEngine;
|
|
47
|
+
try {
|
|
48
|
+
const resolved = resolve(engineName, config);
|
|
49
|
+
if (resolved.kind === "sdk")
|
|
50
|
+
sdkRunner = resolved;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
sdkRunner = undefined;
|
|
54
|
+
}
|
|
55
|
+
if (sdkRunner?.fallbackConnection) {
|
|
56
|
+
fallback = { kind: "llm", connection: sdkRunner.fallbackConnection };
|
|
57
|
+
fallbackCredential = sdkRunner.fallbackCredential;
|
|
58
|
+
}
|
|
59
|
+
else if (fallbackEngine) {
|
|
60
|
+
try {
|
|
61
|
+
const resolved = resolve(fallbackEngine, config);
|
|
62
|
+
if (resolved.kind === "llm") {
|
|
63
|
+
fallback = resolved;
|
|
64
|
+
fallbackCredential = resolved.credential;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
fallback = undefined;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const configuredModel = configuredEngine.model
|
|
72
|
+
? resolveModel(configuredEngine.model, "opencode-sdk", configuredEngine.modelAliases, config.modelAliases)
|
|
73
|
+
: undefined;
|
|
74
|
+
const effectiveModel = sdkRunner?.profile.model ?? configuredModel ?? fallback?.connection.model;
|
|
75
|
+
const fallbackCredentialAvailable = credentialAvailable(fallbackCredential, env);
|
|
76
|
+
const missing = [
|
|
77
|
+
!packageAvailable ? "@opencode-ai/sdk package" : undefined,
|
|
78
|
+
!binaryAvailable ? `${binary} binary` : undefined,
|
|
79
|
+
fallbackEngine && !fallback ? "configured fallback LLM connection" : undefined,
|
|
80
|
+
!fallbackCredentialAvailable ? "required fallback credential" : undefined,
|
|
81
|
+
].filter((value) => value !== undefined);
|
|
41
82
|
return {
|
|
42
|
-
name:
|
|
83
|
+
name: checkName,
|
|
43
84
|
kind: "deterministic",
|
|
44
|
-
status: "
|
|
85
|
+
status: missing.length === 0 ? "pass" : "warn",
|
|
45
86
|
confidence: "high",
|
|
46
|
-
message:
|
|
87
|
+
message: missing.length === 0
|
|
88
|
+
? `SDK engine "${engineName}" is available.`
|
|
89
|
+
: `SDK engine "${engineName}" is incomplete: missing ${missing.join(", ")}.`,
|
|
90
|
+
evidence: {
|
|
91
|
+
engine: engineName,
|
|
92
|
+
platform: configuredEngine.platform,
|
|
93
|
+
runtimeKind: "sdk",
|
|
94
|
+
binary,
|
|
95
|
+
binaryAvailable,
|
|
96
|
+
package: "@opencode-ai/sdk",
|
|
97
|
+
packageAvailable,
|
|
98
|
+
model: effectiveModel ?? null,
|
|
99
|
+
configuredModel: configuredModel ?? null,
|
|
100
|
+
modelSource: configuredModel ? "sdk" : effectiveModel ? "fallback" : null,
|
|
101
|
+
fallbackEngine: fallbackEngine ?? null,
|
|
102
|
+
fallbackEndpoint: fallback?.connection.endpoint ?? null,
|
|
103
|
+
fallbackModel: fallback?.connection.model ?? null,
|
|
104
|
+
requiredCredentialAvailable: fallbackCredentialAvailable,
|
|
105
|
+
},
|
|
47
106
|
};
|
|
48
107
|
}
|
|
49
|
-
let profile;
|
|
50
108
|
try {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
109
|
+
const runner = (deps.resolveEngine ?? resolveEngine)(engineName, config);
|
|
110
|
+
if (runner.kind === "llm") {
|
|
111
|
+
const requiredCredentialAvailable = credentialAvailable(runner.credential, env);
|
|
112
|
+
return {
|
|
113
|
+
name: checkName,
|
|
114
|
+
kind: "deterministic",
|
|
115
|
+
status: requiredCredentialAvailable ? "pass" : "warn",
|
|
116
|
+
confidence: "high",
|
|
117
|
+
message: requiredCredentialAvailable
|
|
118
|
+
? `LLM engine "${engineName}" is configured.`
|
|
119
|
+
: `LLM engine "${engineName}" is configured, but its required credential is unavailable.`,
|
|
120
|
+
evidence: {
|
|
121
|
+
engine: engineName,
|
|
122
|
+
platform: null,
|
|
123
|
+
runtimeKind: "llm",
|
|
124
|
+
model: runner.connection.model,
|
|
125
|
+
endpoint: runner.connection.endpoint,
|
|
126
|
+
requiredCredentialAvailable,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const profile = runner.profile;
|
|
131
|
+
if (runner.kind === "sdk")
|
|
132
|
+
throw new Error(`SDK engine "${engineName}" has no matching SDK config.`);
|
|
133
|
+
const version = (deps.spawnSync ?? spawnSync)(profile.bin, ["--version"], { encoding: "utf8", timeout: 5_000 });
|
|
134
|
+
if ((version.status ?? 1) !== 0) {
|
|
135
|
+
return {
|
|
136
|
+
name: checkName,
|
|
137
|
+
kind: "deterministic",
|
|
138
|
+
status: "warn",
|
|
139
|
+
confidence: "medium",
|
|
140
|
+
message: `Agent engine "${engineName}" was found but \`--version\` failed.`,
|
|
141
|
+
evidence: {
|
|
142
|
+
engine: engineName,
|
|
143
|
+
platform: profile.platform ?? null,
|
|
144
|
+
runtimeKind: "agent",
|
|
145
|
+
model: profile.model ?? null,
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
54
149
|
return {
|
|
55
|
-
name:
|
|
150
|
+
name: checkName,
|
|
56
151
|
kind: "deterministic",
|
|
57
|
-
status: "
|
|
152
|
+
status: "pass",
|
|
58
153
|
confidence: "high",
|
|
59
|
-
message:
|
|
154
|
+
message: `Agent engine "${engineName}" is available.`,
|
|
155
|
+
evidence: {
|
|
156
|
+
engine: engineName,
|
|
157
|
+
platform: profile.platform ?? null,
|
|
158
|
+
runtimeKind: "agent",
|
|
159
|
+
model: profile.model ?? null,
|
|
160
|
+
},
|
|
60
161
|
};
|
|
61
162
|
}
|
|
62
|
-
|
|
163
|
+
catch (error) {
|
|
63
164
|
return {
|
|
64
|
-
name:
|
|
165
|
+
name: checkName,
|
|
65
166
|
kind: "deterministic",
|
|
66
|
-
status:
|
|
167
|
+
status: "warn",
|
|
67
168
|
confidence: "high",
|
|
68
|
-
message:
|
|
69
|
-
? `SDK mode profile "${profile.name}" is configured.`
|
|
70
|
-
: `SDK mode profile "${profile.name}" has no explicit model.`,
|
|
71
|
-
evidence: { profile: profile.name, sdkMode: true, model: profile.model ?? null },
|
|
169
|
+
message: error instanceof Error ? error.message : String(error),
|
|
72
170
|
};
|
|
73
171
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
172
|
+
}
|
|
173
|
+
export function runDefaultEngineProbe(deps = {}) {
|
|
174
|
+
const config = deps.loadConfig?.() ?? loadConfig();
|
|
175
|
+
return runConfiguredEngineProbe("default-engine", config.defaults?.engine, config, deps);
|
|
176
|
+
}
|
|
177
|
+
export function runDefaultLlmEngineProbe(deps = {}) {
|
|
178
|
+
const config = deps.loadConfig?.() ?? loadConfig();
|
|
179
|
+
return runConfiguredEngineProbe("default-llm-engine", config.defaults?.llmEngine, config, deps);
|
|
180
|
+
}
|
|
181
|
+
export function runActiveImproveStrategyProbe(deps = {}) {
|
|
182
|
+
const config = deps.loadConfig?.() ?? loadConfig();
|
|
183
|
+
const strategyName = config.defaults?.improveStrategy ?? "default";
|
|
184
|
+
try {
|
|
185
|
+
const plan = resolveImprovePlan(strategyName, config);
|
|
186
|
+
const env = deps.env ?? process.env;
|
|
187
|
+
const unavailableProcesses = Object.entries(plan.processes).flatMap(([name, process]) => {
|
|
188
|
+
if (!process.enabled || !process.runner)
|
|
189
|
+
return [];
|
|
190
|
+
return credentialAvailable(process.runner.credential, env) ? [] : [name];
|
|
191
|
+
});
|
|
192
|
+
if (plan.triageJudgment) {
|
|
193
|
+
const judgmentCredential = plan.triageJudgment.kind === "llm"
|
|
194
|
+
? plan.triageJudgment.credential
|
|
195
|
+
: plan.triageJudgment.kind === "sdk"
|
|
196
|
+
? plan.triageJudgment.fallbackCredential
|
|
197
|
+
: undefined;
|
|
198
|
+
if (!credentialAvailable(judgmentCredential, env))
|
|
199
|
+
unavailableProcesses.push("triage.judgment");
|
|
200
|
+
}
|
|
77
201
|
return {
|
|
78
|
-
name: "
|
|
202
|
+
name: "active-improve-strategy",
|
|
79
203
|
kind: "deterministic",
|
|
80
|
-
status: "
|
|
204
|
+
status: unavailableProcesses.length === 0 ? "pass" : "warn",
|
|
81
205
|
confidence: "high",
|
|
82
|
-
message:
|
|
83
|
-
|
|
206
|
+
message: unavailableProcesses.length === 0
|
|
207
|
+
? `Active improve strategy "${plan.strategy.name}" has available process engines.`
|
|
208
|
+
: `Active improve strategy "${plan.strategy.name}" has unavailable required credentials for: ${unavailableProcesses.join(", ")}.`,
|
|
209
|
+
evidence: {
|
|
210
|
+
strategy: plan.strategy.name,
|
|
211
|
+
unavailableProcesses,
|
|
212
|
+
},
|
|
84
213
|
};
|
|
85
214
|
}
|
|
86
|
-
|
|
87
|
-
|
|
215
|
+
catch (error) {
|
|
216
|
+
const explicitlyConfigured = config.defaults?.improveStrategy !== undefined || Object.keys(config.improve?.strategies ?? {}).length > 0;
|
|
88
217
|
return {
|
|
89
|
-
name: "
|
|
218
|
+
name: "active-improve-strategy",
|
|
90
219
|
kind: "deterministic",
|
|
91
|
-
status: "warn",
|
|
92
|
-
confidence: "
|
|
93
|
-
message: `
|
|
94
|
-
evidence: {
|
|
95
|
-
profile: profile.name,
|
|
96
|
-
bin: profile.bin,
|
|
97
|
-
exitCode: version.status ?? null,
|
|
98
|
-
stderr: (version.stderr ?? "").trim(),
|
|
99
|
-
},
|
|
220
|
+
status: explicitlyConfigured ? "warn" : "unknown",
|
|
221
|
+
confidence: "high",
|
|
222
|
+
message: `Active improve strategy "${strategyName}" is unavailable: ${error instanceof Error ? error.message : String(error)}`,
|
|
223
|
+
evidence: { strategy: strategyName, unavailableProcesses: [] },
|
|
100
224
|
};
|
|
101
225
|
}
|
|
102
|
-
return {
|
|
103
|
-
name: "agent-profile",
|
|
104
|
-
kind: "deterministic",
|
|
105
|
-
status: "pass",
|
|
106
|
-
confidence: "high",
|
|
107
|
-
message: `Agent profile "${profile.name}" is available.`,
|
|
108
|
-
evidence: { profile: profile.name, bin: profile.bin, version: (version.stdout ?? "").trim() },
|
|
109
|
-
};
|
|
110
226
|
}
|
|
111
227
|
/**
|
|
112
228
|
* The ordered health-check registry. ORDER IS LOAD-BEARING: `akmHealth`
|
|
@@ -185,9 +301,19 @@ export const HEALTH_CHECKS = [
|
|
|
185
301
|
}),
|
|
186
302
|
},
|
|
187
303
|
{
|
|
188
|
-
name: "
|
|
304
|
+
name: "default-engine",
|
|
305
|
+
channel: "hard",
|
|
306
|
+
run: () => runDefaultEngineProbe(),
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
name: "default-llm-engine",
|
|
310
|
+
channel: "hard",
|
|
311
|
+
run: () => runDefaultLlmEngineProbe(),
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
name: "active-improve-strategy",
|
|
189
315
|
channel: "hard",
|
|
190
|
-
run: () =>
|
|
316
|
+
run: () => runActiveImproveStrategyProbe(),
|
|
191
317
|
},
|
|
192
318
|
{
|
|
193
319
|
// C2 (13-bus-factor): the cron task-failure rate was computed and rendered
|
|
@@ -93,6 +93,8 @@ function reshapeRun(r) {
|
|
|
93
93
|
return {
|
|
94
94
|
id: r.id,
|
|
95
95
|
taskId: r.taskId ?? "manual",
|
|
96
|
+
strategy: r.strategy,
|
|
97
|
+
legacyProfile: r.legacyProfile,
|
|
96
98
|
startedAt: r.startedAt,
|
|
97
99
|
completedAt: r.completedAt,
|
|
98
100
|
wallTimeMs: wall,
|
|
@@ -295,6 +297,8 @@ export function buildHealthHtmlReplacements(result, opts) {
|
|
|
295
297
|
totalTokens: 0,
|
|
296
298
|
reasoningTokens: 0,
|
|
297
299
|
byStage: {},
|
|
300
|
+
byProcess: {},
|
|
301
|
+
byEngine: {},
|
|
298
302
|
};
|
|
299
303
|
const totalRuns = runs.length;
|
|
300
304
|
const failedRuns = runs.filter((r) => !r.ok).length;
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
import { decodeImproveResult } from "../../core/improve-result.js";
|
|
4
5
|
import { queryImproveRuns } from "../../storage/repositories/improve-runs-repository.js";
|
|
6
|
+
import { decodeTaskHistoryMetadata } from "../../storage/repositories/task-history-repository.js";
|
|
5
7
|
import { summarizeCalibration } from "../improve/calibration.js";
|
|
6
8
|
export function roundRate(value) {
|
|
7
9
|
return Number(value.toFixed(4));
|
|
8
10
|
}
|
|
9
11
|
export function parseTaskMetadata(row) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const metadata = decodeTaskHistoryMetadata(row.metadata_json);
|
|
13
|
+
return {
|
|
14
|
+
...(metadata.durationMs !== undefined ? { durationMs: metadata.durationMs } : {}),
|
|
15
|
+
...(metadata.detail ? { detail: metadata.detail } : {}),
|
|
16
|
+
...(metadata.metadataVersion === 2 && metadata.engine !== undefined ? { engine: metadata.engine } : {}),
|
|
17
|
+
...(metadata.metadataVersion === 1 && metadata.legacyProfile !== undefined
|
|
18
|
+
? { legacyProfile: metadata.legacyProfile }
|
|
19
|
+
: {}),
|
|
20
|
+
};
|
|
16
21
|
}
|
|
17
22
|
function createUnknownImproveMetrics() {
|
|
18
23
|
return {
|
|
@@ -21,7 +26,7 @@ function createUnknownImproveMetrics() {
|
|
|
21
26
|
skipped: 0,
|
|
22
27
|
skipReasons: {},
|
|
23
28
|
plannedRefs: 0,
|
|
24
|
-
|
|
29
|
+
strategyFilteredRefs: 0,
|
|
25
30
|
actions: {
|
|
26
31
|
reflect: { ok: 0, failed: 0, cooldown: 0, skipped: 0, guardRejected: 0, skippedByReason: {} },
|
|
27
32
|
distill: {
|
|
@@ -181,12 +186,14 @@ function projectRunMetrics(result) {
|
|
|
181
186
|
const plannedRefs = result.plannedRefs;
|
|
182
187
|
if (Array.isArray(plannedRefs))
|
|
183
188
|
metrics.plannedRefs += plannedRefs.length;
|
|
184
|
-
//
|
|
189
|
+
// strategyFilteredRefs (array of {ref, reason}) — 2026-05-27: pre-filter
|
|
185
190
|
// bucket from `collectEligibleRefs` so the metric reflects work the
|
|
186
191
|
// planner dropped before signal-delta / per-pass dispatch.
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
192
|
+
// Health v3 reports strategy metrics only. Historical v1 profile filtering
|
|
193
|
+
// remains legacy data and must not be silently relabelled as a strategy metric.
|
|
194
|
+
const strategyFilteredRefs = result.schemaVersion === 2 ? result.strategyFilteredRefs : undefined;
|
|
195
|
+
if (Array.isArray(strategyFilteredRefs))
|
|
196
|
+
metrics.strategyFilteredRefs += strategyFilteredRefs.length;
|
|
190
197
|
// actions: split reflect / distill by outcome, count others.
|
|
191
198
|
const actions = result.actions;
|
|
192
199
|
if (Array.isArray(actions)) {
|
|
@@ -496,8 +503,8 @@ function finalizeImproveMetrics(metrics) {
|
|
|
496
503
|
*/
|
|
497
504
|
function mergeImproveMetrics(dst, src) {
|
|
498
505
|
dst.plannedRefs += src.plannedRefs;
|
|
499
|
-
//
|
|
500
|
-
// active
|
|
506
|
+
// strategyFilteredRefs is the count of refs the planner drops up-front for the
|
|
507
|
+
// active strategy — recomputed against the (stable) stash every run, so it is a
|
|
501
508
|
// snapshot, NOT a per-run increment. Summing it re-counts the same refs each
|
|
502
509
|
// run (the ~2.4M bug). Set from the most recent run in summarizeImproveRuns.
|
|
503
510
|
dst.actions.reflect.ok += src.actions.reflect.ok;
|
|
@@ -613,22 +620,16 @@ export function summarizeImproveRuns(db, since, until) {
|
|
|
613
620
|
// MOST RECENT run's snapshot (current state) — not a sum across runs.
|
|
614
621
|
let latestStartMs = Number.NEGATIVE_INFINITY;
|
|
615
622
|
let latestMemorySummary;
|
|
616
|
-
let
|
|
623
|
+
let latestStrategyFilteredRefs = 0;
|
|
617
624
|
for (const row of rows) {
|
|
618
|
-
|
|
619
|
-
try {
|
|
620
|
-
result = JSON.parse(row.result_json);
|
|
621
|
-
}
|
|
622
|
-
catch {
|
|
623
|
-
continue;
|
|
624
|
-
}
|
|
625
|
+
const result = decodeImproveResult(row.result_json).envelope;
|
|
625
626
|
const perRow = projectRunMetrics(result);
|
|
626
627
|
mergeImproveMetrics(accum, perRow);
|
|
627
628
|
const startMs = new Date(row.started_at).getTime();
|
|
628
629
|
if (Number.isFinite(startMs) && startMs >= latestStartMs) {
|
|
629
630
|
latestStartMs = startMs;
|
|
630
631
|
latestMemorySummary = perRow.memorySummary;
|
|
631
|
-
|
|
632
|
+
latestStrategyFilteredRefs = perRow.strategyFilteredRefs;
|
|
632
633
|
}
|
|
633
634
|
// Collect per-phase durations directly off the envelope. consolidation's
|
|
634
635
|
// duration lives inside the sub-object; memoryInference and graphExtraction
|
|
@@ -648,7 +649,7 @@ export function summarizeImproveRuns(db, since, until) {
|
|
|
648
649
|
finalizeImproveMetrics(accum);
|
|
649
650
|
if (latestMemorySummary)
|
|
650
651
|
accum.memorySummary = latestMemorySummary;
|
|
651
|
-
accum.
|
|
652
|
+
accum.strategyFilteredRefs = latestStrategyFilteredRefs;
|
|
652
653
|
accum.wallTime.byPhase = {
|
|
653
654
|
consolidation: summarizePhaseDurations(phaseDurations.consolidation),
|
|
654
655
|
memoryInference: summarizePhaseDurations(phaseDurations.memoryInference),
|
|
@@ -680,13 +681,8 @@ export function summarizePhaseDurations(samples) {
|
|
|
680
681
|
* Used by `akm health --detail per-run`.
|
|
681
682
|
*/
|
|
682
683
|
export function projectImproveRunSummary(row, wallTimeMs, taskId) {
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
result = JSON.parse(row.result_json);
|
|
686
|
-
}
|
|
687
|
-
catch {
|
|
688
|
-
// fall through with empty result so per-stage rollups are zeros
|
|
689
|
-
}
|
|
684
|
+
const decoded = decodeImproveResult(row.result_json);
|
|
685
|
+
const result = decoded.envelope;
|
|
690
686
|
const perRow = projectRunMetrics(result);
|
|
691
687
|
finalizeImproveMetrics(perRow);
|
|
692
688
|
const orphansPurged = toFiniteNumber(result.orphansPurged);
|
|
@@ -699,6 +695,8 @@ export function projectImproveRunSummary(row, wallTimeMs, taskId) {
|
|
|
699
695
|
completedAt: row.completed_at,
|
|
700
696
|
wallTimeMs,
|
|
701
697
|
ok: row.ok === 1,
|
|
698
|
+
strategy: row.strategy,
|
|
699
|
+
legacyProfile: row.legacyProfile,
|
|
702
700
|
scope: {
|
|
703
701
|
mode: row.scope_mode,
|
|
704
702
|
...(row.scope_value ? { value: row.scope_value } : {}),
|
|
@@ -744,10 +742,10 @@ export function buildImproveSkipSummary(events) {
|
|
|
744
742
|
// - Per-occurrence (no `count`): one event per skipped ref → SUM is correct.
|
|
745
743
|
// - Aggregated snapshot (carries `count`): a single per-run event whose count
|
|
746
744
|
// is the number of refs that hit a STABLE, whole-stash condition that run
|
|
747
|
-
// (`no_new_signal`, `
|
|
745
|
+
// (`no_new_signal`, `strategy_filtered_all_passes`). Each run re-counts the
|
|
748
746
|
// same stable set, so summing across the window re-counts it N times (the
|
|
749
747
|
// 2.7M / 3M inflation). For these we keep the MOST RECENT run's count — the
|
|
750
|
-
// current snapshot — matching how memorySummary/
|
|
748
|
+
// current snapshot — matching how memorySummary/strategyFilteredRefs are
|
|
751
749
|
// handled. Events arrive in chronological (offset) order, so the last
|
|
752
750
|
// count-bearing event per reason is the latest run's value.
|
|
753
751
|
const summed = {};
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { readEvents } from "../../core/events.js";
|
|
9
9
|
import { LLM_USAGE_EVENT } from "../../llm/usage-persist.js";
|
|
10
|
-
import {
|
|
10
|
+
import { decodeLlmUsageRecord } from "../../llm/usage-telemetry.js";
|
|
11
11
|
/** Stage key used for `llm_usage` events recorded outside any stage scope. */
|
|
12
12
|
const UNATTRIBUTED_STAGE = "unattributed";
|
|
13
13
|
function emptyLlmUsageStageAggregate() {
|
|
@@ -21,7 +21,7 @@ function emptyLlmUsageStageAggregate() {
|
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
function emptyLlmUsageAggregate() {
|
|
24
|
-
return { ...emptyLlmUsageStageAggregate(), byStage: {} };
|
|
24
|
+
return { ...emptyLlmUsageStageAggregate(), byStage: {}, byProcess: {}, byEngine: {} };
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* Aggregate `llm_usage` events (#576) into a window total plus a per-stage
|
|
@@ -32,25 +32,25 @@ function emptyLlmUsageAggregate() {
|
|
|
32
32
|
export function summarizeLlmUsage(events) {
|
|
33
33
|
const aggregate = emptyLlmUsageAggregate();
|
|
34
34
|
for (const event of events) {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
aggregate.byStage
|
|
35
|
+
const record = decodeLlmUsageRecord(event.metadata);
|
|
36
|
+
if (!record)
|
|
37
|
+
continue;
|
|
38
|
+
const dimensions = [];
|
|
39
|
+
for (const [groups, key] of [
|
|
40
|
+
[aggregate.byStage, record.stage ?? UNATTRIBUTED_STAGE],
|
|
41
|
+
[aggregate.byProcess, record.process ?? UNATTRIBUTED_STAGE],
|
|
42
|
+
[aggregate.byEngine, record.engine ?? UNATTRIBUTED_STAGE],
|
|
43
|
+
]) {
|
|
44
|
+
groups[key] ??= emptyLlmUsageStageAggregate();
|
|
45
|
+
dimensions.push(groups[key]);
|
|
41
46
|
}
|
|
42
|
-
const
|
|
43
|
-
const promptTokens = toFiniteNumber(meta.promptTokens);
|
|
44
|
-
const completionTokens = toFiniteNumber(meta.completionTokens);
|
|
45
|
-
const totalTokens = toFiniteNumber(meta.totalTokens);
|
|
46
|
-
const reasoningTokens = toFiniteNumber(meta.reasoningTokens);
|
|
47
|
-
for (const target of [aggregate, stage]) {
|
|
47
|
+
for (const target of [aggregate, ...dimensions]) {
|
|
48
48
|
target.calls += 1;
|
|
49
|
-
target.totalDurationMs += durationMs;
|
|
50
|
-
target.promptTokens += promptTokens;
|
|
51
|
-
target.completionTokens += completionTokens;
|
|
52
|
-
target.totalTokens += totalTokens;
|
|
53
|
-
target.reasoningTokens += reasoningTokens;
|
|
49
|
+
target.totalDurationMs += record.durationMs;
|
|
50
|
+
target.promptTokens += record.promptTokens ?? 0;
|
|
51
|
+
target.completionTokens += record.completionTokens ?? 0;
|
|
52
|
+
target.totalTokens += record.totalTokens ?? 0;
|
|
53
|
+
target.reasoningTokens += record.reasoningTokens ?? 0;
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
return aggregate;
|
|
@@ -28,6 +28,8 @@ export function renderRunsDetailMd(runs) {
|
|
|
28
28
|
const headers = [
|
|
29
29
|
"ts",
|
|
30
30
|
"ok",
|
|
31
|
+
"strategy",
|
|
32
|
+
"legacy_profile",
|
|
31
33
|
"actions",
|
|
32
34
|
"refl_ok/fail/cd/skip",
|
|
33
35
|
"distill_q/llm-fail/qrej/cfg/skip",
|
|
@@ -54,6 +56,8 @@ export function renderRunsDetailMd(runs) {
|
|
|
54
56
|
return [
|
|
55
57
|
r.startedAt,
|
|
56
58
|
String(r.ok),
|
|
59
|
+
r.strategy ?? "",
|
|
60
|
+
r.legacyProfile ?? "",
|
|
57
61
|
String(totalActions),
|
|
58
62
|
`${r.actions.reflect.ok}/${r.actions.reflect.failed}/${r.actions.reflect.cooldown}/${r.actions.reflect.skipped}`,
|
|
59
63
|
`${r.actions.distill.queued}/${r.actions.distill.llmFailed}/${r.actions.distill.qualityRejected}/${r.actions.distill.configDisabled}/${r.actions.distill.skipped}`,
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* minting rollup, and the WS-5 per-run degradation metrics.
|
|
8
8
|
*/
|
|
9
9
|
import { appendEvent, readEvents } from "../../core/events.js";
|
|
10
|
+
import { decodeImproveResult } from "../../core/improve-result.js";
|
|
10
11
|
import { queryImproveRuns } from "../../storage/repositories/improve-runs-repository.js";
|
|
11
12
|
import { listProposalGateDecisions, listStateProposals } from "../../storage/repositories/proposals-repository.js";
|
|
12
13
|
import { gateDecisionsToSamples, summarizeCalibration } from "../improve/calibration.js";
|
|
@@ -221,7 +222,7 @@ export function computeDegradationMetrics(db, since, until) {
|
|
|
221
222
|
let totalProcessed = 0;
|
|
222
223
|
for (const row of runs) {
|
|
223
224
|
try {
|
|
224
|
-
const result =
|
|
225
|
+
const result = decodeImproveResult(row.result_json).envelope;
|
|
225
226
|
const cons = result.consolidation;
|
|
226
227
|
if (cons) {
|
|
227
228
|
totalContradicted += toFiniteNumber(cons.contradicted);
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import fs from "node:fs";
|
|
20
20
|
import path from "node:path";
|
|
21
|
-
import {
|
|
21
|
+
import { MAX_CONFIG_FILE_BYTES, readTextFileWithLimit } from "../../core/common.js";
|
|
22
|
+
import { CURRENT_CONFIG_VERSION } from "../../core/config/config-schema.js";
|
|
23
|
+
import { compareConfigVersion } from "../../core/config/config-version.js";
|
|
22
24
|
const GROUP_OTHER_BITS = 0o077;
|
|
23
25
|
const OFFENDER_EVIDENCE_CAP = 50;
|
|
24
26
|
function modeOctal(mode) {
|
|
@@ -97,7 +99,7 @@ export function collectSecretPermsAdvisory(input, platform = process.platform) {
|
|
|
97
99
|
export function collectConfigSkewAdvisory(configPath) {
|
|
98
100
|
let raw;
|
|
99
101
|
try {
|
|
100
|
-
raw = JSON.parse(
|
|
102
|
+
raw = JSON.parse(readTextFileWithLimit(configPath, MAX_CONFIG_FILE_BYTES, "Config file"));
|
|
101
103
|
}
|
|
102
104
|
catch {
|
|
103
105
|
return undefined;
|
|
@@ -182,10 +184,10 @@ export function collectEgressAdvisory(config) {
|
|
|
182
184
|
continue;
|
|
183
185
|
endpoints.push(`source ${source.name ?? "(unnamed)"} (${source.type ?? "?"}): ${source.url}`);
|
|
184
186
|
}
|
|
185
|
-
for (const [name,
|
|
186
|
-
if (!
|
|
187
|
+
for (const [name, engine] of Object.entries(config.engines ?? {})) {
|
|
188
|
+
if (engine?.kind !== "llm" || !engine.endpoint)
|
|
187
189
|
continue;
|
|
188
|
-
endpoints.push(`llm ${name}: ${
|
|
190
|
+
endpoints.push(`llm ${name}: ${engine.endpoint}`);
|
|
189
191
|
}
|
|
190
192
|
if (config.embedding?.endpoint)
|
|
191
193
|
endpoints.push(`embedding: ${config.embedding.endpoint}`);
|
package/dist/commands/health.js
CHANGED
|
@@ -72,8 +72,8 @@ function distinctTokens(text) {
|
|
|
72
72
|
}
|
|
73
73
|
/**
|
|
74
74
|
* A merge must strictly increase information (R5 §4.2):
|
|
75
|
-
* 1. Provenance: the merged asset's `
|
|
76
|
-
*
|
|
75
|
+
* 1. Provenance: the merged asset's `xrefs` must be a superset of the union of
|
|
76
|
+
* all participants' `xrefs` plus the participant refs
|
|
77
77
|
* themselves — provenance never shrinks through a merge.
|
|
78
78
|
* 2. Specificity: distinctTokens(mergedBody) ≥ minSpecificityRetention ×
|
|
79
79
|
* |union(distinctTokens(participant bodies))| — a merge that only
|
|
@@ -111,7 +111,7 @@ export function checkMergeInformationFloor(mergedBody, mergedSourceRefs, partici
|
|
|
111
111
|
const specificityOk = specificityRetention >= minRetention;
|
|
112
112
|
const reasons = [];
|
|
113
113
|
if (!provenanceOk) {
|
|
114
|
-
reasons.push(`provenance shrank: merged
|
|
114
|
+
reasons.push(`provenance shrank: merged xrefs missing ${missing.length} ref(s) (e.g. ${missing[0]})`);
|
|
115
115
|
}
|
|
116
116
|
if (!specificityOk) {
|
|
117
117
|
reasons.push(`specificity retention ${specificityRetention.toFixed(2)} < ${minRetention} (merge genericized/shortened)`);
|