akm-cli 0.9.17-alpha.3 → 0.9.17-alpha.5
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 +760 -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/lint/base-linter.js +19 -5
- 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 +4 -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/source-manage.js +9 -2
- 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/asset-placement.js +4 -13
- 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 +43940 -93320
- package/dist/scripts/akm-migrate.js +43700 -93078
- 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 +361 -751
- 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 -441
- 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
package/dist/core/redaction.js
CHANGED
|
@@ -317,6 +317,85 @@ function addPlainMatches(coverageDelta, text, needle) {
|
|
|
317
317
|
offset = match + needle.length;
|
|
318
318
|
}
|
|
319
319
|
}
|
|
320
|
+
/**
|
|
321
|
+
* Name components (after splitting an identifier on `_`/`-` and camelCase
|
|
322
|
+
* boundaries) that mark a `NAME=value` / `NAME: value` pair as
|
|
323
|
+
* credential-shaped regardless of length — the free-text-pattern sibling of
|
|
324
|
+
* `isInferredSecretName` in `src/tasks/log-redaction.ts`, which does the same
|
|
325
|
+
* job for environment variable names. Bare-word matching only: this
|
|
326
|
+
* deliberately does NOT flag "author" ("auth" is not a whole word/component
|
|
327
|
+
* of "author", the same anchoring reasoning `isInferredSecretName` documents)
|
|
328
|
+
* nor prose like "token budget" (no `=`/`:` for the pattern below to anchor
|
|
329
|
+
* on in the first place).
|
|
330
|
+
*/
|
|
331
|
+
const CREDENTIAL_KEY_WORDS = new Set(["password", "passwd", "secret", "token", "auth", "credential", "credentials"]);
|
|
332
|
+
/** Split an identifier into lowercase words at `_`/`-` and camelCase boundaries. */
|
|
333
|
+
function identifierWords(identifier) {
|
|
334
|
+
return identifier
|
|
335
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1_$2")
|
|
336
|
+
.toLowerCase()
|
|
337
|
+
.split(/[_-]+/)
|
|
338
|
+
.filter(Boolean);
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* True when `identifier` names a credential by shape: a whole word from
|
|
342
|
+
* {@link CREDENTIAL_KEY_WORDS}, or `api[_-]?key` / `private[_-]?key` in any
|
|
343
|
+
* of their glued, snake_case, kebab-case or camelCase spellings.
|
|
344
|
+
*/
|
|
345
|
+
function isCredentialLikeKeyName(identifier) {
|
|
346
|
+
const lower = identifier.toLowerCase();
|
|
347
|
+
if (lower.includes("apikey") || lower.includes("privatekey"))
|
|
348
|
+
return true;
|
|
349
|
+
const words = identifierWords(identifier);
|
|
350
|
+
for (let i = 0; i < words.length; i++) {
|
|
351
|
+
const word = words[i];
|
|
352
|
+
if (CREDENTIAL_KEY_WORDS.has(word))
|
|
353
|
+
return true;
|
|
354
|
+
if ((word === "api" || word === "private") && words[i + 1] === "key")
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* `NAME=value` / `NAME: value`, name captured in group 1, separator in group
|
|
361
|
+
* 2. Source string (not a shared `RegExp`, which would carry `lastIndex`
|
|
362
|
+
* state across calls) for {@link redactNamedCredentialValues} to instantiate
|
|
363
|
+
* fresh each call.
|
|
364
|
+
*/
|
|
365
|
+
const NAMED_CREDENTIAL_VALUE_SOURCE = String.raw `\b([A-Za-z][A-Za-z0-9_-]*)(\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^\s,;"']+)`;
|
|
366
|
+
/**
|
|
367
|
+
* Redact `NAME=value` / `NAME: value` pairs whose name is credential-shaped
|
|
368
|
+
* (see {@link isCredentialLikeKeyName}).
|
|
369
|
+
*
|
|
370
|
+
* Not a plain `input.replace(re, fn)`: the greedy unquoted-value alternative
|
|
371
|
+
* happily matches straight through a NESTED assignment when a non-credential
|
|
372
|
+
* name comes first with no separator of its own — `"config: DB_PASSWORD=…"`
|
|
373
|
+
* matches name `config` with value `DB_PASSWORD=…` (one contiguous
|
|
374
|
+
* whitespace-free run), and a plain global replace treats that as ONE
|
|
375
|
+
* consumed, non-matching span and never revisits `DB_PASSWORD=…` on its own,
|
|
376
|
+
* silently leaking the credential. Rejecting a non-credential candidate here
|
|
377
|
+
* instead rewinds the scan to one character past where IT started, so the
|
|
378
|
+
* engine keeps looking and still finds the real assignment nested inside.
|
|
379
|
+
*/
|
|
380
|
+
function redactNamedCredentialValues(input) {
|
|
381
|
+
const re = new RegExp(NAMED_CREDENTIAL_VALUE_SOURCE, "g");
|
|
382
|
+
let result = "";
|
|
383
|
+
let cursor = 0;
|
|
384
|
+
let match = re.exec(input);
|
|
385
|
+
while (match !== null) {
|
|
386
|
+
const [full, name, sep] = match;
|
|
387
|
+
if (isCredentialLikeKeyName(name)) {
|
|
388
|
+
result += `${input.slice(cursor, match.index)}${name}${sep}[REDACTED]`;
|
|
389
|
+
cursor = match.index + full.length;
|
|
390
|
+
re.lastIndex = cursor;
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
re.lastIndex = match.index + 1;
|
|
394
|
+
}
|
|
395
|
+
match = re.exec(input);
|
|
396
|
+
}
|
|
397
|
+
return result + input.slice(cursor);
|
|
398
|
+
}
|
|
320
399
|
/**
|
|
321
400
|
* Redact credential-shaped substrings from arbitrary text by pattern alone —
|
|
322
401
|
* unlike {@link redactSensitiveText}, which requires the exact secret value
|
|
@@ -333,11 +412,23 @@ function addPlainMatches(coverageDelta, text, needle) {
|
|
|
333
412
|
* is kept, only the token segment is redacted
|
|
334
413
|
* - Slack incoming-webhook URLs (`hooks.slack.com/services/<team>/<channel>/<token>`)
|
|
335
414
|
* — the team/channel ids are kept, only the trailing token is redacted
|
|
415
|
+
* - PEM private-key blocks (`-----BEGIN … PRIVATE KEY-----…-----END … PRIVATE KEY-----`)
|
|
416
|
+
* — the BEGIN/END markers are kept, only the body is redacted
|
|
417
|
+
* - JWTs (`eyJ…….…….…`)
|
|
418
|
+
* - GitHub tokens (`ghp_`/`gho_`/`ghs_`/`ghu_`/`ghr_…`)
|
|
419
|
+
* - Slack tokens (`xoxa-`/`xoxb-`/`xoxp-`/`xoxr-…`)
|
|
420
|
+
* - AWS access key ids (`AKIA…`)
|
|
421
|
+
* - `scheme://user:pass@host` URLs — the scheme and host are kept, only the
|
|
422
|
+
* userinfo is redacted
|
|
423
|
+
* - `NAME=value` / `NAME: value` where `NAME` names a credential by shape
|
|
424
|
+
* (password, passwd, secret, token, auth, credential(s), api/private key
|
|
425
|
+
* — see {@link isCredentialLikeKeyName}) — the name is kept, only the
|
|
426
|
+
* value is redacted
|
|
336
427
|
*/
|
|
337
428
|
export function redactCredentialPatterns(input) {
|
|
338
429
|
if (!input)
|
|
339
430
|
return "";
|
|
340
|
-
|
|
431
|
+
const patterned = input
|
|
341
432
|
// Bearer tokens (case-insensitive)
|
|
342
433
|
.replace(/\bBearer\s+[A-Za-z0-9._\-+/=]+/gi, "Bearer [REDACTED]")
|
|
343
434
|
// sk-/sk_ style keys
|
|
@@ -349,7 +440,23 @@ export function redactCredentialPatterns(input) {
|
|
|
349
440
|
// Discord webhook URLs: keep the webhook id, redact the token segment.
|
|
350
441
|
.replace(/(discord(?:app)?\.com\/api\/webhooks\/\d+\/)[A-Za-z0-9_-]+/gi, "$1[REDACTED]")
|
|
351
442
|
// Slack incoming-webhook URLs: keep the team/channel ids, redact the token.
|
|
352
|
-
.replace(/(hooks\.slack\.com\/services\/[A-Za-z0-9]+\/[A-Za-z0-9]+\/)[A-Za-z0-9]+/gi, "$1[REDACTED]")
|
|
443
|
+
.replace(/(hooks\.slack\.com\/services\/[A-Za-z0-9]+\/[A-Za-z0-9]+\/)[A-Za-z0-9]+/gi, "$1[REDACTED]")
|
|
444
|
+
// PEM private-key blocks: keep the BEGIN/END markers, redact the body.
|
|
445
|
+
.replace(/(-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----)[\s\S]*?(-----END [A-Z0-9 ]*PRIVATE KEY-----)/g, "$1[REDACTED]$2")
|
|
446
|
+
// JWTs: three dot-separated base64url segments; the header always
|
|
447
|
+
// starts "eyJ" (base64 of `{"`).
|
|
448
|
+
.replace(/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g, "[REDACTED]")
|
|
449
|
+
// GitHub tokens (ghp_/gho_/ghs_/ghu_/ghr_...)
|
|
450
|
+
.replace(/\bgh[posur]_[A-Za-z0-9]{20,255}\b/g, "[REDACTED]")
|
|
451
|
+
// Slack tokens (xoxa-/xoxb-/xoxp-/xoxr-...)
|
|
452
|
+
.replace(/\bxox[abpr]-[A-Za-z0-9-]+\b/g, "[REDACTED]")
|
|
453
|
+
// AWS access key ids
|
|
454
|
+
.replace(/\bAKIA[0-9A-Z]{16}\b/g, "[REDACTED]")
|
|
455
|
+
// URLs carrying `user:pass@` userinfo: keep the scheme and host.
|
|
456
|
+
.replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^\s/@]+:[^\s/@]+@/gi, "$1[REDACTED]@");
|
|
457
|
+
// NAME=value / NAME: value for credential-shaped names. Not a plain
|
|
458
|
+
// `.replace()` in the chain above — see `redactNamedCredentialValues`.
|
|
459
|
+
return redactNamedCredentialValues(patterned);
|
|
353
460
|
}
|
|
354
461
|
/**
|
|
355
462
|
* Replace exact sensitive values in text.
|
package/dist/core/run-lock.js
CHANGED
|
@@ -20,11 +20,8 @@
|
|
|
20
20
|
* absent-race and stale-reclaim retries `improve` established) and reports
|
|
21
21
|
* whether the caller now owns the lock or, if not, who currently holds it.
|
|
22
22
|
* It does not decide what "held" means — skip, throw, or warn-and-proceed is
|
|
23
|
-
* entirely up to the caller
|
|
24
|
-
*
|
|
25
|
-
* `withMaintenanceStartBarrier`/`tryWithMaintenanceStartBarrier`
|
|
26
|
-
* (`core/maintenance-barrier.ts`) so two racing processes never both create
|
|
27
|
-
* the sentinel in the same window.
|
|
23
|
+
* entirely up to the caller. Creating the sentinel is an `O_EXCL` write, so
|
|
24
|
+
* two racing processes never both create it.
|
|
28
25
|
*/
|
|
29
26
|
import fs from "node:fs";
|
|
30
27
|
import path from "node:path";
|
package/dist/core/spawn-env.js
CHANGED
|
@@ -144,7 +144,7 @@ export function collectAllowlistedEnv(names, source = process.env) {
|
|
|
144
144
|
* a shell's own command-path caching already does, and the cost of not
|
|
145
145
|
* memoizing is paid on every child-env build: two PATH splits and up to seven
|
|
146
146
|
* SYNCHRONOUS `existsSync` probes, on the event loop a 10 000-unit fan-out
|
|
147
|
-
* shares with
|
|
147
|
+
* shares with every other in-flight unit.
|
|
148
148
|
*
|
|
149
149
|
* Bounded so a caller that somehow varies its PATH cannot grow it without
|
|
150
150
|
* limit; a spawn path only ever sees a handful of distinct PATH strings, so
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
|
|
4
|
+
// The state.db schema migration registry. The MIGRATIONS array is the single
|
|
5
|
+
// append-only ordered source of truth: new migrations are APPENDED here and an
|
|
6
|
+
// existing fragment is NEVER renumbered or reordered (that would corrupt the
|
|
7
|
+
// schema_migrations ledger on already-deployed databases). The shared runner
|
|
8
|
+
// at src/storage/sqlite-migrations.ts applies them in array order.
|
|
9
|
+
import { assertMigrationRegistry } from "../../storage/sqlite-migrations.js";
|
|
5
10
|
/**
|
|
6
11
|
* Explicit safety classification for every released state migration ID.
|
|
7
12
|
*
|
|
@@ -9,6 +14,9 @@ import { assertMigrationLedger, assertMigrationRegistry, runMigrations as runSql
|
|
|
9
14
|
* released IDs, order, and SQL stay byte-for-byte unchanged. A runtime
|
|
10
15
|
* assertion below requires this key order to match {@link STATE_MIGRATIONS}
|
|
11
16
|
* exactly, so appending a migration also requires an explicit safety decision.
|
|
17
|
+
* The one consumer of the classification is `openStateDatabase`
|
|
18
|
+
* (src/core/state-db.ts): before a `historical-destructive` migration runs
|
|
19
|
+
* against an existing database, the file is copied beside itself first.
|
|
12
20
|
*/
|
|
13
21
|
export const STATE_MIGRATION_SAFETY_BY_ID = Object.freeze({
|
|
14
22
|
"001-initial-schema": "additive",
|
|
@@ -38,6 +46,7 @@ export const STATE_MIGRATION_SAFETY_BY_ID = Object.freeze({
|
|
|
38
46
|
"025-task-history-vocabulary-backfill": "data-preserving-rebuild",
|
|
39
47
|
"026-proposals-strip-legacy-fragment-refs": "data-preserving-rebuild",
|
|
40
48
|
"027-extract-sessions-seen-harness-rename": "data-preserving-rebuild",
|
|
49
|
+
"028-improve-ledger": "historical-destructive",
|
|
41
50
|
});
|
|
42
51
|
export const STATE_MIGRATIONS = [
|
|
43
52
|
// ── Migration 001 — initial schema ──────────────────────────────────────────
|
|
@@ -1177,6 +1186,104 @@ export const STATE_MIGRATIONS = [
|
|
|
1177
1186
|
UPDATE workflow_runs SET agent_harness = 'claude' WHERE agent_harness = 'claude-code';
|
|
1178
1187
|
`,
|
|
1179
1188
|
},
|
|
1189
|
+
// ── Migration 028 — the improve ledger ──
|
|
1190
|
+
//
|
|
1191
|
+
// One table records what improve last did with each (stash, ref, source) and
|
|
1192
|
+
// when it may try again (`src/storage/repositories/improve-ledger-repository.ts`
|
|
1193
|
+
// owns the outcome → cadence rule). Backfilled from the latest proposals row
|
|
1194
|
+
// per (stash_dir, ref, source) so the rejection windows and pending state an
|
|
1195
|
+
// upgrade inherits are the ones the previous release was already honouring:
|
|
1196
|
+
// pending → proposed (revisit in 7 d)
|
|
1197
|
+
// accepted → accepted (eligible)
|
|
1198
|
+
// rejected → expired when the review reason is the expiry pass's
|
|
1199
|
+
// ("expired: …", 1 d grace), failed when the drain's
|
|
1200
|
+
// stale-target auto-reject or the orphan purge (eligible now —
|
|
1201
|
+
// neither was a content judgement), else rejected (reflect
|
|
1202
|
+
// 14 d, distill 30 d, other 7 d)
|
|
1203
|
+
// reverted → rejected (the operator undid the content)
|
|
1204
|
+
// `strftime` returns NULL for an unparseable timestamp, which reads as
|
|
1205
|
+
// "eligible now" — the safe direction.
|
|
1206
|
+
//
|
|
1207
|
+
// The same migration drops the tables the ledger supersedes or whose code is
|
|
1208
|
+
// gone: `proposal_fingerprints` was a dedup cache derived from proposals
|
|
1209
|
+
// rows, `improve_gate_thresholds` has had no reader since 0.9.0,
|
|
1210
|
+
// `proposal_fs_imports` lost its importer, `canary_queries` /
|
|
1211
|
+
// `improve_cycle_metrics` belonged to the removed collapse detector, and
|
|
1212
|
+
// `consolidation_judged` was already dropped by 018 (a no-op here for any
|
|
1213
|
+
// ledger that ran it). None holds operator state, but dropping tables is
|
|
1214
|
+
// destructive, so it is classified that way: `openStateDatabase` copies an
|
|
1215
|
+
// existing state.db beside itself before it runs.
|
|
1216
|
+
{
|
|
1217
|
+
id: "028-improve-ledger",
|
|
1218
|
+
up: `
|
|
1219
|
+
CREATE TABLE IF NOT EXISTS improve_ledger (
|
|
1220
|
+
stash_dir TEXT NOT NULL,
|
|
1221
|
+
ref TEXT NOT NULL,
|
|
1222
|
+
source TEXT NOT NULL,
|
|
1223
|
+
last_attempt_at TEXT NOT NULL,
|
|
1224
|
+
outcome TEXT NOT NULL,
|
|
1225
|
+
next_eligible_at TEXT,
|
|
1226
|
+
proposal_id TEXT,
|
|
1227
|
+
detail TEXT,
|
|
1228
|
+
PRIMARY KEY (stash_dir, ref, source)
|
|
1229
|
+
);
|
|
1230
|
+
|
|
1231
|
+
INSERT OR REPLACE INTO improve_ledger
|
|
1232
|
+
(stash_dir, ref, source, last_attempt_at, outcome, next_eligible_at, proposal_id, detail)
|
|
1233
|
+
SELECT
|
|
1234
|
+
p.stash_dir,
|
|
1235
|
+
p.ref,
|
|
1236
|
+
p.source,
|
|
1237
|
+
p.updated_at,
|
|
1238
|
+
o.outcome,
|
|
1239
|
+
CASE o.outcome
|
|
1240
|
+
WHEN 'rejected' THEN strftime('%Y-%m-%dT%H:%M:%fZ', p.updated_at,
|
|
1241
|
+
CASE p.source WHEN 'reflect' THEN '+14 days' WHEN 'distill' THEN '+30 days' ELSE '+7 days' END)
|
|
1242
|
+
WHEN 'expired' THEN strftime('%Y-%m-%dT%H:%M:%fZ', p.updated_at, '+1 days')
|
|
1243
|
+
WHEN 'proposed' THEN strftime('%Y-%m-%dT%H:%M:%fZ', p.updated_at, '+7 days')
|
|
1244
|
+
ELSE NULL
|
|
1245
|
+
END,
|
|
1246
|
+
p.id,
|
|
1247
|
+
CASE WHEN json_valid(p.metadata_json)
|
|
1248
|
+
THEN json_extract(p.metadata_json, '$.review.reason') ELSE NULL END
|
|
1249
|
+
FROM proposals p
|
|
1250
|
+
JOIN (
|
|
1251
|
+
SELECT stash_dir, ref, source, MAX(updated_at) AS latest_updated_at
|
|
1252
|
+
FROM proposals GROUP BY stash_dir, ref, source
|
|
1253
|
+
) latest
|
|
1254
|
+
ON latest.stash_dir = p.stash_dir AND latest.ref = p.ref AND latest.source = p.source
|
|
1255
|
+
AND latest.latest_updated_at = p.updated_at
|
|
1256
|
+
JOIN (
|
|
1257
|
+
SELECT rowid AS proposal_rowid,
|
|
1258
|
+
CASE status
|
|
1259
|
+
WHEN 'pending' THEN 'proposed'
|
|
1260
|
+
WHEN 'accepted' THEN 'accepted'
|
|
1261
|
+
WHEN 'reverted' THEN 'rejected'
|
|
1262
|
+
WHEN 'rejected' THEN
|
|
1263
|
+
CASE WHEN json_valid(metadata_json) THEN
|
|
1264
|
+
CASE
|
|
1265
|
+
WHEN json_extract(metadata_json, '$.review.reason') LIKE 'expired:%' THEN 'expired'
|
|
1266
|
+
WHEN json_extract(metadata_json, '$.gateDecision.reason') = 'stale-target' THEN 'failed'
|
|
1267
|
+
WHEN json_extract(metadata_json, '$.review.reason') = 'Asset no longer exists on disk' THEN 'failed'
|
|
1268
|
+
ELSE 'rejected'
|
|
1269
|
+
END
|
|
1270
|
+
ELSE 'rejected' END
|
|
1271
|
+
ELSE NULL
|
|
1272
|
+
END AS outcome
|
|
1273
|
+
FROM proposals
|
|
1274
|
+
) o ON o.proposal_rowid = p.rowid
|
|
1275
|
+
WHERE o.outcome IS NOT NULL
|
|
1276
|
+
ORDER BY p.rowid ASC;
|
|
1277
|
+
|
|
1278
|
+
DROP INDEX IF EXISTS idx_proposal_fingerprints_ref;
|
|
1279
|
+
DROP TABLE IF EXISTS proposal_fingerprints;
|
|
1280
|
+
DROP TABLE IF EXISTS improve_gate_thresholds;
|
|
1281
|
+
DROP TABLE IF EXISTS proposal_fs_imports;
|
|
1282
|
+
DROP TABLE IF EXISTS consolidation_judged;
|
|
1283
|
+
DROP TABLE IF EXISTS improve_cycle_metrics;
|
|
1284
|
+
DROP TABLE IF EXISTS canary_queries;
|
|
1285
|
+
`,
|
|
1286
|
+
},
|
|
1180
1287
|
];
|
|
1181
1288
|
assertMigrationRegistry(STATE_MIGRATIONS);
|
|
1182
1289
|
function assertStateMigrationSafetyRegistry() {
|
|
@@ -1194,63 +1301,3 @@ export function getStateMigrationSafety(migrationId) {
|
|
|
1194
1301
|
throw new Error(`State migration ${migrationId} has no safety classification.`);
|
|
1195
1302
|
return safety;
|
|
1196
1303
|
}
|
|
1197
|
-
/**
|
|
1198
|
-
* Apply every pending migration in a single transaction per migration.
|
|
1199
|
-
*
|
|
1200
|
-
* Delegates to the shared SQLite migration engine; state.db has no
|
|
1201
|
-
* pre-versioning bootstrap step, so no `bootstrap` hook is passed.
|
|
1202
|
-
*
|
|
1203
|
-
* Called automatically by `openStateDatabase()`.
|
|
1204
|
-
*/
|
|
1205
|
-
export function runMigrations(db, options) {
|
|
1206
|
-
const initialMigration = STATE_MIGRATIONS[0];
|
|
1207
|
-
if (!initialMigration)
|
|
1208
|
-
throw new Error("State migration registry has no initial migration.");
|
|
1209
|
-
let existingUnversionedSnapshotPrepared = false;
|
|
1210
|
-
const prepareExistingUnversionedState = (lockedDb) => {
|
|
1211
|
-
if (existingUnversionedSnapshotPrepared)
|
|
1212
|
-
return;
|
|
1213
|
-
if (!options?.existingUnversionedDatabase) {
|
|
1214
|
-
throw new Error("Refusing state.db initialization because its migration ledger disappeared after preflight.");
|
|
1215
|
-
}
|
|
1216
|
-
if (!options.allowHistoricalDestructiveStateUpgrade) {
|
|
1217
|
-
throw new Error("Refusing to migrate an existing unversioned state.db during an ordinary managed open. " +
|
|
1218
|
-
"Run `akm upgrade` (or `akm migrate apply`) to snapshot it before migration 001 and apply it deliberately.");
|
|
1219
|
-
}
|
|
1220
|
-
const ledger = assertMigrationLedger(lockedDb, STATE_MIGRATIONS);
|
|
1221
|
-
if (ledger.migrationIds.length !== 0) {
|
|
1222
|
-
throw new Error("Refusing an existing unversioned state.db whose migration ledger changed after preflight.");
|
|
1223
|
-
}
|
|
1224
|
-
if (!options.beforeExistingUnversionedStateMigration) {
|
|
1225
|
-
throw new Error("An existing unversioned state.db requires a verified pre-migration safety-copy hook.");
|
|
1226
|
-
}
|
|
1227
|
-
options.beforeExistingUnversionedStateMigration(initialMigration);
|
|
1228
|
-
existingUnversionedSnapshotPrepared = true;
|
|
1229
|
-
};
|
|
1230
|
-
runSqliteMigrations(db, STATE_MIGRATIONS, {
|
|
1231
|
-
lockInitialMigrationPrefixThrough: options?.existingUnversionedDatabase ? "002-task-history-per-run" : undefined,
|
|
1232
|
-
beforeLedgerInitializationLocked(lockedDb) {
|
|
1233
|
-
if (options?.freshDatabase)
|
|
1234
|
-
return;
|
|
1235
|
-
prepareExistingUnversionedState(lockedDb);
|
|
1236
|
-
},
|
|
1237
|
-
beforeMigrationLocked(migration, lockedDb) {
|
|
1238
|
-
if (options?.existingUnversionedDatabase && !existingUnversionedSnapshotPrepared) {
|
|
1239
|
-
prepareExistingUnversionedState(lockedDb);
|
|
1240
|
-
}
|
|
1241
|
-
if (getStateMigrationSafety(migration.id) !== "historical-destructive" || options?.freshDatabase)
|
|
1242
|
-
return;
|
|
1243
|
-
// The writer lock closes the window between this exact-prefix decision,
|
|
1244
|
-
// the recovery snapshot, and the destructive migration transaction.
|
|
1245
|
-
assertMigrationLedger(lockedDb, STATE_MIGRATIONS);
|
|
1246
|
-
if (!options?.allowHistoricalDestructiveStateUpgrade) {
|
|
1247
|
-
throw new Error(`Refusing to apply historical destructive state migration ${migration.id} during an ordinary managed open. ` +
|
|
1248
|
-
"Run `akm upgrade` (or `akm migrate apply`) to create a sibling state.db safety copy and apply it deliberately.");
|
|
1249
|
-
}
|
|
1250
|
-
if (!options.beforeHistoricalDestructiveMigration) {
|
|
1251
|
-
throw new Error(`Historical destructive state migration ${migration.id} requires a verified safety-copy hook.`);
|
|
1252
|
-
}
|
|
1253
|
-
options.beforeHistoricalDestructiveMigration(migration);
|
|
1254
|
-
},
|
|
1255
|
-
});
|
|
1256
|
-
}
|
|
@@ -4,10 +4,8 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* Ambient, run-scoped state.db connection reuse.
|
|
6
6
|
*
|
|
7
|
-
* `openStateDatabase` is
|
|
8
|
-
*
|
|
9
|
-
* a throwaway read-only preflight handle to assert the migration ledger, then
|
|
10
|
-
* opens the real handle and applies pragmas. Paying that per repository call
|
|
7
|
+
* `openStateDatabase` is not free: every call opens a handle, applies the
|
|
8
|
+
* pragmas and reads the migration ledger. Paying that per repository call
|
|
11
9
|
* — twice per dispatched workflow unit (insert + finish), plus once per
|
|
12
10
|
* `appendEvent` (two events per unit) — is the dominant cost of a wide `map`
|
|
13
11
|
* fan-out.
|