akm-cli 0.9.16-alpha.1 → 0.9.16

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.
Files changed (147) hide show
  1. package/CHANGELOG.md +56 -132
  2. package/dist/assets/hints/cli-hints-full.md +13 -6
  3. package/dist/assets/tasks/core/index-refresh.yml +1 -1
  4. package/dist/assets/tasks/improve/akm-improve-catchup.yml +3 -6
  5. package/dist/cli/retired-commands.js +0 -4
  6. package/dist/cli/unknown-flags.js +3 -36
  7. package/dist/commands/env/env-binding.js +4 -4
  8. package/dist/commands/env/env-cli.js +3 -3
  9. package/dist/commands/improve/collapse-detector.js +2 -2
  10. package/dist/commands/improve/consolidate.js +4 -6
  11. package/dist/commands/improve/improve-cli.js +20 -15
  12. package/dist/commands/improve/reflect.js +23 -2
  13. package/dist/commands/lint/base-linter.js +9 -0
  14. package/dist/commands/lint/env-key-rules.js +2 -2
  15. package/dist/commands/proposal/propose.js +15 -1
  16. package/dist/commands/proposal/repository.js +3 -12
  17. package/dist/commands/proposal/validators/proposal-quality-validators.js +40 -3
  18. package/dist/commands/proposal/validators/proposal-validators.js +5 -4
  19. package/dist/commands/read/curate.js +44 -34
  20. package/dist/commands/read/search.js +35 -54
  21. package/dist/commands/read/show.js +21 -2
  22. package/dist/commands/registry-cli.js +5 -5
  23. package/dist/commands/sources/add-cli.js +59 -16
  24. package/dist/commands/sources/bundle-cli.js +35 -11
  25. package/dist/commands/sources/bundle-config-ops.js +30 -0
  26. package/dist/commands/sources/dangerous-env-audit.js +4 -4
  27. package/dist/commands/sources/info.js +8 -8
  28. package/dist/commands/sources/installed-stashes.js +55 -61
  29. package/dist/commands/sources/source-add.js +39 -38
  30. package/dist/commands/sources/source-manage.js +34 -12
  31. package/dist/commands/sources/stash-cli.js +111 -119
  32. package/dist/commands/sources/stash-skeleton.js +6 -3
  33. package/dist/commands/tasks/explain.js +4 -1
  34. package/dist/commands/tasks/tasks-cli.js +31 -9
  35. package/dist/commands/tasks/tasks.js +239 -194
  36. package/dist/commands/tasks/validate.js +20 -32
  37. package/dist/core/activation-policy.js +4 -4
  38. package/dist/core/adapter/adapters/akm-adapter.js +8 -35
  39. package/dist/core/adapter/adapters/akm-metadata.js +1 -11
  40. package/dist/core/adapter/execution-source.js +10 -29
  41. package/dist/core/asset/asset-placement.js +0 -35
  42. package/dist/core/config/config-schema.js +64 -8
  43. package/dist/core/config/config-sources.js +96 -2
  44. package/dist/core/config/config.js +190 -24
  45. package/dist/core/config/legacy-source-shape-shim.js +9 -0
  46. package/dist/core/config/schema/embedding.js +30 -7
  47. package/dist/core/config/schema/execution.js +23 -0
  48. package/dist/core/config/schema/experimental.js +1 -1
  49. package/dist/core/config/schema/scheduler.js +20 -0
  50. package/dist/core/config/schema/search.js +10 -12
  51. package/dist/core/config/schema/sources-bundles.js +32 -1
  52. package/dist/core/content-safety.js +52 -0
  53. package/dist/core/errors.js +2 -5
  54. package/dist/core/maintenance-barrier.js +11 -13
  55. package/dist/core/paths.js +11 -0
  56. package/dist/core/run-lock.js +2 -5
  57. package/dist/core/state/migrations.js +1 -26
  58. package/dist/core/state-db.js +27 -63
  59. package/dist/core/type-presentation.js +1 -1
  60. package/dist/core/write-source.js +13 -8
  61. package/dist/indexer/bundle-identity-guard.js +45 -8
  62. package/dist/indexer/ensure-index.js +0 -5
  63. package/dist/indexer/index-db-contention.js +56 -0
  64. package/dist/indexer/index-rebuild-lock.js +73 -0
  65. package/dist/indexer/index-written-assets.js +171 -133
  66. package/dist/indexer/indexer.js +1621 -458
  67. package/dist/indexer/lookup/adapter-concept-owner.js +5 -19
  68. package/dist/indexer/materialize-embeddings.js +785 -0
  69. package/dist/indexer/passes/dir-staleness.js +161 -0
  70. package/dist/indexer/passes/metadata.js +1 -18
  71. package/dist/indexer/scan/drain-dir.js +70 -27
  72. package/dist/indexer/search/db-search.js +89 -373
  73. package/dist/indexer/search/ranking-contributors.js +16 -21
  74. package/dist/indexer/search/ranking.js +57 -135
  75. package/dist/indexer/search/search-source.js +29 -11
  76. package/dist/integrations/agent/execution-lowering.js +3 -2
  77. package/dist/integrations/agent/execution-preparation.js +32 -1
  78. package/dist/integrations/agent/prompts.js +1 -1
  79. package/dist/integrations/agent/request-lowering.js +3 -2
  80. package/dist/llm/client.js +3 -11
  81. package/dist/llm/embedder.js +3 -10
  82. package/dist/llm/embedders/remote.js +104 -133
  83. package/dist/llm/feature-gate.js +2 -4
  84. package/dist/llm/rerank-client.js +3 -3
  85. package/dist/output/html-render.js +2 -1
  86. package/dist/output/shapes/passthrough.js +2 -1
  87. package/dist/output/stdout.js +24 -0
  88. package/dist/output/text/command-format.js +13 -19
  89. package/dist/output/text/helpers.js +1 -1
  90. package/dist/output/text/index.js +2 -5
  91. package/dist/output/text.js +4 -3
  92. package/dist/registry/resolve.js +37 -10
  93. package/dist/scripts/akm-migrate-node.js +15197 -11351
  94. package/dist/scripts/akm-migrate.js +15514 -11668
  95. package/dist/setup/semantic-assets.js +2 -2
  96. package/dist/setup/setup.js +3 -3
  97. package/dist/setup/steps/connection.js +2 -3
  98. package/dist/setup/steps/tasks.js +29 -36
  99. package/dist/sources/providers/git-install.js +17 -11
  100. package/dist/sources/providers/git-provider.js +12 -5
  101. package/dist/sources/providers/git-stash.js +38 -16
  102. package/dist/sources/snapshot-fetchers/website-ingest.js +3 -3
  103. package/dist/storage/repositories/embedding-salvage-repository.js +184 -0
  104. package/dist/storage/repositories/index-connection.js +3 -1
  105. package/dist/storage/repositories/index-entries-repository.js +68 -77
  106. package/dist/storage/repositories/index-entry-schema.js +25 -16
  107. package/dist/storage/repositories/index-fts-repository.js +263 -29
  108. package/dist/storage/repositories/index-meta-repository.js +29 -0
  109. package/dist/storage/repositories/index-schema.js +122 -115
  110. package/dist/storage/repositories/index-utility-repository.js +1 -1
  111. package/dist/storage/repositories/index-vec-repository.js +435 -22
  112. package/dist/tasks/activation-config.js +90 -0
  113. package/dist/tasks/backends/cron.js +9 -0
  114. package/dist/tasks/backends/launchd.js +1 -0
  115. package/dist/tasks/backends/schtasks.js +2 -0
  116. package/dist/tasks/embedded.js +4 -5
  117. package/dist/tasks/scheduler-binding.js +2 -2
  118. package/dist/tasks/scheduler-sync-preview.js +8 -1
  119. package/dist/tasks/scheduler-sync.js +19 -10
  120. package/dist/tasks/source/parse-task-source.js +10 -113
  121. package/dist/tasks/source/project-v4.js +2 -2
  122. package/dist/tasks/source/task-source-v4.js +4 -12
  123. package/dist/tasks/source/task-to-v3.js +4 -12
  124. package/dist/tasks/source/task-to-v4.js +40 -7
  125. package/docs/migration/README.md +1 -0
  126. package/docs/migration/release-notes/0.9.15.md +36 -34
  127. package/docs/migration/release-notes/0.9.16.md +60 -98
  128. package/docs/migration/release-notes/README.md +0 -5
  129. package/docs/migration/v0.9.1-to-v0.9.2.md +6 -9
  130. package/docs/reference/cli.md +124 -122
  131. package/docs/reference/configuration.md +137 -133
  132. package/docs/reference/data-and-telemetry.md +1 -2
  133. package/docs/reference/tasks.md +34 -29
  134. package/package.json +1 -1
  135. package/schemas/akm-config.json +170 -6
  136. package/schemas/akm-task.json +1 -2
  137. package/dist/commands/sources/index-status.js +0 -99
  138. package/dist/core/hash.js +0 -18
  139. package/dist/indexer/drain.js +0 -306
  140. package/dist/indexer/embedding-identity.js +0 -20
  141. package/dist/indexer/enrich.js +0 -260
  142. package/dist/indexer/reconcile.js +0 -890
  143. package/dist/indexer/scan/parse-file.js +0 -66
  144. package/dist/indexer/units/unit.js +0 -159
  145. package/dist/llm/embedders/provider-limits.js +0 -288
  146. package/dist/storage/repositories/files-repository.js +0 -181
  147. package/dist/storage/repositories/units-repository.js +0 -510
@@ -218,87 +218,97 @@ and builds the search index.
218
218
  Build or refresh the search index.
219
219
 
220
220
  ```sh
221
- akm index # Reconcile: diff every configured root against the index, drain the embedding queue
222
- akm index --full # Force every file to be re-derived, ignoring the unchanged-file shortcut, reconciling in place
221
+ akm index # Incremental (only changed directories)
222
+ akm index --full # Full rebuild (reuses unchanged embeddings — see below)
223
223
  akm index --verbose # Print phase progress to stderr
224
- akm index --reembed # Drop the active embedding identity's vectors, then re-embed every unit from scratch
225
- akm index status # Report file/entry/unit counts, active identity, and last-reconcile time — no writes
224
+ akm index --clean # Normal index + remove stale entries from the DB
225
+ akm index --clean --dry-run # Report stale entries without deleting
226
+ akm index --reembed # Force re-embedding of every entry
227
+ akm index --skip-if-locked # for scheduled/opportunistic runs: skip (exit 0) if a run is already in progress
226
228
  ```
227
229
 
228
- Returns stats: `totalEntries`, `entriesUpserted`, `sourcesScanned`,
229
- `verification`, optional `warnings`, and `timing` breakdown in milliseconds.
230
- Use `--verbose` to print the indexing mode,
230
+ Returns stats: `totalEntries`, `generatedMetadata`, `directoriesScanned`,
231
+ `directoriesSkipped`, `verification`, optional `warnings`, and `timing`
232
+ breakdown in milliseconds. Use `--verbose` to print the indexing mode,
231
233
  semantic-search settings, and phase-by-phase progress to stderr while the
232
234
  index is being built. Malformed workflow assets are skipped with file-path
233
235
  warnings instead of aborting the full run.
234
236
 
235
- **Progress in non-verbose JSON/yaml/jsonl mode:** phase-start messages and
236
- each phase's summary line — including `[embed] endpoint ...` and `[drain]
237
- done: ...` — reach stderr regardless of `--verbose`: a long-running index
238
- build against a slow or unresponsive provider is no longer silent until the
239
- whole run finishes. Two high-frequency, one-line-per-unit-of-work lines are
240
- the exception and stay suppressed without `--verbose`: drain's per-batch
241
- commit line (`[drain] batch N: ...`) and reconcile's per-root line
242
- (`Reconciled "<path>": N files scanned.`) — printing one of those per batch
243
- or per root would be spam, not a heartbeat. Pass `--verbose` to print those
244
- two as well, alongside the same summary lines. Text mode is where
245
- `--verbose` also matters for everything else: without it, progress updates a
246
- single spinner line in place; with it, every line is printed as it arrives
247
- instead. JSON stdout output is unaffected either way.
248
-
249
- **Reconcile, not a walk-and-rebuild pipeline:** `akm index` diffs every
250
- configured root's files against the index (stat cache: unchanged files are
251
- skipped without a re-parse), upserts what changed, removes what is genuinely
252
- gone, then drains the content-addressed embedding queue. Every write is a
253
- short, idempotent transaction — there is no rebuild lock, no writer lock on
254
- the index path, and no per-command background reindex spawn: two concurrent
255
- `akm index` runs simply converge on the same end state instead of
256
- contending. `akm index status` (no writes) reports file/entry/unit counts,
257
- the active embedding identity, and the last-reconcile time.
258
-
259
- **`--full`:** does NOT drop or wipe anything first. It reconciles with every
260
- walked file treated as needing re-derivation — the stat-hint "unchanged"
261
- shortcut is skipped, so every file is re-parsed — but each file's existing
262
- row (keyed by its stable `item_ref`) is updated in place, not deleted and
263
- reinserted: the row keeps its id, its embeddings, and its learned utility
264
- scores. Content-addressed units (`units`/`units_vec`, keyed by content hash,
265
- never by entry id) are never at risk from a reindex at all, `--full`
266
- included — there is nothing to re-embed for unchanged content. Gone-path
267
- detection (files genuinely removed) is unaffected by `--full`; a root whose
268
- walk could not be trusted this run (an unreachable path, a mid-walk stat
269
- failure) has its entire existing snapshot preserved rather than partially
270
- wiped over a transient scan failure.
271
-
272
- **`--reembed`:** drops the active embedding identity's vectors, then the
273
- drain re-embeds every unit from scratch under that identity. Ordinary
274
- indexing does not need a separate rename-compatibility check: the identity a
275
- unit's vector is keyed under is exactly what the provider's response
276
- reported (model id and vector width), so a config-only rename of
277
- `embedding.model` that still resolves to the same server-reported model
278
- keeps the same identity — and its stored vectors — automatically, while a
279
- genuine model or dimension change lands under a different identity and its
280
- units are simply "missing" until the next drain.
281
-
282
- **`--skip-if-locked`:** deprecated, no effect — index runs no longer take a
283
- rebuild lock, so there is nothing left to skip around. Passing it prints one
284
- deprecation warning; the run proceeds exactly as an ordinary `akm index`
285
- would. Kept only so an existing script or scheduled task does not fail on an
286
- unknown flag. If index.db is genuinely busy (a second connection holds a
287
- write transaction) long enough to exhaust the driver's own SQLite
288
- `busy_timeout`, the run fails with exit 75 (`TransientError`, code
289
- `INDEX_DB_CONTENDED`) instead of the raw driver error at exit 70 — the same
290
- retry-shortly contract as `STATE_DB_CONTENDED`, so a scheduler can branch on
291
- it instead of alerting.
292
- Locks that do still exist (`akm improve`, `akm workflow run`) are registered through a brief
293
- internal barrier shared by every akm lock and lease; two runs launched close enough together to
294
- collide on that registration step retry briefly and then, if it is still busy, exit 75 (code
295
- `MAINTENANCE_BARRIER_BUSY`) rather than the config-error exit 78 a 2026-09-10 field report
296
- found — a busy registration barrier is ordinary contention between two legitimate runs, never a
297
- broken config file.
298
-
299
- In text mode, the default CLI UI shows a spinner with processed-versus-total
300
- source counts; structured output modes (`json`, `yaml`, `jsonl`) stay clean
301
- and machine-readable.
237
+ **Progress in non-verbose JSON mode (default output format, #954):** even
238
+ without `--verbose`, phase-start messages and the embedding heartbeat
239
+ (`Still generating embeddings: X/N stored, F failed; waiting on embedding
240
+ provider.`) are now written to stderr, and a failed embedding batch logs at
241
+ the default level instead of `--verbose`-only — a long-running index build
242
+ against a slow or unresponsive provider is no longer silent until the whole
243
+ run finishes. Text-mode output keeps its spinner instead (no stderr line
244
+ growth); JSON stdout output is unaffected either way. The high-frequency
245
+ per-batch `Embedded N/M entries.` line stays out of non-verbose stderr (it
246
+ fires after every committed batch) — pass `--verbose` for that level of
247
+ detail.
248
+
249
+ **`--clean` flag:** After indexing completes, verifies every indexed entry's source
250
+ file still exists on disk. Removes any entries whose file is missing (for local
251
+ bundle sources only; remote entries are skipped). Returns a `clean` block in the
252
+ JSON result with `checked`, `removed`, `removedRefs` arrays, and `dryRun` flag.
253
+ Use `--clean` to resolve the edge case where a deleted file in an unchanged
254
+ directory lingers in the index across incremental runs. With `--dry-run`, reports
255
+ which entries would be removed without modifying the database.
256
+
257
+ **`--full` no longer re-embeds unchanged content (#955):** a full rebuild
258
+ (and an index-generation bump on first open under a new binary) used to
259
+ delete every embedding unconditionally, forcing a full re-embed of the
260
+ whole corpus even when nothing changed. Vectors about to be discarded are
261
+ now salvaged (keyed by a hash of their content plus the fingerprint they
262
+ were generated under) and handed straight back to unchanged entries at the
263
+ start of the next embedding pass, with zero provider calls for them — a
264
+ progress line reports the split (`Reused N embeddings from the previous
265
+ generation; embedding M new.`). Content that changed even by one byte, or
266
+ a fingerprint that no longer matches, still goes through the provider
267
+ normally. `--reembed` is the way to force a full re-embed regardless.
268
+
269
+ **`--reembed` flag:** Forces a full purge and re-embed of every entry,
270
+ independent of the embedding-model-rename compatibility check described
271
+ below. Ordinary indexing already tells a config-only rename of
272
+ `embedding.model` (e.g. a gateway that changes how it names the same model)
273
+ apart from a genuine model change, and keeps the stored vectors when they
274
+ are still compatible; `--reembed` skips that check and forces a rebuild
275
+ regardless of what it would have decided.
276
+
277
+ **`--skip-if-locked` flag:** Every explicit `akm index` run acquires an
278
+ opt-in, PID-liveness-only rebuild lock and releases it on exit — this is
279
+ advisory, never the blocking lock #872 removed (see
280
+ [Locks](https://github.com/itlackey/akm/blob/main/docs/architecture/internals/indexing.md#locks)). A human-typed
281
+ `akm index` with no flag is never gated by it: if another run already holds
282
+ the lock, it warns and proceeds anyway, contending with the existing run. If
283
+ that contention makes index.db genuinely busy (SQLite `database is locked`)
284
+ long enough to exhaust the driver's retry window, the run now fails with
285
+ exit 75 (`TransientError`, code `INDEX_DB_CONTENDED`) instead of the raw
286
+ driver error at exit 70 — the same retry-shortly contract as
287
+ `STATE_DB_CONTENDED`, so a scheduler can branch on it instead of alerting.
288
+ The rebuild lock itself is registered through a brief internal barrier
289
+ (`getMaintenanceBarrierPath()`) shared with every other akm lock/lease; two
290
+ `akm index` runs launched close enough together to collide on that
291
+ registration step retry briefly and then, if it is still busy, also exit 75
292
+ (code `MAINTENANCE_BARRIER_BUSY`) rather than the config-error exit 78 a
293
+ 2026-09-10 field report found — a busy registration barrier is ordinary
294
+ contention between two legitimate runs, never a broken config file.
295
+ `--skip-if-locked` changes that only for the invocation that passes it: if
296
+ the lock is already held by a live process, it skips gracefully (exit 0,
297
+ `{ ok: true, skipped: { reason: "lock-held", pid, launcherPid, startedAt } }`
298
+ — `launcherPid` is the holder's launcher pid when known, `null` otherwise,
299
+ #956) instead of contending. `akm index` and `akm curate` are both safe to call frequently —
300
+ `curate` never blocks on a rebuild in progress ([read-path indexing stays
301
+ non-blocking](#curate)) — but a hook, cron job, or scheduled task that
302
+ invokes `akm index` directly should pass `--skip-if-locked` so it steps
303
+ aside instead of piling up behind a longer rebuild (the shipped
304
+ `index-refresh` task does this).
305
+
306
+ `akm index` always rebuilds the search index and keeps metadata in the index.
307
+ When a selected named LLM engine (`defaults.llmEngine` or an indexing-pass
308
+ override) is configured and the per-pass gate allows it, metadata
309
+ enhancement runs during indexing. In text mode, the default CLI UI shows a
310
+ spinner with processed-versus-total source counts; structured output modes
311
+ (`json`, `yaml`, `jsonl`) stay clean and machine-readable.
302
312
 
303
313
  ### info
304
314
 
@@ -327,16 +337,12 @@ Returns a JSON object with:
327
337
  | `indexStats` | Index stats: `entryCount`, `byType` (per-asset-type breakdown), `lastBuiltAt`, `hasEmbeddings`, `vecAvailable` |
328
338
 
329
339
  `semanticSearch.status` values:
330
- - `"ready-vec"` — embeddings present, `sqlite-vec` active
340
+ - `"ready-vec"` — native sqlite-vec extension active (fastest)
341
+ - `"ready-js"` — pure JS fallback active (correct but slower at scale)
331
342
  - `"pending"` — not yet initialized (run `akm index` to set up)
343
+ - `"blocked"` — setup failed (see `reason` and `message` fields)
332
344
  - `"disabled"` — semantic search is turned off in config
333
345
 
334
- (`"ready-js"`, a pure-JS cosine fallback for when the extension was
335
- unavailable, is retired — the unit vector store has no BLOB fallback to fall
336
- back to. A degraded/failed embedding run is reflected here as `"pending"`,
337
- not a separate `"blocked"` value; see `akm index`'s own `verification.semanticStatus`,
338
- which does distinguish `"blocked"`, for that detail.)
339
-
340
346
  Use `akm info` to verify that semantic search is working after setup.
341
347
 
342
348
  Scripts that need akm's resolved paths (for example a health check that
@@ -493,18 +499,6 @@ query. The last case also adds one sanitized, endpoint-naming entry to
493
499
  preserved by `--shape agent` so machine consumers can lower their confidence
494
500
  instead of treating keyword fallback as healthy semantic ranking.
495
501
 
496
- An optional cross-encoder rerank pass (#951, `search.rerank.*` —
497
- `docs/reference/configuration.md`) can run over local hits before `--from
498
- local`/`--from all` diverge; disabled by default, and registry hits (`--from
499
- registry`, and the registry half of `--from all`) are never reranked. When it
500
- runs, it changes hit **ORDER** only — each hit's `score` stays the retrieval
501
- score `akm search` computed, not the reranker's own relevance value. A
502
- consumer that wants the reranked ranking must read hits in ARRAY ORDER, not
503
- by re-sorting on `score`: `score` is a fixed `[0,1]` contract (see the
504
- callout below) that a reranker's own scale — provider-defined, not
505
- calibrated to `[0,1]` — would break if it overwrote it, and a re-sort would
506
- silently undo the rerank for exactly the consumers it exists to serve.
507
-
508
502
  | Flag | Values | Default | Description |
509
503
  | --- | --- | --- | --- |
510
504
  | `--type` | `skill`, `command`, `agent`, `knowledge`, `instruction`, `workflow`, `script`, `memory`, `env`, `secret`, `lesson`, `task`, `session`, `fact`, `any` | `any` | Filter by asset type. Free-form and unvalidated — an unknown type returns no hits. Also accepts any adapter-defined type (e.g. `website`) — see [Bundle Types](bundle-types.md) for the open types each adapter emits. |
@@ -1048,7 +1042,8 @@ akm bundle add https://docs.example.com --max-pages 100 --max-depth 5
1048
1042
  | `--provider` | Explicit provider for declarative source configuration; normally inferred from the input |
1049
1043
  | `--writable` | Mark a git source as writable so `akm sync` also pushes (default: false) |
1050
1044
  | `--options` | Provider options as JSON (e.g. `'{"ref":"main"}'`) |
1051
- | `--allow-insecure` | Bypass plain-HTTP source rejection **and** dangerous env key blocking. Accepts two risks: (1) plain-HTTP download without TLS, (2) env keys that can hijack process execution. Use only after reviewing the bundle manually |
1045
+ | `--allow-insecure-transport` | Allow a plain-HTTP source URL after explicitly accepting transport substitution risk |
1046
+ | `--allow-dangerous-env-keys` | Allow reviewed process-hijacking env keys in the installed bundle; does not permit plain HTTP |
1052
1047
  | `--max-pages` | Maximum pages to crawl for website sources (default: 50) |
1053
1048
  | `--max-depth` | Maximum crawl depth for website sources (default: 3) |
1054
1049
 
@@ -1076,7 +1071,7 @@ config override injection).
1076
1071
 
1077
1072
  When dangerous keys are found, `akm bundle add` pauses and prompts for
1078
1073
  confirmation (default: No). In non-interactive mode (CI, scripts) the
1079
- install fails with **exit 1** unless `--allow-insecure` is passed, and the
1074
+ install fails with **exit 1** unless `--allow-dangerous-env-keys` is passed, and the
1080
1075
  freshly-installed bundle is rolled back before the process exits.
1081
1076
 
1082
1077
  ```sh
@@ -1084,7 +1079,7 @@ freshly-installed bundle is rolled back before the process exits.
1084
1079
  akm bundle add github:owner/repo-with-sensitive-env
1085
1080
 
1086
1081
  # Non-interactive: fails unless bypassed
1087
- akm bundle add github:owner/repo-with-sensitive-env --allow-insecure
1082
+ akm bundle add github:owner/repo-with-sensitive-env --allow-dangerous-env-keys
1088
1083
  ```
1089
1084
 
1090
1085
  Bundle publishers: see the [Author Bundles guide](https://github.com/itlackey/akm/blob/main/docs/guides/author-bundles.md#env-security)
@@ -1161,14 +1156,14 @@ akm bundle update npm:@scope/pkg
1161
1156
  akm bundle update --all
1162
1157
  akm bundle update --all --force # Force fresh download even if version is unchanged
1163
1158
  akm bundle update --all --yes # Skip confirmation when an update needs to delete a moved install dir
1164
- akm bundle update npm:@scope/pkg --allow-insecure # Explicitly approve reviewed dangerous env keys
1159
+ akm bundle update npm:@scope/pkg --allow-dangerous-env-keys # Explicitly approve reviewed dangerous env keys
1165
1160
  ```
1166
1161
 
1167
1162
  | Flag | Description |
1168
1163
  | --- | --- |
1169
1164
  | `--all` | Update all managed sources |
1170
1165
  | `--force` | Delete cached extraction before re-downloading |
1171
- | `--allow-insecure` | Permit a staged update containing dangerous environment keys after warning. Without it, an interactive terminal prompts with a default of No; non-interactive use fails closed. This is independent of `--yes`. |
1166
+ | `--allow-dangerous-env-keys` | Permit a staged update containing dangerous environment keys after warning. Without it, an interactive terminal prompts with a default of No; non-interactive use fails closed. This is independent of `--yes`. |
1172
1167
  | `-y`, `--yes` | Skip the confirmation prompt for the rare branch where the resolved content location moved and the previous install directory must be deleted. No effect on a normal refresh, which deletes nothing. |
1173
1168
 
1174
1169
  The audit examines key names in `.env`-suffixed files under the staged
@@ -1650,7 +1645,7 @@ akm registry add https://skills.sh --name skills.sh --provider skills-sh
1650
1645
  | `--name` | Human-friendly label for the registry |
1651
1646
  | `--provider` | Provider type (e.g. `static-index`, `skills-sh`). Default: `static-index` |
1652
1647
  | `--options` | Provider-specific options as JSON (e.g. `'{"apiKey":"key"}'`) |
1653
- | `--allow-insecure` | Allow a plain HTTP registry URL (rejected by default) |
1648
+ | `--allow-insecure-transport` | Allow a plain HTTP registry URL (rejected by default) |
1654
1649
 
1655
1650
  Duplicate URLs are rejected.
1656
1651
 
@@ -1913,6 +1908,7 @@ akm env run env/prod --only A,B -- cmd # inject only A and B
1913
1908
  akm env run env/prod --except DEBUG -- cmd
1914
1909
  akm env run env/prod --clean -- cmd
1915
1910
  akm env run env/prod --clean --inherit SSH_AUTH_SOCK -- cmd
1911
+ akm env run third-party//env/prod --allow-dangerous-env-keys -- cmd
1916
1912
  ```
1917
1913
 
1918
1914
  Runs the command with the env file's values injected **directly into the child
@@ -1925,7 +1921,8 @@ environment (PATH/HOME/locale/terminal basics) instead of inheriting the full
1925
1921
  parent environment; use `--inherit KEY1,KEY2` to pass specific parent vars
1926
1922
  through in clean mode. Before spawning, the injected key names are scanned for
1927
1923
  known process-hijacking variables (`LD_PRELOAD`, `PATH`, `GIT_CONFIG_*`, ...):
1928
- a first-party bundle warns and proceeds; a third-party-sourced bundle is refused.
1924
+ a first-party bundle warns and proceeds; a third-party-sourced bundle is refused
1925
+ unless the reviewed run explicitly passes `--allow-dangerous-env-keys`.
1929
1926
 
1930
1927
  > The single-key `run <ref>/KEY` form was removed. To inject one value, store it
1931
1928
  > as a [secret](#secret) and use `akm secret run secrets/<name> <VAR> -- …`, or
@@ -2818,9 +2815,10 @@ shell commands. It manages on-disk task definitions under
2818
2815
  (cron / launchd / schtasks). Task source v4 YAML (`version: 4`) is the only
2819
2816
  executable source contract this release accepts; `akm task add` writes v4 —
2820
2817
  see the canonical [Tasks reference](tasks.md). The
2821
- group is `add | run | explain | validate | list | sync | doctor | history | prune`
2818
+ group is `add | enable | disable | run | explain | validate | list | sync | doctor | history | prune`
2822
2819
  — there is no `show` or `remove`; use `akm show tasks/<id>` to inspect one
2823
- task, and edit the file + `akm task sync` to change or remove a schedule.
2820
+ task. Use `task enable` / `task disable` for host-local activation; edit the
2821
+ file only to change the authored schedule or remove the task.
2824
2822
  `task list` is a delegating alias for `akm search --type task` — both
2825
2823
  spellings return the identical envelope.
2826
2824
 
@@ -2832,11 +2830,13 @@ akm task add <id> --schedule "@daily" \ # Register a new task and install it
2832
2830
  akm task add review --schedule "@daily" --prompt "Review recent changes" --engine reviewer
2833
2831
  akm task add nightly --schedule "@daily" --command "akm improve" --disabled # register but leave off
2834
2832
  akm task add nightly --schedule "@daily" --command "akm improve" --force # overwrite an existing task id
2833
+ akm task enable team//tasks/nightly # Add local activation and sync its bundle
2834
+ akm task disable team//tasks/nightly # Remove local activation and unschedule it
2835
2835
  akm task run <id> # Execute now (what the scheduler calls)
2836
2836
  akm task explain <ref> # Read-only: declared inputs, target, schedule — spawns nothing
2837
2837
  akm task validate <path> # Read-only: parse one task file by path, report sync's diagnostic
2838
2838
  akm task history [<id>] [--id <id>] [--limit <n>] # Recent runs from state.db (positional id == --id)
2839
- akm task sync # Reconcile on-disk YAML with scheduler
2839
+ akm task sync # Reconcile activated refs from all enabled configured bundles
2840
2840
  akm task sync --dry-run # Preview the reconcile — zero scheduler writes
2841
2841
  akm task sync --rebind # Also capture the current installed runtime
2842
2842
  akm task doctor # Report scheduler backend + paths
@@ -2869,21 +2869,19 @@ concept ref or id, and the file need not live in any configured bundle —
2869
2869
  and reports the same diagnostic `akm task sync` would produce for it,
2870
2870
  INCLUDING sync's own cron-dialect check and its per-schedule-entry
2871
2871
  input-contract check (so a file `sync` would reject can never be reported
2872
- `valid`/`converts` here): `{ok, path, sourceVersion, outcome, reason?,
2872
+ `valid` here): `{ok, path, sourceVersion, outcome, reason?,
2873
2873
  resolved?}` where `outcome` is `valid` (parses as task source v4 directly
2874
- and passes both sync checks), `converts` (task v2/v3 that the deterministic
2875
- migrator converts in memory and which then also passes both sync checks),
2876
- `blocked` (task v2/v3 the migrator itself cannot convert — needs a human
2877
- decision), `invalid` (the YAML doesn't parse, or the document fails schema
2874
+ and passes both sync checks), `blocked` (task v2/v3 that must first be
2875
+ rewritten by `akm migrate apply`), `invalid` (the YAML doesn't parse, or the document fails schema
2878
2876
  validation, or it parsed but fails one of the two sync checks), or
2879
2877
  `not-a-task` (the YAML parses but never declares a `version:` field — not
2880
2878
  shaped like a task source). `resolved` is the compiled task shape
2881
2879
  `akm task sync` itself would build a scheduler binding from — id, the
2882
2880
  compiled schema version, resolved `uses`/`run` target, declared `inputs`
2883
- contract, and `schedule` bindings — present only on `valid`/`converts`.
2881
+ contract, and `schedule` bindings — present only on `valid`.
2884
2882
  Unlike `akm task explain`, it never runs execution lowering: a command-kind
2885
2883
  task validates the same whether or not the local config has an engine
2886
- configured. Exits 0 for `valid`/`converts`, 1 for
2884
+ configured. Exits 0 for `valid`, 1 for
2887
2885
  `blocked`/`invalid`/`not-a-task`, 2 for a missing or unreadable path.
2888
2886
  **Read-only**: it never touches the scheduler and never requires the file to
2889
2887
  be indexed or wired into a bundle.
@@ -2893,9 +2891,11 @@ time. Each run is recorded as a row in the durable `task_history` table
2893
2891
  (`state.db`), surfaced by `akm task history` — **not** by `akm log`; there is
2894
2892
  no `task_invoked`/`task_completed` event type on the `akm log` stream.
2895
2893
 
2896
- To disable a scheduled task, set `enabled: false` on its `schedule:` entry
2897
- (task source v4 has no document-level `enabled` flag — it lives per
2898
- schedule-binding) and run `akm task sync`. To remove one, delete its file
2894
+ Task source cannot enable itself. `akm task enable <fully-qualified-ref>` adds
2895
+ an exact source-bound `{kind, ref, sourceId}` grant to this host's
2896
+ `scheduler.enabled` config and
2897
+ syncs that bundle; `akm task disable` removes it and unschedules the task.
2898
+ Manual `akm task run` remains available. To remove a task, delete its file
2899
2899
  (`<bundle>/tasks/<id>.yml`) and run `akm task sync` — sync uninstalls the
2900
2900
  orphaned scheduler entry.
2901
2901
 
@@ -2916,9 +2916,10 @@ to specific binding ids — naming an id that isn't a current orphan
2916
2916
  candidate (not installed, or it still resolves to a live bundle) is
2917
2917
  refused with a usage error and removes nothing.
2918
2918
 
2919
- Scheduler activation captures the installed akm runtime. Ordinary `task sync`
2920
- reconciles definitions, schedules, and enabled state while preserving that
2921
- runtime binding. Use `task sync --rebind` only after intentionally moving or
2919
+ Scheduler activation is host-local config and captures the installed akm
2920
+ runtime. Ordinary `task sync` reconciles activated refs from all enabled
2921
+ configured bundles while preserving that runtime binding. Use `task sync
2922
+ --rebind` only after intentionally moving or
2922
2923
  replacing the installation, or to repair a stale runtime path, then verify the
2923
2924
  result with `akm task doctor`. Interactive `akm setup` reviews every embedded
2924
2925
  task template (both the core set and the improve-schedule set) and asks once
@@ -2936,9 +2937,10 @@ Setup reconfiguration preserves existing scheduler runtime bindings. Changing
2936
2937
  the AKM storage path or installed runtime path therefore requires an explicit
2937
2938
  `akm task sync --rebind`; setup does not silently migrate those entries.
2938
2939
 
2939
- **Bundle targeting (`--bundle <bundle>`).** By default every subcommand
2940
- operates on the primary/default bundle. `add`, `history`, `sync`, `run`, and
2941
- `explain` all accept `--bundle <bundle>` to schedule, reconcile, or inspect
2940
+ **Bundle targeting (`--bundle <bundle>`).** By default read/write commands
2941
+ operate on the primary/default bundle, while an unscoped `sync` reconciles all
2942
+ enabled configured bundles. `add`, `enable`, `disable`, `history`, `sync`,
2943
+ `run`, and `explain` accept `--bundle <bundle>` to schedule, reconcile, or inspect
2942
2944
  tasks that live in another configured bundle (`doctor` reports scheduler-wide
2943
2945
  state and takes no `--bundle`; `validate` takes a bare filesystem path
2944
2946
  instead of a ref, so it has no bundle to target either):
@@ -2950,9 +2952,9 @@ akm task sync --bundle team-bundle # reconcile only that bundle
2950
2952
 
2951
2953
  A non-default bundle is recorded in the installed scheduler entry as a
2952
2954
  `--bundle <bundle>` token, so the scheduled `akm task run` resolves the task
2953
- (and its relative asset refs) from that bundle. `sync` reconciles one bundle at a
2954
- time and only touches entries attributed to it, so a plain (primary) sync never
2955
- disturbs another bundle's scheduled tasks. Scheduler ids are the bare task id and
2955
+ (and its relative asset refs) from that bundle. `sync --bundle` limits a run to
2956
+ one bundle; unscoped `sync` reconciles every configured bundle as one
2957
+ transaction. Scheduler ids are the bare task id and
2956
2958
  are never namespaced: registering a task whose id is already scheduled from a
2957
2959
  different bundle is a hard error.
2958
2960