akm-cli 0.9.0-beta.9 → 0.9.0-rc.1
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 +715 -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/prompts/workflow-unit-preamble.md +26 -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 -21
- 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-binding.js +95 -0
- package/dist/commands/env/env-cli.js +228 -292
- package/dist/commands/env/env.js +14 -67
- package/dist/commands/env/secret-cli.js +140 -138
- package/dist/commands/feedback-cli.js +156 -155
- package/dist/commands/graph/graph-cli.js +5 -13
- package/dist/commands/graph/graph.js +3 -3
- 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 -1091
- 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 +1295 -1277
- 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 +228 -605
- 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 +54 -3
- 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 +157 -10
- package/dist/commands/improve/improve-cli.js +115 -73
- package/dist/commands/improve/improve-profiles.js +28 -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 +485 -2764
- 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 +37 -35
- 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 +206 -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 +2 -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 -895
- package/dist/commands/read/curate.js +410 -111
- 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/migration-help.js +7 -4
- 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 +19 -39
- 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 +291 -13
- package/dist/core/asset/asset-registry.js +3 -1
- package/dist/core/asset/asset-spec.js +79 -5
- 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 +403 -62
- 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/json-schema.js +142 -0
- package/dist/core/logs-db.js +14 -75
- package/dist/core/parse.js +36 -16
- package/dist/core/paths.js +18 -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 +132 -1126
- 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 +261 -770
- 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 +36 -92
- 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 +18 -11
- package/dist/indexer/index-written-assets.js +105 -0
- package/dist/indexer/indexer.js +182 -204
- 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 +48 -0
- package/dist/indexer/walk/walker.js +21 -13
- package/dist/integrations/agent/builders.js +41 -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 +16 -2
- package/dist/integrations/agent/profiles.js +79 -6
- package/dist/integrations/agent/prompts.js +75 -9
- package/dist/integrations/agent/runner-dispatch.js +83 -0
- package/dist/integrations/agent/runner.js +13 -9
- package/dist/integrations/agent/spawn.js +206 -81
- package/dist/integrations/harnesses/aider/agent-builder.js +113 -0
- package/dist/integrations/harnesses/aider/index.js +58 -0
- package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
- package/dist/integrations/harnesses/amazonq/agent-builder.js +153 -0
- package/dist/integrations/harnesses/amazonq/index.js +59 -0
- package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
- package/dist/integrations/harnesses/claude/agent-builder.js +46 -7
- package/dist/integrations/harnesses/claude/index.js +27 -23
- package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
- package/dist/integrations/harnesses/claude/session-log.js +10 -0
- package/dist/integrations/harnesses/codex/agent-builder.js +137 -0
- package/dist/integrations/harnesses/codex/index.js +63 -0
- package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
- package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
- package/dist/integrations/harnesses/copilot/index.js +60 -0
- package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
- package/dist/integrations/harnesses/gemini/agent-builder.js +121 -0
- package/dist/integrations/harnesses/gemini/index.js +60 -0
- package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
- package/dist/integrations/harnesses/index.js +28 -7
- package/dist/integrations/harnesses/opencode/agent-builder.js +1 -1
- package/dist/integrations/harnesses/opencode/index.js +17 -16
- package/dist/integrations/harnesses/opencode/session-log.js +173 -3
- package/dist/integrations/harnesses/opencode-sdk/harness.js +65 -0
- package/dist/integrations/harnesses/opencode-sdk/index.js +10 -34
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +642 -71
- package/dist/integrations/harnesses/openhands/agent-builder.js +126 -0
- package/dist/integrations/harnesses/openhands/index.js +58 -0
- package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
- package/dist/integrations/harnesses/pi/agent-builder.js +104 -0
- package/dist/integrations/harnesses/pi/index.js +58 -0
- package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
- package/dist/integrations/harnesses/types.js +8 -0
- package/dist/integrations/session-logs/index.js +40 -11
- package/dist/llm/call-ai.js +2 -2
- package/dist/llm/client.js +34 -11
- 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 +87 -15
- package/dist/output/shapes/curate.js +14 -2
- package/dist/output/shapes/helpers.js +0 -3
- package/dist/output/shapes/passthrough.js +6 -1
- package/dist/output/text/helpers.js +241 -2
- package/dist/output/text/workflow.js +4 -1
- 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/schemas/akm-config.json +14225 -0
- package/dist/schemas/akm-workflow.json +328 -0
- package/dist/scripts/migrate-storage.js +2743 -8390
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +1652 -607
- 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/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/repositories/workflow-runs-repository.js +189 -1
- 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 +1 -1
- package/dist/wiki/wiki.js +52 -11
- package/dist/workflows/authoring/authoring.js +123 -10
- package/dist/workflows/authoring/workflow-program-template.yaml +31 -0
- package/dist/workflows/cli.js +5 -0
- package/dist/workflows/db.js +138 -4
- package/dist/workflows/exec/brief.js +484 -0
- package/dist/workflows/exec/native-executor.js +975 -0
- package/dist/workflows/exec/param-secrets.js +115 -0
- package/dist/workflows/exec/report.js +1295 -0
- package/dist/workflows/exec/run-workflow.js +596 -0
- package/dist/workflows/exec/scheduler.js +100 -0
- package/dist/workflows/exec/step-work.js +1156 -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 +388 -0
- package/dist/workflows/ir/params.js +54 -0
- package/dist/workflows/ir/plan-hash.js +33 -0
- package/dist/workflows/ir/schema.js +4 -0
- package/dist/workflows/parser.js +3 -1
- package/dist/workflows/program/expressions.js +369 -0
- package/dist/workflows/program/parser.js +760 -0
- package/dist/workflows/program/project.js +105 -0
- package/dist/workflows/program/schema.js +54 -0
- package/dist/workflows/renderer.js +82 -5
- package/dist/workflows/runtime/agent-identity.js +59 -14
- package/dist/workflows/runtime/runs.js +248 -153
- package/dist/workflows/runtime/unit-checkin.js +45 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +188 -0
- package/dist/workflows/validate-summary.js +26 -10
- package/dist/workflows/validator.js +1 -1
- package/docs/README.md +69 -18
- package/docs/data-and-telemetry.md +7 -5
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.9.0-beta.60.md +19 -0
- 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
|
@@ -22,8 +22,14 @@
|
|
|
22
22
|
* - Two exceptions (hard-rejected): openviking source type and legacy
|
|
23
23
|
* `stashes[]` key. Both have explicit migration paths; silently dropping
|
|
24
24
|
* would mask user data loss.
|
|
25
|
-
* -
|
|
26
|
-
*
|
|
25
|
+
* - UNKNOWN-KEY POLICY: object schemas use passthrough (unknown keys are
|
|
26
|
+
* preserved and ignored, NOT rejected). akm runs across multiple installed
|
|
27
|
+
* versions sharing one config.json; a newer version writes keys an older
|
|
28
|
+
* version's schema doesn't know yet, so hard-rejecting unknown keys turned
|
|
29
|
+
* benign version skew into `INVALID_CONFIG_FILE` failures. Known keys are
|
|
30
|
+
* still type-checked; passthrough preserves unknown keys across a
|
|
31
|
+
* load→save round trip so an older reader never strips a newer writer's
|
|
32
|
+
* settings. (Replaced the prior strict-mode object walls.)
|
|
27
33
|
* - `defaultWriteTarget` resolution and similar cross-field invariants are
|
|
28
34
|
* enforced at save time via `superRefine` on the top-level schema.
|
|
29
35
|
*/
|
|
@@ -43,14 +49,27 @@ const nonEmptyString = z
|
|
|
43
49
|
const httpUrl = z.string().refine((v) => v.startsWith("http://") || v.startsWith("https://"), {
|
|
44
50
|
message: "endpoint must start with http:// or https://",
|
|
45
51
|
});
|
|
46
|
-
// ── Feedback failure modes
|
|
47
|
-
|
|
52
|
+
// ── Feedback failure modes (F-3 / #384) ─────────────────────────────────────
|
|
53
|
+
/**
|
|
54
|
+
* Curated taxonomy of failure modes for negative feedback.
|
|
55
|
+
*
|
|
56
|
+
* Structured failure modes enable aggregation across feedback events so the
|
|
57
|
+
* distill pipeline can detect that "5 assets failed for the same reason" and
|
|
58
|
+
* act on it — free-text strings about the same issue are not aggregatable.
|
|
59
|
+
*/
|
|
60
|
+
export const FEEDBACK_FAILURE_MODES = [
|
|
61
|
+
"incorrect", // Factually wrong or logically flawed content
|
|
62
|
+
"outdated", // Correct at some point but now stale
|
|
63
|
+
"dangerous", // Could cause harm if followed (security, safety)
|
|
64
|
+
"incomplete", // Missing key steps, context, or caveats
|
|
65
|
+
"redundant", // Duplicates another asset without adding value
|
|
66
|
+
];
|
|
48
67
|
// ── Connection configs (LLM / embedding) ────────────────────────────────────
|
|
49
68
|
const LlmCapabilitiesSchema = z
|
|
50
69
|
.object({
|
|
51
70
|
structuredOutput: z.boolean().optional(),
|
|
52
71
|
})
|
|
53
|
-
.
|
|
72
|
+
.passthrough();
|
|
54
73
|
/**
|
|
55
74
|
* Connection config used for both top-level `llm` (after migration) and
|
|
56
75
|
* `profiles.llm[*]`. `model` is required at schema level — partial entries
|
|
@@ -75,15 +94,15 @@ export const LlmConnectionConfigSchema = z
|
|
|
75
94
|
judgeModel: z.string().min(1).optional(),
|
|
76
95
|
enableThinking: z.boolean().optional(),
|
|
77
96
|
})
|
|
78
|
-
.
|
|
97
|
+
.passthrough();
|
|
79
98
|
export const LlmProfileConfigSchema = LlmConnectionConfigSchema.extend({
|
|
80
99
|
supportsJsonSchema: z.boolean().optional(),
|
|
81
|
-
}).
|
|
100
|
+
}).passthrough();
|
|
82
101
|
const EmbeddingOllamaOptionsSchema = z
|
|
83
102
|
.object({
|
|
84
103
|
num_ctx: positiveInt.optional(),
|
|
85
104
|
})
|
|
86
|
-
.
|
|
105
|
+
.passthrough();
|
|
87
106
|
/**
|
|
88
107
|
* Embedding connection config. Both `endpoint` and `model` are optional:
|
|
89
108
|
* - Remote: provide `endpoint` (http/https URL) + `model`.
|
|
@@ -107,7 +126,7 @@ export const EmbeddingConnectionConfigSchema = z
|
|
|
107
126
|
contextLength: positiveInt.optional(),
|
|
108
127
|
ollamaOptions: EmbeddingOllamaOptionsSchema.optional(),
|
|
109
128
|
})
|
|
110
|
-
.
|
|
129
|
+
.passthrough();
|
|
111
130
|
// ── Agent profiles ──────────────────────────────────────────────────────────
|
|
112
131
|
// Derives from the canonical VALID_HARNESS_IDS (#565) so the Zod gate cannot
|
|
113
132
|
// drift from the TS union / parse check / setup detection.
|
|
@@ -119,8 +138,17 @@ export const AgentProfileConfigSchema = z
|
|
|
119
138
|
args: z.array(z.string()).optional(),
|
|
120
139
|
workspace: z.string().min(1).optional(),
|
|
121
140
|
model: z.string().min(1).optional(),
|
|
141
|
+
// Per-call timeout (ms) used when a command does not pass an explicit
|
|
142
|
+
// timeout (e.g. `akm wiki ingest` without `--timeout-ms`). null = no
|
|
143
|
+
// timeout. Honored by resolveAgentProfile (integrations/agent/config.ts).
|
|
144
|
+
timeoutMs: z.union([positiveInt, z.null()]).optional(),
|
|
145
|
+
// Per-profile model aliases: lowercase alias → exact model string for
|
|
146
|
+
// this profile's CLI. Highest-precedence tier in resolveModel
|
|
147
|
+
// (integrations/agent/model-aliases.ts) — beats the config-root
|
|
148
|
+
// `modelAliases` table and the built-in opus/sonnet/haiku entries.
|
|
149
|
+
modelAliases: z.record(z.string().min(1), z.string().min(1)).optional(),
|
|
122
150
|
})
|
|
123
|
-
.
|
|
151
|
+
.passthrough();
|
|
124
152
|
// ── Improve profile / process ──────────────────────────────────────────────
|
|
125
153
|
export const ImproveProcessConfigSchema = z
|
|
126
154
|
.object({
|
|
@@ -133,8 +161,39 @@ export const ImproveProcessConfigSchema = z
|
|
|
133
161
|
// consolidation pass skips entirely (emits `pool_below_min_size`). 0 disables
|
|
134
162
|
// the guard. Only meaningful on the `consolidate` process. Default 500.
|
|
135
163
|
minPoolSize: z.number().int().min(0).optional(),
|
|
136
|
-
|
|
137
|
-
|
|
164
|
+
// Consolidate process: deterministic near-duplicate dedup pre-pass (#617).
|
|
165
|
+
// A cheap, no-LLM fast path that collapses obvious duplicates (`.derived`
|
|
166
|
+
// origin pairs + content twins) before the LLM consolidation. Default OFF
|
|
167
|
+
// — when absent the consolidate pass behaves byte-identically to today.
|
|
168
|
+
// `cosineThreshold` is a strict floor in [0, 1] (default 0.97) for the
|
|
169
|
+
// optional embedding-similarity match; exact normalized content-hash
|
|
170
|
+
// equality always collapses regardless of the threshold. Only meaningful
|
|
171
|
+
// on the `consolidate` process.
|
|
172
|
+
dedup: z
|
|
173
|
+
.object({
|
|
174
|
+
enabled: z.boolean().optional(),
|
|
175
|
+
cosineThreshold: z.number().min(0).max(1).optional(),
|
|
176
|
+
// WS-3a: maximum pool size for the O(n²) cosine-similarity twin compare.
|
|
177
|
+
// Only the first `cosineCandidateLimit` memories are cosine-compared;
|
|
178
|
+
// exact-hash matches still run over the full pool. Default 500. Raise
|
|
179
|
+
// with care — cost is O(n²).
|
|
180
|
+
cosineCandidateLimit: z.number().int().positive().optional(),
|
|
181
|
+
})
|
|
182
|
+
.passthrough()
|
|
183
|
+
.optional(),
|
|
184
|
+
// Consolidate process: judged-state cache (#581). When enabled, a memory
|
|
185
|
+
// whose current content hash equals its cached judged hash is SKIPPED from
|
|
186
|
+
// the LLM pool (judged-unchanged → no re-judge), letting one run sweep the
|
|
187
|
+
// whole corpus at O(changed/new) cost instead of narrowing to a recent
|
|
188
|
+
// time-window slice. Default OFF — when absent the consolidate pass behaves
|
|
189
|
+
// byte-identically to today (the incrementalSince path is unaffected). Only
|
|
190
|
+
// meaningful on the `consolidate` process.
|
|
191
|
+
judgedCache: z.object({ enabled: z.boolean().optional() }).passthrough().optional(),
|
|
192
|
+
// Distill process: LLM-as-judge lesson quality gate. Default ON (R3);
|
|
193
|
+
// fail-open — judge failure/timeout/parse errors pass through. Set
|
|
194
|
+
// `enabled: false` on the distill process to opt out.
|
|
195
|
+
qualityGate: z.object({ enabled: z.boolean().optional() }).passthrough().optional(),
|
|
196
|
+
contradictionDetection: z.object({ enabled: z.boolean().optional() }).passthrough().optional(),
|
|
138
197
|
// Extract process config (only meaningful for extract process)
|
|
139
198
|
defaultSince: z.string().min(1).optional(),
|
|
140
199
|
maxTotalChars: positiveInt.optional(),
|
|
@@ -162,9 +221,28 @@ export const ImproveProcessConfigSchema = z
|
|
|
162
221
|
// proactiveMaintenance process: top-N bound per run (default 25). Alias for
|
|
163
222
|
// `limit`; `maxPerRun` wins when both are set.
|
|
164
223
|
maxPerRun: positiveInt.optional(),
|
|
165
|
-
//
|
|
166
|
-
//
|
|
167
|
-
|
|
224
|
+
// graphExtraction process (#624 P2): when set, rank eligible files by
|
|
225
|
+
// utility_scores DESC and process only the top-N per run (incremental
|
|
226
|
+
// high-signal-first sweep). Unset = process all eligible (current
|
|
227
|
+
// behavior). Only meaningful on `graphExtraction`.
|
|
228
|
+
topN: positiveInt.optional(),
|
|
229
|
+
// graphExtraction process: full-corpus scan. When true, graph extraction
|
|
230
|
+
// runs on ALL stash files instead of only files touched by actionable refs
|
|
231
|
+
// in the current run. Used by the `graph-refresh` built-in profile / a
|
|
232
|
+
// scheduled weekly task. Only meaningful on `graphExtraction`.
|
|
233
|
+
fullScan: z.boolean().optional(),
|
|
234
|
+
// #626 — extract process: pre-LLM heuristic triage gate. When enabled, a
|
|
235
|
+
// deterministic scorer decides BEFORE the extraction LLM call whether a
|
|
236
|
+
// session carries enough signal to be worth extracting; low-signal sessions
|
|
237
|
+
// are skipped at zero LLM cost. Default OFF. Only meaningful on `extract`.
|
|
238
|
+
// `minScore` is the minimum total heuristic score to PASS (default 2).
|
|
239
|
+
triage: z
|
|
240
|
+
.object({
|
|
241
|
+
enabled: z.boolean().optional(),
|
|
242
|
+
minScore: z.number().min(0).optional(),
|
|
243
|
+
})
|
|
244
|
+
.passthrough()
|
|
245
|
+
.optional(),
|
|
168
246
|
// MemoryInference process: minimum pending memory count to run the pass.
|
|
169
247
|
minPendingCount: z.number().int().min(0).optional(),
|
|
170
248
|
// Extract process: minimum number of new (unseen, in-window) candidate
|
|
@@ -173,12 +251,146 @@ export const ImproveProcessConfigSchema = z
|
|
|
173
251
|
// disables the guard. Only meaningful on the `extract` process. Default 0
|
|
174
252
|
// (disabled) so existing behaviour is preserved; only opted-in profiles set it.
|
|
175
253
|
minNewSessions: z.number().int().min(0).optional(),
|
|
254
|
+
// Extract process: cap on NEW sessions processed (LLM-called) per run; the
|
|
255
|
+
// rest roll to the next run (still unseen). 0 disables. Absent = default 25.
|
|
256
|
+
maxSessionsPerRun: z.number().int().min(0).optional(),
|
|
176
257
|
// #561 — index agent sessions as a searchable `session` asset (extract
|
|
177
258
|
// process). Absent = on-when-an-LLM-is-available (fail-open when offline).
|
|
259
|
+
// COST: when on, each processed session makes a SECOND LLM call (the session
|
|
260
|
+
// summary) on top of the extraction call — i.e. ~2 LLM calls/session. Set to
|
|
261
|
+
// false to halve per-session extract cost at the price of unsearchable
|
|
262
|
+
// sessions. (Unchanged/skip sessions still cost zero — the content-hash
|
|
263
|
+
// ledger gates both calls upstream.)
|
|
178
264
|
indexSessions: z.boolean().optional(),
|
|
179
265
|
// #561 — minimum session duration in minutes for session indexing. 0
|
|
180
266
|
// disables the gate. Absent = default 5. Only meaningful on `extract`.
|
|
181
267
|
minSessionDuration: z.number().min(0).optional(),
|
|
268
|
+
// Consolidate process: fallback p90 wall-clock time per consolidation chunk
|
|
269
|
+
// in seconds, used for cold-start budget estimation when no telemetry
|
|
270
|
+
// history exists. The actual p90 is derived from observed run durations
|
|
271
|
+
// once sufficient history accumulates; this value is only used on the very
|
|
272
|
+
// first run. Default 30 s. Only meaningful on the `consolidate` process.
|
|
273
|
+
p90ChunkSecondsDefault: z.number().finite().positive().optional(),
|
|
274
|
+
// (WS-3b step 0a `homeostaticDemotion` was removed — R4. The key is
|
|
275
|
+
// tolerated via passthrough if an old config still carries it; continuous
|
|
276
|
+
// decay is now part of the always-applied salience recency term.)
|
|
277
|
+
// WS-3b: Schema-similarity gate (step 0b). At intake, if a new candidate's
|
|
278
|
+
// body embedding is within epsilon of an existing derived-layer lesson/knowledge
|
|
279
|
+
// node, mark it schema-consistent and lower its priority. Default ON for
|
|
280
|
+
// the `extract` process since R3 (fail-open; set `enabled: false` to opt out).
|
|
281
|
+
// Only meaningful on the `consolidate` and `extract` processes.
|
|
282
|
+
schemaSimilarity: z
|
|
283
|
+
.object({
|
|
284
|
+
enabled: z.boolean().optional(),
|
|
285
|
+
// Epsilon: cosine similarity threshold above which a candidate is schema-consistent
|
|
286
|
+
// (default 0.85 — looser than dedup's 0.97 since we want to catch conceptual overlap).
|
|
287
|
+
epsilon: z.number().min(0).max(1).optional(),
|
|
288
|
+
// Multiplicative factor applied to candidate confidence when schema-consistent.
|
|
289
|
+
// Default 0.5 — halves the confidence so schema-consistent candidates are less likely
|
|
290
|
+
// to pass the quality gate and create redundant stash entries.
|
|
291
|
+
confidencePenalty: z.number().min(0).max(1).optional(),
|
|
292
|
+
})
|
|
293
|
+
.passthrough()
|
|
294
|
+
.optional(),
|
|
295
|
+
// WS-3b: Hot-probation intake buffer (step 0c, #604). New system-generated
|
|
296
|
+
// extractions enter captureMode: hot-probation and spend ONE consolidation
|
|
297
|
+
// cycle in probation. Dedup + quality second-pass runs before promotion.
|
|
298
|
+
// Default OFF. Only meaningful on the `extract` process.
|
|
299
|
+
hotProbation: z
|
|
300
|
+
.object({
|
|
301
|
+
enabled: z.boolean().optional(),
|
|
302
|
+
})
|
|
303
|
+
.passthrough()
|
|
304
|
+
.optional(),
|
|
305
|
+
// WS-3b: Anti-collapse guards (step 8). Prevents the consolidation pipeline
|
|
306
|
+
// from collapsing too aggressively and losing diversity.
|
|
307
|
+
// - maxGeneration: refuse to merge two assets both above this generation (default 2).
|
|
308
|
+
// - lexicalDiversityCheck: low n-gram diversity ⇒ raise merge threshold.
|
|
309
|
+
// - randomClusterFraction: occasional random (non-similar) cluster in pool (default 0.05).
|
|
310
|
+
// - mergeInformationFloor: measure that merges keep provenance + specificity
|
|
311
|
+
// (R5 §4.2; ADVISORY in v1 — counted, never refused).
|
|
312
|
+
// - minSpecificityRetention: distinct-token retention floor for merges (default 0.6).
|
|
313
|
+
// Default ON since R5 (opt out via enabled: false). Only meaningful on the
|
|
314
|
+
// `consolidate` process.
|
|
315
|
+
antiCollapse: z
|
|
316
|
+
.object({
|
|
317
|
+
enabled: z.boolean().optional(),
|
|
318
|
+
maxGeneration: z.number().int().min(1).optional(),
|
|
319
|
+
lexicalDiversityCheck: z.boolean().optional(),
|
|
320
|
+
randomClusterFraction: z.number().min(0).max(1).optional(),
|
|
321
|
+
mergeInformationFloor: z.boolean().optional(),
|
|
322
|
+
minSpecificityRetention: z.number().min(0).max(1).optional(),
|
|
323
|
+
})
|
|
324
|
+
.passthrough()
|
|
325
|
+
.optional(),
|
|
326
|
+
// WS-3b: CLS (Complementary Learning System) interleaving (step 9).
|
|
327
|
+
// distill/memoryInference prompts include embedding-retrieved existing adjacent
|
|
328
|
+
// lessons/knowledge to prevent catastrophic interference with prior generalizations.
|
|
329
|
+
// Default OFF. Only meaningful on `distill` and `memoryInference` processes.
|
|
330
|
+
cls: z
|
|
331
|
+
.object({
|
|
332
|
+
enabled: z.boolean().optional(),
|
|
333
|
+
// Number of adjacent lessons/knowledge to include in prompts (default 3).
|
|
334
|
+
adjacentCount: z.number().int().min(1).optional(),
|
|
335
|
+
})
|
|
336
|
+
.passthrough()
|
|
337
|
+
.optional(),
|
|
338
|
+
// WS-3b: Distill→source fidelity check (step 10). After a distill proposal,
|
|
339
|
+
// check it against its cited source memories; a contradiction flag forces
|
|
340
|
+
// human review. Default OFF. Only meaningful on `distill` process.
|
|
341
|
+
fidelityCheck: z
|
|
342
|
+
.object({
|
|
343
|
+
enabled: z.boolean().optional(),
|
|
344
|
+
})
|
|
345
|
+
.passthrough()
|
|
346
|
+
.optional(),
|
|
347
|
+
// #609 — recombine process: minimum related-memory cluster size before an
|
|
348
|
+
// LLM generalization call. Default 3. Only meaningful on `recombine`.
|
|
349
|
+
minClusterSize: z.number().int().min(2).optional(),
|
|
350
|
+
// #609 — recombine process: hard cap on clusters processed per run (one
|
|
351
|
+
// bounded LLM call each). Default 5. Only meaningful on `recombine`.
|
|
352
|
+
maxClustersPerRun: positiveInt.optional(),
|
|
353
|
+
// #632 — recombine process: max members a cluster may contain before it is
|
|
354
|
+
// SKIPPED (drops bland over-broad buckets). When set, largest-first ranking
|
|
355
|
+
// no longer starves tighter clusters. Default UNSET = no cap. Only
|
|
356
|
+
// meaningful on `recombine`.
|
|
357
|
+
maxClusterSize: positiveInt.optional(),
|
|
358
|
+
// #632 — recombine process: tag values that must never form a tag cluster
|
|
359
|
+
// (generic project-wide tags). Default UNSET/[]. Only meaningful on
|
|
360
|
+
// `recombine`.
|
|
361
|
+
excludeTags: z.array(z.string().min(1)).optional(),
|
|
362
|
+
// #632 — recombine process: entity_norm values that must never form an
|
|
363
|
+
// entity cluster (user counterpart to the built-in generic-entity filter).
|
|
364
|
+
// Default UNSET/[]. Only meaningful on `recombine`.
|
|
365
|
+
excludeEntities: z.array(z.string().min(1)).optional(),
|
|
366
|
+
// #609 — recombine process: relatedness signal used to form clusters
|
|
367
|
+
// (tags | graph | both). Clustering is by relatedness, never embedding
|
|
368
|
+
// similarity. Default "both" (#632). Only meaningful on `recombine`.
|
|
369
|
+
relatednessSource: z.enum(["tags", "graph", "both"]).optional(),
|
|
370
|
+
// #609 — recombine process: consecutive re-inductions required before a
|
|
371
|
+
// hypothesis is promoted to a lesson. Default 2. Only meaningful on
|
|
372
|
+
// `recombine`.
|
|
373
|
+
confirmThreshold: z.number().int().min(1).optional(),
|
|
374
|
+
// #615 — procedural process: minimum number of distinct assets sharing the
|
|
375
|
+
// same successful normalized ordered-action sequence before it is compiled
|
|
376
|
+
// into a workflow proposal. Default 3. Only meaningful on `procedural`.
|
|
377
|
+
minRecurrence: z.number().int().min(2).optional(),
|
|
378
|
+
// #615 — procedural process: hard cap on workflow proposals emitted per run
|
|
379
|
+
// (one bounded LLM call each). Default 3. Only meaningful on `procedural`.
|
|
380
|
+
maxProposalsPerRun: positiveInt.optional(),
|
|
381
|
+
// #615 — procedural process: asset type a compiled sequence is emitted as.
|
|
382
|
+
// Reserved; v1 always emits "workflow". Only meaningful on `procedural`.
|
|
383
|
+
emitAs: z.enum(["workflow", "skill"]).optional(),
|
|
384
|
+
// #639 — semantic value-floor filter for the `reflect` process. When
|
|
385
|
+
// enabled, proposals classified as "low-value" by the deterministic noise
|
|
386
|
+
// gate are deferred. DEFAULT OFF (absent / { enabled: false } = pre-#639
|
|
387
|
+
// byte-identical behaviour). Only meaningful on the `reflect` process.
|
|
388
|
+
lowValueFilter: z.object({ enabled: z.boolean().optional() }).passthrough().optional(),
|
|
389
|
+
// #641 — procedural-aware floor for the `extract` process triage gate.
|
|
390
|
+
// When true, a session must have markers>=1 OR editCommit>=0.5 to pass, even
|
|
391
|
+
// if score>=minScore. DEFAULT OFF (absent/false = pre-#641 byte-identical).
|
|
392
|
+
// Only meaningful on the `extract` process when triage is also enabled.
|
|
393
|
+
proceduralAwareFloor: z.boolean().optional(),
|
|
182
394
|
// Triage process config (only meaningful for the `triage` process)
|
|
183
395
|
applyMode: z.enum(["queue", "promote"]).optional(),
|
|
184
396
|
policy: z.string().min(1).optional(),
|
|
@@ -191,10 +403,10 @@ export const ImproveProcessConfigSchema = z
|
|
|
191
403
|
profile: z.string().min(1).optional(),
|
|
192
404
|
timeoutMs: z.union([positiveInt, z.null()]).optional(),
|
|
193
405
|
})
|
|
194
|
-
.
|
|
406
|
+
.passthrough()
|
|
195
407
|
.optional(),
|
|
196
408
|
})
|
|
197
|
-
.
|
|
409
|
+
.passthrough();
|
|
198
410
|
const ImproveProfileProcessesSchema = z
|
|
199
411
|
.object({
|
|
200
412
|
reflect: ImproveProcessConfigSchema.optional(),
|
|
@@ -202,42 +414,27 @@ const ImproveProfileProcessesSchema = z
|
|
|
202
414
|
consolidate: ImproveProcessConfigSchema.optional(),
|
|
203
415
|
memoryInference: ImproveProcessConfigSchema.optional(),
|
|
204
416
|
graphExtraction: ImproveProcessConfigSchema.optional(),
|
|
417
|
+
extract: ImproveProcessConfigSchema.optional(),
|
|
205
418
|
validation: ImproveProcessConfigSchema.optional(),
|
|
206
419
|
triage: ImproveProcessConfigSchema.optional(),
|
|
207
420
|
proactiveMaintenance: ImproveProcessConfigSchema.optional(),
|
|
421
|
+
recombine: ImproveProcessConfigSchema.optional(),
|
|
422
|
+
procedural: ImproveProcessConfigSchema.optional(),
|
|
208
423
|
})
|
|
209
424
|
.passthrough()
|
|
210
425
|
.superRefine((val, ctx) => {
|
|
211
426
|
// 0.8.0 removed the duplicated `feedbackDistillation` process key — it was
|
|
212
|
-
// a thin wrapper around `processes.distill.enabled`.
|
|
213
|
-
|
|
214
|
-
|
|
427
|
+
// a thin wrapper around `processes.distill.enabled`. Keep the migration
|
|
428
|
+
// hint so a stale config gets an actionable message rather than silently
|
|
429
|
+
// doing nothing. All OTHER unknown process keys are tolerated (passthrough)
|
|
430
|
+
// — see the unknown-key policy in this file's header. Hard-rejecting them
|
|
431
|
+
// turned benign cross-version skew into INVALID_CONFIG_FILE failures.
|
|
432
|
+
if ("feedbackDistillation" in val) {
|
|
215
433
|
ctx.addIssue({
|
|
216
434
|
code: z.ZodIssueCode.custom,
|
|
217
435
|
message: "feedbackDistillation was removed in 0.8.0 — use processes.distill.enabled instead. " +
|
|
218
436
|
"It now controls both the orchestration gate and the LLM-call gate.",
|
|
219
437
|
});
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
const allowed = new Set([
|
|
223
|
-
"reflect",
|
|
224
|
-
"distill",
|
|
225
|
-
"consolidate",
|
|
226
|
-
"memoryInference",
|
|
227
|
-
"graphExtraction",
|
|
228
|
-
"validation",
|
|
229
|
-
"extract",
|
|
230
|
-
"triage",
|
|
231
|
-
"proactiveMaintenance",
|
|
232
|
-
]);
|
|
233
|
-
for (const k of Object.keys(raw)) {
|
|
234
|
-
if (!allowed.has(k)) {
|
|
235
|
-
ctx.addIssue({
|
|
236
|
-
code: z.ZodIssueCode.unrecognized_keys,
|
|
237
|
-
keys: [k],
|
|
238
|
-
message: `Unrecognized improve process key: "${k}".`,
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
438
|
}
|
|
242
439
|
});
|
|
243
440
|
export const ImproveProfileConfigSchema = z
|
|
@@ -246,16 +443,26 @@ export const ImproveProfileConfigSchema = z
|
|
|
246
443
|
processes: ImproveProfileProcessesSchema.optional(),
|
|
247
444
|
autoAccept: nonNegativeNumber.optional(),
|
|
248
445
|
limit: positiveInt.optional(),
|
|
446
|
+
// #616 — bounded multi-cycle phasing. Number of prep->loop->post-loop
|
|
447
|
+
// cycles per run. positiveInt forbids 0/negative. DEFAULT 1 => byte-identical
|
|
448
|
+
// single-pass behavior.
|
|
449
|
+
maxCycles: positiveInt.optional(),
|
|
450
|
+
// #614 — symmetric valence weighting in the eligibility sort. When true,
|
|
451
|
+
// the attention term becomes |valence| MAGNITUDE so BOTH strong positive
|
|
452
|
+
// and strong negative feedback drive attention (utility stays dominant) and
|
|
453
|
+
// strong-signed assets are routed to a fix/reinforce lane. DEFAULT OFF —
|
|
454
|
+
// false/absent preserves the legacy negative-only ranking byte-for-byte.
|
|
455
|
+
symmetricValence: z.boolean().optional(),
|
|
249
456
|
sync: z
|
|
250
457
|
.object({
|
|
251
458
|
enabled: z.boolean().optional(),
|
|
252
459
|
push: z.boolean().optional(),
|
|
253
460
|
message: z.string().min(1).optional(),
|
|
254
461
|
})
|
|
255
|
-
.
|
|
462
|
+
.passthrough()
|
|
256
463
|
.optional(),
|
|
257
464
|
})
|
|
258
|
-
.
|
|
465
|
+
.passthrough();
|
|
259
466
|
// ── Profiles / defaults ────────────────────────────────────────────────────
|
|
260
467
|
export const ProfilesSchema = z
|
|
261
468
|
.object({
|
|
@@ -263,14 +470,14 @@ export const ProfilesSchema = z
|
|
|
263
470
|
agent: z.record(z.string(), AgentProfileConfigSchema).optional(),
|
|
264
471
|
improve: z.record(z.string(), ImproveProfileConfigSchema).optional(),
|
|
265
472
|
})
|
|
266
|
-
.
|
|
473
|
+
.passthrough();
|
|
267
474
|
export const DefaultsSchema = z
|
|
268
475
|
.object({
|
|
269
476
|
llm: z.string().min(1).optional(),
|
|
270
477
|
agent: z.string().min(1).optional(),
|
|
271
478
|
improve: z.string().min(1).optional(),
|
|
272
479
|
})
|
|
273
|
-
.
|
|
480
|
+
.passthrough();
|
|
274
481
|
// ── Sources / registries / installed ────────────────────────────────────────
|
|
275
482
|
const SourceConfigEntryOptionsSchema = z
|
|
276
483
|
.object({
|
|
@@ -294,7 +501,7 @@ export const SourceConfigEntrySchema = z
|
|
|
294
501
|
options: SourceConfigEntryOptionsSchema.optional(),
|
|
295
502
|
wikiName: z.string().min(1).optional(),
|
|
296
503
|
})
|
|
297
|
-
.
|
|
504
|
+
.passthrough()
|
|
298
505
|
.superRefine((entry, ctx) => {
|
|
299
506
|
if (entry.writable === true && (entry.type === "website" || entry.type === "npm")) {
|
|
300
507
|
ctx.addIssue({
|
|
@@ -313,7 +520,7 @@ export const RegistryConfigEntrySchema = z
|
|
|
313
520
|
provider: z.string().min(1).optional(),
|
|
314
521
|
options: z.record(z.unknown()).optional(),
|
|
315
522
|
})
|
|
316
|
-
.
|
|
523
|
+
.passthrough();
|
|
317
524
|
const KitSourceSchema = z.enum(["filesystem", "git", "npm", "github", "website", "local"]);
|
|
318
525
|
export const InstalledStashEntrySchema = z
|
|
319
526
|
.object({
|
|
@@ -329,7 +536,7 @@ export const InstalledStashEntrySchema = z
|
|
|
329
536
|
resolvedRevision: z.string().min(1).optional(),
|
|
330
537
|
wikiName: z.string().min(1).optional(),
|
|
331
538
|
})
|
|
332
|
-
.
|
|
539
|
+
.passthrough()
|
|
333
540
|
.superRefine((entry, ctx) => {
|
|
334
541
|
if (entry.writable === true && entry.source !== "git" && entry.source !== "filesystem") {
|
|
335
542
|
ctx.addIssue({
|
|
@@ -344,7 +551,7 @@ export const OutputConfigSchema = z
|
|
|
344
551
|
format: z.enum(["json", "yaml", "text"]).optional(),
|
|
345
552
|
detail: z.enum(["brief", "normal", "full"]).optional(),
|
|
346
553
|
})
|
|
347
|
-
.
|
|
554
|
+
.passthrough();
|
|
348
555
|
// ── Search ──────────────────────────────────────────────────────────────────
|
|
349
556
|
const SearchGraphBoostSchema = z
|
|
350
557
|
.object({
|
|
@@ -358,34 +565,122 @@ const SearchGraphBoostSchema = z
|
|
|
358
565
|
/** Range [0, 1]; values > 1 hard-error (no silent clamp). */
|
|
359
566
|
confidenceWeight: z.number().finite().min(0).max(1).default(0.2).optional(),
|
|
360
567
|
})
|
|
361
|
-
.
|
|
568
|
+
.passthrough();
|
|
362
569
|
export const SearchConfigSchema = z
|
|
363
570
|
.object({
|
|
364
571
|
minScore: nonNegativeNumber.optional(),
|
|
365
|
-
|
|
572
|
+
defaultExcludeTypes: z.array(nonEmptyString).optional(),
|
|
366
573
|
graphBoost: SearchGraphBoostSchema.optional(),
|
|
367
574
|
})
|
|
368
|
-
.
|
|
575
|
+
.passthrough();
|
|
369
576
|
// ── Feedback ────────────────────────────────────────────────────────────────
|
|
370
577
|
export const FeedbackConfigSchema = z
|
|
371
578
|
.object({
|
|
372
579
|
requireReason: z.boolean().optional(),
|
|
373
580
|
allowedFailureModes: z.array(nonEmptyString).optional(),
|
|
374
581
|
})
|
|
375
|
-
.
|
|
582
|
+
.passthrough();
|
|
376
583
|
// ── Improve top-level (utility decay, event retention) ─────────────────────
|
|
377
584
|
const ImproveUtilityDecaySchema = z
|
|
378
585
|
.object({
|
|
379
586
|
halfLifeDays: z.number().finite().min(0.1).optional(),
|
|
380
587
|
feedbackStabilityBoost: z.number().finite().min(1).optional(),
|
|
381
588
|
})
|
|
382
|
-
.
|
|
589
|
+
.passthrough();
|
|
590
|
+
// #612 / WS-4 — auto-accept gate calibration + bounded, opt-in per-phase
|
|
591
|
+
// threshold auto-tune. DEFAULT OFF: when absent (or `autoTune: false`) no
|
|
592
|
+
// tuning occurs, so the gate behaves byte-identically to today.
|
|
593
|
+
// WS-4 adds: per-phase persistence (state.db) + auto-tune ceiling default 85.
|
|
594
|
+
const ImproveCalibrationSchema = z
|
|
595
|
+
.object({
|
|
596
|
+
/** Master switch for the bounded threshold auto-tune. Default false (parity). */
|
|
597
|
+
autoTune: z.boolean().optional(),
|
|
598
|
+
/** Lower bound (0-100) the tuned threshold may never drop below. */
|
|
599
|
+
minThreshold: z.number().int().min(0).max(100).optional(),
|
|
600
|
+
/**
|
|
601
|
+
* Upper bound (0-100) the tuned threshold may never rise above.
|
|
602
|
+
* WS-4 default: 85 (prevents gate converging to pure exploitation).
|
|
603
|
+
*/
|
|
604
|
+
maxThreshold: z.number().int().min(0).max(100).optional(),
|
|
605
|
+
/** Maximum adjustment magnitude (points) applied in one tune step. */
|
|
606
|
+
maxStep: positiveInt.optional(),
|
|
607
|
+
/** Minimum acted-on sample count required before any adjustment. */
|
|
608
|
+
minSamples: nonNegativeNumber.optional(),
|
|
609
|
+
/** Target realized accept rate in [0, 1]. Default 0.9. */
|
|
610
|
+
targetAcceptRate: z.number().finite().min(0).max(1).optional(),
|
|
611
|
+
})
|
|
612
|
+
.passthrough();
|
|
613
|
+
// WS-4 — exploration budget: a fixed fraction of proposals accepted per run
|
|
614
|
+
// regardless of confidence. DEFAULT OFF.
|
|
615
|
+
const ImproveExplorationSchema = z
|
|
616
|
+
.object({
|
|
617
|
+
/**
|
|
618
|
+
* Enable the exploration budget lane. Default false (parity).
|
|
619
|
+
* When true, a fraction of proposals are accepted regardless of confidence.
|
|
620
|
+
*/
|
|
621
|
+
enabled: z.boolean().optional(),
|
|
622
|
+
/**
|
|
623
|
+
* Fraction of proposals per run to accept as exploration [0, 1].
|
|
624
|
+
* Default 0.05 (5%). Clamped to [0, 1] at read time.
|
|
625
|
+
*/
|
|
626
|
+
budgetFraction: z.number().finite().min(0).max(1).optional(),
|
|
627
|
+
})
|
|
628
|
+
.passthrough();
|
|
629
|
+
const ImproveSalienceSchema = z
|
|
630
|
+
.object({
|
|
631
|
+
/**
|
|
632
|
+
* WS-2 Part-V gate: enable the outcome-weight term in the salience projection.
|
|
633
|
+
* Default false (parity — WS-1 weights w_e=0.30, w_r=0.70 until Part-V confirms
|
|
634
|
+
* no regression). Set to true after running scripts/akm-eval + health report.
|
|
635
|
+
*/
|
|
636
|
+
outcomeWeightEnabled: z.boolean().optional(),
|
|
637
|
+
/**
|
|
638
|
+
* Minimum encoding salience score [0, 1] for a zero-feedback asset to be
|
|
639
|
+
* admitted to the high-salience improve lane (#608).
|
|
640
|
+
* Default 0.75. Set to 1.0 to disable the lane entirely.
|
|
641
|
+
*/
|
|
642
|
+
salienceThreshold: z.number().min(0).max(1).optional(),
|
|
643
|
+
/**
|
|
644
|
+
* Per-run additive replay budget (#610). Up to this many top-salience refs are
|
|
645
|
+
* revisited even with no reactive signal and regardless of cooldown. Additive
|
|
646
|
+
* on top of --limit. Default 0 = no replay.
|
|
647
|
+
*/
|
|
648
|
+
replayBudget: z.number().int().min(0).optional(),
|
|
649
|
+
})
|
|
650
|
+
.passthrough();
|
|
651
|
+
// R5 — longitudinal collapse/churn detector (observe-only in v1; deterministic,
|
|
652
|
+
// fail-open, runs only on cycles where consolidate/recombine did work).
|
|
653
|
+
// Default ON; opt out via `improve.collapseDetector.enabled: false`.
|
|
654
|
+
// See docs/design/improve-collapse-churn-detector-design.md.
|
|
655
|
+
const ImproveCollapseDetectorSchema = z
|
|
656
|
+
.object({
|
|
657
|
+
enabled: z.boolean().optional(),
|
|
658
|
+
// Canary set size minted on first run (owner-approved 30–50 range; default 40).
|
|
659
|
+
canaryCount: z.number().int().min(3).max(200).optional(),
|
|
660
|
+
// Top-K cutoff for canary recall/nDCG (default 10).
|
|
661
|
+
k: z.number().int().min(1).max(100).optional(),
|
|
662
|
+
// Trend window in qualifying cycles (default 5).
|
|
663
|
+
windowCycles: z.number().int().min(2).max(50).optional(),
|
|
664
|
+
// Absolute mean-recall drop vs window median that fires collapse (default 0.15).
|
|
665
|
+
recallDropThreshold: z.number().min(0).max(1).optional(),
|
|
666
|
+
// distinct-content-ratio decline over the window that fires collapse (default 0.05).
|
|
667
|
+
entropyDropThreshold: z.number().min(0).max(1).optional(),
|
|
668
|
+
// Accepted-action volume over the window below which churn never fires (default 25).
|
|
669
|
+
churnMinAcceptedActions: z.number().int().min(1).optional(),
|
|
670
|
+
// improve_cycle_metrics retention (default 365 days, owner-approved).
|
|
671
|
+
retentionDays: z.number().int().min(1).optional(),
|
|
672
|
+
})
|
|
673
|
+
.passthrough();
|
|
383
674
|
export const ImproveConfigSchema = z
|
|
384
675
|
.object({
|
|
385
676
|
utilityDecay: ImproveUtilityDecaySchema.optional(),
|
|
386
677
|
eventRetentionDays: nonNegativeNumber.optional(),
|
|
678
|
+
calibration: ImproveCalibrationSchema.optional(),
|
|
679
|
+
exploration: ImproveExplorationSchema.optional(),
|
|
680
|
+
salience: ImproveSalienceSchema.optional(),
|
|
681
|
+
collapseDetector: ImproveCollapseDetectorSchema.optional(),
|
|
387
682
|
})
|
|
388
|
-
.
|
|
683
|
+
.passthrough();
|
|
389
684
|
// ── Index / per-pass ────────────────────────────────────────────────────────
|
|
390
685
|
const GRAPH_EXTRACTION_INCLUDE_TYPES_ALLOWED = [
|
|
391
686
|
"memory",
|
|
@@ -397,6 +692,7 @@ const GRAPH_EXTRACTION_INCLUDE_TYPES_ALLOWED = [
|
|
|
397
692
|
"lesson",
|
|
398
693
|
"task",
|
|
399
694
|
"wiki",
|
|
695
|
+
"fact",
|
|
400
696
|
];
|
|
401
697
|
const INDEX_PASS_PROVIDER_KEYS = new Set([
|
|
402
698
|
"endpoint",
|
|
@@ -413,6 +709,7 @@ const INDEX_PASS_KNOWN_KEYS = new Set([
|
|
|
413
709
|
"graphExtractionBatchSize",
|
|
414
710
|
"graphExtractionIncludeTypes",
|
|
415
711
|
"memoryInferenceBatchSize",
|
|
712
|
+
"lazyGraphExtraction",
|
|
416
713
|
]);
|
|
417
714
|
/**
|
|
418
715
|
* Per-pass `index.<pass>` entry. Uses preprocess + manual validation so we can
|
|
@@ -439,8 +736,8 @@ export const IndexPassConfigSchema = z.preprocess((raw, ctx) => {
|
|
|
439
736
|
ctx.addIssue({
|
|
440
737
|
code: z.ZodIssueCode.custom,
|
|
441
738
|
message: `Unknown key \`${[...(ctx.path ?? []), key].join(".")}\`. Per-pass entries support \`llm\` ` +
|
|
442
|
-
"(boolean opt-out), `graphExtractionBatchSize`, `graphExtractionIncludeTypes`,
|
|
443
|
-
"`memoryInferenceBatchSize`.",
|
|
739
|
+
"(boolean opt-out), `graphExtractionBatchSize`, `graphExtractionIncludeTypes`, " +
|
|
740
|
+
"`memoryInferenceBatchSize`, and `lazyGraphExtraction`.",
|
|
444
741
|
});
|
|
445
742
|
return raw;
|
|
446
743
|
}
|
|
@@ -459,15 +756,23 @@ export const IndexPassConfigSchema = z.preprocess((raw, ctx) => {
|
|
|
459
756
|
graphExtractionBatchSize: positiveInt.optional(),
|
|
460
757
|
graphExtractionIncludeTypes: z.array(z.enum(GRAPH_EXTRACTION_INCLUDE_TYPES_ALLOWED)).nonempty().optional(),
|
|
461
758
|
memoryInferenceBatchSize: positiveInt.optional(),
|
|
759
|
+
lazyGraphExtraction: z.boolean().optional(),
|
|
462
760
|
})
|
|
463
761
|
.passthrough());
|
|
464
|
-
const MetadataEnhanceSchema = z.object({ enabled: z.boolean().optional() }).
|
|
762
|
+
const MetadataEnhanceSchema = z.object({ enabled: z.boolean().optional() }).passthrough();
|
|
763
|
+
/**
|
|
764
|
+
* RETIRED (meta-review 10-Q3): the staleness-detect pass was deleted; nothing
|
|
765
|
+
* reads this section anymore. The key stays TOLERATED here so configs that
|
|
766
|
+
* still carry `index.stalenessDetection` (written by 0.8.x migrations) do not
|
|
767
|
+
* fail validation — deleting the key would route it into the per-pass
|
|
768
|
+
* catchall, which rejects its `enabled`/`thresholdDays` fields.
|
|
769
|
+
*/
|
|
465
770
|
const StalenessDetectionSchema = z
|
|
466
771
|
.object({
|
|
467
772
|
enabled: z.boolean().optional(),
|
|
468
773
|
thresholdDays: positiveInt.optional(),
|
|
469
774
|
})
|
|
470
|
-
.
|
|
775
|
+
.passthrough();
|
|
471
776
|
/**
|
|
472
777
|
* Index config is a union of reserved feature sections and per-pass entries.
|
|
473
778
|
* Passthrough so per-pass entries (keyed by arbitrary pass names like `graph`,
|
|
@@ -527,6 +832,26 @@ export const IndexConfigSchema = z.preprocess((raw, ctx) => {
|
|
|
527
832
|
stalenessDetection: StalenessDetectionSchema.optional(),
|
|
528
833
|
})
|
|
529
834
|
.catchall(IndexPassConfigSchema));
|
|
835
|
+
// ── Workflow engine ─────────────────────────────────────────────────────────
|
|
836
|
+
/**
|
|
837
|
+
* Workflow-engine settings (`workflow`).
|
|
838
|
+
*
|
|
839
|
+
* `maxConcurrency` is the engine-wide ceiling on concurrent units for native
|
|
840
|
+
* fan-out (`akm workflow run`). It replaces the hard-coded `min(16, cores−2)`
|
|
841
|
+
* cap (which matched Claude Code) with a user knob:
|
|
842
|
+
* - UNSET → the CPU-derived default `min(16, max(1, cores−2))`.
|
|
843
|
+
* - SET → the explicit positive integer, CLAMPED at read time to
|
|
844
|
+
* `[1, WORKFLOW_MAX_CONCURRENCY_CEILING]` (64). Values above the ceiling
|
|
845
|
+
* are clamped, not rejected, so a config shared across machines with wildly
|
|
846
|
+
* different core counts never hard-fails validation.
|
|
847
|
+
* The R3 brief/report driver surface does NOT consult this — drivers own their
|
|
848
|
+
* own parallelism (the engine only caps native dispatch).
|
|
849
|
+
*/
|
|
850
|
+
export const WorkflowConfigSchema = z
|
|
851
|
+
.object({
|
|
852
|
+
maxConcurrency: positiveInt.optional(),
|
|
853
|
+
})
|
|
854
|
+
.passthrough();
|
|
530
855
|
// ── Setup-derived recommendations ──────────────────────────────────────────
|
|
531
856
|
/**
|
|
532
857
|
* Cron-style schedule hints derived by `akm setup --reset-recommended`.
|
|
@@ -540,12 +865,12 @@ export const SetupTaskSchedulesSchema = z
|
|
|
540
865
|
improve: z.string().min(1).optional(),
|
|
541
866
|
index: z.string().min(1).optional(),
|
|
542
867
|
})
|
|
543
|
-
.
|
|
868
|
+
.passthrough();
|
|
544
869
|
export const SetupConfigSchema = z
|
|
545
870
|
.object({
|
|
546
871
|
taskSchedules: SetupTaskSchedulesSchema.optional(),
|
|
547
872
|
})
|
|
548
|
-
.
|
|
873
|
+
.passthrough();
|
|
549
874
|
// ── Top-level AkmConfig ────────────────────────────────────────────────────
|
|
550
875
|
/**
|
|
551
876
|
* Base object schema used both as the top-level shape and as the source of
|
|
@@ -561,10 +886,25 @@ export const AkmConfigShape = {
|
|
|
561
886
|
configVersion: z.union([z.string().min(1), z.number()]).optional(),
|
|
562
887
|
profiles: ProfilesSchema.optional(),
|
|
563
888
|
defaults: DefaultsSchema.optional(),
|
|
889
|
+
// Global model-alias tiers: alias → platform → exact model string, with a
|
|
890
|
+
// reserved `"*"` platform key as fallback. Lets workflows/callers name a
|
|
891
|
+
// semantic tier ("fast", "deep") that resolves per-harness at dispatch
|
|
892
|
+
// time. Values are literal model strings, never other aliases (one
|
|
893
|
+
// resolution level). Platform keys match the platform string a command
|
|
894
|
+
// builder resolves against ("claude", "opencode", "opencode-sdk", or a
|
|
895
|
+
// custom profile's name for the default builder) — unknown keys are inert.
|
|
896
|
+
// Precedence: profile modelAliases > this table > built-in aliases.
|
|
897
|
+
modelAliases: z.record(z.string().min(1), z.record(z.string().min(1), z.string().min(1))).optional(),
|
|
564
898
|
stashDir: nonEmptyString.optional(),
|
|
565
899
|
semanticSearchMode: z.enum(["off", "auto"]).default("auto"),
|
|
566
900
|
embedding: EmbeddingConnectionConfigSchema.optional(),
|
|
567
901
|
index: IndexConfigSchema.optional(),
|
|
902
|
+
// The `installed[]` shape is OWNED by the registry (`InstalledStashEntry`):
|
|
903
|
+
// its `source` is the 4-value `InstallKind` produced by the registry ref
|
|
904
|
+
// parser, and installed entries never carry the extra passthrough keys. The
|
|
905
|
+
// schema still validates entries at runtime, but its OUTPUT type is pinned to
|
|
906
|
+
// the domain type so config consumers get the registry `InstalledStashEntry`
|
|
907
|
+
// (not a looser schema-local mirror) — the single-source-of-truth boundary.
|
|
568
908
|
installed: z.array(InstalledStashEntrySchema).optional(),
|
|
569
909
|
registries: z.array(RegistryConfigEntrySchema).optional(),
|
|
570
910
|
sources: z.array(SourceConfigEntrySchema).optional(),
|
|
@@ -575,9 +915,10 @@ export const AkmConfigShape = {
|
|
|
575
915
|
feedback: FeedbackConfigSchema.optional(),
|
|
576
916
|
archiveRetentionDays: nonNegativeNumber.optional(),
|
|
577
917
|
improve: ImproveConfigSchema.optional(),
|
|
918
|
+
workflow: WorkflowConfigSchema.optional(),
|
|
578
919
|
setup: SetupConfigSchema.optional(),
|
|
579
920
|
};
|
|
580
|
-
export const AkmConfigBaseSchema = z.object(AkmConfigShape).
|
|
921
|
+
export const AkmConfigBaseSchema = z.object(AkmConfigShape).passthrough();
|
|
581
922
|
export const AkmConfigSchema = AkmConfigBaseSchema.superRefine((config, ctx) => {
|
|
582
923
|
// #464.a: defaultWriteTarget must name a configured source when sources
|
|
583
924
|
// are present. With no sources configured, error out instead of silently
|