akm-cli 0.9.30 → 0.10.261001-beta
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 +438 -0
- package/README.md +10 -10
- package/ROADMAP.md +112 -0
- package/STABILITY.md +99 -57
- package/dist/api-node.mjs +20 -0
- package/dist/api.d.ts +23 -0
- package/dist/api.js +45 -0
- package/dist/assets/hints/cli-hints-full.md +15 -29
- package/dist/assets/hints/cli-hints-short.md +2 -2
- package/dist/assets/improve-strategies/default.json +3 -3
- package/dist/assets/prompts/consolidate-pair.md +9 -7
- package/dist/assets/stash-skeleton/README.md +1 -1
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +1 -1
- package/dist/cli/shared.js +31 -48
- package/dist/cli/unknown-flags.js +6 -43
- package/dist/cli.js +8 -34
- package/dist/commands/agent/contribute-cli.js +1 -1
- package/dist/commands/completions.js +1 -2
- package/dist/commands/config-cli.js +5 -28
- package/dist/commands/env/env-cli.js +5 -5
- package/dist/commands/env/secret-cli.js +2 -2
- package/dist/commands/feedback-cli.js +75 -49
- package/dist/commands/health/checks.js +41 -16
- package/dist/commands/health/plugin-staleness.js +52 -22
- package/dist/commands/improve/autonomy-gate.js +5 -3
- package/dist/commands/improve/consolidate/chunking.js +3 -10
- package/dist/commands/improve/consolidate/continuity-check.js +4 -4
- package/dist/commands/improve/consolidate/pair-pass.js +29 -10
- package/dist/commands/improve/consolidate.js +10 -65
- package/dist/commands/improve/distill/lesson-update.js +91 -0
- package/dist/commands/improve/distill-guards.js +1 -43
- package/dist/commands/improve/distill.js +148 -21
- package/dist/commands/improve/eligibility.js +14 -1
- package/dist/commands/improve/extract-cli.js +1 -1
- package/dist/commands/improve/extract-prompt.js +17 -7
- package/dist/commands/improve/extract.js +5 -7
- package/dist/commands/improve/improve-cli.js +125 -118
- package/dist/commands/improve/improve-strategies.js +8 -12
- package/dist/commands/improve/improve.js +134 -52
- package/dist/commands/improve/loop-stages.js +18 -5
- package/dist/commands/improve/planner.js +0 -1
- package/dist/commands/improve/preparation.js +40 -99
- package/dist/commands/improve/proactive-maintenance.js +2 -2
- package/dist/commands/improve/reflect-noise.js +3 -55
- package/dist/commands/improve/reflect.js +29 -34
- package/dist/commands/improve/retrieval-queries.js +37 -0
- package/dist/commands/improve/retrieval-scope.js +2 -2
- package/dist/commands/improve/salience.js +2 -9
- package/dist/commands/improve/session-asset.js +4 -1
- package/dist/commands/improve/stage.js +23 -12
- package/dist/commands/lint/index.js +5 -20
- package/dist/commands/observability-cli.js +3 -9
- package/dist/commands/proposal/drain.js +43 -6
- package/dist/commands/proposal/proposal-cli.js +11 -31
- package/dist/commands/proposal/repository.js +20 -14
- package/dist/commands/proposal/validators/proposal-quality-validators.js +0 -3
- package/dist/commands/read/knowledge.js +3 -3
- package/dist/commands/read/remember-cli.js +0 -13
- package/dist/commands/read/search-cli.js +29 -97
- package/dist/commands/read/search.js +0 -11
- package/dist/commands/read/show.js +0 -19
- package/dist/commands/sources/plugin-upgrade.js +164 -101
- package/dist/commands/sources/sources-cli.js +1 -15
- package/dist/commands/sources/stash-cli.js +6 -14
- package/dist/commands/tasks/tasks-cli.js +4 -115
- package/dist/commands/workflow/plan.js +11 -33
- package/dist/commands/workflow-cli.js +2 -7
- package/dist/core/adapter/adapter-ids.js +1 -2
- package/dist/core/adapter/adapters/agent-skills-adapter.js +0 -4
- package/dist/core/adapter/adapters/akm-adapter.js +9 -48
- package/dist/core/adapter/adapters/akm-lint.js +10 -26
- package/dist/core/adapter/adapters/akm-metadata.js +2 -72
- package/dist/core/adapter/adapters/akm-task-adapter.js +0 -5
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +9 -28
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -20
- package/dist/core/adapter/adapters/generic-files-adapter.js +0 -10
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +0 -4
- package/dist/core/adapter/adapters/tool-dir-shared.js +0 -24
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -4
- package/dist/core/adapter/recognize-match.js +3 -4
- package/dist/core/common.js +18 -2
- package/dist/core/config/config-schema.js +12 -15
- package/dist/core/config/config-types.js +6 -15
- package/dist/core/config/config-walker.js +6 -23
- package/dist/core/config/config.js +17 -80
- package/dist/core/config/engine-semantics.js +7 -3
- package/dist/core/config/schema/engines.js +7 -7
- package/dist/core/config/schema/improve-processes.js +10 -63
- package/dist/core/config/schema/improve.js +2 -21
- package/dist/core/config/schema/index-config.js +6 -39
- package/dist/core/env-secret-ref.js +2 -45
- package/dist/core/errors.js +1 -2
- package/dist/core/extra-params.js +2 -86
- package/dist/core/file-lock.js +12 -7
- package/dist/core/improve-result.js +13 -1
- package/dist/core/mutation-target.js +2 -2
- package/dist/core/paths.js +4 -0
- package/dist/core/recognition-util.js +4 -5
- package/dist/core/run-lock.js +1 -1
- package/dist/core/subprocess.js +49 -0
- package/dist/core/warn.js +21 -4
- package/dist/core/write-source.js +3 -3
- package/dist/execution/target-ref.js +1 -2
- package/dist/indexer/indexer.js +15 -6
- package/dist/indexer/passes/memory-inference.js +15 -6
- package/dist/indexer/search/db-search.js +49 -36
- package/dist/indexer/search/fts-query.js +0 -19
- package/dist/indexer/search/ranking.js +29 -1
- package/dist/indexer/usage/usage-events.js +21 -16
- package/dist/integrations/agent/engine-resolution.js +5 -2
- package/dist/integrations/agent/index.js +1 -1
- package/dist/integrations/agent/profiles.js +41 -98
- package/dist/integrations/agent/request-lowering.js +3 -3
- package/dist/integrations/harnesses/aider/index.js +5 -0
- package/dist/integrations/harnesses/amazonq/index.js +1 -0
- package/dist/integrations/harnesses/claude/config-import.js +2 -3
- package/dist/integrations/harnesses/claude/index.js +5 -0
- package/dist/integrations/harnesses/codex/index.js +1 -0
- package/dist/integrations/harnesses/copilot/index.js +1 -0
- package/dist/integrations/harnesses/gemini/index.js +1 -0
- package/dist/integrations/harnesses/index.js +18 -39
- package/dist/integrations/harnesses/opencode/agent-builder.js +60 -35
- package/dist/integrations/harnesses/opencode/config-import.js +121 -52
- package/dist/integrations/harnesses/opencode/index.js +22 -0
- package/dist/integrations/harnesses/opencode/plugin-layout.js +68 -0
- package/dist/integrations/harnesses/opencode/session-log-types.js +12 -0
- package/dist/integrations/harnesses/opencode/session-log-v1.js +72 -0
- package/dist/integrations/harnesses/opencode/session-log-v2.js +140 -0
- package/dist/integrations/harnesses/opencode/session-log.js +104 -115
- package/dist/integrations/harnesses/opencode/version.js +98 -0
- package/dist/integrations/harnesses/opencode-sdk/{harness.js → index.js} +5 -17
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +105 -206
- package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +199 -0
- package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +254 -0
- package/dist/integrations/harnesses/opencode-sdk/wire.js +66 -0
- package/dist/integrations/harnesses/openhands/index.js +1 -0
- package/dist/integrations/harnesses/pi/index.js +1 -0
- package/dist/integrations/harnesses/shared.js +2 -0
- package/dist/integrations/harnesses/types.js +2 -0
- package/dist/llm/client.js +74 -14
- package/dist/output/cli-hints.js +1 -1
- package/dist/output/context.js +10 -19
- package/dist/output/format-exempt.js +5 -8
- package/dist/output/shapes/helpers.js +1 -22
- package/dist/output/shapes/passthrough.js +0 -1
- package/dist/output/shapes.js +3 -31
- package/dist/output/stdout.js +5 -1
- package/dist/output/text/command-format.js +6 -1
- package/dist/output/text/workflow-format.js +4 -22
- package/dist/scripts/akm-migrate-node.js +15769 -16731
- package/dist/scripts/akm-migrate.js +16339 -17297
- package/dist/setup/detect.js +10 -4
- package/dist/setup/harness-config-import.js +5 -14
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/tasks.js +12 -13
- package/dist/sources/providers/git-stash.js +94 -13
- package/dist/storage/repositories/index-utility-repository.js +2 -32
- package/dist/storage/repositories/index-vec-repository.js +4 -0
- package/dist/storage/repositories/task-history-repository.js +0 -5
- package/dist/storage/repositories/workflow-runs-repository.js +5 -15
- package/dist/tasks/embedded.js +2 -1
- package/dist/tasks/run/run-command-task.js +9 -1
- package/dist/tasks/run/run-workflow-task.js +4 -3
- package/dist/tasks/run/task-history.js +0 -2
- package/dist/tasks/run/task-log.js +38 -1
- package/dist/tasks/schedule-gates.js +39 -0
- package/dist/tasks/scheduler-binding.js +0 -16
- package/dist/tasks/scheduler-sync.js +3 -97
- package/dist/tasks/source/bounded-document.js +1 -1
- package/dist/tasks/source/task-source-v4.js +2 -12
- package/dist/tasks/task-run-reserved-flags.js +2 -31
- package/dist/workflows/authoring/authoring.js +6 -6
- package/dist/workflows/compile.js +8 -65
- package/dist/workflows/exec/child-workflow.js +22 -3
- package/dist/workflows/exec/native-executor.js +12 -147
- package/dist/workflows/exec/run-workflow.js +31 -103
- package/dist/workflows/exec/step-work.js +9 -178
- package/dist/workflows/exec/unit-dispatch.js +0 -10
- package/dist/workflows/freeze/environment.js +3 -44
- package/dist/workflows/freeze/freeze.js +8 -41
- package/dist/workflows/freeze/targets/child-workflow.js +27 -63
- package/dist/workflows/freeze/targets/command.js +2 -16
- package/dist/workflows/freeze/targets/shell.js +0 -2
- package/dist/workflows/freeze/task-bindings.js +2 -28
- package/dist/workflows/ir/params.js +12 -2
- package/dist/workflows/parser.js +82 -232
- package/dist/workflows/plan.js +1 -1
- package/dist/workflows/renderer.js +10 -19
- package/dist/workflows/runtime/run-plan.js +11 -53
- package/dist/workflows/runtime/runs.js +4 -27
- package/dist/workflows/source-files.js +12 -16
- package/dist/workflows/source-semantics.js +1 -93
- package/docs/README.md +43 -42
- package/docs/agents/README.md +15 -0
- package/docs/agents/agent-install.md +14 -0
- package/docs/architecture/0.10-process-rules.md +827 -0
- package/docs/architecture/README.md +67 -0
- package/docs/architecture/adapters.md +258 -0
- package/docs/architecture/akm-architecture-decision-history.md +2055 -0
- package/docs/architecture/akm-core-principles.md +126 -0
- package/docs/architecture/architecture.md +578 -0
- package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +550 -0
- package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +72 -0
- package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +142 -0
- package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +189 -0
- package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +97 -0
- package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +108 -0
- package/docs/architecture/decisions/0006-task-source-version-routing.md +124 -0
- package/docs/architecture/decisions/0007-workflow-composition-bounds.md +83 -0
- package/docs/architecture/decisions/0008-task-binding-normalization.md +88 -0
- package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +80 -0
- package/docs/architecture/decisions/0010-driver-protocol-cut.md +36 -0
- package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +125 -0
- package/docs/architecture/decisions/README.md +62 -0
- package/docs/architecture/improvement.md +479 -0
- package/docs/architecture/internals/classification.md +154 -0
- package/docs/architecture/internals/fresh-host-rebuild-runbook.md +40 -0
- package/docs/architecture/internals/functional-contract-patterns.md +340 -0
- package/docs/architecture/internals/health-advisories.md +110 -0
- package/docs/architecture/internals/improve-workflow.md +719 -0
- package/docs/architecture/internals/indexing.md +498 -0
- package/docs/architecture/internals/registry-network-boundary.md +57 -0
- package/docs/architecture/internals/search.md +248 -0
- package/docs/architecture/internals/storage-locations.md +943 -0
- package/docs/architecture/persisted-data-compat.md +68 -0
- package/docs/architecture/reviews/env-secret-access.md +319 -0
- package/docs/architecture/runtime-boundary-design.md +153 -0
- package/docs/architecture/specs/0.9.0-close-out-plan.md +361 -0
- package/docs/architecture/specs/0.9.0-decisions.md +532 -0
- package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +745 -0
- package/docs/architecture/specs/0.9.0-open-items-register.md +135 -0
- package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +740 -0
- package/docs/architecture/specs/0.9.0-release-surface-review.md +636 -0
- package/docs/architecture/specs/agent-command-engine-model-design.md +513 -0
- package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +501 -0
- package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +291 -0
- package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +2059 -0
- package/docs/architecture/specs/di-seams-plan.md +539 -0
- package/docs/architecture/specs/driver-protocol-keep-or-cut.md +275 -0
- package/docs/architecture/specs/fact-asset-type.md +142 -0
- package/docs/architecture/specs/improve-collapse-churn-detector-design.md +634 -0
- package/docs/architecture/specs/okf-support.md +148 -0
- package/docs/architecture/specs/ref.md +329 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/README.md +72 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +152 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +352 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +300 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +402 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +758 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +645 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +602 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +27 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +27 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +74 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +15 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +132 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +147 -0
- package/docs/architecture/specs/stash-conventions-code-spec.md +275 -0
- package/docs/architecture/specs/stash-organization-conventions.md +377 -0
- package/docs/architecture/specs/task-workflow-format-unification.md +721 -0
- package/docs/architecture/specs/workflow-engine-buy-vs-build.md +231 -0
- package/docs/architecture/specs/workflow-format-unification.md +432 -0
- package/docs/architecture/testing/manual-testing-checklist.md +3411 -0
- package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +924 -0
- package/docs/architecture/testing/task-workflow-manual-tests.md +1720 -0
- package/docs/architecture/testing/testing-workflow.md +446 -0
- package/docs/architecture/workflow-engine.md +223 -0
- package/docs/guides/README.md +33 -0
- package/docs/guides/author-bundles.md +310 -0
- package/docs/guides/author-workflows.md +490 -0
- package/docs/guides/bundles.md +323 -0
- package/docs/guides/capture-knowledge.md +136 -0
- package/docs/guides/claude-code-vs-akm-workflows.md +29 -0
- package/docs/guides/concepts.md +93 -0
- package/docs/guides/discover-and-load.md +158 -0
- package/docs/guides/getting-started.md +240 -0
- package/docs/guides/improve-the-library.md +247 -0
- package/docs/guides/knowledge-management.md +18 -0
- package/docs/guides/recipes/headless-install.md +97 -0
- package/docs/guides/recipes/website-source.md +28 -0
- package/docs/guides/run-workflows.md +279 -0
- package/docs/guides/scheduling.md +131 -0
- package/docs/guides/use-with-any-agent.md +174 -0
- package/docs/guides/wikis.md +81 -0
- package/docs/integration/bundling-akm.md +7 -6
- package/docs/maintainers/README.md +19 -0
- package/docs/maintainers/curate-workmap.md +335 -0
- package/docs/maintainers/eval.md +3 -0
- package/docs/maintainers/local-development.md +108 -0
- package/docs/maintainers/release-checklist.md +135 -0
- package/docs/migration/README.md +4 -2
- package/docs/migration/release-notes/0.0.13.md +1 -1
- package/docs/migration/release-notes/0.1.0.md +1 -1
- package/docs/migration/release-notes/0.10.0.md +201 -0
- package/docs/migration/release-notes/0.2.0.md +1 -1
- package/docs/migration/release-notes/0.3.0.md +1 -1
- package/docs/migration/release-notes/0.5.0.md +1 -1
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.7.3.md +2 -2
- package/docs/migration/release-notes/0.7.4.md +1 -1
- package/docs/migration/release-notes/0.7.5.md +1 -1
- package/docs/migration/release-notes/0.8.0.md +1 -1
- package/docs/migration/release-notes/0.9.0.md +1 -1
- package/docs/migration/release-notes/0.9.14.md +1 -1
- package/docs/migration/release-notes/0.9.15.md +1 -1
- package/docs/migration/release-notes/0.9.16.md +1 -1
- package/docs/migration/release-notes/0.9.17.md +1 -1
- package/docs/migration/release-notes/0.9.19.md +1 -1
- package/docs/migration/release-notes/0.9.2.md +1 -1
- package/docs/migration/release-notes/README.md +28 -31
- package/docs/migration/v0.5-to-v0.6.md +759 -0
- package/docs/migration/v0.8-to-v0.9.md +1 -1
- package/docs/migration/v0.9-to-v0.10.md +507 -0
- package/docs/plans/0.9.2-agent-command-workflow-plan.md +423 -0
- package/docs/posts/README.md +30 -0
- package/docs/posts/akm-command-tour.md +495 -0
- package/docs/posts/akm-logo-sized.webp +0 -0
- package/docs/posts/belief-aware-memory-12.md +139 -0
- package/docs/posts/config-v2-lessons-16.md +191 -0
- package/docs/posts/improve-loop-autonomous-10.md +225 -0
- package/docs/posts/improve-pipeline-debugging-0803.md +179 -0
- package/docs/posts/intro-part-01.md +76 -0
- package/docs/posts/intro-part-02.md +221 -0
- package/docs/posts/intro-part-03.md +190 -0
- package/docs/posts/intro-part-04.md +221 -0
- package/docs/posts/llm-mode-reflect-13.md +166 -0
- package/docs/posts/openpalm-built-on-akm.md +86 -0
- package/docs/posts/progressive-disclosure-06.md +129 -0
- package/docs/posts/proposal-safety-net-15.md +112 -0
- package/docs/posts/release-0.5.0.md +247 -0
- package/docs/posts/release-0.6.0.md +117 -0
- package/docs/posts/release-0.7.0.md +159 -0
- package/docs/posts/release-0.8.0.md +332 -0
- package/docs/posts/scattered-skills-05.md +100 -0
- package/docs/posts/task-assets-persistent-workflows-11.md +222 -0
- package/docs/posts/team-skills-07.md +198 -0
- package/docs/posts/wiki-agent-knowledge-08.md +223 -0
- package/docs/posts/workflows-vaults-09.md +321 -0
- package/docs/product-surface.md +54 -0
- package/docs/reference/README.md +2 -2
- package/docs/reference/api.md +65 -0
- package/docs/reference/asset-types.md +166 -0
- package/docs/reference/bundle-types.md +2 -4
- package/docs/reference/cli.md +163 -192
- package/docs/reference/configuration.md +101 -20
- package/docs/reference/data-and-telemetry.md +2 -2
- package/docs/reference/env-and-secrets.md +126 -0
- package/docs/reference/memory.md +124 -0
- package/docs/reference/refs.md +156 -0
- package/docs/reference/registry.md +489 -0
- package/docs/reference/supported-formats.md +3 -4
- package/docs/reference/tasks.md +12 -19
- package/docs/reference/website-sources.md +141 -0
- package/docs/reference/workflow-schema.md +89 -317
- package/docs/reference/workflows.md +20 -48
- package/package.json +23 -16
- package/schemas/akm-config.json +2 -243
- package/schemas/akm-task.json +2 -3
- package/schemas/akm-workflow.json +47 -84
- package/dist/assets/improve-strategies/catchup.json +0 -41
- package/dist/assets/improve-strategies/proactive-maintenance.json +0 -24
- package/dist/assets/improve-strategies/quick.json +0 -17
- package/dist/assets/improve-strategies/reflect-distill.json +0 -29
- package/dist/assets/improve-strategies/thorough.json +0 -49
- package/dist/assets/prompts/retrieval-relevance-judge.md +0 -6
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +0 -6
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +0 -4
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +0 -4
- package/dist/cli/retired-commands.js +0 -118
- package/dist/commands/improve/retrieval-gate.js +0 -132
- package/dist/commands/tasks/validate.js +0 -176
- package/dist/core/config/legacy-source-shape-shim.js +0 -117
- package/dist/indexer/feedback/utility-policy.js +0 -75
- package/dist/integrations/harnesses/ids.js +0 -28
- package/dist/tasks/source/task-source-v3-frozen.js +0 -424
- package/dist/tasks/source/task-to-v4.js +0 -863
- package/dist/workflows/exec/worktree.js +0 -372
- package/dist/workflows/freeze/child-output-references.js +0 -83
- package/dist/workflows/freeze/identity.js +0 -22
- package/dist/workflows/freeze/targets/script.js +0 -50
- package/dist/workflows/freeze/targets/task.js +0 -124
- package/dist/workflows/github-yaml.js +0 -506
- package/dist/workflows/runtime/run-outputs.js +0 -80
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
# Indexing
|
|
2
|
+
|
|
3
|
+
`akm index` builds and refreshes the local SQLite search index.
|
|
4
|
+
|
|
5
|
+
By default it builds the local index and keeps metadata in the index.
|
|
6
|
+
Metadata is generated deterministically (`src/indexer/passes/metadata.ts`);
|
|
7
|
+
the LLM metadata-enhancement pass that used to run during indexing is
|
|
8
|
+
retired (0.9.17-alpha.9, see CHANGELOG). There is no top-level `llm` config
|
|
9
|
+
key in 0.9 — it is retired and hard-rejected at load; per-call tuning lives
|
|
10
|
+
on each named engine under `engines.<name>.*`.
|
|
11
|
+
|
|
12
|
+
## High-Level Flow
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
Resolve all sources (filesystem, git, website, npm) and materialise caches
|
|
16
|
+
↓
|
|
17
|
+
Walk files and classify assets
|
|
18
|
+
↓
|
|
19
|
+
Generate metadata from the asset
|
|
20
|
+
↓
|
|
21
|
+
Build weighted search fields
|
|
22
|
+
↓
|
|
23
|
+
Atomically apply entries + FTS projections + vector invalidation
|
|
24
|
+
↓
|
|
25
|
+
Reconcile removed sources and explicit --clean deletions
|
|
26
|
+
↓
|
|
27
|
+
Generate missing/stale embeddings when enabled
|
|
28
|
+
↓
|
|
29
|
+
Re-link preserved usage events and recompute utility scores
|
|
30
|
+
↓
|
|
31
|
+
Verify and report the final generation
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Cache materialisation runs through each source's `sync()` method
|
|
35
|
+
(`src/sources/providers/`) before the indexer walks `path()`.
|
|
36
|
+
|
|
37
|
+
## Search Field Mapping
|
|
38
|
+
|
|
39
|
+
`src/indexer/search/search-fields.ts` builds five FTS columns:
|
|
40
|
+
|
|
41
|
+
| Column | Contents |
|
|
42
|
+
| --- | --- |
|
|
43
|
+
| `name` | normalized asset name |
|
|
44
|
+
| `description` | description text |
|
|
45
|
+
| `tags` | tags + aliases |
|
|
46
|
+
| `hints` | `searchHints`, `examples`, `usage`, intent text, wiki xrefs, wiki page kind |
|
|
47
|
+
| `content` | bounded native/adapter body projection, TOC headings, and parameter names/descriptions |
|
|
48
|
+
|
|
49
|
+
The `content` column is intentionally lowest-weight. AKM-native Markdown body
|
|
50
|
+
prose is normalized and bounded at the adapter boundary; secrets, env values,
|
|
51
|
+
raw sessions, and session checkpoints never enter it. Longer structured
|
|
52
|
+
guidance such as `usage` and `intent` continues to feed `hints`.
|
|
53
|
+
|
|
54
|
+
Lexical retrieval uses one central progressive plan: Unicode letter/number
|
|
55
|
+
tokens are deduplicated and capped, then FTS executes strict AND, prefix-AND,
|
|
56
|
+
and—only if both miss—one OR/prefix-OR recovery query. Every stage feeds the
|
|
57
|
+
same BM25 normalization and downstream ranker; callers do not strip stopwords
|
|
58
|
+
or maintain alternate result collections.
|
|
59
|
+
|
|
60
|
+
## Modes
|
|
61
|
+
|
|
62
|
+
- incremental (default): drains only directories whose walked file set
|
|
63
|
+
changed, and within a drained directory re-persists only files whose
|
|
64
|
+
content hash, path, or adapter variant changed — an unchanged sibling keeps
|
|
65
|
+
its stored row, FTS rows, vector, and LLM enrichment untouched
|
|
66
|
+
- full (`akm index --full`): drains every directory and re-persists every
|
|
67
|
+
entry through the same id-preserving upsert, so vectors, utility scores
|
|
68
|
+
and usage links stay attached to unchanged entries
|
|
69
|
+
|
|
70
|
+
## Two files, one ref
|
|
71
|
+
|
|
72
|
+
A source can hold two files that claim one ref: a skill's `references/a.md` and
|
|
73
|
+
`knowledge/skills/x/references/a.md` are both `knowledge/skills/x/references/a`.
|
|
74
|
+
The index holds one row for the ref, and the file with the smaller path
|
|
75
|
+
(code-point order, the order `akm show`'s refusal lists them in) holds it,
|
|
76
|
+
whichever directories a run drains and in whatever order the walk finds them
|
|
77
|
+
(#1050). `akm index` reports each pair in its `warnings`, naming the file it
|
|
78
|
+
indexed and the one it skipped. A directory that gives a ref up is drained
|
|
79
|
+
again on later runs, so the ref passes to the other file when its holder is
|
|
80
|
+
deleted. `akm show` refuses such a ref (`RESOURCE_ALREADY_EXISTS`); search
|
|
81
|
+
returns the indexed file.
|
|
82
|
+
|
|
83
|
+
Each derived population keeps its own cursor, so a change to one pass's
|
|
84
|
+
inputs re-runs only that pass: `entries.content_hash` for entries and their
|
|
85
|
+
FTS rows (written in the same transaction), `embeddings.model` for vectors,
|
|
86
|
+
and `llm_enrichment_cache` (file path + body hash) for memory inference.
|
|
87
|
+
|
|
88
|
+
## Locks
|
|
89
|
+
|
|
90
|
+
`akm index` takes no blocking lock. #872 deliberately removed the index
|
|
91
|
+
rebuild's earlier 12-hour age-based-stale lease: the index is a fully
|
|
92
|
+
regenerable cache, so two concurrent rebuilds only waste work rather than
|
|
93
|
+
corrupt anything, and a live-but-wedged holder passed that lease's
|
|
94
|
+
PID-liveness check forever — only the age clock could ever free it, and that
|
|
95
|
+
cost one real install a half-day indexing outage. The `index.db.write.lock`
|
|
96
|
+
lease that remains (`src/indexer/index-writer-lock.ts`) is unrelated to
|
|
97
|
+
indexing since that removal; it only serializes actual asset-content
|
|
98
|
+
mutations (`remember`, `import`, `source update`, proposal apply) so two
|
|
99
|
+
writers cannot both pass a git exact-path preflight before either commits.
|
|
100
|
+
|
|
101
|
+
#956 added a second, opt-in, advisory-only sentinel:
|
|
102
|
+
`<dataDir>/index.rebuild.lock` (`getIndexRebuildLockPath()`), acquired and
|
|
103
|
+
released by every explicit `akm index` command run
|
|
104
|
+
(`src/indexer/index-rebuild-lock.ts`, built on the same PID-liveness-only
|
|
105
|
+
mechanics in `src/core/run-lock.ts` that `akm improve`'s whole-run lock
|
|
106
|
+
uses — no age-based stale reclaim, per the #872 lesson). It changes nothing
|
|
107
|
+
by default: a plain `akm index` that finds the lock already held just warns
|
|
108
|
+
and proceeds, contending with the other run exactly as before this lock
|
|
109
|
+
existed. Only `akm index --skip-if-locked` (intended for scheduled/
|
|
110
|
+
opportunistic callers — the shipped `index-refresh` task passes it) treats a
|
|
111
|
+
live holder as a reason to skip the run entirely and exit 0. This is
|
|
112
|
+
distinct from `ensureIndex()`'s implicit inline reindex (the read path's
|
|
113
|
+
bootstrap when the index is otherwise unusable): that path never consults
|
|
114
|
+
this lock, since a caller reaching it has no usable index to serve either
|
|
115
|
+
way and must proceed. The lock's "held" message names the pid that actually
|
|
116
|
+
holds it (the bun/node process) and, when the published launcher is
|
|
117
|
+
involved, the launcher pid alongside it — `pid 4242 (launcher 4240)`
|
|
118
|
+
(`createLockPayload`, `src/core/file-lock.ts`; `AKM_LAUNCHER_PID`, #956) —
|
|
119
|
+
since every process listing and task log shows the launcher pid, not the
|
|
120
|
+
child's.
|
|
121
|
+
|
|
122
|
+
The write path's targeted index upsert (`indexWrittenAssets`, used by
|
|
123
|
+
`remember`/`import`/`proposal accept`/`source clone`/extract session assets
|
|
124
|
+
to make a just-written asset searchable immediately) probes this same
|
|
125
|
+
rebuild lock before doing any work: a live holder means it skips the
|
|
126
|
+
upsert/embedding entirely with one log line and returns success right away
|
|
127
|
+
— the file write itself already succeeded, and the in-progress rebuild will
|
|
128
|
+
pick up the change on its own. This is a fail-open skip like every other
|
|
129
|
+
branch of `indexWrittenAssets`, not a failure: a caller that gates its own
|
|
130
|
+
result on this boolean (`proposal accept`, `source clone`) must not fail or
|
|
131
|
+
warn just because a rebuild happens to be running concurrently. It never
|
|
132
|
+
tries to acquire or reclaim the lock itself; reclaiming a dead-PID sentinel
|
|
133
|
+
stays `akm index`'s job.
|
|
134
|
+
|
|
135
|
+
**Embedding phase and transactions** (#954) —
|
|
136
|
+
`generateEmbeddingsForDb` (`src/indexer/materialize-embeddings.ts`) refuses
|
|
137
|
+
to run against a connection that already has a transaction open: its
|
|
138
|
+
per-batch `db.transaction()` calls are only a durable commit when `db` has
|
|
139
|
+
no ambient transaction, since one nested inside another SQLite transaction
|
|
140
|
+
runs as an unobservable SAVEPOINT instead. `akm bundle update`
|
|
141
|
+
(`src/commands/sources/installed-stashes.ts`) publishes the new content and
|
|
142
|
+
lock entry, then runs an ordinary `akmIndex` with no outer transaction, so
|
|
143
|
+
its embedding phase (`runEmbeddingPass`, `src/indexer/indexer.ts`) runs like
|
|
144
|
+
any other index run's. A failing embedding pass (provider down) still leaves
|
|
145
|
+
the update successful, with the reported `semanticStatus: "blocked"`
|
|
146
|
+
(surfaced on `akm bundle update`'s own JSON response, `index.semanticStatus`)
|
|
147
|
+
showing that semantic search fell behind, exactly like a plain `akm index`
|
|
148
|
+
run whose embedding phase fails.
|
|
149
|
+
|
|
150
|
+
## Mutation and finalization boundary
|
|
151
|
+
|
|
152
|
+
The canonical entry repository owns each complete synchronous mutation of
|
|
153
|
+
`index.db`: the `entries` row, its weighted `entries_fts` projection, its
|
|
154
|
+
`entry_fragments` safe Markdown (read by `akm show` for `#fragment` refs), and
|
|
155
|
+
stale vector invalidation are committed in one SQLite transaction. Entry
|
|
156
|
+
deletion removes FTS, fragment, vector, and utility children before the
|
|
157
|
+
parent row.
|
|
158
|
+
Callers do not maintain a dirty queue or request an incremental FTS rebuild.
|
|
159
|
+
The full `rebuildFts()` operation remains only as an explicit recovery verifier
|
|
160
|
+
for this regenerable database.
|
|
161
|
+
|
|
162
|
+
An explicit `akm index --clean` reconciles missing files after the filesystem
|
|
163
|
+
walk and before embedding, utility recomputation, totals, and verification.
|
|
164
|
+
Consequently `totalEntries`, FTS state, semantic verification, and
|
|
165
|
+
`clean.removed` all describe the same committed generation.
|
|
166
|
+
|
|
167
|
+
## Indexed Identity and Location
|
|
168
|
+
|
|
169
|
+
Every current `entries` row carries a canonical fully qualified
|
|
170
|
+
`item_ref` (`bundle//conceptId`), its `bundle_id` and `concept_id` provenance,
|
|
171
|
+
and the absolute `file_path` of the materialized local asset. Search and show
|
|
172
|
+
use those required columns for identity and access rather than reconstructing
|
|
173
|
+
refs from a name or source path. `item_ref` is the sole upsert conflict key;
|
|
174
|
+
`document_json` is the sole stored document projection. The schema does not
|
|
175
|
+
admit incomplete identity rows or retain an entry-key/path lookup fallback.
|
|
176
|
+
This preserves bundle identity when multiple sources contain the same concept.
|
|
177
|
+
|
|
178
|
+
## Embedding Phase
|
|
179
|
+
|
|
180
|
+
Once entries are upserted, `generateEmbeddingsForDb`
|
|
181
|
+
(`src/indexer/materialize-embeddings.ts`) generates and stores vectors for
|
|
182
|
+
every entry that does not already have one. **Fragments are never embedded
|
|
183
|
+
or searched** — `entry_fragments` only lets `akm show` select a section — so
|
|
184
|
+
every entry vector comes from that entry's own (capped, see below) search
|
|
185
|
+
text, which the pass derives from the stored document (`buildSearchText`),
|
|
186
|
+
and the embedding phase issues one embedder input per entry.
|
|
187
|
+
|
|
188
|
+
**Per-document cap** (`embedding.maxInputTokens`, default 512, #956) —
|
|
189
|
+
before batching, each pending document's search text is truncated to
|
|
190
|
+
this many estimated tokens (head only, unicode-safe) if it exceeds the cap;
|
|
191
|
+
a document is skipped only when its capped head is empty. This replaces
|
|
192
|
+
"one oversized document fails its whole batch" with "one oversized document
|
|
193
|
+
is embedded on its head" — llama.cpp rejects a single sequence longer than
|
|
194
|
+
its physical batch (`--ubatch-size`, default 512) with HTTP 500 ("input is
|
|
195
|
+
too large to process"), and the cap's default matches that common local
|
|
196
|
+
default. The materializer logs once per run how many entries were
|
|
197
|
+
truncated.
|
|
198
|
+
|
|
199
|
+
**Request batching** — `RemoteEmbedder.embedBatch` (`src/llm/embedders/remote.ts`)
|
|
200
|
+
groups (already-capped) texts into provider requests bounded by an estimated
|
|
201
|
+
token budget (`embedding.maxTokens`, default 6000 tokens, lowered from 8000
|
|
202
|
+
by #954 — see below) and a
|
|
203
|
+
document-count safety cap (`embedding.batchSize`, default 100) — the token
|
|
204
|
+
budget is what actually keeps a request inside the endpoint's context window
|
|
205
|
+
and the per-request timeout; the count cap only guards against many tiny
|
|
206
|
+
documents packing an oversized request. With the 512-token per-document cap
|
|
207
|
+
above, a request carries about 11 documents by default. A single document
|
|
208
|
+
whose own estimate still exceeds the token budget (only possible when
|
|
209
|
+
`maxInputTokens` is configured larger than `maxTokens`) is isolated and
|
|
210
|
+
skipped before ever going over HTTP. `embedding.contextLength` does NOT feed
|
|
211
|
+
this budget (#956) — it is Ollama's `num_ctx` only, forwarded
|
|
212
|
+
verbatim as `options.num_ctx` on the native `/api/embed` request (see the
|
|
213
|
+
embedding knobs table in `docs/reference/configuration.md`).
|
|
214
|
+
|
|
215
|
+
**Timeout** — each request is bounded by `embedding.timeoutMs` (positive
|
|
216
|
+
integer, default 120_000 — 120s, #954), used by both
|
|
217
|
+
`RemoteEmbedder.embed` and `requestBatch`. The prior fixed 30s cut off
|
|
218
|
+
exactly the field-report case: a local model server on a large
|
|
219
|
+
token-budget-bounded batch legitimately took longer than that, the timeout
|
|
220
|
+
fired mid-response with no retry, and every batch it hit was silently
|
|
221
|
+
dropped for the rest of an hours-long run. `embedding.timeoutMs` is the
|
|
222
|
+
budget for a request at the FULL token budget; a smaller request gets a
|
|
223
|
+
proportionally smaller timeout, `clamp(timeoutMs × requestTokens /
|
|
224
|
+
tokenBudget, 30_000, timeoutMs)` (2026-09-09 field-review follow-up), so a dead
|
|
225
|
+
endpoint is detected in seconds on the common case of small documents
|
|
226
|
+
instead of always waiting out the full configured budget.
|
|
227
|
+
|
|
228
|
+
**Concurrency** — provider batches are dispatched through a bounded pool
|
|
229
|
+
(`concurrentMap`) instead of strictly sequentially. Default width (unset
|
|
230
|
+
`embedding.concurrency`) — `resolveEmbeddingConcurrency`
|
|
231
|
+
(`src/llm/embedders/remote.ts`) derives it via the shared
|
|
232
|
+
`defaultConcurrencyForEndpoint` classifier (`src/core/loopback.ts`):
|
|
233
|
+
**1** for a loopback endpoint (a local model server serves one inference at
|
|
234
|
+
a time; parallel requests thrash it) and **2** for a remote one.
|
|
235
|
+
`embedding.concurrency` (positive
|
|
236
|
+
integer, 1-16, #954) overrides this default — added after
|
|
237
|
+
field evidence that a multi-slot local server (llama.cpp `--parallel N`,
|
|
238
|
+
vLLM) genuinely serves parallel requests and sat idle under the fixed
|
|
239
|
+
default. Request SIZE remains the first throughput lever regardless (see
|
|
240
|
+
Request batching above); the override exists for a server that actually
|
|
241
|
+
serves parallel slots, not as a blanket "go faster" knob. A caller abort
|
|
242
|
+
(`signal.aborted`) still propagates once the pool drains, even though
|
|
243
|
+
`concurrentMap` itself swallows per-item throws.
|
|
244
|
+
|
|
245
|
+
**Context-size split-and-retry** — a batch rejected specifically for
|
|
246
|
+
exceeding the endpoint's context window (HTTP 413, or a recognised
|
|
247
|
+
context-size error body such as `exceed_context_size_error`, or llama.cpp's
|
|
248
|
+
own physical-batch rejection — `input is too large to process`, `physical
|
|
249
|
+
batch size`, `ubatch`, #954) is split in half and retried recursively
|
|
250
|
+
rather than discarded whole, down to individual documents; a single
|
|
251
|
+
document that still fails this way becomes a
|
|
252
|
+
`context-window-exceeded` skip.
|
|
253
|
+
|
|
254
|
+
**Run-scoped adaptive budget** (#954, field report on beta.1) — the
|
|
255
|
+
4-chars-per-token estimator undercounts dense technical text by 7-55%,
|
|
256
|
+
which the default budget change above only partly absorbs: an endpoint with
|
|
257
|
+
a smaller real context window, or a configured `embedding.maxTokens` too big
|
|
258
|
+
for it, still sees a steady trickle of rejections. On the FIRST context-size
|
|
259
|
+
rejection of an `embedBatch` run, the effective request budget shrinks to
|
|
260
|
+
three quarters of its current value — floored at twice
|
|
261
|
+
`embedding.maxInputTokens`, so it can never drop below batching at least one
|
|
262
|
+
document per request — for every batch not yet dispatched; the still-planned
|
|
263
|
+
tail of pending documents is re-batched at the smaller budget
|
|
264
|
+
(`buildTokenBoundedBatches`), and one default-level line reports the new
|
|
265
|
+
value. This never touches the rejected batch's OWN split-and-retry above,
|
|
266
|
+
and never fires a second time in the same run even if a later batch is also
|
|
267
|
+
rejected — a budget that is simply too big for the endpoint should
|
|
268
|
+
self-correct once per run, not ratchet down indefinitely.
|
|
269
|
+
|
|
270
|
+
**Timeout back-off-and-retry** (#954, 2026-09-09 field-review follow-up)
|
|
271
|
+
— a request TIMEOUT never drops its batch outright: field
|
|
272
|
+
confirmation showed that once akm abandons a timed-out request the endpoint
|
|
273
|
+
(e.g. llama-server) keeps computing it anyway, so dropping it immediately
|
|
274
|
+
just grows the provider's queue while every following batch dies the same
|
|
275
|
+
way. Instead, on a timeout, `RemoteEmbedder.embedBatch` backs off (5s,
|
|
276
|
+
doubling, capped at 60s — in practice always the formula's first term, since
|
|
277
|
+
a given request size is only ever retried once before it splits or is
|
|
278
|
+
skipped) so the provider can drain the abandoned request, then retries the
|
|
279
|
+
SAME request once. A second timeout on that retry splits the batch in half
|
|
280
|
+
(like a context-size rejection) and retries each half the same way, down to
|
|
281
|
+
single documents; a single document that times out twice is finally skipped
|
|
282
|
+
with a default-level `warn`. Any other failure (network error, a
|
|
283
|
+
non-timeout HTTP failure, malformed response) still skips the whole batch
|
|
284
|
+
immediately at any size, as before — a genuinely broken batch does not get
|
|
285
|
+
retried into a storm of smaller requests against a down endpoint.
|
|
286
|
+
|
|
287
|
+
**Circuit breaker** (#954) — the
|
|
288
|
+
embedding phase stops dispatching further provider requests and ends the
|
|
289
|
+
pass as a failure once either of two consecutive-failure streaks reaches 3:
|
|
290
|
+
failures at single-document size (timeout OR network error — a
|
|
291
|
+
multi-document timeout is not by itself evidence the endpoint is dead,
|
|
292
|
+
since it is retried and split smaller before ever being reported as failed
|
|
293
|
+
at single-document size), or network errors at ANY size (never retried, so
|
|
294
|
+
trusted immediately regardless of size). `context-window-exceeded` never
|
|
295
|
+
counts — it proves the provider IS reachable — and resets both streaks
|
|
296
|
+
instead. The pass ends with: `embedding provider failed 3 consecutive
|
|
297
|
+
batches (last: <reason>); stopped after <N> embeddings were stored — rerun
|
|
298
|
+
akm index when the endpoint is healthy`. Every batch already committed is
|
|
299
|
+
kept; a genuine caller abort (Ctrl-C, the improve budget) is a separate code
|
|
300
|
+
path and stays distinguishable. Mechanically, the materializer's `onSkip`
|
|
301
|
+
callback (policy lives with the caller, not the embedder) returns `false`
|
|
302
|
+
on the batch that trips a threshold; `RemoteEmbedder.embedBatch` honors
|
|
303
|
+
that through its existing dispatch-abort controller — the same one an
|
|
304
|
+
`onBatch` persistence failure already used to stop further dispatch — with
|
|
305
|
+
a distinct reason, and resolves normally with whatever results already
|
|
306
|
+
landed rather than rejecting. This is what turns an hours-long grind
|
|
307
|
+
against a dead provider (the field report's own symptom) into a fast,
|
|
308
|
+
visible failure instead.
|
|
309
|
+
|
|
310
|
+
**Per-batch commit** — each provider (or local-embedder) batch is written to
|
|
311
|
+
`index.db` inside its own short `db.transaction()` as it completes, via an
|
|
312
|
+
`onBatch` callback threaded through both `RemoteEmbedder` and `LocalEmbedder`.
|
|
313
|
+
Earlier releases buffered every vector in memory and wrote them all in one
|
|
314
|
+
transaction at the very end of the whole run — an interruption (a competing
|
|
315
|
+
indexer collision, a killed process, any thrown error) discarded everything
|
|
316
|
+
already computed. Per-batch commit keeps whatever landed before the
|
|
317
|
+
interruption and keeps the exclusive-write window short enough for
|
|
318
|
+
`akm remember`/`akm improve` to interleave on the same stash.
|
|
319
|
+
|
|
320
|
+
**Progress and throughput** — a progress line (`Embedded N/M entries.`) is
|
|
321
|
+
emitted after EVERY committed batch (#954 — the earlier 500-stored-entries
|
|
322
|
+
bucketing left a non-verbose run silent for its entire embedding phase on
|
|
323
|
+
any run smaller than 500 entries), and the heartbeat (every 15s while
|
|
324
|
+
waiting on the provider) names both the live stored AND failed counts:
|
|
325
|
+
`Still generating embeddings: X/N stored, F failed; waiting on embedding
|
|
326
|
+
provider.` The final line reports throughput: `Stored N embeddings in Xs
|
|
327
|
+
(Y.Y entries/s, ~Z tokens/s).` `Z` sums the estimate of the capped text
|
|
328
|
+
`embedBatch` actually transmitted for each stored entry, not the entry's
|
|
329
|
+
raw pre-cap search text (#954) — otherwise every entry over
|
|
330
|
+
`embedding.maxInputTokens` inflated the reported rate. A failed provider
|
|
331
|
+
batch itself logs at the
|
|
332
|
+
default `warn` level, not `--verbose`-only, naming the batch size and
|
|
333
|
+
reason — a silently grinding, hours-long run against a dead provider with
|
|
334
|
+
one aggregate warning at the very end was the field report's own symptom.
|
|
335
|
+
In the `akm index` CLI, phase-start messages and the heartbeat reach stderr
|
|
336
|
+
in non-verbose JSON/yaml output mode too (via `info()`); text mode keeps
|
|
337
|
+
its spinner instead, and `--verbose` gets everything, including the
|
|
338
|
+
high-frequency per-batch line JSON mode deliberately omits.
|
|
339
|
+
|
|
340
|
+
**Embedding model per row** — every `embeddings` row records the model it
|
|
341
|
+
was generated under (`embeddings.model`, the provider fingerprint:
|
|
342
|
+
`remote:<embedding.model>|<dimension>` for a remote endpoint,
|
|
343
|
+
`local:<localModel>` otherwise), and the configured fingerprint is recorded
|
|
344
|
+
in `index_meta.embeddingFingerprint` before the first provider request of a
|
|
345
|
+
pass (#956). That column is the pass's cursor: an entry is embedded when it
|
|
346
|
+
has no row for the configured model, so a model change re-embeds entry by
|
|
347
|
+
entry with per-batch commits — nothing is purged first, an interrupted run
|
|
348
|
+
resumes with only the entries still on the old model, and readers serve
|
|
349
|
+
only the configured model's rows in the meantime. `akm index --reembed` is the one path
|
|
350
|
+
that discards every stored vector. `upsertEntry` deletes an entry's vector
|
|
351
|
+
when the hash of its search text (`entries.embed_hash`) changes; `akm index --full` keeps entry ids, so it
|
|
352
|
+
re-embeds only changed text. (Until layout 24 a model-string change ran a
|
|
353
|
+
re-embed "canary" and a full rebuild copied vectors aside into
|
|
354
|
+
`embedding_salvage`, #955; both are gone.)
|
|
355
|
+
|
|
356
|
+
## Progress Reporting
|
|
357
|
+
|
|
358
|
+
- text mode: shows a spinner with processed-versus-total source counts
|
|
359
|
+
- `--verbose`: prints every phase progress message to stderr, including the
|
|
360
|
+
high-frequency per-batch `Embedded N/M entries.` line
|
|
361
|
+
- non-verbose structured output (`json`, `yaml`, `jsonl`, #954):
|
|
362
|
+
emits clean machine-readable output on stdout, but phase-start messages
|
|
363
|
+
and the embedding heartbeat (`Still generating embeddings: X/N stored, F
|
|
364
|
+
failed; waiting on embedding provider.`) now reach stderr via `info()` too
|
|
365
|
+
— a stalled run used to print nothing at all until the whole run finished,
|
|
366
|
+
indistinguishable from "no database open, nothing written" (field
|
|
367
|
+
report). The per-batch `Embedded N/M entries.` line is deliberately
|
|
368
|
+
excluded here (that would be spam, not a heartbeat).
|
|
369
|
+
- source-cache hydration (`ensureSourceCaches`, `src/indexer/search/search-source.ts`,
|
|
370
|
+
#954) — which runs BEFORE `index.db` is even opened — reports
|
|
371
|
+
`Hydrating source i/n: <name>` per source about to sync, plus a 15s
|
|
372
|
+
heartbeat while that source's sync is in flight, through the same
|
|
373
|
+
progress channel.
|
|
374
|
+
|
|
375
|
+
## Database Tables
|
|
376
|
+
|
|
377
|
+
`index.db`'s schema (`ensureSchema()`,
|
|
378
|
+
`src/storage/repositories/index-schema.ts`) creates 14 logical
|
|
379
|
+
tables, including one FTS5 virtual table. Full column-level detail lives in
|
|
380
|
+
[Storage Locations](storage-locations.md#dataindexdb--main-search-index);
|
|
381
|
+
this is a purpose summary:
|
|
382
|
+
|
|
383
|
+
| Table | Purpose |
|
|
384
|
+
| --- | --- |
|
|
385
|
+
| `entries` | normalized asset records |
|
|
386
|
+
| `entries_fts` (virtual, FTS5) | multi-column full-text index |
|
|
387
|
+
| `entry_fragments` | safe Markdown projection retained per parent entry for fragment resolution |
|
|
388
|
+
| `embeddings` | stored embedding vectors, each tagged with its model; vector search scans them |
|
|
389
|
+
| `utility_scores` | recomputed utility boost state (global) |
|
|
390
|
+
| `index_meta` | schema/version/runtime metadata |
|
|
391
|
+
| `index_dir_state` | incremental-indexing cache (per-directory hash + mtime) |
|
|
392
|
+
| `llm_enrichment_cache` | cached memory-inference results |
|
|
393
|
+
| `registry_index_cache` | cached registry index JSON (replaces flat cache files) |
|
|
394
|
+
|
|
395
|
+
`usage_events` (search/show/feedback telemetry) and workflow runtime state
|
|
396
|
+
both live in `state.db`, not `index.db`, so rebuildable search state remains
|
|
397
|
+
separate from durable runtime state.
|
|
398
|
+
|
|
399
|
+
## Schema Versioning
|
|
400
|
+
|
|
401
|
+
`index.db` is derived state, rebuildable from sources by `akm index`, but it
|
|
402
|
+
holds work that is expensive to redo (embeddings, the LLM enrichment cache),
|
|
403
|
+
so a layout change is applied in place rather than by discarding the index.
|
|
404
|
+
`index_meta.version` (currently 24) is a layout marker, not a gate:
|
|
405
|
+
|
|
406
|
+
- `ensureSchema()` (`src/storage/repositories/index-schema.ts`), run by the
|
|
407
|
+
writable opener, is additive: `CREATE ... IF NOT EXISTS`, `ALTER TABLE ...
|
|
408
|
+
ADD COLUMN` for columns added later (`embeddings.model`,
|
|
409
|
+
`index_dir_state.row_count`/`index_variant`), and a one-time rebuild of
|
|
410
|
+
both FTS tables from `entries` / `entry_fragments` when they still carry
|
|
411
|
+
the layout-23 content copies (seconds at 24k entries). It never drops
|
|
412
|
+
`embeddings`, `utility_scores*`, or `llm_enrichment_cache`. The one
|
|
413
|
+
exception is the LLM entity graph (`graph_meta`, `graph_files`,
|
|
414
|
+
`graph_file_*`), retired in 0.9.17-alpha.9: those tables are dropped
|
|
415
|
+
unconditionally. An index without `entry_fragments` (layout 22 and
|
|
416
|
+
older) also has its per-directory cursor cleared so the next run
|
|
417
|
+
re-reads every source and fills the fragments; entry ids, and therefore
|
|
418
|
+
embeddings, stay put.
|
|
419
|
+
- An `entries` table older than layout 21 (no `item_ref`, or still the retired
|
|
420
|
+
`entry_key` columns, as 0.9.1 wrote it) cannot be keyed by this release: its
|
|
421
|
+
entries-keyed tables are recreated and re-walked, keeping the LLM enrichment
|
|
422
|
+
cache.
|
|
423
|
+
- Read-only and existing-database openers never refuse over the marker: an
|
|
424
|
+
older layout is served as-is (readers handle both FTS layouts and a missing
|
|
425
|
+
`embeddings.model`), a newer one likewise, each named once on stderr.
|
|
426
|
+
- On-disk corruption (`SQLITE_CORRUPT`) is the one case that deletes the file
|
|
427
|
+
and rebuilds from scratch (#865).
|
|
428
|
+
|
|
429
|
+
Durable workflow, task, proposal, event, and usage state in `state.db` is
|
|
430
|
+
never touched by these paths.
|
|
431
|
+
|
|
432
|
+
The workflow `.md` adapter compiles directly to source IR version 1.
|
|
433
|
+
The index stores only the ordinary normalized `entries` row and searchable
|
|
434
|
+
metadata derived from that IR. It does not cache a second workflow AST or an
|
|
435
|
+
executable plan. Starting a run recompiles the authored source once and freezes
|
|
436
|
+
the sole durable plan format into `state.db`.
|
|
437
|
+
|
|
438
|
+
## Metadata Sources
|
|
439
|
+
|
|
440
|
+
AKM now treats file-derived metadata as the primary runtime source. It derives
|
|
441
|
+
metadata from signals such as:
|
|
442
|
+
|
|
443
|
+
- frontmatter
|
|
444
|
+
- comments / headers
|
|
445
|
+
- filenames
|
|
446
|
+
- `package.json`
|
|
447
|
+
- renderer-specific extraction (workflow params, TOC, vault key hints, wiki metadata)
|
|
448
|
+
|
|
449
|
+
The live indexer no longer reads `.stash.json` at all — since the 0.9.0
|
|
450
|
+
cutover it is a migrator-only concern: the storage migrator folds each
|
|
451
|
+
sidecar's overrides into the asset's inline metadata (frontmatter or header
|
|
452
|
+
comments) and deletes the sidecar. See `docs/architecture/internals/storage-locations.md`.
|
|
453
|
+
|
|
454
|
+
## Parameters
|
|
455
|
+
|
|
456
|
+
Structured parameters can come from:
|
|
457
|
+
|
|
458
|
+
- command placeholders (`$ARGUMENTS`, `$1`-`$9`, `{{named}}`)
|
|
459
|
+
- frontmatter `params`
|
|
460
|
+
- script comment extraction
|
|
461
|
+
- workflow markdown parameters
|
|
462
|
+
|
|
463
|
+
Parameter names and descriptions are stored structurally and also fed into the
|
|
464
|
+
lowest-weight `content` field.
|
|
465
|
+
|
|
466
|
+
## Quality Values
|
|
467
|
+
|
|
468
|
+
The `quality` field on an index entry tracks how its metadata was produced.
|
|
469
|
+
Well-known values (defined in `src/indexer/passes/metadata.ts`):
|
|
470
|
+
|
|
471
|
+
| Value | Meaning |
|
|
472
|
+
| --- | --- |
|
|
473
|
+
| `"generated"` | metadata derived automatically from file content |
|
|
474
|
+
| `"enriched"` | metadata produced by or updated via an LLM enrichment pass |
|
|
475
|
+
| `"curated"` | metadata written or explicitly approved by a human |
|
|
476
|
+
| `"proposed"` | metadata from a proposal awaiting review |
|
|
477
|
+
|
|
478
|
+
The `"enriched"` marker was set by the now-retired LLM metadata-enhancement
|
|
479
|
+
pass (see CHANGELOG, 0.9.17-alpha.9); it is still recognized on entries an
|
|
480
|
+
earlier release enriched, but nothing sets it anymore.
|
|
481
|
+
|
|
482
|
+
## Utility Recomputation
|
|
483
|
+
|
|
484
|
+
Utility scores are rebuilt from `usage_events`.
|
|
485
|
+
|
|
486
|
+
- old events are purged on a rolling window
|
|
487
|
+
- event history is preserved through schema resets/full rebuilds
|
|
488
|
+
- decay is based on elapsed time, not on how often indexing runs
|
|
489
|
+
- utility is a secondary boost, not the primary ranking signal
|
|
490
|
+
|
|
491
|
+
## Semantic Search Integration
|
|
492
|
+
|
|
493
|
+
When semantic search is enabled:
|
|
494
|
+
|
|
495
|
+
- semantic readiness is tracked in `semantic-status.json`
|
|
496
|
+
- provider fingerprints include model/dimension for remote configs, deliberately EXCLUDING the endpoint — moving the same model+dimension to a different host does not force a rebuild
|
|
497
|
+
- fingerprint changes force semantic status back to pending until a rebuild
|
|
498
|
+
- vector search is an exact cosine scan of `embeddings` in JavaScript; no extension is needed
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Registry network boundary
|
|
2
|
+
|
|
3
|
+
All HTTP(S) traffic used to discover or install registry content passes
|
|
4
|
+
through `fetchRegistry` / `fetchRegistryJson` in `src/registry/network.ts`.
|
|
5
|
+
The boundary is plain `fetch()` plus a request timeout, bounded retries on
|
|
6
|
+
network failure / timeout / 429 / 5xx (honoring a capped `Retry-After`), a
|
|
7
|
+
byte cap on the response body, and classified errors: a request that fails
|
|
8
|
+
after retries, or whose body can't be used, always leaves as an `AkmError` —
|
|
9
|
+
never a raw, unclassified exit 70.
|
|
10
|
+
|
|
11
|
+
- Not found / unusable response (HTTP 404/410, or a body that isn't valid
|
|
12
|
+
JSON / isn't shaped as expected) -> `NotFoundError` (exit 1).
|
|
13
|
+
- Every other non-2xx status, and connection failure / timeout after retries
|
|
14
|
+
are exhausted -> `TransientError` (`REGISTRY_UNREACHABLE`, exit 75).
|
|
15
|
+
- A malformed registry URL, an embedded `user:pass@`, or a non-http(s) scheme
|
|
16
|
+
-> `ConfigError` (`REGISTRY_URL_INVALID`, exit 78).
|
|
17
|
+
|
|
18
|
+
Callers: `src/registry/providers/static-index.ts`, `providers/skills-sh.ts`,
|
|
19
|
+
`src/registry/resolve.ts` (npm and GitHub metadata), `src/setup/registry-stash-loader.ts`,
|
|
20
|
+
and `src/sources/providers/provider-utils.ts`'s `downloadArchive` (npm tarball
|
|
21
|
+
download, used by `sources/providers/npm.ts`). Credentials (a resolved GitHub
|
|
22
|
+
token, etc.) are injected by the caller as ordinary `headers` on the request —
|
|
23
|
+
this module does not resolve credentials itself. HTTPS is not required by
|
|
24
|
+
`fetchRegistry` itself: `--allow-insecure-transport`/HTTPS enforcement happens
|
|
25
|
+
once, where a URL enters configuration (`akm registry add`, `akm bundle add`),
|
|
26
|
+
per `AGENTS.md`'s "Unsafe CLI overrides" policy.
|
|
27
|
+
|
|
28
|
+
## What this boundary does *not* do
|
|
29
|
+
|
|
30
|
+
Earlier releases pinned every registry request's DNS resolution: they
|
|
31
|
+
resolved and classified the hostname's A/AAAA answers, rejected loopback /
|
|
32
|
+
private / link-local / cloud-metadata / reserved addresses, connected to the
|
|
33
|
+
one validated numeric address (never re-resolving at connect time), and
|
|
34
|
+
re-validated on every retry and redirect hop. Because Bun's fetch client
|
|
35
|
+
cannot pin a TLS connection to a literal address while retaining SNI, that
|
|
36
|
+
DNS-pinned transport spawned a short-lived Node child process per request to
|
|
37
|
+
do the actual connect, over a bounded stdin/stdout framing protocol.
|
|
38
|
+
|
|
39
|
+
That pinning, and the subprocess that implemented it
|
|
40
|
+
(`pinned-transport.ts`, `pinned-request-helper.ts`), were deleted as
|
|
41
|
+
over-engineering for this codebase's actual threat model: registry URLs are
|
|
42
|
+
either the built-in registry or a URL an operator explicitly configured
|
|
43
|
+
(`akm registry add`, `AKM_REGISTRY_URL`, `AKM_NPM_REGISTRY`) — a deliberate
|
|
44
|
+
human command, not third-party input akm fetches on an untrusted caller's
|
|
45
|
+
behalf (see `AGENTS.md`'s "Defensive Code" test 3). The subprocess-per-request
|
|
46
|
+
design was also the direct cause of registry network failures surfacing as an
|
|
47
|
+
unclassified exit 70 instead of a typed error, a symptom fixed repeatedly
|
|
48
|
+
before this simplification (see CHANGELOG history around the registry HTTP
|
|
49
|
+
stack). `src/core/network-policy.ts`'s address classifier is unrelated to this
|
|
50
|
+
boundary now; it still backs the `website` source provider's own SSRF guard
|
|
51
|
+
(`src/sources/snapshot-fetchers/host-guard.ts`), which fetches arbitrary
|
|
52
|
+
operator-pasted URLs and keeps its own justification for that guard.
|
|
53
|
+
|
|
54
|
+
Registry-derived `source: git` entries are still rejected before an install
|
|
55
|
+
ref can reach `git ls-remote` or clone — that check lives in
|
|
56
|
+
`src/registry/providers/static-index.ts` and is independent of the network
|
|
57
|
+
boundary.
|