akm-cli 0.9.0-beta.6 → 0.9.0-rc.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/CHANGELOG.md +663 -0
- package/README.md +12 -4
- package/dist/akm +38 -0
- package/dist/akm-migrate-storage +38 -0
- package/dist/assets/help/help-improve.md +9 -6
- package/dist/assets/hints/cli-hints-full.md +6 -5
- package/dist/assets/profiles/default.json +9 -4
- package/dist/assets/profiles/frequent.json +1 -1
- package/dist/assets/profiles/memory-focus.json +1 -1
- package/dist/assets/profiles/proactive-maintenance.json +25 -0
- package/dist/assets/profiles/quick.json +1 -1
- package/dist/assets/profiles/recombine-only.json +21 -0
- package/dist/assets/profiles/reflect-distill.json +30 -0
- package/dist/assets/profiles/synthesize.json +15 -0
- package/dist/assets/profiles/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +23 -0
- package/dist/assets/prompts/contradiction-judge.md +33 -0
- package/dist/assets/prompts/distill-knowledge-system.md +22 -0
- package/dist/assets/prompts/distill-lesson-system.md +36 -0
- package/dist/assets/prompts/extract-session.md +11 -3
- package/dist/assets/prompts/graph-extract-system.md +1 -0
- package/dist/assets/prompts/graph-extract-user-prompt.md +1 -1
- package/dist/assets/prompts/memory-infer-system.md +1 -0
- package/dist/assets/prompts/memory-infer-user.md +5 -0
- package/dist/assets/prompts/metadata-enhance-system.md +1 -0
- package/dist/assets/prompts/procedural-system.md +44 -0
- package/dist/assets/prompts/recombine-system.md +40 -0
- package/dist/assets/prompts/staleness-detect-system.md +6 -0
- package/dist/assets/prompts/validate-summary-judge.md +1 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +39 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +40 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +43 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +43 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +40 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +43 -0
- package/dist/assets/templates/html/health.html +281 -111
- package/dist/assets/wiki/ingest-workflow-template.md +45 -16
- package/dist/assets/wiki/schema-template.md +4 -4
- package/dist/cli/clack.js +56 -0
- package/dist/cli/config-migrate.js +7 -1
- package/dist/cli/confirm.js +1 -1
- package/dist/cli/parse-args.js +46 -1
- package/dist/cli/shared.js +28 -0
- package/dist/cli.js +25 -14
- package/dist/commands/agent/agent-dispatch.js +3 -2
- package/dist/commands/agent/agent-support.js +0 -7
- package/dist/commands/agent/contribute-cli.js +26 -7
- package/dist/commands/config-cli.js +26 -13
- package/dist/commands/env/child-env.js +47 -0
- package/dist/commands/env/env-cli.js +220 -227
- package/dist/commands/env/env.js +14 -67
- package/dist/commands/env/secret-cli.js +140 -138
- package/dist/commands/feedback-cli.js +153 -147
- package/dist/commands/graph/graph-cli.js +5 -13
- package/dist/commands/graph/graph.js +76 -72
- package/dist/commands/health/advisories.js +151 -0
- package/dist/commands/health/checks.js +103 -16
- package/dist/commands/health/html-report.js +447 -81
- package/dist/commands/health/improve-metrics.js +771 -0
- package/dist/commands/health/llm-usage.js +65 -0
- package/dist/commands/health/md-report.js +103 -0
- package/dist/commands/health/metrics.js +278 -0
- package/dist/commands/health/stash-exposure.js +46 -0
- package/dist/commands/health/surfaces.js +216 -0
- package/dist/commands/health/task-runs.js +135 -0
- package/dist/commands/health/types.js +26 -0
- package/dist/commands/health/windows.js +195 -0
- package/dist/commands/health.js +91 -1083
- package/dist/commands/improve/anti-collapse.js +170 -0
- package/dist/commands/improve/calibration.js +161 -0
- package/dist/commands/improve/collapse-detector.js +421 -0
- package/dist/commands/improve/consolidate/chunking.js +141 -0
- package/dist/commands/improve/consolidate/eligibility.js +64 -0
- package/dist/commands/improve/consolidate/merge.js +145 -0
- package/dist/commands/improve/consolidate/sanitize.js +231 -0
- package/dist/commands/{lint.js → improve/consolidate/types.js} +1 -1
- package/dist/commands/improve/consolidate.js +1313 -1278
- package/dist/commands/improve/dedup.js +482 -0
- package/dist/commands/improve/distill/content-repair.js +202 -0
- package/dist/commands/improve/distill/promote-memory.js +229 -0
- package/dist/commands/improve/distill/quality-gate.js +236 -0
- package/dist/commands/improve/distill-guards.js +127 -0
- package/dist/commands/improve/distill-promotion-policy.js +826 -167
- package/dist/commands/improve/distill.js +243 -599
- package/dist/commands/improve/eligibility.js +434 -0
- package/dist/commands/improve/encoding-salience.js +205 -0
- package/dist/commands/improve/extract-cli.js +179 -59
- package/dist/commands/improve/extract-prompt.js +55 -4
- package/dist/commands/improve/extract-watch.js +140 -0
- package/dist/commands/improve/extract.js +409 -43
- package/dist/commands/improve/feedback-valence.js +54 -0
- package/dist/commands/improve/hot-probation.js +45 -0
- package/dist/commands/improve/improve-auto-accept.js +160 -7
- package/dist/commands/improve/improve-cli.js +115 -73
- package/dist/commands/improve/improve-profiles.js +32 -8
- package/dist/commands/improve/improve-result-file.js +15 -25
- package/dist/commands/improve/improve-session.js +58 -0
- package/dist/commands/improve/improve.js +510 -2537
- package/dist/commands/improve/locks.js +154 -0
- package/dist/commands/improve/loop-stages.js +1100 -0
- package/dist/commands/improve/memory/memory-belief.js +14 -15
- package/dist/commands/improve/memory/memory-contradiction-detect.js +83 -60
- package/dist/commands/improve/memory/memory-improve.js +27 -27
- package/dist/commands/improve/outcome-loop.js +270 -0
- package/dist/commands/improve/preparation.js +2002 -0
- package/dist/commands/improve/proactive-maintenance.js +115 -0
- package/dist/commands/improve/procedural.js +398 -0
- package/dist/commands/improve/recombine.js +818 -0
- package/dist/commands/improve/reflect-noise.js +0 -0
- package/dist/commands/improve/reflect.js +212 -45
- package/dist/commands/improve/salience.js +455 -0
- package/dist/commands/improve/schema-similarity-gate.js +168 -0
- package/dist/commands/improve/shared.js +51 -0
- package/dist/commands/improve/triage.js +93 -0
- package/dist/commands/lint/agent-linter.js +19 -24
- package/dist/commands/lint/base-linter.js +173 -60
- package/dist/commands/lint/command-linter.js +19 -24
- package/dist/commands/lint/env-key-rules.js +38 -1
- package/dist/commands/lint/fact-linter.js +39 -0
- package/dist/commands/lint/index.js +31 -13
- package/dist/commands/lint/memory-linter.js +1 -1
- package/dist/commands/lint/registry.js +7 -2
- package/dist/commands/lint/task-linter.js +3 -3
- package/dist/commands/lint/workflow-linter.js +26 -1
- package/dist/commands/observability-cli.js +4 -4
- package/dist/commands/proposal/drain-policies.js +13 -4
- package/dist/commands/proposal/drain.js +45 -51
- package/dist/commands/proposal/legacy-import.js +115 -0
- package/dist/commands/proposal/proposal-cli.js +24 -34
- package/dist/commands/proposal/proposal.js +7 -1
- package/dist/commands/proposal/propose.js +8 -3
- package/dist/commands/proposal/repository.js +829 -0
- package/dist/commands/proposal/validators/proposal-quality-validators.js +9 -8
- package/dist/commands/proposal/validators/proposals.js +93 -882
- package/dist/commands/read/curate.js +419 -103
- package/dist/commands/read/knowledge.js +10 -3
- package/dist/commands/read/remember-cli.js +133 -138
- package/dist/commands/read/search-cli.js +15 -8
- package/dist/commands/read/search.js +22 -11
- package/dist/commands/read/show.js +106 -14
- package/dist/commands/registry-cli.js +76 -87
- package/dist/commands/remember.js +11 -12
- package/dist/commands/sources/add-cli.js +91 -95
- package/dist/commands/sources/history.js +1 -1
- package/dist/commands/sources/init.js +66 -18
- package/dist/commands/sources/installed-stashes.js +11 -3
- package/dist/commands/sources/schema-repair.js +44 -46
- package/dist/commands/sources/self-update.js +2 -2
- package/dist/commands/sources/source-add.js +7 -3
- package/dist/commands/sources/sources-cli.js +3 -3
- package/dist/commands/sources/stash-cli.js +29 -41
- package/dist/commands/sources/stash-skeleton.js +57 -8
- package/dist/commands/tasks/default-tasks.js +15 -2
- package/dist/commands/tasks/tasks-cli.js +20 -29
- package/dist/commands/tasks/tasks.js +39 -11
- package/dist/commands/wiki-cli.js +23 -38
- package/dist/commands/workflow-cli.js +15 -1
- package/dist/core/asset/asset-registry.js +3 -1
- package/dist/core/asset/asset-spec.js +21 -4
- package/dist/core/asset/frontmatter.js +188 -167
- package/dist/core/asset/markdown.js +8 -0
- package/dist/core/authoring-rules.js +92 -0
- package/dist/core/common.js +4 -23
- package/dist/core/concurrent.js +10 -1
- package/dist/core/config/config-io.js +10 -1
- package/dist/core/config/config-migration.js +18 -40
- package/dist/core/config/config-schema.js +389 -58
- package/dist/core/config/config-types.js +3 -3
- package/dist/core/config/config.js +67 -22
- package/dist/core/deep-merge.js +38 -0
- package/dist/core/errors.js +1 -0
- package/dist/core/eval/rank-metrics.js +113 -0
- package/dist/core/events.js +4 -7
- package/dist/core/improve-types.js +47 -8
- package/dist/core/logs-db.js +14 -75
- package/dist/core/parse.js +36 -16
- package/dist/core/paths.js +21 -18
- package/dist/core/standards/resolve-standards-context.js +87 -0
- package/dist/core/standards/resolve-stash-standards.js +99 -0
- package/dist/core/standards/resolve-type-conventions.js +66 -0
- package/dist/core/state/migrations.js +770 -0
- package/dist/core/state-db.js +142 -1091
- package/dist/core/structured.js +69 -0
- package/dist/core/time.js +53 -0
- package/dist/core/warn.js +21 -0
- package/dist/core/write-source.js +37 -0
- package/dist/indexer/db/db.js +356 -780
- package/dist/indexer/db/entry-mapper.js +41 -0
- package/dist/indexer/db/graph-db.js +129 -86
- package/dist/indexer/db/llm-cache.js +2 -2
- package/dist/indexer/db/schema.js +516 -0
- package/dist/indexer/ensure-index.js +103 -24
- package/dist/indexer/feedback/utility-policy.js +75 -0
- package/dist/indexer/graph/graph-boost.js +51 -41
- package/dist/indexer/graph/graph-extraction.js +207 -4
- package/dist/indexer/index-writer-lock.js +106 -0
- package/dist/indexer/index-written-assets.js +105 -0
- package/dist/indexer/indexer.js +291 -310
- package/dist/indexer/passes/dir-staleness.js +114 -0
- package/dist/indexer/passes/memory-inference.js +13 -5
- package/dist/indexer/passes/metadata.js +20 -0
- package/dist/indexer/read-preflight.js +23 -0
- package/dist/indexer/search/db-search.js +89 -13
- package/dist/indexer/search/fts-query.js +51 -0
- package/dist/indexer/search/ranking-contributors.js +95 -9
- package/dist/indexer/search/ranking.js +79 -3
- package/dist/indexer/search/search-fields.js +6 -0
- package/dist/indexer/search/search-source.js +32 -21
- package/dist/indexer/search/semantic-status.js +4 -0
- package/dist/indexer/walk/matchers.js +9 -0
- package/dist/indexer/walk/walker.js +21 -13
- package/dist/integrations/agent/builders.js +39 -13
- package/dist/integrations/agent/config.js +20 -59
- package/dist/integrations/agent/detect.js +9 -0
- package/dist/integrations/agent/index.js +3 -19
- package/dist/integrations/agent/model-aliases.js +7 -2
- package/dist/integrations/agent/profiles.js +7 -1
- package/dist/integrations/agent/prompts.js +75 -9
- package/dist/integrations/agent/runner-dispatch.js +59 -0
- package/dist/integrations/agent/runner.js +13 -9
- package/dist/integrations/agent/spawn.js +69 -67
- package/dist/integrations/harnesses/claude/agent-builder.js +1 -1
- package/dist/integrations/harnesses/claude/index.js +2 -0
- package/dist/integrations/harnesses/claude/session-log.js +11 -1
- package/dist/integrations/harnesses/index.js +2 -3
- package/dist/integrations/harnesses/opencode/agent-builder.js +1 -1
- package/dist/integrations/harnesses/opencode/index.js +2 -0
- package/dist/integrations/harnesses/opencode/session-log.js +173 -3
- package/dist/integrations/harnesses/opencode-sdk/index.js +2 -2
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +98 -17
- package/dist/integrations/harnesses/types.js +1 -0
- package/dist/integrations/session-logs/index.js +16 -0
- package/dist/llm/call-ai.js +2 -2
- package/dist/llm/client.js +57 -15
- package/dist/llm/embedder.js +67 -4
- package/dist/llm/embedders/cache.js +3 -1
- package/dist/llm/embedders/deterministic.js +66 -0
- package/dist/llm/embedders/local.js +73 -3
- package/dist/llm/feature-gate.js +16 -15
- package/dist/llm/graph-extract.js +67 -44
- package/dist/llm/memory-infer-impl.js +138 -0
- package/dist/llm/memory-infer.js +1 -127
- package/dist/llm/metadata-enhance.js +44 -31
- package/dist/llm/structured-call.js +49 -0
- package/dist/migrate-storage-node.mjs +8 -0
- package/dist/output/context.js +5 -5
- package/dist/output/renderers.js +85 -14
- package/dist/output/shapes/curate.js +14 -2
- package/dist/output/shapes/helpers.js +0 -3
- package/dist/output/shapes/passthrough.js +2 -1
- package/dist/output/text/helpers.js +29 -1
- package/dist/output/text/workflow.js +1 -0
- package/dist/registry/providers/skills-sh.js +21 -147
- package/dist/registry/providers/static-index.js +15 -157
- package/dist/registry/resolve.js +27 -9
- package/dist/runtime.js +25 -1
- package/dist/scripts/migrate-storage.js +2718 -2354
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +891 -597
- package/dist/setup/detect.js +9 -0
- package/dist/setup/legacy-config.js +106 -0
- package/dist/setup/prompt.js +57 -0
- package/dist/setup/providers.js +14 -0
- package/dist/setup/registry-stash-loader.js +12 -0
- package/dist/setup/semantic-assets.js +124 -0
- package/dist/setup/setup.js +52 -1614
- package/dist/setup/steps/connection.js +734 -0
- package/dist/setup/steps/output.js +31 -0
- package/dist/setup/steps/platforms.js +124 -0
- package/dist/setup/steps/semantic.js +27 -0
- package/dist/setup/steps/sources.js +222 -0
- package/dist/setup/steps/stashdir.js +42 -0
- package/dist/setup/steps/tasks.js +152 -0
- package/dist/sources/include.js +6 -2
- package/dist/sources/providers/filesystem.js +0 -1
- package/dist/sources/providers/git-install.js +210 -0
- package/dist/sources/providers/git-provider.js +234 -0
- package/dist/sources/providers/git-stash.js +248 -0
- package/dist/sources/providers/git.js +10 -661
- package/dist/sources/providers/npm.js +2 -6
- package/dist/sources/providers/provider-utils.js +13 -7
- package/dist/sources/providers/sync-from-ref.js +9 -1
- package/dist/sources/providers/tar-utils.js +16 -8
- package/dist/sources/providers/website.js +9 -5
- package/dist/sources/website-ingest.js +187 -29
- package/dist/sources/wiki-fetchers/registry.js +53 -0
- package/dist/sources/wiki-fetchers/youtube.js +239 -0
- package/dist/storage/database.js +45 -10
- package/dist/storage/managed-db.js +82 -0
- package/dist/storage/repositories/canaries-repository.js +107 -0
- package/dist/storage/repositories/consolidation-repository.js +38 -0
- package/dist/storage/repositories/embeddings-repository.js +72 -0
- package/dist/storage/repositories/events-repository.js +187 -0
- package/dist/storage/repositories/extract-sessions-repository.js +96 -0
- package/dist/storage/repositories/improve-runs-repository.js +146 -0
- package/dist/storage/repositories/index-db.js +14 -8
- package/dist/storage/repositories/proposals-repository.js +220 -0
- package/dist/storage/repositories/recombine-repository.js +213 -0
- package/dist/storage/repositories/registry-cache.js +93 -0
- package/dist/storage/repositories/registry-index-cache-repository.js +46 -0
- package/dist/storage/repositories/task-history-repository.js +93 -0
- package/dist/storage/sqlite-pragmas.js +146 -0
- package/dist/tasks/backends/cron.js +1 -1
- package/dist/tasks/backends/index.js +9 -0
- package/dist/tasks/backends/launchd.js +1 -1
- package/dist/tasks/backends/schtasks.js +1 -1
- package/dist/tasks/{resolveAkmBin.js → resolve-akm-bin.js} +2 -2
- package/dist/tasks/runner.js +15 -13
- package/dist/text-import-hook.mjs +0 -0
- package/dist/wiki/wiki.js +52 -11
- package/dist/workflows/cli.js +1 -0
- package/dist/workflows/db.js +3 -4
- package/dist/workflows/runtime/runs.js +43 -118
- package/dist/workflows/runtime/workflow-asset-loader.js +125 -0
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/README.md +69 -18
- package/docs/data-and-telemetry.md +5 -4
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.9.0.md +39 -0
- package/package.json +10 -10
- package/dist/assets/tasks/core/update-stashes.yml +0 -4
- package/dist/commands/db-cli.js +0 -23
- package/dist/indexer/db/db-backup.js +0 -376
- package/dist/indexer/passes/staleness-detect.js +0 -488
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* Improve-pipeline advisories for `akm health`: projects the computed
|
|
6
|
+
* {@link ImproveHealthMetrics} plus a few direct event reads into the
|
|
7
|
+
* ordered advisory list.
|
|
8
|
+
*/
|
|
9
|
+
import { readEvents } from "../../core/events.js";
|
|
10
|
+
import { getLatestCycleMetrics } from "../../storage/repositories/canaries-repository.js";
|
|
11
|
+
import { ENRICHMENT_MINTED_FAIL_SHARE, ENRICHMENT_MINTED_WARN_SHARE, } from "./types.js";
|
|
12
|
+
/**
|
|
13
|
+
* Build the improve-pipeline advisories for the health window from the already
|
|
14
|
+
* computed {@link ImproveHealthMetrics} plus a few direct event reads. Pure
|
|
15
|
+
* projection of state → advisories; emission order is preserved so the health
|
|
16
|
+
* report is byte-identical to the previous inline construction.
|
|
17
|
+
*/
|
|
18
|
+
export function collectImproveAdvisories(db, stateDbPath, since, improveSummary) {
|
|
19
|
+
const advisories = [];
|
|
20
|
+
// WS-2 proxy-adequacy tripwire: surface any outcome_proxy_inverted events
|
|
21
|
+
// in the health window as an advisory so operators know when the 0.10+
|
|
22
|
+
// rich in-session signal is no longer deferrable.
|
|
23
|
+
const proxyInvertedEvents = readEvents({ since, type: "outcome_proxy_inverted" }, { dbPath: stateDbPath }).events;
|
|
24
|
+
if (proxyInvertedEvents.length > 0) {
|
|
25
|
+
const lastEvent = proxyInvertedEvents[proxyInvertedEvents.length - 1];
|
|
26
|
+
const correlation = typeof lastEvent.metadata?.correlation === "number" ? lastEvent.metadata.correlation.toFixed(3) : "unknown";
|
|
27
|
+
advisories.push({
|
|
28
|
+
name: "outcome-proxy-adequacy",
|
|
29
|
+
status: "warn",
|
|
30
|
+
kind: "deterministic",
|
|
31
|
+
confidence: "high",
|
|
32
|
+
message: `WS-2 outcome proxy inverted (${proxyInvertedEvents.length} event(s) in window). ` +
|
|
33
|
+
`corr(outcome_score, accepted_change_rate) = ${correlation} < −0.3. ` +
|
|
34
|
+
"Popular assets are also the most-needing-improvement assets — " +
|
|
35
|
+
"the retrieval-based proxy is inverted. " +
|
|
36
|
+
"The 0.10+ rich in-session outcome signal is no longer deferrable. See plan §WS-2.",
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
// Two-tailed companion: a proxy that decays to noise (|corr| < 0.1 at scale)
|
|
40
|
+
// is as much a failure as an inverted one — it just fails silently.
|
|
41
|
+
const proxyDeadEvents = readEvents({ since, type: "outcome_proxy_dead" }, { dbPath: stateDbPath, db }).events;
|
|
42
|
+
if (proxyDeadEvents.length > 0) {
|
|
43
|
+
const lastEvent = proxyDeadEvents[proxyDeadEvents.length - 1];
|
|
44
|
+
const correlation = typeof lastEvent.metadata?.correlation === "number" ? lastEvent.metadata.correlation.toFixed(3) : "unknown";
|
|
45
|
+
advisories.push({
|
|
46
|
+
name: "outcome-proxy-dead",
|
|
47
|
+
status: "warn",
|
|
48
|
+
kind: "deterministic",
|
|
49
|
+
confidence: "high",
|
|
50
|
+
message: `WS-2 outcome proxy is DEAD (${proxyDeadEvents.length} event(s) in window). ` +
|
|
51
|
+
`|corr(outcome_score, accepted_change_rate)| = ${correlation} < 0.1 at n ≥ 500. ` +
|
|
52
|
+
"outcome_score is statistically unrelated to improvement outcomes — " +
|
|
53
|
+
"treat outcome-derived rank contributions as noise until a real usage/outcome signal lands.",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
// Salience-distribution collapse: Gini below the uniform baseline means
|
|
57
|
+
// ranking no longer discriminates between assets.
|
|
58
|
+
if (improveSummary.degradation?.salienceUniformityFlagged) {
|
|
59
|
+
advisories.push({
|
|
60
|
+
name: "salience-uniformity-collapse",
|
|
61
|
+
status: "warn",
|
|
62
|
+
kind: "deterministic",
|
|
63
|
+
confidence: "high",
|
|
64
|
+
message: `Salience distribution collapsed toward uniform: top-100 retrieval_salience Gini = ` +
|
|
65
|
+
`${improveSummary.degradation.corpusCentroidDistance} < 0.08 (uniform baseline ≈ 0.1). ` +
|
|
66
|
+
"Ranking currently carries little to no discrimination between assets.",
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
// Enrichment-vs-minting policy: enrichment lanes edit existing assets;
|
|
70
|
+
// a rising minted share means a lane is generating new content instead.
|
|
71
|
+
const minting = improveSummary.enrichmentMinting;
|
|
72
|
+
if (minting && Number.isFinite(minting.share) && minting.share > ENRICHMENT_MINTED_WARN_SHARE) {
|
|
73
|
+
advisories.push({
|
|
74
|
+
name: "enrichment-lane-minting",
|
|
75
|
+
status: minting.share > ENRICHMENT_MINTED_FAIL_SHARE ? "fail" : "warn",
|
|
76
|
+
kind: "deterministic",
|
|
77
|
+
confidence: "high",
|
|
78
|
+
message: `Enrichment lanes minted ${minting.minted} NEW asset(s) vs ${minting.updated} update(s) ` +
|
|
79
|
+
`(${Math.round(minting.share * 100)}% minted, threshold ${Math.round(ENRICHMENT_MINTED_WARN_SHARE * 100)}%). ` +
|
|
80
|
+
"Enrichment-classed lanes (proactive/high-salience/high-retrieval/signal-delta) are ratified to edit " +
|
|
81
|
+
"existing assets only — new-asset generation belongs to the signal-gated minting lanes.",
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// Churn: accepted proposals far exceeding distinct touched refs means the
|
|
85
|
+
// loop is repeatedly rewriting the same assets, not covering the corpus.
|
|
86
|
+
if (Number.isFinite(improveSummary.coverage.churnRatio) && improveSummary.coverage.churnRatio > 1.5) {
|
|
87
|
+
advisories.push({
|
|
88
|
+
name: "improve-churn-ratio",
|
|
89
|
+
status: "warn",
|
|
90
|
+
kind: "deterministic",
|
|
91
|
+
confidence: "high",
|
|
92
|
+
message: `Improve churn ratio ${improveSummary.coverage.churnRatio} > 1.5: ` +
|
|
93
|
+
`${improveSummary.coverage.acceptedProposals} accepted proposals touched only ` +
|
|
94
|
+
`${improveSummary.coverage.distinctRefs} distinct assets in the window — ` +
|
|
95
|
+
"repeated rewrites of the same refs count as churn, not coverage.",
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
// R5 collapse/churn detector: surface any collapse_detector_alert events
|
|
99
|
+
// in the health window, plus the latest cycle row's headline numbers so
|
|
100
|
+
// the operator can act without opening the DB. `unknown` when the detector
|
|
101
|
+
// has never produced a cycle row (no consolidate/recombine work yet).
|
|
102
|
+
try {
|
|
103
|
+
// Reuse the already-open state.db handle (readEvents supports a
|
|
104
|
+
// borrowed connection) — no extra open/migrate/close per health call.
|
|
105
|
+
const collapseAlertEvents = readEvents({ since, type: "collapse_detector_alert" }, { dbPath: stateDbPath, db }).events;
|
|
106
|
+
const latestCycle = getLatestCycleMetrics(db);
|
|
107
|
+
const cycleSummary = latestCycle
|
|
108
|
+
? `Latest cycle (${latestCycle.ts}, ${latestCycle.pass}): mean canary recall ${latestCycle.mean_recall.toFixed(3)}, ` +
|
|
109
|
+
`distinct-content ratio ${latestCycle.distinct_content_ratio.toFixed(3)}, ` +
|
|
110
|
+
`${latestCycle.accepted_actions} accepted action(s).`
|
|
111
|
+
: "";
|
|
112
|
+
if (collapseAlertEvents.length > 0) {
|
|
113
|
+
const kinds = [...new Set(collapseAlertEvents.map((e) => String(e.metadata?.kind ?? "unknown")))];
|
|
114
|
+
const collapseKinds = kinds.filter((k) => k.startsWith("collapse"));
|
|
115
|
+
advisories.push({
|
|
116
|
+
name: "collapse-churn-detector",
|
|
117
|
+
status: "warn",
|
|
118
|
+
kind: "deterministic",
|
|
119
|
+
// Collapse kinds are measured, not inferred; churn/merge-floor
|
|
120
|
+
// volume thresholds are still being tuned (design doc §7).
|
|
121
|
+
confidence: collapseKinds.length > 0 ? "high" : "medium",
|
|
122
|
+
message: `R5 detector fired ${collapseAlertEvents.length} alert(s) in window (kinds: ${kinds.join(", ")}). ` +
|
|
123
|
+
`${cycleSummary} See docs/design/improve-collapse-churn-detector-design.md §6.3 runbook queries.`,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
else if (latestCycle) {
|
|
127
|
+
advisories.push({
|
|
128
|
+
name: "collapse-churn-detector",
|
|
129
|
+
status: "pass",
|
|
130
|
+
kind: "deterministic",
|
|
131
|
+
confidence: "high",
|
|
132
|
+
message: `No collapse/churn alerts in window. ${cycleSummary}`,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
advisories.push({
|
|
137
|
+
name: "collapse-churn-detector",
|
|
138
|
+
status: "unknown",
|
|
139
|
+
kind: "deterministic",
|
|
140
|
+
confidence: "high",
|
|
141
|
+
message: "No detector cycle rows yet — the collapse/churn detector runs only on improve cycles " +
|
|
142
|
+
"where consolidate/recombine did work (synthesis lanes may be idle).",
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// Table may predate migration 016 in odd mixed-version setups — advisory
|
|
148
|
+
// is best-effort and must never fail the health command.
|
|
149
|
+
}
|
|
150
|
+
return advisories;
|
|
151
|
+
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { spawnSync } from "node:child_process";
|
|
5
5
|
import { loadConfig } from "../../core/config/config.js";
|
|
6
6
|
import { detectAgentCliProfiles, requireAgentProfile } from "../../integrations/agent/index.js";
|
|
7
|
+
import { TASK_FAIL_RATE_WARN, } from "./types.js";
|
|
7
8
|
const ACTIVE_RUN_WARN_MS = 15 * 60 * 1000;
|
|
8
9
|
/**
|
|
9
10
|
* Probe the configured agent profile. Self-contained (reads config + PATH); the
|
|
@@ -188,24 +189,62 @@ export const HEALTH_CHECKS = [
|
|
|
188
189
|
channel: "hard",
|
|
189
190
|
run: () => runAgentProbe(),
|
|
190
191
|
},
|
|
192
|
+
{
|
|
193
|
+
// C2 (13-bus-factor): the cron task-failure rate was computed and rendered
|
|
194
|
+
// in the HTML report but never surfaced as an advisory, so a sustained
|
|
195
|
+
// 15–16% fail rate stayed invisible on `akm health`. Warn at/above the SAME
|
|
196
|
+
// 5% threshold the html-report badge uses (see TASK_FAIL_RATE_WARN).
|
|
197
|
+
name: "task-fail-rate",
|
|
198
|
+
channel: "advisory",
|
|
199
|
+
run: (ctx) => {
|
|
200
|
+
const pctStr = `${(ctx.taskFailRate * 100).toFixed(1)}%`;
|
|
201
|
+
const thresholdPct = `${(TASK_FAIL_RATE_WARN * 100).toFixed(0)}%`;
|
|
202
|
+
const warn = ctx.taskFailRate >= TASK_FAIL_RATE_WARN;
|
|
203
|
+
return {
|
|
204
|
+
name: "task-fail-rate",
|
|
205
|
+
kind: "deterministic",
|
|
206
|
+
status: warn ? "warn" : "pass",
|
|
207
|
+
confidence: "high",
|
|
208
|
+
message: ctx.taskRowCount === 0
|
|
209
|
+
? `No cron tasks ran since ${ctx.since} — no task-fail-rate signal.`
|
|
210
|
+
: warn
|
|
211
|
+
? `Cron task fail rate ${pctStr} across ${ctx.taskRowCount} task(s) since ${ctx.since} ≥ ${thresholdPct} threshold — inspect failed runs (ok=false) for early-exit/harness errors.`
|
|
212
|
+
: `Cron task fail rate ${pctStr} across ${ctx.taskRowCount} task(s) since ${ctx.since} (below ${thresholdPct} threshold).`,
|
|
213
|
+
evidence: { taskFailRate: ctx.taskFailRate, taskRowCount: ctx.taskRowCount, threshold: TASK_FAIL_RATE_WARN },
|
|
214
|
+
};
|
|
215
|
+
},
|
|
216
|
+
},
|
|
191
217
|
{
|
|
192
218
|
name: "semantic-search-runtime",
|
|
193
219
|
channel: "advisory",
|
|
194
|
-
run: (ctx) =>
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
220
|
+
run: (ctx) => {
|
|
221
|
+
const blocked = ctx.semanticStatus?.status === "blocked";
|
|
222
|
+
// The generic "status: blocked" line is not actionable when the real
|
|
223
|
+
// problem is a configured remote embedding endpoint that is down while
|
|
224
|
+
// semanticSearchMode leaves semantic search enabled — every index run
|
|
225
|
+
// burns time failing against it and searches silently degrade to
|
|
226
|
+
// keyword-only. Name the endpoint and the two ways out.
|
|
227
|
+
const remoteReason = ctx.semanticStatus?.reason?.startsWith("remote-") === true;
|
|
228
|
+
const endpointAdvisory = blocked && remoteReason && ctx.embeddingEndpoint
|
|
229
|
+
? `Configured embedding endpoint ${ctx.embeddingEndpoint} is failing ` +
|
|
230
|
+
`(${ctx.semanticStatus?.reason}${ctx.semanticStatus?.message ? `: ${ctx.semanticStatus.message}` : ""}) ` +
|
|
231
|
+
`while semanticSearchMode is "${ctx.semanticSearchMode ?? "auto"}". Searches fall back to keyword-only. ` +
|
|
232
|
+
`Restore the endpoint, or set semanticSearchMode to "off" (or remove embedding.endpoint to use the local model).`
|
|
233
|
+
: undefined;
|
|
234
|
+
return {
|
|
235
|
+
name: "semantic-search-runtime",
|
|
236
|
+
kind: "deterministic",
|
|
237
|
+
status: !ctx.semanticStatus || !blocked ? "pass" : "warn",
|
|
238
|
+
confidence: "medium",
|
|
239
|
+
message: endpointAdvisory ??
|
|
240
|
+
(ctx.semanticStatus
|
|
241
|
+
? `Semantic search status: ${ctx.semanticStatus.status}`
|
|
242
|
+
: "No semantic-search runtime status recorded yet."),
|
|
243
|
+
evidence: ctx.semanticStatus
|
|
244
|
+
? { ...ctx.semanticStatus, ...(ctx.embeddingEndpoint ? { embeddingEndpoint: ctx.embeddingEndpoint } : {}) }
|
|
245
|
+
: undefined,
|
|
246
|
+
};
|
|
247
|
+
},
|
|
209
248
|
},
|
|
210
249
|
{
|
|
211
250
|
// session-log-failures: demoted to informational — the ERROR_PATTERNS regex
|
|
@@ -257,6 +296,54 @@ export const HEALTH_CHECKS = [
|
|
|
257
296
|
};
|
|
258
297
|
},
|
|
259
298
|
},
|
|
299
|
+
{
|
|
300
|
+
// #603: pool-saturation advisory. The raw `sessionsScanned` count fired on
|
|
301
|
+
// normal cadence changes (the Jun 12 false alarm). Instead track the ratio
|
|
302
|
+
// of NEW (unseen) sessions to the total session pool extract evaluated in
|
|
303
|
+
// the window: a low ratio is the *expected* steady state, only a near-zero
|
|
304
|
+
// ratio signals a possible discovery/dedup bug.
|
|
305
|
+
//
|
|
306
|
+
// unseen ≈ `sessionsScanned` (extract only processes new sessions; already-
|
|
307
|
+
// seen ones are deduped into `sessionsSkipped`). total = scanned + skipped.
|
|
308
|
+
// This is a heuristic approximation — `sessionsSkipped` also folds in
|
|
309
|
+
// too-short skips — so the check is informational and never gates status.
|
|
310
|
+
name: "pool-saturation",
|
|
311
|
+
channel: "advisory",
|
|
312
|
+
run: (ctx) => {
|
|
313
|
+
const sx = ctx.sessionExtraction;
|
|
314
|
+
const total = sx.sessionsScanned + sx.sessionsSkipped;
|
|
315
|
+
const unseen = sx.sessionsScanned;
|
|
316
|
+
const ratio = total > 0 ? unseen / total : null;
|
|
317
|
+
const pct = ratio === null ? null : Math.round(ratio * 1000) / 10;
|
|
318
|
+
let status = "pass";
|
|
319
|
+
let confidence = "low";
|
|
320
|
+
let message;
|
|
321
|
+
if (!sx.ran || ratio === null) {
|
|
322
|
+
message = "Pool saturation: no extract activity in the window — no signal.";
|
|
323
|
+
}
|
|
324
|
+
else if (ratio < 0.02) {
|
|
325
|
+
status = "warn";
|
|
326
|
+
confidence = "medium";
|
|
327
|
+
message = `Session pool near-exhausted: only ${pct}% of the ${total}-session pool was new (<2%). Possible discovery/dedup bug — verify extract is still finding new sessions.`;
|
|
328
|
+
}
|
|
329
|
+
else if (ratio < 0.1) {
|
|
330
|
+
confidence = "medium";
|
|
331
|
+
message = `Session pool saturation: ${pct}% of ${total} sessions were new (<10%, steady-state expected — informational).`;
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
confidence = "medium";
|
|
335
|
+
message = `Session pool healthy: ${pct}% of ${total} sessions were new.`;
|
|
336
|
+
}
|
|
337
|
+
return {
|
|
338
|
+
name: "pool-saturation",
|
|
339
|
+
kind: "heuristic",
|
|
340
|
+
status,
|
|
341
|
+
confidence,
|
|
342
|
+
message,
|
|
343
|
+
evidence: { totalSessions: total, unseenSessions: unseen, saturationRatio: ratio },
|
|
344
|
+
};
|
|
345
|
+
},
|
|
346
|
+
},
|
|
260
347
|
{
|
|
261
348
|
name: "auto-accept-validation",
|
|
262
349
|
channel: "advisory",
|
|
@@ -268,7 +355,7 @@ export const HEALTH_CHECKS = [
|
|
|
268
355
|
status: aa.validationFailed > 0 ? "warn" : "pass",
|
|
269
356
|
confidence: aa.promoted + aa.validationFailed > 0 ? "high" : "low",
|
|
270
357
|
message: aa.validationFailed > 0
|
|
271
|
-
? `${aa.validationFailed}
|
|
358
|
+
? `${aa.validationFailed} auto-accept validation attempt(s) failed after passing the confidence threshold (truncated description, invalid frontmatter, etc.) — the affected proposals remain pending for manual review.`
|
|
272
359
|
: aa.promoted > 0
|
|
273
360
|
? `Auto-accept healthy: ${aa.promoted} proposal(s) promoted, 0 validation failures.`
|
|
274
361
|
: "Auto-accept gate did not run (disabled or no proposals above threshold).",
|