akm-cli 0.9.0-rc.0 → 0.9.0-rc.2
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 +339 -2
- 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}/default.json +1 -0
- package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +1 -1
- package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +2 -3
- package/dist/assets/{profiles → improve-strategies}/reflect-distill.json +3 -4
- package/dist/assets/prompts/workflow-unit-preamble.md +26 -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 +1 -0
- 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 +31 -138
- package/dist/cli/config-validate.js +10 -8
- package/dist/cli.js +48 -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 +54 -0
- package/dist/commands/config-cli.js +45 -159
- package/dist/commands/env/env-binding.js +95 -0
- package/dist/commands/env/env-cli.js +8 -65
- package/dist/commands/env/secret.js +8 -5
- package/dist/commands/health/checks.js +130 -83
- 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 +5 -4
- package/dist/commands/health.js +1 -1
- package/dist/commands/improve/consolidate/chunking.js +2 -2
- package/dist/commands/improve/consolidate.js +28 -25
- package/dist/commands/improve/distill/promote-memory.js +5 -12
- package/dist/commands/improve/distill/quality-gate.js +5 -7
- package/dist/commands/improve/distill.js +16 -5
- package/dist/commands/improve/eligibility.js +22 -12
- package/dist/commands/improve/extract-cli.js +47 -19
- package/dist/commands/improve/extract.js +110 -62
- package/dist/commands/improve/improve-cli.js +38 -16
- package/dist/commands/improve/improve-result-file.js +30 -24
- package/dist/commands/improve/improve-strategies.js +137 -0
- package/dist/commands/improve/improve.js +60 -30
- package/dist/commands/improve/locks.js +66 -45
- package/dist/commands/improve/loop-stages.js +75 -33
- 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 +71 -73
- package/dist/commands/improve/procedural.js +3 -2
- package/dist/commands/improve/recombine.js +2 -1
- package/dist/commands/improve/reflect.js +119 -214
- package/dist/commands/improve/shared.js +11 -5
- package/dist/commands/lint/base-linter.js +152 -42
- package/dist/commands/mv-cli.js +809 -0
- package/dist/commands/proposal/proposal-cli.js +18 -8
- package/dist/commands/proposal/propose.js +64 -69
- package/dist/commands/read/knowledge.js +436 -4
- package/dist/commands/read/remember-cli.js +39 -2
- package/dist/commands/read/search-cli.js +6 -1
- 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/migration-help.js +7 -4
- package/dist/commands/sources/schema-repair.js +2 -4
- package/dist/commands/sources/source-add.js +62 -73
- package/dist/commands/sources/source-manage.js +50 -46
- 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/commands/workflow-cli.js +276 -12
- package/dist/core/asset/asset-spec.js +58 -1
- package/dist/core/asset/frontmatter.js +12 -2
- package/dist/core/common.js +5 -3
- package/dist/core/config/config-io.js +28 -17
- package/dist/core/config/config-schema.js +379 -66
- 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 +132 -266
- 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 +201 -56
- package/dist/core/improve-result.js +178 -0
- package/dist/core/json-schema.js +142 -0
- package/dist/core/maintenance-barrier.js +119 -0
- package/dist/core/migration-backup.js +416 -0
- package/dist/core/paths.js +3 -0
- package/dist/core/redaction.js +358 -0
- package/dist/core/state/migrations.js +17 -2
- package/dist/core/state-db.js +44 -1
- package/dist/indexer/db/db.js +118 -2
- package/dist/indexer/graph/graph-extraction.js +28 -16
- package/dist/indexer/index-writer-lock.js +31 -24
- package/dist/indexer/index-written-assets.js +15 -6
- package/dist/indexer/indexer.js +47 -2
- 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/walk/matchers.js +39 -0
- package/dist/integrations/agent/builder-shared.js +7 -0
- package/dist/integrations/agent/builders.js +5 -50
- package/dist/integrations/agent/config.js +3 -143
- package/dist/integrations/agent/detect.js +17 -2
- package/dist/integrations/agent/engine-resolution.js +202 -0
- package/dist/integrations/agent/index.js +1 -2
- package/dist/integrations/agent/model-aliases.js +16 -2
- package/dist/integrations/agent/profiles.js +36 -62
- package/dist/integrations/agent/runner-dispatch.js +91 -4
- package/dist/integrations/agent/runner.js +76 -207
- package/dist/integrations/agent/spawn.js +141 -20
- package/dist/integrations/harnesses/aider/agent-builder.js +112 -0
- package/dist/integrations/harnesses/aider/index.js +57 -0
- package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
- package/dist/integrations/harnesses/amazonq/agent-builder.js +152 -0
- package/dist/integrations/harnesses/amazonq/index.js +58 -0
- package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
- package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
- package/dist/integrations/harnesses/claude/index.js +25 -25
- package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
- package/dist/integrations/harnesses/codex/agent-builder.js +136 -0
- package/dist/integrations/harnesses/codex/index.js +62 -0
- package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
- package/dist/integrations/harnesses/copilot/agent-builder.js +121 -0
- package/dist/integrations/harnesses/copilot/index.js +59 -0
- package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
- package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
- package/dist/integrations/harnesses/gemini/index.js +59 -0
- package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
- package/dist/integrations/harnesses/index.js +27 -28
- package/dist/integrations/harnesses/opencode/agent-builder.js +2 -3
- package/dist/integrations/harnesses/opencode/index.js +15 -22
- package/dist/integrations/harnesses/opencode-sdk/harness.js +60 -0
- package/dist/integrations/harnesses/opencode-sdk/index.js +8 -32
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
- package/dist/integrations/harnesses/openhands/agent-builder.js +125 -0
- package/dist/integrations/harnesses/openhands/index.js +57 -0
- package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
- package/dist/integrations/harnesses/pi/agent-builder.js +103 -0
- package/dist/integrations/harnesses/pi/index.js +57 -0
- package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
- package/dist/integrations/harnesses/types.js +8 -32
- package/dist/integrations/lockfile.js +32 -21
- package/dist/integrations/session-logs/index.js +24 -11
- 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/renderers.js +3 -2
- package/dist/output/shapes/helpers.js +2 -1
- package/dist/output/shapes/passthrough.js +6 -0
- package/dist/output/text/helpers.js +215 -2
- package/dist/output/text/workflow.js +3 -1
- package/dist/schemas/akm-config.json +16638 -0
- package/dist/schemas/akm-task.json +87 -0
- package/dist/schemas/akm-workflow.json +372 -0
- package/dist/scripts/migrate-storage.js +10944 -8801
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +9247 -350
- package/dist/setup/detected-engines.js +142 -0
- package/dist/setup/engine-config.js +89 -0
- package/dist/setup/setup.js +236 -132
- package/dist/setup/steps/connection.js +61 -32
- package/dist/setup/steps/platforms.js +4 -4
- package/dist/setup/steps.js +3 -2
- package/dist/storage/database.js +13 -1
- package/dist/storage/engines/sqlite-migrations.js +1 -0
- package/dist/storage/repositories/improve-runs-repository.js +5 -5
- package/dist/storage/repositories/task-history-repository.js +78 -0
- package/dist/storage/repositories/workflow-runs-repository.js +190 -1
- 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/text-import-hook.mjs +1 -1
- package/dist/wiki/wiki.js +9 -8
- package/dist/workflows/authoring/authoring.js +123 -10
- package/dist/workflows/authoring/workflow-program-template.yaml +31 -0
- package/dist/workflows/cli.js +4 -0
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/db.js +200 -13
- package/dist/workflows/exec/brief.js +478 -0
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +1034 -0
- package/dist/workflows/exec/param-secrets.js +115 -0
- package/dist/workflows/exec/report.js +1355 -0
- package/dist/workflows/exec/run-workflow.js +609 -0
- package/dist/workflows/exec/scheduler.js +71 -0
- package/dist/workflows/exec/step-work.js +1212 -0
- package/dist/workflows/exec/unit-writer.js +23 -0
- package/dist/workflows/exec/watch.js +116 -0
- package/dist/workflows/exec/worktree.js +171 -0
- package/dist/workflows/ir/compile.js +375 -0
- package/dist/workflows/ir/freeze.js +243 -0
- package/dist/workflows/ir/params.js +54 -0
- package/dist/workflows/ir/plan-hash.js +68 -0
- package/dist/workflows/ir/schema.js +545 -0
- package/dist/workflows/parser.js +10 -1
- package/dist/workflows/program/expressions.js +369 -0
- package/dist/workflows/program/parser.js +869 -0
- package/dist/workflows/program/project.js +104 -0
- package/dist/workflows/program/schema.js +54 -0
- package/dist/workflows/renderer.js +82 -5
- package/dist/workflows/resource-limits.js +20 -0
- package/dist/workflows/runtime/agent-identity.js +59 -14
- package/dist/workflows/runtime/plan-classifier.js +187 -0
- package/dist/workflows/runtime/runs.js +246 -69
- package/dist/workflows/runtime/unit-checkin.js +45 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +42 -1
- package/dist/workflows/validate-summary.js +24 -3
- package/dist/workflows/validator.js +26 -1
- package/docs/data-and-telemetry.md +4 -3
- 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-beta.60.md +19 -0
- package/docs/migration/v0.8-to-v0.9.md +401 -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}/catchup.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/consolidate.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/frequent.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/memory-focus.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/quick.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/recombine-only.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/synthesize.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/thorough.json +0 -0
|
@@ -6,13 +6,14 @@ import path from "node:path";
|
|
|
6
6
|
import { parseAssetRef } from "../../core/asset/asset-ref.js";
|
|
7
7
|
import { parseFrontmatter } from "../../core/asset/frontmatter.js";
|
|
8
8
|
import { daysToMs } from "../../core/common.js";
|
|
9
|
-
import {
|
|
10
|
-
import { rethrowIfTestIsolationError } from "../../core/errors.js";
|
|
9
|
+
import { loadConfig } from "../../core/config/config.js";
|
|
10
|
+
import { ConfigError, rethrowIfTestIsolationError } from "../../core/errors.js";
|
|
11
11
|
import { appendEvent, readEvents } from "../../core/events.js";
|
|
12
12
|
import { openStateDatabase, withStateDb } from "../../core/state-db.js";
|
|
13
13
|
import { info, warn } from "../../core/warn.js";
|
|
14
14
|
import { closeDatabase, getRetrievalCounts, getZeroResultSearches, openExistingDatabase } from "../../indexer/db/db.js";
|
|
15
15
|
import { countUsageEventsByType } from "../../indexer/usage/usage-events.js";
|
|
16
|
+
import { materializeLlmRunnerConnection } from "../../integrations/agent/runner.js";
|
|
16
17
|
import { getAvailableHarnesses } from "../../integrations/session-logs/index.js";
|
|
17
18
|
import { withLlmStage } from "../../llm/usage-telemetry.js";
|
|
18
19
|
import { persistPhaseThreshold } from "../../storage/repositories/improve-runs-repository.js";
|
|
@@ -27,7 +28,6 @@ import { buildLatestFeedbackTsMap, buildLatestProposalTsMap, buildUtilityMap, de
|
|
|
27
28
|
import { akmExtract, countNewExtractCandidates } from "./extract.js";
|
|
28
29
|
import { computeValenceScore, FEEDBACK_WEIGHT, UTILITY_WEIGHT } from "./feedback-valence.js";
|
|
29
30
|
import { makeGateConfig, resolveExtractConfidence, runAutoAcceptGate } from "./improve-auto-accept.js";
|
|
30
|
-
import { resolveProcessEnabled } from "./improve-profiles.js";
|
|
31
31
|
import { applyMemoryCleanup } from "./memory/memory-improve.js";
|
|
32
32
|
import { computeProxyAdequacy, getAllAssetOutcomes, getOutcomeScoresByRef, OUTCOME_SCORE_MAX, outcomeScoreToSalience, updateAssetOutcome, } from "./outcome-loop.js";
|
|
33
33
|
import { DEFAULT_DUE_DAYS, DEFAULT_MAX_PER_RUN, selectProactiveMaintenanceRefs } from "./proactive-maintenance.js";
|
|
@@ -151,36 +151,12 @@ export function maybeAutoTuneThreshold(currentThreshold, config, stateDbPath, ct
|
|
|
151
151
|
* need, so the fix is non-invasive and provably correct.
|
|
152
152
|
*/
|
|
153
153
|
export async function runConsolidationPass(args) {
|
|
154
|
-
const { options, primaryStashDir, memorySummary, improveProfile, eventsCtx, budgetSignal, runBudgetMs } = args;
|
|
154
|
+
const { options, primaryStashDir, memorySummary, improveProfile, resolvedPlan, eventsCtx, budgetSignal, runBudgetMs, } = args;
|
|
155
155
|
const baseConfig = options.config ?? loadConfig();
|
|
156
156
|
const MEMORY_VOLUME_THRESHOLD = options.memoryVolumeConsolidationThreshold ?? 100;
|
|
157
|
-
const hasLlm =
|
|
157
|
+
const hasLlm = resolvedPlan.processes.consolidate.runner !== null;
|
|
158
158
|
const volumeTriggered = typeof memorySummary.eligible === "number" && memorySummary.eligible > MEMORY_VOLUME_THRESHOLD && hasLlm;
|
|
159
|
-
|
|
160
|
-
// process on the default improve profile so the gate accepts the run even
|
|
161
|
-
// if the user's config disabled it. We synthesise a new profile override
|
|
162
|
-
// rather than mutating connection settings.
|
|
163
|
-
const consolidationConfig = volumeTriggered
|
|
164
|
-
? {
|
|
165
|
-
...baseConfig,
|
|
166
|
-
profiles: {
|
|
167
|
-
...(baseConfig.profiles ?? {}),
|
|
168
|
-
improve: {
|
|
169
|
-
...(baseConfig.profiles?.improve ?? {}),
|
|
170
|
-
default: {
|
|
171
|
-
...(baseConfig.profiles?.improve?.default ?? {}),
|
|
172
|
-
processes: {
|
|
173
|
-
...(baseConfig.profiles?.improve?.default?.processes ?? {}),
|
|
174
|
-
consolidate: {
|
|
175
|
-
...(baseConfig.profiles?.improve?.default?.processes?.consolidate ?? {}),
|
|
176
|
-
enabled: true,
|
|
177
|
-
},
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
},
|
|
181
|
-
},
|
|
182
|
-
}
|
|
183
|
-
: baseConfig;
|
|
159
|
+
const consolidationConfig = baseConfig;
|
|
184
160
|
// 0.8.0 pool-delta gate for consolidate: re-eligible iff at least one
|
|
185
161
|
// memory file has been updated since the most recent successful
|
|
186
162
|
// consolidate_completed event. Time-based cooldowns produced the same
|
|
@@ -323,6 +299,9 @@ export async function runConsolidationPass(args) {
|
|
|
323
299
|
// Active profile for this improve run — lets consolidate's secondary
|
|
324
300
|
// process-config reads honor `--profile <name>` instead of `default`.
|
|
325
301
|
improveProfile,
|
|
302
|
+
llmConfig: resolvedPlan.processes.consolidate.runner
|
|
303
|
+
? materializeLlmRunnerConnection(resolvedPlan.processes.consolidate.runner)
|
|
304
|
+
: null,
|
|
326
305
|
autoTriggered: volumeTriggered,
|
|
327
306
|
// Tie consolidate proposals back to this improve invocation so
|
|
328
307
|
// accept-rate-per-run aggregation works. Mirrors reflect/propose/extract.
|
|
@@ -357,7 +336,7 @@ export async function runConsolidationPass(args) {
|
|
|
357
336
|
// WS-5: pass total run budget so perfTelemetry.estimatedBudgetFractionUsed
|
|
358
337
|
// can flag when consolidation alone exceeded the budget.
|
|
359
338
|
runBudgetMs,
|
|
360
|
-
}));
|
|
339
|
+
}), { engine: resolvedPlan.processes.consolidate.runner?.engine, process: "consolidate" });
|
|
361
340
|
{
|
|
362
341
|
const consolidateGr = await runAutoAcceptGate(consolidation.promoted.map((proposalId) => {
|
|
363
342
|
try {
|
|
@@ -422,7 +401,7 @@ export async function runConsolidationPass(args) {
|
|
|
422
401
|
* consolidation pass and accumulated here.
|
|
423
402
|
*/
|
|
424
403
|
async function runSessionExtractPass(args) {
|
|
425
|
-
const { options, primaryStashDir, improveProfile, eventsCtx, seedGateAccepted, seedGateFailed } = args;
|
|
404
|
+
const { options, primaryStashDir, improveProfile, resolvedPlan, eventsCtx, seedGateAccepted, seedGateFailed } = args;
|
|
426
405
|
const warnings = [];
|
|
427
406
|
// Phase 0.4 — session-extract pass.
|
|
428
407
|
//
|
|
@@ -476,11 +455,22 @@ async function runSessionExtractPass(args) {
|
|
|
476
455
|
// #593/#594: the ACTIVE resolved improve profile is the single source of
|
|
477
456
|
// truth for whether extract runs. (Previously this also ANDed in the legacy
|
|
478
457
|
// `session_extraction` feature flag, which only reads
|
|
479
|
-
//
|
|
480
|
-
// profile a global kill switch, so a non-default profile enabling extract was
|
|
481
|
-
// silently overridden. The default profile is now just another profile.)
|
|
458
|
+
// a retired global feature path; the selected strategy is authoritative.)
|
|
482
459
|
// `akmExtract` re-checks the same active profile internally via `improveProfile`.
|
|
483
|
-
if (
|
|
460
|
+
if (resolvedPlan.processes.extract.enabled) {
|
|
461
|
+
const extractRunner = resolvedPlan.processes.extract.runner;
|
|
462
|
+
if (!extractRunner?.engine) {
|
|
463
|
+
throw new ConfigError("Resolved improve plan has no runner for enabled extract process.", "LLM_NOT_CONFIGURED");
|
|
464
|
+
}
|
|
465
|
+
const extractPlan = Object.freeze({
|
|
466
|
+
strategy: resolvedPlan.strategy.name,
|
|
467
|
+
engine: extractRunner.engine,
|
|
468
|
+
enabled: true,
|
|
469
|
+
process: resolvedPlan.processes.extract.config,
|
|
470
|
+
runner: extractRunner,
|
|
471
|
+
timeoutMs: extractRunner.timeoutMs === undefined ? 600_000 : extractRunner.timeoutMs,
|
|
472
|
+
embeddingConfig: Object.freeze(structuredClone(extractConfig.embedding)),
|
|
473
|
+
});
|
|
484
474
|
const availableHarnesses = options.extractHarnesses ?? getAvailableHarnesses();
|
|
485
475
|
// The guard engages only when minNewSessions > 0; 0 disables it entirely.
|
|
486
476
|
let belowMinNewSessions = false;
|
|
@@ -521,14 +511,12 @@ async function runSessionExtractPass(args) {
|
|
|
521
511
|
type: h.name,
|
|
522
512
|
...(primaryStashDir !== undefined ? { stashDir: primaryStashDir } : {}),
|
|
523
513
|
config: extractConfig,
|
|
524
|
-
|
|
525
|
-
// config read the running profile, not always `default`.
|
|
526
|
-
improveProfile,
|
|
514
|
+
resolvedPlan: extractPlan,
|
|
527
515
|
dryRun: options.dryRun ?? false,
|
|
528
516
|
...(options.extractHarnesses ? { harnesses: options.extractHarnesses } : {}),
|
|
529
517
|
// C2: pin extract's skip-tracking state.db open to the boundary path.
|
|
530
518
|
...(eventsCtx?.dbPath ? { stateDbPath: eventsCtx.dbPath } : {}),
|
|
531
|
-
}));
|
|
519
|
+
}), { engine: resolvedPlan.processes.extract.runner?.engine, process: "extract" });
|
|
532
520
|
extractResults.push(result);
|
|
533
521
|
{
|
|
534
522
|
const gr = await runAutoAcceptGate(primaryStashDir
|
|
@@ -577,49 +565,47 @@ async function runSessionExtractPass(args) {
|
|
|
577
565
|
* with structural problems (missing file, missing lesson description), attempts
|
|
578
566
|
* LLM schema repair, and returns the still-failing ref set + the repair records.
|
|
579
567
|
*/
|
|
580
|
-
async function runValidationAndRepairPass(args) {
|
|
581
|
-
const { postCleanupRefs, options, startMs, budgetMs, primaryStashDir } = args;
|
|
582
|
-
const
|
|
583
|
-
for (const candidate of postCleanupRefs) {
|
|
568
|
+
export async function runValidationAndRepairPass(args) {
|
|
569
|
+
const { postCleanupRefs, options, startMs, budgetMs, primaryStashDir, resolvedPlan, repairValidationFailures, schemaRepairFn = runSchemaRepairPass, } = args;
|
|
570
|
+
const validateCandidate = async (candidate) => {
|
|
584
571
|
try {
|
|
585
|
-
// #591: use the path pre-resolved at planning time when it is still on
|
|
586
|
-
// disk — a serial async DB lookup per ref cost ~500 s on a 9 000-ref
|
|
587
|
-
// stash. Fall back to findAssetFilePath only for refs that bypassed
|
|
588
|
-
// collectEligibleRefs' index scan or whose file moved since planning.
|
|
589
572
|
const filePath = candidate.filePath && fs.existsSync(candidate.filePath)
|
|
590
573
|
? candidate.filePath
|
|
591
574
|
: await findAssetFilePath(candidate.ref, options.stashDir);
|
|
592
|
-
if (!filePath)
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
if (path.extname(filePath).toLowerCase() !== ".md") {
|
|
597
|
-
continue;
|
|
598
|
-
}
|
|
575
|
+
if (!filePath)
|
|
576
|
+
return "file not found on disk";
|
|
577
|
+
if (path.extname(filePath).toLowerCase() !== ".md")
|
|
578
|
+
return undefined;
|
|
599
579
|
if (isLessonCandidate(candidate.ref)) {
|
|
600
|
-
const
|
|
601
|
-
const fm = parseFrontmatter(raw).data;
|
|
580
|
+
const fm = parseFrontmatter(fs.readFileSync(filePath, "utf8")).data;
|
|
602
581
|
if (!fm.description)
|
|
603
|
-
|
|
582
|
+
return "missing description";
|
|
604
583
|
}
|
|
584
|
+
return undefined;
|
|
605
585
|
}
|
|
606
|
-
catch (
|
|
607
|
-
|
|
586
|
+
catch (error) {
|
|
587
|
+
return String(error);
|
|
608
588
|
}
|
|
589
|
+
};
|
|
590
|
+
const validationFailures = [];
|
|
591
|
+
for (const candidate of postCleanupRefs) {
|
|
592
|
+
const reason = await validateCandidate(candidate);
|
|
593
|
+
if (reason)
|
|
594
|
+
validationFailures.push({ ref: candidate.ref, reason });
|
|
609
595
|
}
|
|
610
596
|
if (validationFailures.length > 0) {
|
|
611
|
-
info(`[improve] ${validationFailures.length} assets have validation issues (will attempt schema repair):`);
|
|
597
|
+
info(`[improve] ${validationFailures.length} assets have validation issues${repairValidationFailures ? " (will attempt schema repair)" : ""}:`);
|
|
612
598
|
for (const f of validationFailures)
|
|
613
599
|
info(` ${f.ref}: ${f.reason}`);
|
|
614
600
|
}
|
|
615
601
|
let schemaRepairs = [];
|
|
616
|
-
|
|
602
|
+
const repairedRefs = new Set();
|
|
617
603
|
// Schema repair pass: attempt to fix validation failures via LLM before skipping.
|
|
618
|
-
if (validationFailures.length > 0
|
|
619
|
-
const
|
|
620
|
-
const llmCfg =
|
|
604
|
+
if (validationFailures.length > 0) {
|
|
605
|
+
const validationRunner = resolvedPlan.processes.validation.runner;
|
|
606
|
+
const llmCfg = validationRunner ? materializeLlmRunnerConnection(validationRunner) : undefined;
|
|
621
607
|
if (llmCfg) {
|
|
622
|
-
const result = await
|
|
608
|
+
const result = await withLlmStage("validation", () => schemaRepairFn(validationFailures, {
|
|
623
609
|
startMs,
|
|
624
610
|
budgetMs,
|
|
625
611
|
llmConfig: llmCfg,
|
|
@@ -633,9 +619,17 @@ async function runValidationAndRepairPass(args) {
|
|
|
633
619
|
stashDir: primaryStashDir,
|
|
634
620
|
findFilePath: findAssetFilePath,
|
|
635
621
|
isLessonCandidateFn: isLessonCandidate,
|
|
636
|
-
});
|
|
622
|
+
}), { engine: resolvedPlan.processes.validation.runner?.engine, process: "validation" });
|
|
637
623
|
schemaRepairs = result.repairs;
|
|
638
|
-
|
|
624
|
+
// A repair result is advisory. Only a fresh structural read of the live
|
|
625
|
+
// asset can remove it from the failure set; queued content is not live.
|
|
626
|
+
const failedRefs = new Set(validationFailures.map((failure) => failure.ref));
|
|
627
|
+
const candidatesByRef = new Map(postCleanupRefs.map((candidate) => [candidate.ref, candidate]));
|
|
628
|
+
for (const ref of failedRefs) {
|
|
629
|
+
const candidate = candidatesByRef.get(ref);
|
|
630
|
+
if (candidate && !(await validateCandidate(candidate)))
|
|
631
|
+
repairedRefs.add(ref);
|
|
632
|
+
}
|
|
639
633
|
}
|
|
640
634
|
}
|
|
641
635
|
const validationFailureRefs = new Set(validationFailures.filter((f) => !repairedRefs.has(f.ref)).map((f) => f.ref));
|
|
@@ -645,7 +639,7 @@ async function runValidationAndRepairPass(args) {
|
|
|
645
639
|
return { validationFailures, validationFailureRefs, schemaRepairs };
|
|
646
640
|
}
|
|
647
641
|
export async function runImprovePreparationStage(args) {
|
|
648
|
-
const { scope, options, plannedRefs, memoryCleanupPlan, primaryStashDir, memorySummary, reindexFn, startMs, budgetMs, eventsCtx, initialCleanupWarnings, improveProfile, budgetSignal, } = args;
|
|
642
|
+
const { scope, options, plannedRefs, memoryCleanupPlan, primaryStashDir, memorySummary, reindexFn, startMs, budgetMs, eventsCtx, initialCleanupWarnings, improveProfile, resolvedPlan, strategyName, budgetSignal, } = args;
|
|
649
643
|
const actions = [];
|
|
650
644
|
const cleanupWarnings = initialCleanupWarnings ? [...initialCleanupWarnings] : [];
|
|
651
645
|
// Phase 0 — MEMORY.md budget check (200-line cap; warn at 180)
|
|
@@ -681,6 +675,7 @@ export async function runImprovePreparationStage(args) {
|
|
|
681
675
|
primaryStashDir,
|
|
682
676
|
memorySummary,
|
|
683
677
|
improveProfile,
|
|
678
|
+
resolvedPlan,
|
|
684
679
|
eventsCtx,
|
|
685
680
|
budgetSignal,
|
|
686
681
|
runBudgetMs: budgetMs,
|
|
@@ -690,6 +685,7 @@ export async function runImprovePreparationStage(args) {
|
|
|
690
685
|
options,
|
|
691
686
|
primaryStashDir,
|
|
692
687
|
improveProfile,
|
|
688
|
+
resolvedPlan,
|
|
693
689
|
eventsCtx,
|
|
694
690
|
seedGateAccepted: consolidationPass.gateAutoAcceptedCount,
|
|
695
691
|
seedGateFailed: consolidationPass.gateAutoAcceptFailedCount,
|
|
@@ -704,7 +700,7 @@ export async function runImprovePreparationStage(args) {
|
|
|
704
700
|
appendEvent({
|
|
705
701
|
eventType: "improve_invoked",
|
|
706
702
|
ref: scope.mode === "ref" ? scope.value : `improve:${scope.mode}:${scope.value ?? "all"}`,
|
|
707
|
-
metadata: { scope, dryRun: options.dryRun ?? false, eligibleCount: plannedRefs.length },
|
|
703
|
+
metadata: { strategy: strategyName, scope, dryRun: options.dryRun ?? false, eligibleCount: plannedRefs.length },
|
|
708
704
|
}, eventsCtx);
|
|
709
705
|
// ensureIndex now runs in akmImprove() BEFORE collectEligibleRefs so the
|
|
710
706
|
// eligible-ref query sees a populated `entries` table on the very first
|
|
@@ -751,6 +747,8 @@ export async function runImprovePreparationStage(args) {
|
|
|
751
747
|
startMs,
|
|
752
748
|
budgetMs,
|
|
753
749
|
primaryStashDir,
|
|
750
|
+
resolvedPlan,
|
|
751
|
+
repairValidationFailures: resolvedPlan.processes.validation.enabled && options.repairValidationFailures !== false,
|
|
754
752
|
});
|
|
755
753
|
// Phase 0.5 — structural hygiene pass
|
|
756
754
|
let lintSummary;
|
|
@@ -892,7 +890,7 @@ export async function runImprovePreparationStage(args) {
|
|
|
892
890
|
// Has feedback on record but no signal delta since the last proposal —
|
|
893
891
|
// genuinely fully skipped. Counted here; a single aggregated
|
|
894
892
|
// improve_skipped event is emitted after the loop (mirrors
|
|
895
|
-
//
|
|
893
|
+
// strategy_filtered_all_passes) instead of one event per ref.
|
|
896
894
|
fullySkippedCount++;
|
|
897
895
|
actions.push({
|
|
898
896
|
ref: r.ref,
|
|
@@ -903,7 +901,7 @@ export async function runImprovePreparationStage(args) {
|
|
|
903
901
|
}
|
|
904
902
|
// Emit ONE aggregated skip event for the fully-skipped bucket rather than one
|
|
905
903
|
// improve_skipped event per ref (#592 pattern, mirrors
|
|
906
|
-
//
|
|
904
|
+
// strategy_filtered_all_passes above). The per-ref loop previously produced
|
|
907
905
|
// ~11K state.db writes per run on a large stash, the dominant contributor to
|
|
908
906
|
// 900 s timeouts. The in-memory `actions` log keeps the per-ref detail for the
|
|
909
907
|
// run summary; no downstream consumer needs a per-ref DB audit trail (health's
|
|
@@ -1063,7 +1061,7 @@ export async function runImprovePreparationStage(args) {
|
|
|
1063
1061
|
// runs rotate through the due pool rather than re-selecting the same heads.
|
|
1064
1062
|
let proactiveRefs = [];
|
|
1065
1063
|
let proactiveMaintenanceSummary;
|
|
1066
|
-
const proactiveEnabled = scope.mode !== "ref" &&
|
|
1064
|
+
const proactiveEnabled = scope.mode !== "ref" && resolvedPlan.processes.proactiveMaintenance.enabled;
|
|
1067
1065
|
if (proactiveEnabled) {
|
|
1068
1066
|
const pmCfg = improveProfile.processes?.proactiveMaintenance;
|
|
1069
1067
|
const dueDays = pmCfg?.dueDays ?? DEFAULT_DUE_DAYS;
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* #615 — procedural-compilation pass.
|
|
6
6
|
*
|
|
7
|
-
* An OPT-IN post-loop improve stage (default
|
|
8
|
-
* `
|
|
7
|
+
* An OPT-IN post-loop improve stage (the built-in default strategy sets
|
|
8
|
+
* `processes.procedural.enabled: false`). It reads assets that carry an
|
|
9
9
|
* `orderedActions` frontmatter list (captured by #619), detects RECURRING
|
|
10
10
|
* successful action sequences across sessions (the SAME normalized ordered step
|
|
11
11
|
* list appearing >= `minRecurrence` times with a non-failure `outcomeData`), and
|
|
@@ -293,6 +293,7 @@ export async function akmProcedural(opts) {
|
|
|
293
293
|
tag: "[procedural]",
|
|
294
294
|
signal: opts.signal,
|
|
295
295
|
activeProfile: opts.improveProfile,
|
|
296
|
+
llmConfig: opts.llmConfig,
|
|
296
297
|
});
|
|
297
298
|
if (!llmFn) {
|
|
298
299
|
warnings.push("procedural: no LLM configured — skipping");
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* #609 — recombine / synthesize pass.
|
|
6
6
|
*
|
|
7
7
|
* A whole-corpus synthesis stage that runs AFTER consolidation and is OPT-IN
|
|
8
|
-
* (default
|
|
8
|
+
* (the built-in default strategy sets `processes.recombine.enabled: false`). It clusters
|
|
9
9
|
* memories by RELATEDNESS (shared tags / graph entities — NEVER embedding
|
|
10
10
|
* similarity), issues ONE bounded LLM call per cluster to induce a single
|
|
11
11
|
* cross-episodic generalization, and emits the result as a NORMAL pending
|
|
@@ -554,6 +554,7 @@ export async function akmRecombine(opts) {
|
|
|
554
554
|
tag: "[recombine]",
|
|
555
555
|
signal: opts.signal,
|
|
556
556
|
activeProfile: opts.improveProfile,
|
|
557
|
+
llmConfig: opts.llmConfig,
|
|
557
558
|
});
|
|
558
559
|
if (!llmFn) {
|
|
559
560
|
warnings.push("recombine: no LLM configured — skipping");
|