akm-cli 0.9.17-alpha.2 → 0.9.17-alpha.4
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 +756 -0
- package/dist/akm +94 -196
- package/dist/cli/shared.js +6 -2
- package/dist/cli.js +22 -9
- package/dist/commands/agent/agent-dispatch.js +1 -1
- package/dist/commands/command/command-execution.js +24 -62
- package/dist/commands/feedback-cli.js +0 -1
- package/dist/commands/health/accept-rate.js +2 -2
- package/dist/commands/health/checks.js +30 -75
- package/dist/commands/health/config-skew.js +38 -0
- package/dist/commands/health/egress.js +54 -0
- package/dist/commands/health/html-report.js +0 -38
- package/dist/commands/health/improve-metrics.js +123 -562
- package/dist/commands/health/plugin-staleness.js +53 -3
- package/dist/commands/health/renderers.js +12 -4
- package/dist/commands/health/report-view-model.js +11 -106
- package/dist/commands/health/types-improve.js +4 -19
- package/dist/commands/health/windows.js +64 -73
- package/dist/commands/health.js +122 -143
- package/dist/commands/improve/consolidate/chunking.js +25 -100
- package/dist/commands/improve/consolidate/sanitize.js +54 -149
- package/dist/commands/improve/consolidate.js +538 -1075
- package/dist/commands/improve/content-hash.js +16 -24
- package/dist/commands/improve/distill/content-repair.js +18 -100
- package/dist/commands/improve/distill-guards.js +20 -81
- package/dist/commands/improve/distill-promotion-policy.js +23 -243
- package/dist/commands/improve/distill.js +608 -1075
- package/dist/commands/improve/eligibility.js +126 -400
- package/dist/commands/improve/execution.js +3 -5
- package/dist/commands/improve/extract.js +487 -1046
- package/dist/commands/improve/feedback-valence.js +0 -25
- package/dist/commands/improve/improve-cli.js +29 -166
- package/dist/commands/improve/improve-result-file.js +10 -66
- package/dist/commands/improve/improve-strategies.js +12 -7
- package/dist/commands/improve/improve-usage-report.js +18 -64
- package/dist/commands/improve/improve.js +443 -1063
- package/dist/commands/improve/ledger.js +114 -0
- package/dist/commands/improve/locks.js +2 -8
- package/dist/commands/improve/loop-stages.js +459 -1172
- package/dist/commands/improve/memory/derived-ref.js +12 -77
- package/dist/commands/improve/memory/memory-belief.js +14 -118
- package/dist/commands/improve/memory/memory-improve.js +4 -3
- package/dist/commands/improve/outcome-loop.js +28 -156
- package/dist/commands/improve/planner.js +5 -10
- package/dist/commands/improve/preparation.js +851 -2339
- package/dist/commands/improve/proactive-maintenance.js +34 -101
- package/dist/commands/improve/reflect-noise.js +104 -280
- package/dist/commands/improve/reflect.js +621 -1367
- package/dist/commands/improve/salience.js +46 -232
- package/dist/commands/improve/session-asset.js +19 -100
- package/dist/commands/improve/stage.js +323 -0
- package/dist/commands/proposal/drain.js +251 -644
- package/dist/commands/proposal/proposal-cli.js +3 -18
- package/dist/commands/proposal/proposal-types.js +20 -41
- package/dist/commands/proposal/proposal.js +1 -2
- package/dist/commands/proposal/propose.js +134 -160
- package/dist/commands/proposal/repository.js +502 -1487
- package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
- package/dist/commands/proposal/validators/proposal-validators.js +1 -1
- package/dist/commands/proposal/validators/proposals.js +13 -89
- package/dist/commands/read/curate.js +63 -413
- package/dist/commands/read/search-cli.js +16 -33
- package/dist/commands/read/search.js +17 -23
- package/dist/commands/read/show.js +2 -13
- package/dist/commands/sources/bundle-cli.js +25 -2
- package/dist/commands/sources/bundle-config-ops.js +7 -0
- package/dist/commands/sources/dangerous-env-audit.js +1 -2
- package/dist/commands/sources/info.js +2 -11
- package/dist/commands/sources/installed-stashes.js +197 -746
- package/dist/commands/sources/schema-repair.js +98 -129
- package/dist/commands/sources/source-add.js +62 -12
- package/dist/commands/sources/stash-cli.js +1 -1
- package/dist/commands/tasks/explain.js +10 -13
- package/dist/commands/tasks/tasks-cli.js +9 -8
- package/dist/commands/tasks/tasks.js +326 -930
- package/dist/commands/tasks/validate.js +42 -21
- package/dist/commands/workflow/plan.js +22 -29
- package/dist/commands/workflow-cli.js +4 -4
- package/dist/core/adapter/adapters/akm-adapter.js +0 -1
- package/dist/core/adapter/adapters/akm-lint.js +2 -3
- package/dist/core/adapter/adapters/akm-metadata.js +11 -12
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +17 -29
- package/dist/core/asset/resolve-ref.js +1 -1
- package/dist/core/bundle-id.js +42 -5
- package/dist/core/bundle-rename.js +291 -0
- package/dist/core/config/config-io.js +1 -2
- package/dist/core/config/config-schema.js +1 -33
- package/dist/core/config/config-walker.js +1 -1
- package/dist/core/config/config.js +163 -68
- package/dist/core/config/legacy-source-shape-shim.js +38 -9
- package/dist/core/config/schema/embedding.js +20 -5
- package/dist/core/config/schema/engines.js +5 -0
- package/dist/core/config/schema/execution.js +1 -1
- package/dist/core/config/schema/experimental.js +1 -1
- package/dist/core/config/schema/improve-processes.js +21 -95
- package/dist/core/config/schema/improve.js +4 -42
- package/dist/core/config/schema/scheduler.js +12 -12
- package/dist/core/config/schema/search.js +6 -22
- package/dist/core/env-secret-ref.js +0 -1
- package/dist/core/errors.js +8 -9
- package/dist/core/file-lock.js +76 -173
- package/dist/core/logs-db.js +2 -2
- package/dist/core/paths.js +0 -27
- package/dist/core/redaction.js +109 -2
- package/dist/core/run-lock.js +2 -5
- package/dist/core/spawn-env.js +1 -1
- package/dist/core/state/migrations.js +108 -61
- package/dist/core/state-db-scope.js +2 -4
- package/dist/core/state-db.js +126 -692
- package/dist/core/type-presentation.js +1 -9
- package/dist/core/write-source.js +293 -1012
- package/dist/execution/input-contract.js +1 -1
- package/dist/execution/resolved-request.js +135 -689
- package/dist/execution/source.js +63 -257
- package/dist/execution/target-ref.js +1 -1
- package/dist/indexer/bundle-identity-guard.js +2 -2
- package/dist/indexer/db/graph-db.js +106 -46
- package/dist/indexer/ensure-index.js +44 -85
- package/dist/indexer/graph/graph-extraction.js +340 -562
- package/dist/indexer/graph/graph-related.js +130 -0
- package/dist/indexer/index-rebuild-lock.js +3 -11
- package/dist/indexer/index-writer-lock.js +8 -17
- package/dist/indexer/index-written-assets.js +139 -151
- package/dist/indexer/indexer.js +524 -846
- package/dist/indexer/materialize-embeddings.js +60 -397
- package/dist/indexer/passes/memory-inference.js +81 -90
- package/dist/indexer/passes/metadata.js +132 -200
- package/dist/indexer/read-preflight.js +0 -7
- package/dist/indexer/scan/doc-to-entry.js +1 -3
- package/dist/indexer/scan/drain-dir.js +1 -1
- package/dist/indexer/search/db-search.js +181 -590
- package/dist/indexer/search/fts-query.js +30 -41
- package/dist/indexer/search/ranking.js +28 -154
- package/dist/indexer/search/search-attribution.js +12 -32
- package/dist/indexer/search/search-fields.js +11 -15
- package/dist/indexer/search/search-hit-enrichers.js +54 -85
- package/dist/indexer/search/search-source.js +1 -4
- package/dist/indexer/usage/usage-events.js +2 -7
- package/dist/integrations/agent/engine-fallback.js +23 -40
- package/dist/integrations/agent/engine-resolution.js +93 -183
- package/dist/integrations/agent/execution.js +507 -0
- package/dist/integrations/agent/model-map.js +28 -156
- package/dist/integrations/agent/request-lowering.js +66 -141
- package/dist/integrations/agent/runner-dispatch.js +143 -321
- package/dist/integrations/agent/runner.js +54 -14
- package/dist/integrations/lockfile.js +53 -101
- package/dist/llm/embedders/deterministic.js +2 -3
- package/dist/llm/embedders/profile.js +71 -0
- package/dist/llm/embedders/remote.js +10 -15
- package/dist/llm/graph-extract.js +3 -12
- package/dist/llm/index-passes.js +3 -5
- package/dist/llm/memory-infer.js +1 -2
- package/dist/llm/metadata-enhance.js +1 -2
- package/dist/llm/structured-call.js +5 -24
- package/dist/output/generic-render.js +23 -11
- package/dist/output/html-render.js +13 -10
- package/dist/output/render-registry.js +3 -32
- package/dist/output/shapes/helpers.js +2 -34
- package/dist/output/shapes/passthrough.js +1 -9
- package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
- package/dist/output/text/command-format.js +60 -23
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +5 -14
- package/dist/output/text/proposal-format.js +1 -2
- package/dist/output/text/workflow-format.js +0 -32
- package/dist/output/text.js +2 -0
- package/dist/registry/factory.js +4 -19
- package/dist/registry/network.js +66 -220
- package/dist/registry/providers/index.js +0 -2
- package/dist/registry/providers/skills-sh.js +3 -14
- package/dist/registry/providers/static-index.js +24 -26
- package/dist/registry/resolve.js +55 -131
- package/dist/scripts/akm-migrate-node.js +43937 -93313
- package/dist/scripts/akm-migrate.js +43697 -93071
- package/dist/setup/registry-stash-loader.js +4 -13
- package/dist/setup/semantic-assets.js +3 -44
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/tasks.js +25 -15
- package/dist/sources/provider-factory.js +17 -18
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +7 -1
- package/dist/sources/providers/git-provider.js +0 -3
- package/dist/sources/providers/git-stash.js +0 -17
- package/dist/sources/providers/npm.js +2 -4
- package/dist/sources/providers/provider-utils.js +5 -10
- package/dist/sources/providers/website.js +0 -2
- package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
- package/dist/sources/website-url.js +2 -2
- package/dist/storage/database.js +9 -35
- package/dist/storage/repositories/improve-ledger-repository.js +168 -0
- package/dist/storage/repositories/index-connection.js +34 -70
- package/dist/storage/repositories/index-entries-repository.js +69 -111
- package/dist/storage/repositories/index-entry-mapper.js +1 -2
- package/dist/storage/repositories/index-entry-schema.js +83 -269
- package/dist/storage/repositories/index-fts-repository.js +86 -256
- package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
- package/dist/storage/repositories/index-meta-repository.js +6 -4
- package/dist/storage/repositories/index-schema.js +192 -220
- package/dist/storage/repositories/index-utility-repository.js +8 -29
- package/dist/storage/repositories/index-vec-repository.js +133 -414
- package/dist/storage/repositories/outcome-repository.js +2 -1
- package/dist/storage/repositories/proposals-repository.js +35 -0
- package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
- package/dist/storage/repositories/task-history-repository.js +26 -4
- package/dist/storage/repositories/workflow-runs-repository.js +53 -244
- package/dist/storage/sqlite-migrations.js +136 -0
- package/dist/storage/sqlite-pragmas.js +11 -9
- package/dist/storage/sqlite-transaction.js +170 -0
- package/dist/storage/state-db-integrity.js +34 -27
- package/dist/tasks/activation-config.js +134 -62
- package/dist/tasks/backends/cron.js +129 -277
- package/dist/tasks/backends/exec-utils.js +2 -5
- package/dist/tasks/backends/launchd.js +125 -745
- package/dist/tasks/backends/schtasks.js +101 -620
- package/dist/tasks/prepare/prepare-support.js +5 -15
- package/dist/tasks/prepare/prepare.js +0 -2
- package/dist/tasks/resolve-akm-bin.js +20 -79
- package/dist/tasks/run/attempt-lifecycle.js +0 -1
- package/dist/tasks/scheduler-binding.js +18 -238
- package/dist/tasks/scheduler-invocation.js +52 -52
- package/dist/tasks/scheduler-lock.js +53 -0
- package/dist/tasks/scheduler-sync.js +363 -679
- package/dist/tasks/source/parse-task-source.js +160 -10
- package/dist/tasks/source/task-source-v3-frozen.js +3 -4
- package/dist/tasks/source/task-to-v4.js +2 -2
- package/dist/workflows/authoring/authoring.js +3 -12
- package/dist/workflows/compile.js +211 -0
- package/dist/workflows/concurrency-policy.js +13 -74
- package/dist/workflows/exec/child-invocation.js +3 -17
- package/dist/workflows/exec/child-workflow.js +32 -141
- package/dist/workflows/exec/dispatch-redaction.js +13 -53
- package/dist/workflows/exec/environment.js +98 -0
- package/dist/workflows/exec/exec-unit.js +33 -140
- package/dist/workflows/exec/frozen-judge.js +7 -59
- package/dist/workflows/exec/native-executor.js +82 -341
- package/dist/workflows/exec/param-secrets.js +29 -47
- package/dist/workflows/exec/run-workflow.js +154 -387
- package/dist/workflows/exec/scheduler.js +9 -36
- package/dist/workflows/exec/step-work.js +127 -430
- package/dist/workflows/exec/unit-dispatch.js +11 -63
- package/dist/workflows/exec/unit-writer.js +8 -52
- package/dist/workflows/exec/worktree.js +39 -273
- package/dist/workflows/freeze/child-output-references.js +4 -15
- package/dist/workflows/freeze/environment.js +99 -92
- package/dist/workflows/freeze/freeze.js +172 -0
- package/dist/workflows/freeze/step-values.js +19 -21
- package/dist/workflows/freeze/targets/child-workflow.js +23 -92
- package/dist/workflows/freeze/targets/command.js +10 -33
- package/dist/workflows/freeze/targets/script.js +5 -12
- package/dist/workflows/freeze/targets/shell.js +3 -6
- package/dist/workflows/freeze/targets/task.js +25 -80
- package/dist/workflows/freeze/task-bindings.js +20 -67
- package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
- package/dist/workflows/ir/params.js +6 -51
- package/dist/workflows/ir/plan-hash.js +2 -34
- package/dist/workflows/parser.js +140 -43
- package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
- package/dist/workflows/renderer.js +36 -69
- package/dist/workflows/resource-limits.js +12 -120
- package/dist/workflows/runtime/agent-identity.js +8 -40
- package/dist/workflows/runtime/run-outputs.js +3 -6
- package/dist/workflows/runtime/run-plan.js +316 -0
- package/dist/workflows/runtime/runs.js +48 -200
- package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
- package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/integration/bundling-akm.md +49 -42
- package/docs/migration/README.md +1 -0
- package/docs/migration/release-notes/0.9.17.md +41 -0
- package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
- package/docs/reference/cli.md +182 -125
- package/docs/reference/configuration.md +49 -56
- package/docs/reference/data-and-telemetry.md +19 -20
- package/docs/reference/tasks.md +86 -38
- package/docs/reference/workflow-schema.md +14 -18
- package/docs/reference/workflows.md +6 -9
- package/package.json +1 -1
- package/schemas/akm-config.json +87 -406
- package/dist/commands/health/advisories.js +0 -150
- package/dist/commands/health/metrics.js +0 -329
- package/dist/commands/health/surfaces.js +0 -102
- package/dist/commands/improve/anti-collapse.js +0 -83
- package/dist/commands/improve/collapse-detector.js +0 -432
- package/dist/commands/improve/consolidate/eligibility.js +0 -48
- package/dist/commands/improve/consolidate/merge.js +0 -146
- package/dist/commands/improve/distill/promote-memory.js +0 -329
- package/dist/commands/improve/distill/quality-gate.js +0 -500
- package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
- package/dist/commands/improve/proposal-envelope.js +0 -31
- package/dist/commands/improve/run-context.js +0 -123
- package/dist/commands/improve/shared.js +0 -21
- package/dist/commands/improve/source-identity.js +0 -28
- package/dist/commands/improve/triage.js +0 -96
- package/dist/commands/proposal/drain-policies.js +0 -151
- package/dist/commands/sources/update-transaction.js +0 -220
- package/dist/core/action-contributors.js +0 -28
- package/dist/core/config/config-version-shim.js +0 -101
- package/dist/core/config/retired-experimental-keys-shim.js +0 -62
- package/dist/core/fs-txn.js +0 -405
- package/dist/core/lexical-score.js +0 -25
- package/dist/core/maintenance-barrier.js +0 -167
- package/dist/execution/executable-identity.js +0 -105
- package/dist/execution/guarded-source.js +0 -427
- package/dist/indexer/graph/graph-boost.js +0 -427
- package/dist/indexer/graph/graph-dedup.js +0 -95
- package/dist/indexer/search/name-match.js +0 -35
- package/dist/indexer/search/ranking-contributors.js +0 -515
- package/dist/indexer/walk/project-context.js +0 -192
- package/dist/integrations/agent/execution-cascade.js +0 -566
- package/dist/integrations/agent/execution-definitions.js +0 -202
- package/dist/integrations/agent/execution-lowering.js +0 -841
- package/dist/integrations/agent/execution-preparation.js +0 -98
- package/dist/integrations/agent/inline-execution.js +0 -74
- package/dist/registry/create-provider-registry.js +0 -29
- package/dist/registry/pinned-request-helper.js +0 -247
- package/dist/registry/pinned-transport.js +0 -717
- package/dist/sources/providers/index.js +0 -14
- package/dist/storage/engines/sqlite-migrations.js +0 -271
- package/dist/storage/repositories/canaries-repository.js +0 -107
- package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
- package/dist/storage/repositories/registry-cache.js +0 -113
- package/dist/tasks/scheduler-sync-preview.js +0 -52
- package/dist/workflows/freeze/resolve-steps.js +0 -86
- package/dist/workflows/freeze/source-freeze.js +0 -64
- package/dist/workflows/ir/compile.js +0 -321
- package/dist/workflows/ir/environment-v4.js +0 -330
- package/dist/workflows/ir/freeze-v4.js +0 -153
- package/dist/workflows/ir/schema-v4.js +0 -745
- package/dist/workflows/ir/schema.js +0 -354
- package/dist/workflows/program/schema.js +0 -78
- package/dist/workflows/runtime/checkin.js +0 -57
- package/dist/workflows/runtime/plan-classifier.js +0 -196
- package/dist/workflows/runtime/unit-checkin.js +0 -45
- package/dist/workflows/runtime/unit-phases.js +0 -20
- package/dist/workflows/schema.js +0 -4
- package/dist/workflows/source-ir/compile.js +0 -200
- package/dist/workflows/source-ir/program.js +0 -50
- package/dist/workflows/source-ir/result.js +0 -26
- package/dist/workflows/source-ir/schema.js +0 -786
- package/dist/workflows/source-ir/triggers.js +0 -79
- package/dist/workflows/source-ir/uses.js +0 -40
- package/dist/workflows/validator.js +0 -60
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
export const IMPROVE_LEDGER_OUTCOMES = [
|
|
5
|
+
"proposed",
|
|
6
|
+
"accepted",
|
|
7
|
+
"rejected",
|
|
8
|
+
"quality_rejected",
|
|
9
|
+
"review_needed",
|
|
10
|
+
"expired",
|
|
11
|
+
"unchanged",
|
|
12
|
+
"failed",
|
|
13
|
+
"judged_no_action",
|
|
14
|
+
];
|
|
15
|
+
const MS_PER_DAY = 86_400_000;
|
|
16
|
+
const DETAIL_MAX_CHARS = 500;
|
|
17
|
+
/**
|
|
18
|
+
* Post-rejection windows by source: reflect 14 d, distill 30 d, every other
|
|
19
|
+
* source 7 d — the constants the rejection backoff always used.
|
|
20
|
+
*/
|
|
21
|
+
export const LEDGER_REJECTION_WINDOW_DAYS = Object.freeze({
|
|
22
|
+
reflect: 14,
|
|
23
|
+
distill: 30,
|
|
24
|
+
});
|
|
25
|
+
export const LEDGER_DEFAULT_REJECTION_WINDOW_DAYS = 7;
|
|
26
|
+
/** A proposal nobody reviewed inside the retention window: short grace, not a rejection backoff. */
|
|
27
|
+
export const LEDGER_EXPIRED_GRACE_DAYS = 1;
|
|
28
|
+
/** Revisit cadence for a ref the stage looked at and had nothing to do (or is still pending). */
|
|
29
|
+
export const LEDGER_REVISIT_CADENCE_DAYS = 7;
|
|
30
|
+
/**
|
|
31
|
+
* Outcomes whose window a fresh signal on the asset (new feedback, a content
|
|
32
|
+
* change) cannot lift. Every other window is a revisit cadence that a signal
|
|
33
|
+
* newer than `last_attempt_at` lifts.
|
|
34
|
+
*/
|
|
35
|
+
export const LEDGER_HARD_OUTCOMES = new Set([
|
|
36
|
+
"rejected",
|
|
37
|
+
"quality_rejected",
|
|
38
|
+
"expired",
|
|
39
|
+
]);
|
|
40
|
+
function windowDays(source, outcome) {
|
|
41
|
+
switch (outcome) {
|
|
42
|
+
case "rejected":
|
|
43
|
+
case "quality_rejected":
|
|
44
|
+
return LEDGER_REJECTION_WINDOW_DAYS[source] ?? LEDGER_DEFAULT_REJECTION_WINDOW_DAYS;
|
|
45
|
+
case "expired":
|
|
46
|
+
return LEDGER_EXPIRED_GRACE_DAYS;
|
|
47
|
+
case "unchanged":
|
|
48
|
+
case "judged_no_action":
|
|
49
|
+
case "proposed":
|
|
50
|
+
case "review_needed":
|
|
51
|
+
return LEDGER_REVISIT_CADENCE_DAYS;
|
|
52
|
+
case "accepted":
|
|
53
|
+
case "failed":
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The single cadence function: when a `(source, outcome)` recorded at
|
|
59
|
+
* `fromIso` becomes eligible again, or `null` for "immediately".
|
|
60
|
+
*/
|
|
61
|
+
export function nextEligibleAt(source, outcome, fromIso) {
|
|
62
|
+
const from = Date.parse(fromIso);
|
|
63
|
+
if (!Number.isFinite(from))
|
|
64
|
+
return null;
|
|
65
|
+
const days = windowDays(source, outcome);
|
|
66
|
+
return days === null ? null : new Date(from + days * MS_PER_DAY).toISOString();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Whether the ledger blocks another attempt on this row at `nowIso`.
|
|
70
|
+
* `signalSinceIso` is the newest signal on the asset (feedback, content
|
|
71
|
+
* change); a signal newer than the last attempt lifts a soft window but never
|
|
72
|
+
* a hard one ({@link LEDGER_HARD_OUTCOMES}).
|
|
73
|
+
*/
|
|
74
|
+
export function isLedgerBlocked(row, nowIso, signalSinceIso) {
|
|
75
|
+
if (!row?.nextEligibleAt)
|
|
76
|
+
return false;
|
|
77
|
+
if (row.nextEligibleAt <= nowIso)
|
|
78
|
+
return false;
|
|
79
|
+
if (LEDGER_HARD_OUTCOMES.has(row.outcome))
|
|
80
|
+
return true;
|
|
81
|
+
return !(signalSinceIso !== undefined && signalSinceIso > row.lastAttemptAt);
|
|
82
|
+
}
|
|
83
|
+
function toRow(row) {
|
|
84
|
+
return {
|
|
85
|
+
stashDir: row.stash_dir,
|
|
86
|
+
ref: row.ref,
|
|
87
|
+
source: row.source,
|
|
88
|
+
lastAttemptAt: row.last_attempt_at,
|
|
89
|
+
// Tolerate an outcome a newer release may add: it still carries a window.
|
|
90
|
+
outcome: row.outcome,
|
|
91
|
+
nextEligibleAt: row.next_eligible_at,
|
|
92
|
+
proposalId: row.proposal_id,
|
|
93
|
+
detail: row.detail,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function trimDetail(detail) {
|
|
97
|
+
if (detail === undefined)
|
|
98
|
+
return null;
|
|
99
|
+
const trimmed = detail.trim();
|
|
100
|
+
if (trimmed.length === 0)
|
|
101
|
+
return null;
|
|
102
|
+
return trimmed.length > DETAIL_MAX_CHARS ? `${trimmed.slice(0, DETAIL_MAX_CHARS - 1)}…` : trimmed;
|
|
103
|
+
}
|
|
104
|
+
/** Record an attempt on `(stashDir, ref, source)`: upsert the row and its cadence. */
|
|
105
|
+
export function recordImproveLedger(db, input) {
|
|
106
|
+
const row = {
|
|
107
|
+
stashDir: input.stashDir,
|
|
108
|
+
ref: input.ref,
|
|
109
|
+
source: input.source,
|
|
110
|
+
lastAttemptAt: input.at,
|
|
111
|
+
outcome: input.outcome,
|
|
112
|
+
nextEligibleAt: nextEligibleAt(input.source, input.outcome, input.at),
|
|
113
|
+
proposalId: input.proposalId ?? null,
|
|
114
|
+
detail: trimDetail(input.detail),
|
|
115
|
+
};
|
|
116
|
+
db.prepare(`INSERT INTO improve_ledger
|
|
117
|
+
(stash_dir, ref, source, last_attempt_at, outcome, next_eligible_at, proposal_id, detail)
|
|
118
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
119
|
+
ON CONFLICT(stash_dir, ref, source) DO UPDATE SET
|
|
120
|
+
last_attempt_at = excluded.last_attempt_at,
|
|
121
|
+
outcome = excluded.outcome,
|
|
122
|
+
next_eligible_at = excluded.next_eligible_at,
|
|
123
|
+
proposal_id = excluded.proposal_id,
|
|
124
|
+
detail = excluded.detail`).run(row.stashDir, row.ref, row.source, row.lastAttemptAt, row.outcome, row.nextEligibleAt, row.proposalId, row.detail);
|
|
125
|
+
return row;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Record a decision (accept / reject / expire / revert) on the proposal a row
|
|
129
|
+
* was minted for. The row is found by `proposal_id` — the proposal's ref may
|
|
130
|
+
* differ from the ledger key (a distill proposal for `lessons/x` is keyed by
|
|
131
|
+
* its input `memories/x`) — and `last_attempt_at` is kept: the window starts
|
|
132
|
+
* at the decision, the attempt happened when it happened. A proposal no row
|
|
133
|
+
* knows (minted before the ledger existed) gets a row keyed by its own ref.
|
|
134
|
+
*/
|
|
135
|
+
export function recordImproveLedgerDecision(db, input) {
|
|
136
|
+
const changes = db
|
|
137
|
+
.prepare(`UPDATE improve_ledger
|
|
138
|
+
SET outcome = ?, next_eligible_at = ?, detail = ?
|
|
139
|
+
WHERE stash_dir = ? AND proposal_id = ?`)
|
|
140
|
+
.run(input.outcome, nextEligibleAt(input.source, input.outcome, input.at), trimDetail(input.detail), input.stashDir, input.proposalId).changes;
|
|
141
|
+
if (Number(changes) > 0)
|
|
142
|
+
return;
|
|
143
|
+
recordImproveLedger(db, {
|
|
144
|
+
stashDir: input.stashDir,
|
|
145
|
+
ref: input.ref,
|
|
146
|
+
source: input.source,
|
|
147
|
+
outcome: input.outcome,
|
|
148
|
+
at: input.at,
|
|
149
|
+
proposalId: input.proposalId,
|
|
150
|
+
...(input.detail !== undefined ? { detail: input.detail } : {}),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
export function getImproveLedgerRow(db, stashDir, ref, source) {
|
|
154
|
+
const row = db
|
|
155
|
+
.prepare(`SELECT stash_dir, ref, source, last_attempt_at, outcome, next_eligible_at, proposal_id, detail
|
|
156
|
+
FROM improve_ledger WHERE stash_dir = ? AND ref = ? AND source = ?`)
|
|
157
|
+
.get(stashDir, ref, source);
|
|
158
|
+
return row ? toRow(row) : undefined;
|
|
159
|
+
}
|
|
160
|
+
/** Every row for one stash, optionally narrowed to `sources`. */
|
|
161
|
+
export function listImproveLedgerRows(db, stashDir, sources) {
|
|
162
|
+
const sourceFilter = sources && sources.length > 0 ? ` AND source IN (${sources.map(() => "?").join(", ")})` : "";
|
|
163
|
+
const rows = db
|
|
164
|
+
.prepare(`SELECT stash_dir, ref, source, last_attempt_at, outcome, next_eligible_at, proposal_id, detail
|
|
165
|
+
FROM improve_ledger WHERE stash_dir = ?${sourceFilter} ORDER BY ref ASC, source ASC`)
|
|
166
|
+
.all(stashDir, ...(sources && sources.length > 0 ? sources : []));
|
|
167
|
+
return rows.map(toRow);
|
|
168
|
+
}
|
|
@@ -4,14 +4,13 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* `index.db` connection lifecycle for the storage layer.
|
|
6
6
|
*
|
|
7
|
-
* Opens/closes the index database,
|
|
8
|
-
*
|
|
9
|
-
* indexer, so the storage loan helpers (`index-db.ts`, `registry-cache.ts`)
|
|
7
|
+
* Opens/closes the index database, running `ensureSchema` on the managed
|
|
8
|
+
* (writable) open path. This module lives BELOW the
|
|
9
|
+
* indexer, so the storage loan helpers (`index-db.ts`, `registry-index-cache-repository.ts`)
|
|
10
10
|
* import their opener from a sibling here instead of reaching up into the
|
|
11
11
|
* indexer — inverting the old storage→indexer arrow.
|
|
12
12
|
*/
|
|
13
13
|
import fs from "node:fs";
|
|
14
|
-
import { createRequire } from "node:module";
|
|
15
14
|
import { ConfigError } from "../../core/errors.js";
|
|
16
15
|
import { classifyPathAccess, describeInaccessiblePath } from "../../core/path-access.js";
|
|
17
16
|
import { getDbPath } from "../../core/paths.js";
|
|
@@ -20,9 +19,8 @@ import { openDatabase } from "../database.js";
|
|
|
20
19
|
import { openManagedDatabase } from "../managed-db.js";
|
|
21
20
|
import { SQLITE_BUSY_TIMEOUT_MS } from "../sqlite-pragmas.js";
|
|
22
21
|
import { openSqliteReadSnapshot, SqliteReadSnapshotUnavailableError } from "../sqlite-read-snapshot.js";
|
|
23
|
-
import { CANONICAL_INDEX_DB_VERSION
|
|
24
|
-
import { ensureSchema } from "./index-schema.js";
|
|
25
|
-
import { loadVecExtension, warnIfVecMissing } from "./index-vec-repository.js";
|
|
22
|
+
import { CANONICAL_INDEX_DB_VERSION } from "./index-entry-schema.js";
|
|
23
|
+
import { ensureSchema, newerIndexLayoutError } from "./index-schema.js";
|
|
26
24
|
/**
|
|
27
25
|
* Whether `error` is SQLite reporting on-disk corruption (`SQLITE_CORRUPT`,
|
|
28
26
|
* "database disk image is malformed") rather than a permission, lock, or
|
|
@@ -41,21 +39,11 @@ export function openIndexDatabase(dbPath, options) {
|
|
|
41
39
|
const spec = {
|
|
42
40
|
path: resolvedPath,
|
|
43
41
|
init: (db) => {
|
|
44
|
-
// Try to load sqlite-vec extension
|
|
45
|
-
loadVecExtension(db);
|
|
46
42
|
// Source update uses this narrow lifecycle seam to ATTACH state.db and
|
|
47
43
|
// open its coordinator-owned outer transaction before ensureSchema or
|
|
48
44
|
// any indexer write can mutate the live generation.
|
|
49
45
|
options?.beforeSchema?.(db);
|
|
50
|
-
|
|
51
|
-
// config so unparameterised opens (registry providers, graph helpers,
|
|
52
|
-
// ad-hoc CLI subcommands) honour the operator-declared dimension. Only if
|
|
53
|
-
// both are absent do we fall through to the no-clobber path, which keeps
|
|
54
|
-
// ensureSchema from touching `index_meta.embeddingDim` at all.
|
|
55
|
-
const resolvedDim = options?.embeddingDim ?? resolveConfiguredEmbeddingDim();
|
|
56
|
-
ensureSchema(db, resolvedDim);
|
|
57
|
-
// Warn once at init if using JS fallback with many entries
|
|
58
|
-
warnIfVecMissing(db, { once: true });
|
|
46
|
+
ensureSchema(db);
|
|
59
47
|
},
|
|
60
48
|
};
|
|
61
49
|
try {
|
|
@@ -66,10 +54,9 @@ export function openIndexDatabase(dbPath, options) {
|
|
|
66
54
|
// (see src/core/state-db.ts's "Why a separate database from index.db"
|
|
67
55
|
// note) — so real on-disk corruption is recovered by deleting the file
|
|
68
56
|
// and rebuilding, not by surfacing a raw SQLITE_CORRUPT to the caller or
|
|
69
|
-
// quietly falling through to an unreadable index. This
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
// even opening, so the file itself has to go first).
|
|
57
|
+
// quietly falling through to an unreadable index (#865). This is the ONE
|
|
58
|
+
// from-scratch rebuild: an older layout is migrated in place by
|
|
59
|
+
// ensureSchema, never dropped.
|
|
73
60
|
if (!isCorruptionError(error))
|
|
74
61
|
throw error;
|
|
75
62
|
warn(`Index database is corrupt at ${resolvedPath} — rebuilding.`);
|
|
@@ -85,34 +72,9 @@ export function openIndexDatabase(dbPath, options) {
|
|
|
85
72
|
return openManagedDatabase(spec);
|
|
86
73
|
}
|
|
87
74
|
}
|
|
88
|
-
/**
|
|
89
|
-
* Read the operator-configured embedding dimension from the on-disk config.
|
|
90
|
-
* Returns `undefined` when no config file is present, when the config has
|
|
91
|
-
* no `embedding.dimension` set, or when reading the config throws (e.g.
|
|
92
|
-
* inside isolated test fixtures with no XDG home). Failure is silent on
|
|
93
|
-
* purpose — every openDatabase() call would otherwise have to handle a
|
|
94
|
-
* config-not-found error path, and the fallback (no-clobber semantics) is
|
|
95
|
-
* already correct.
|
|
96
|
-
*/
|
|
97
|
-
function resolveConfiguredEmbeddingDim() {
|
|
98
|
-
try {
|
|
99
|
-
const esmRequire = createRequire(import.meta.url);
|
|
100
|
-
const { loadConfig } = esmRequire("../../core/config/config");
|
|
101
|
-
const dim = loadConfig().embedding?.dimension;
|
|
102
|
-
if (typeof dim === "number" && Number.isInteger(dim) && dim > 0 && dim <= 4096) {
|
|
103
|
-
return dim;
|
|
104
|
-
}
|
|
105
|
-
return undefined;
|
|
106
|
-
}
|
|
107
|
-
catch {
|
|
108
|
-
return undefined;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
75
|
export function openExistingDatabase(dbPath) {
|
|
112
|
-
// Existing-DB callers do not mutate schema or embedding metadata on open
|
|
113
|
-
//
|
|
114
|
-
// handle, so no current reader can accidentally serve a populated legacy
|
|
115
|
-
// table and fail later on its first canonical-column query.
|
|
76
|
+
// Existing-DB callers do not mutate schema or embedding metadata on open;
|
|
77
|
+
// they serve an older layout as-is and refuse a newer one (see checkIndexLayout).
|
|
116
78
|
//
|
|
117
79
|
// "Existing" is load-bearing: a missing file throws instead of being
|
|
118
80
|
// created. Create-on-open used to leave a schema-less index.db behind (a
|
|
@@ -126,15 +88,9 @@ export function openExistingDatabase(dbPath) {
|
|
|
126
88
|
if (classifyPathAccess(resolvedPath).access === "absent") {
|
|
127
89
|
throw new Error(`Index database not found at ${resolvedPath}. Run 'akm index' to build it.`);
|
|
128
90
|
}
|
|
129
|
-
const db = openManagedDatabase({
|
|
130
|
-
path: resolvedPath,
|
|
131
|
-
init: (db) => {
|
|
132
|
-
loadVecExtension(db);
|
|
133
|
-
},
|
|
134
|
-
create: false,
|
|
135
|
-
});
|
|
91
|
+
const db = openManagedDatabase({ path: resolvedPath, create: false });
|
|
136
92
|
try {
|
|
137
|
-
|
|
93
|
+
checkIndexLayout(db, resolvedPath);
|
|
138
94
|
return db;
|
|
139
95
|
}
|
|
140
96
|
catch (error) {
|
|
@@ -143,21 +99,29 @@ export function openExistingDatabase(dbPath) {
|
|
|
143
99
|
}
|
|
144
100
|
}
|
|
145
101
|
/**
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
102
|
+
* A reader serves an older layout as-is (the FTS readers understand both
|
|
103
|
+
* layouts, and a missing table degrades at the caller — keyword-only search,
|
|
104
|
+
* an inline rebuild, or a "run akm index" notice) and names it once per
|
|
105
|
+
* process; the next writable open migrates it in place. A newer layout is
|
|
106
|
+
* refused, naming the upgrade ({@link newerIndexLayoutError}).
|
|
149
107
|
*/
|
|
150
|
-
function
|
|
151
|
-
|
|
108
|
+
function checkIndexLayout(db, resolvedPath) {
|
|
109
|
+
let stored;
|
|
110
|
+
try {
|
|
111
|
+
const row = db.prepare("SELECT value FROM index_meta WHERE key = 'version'").get();
|
|
112
|
+
if (!row)
|
|
113
|
+
return;
|
|
114
|
+
stored = Number(row.value);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
152
117
|
return;
|
|
153
|
-
const classification = classifyIndexGeneration(db);
|
|
154
|
-
const stored = classification.storedVersion ?? "unknown";
|
|
155
|
-
if (classification.status === "newer") {
|
|
156
|
-
throw new ConfigError(`Index database at ${resolvedPath} was built by a newer akm (stored generation ${stored}; ` +
|
|
157
|
-
`this binary understands ${CANONICAL_INDEX_DB_VERSION}). Upgrade akm to use this index.`, "INDEX_SCHEMA_INCOMPATIBLE", "Upgrade akm to a version that understands this index generation.");
|
|
158
118
|
}
|
|
159
|
-
|
|
160
|
-
|
|
119
|
+
if (!Number.isFinite(stored) || stored === CANONICAL_INDEX_DB_VERSION)
|
|
120
|
+
return;
|
|
121
|
+
if (stored > CANONICAL_INDEX_DB_VERSION)
|
|
122
|
+
throw newerIndexLayoutError(stored, resolvedPath);
|
|
123
|
+
warnOnce(`index-db-layout:${resolvedPath}`, `Index database at ${resolvedPath} uses an older layout (${stored}; this akm writes ${CANONICAL_INDEX_DB_VERSION}). ` +
|
|
124
|
+
"Serving it as-is; the next 'akm index' migrates it in place.");
|
|
161
125
|
}
|
|
162
126
|
/**
|
|
163
127
|
* Refuse to treat an UNREADABLE index as a missing one (#791).
|
|
@@ -219,7 +183,7 @@ export function openReadonlyExistingDatabase(dbPath, options) {
|
|
|
219
183
|
// connection, so apply just that one.
|
|
220
184
|
try {
|
|
221
185
|
db.exec(`PRAGMA busy_timeout = ${SQLITE_BUSY_TIMEOUT_MS}`);
|
|
222
|
-
|
|
186
|
+
checkIndexLayout(db, resolvedPath);
|
|
223
187
|
return db;
|
|
224
188
|
}
|
|
225
189
|
catch (error) {
|