akm-cli 0.9.15 → 0.9.16-alpha.2

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 (86) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/dist/assets/hints/cli-hints-full.md +13 -6
  3. package/dist/assets/tasks/improve/akm-improve-catchup.yml +3 -6
  4. package/dist/cli/retired-commands.js +0 -2
  5. package/dist/commands/env/env-binding.js +4 -4
  6. package/dist/commands/env/env-cli.js +3 -3
  7. package/dist/commands/improve/improve-cli.js +19 -14
  8. package/dist/commands/improve/reflect.js +23 -2
  9. package/dist/commands/lint/base-linter.js +9 -0
  10. package/dist/commands/lint/env-key-rules.js +2 -2
  11. package/dist/commands/proposal/propose.js +15 -1
  12. package/dist/commands/proposal/validators/proposal-quality-validators.js +40 -3
  13. package/dist/commands/proposal/validators/proposal-validators.js +5 -4
  14. package/dist/commands/read/search.js +33 -4
  15. package/dist/commands/read/show.js +21 -2
  16. package/dist/commands/registry-cli.js +5 -5
  17. package/dist/commands/sources/add-cli.js +59 -16
  18. package/dist/commands/sources/bundle-cli.js +35 -11
  19. package/dist/commands/sources/bundle-config-ops.js +30 -0
  20. package/dist/commands/sources/dangerous-env-audit.js +4 -4
  21. package/dist/commands/sources/installed-stashes.js +43 -28
  22. package/dist/commands/sources/source-add.js +33 -17
  23. package/dist/commands/sources/source-manage.js +34 -12
  24. package/dist/commands/sources/stash-skeleton.js +6 -3
  25. package/dist/commands/tasks/explain.js +4 -1
  26. package/dist/commands/tasks/tasks-cli.js +31 -9
  27. package/dist/commands/tasks/tasks.js +239 -194
  28. package/dist/commands/tasks/validate.js +20 -32
  29. package/dist/core/activation-policy.js +4 -4
  30. package/dist/core/adapter/adapters/akm-adapter.js +5 -0
  31. package/dist/core/adapter/execution-source.js +10 -29
  32. package/dist/core/config/config-schema.js +64 -8
  33. package/dist/core/config/config-sources.js +96 -2
  34. package/dist/core/config/config.js +190 -24
  35. package/dist/core/config/legacy-source-shape-shim.js +9 -0
  36. package/dist/core/config/schema/execution.js +23 -0
  37. package/dist/core/config/schema/experimental.js +1 -1
  38. package/dist/core/config/schema/scheduler.js +20 -0
  39. package/dist/core/config/schema/search.js +1 -1
  40. package/dist/core/config/schema/sources-bundles.js +32 -1
  41. package/dist/core/content-safety.js +52 -0
  42. package/dist/core/maintenance-barrier.js +6 -6
  43. package/dist/core/type-presentation.js +1 -1
  44. package/dist/core/write-source.js +13 -8
  45. package/dist/indexer/bundle-identity-guard.js +45 -8
  46. package/dist/indexer/indexer.js +1 -1
  47. package/dist/indexer/materialize-embeddings.js +15 -1
  48. package/dist/indexer/search/search-source.js +29 -11
  49. package/dist/integrations/agent/execution-lowering.js +3 -2
  50. package/dist/integrations/agent/execution-preparation.js +32 -1
  51. package/dist/integrations/agent/prompts.js +1 -1
  52. package/dist/integrations/agent/request-lowering.js +3 -2
  53. package/dist/llm/client.js +2 -1
  54. package/dist/output/shapes/passthrough.js +2 -0
  55. package/dist/registry/resolve.js +37 -10
  56. package/dist/scripts/akm-migrate-node.js +13644 -9894
  57. package/dist/scripts/akm-migrate.js +12626 -8876
  58. package/dist/setup/setup.js +3 -3
  59. package/dist/setup/steps/tasks.js +29 -36
  60. package/dist/sources/providers/git-install.js +17 -11
  61. package/dist/sources/providers/git-provider.js +12 -5
  62. package/dist/sources/providers/git-stash.js +38 -16
  63. package/dist/sources/snapshot-fetchers/website-ingest.js +3 -3
  64. package/dist/storage/repositories/index-vec-repository.js +100 -0
  65. package/dist/tasks/activation-config.js +90 -0
  66. package/dist/tasks/backends/cron.js +9 -0
  67. package/dist/tasks/backends/launchd.js +1 -0
  68. package/dist/tasks/backends/schtasks.js +2 -0
  69. package/dist/tasks/embedded.js +4 -5
  70. package/dist/tasks/scheduler-binding.js +2 -2
  71. package/dist/tasks/scheduler-sync-preview.js +8 -1
  72. package/dist/tasks/scheduler-sync.js +19 -10
  73. package/dist/tasks/source/parse-task-source.js +10 -113
  74. package/dist/tasks/source/project-v4.js +2 -2
  75. package/dist/tasks/source/task-source-v4.js +4 -12
  76. package/dist/tasks/source/task-to-v3.js +4 -12
  77. package/dist/tasks/source/task-to-v4.js +40 -7
  78. package/docs/migration/README.md +1 -0
  79. package/docs/migration/release-notes/0.9.16.md +72 -0
  80. package/docs/migration/v0.9.1-to-v0.9.2.md +6 -9
  81. package/docs/reference/cli.md +37 -29
  82. package/docs/reference/configuration.md +48 -5
  83. package/docs/reference/tasks.md +34 -29
  84. package/package.json +1 -1
  85. package/schemas/akm-config.json +112 -4
  86. package/schemas/akm-task.json +1 -2
@@ -1042,7 +1042,8 @@ akm bundle add https://docs.example.com --max-pages 100 --max-depth 5
1042
1042
  | `--provider` | Explicit provider for declarative source configuration; normally inferred from the input |
1043
1043
  | `--writable` | Mark a git source as writable so `akm sync` also pushes (default: false) |
1044
1044
  | `--options` | Provider options as JSON (e.g. `'{"ref":"main"}'`) |
1045
- | `--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 |
1046
1047
  | `--max-pages` | Maximum pages to crawl for website sources (default: 50) |
1047
1048
  | `--max-depth` | Maximum crawl depth for website sources (default: 3) |
1048
1049
 
@@ -1070,7 +1071,7 @@ config override injection).
1070
1071
 
1071
1072
  When dangerous keys are found, `akm bundle add` pauses and prompts for
1072
1073
  confirmation (default: No). In non-interactive mode (CI, scripts) the
1073
- 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
1074
1075
  freshly-installed bundle is rolled back before the process exits.
1075
1076
 
1076
1077
  ```sh
@@ -1078,7 +1079,7 @@ freshly-installed bundle is rolled back before the process exits.
1078
1079
  akm bundle add github:owner/repo-with-sensitive-env
1079
1080
 
1080
1081
  # Non-interactive: fails unless bypassed
1081
- 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
1082
1083
  ```
1083
1084
 
1084
1085
  Bundle publishers: see the [Author Bundles guide](https://github.com/itlackey/akm/blob/main/docs/guides/author-bundles.md#env-security)
@@ -1155,14 +1156,14 @@ akm bundle update npm:@scope/pkg
1155
1156
  akm bundle update --all
1156
1157
  akm bundle update --all --force # Force fresh download even if version is unchanged
1157
1158
  akm bundle update --all --yes # Skip confirmation when an update needs to delete a moved install dir
1158
- 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
1159
1160
  ```
1160
1161
 
1161
1162
  | Flag | Description |
1162
1163
  | --- | --- |
1163
1164
  | `--all` | Update all managed sources |
1164
1165
  | `--force` | Delete cached extraction before re-downloading |
1165
- | `--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`. |
1166
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. |
1167
1168
 
1168
1169
  The audit examines key names in `.env`-suffixed files under the staged
@@ -1644,7 +1645,7 @@ akm registry add https://skills.sh --name skills.sh --provider skills-sh
1644
1645
  | `--name` | Human-friendly label for the registry |
1645
1646
  | `--provider` | Provider type (e.g. `static-index`, `skills-sh`). Default: `static-index` |
1646
1647
  | `--options` | Provider-specific options as JSON (e.g. `'{"apiKey":"key"}'`) |
1647
- | `--allow-insecure` | Allow a plain HTTP registry URL (rejected by default) |
1648
+ | `--allow-insecure-transport` | Allow a plain HTTP registry URL (rejected by default) |
1648
1649
 
1649
1650
  Duplicate URLs are rejected.
1650
1651
 
@@ -1907,6 +1908,7 @@ akm env run env/prod --only A,B -- cmd # inject only A and B
1907
1908
  akm env run env/prod --except DEBUG -- cmd
1908
1909
  akm env run env/prod --clean -- cmd
1909
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
1910
1912
  ```
1911
1913
 
1912
1914
  Runs the command with the env file's values injected **directly into the child
@@ -1919,7 +1921,8 @@ environment (PATH/HOME/locale/terminal basics) instead of inheriting the full
1919
1921
  parent environment; use `--inherit KEY1,KEY2` to pass specific parent vars
1920
1922
  through in clean mode. Before spawning, the injected key names are scanned for
1921
1923
  known process-hijacking variables (`LD_PRELOAD`, `PATH`, `GIT_CONFIG_*`, ...):
1922
- 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`.
1923
1926
 
1924
1927
  > The single-key `run <ref>/KEY` form was removed. To inject one value, store it
1925
1928
  > as a [secret](#secret) and use `akm secret run secrets/<name> <VAR> -- …`, or
@@ -2812,9 +2815,10 @@ shell commands. It manages on-disk task definitions under
2812
2815
  (cron / launchd / schtasks). Task source v4 YAML (`version: 4`) is the only
2813
2816
  executable source contract this release accepts; `akm task add` writes v4 —
2814
2817
  see the canonical [Tasks reference](tasks.md). The
2815
- 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`
2816
2819
  — there is no `show` or `remove`; use `akm show tasks/<id>` to inspect one
2817
- 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.
2818
2822
  `task list` is a delegating alias for `akm search --type task` — both
2819
2823
  spellings return the identical envelope.
2820
2824
 
@@ -2826,11 +2830,13 @@ akm task add <id> --schedule "@daily" \ # Register a new task and install it
2826
2830
  akm task add review --schedule "@daily" --prompt "Review recent changes" --engine reviewer
2827
2831
  akm task add nightly --schedule "@daily" --command "akm improve" --disabled # register but leave off
2828
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
2829
2835
  akm task run <id> # Execute now (what the scheduler calls)
2830
2836
  akm task explain <ref> # Read-only: declared inputs, target, schedule — spawns nothing
2831
2837
  akm task validate <path> # Read-only: parse one task file by path, report sync's diagnostic
2832
2838
  akm task history [<id>] [--id <id>] [--limit <n>] # Recent runs from state.db (positional id == --id)
2833
- akm task sync # Reconcile on-disk YAML with scheduler
2839
+ akm task sync # Reconcile activated refs from all enabled configured bundles
2834
2840
  akm task sync --dry-run # Preview the reconcile — zero scheduler writes
2835
2841
  akm task sync --rebind # Also capture the current installed runtime
2836
2842
  akm task doctor # Report scheduler backend + paths
@@ -2863,21 +2869,19 @@ concept ref or id, and the file need not live in any configured bundle —
2863
2869
  and reports the same diagnostic `akm task sync` would produce for it,
2864
2870
  INCLUDING sync's own cron-dialect check and its per-schedule-entry
2865
2871
  input-contract check (so a file `sync` would reject can never be reported
2866
- `valid`/`converts` here): `{ok, path, sourceVersion, outcome, reason?,
2872
+ `valid` here): `{ok, path, sourceVersion, outcome, reason?,
2867
2873
  resolved?}` where `outcome` is `valid` (parses as task source v4 directly
2868
- and passes both sync checks), `converts` (task v2/v3 that the deterministic
2869
- migrator converts in memory and which then also passes both sync checks),
2870
- `blocked` (task v2/v3 the migrator itself cannot convert — needs a human
2871
- 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
2872
2876
  validation, or it parsed but fails one of the two sync checks), or
2873
2877
  `not-a-task` (the YAML parses but never declares a `version:` field — not
2874
2878
  shaped like a task source). `resolved` is the compiled task shape
2875
2879
  `akm task sync` itself would build a scheduler binding from — id, the
2876
2880
  compiled schema version, resolved `uses`/`run` target, declared `inputs`
2877
- contract, and `schedule` bindings — present only on `valid`/`converts`.
2881
+ contract, and `schedule` bindings — present only on `valid`.
2878
2882
  Unlike `akm task explain`, it never runs execution lowering: a command-kind
2879
2883
  task validates the same whether or not the local config has an engine
2880
- configured. Exits 0 for `valid`/`converts`, 1 for
2884
+ configured. Exits 0 for `valid`, 1 for
2881
2885
  `blocked`/`invalid`/`not-a-task`, 2 for a missing or unreadable path.
2882
2886
  **Read-only**: it never touches the scheduler and never requires the file to
2883
2887
  be indexed or wired into a bundle.
@@ -2887,9 +2891,11 @@ time. Each run is recorded as a row in the durable `task_history` table
2887
2891
  (`state.db`), surfaced by `akm task history` — **not** by `akm log`; there is
2888
2892
  no `task_invoked`/`task_completed` event type on the `akm log` stream.
2889
2893
 
2890
- To disable a scheduled task, set `enabled: false` on its `schedule:` entry
2891
- (task source v4 has no document-level `enabled` flag — it lives per
2892
- 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
2893
2899
  (`<bundle>/tasks/<id>.yml`) and run `akm task sync` — sync uninstalls the
2894
2900
  orphaned scheduler entry.
2895
2901
 
@@ -2910,9 +2916,10 @@ to specific binding ids — naming an id that isn't a current orphan
2910
2916
  candidate (not installed, or it still resolves to a live bundle) is
2911
2917
  refused with a usage error and removes nothing.
2912
2918
 
2913
- Scheduler activation captures the installed akm runtime. Ordinary `task sync`
2914
- reconciles definitions, schedules, and enabled state while preserving that
2915
- 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
2916
2923
  replacing the installation, or to repair a stale runtime path, then verify the
2917
2924
  result with `akm task doctor`. Interactive `akm setup` reviews every embedded
2918
2925
  task template (both the core set and the improve-schedule set) and asks once
@@ -2930,9 +2937,10 @@ Setup reconfiguration preserves existing scheduler runtime bindings. Changing
2930
2937
  the AKM storage path or installed runtime path therefore requires an explicit
2931
2938
  `akm task sync --rebind`; setup does not silently migrate those entries.
2932
2939
 
2933
- **Bundle targeting (`--bundle <bundle>`).** By default every subcommand
2934
- operates on the primary/default bundle. `add`, `history`, `sync`, `run`, and
2935
- `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
2936
2944
  tasks that live in another configured bundle (`doctor` reports scheduler-wide
2937
2945
  state and takes no `--bundle`; `validate` takes a bare filesystem path
2938
2946
  instead of a ref, so it has no bundle to target either):
@@ -2944,9 +2952,9 @@ akm task sync --bundle team-bundle # reconcile only that bundle
2944
2952
 
2945
2953
  A non-default bundle is recorded in the installed scheduler entry as a
2946
2954
  `--bundle <bundle>` token, so the scheduled `akm task run` resolves the task
2947
- (and its relative asset refs) from that bundle. `sync` reconciles one bundle at a
2948
- time and only touches entries attributed to it, so a plain (primary) sync never
2949
- 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
2950
2958
  are never namespaced: registering a task whose id is already scheduled from a
2951
2959
  different bundle is a hard error.
2952
2960
 
@@ -16,14 +16,13 @@ auto-upgrade in memory (see "Version read shim" below). Missing, newer,
16
16
  numeric, and any other unrecognized version are rejected by ordinary
17
17
  commands without rewriting the file — an older binary never guesses at a
18
18
  newer, unknown shape. Pre-0.9 config and database layouts are not runtime
19
- inputs and are not migrated by `akm upgrade`. Configure the current schema
20
- directly. The standalone migrator exists only for explicit task migration:
21
- task v2 to task v3, then task v3 to task source v4, in one pass.
19
+ inputs. Historical task sources and scheduler activation are handled by the
20
+ standalone `akm-migrate` executable, also invoked by `akm migrate` / `akm
21
+ upgrade`; ordinary runtime code reads only the current shape.
22
22
 
23
23
  ### Version read shim
24
24
 
25
- Like the task-source v2/v3 auto-shim (`akm migrate apply`'s in-memory
26
- counterpart, documented under Migration below), a known older `configVersion`
25
+ For config only, a known older `configVersion`
27
26
  is converted to the current shape in memory on load — with a one-line stderr
28
27
  deprecation warning — rather than hard-failing every command. Nothing is
29
28
  written back to disk by the shim itself; the very next config-mutating
@@ -64,6 +63,9 @@ the first bump that will need it, per #863.
64
63
  "maxConcurrency": 8,
65
64
  "judgeEngine": "reviewer"
66
65
  },
66
+ "execution": {
67
+ "allowedTools": ["read_file", "search"]
68
+ },
67
69
  "improve": {
68
70
  "strategies": {
69
71
  "nightly": {
@@ -78,6 +80,25 @@ the first bump that will need it, per #863.
78
80
  }
79
81
  ```
80
82
 
83
+ ## Scheduler activation
84
+
85
+ `scheduler.enabled` is this host's explicit scheduling allow-list. Each entry
86
+ has a `kind` (`task` or `workflow`), a canonical fully qualified `ref`, and a
87
+ `sourceId` binding the grant to the configured source installation that was
88
+ approved. Absence means disabled. Replacing a bundle's path or locator under
89
+ the same name invalidates the old grant; ordinary updates from the same origin
90
+ do not. Authored task/workflow files may describe schedules but cannot grant
91
+ themselves authority to create native scheduler entries. Do not edit
92
+ `sourceId` manually: `akm task enable` writes it, and `akm migrate apply`
93
+ upgrades grants written by older releases.
94
+
95
+ This key is deliberately local: if a config uses `extends`, any `scheduler`
96
+ section in the base is ignored with a warning. Only the top-level local config
97
+ can activate schedules. Prefer `akm task enable <ref>` and `akm task disable
98
+ <ref>` over editing the JSON by hand; both update the allow-list and sync the
99
+ affected bundle. An unscoped `akm task sync` reconciles enabled refs across all
100
+ enabled configured bundles.
101
+
81
102
  ## Engines
82
103
 
83
104
  `engines` is the only public execution map. An engine name is lowercase
@@ -112,6 +133,12 @@ An agent engine may set `bin`, `args`, `workspace`, `model`, and `timeoutMs`.
112
133
  Only `platform: "opencode-sdk"` may set `llmEngine`; it names
113
134
  the LLM engine used as that SDK engine's fallback connection.
114
135
 
136
+ Executable assets may request tools, but the request is not authority. Configure
137
+ the host-local `execution.allowedTools` list to define the ceiling; `"*"` is an
138
+ explicit allow-all. The default is an empty list. Asset frontmatter cannot set
139
+ `workspace`, `environment`, or opaque `runtime` values; those belong to local
140
+ engine configuration or workflow environment bindings.
141
+
115
142
  `platform: "opencode-sdk"` needs the **`opencode` binary** on PATH (or a `bin`
116
143
  pointing at it). akm bundles `@opencode-ai/sdk`, but that package is an HTTP
117
144
  client with no dependencies — it spawns `opencode serve` and talks to it — so
@@ -551,6 +578,12 @@ bundle's `components.<id>.adapter` key pins it to a specific format adapter
551
578
  instead of relying on auto-detection — see [Bundle Types](bundle-types.md)
552
579
  for the full adapter list and what each one reads/writes.
553
580
 
581
+ Each physical content root has one bundle id. Duplicate paths and symbolic-link
582
+ aliases are rejected because source ownership, scheduler authority, and default
583
+ selection must not depend on which spelling a caller used. If an older config
584
+ contains aliases, choose the id whose durable refs should survive and remove
585
+ the other entry before running ordinary commands.
586
+
554
587
  ### defaultWriteTarget
555
588
 
556
589
  `defaultWriteTarget` names the bundle that write commands (`akm remember`,
@@ -700,6 +733,16 @@ one file, and have each host's local config extend it.
700
733
  add`/`akm sync` first so the file is materialized locally, then point
701
734
  `extends` at it.
702
735
 
736
+ Shared layers carry portable policy, not host authority. `bundles`, source and
737
+ write defaults, registries, embedding connections, scheduler grants,
738
+ `execution`, `experimental`, and setup state are ignored when inherited.
739
+ Engine definitions may be shared, but credentials and executable authority
740
+ (`apiKey`, `apiKeyFile`, `bin`, `args`, and `workspace`) must be supplied by
741
+ the local file. Improve publication (`strategies.*.sync`) and reranker network
742
+ configuration are local as well. Bundle-relative chains stay physically inside
743
+ the bundle root for every hop; lexical `..` paths and symlink escapes are both
744
+ rejected before a referenced file is read.
745
+
703
746
  There is no `extends: <url>` form: config load is synchronous and runs on
704
747
  every invocation, and akm deliberately does not fetch network resources at
705
748
  load time (the same reason `registries` is never fetched until a
@@ -148,12 +148,10 @@ name: Nightly review
148
148
  run: akm improve --strategy default
149
149
  schedule:
150
150
  - cron: "@daily"
151
- enabled: false
152
151
  ```
153
152
 
154
- A bare string (`schedule: "0 8 * * 1"`) is shorthand for one enabled
155
- binding with no inputs. A list entry may set its own `enabled` (default
156
- `true`) and literal `inputs`; those literals are validated against the
153
+ A bare string (`schedule: "0 8 * * 1"`) is shorthand for one trigger with
154
+ no inputs. A list entry may set literal `inputs`; those literals are validated against the
157
155
  task's `inputs:` declarations both at parse time and again at
158
156
  `akm task sync` (once with declared defaults applied), and are
159
157
  **delivered** to the scheduled run: `akm task sync` compiles each entry's
@@ -163,18 +161,26 @@ fired run receives them exactly as `akm task run <id> --<name> <value>`
163
161
  would. Multiple schedule entries create deterministic scheduler bindings
164
162
  for the one source task.
165
163
 
166
- Task source v4 has **no document-level `enabled` flag** — enablement is
167
- per schedule binding. Disable one binding by setting its own
168
- `enabled: false`. `--schedule` is a required flag on every `akm task add`
169
- invocation, `--disabled` included — not a check specific to `--disabled` —
170
- so `akm task add --disabled` always has a schedule to write `enabled: false`
171
- onto and never needs to reject a schedule-less task with "nothing to
172
- disable."
164
+ Task source v4 has **no enablement flag**. A source describes what may run;
165
+ it cannot authorize its own host scheduling. Activation is an exact,
166
+ host-local allow-list in `config.json` under `scheduler.enabled`, keyed by
167
+ asset kind, fully qualified ref, and the approved source installation identity.
168
+ Absence means disabled. A removed, disabled, or replaced bundle cannot reuse a
169
+ grant written for an earlier source under the same name. Use `akm task
170
+ enable <bundle>//tasks/<id>` and `akm task disable <bundle>//tasks/<id>` to
171
+ change that list and immediately sync the affected bundle. `akm task add`
172
+ enables its new task by default; `--disabled` writes the same task source but
173
+ does not add the local activation.
173
174
 
174
175
  `akm task run <id>` executes a task immediately, including a disabled task.
175
- `akm task sync` validates the complete desired set before atomically
176
- reconciling scheduler state. Scheduled invocations re-read the guarded current
177
- task bytes; workflow targets then create a fresh durable workflow freeze.
176
+ `akm task sync` scans every enabled configured bundle, selects only locally
177
+ activated task/workflow refs, validates the complete desired set, and then
178
+ atomically reconciles scheduler state. `--bundle <name>` narrows that pass to
179
+ one active bundle. If every configured bundle is disabled, sync removes the
180
+ attributable native entries without reading task content. Scheduled task
181
+ invocations check both the local activation and current source identity again at
182
+ fire time before re-reading the guarded current task bytes; workflow targets
183
+ then create a fresh durable workflow freeze.
178
184
 
179
185
  ## Typed inputs and output
180
186
 
@@ -200,7 +206,6 @@ output:
200
206
  uses: commands/review
201
207
  schedule:
202
208
  - cron: "0 8 * * 1"
203
- enabled: true
204
209
  inputs: { scope: all, ticket: OPS-1234 }
205
210
  timeout: 45000
206
211
  engine: reviewer
@@ -229,9 +234,7 @@ redact: [TOKEN]
229
234
  field path (`schedule`, or `schedule[<i>]`), naming the unsatisfied
230
235
  input. The rule covers every entry: the `schedule: "<cron>"` string
231
236
  shorthand, a list entry with no `inputs:` key, and an entry whose
232
- `inputs:` mapping is present but incomplete — including one written
233
- `enabled: false`, so enabling it later can never turn a parsed document
234
- unrunnable. `akm task sync` keeps its own equivalent check over the
237
+ `inputs:` mapping is present but incomplete. `akm task sync` keeps its own equivalent check over the
235
238
  defaulted values and still rejects the whole desired set before touching
236
239
  any scheduler state. Give every schedule entry an explicit value for the
237
240
  input, or declare a `default` instead; manual runs are unaffected — a
@@ -343,7 +346,8 @@ Common v2 → v3 blocked reasons and what to do about each — these need a
343
346
  hand-authored replacement, not a re-run; see [the 0.9.1 to 0.9.2 migration
344
347
  guide](../migration/v0.9.1-to-v0.9.2.md#v2--v3-blocked-cases) for the full v2
345
348
  to v4 field mapping (`command:` array → `run:` + `shell:`, `timeoutMs:` →
346
- `timeout:`, document-level `enabled:` → per-`schedule:`-entry `enabled`):
349
+ `timeout:`). Source-owned `enabled` fields are removed; native bindings that
350
+ are provably enabled seed the host-local activation list:
347
351
 
348
352
  | Reason | Meaning | Fix |
349
353
  |---|---|---|
@@ -357,7 +361,6 @@ Common v3 → v4 blocked reasons and what to do about each:
357
361
  | `github-action-target-removed` | The task's `uses:` is a GitHub Action locator (`owner/repo[/path]@ref`); that spelling has no task source v4 equivalent. | Rewrite the target as `commands/`, `scripts/`, `workflows/`, or `akm/command` by hand. |
358
362
  | `with-on-non-command-target` | A `with:` block is authored on a target other than `uses: akm/command`. | Task-call inputs are declared and bound separately in v4 — author `inputs:` on the task and, if it is a workflow step's own composition, bind them with the step's `with:` instead. |
359
363
  | `ambiguous-scheduling-source` | The document declares both `akm.schedule` and `on:`. | Pick one; the migrator will not guess which one wins. |
360
- | `enabled-false-has-no-schedule-entry` | `akm.enabled: false` with no cron trigger to attach it to (the only trigger is `on.workflow_dispatch`). | Task source v4 has no document-level `enabled` flag — decide whether the task should be scheduled (add a cron) or left manual-only (drop `akm.enabled`), then re-run. |
361
364
  | `read-only-source` | The owning source or file is not writable. | Move or re-source the file somewhere writable, or edit it by hand. |
362
365
  | `invalid-v3-task` | The v3 document itself is structurally invalid (unknown fields, missing selector, malformed trigger, etc). | Fix the underlying v3 document first — the migrator translates structure, it does not repair it. |
363
366
  | `generated-v4-validation-failed` | The converted bytes fail the real task source v4 parser; the detail carries the parse error. | Read the detail — it names the offending field and why v4 refuses it — then fix that field in the v3 file and preview again. |
@@ -402,20 +405,20 @@ for full before/after examples and recovery guidance.
402
405
  anything — see [`akm task explain`](#akm-task-explain) above.
403
406
  - `akm task validate <path>` parses one task file by filesystem path (the
404
407
  file need not live in a configured bundle) and reports the same
405
- `valid`/`converts`/`blocked`/`invalid`/`not-a-task` diagnostic
408
+ `valid`/`blocked`/`invalid`/`not-a-task` diagnostic
406
409
  `akm task sync` would produce for it — including sync's own cron-dialect
407
410
  check and its per-schedule-entry input-contract check — without touching
408
411
  the scheduler and without requiring a configured engine, even for a
409
412
  command-kind task. The envelope's own `sourceVersion` field names the
410
- file's originally declared schema version (2, 3, or 4).
413
+ file's declared schema version. Version 2/3 files are `blocked` with an
414
+ `akm migrate apply` instruction; validation never migrates them in memory.
411
415
  - `akm task add` writes a task source v4 document and installs it after
412
416
  validation. `--params` renders typed `inputs:` declarations instead of a
413
- `with:` bag; `--schedule` is required on every invocation, and
414
- `--disabled` writes `schedule: [{cron: …, enabled: false}]` instead of a
415
- document-level flag.
417
+ `with:` bag; `--schedule` is required on every invocation. `--disabled`
418
+ leaves the new ref absent from local scheduler activation.
416
419
  - `akm task history` reads durable run history from `state.db`.
417
- - Disable a binding by editing the source and syncing: set that schedule
418
- entry's own `enabled: false`.
420
+ - `akm task enable <ref>` / `akm task disable <ref>` change only local
421
+ scheduler config, then reconcile that bundle.
419
422
  - Delete the `.yml` source and sync to remove its derived binding(s).
420
423
  - `akm task sync --dry-run` previews the reconcile (adds/updates/removes,
421
424
  removals annotated with their owning bundle) without writing to the
@@ -469,8 +472,10 @@ on:
469
472
  refs consumed it as run params; command/script refs rejected it outright).
470
473
  A GitHub Action locator (`owner/repo[/path]@ref`) was a recognized `uses:`
471
474
  shape that was always rejected before dispatch — remote action acquisition
472
- was never implemented in any akm release. `akm.enabled: false` disabled the
473
- whole document, not a specific schedule binding.
475
+ was never implemented in any akm release. `akm.enabled` was source-owned
476
+ scheduling state. `akm migrate apply` removes it; migration preserves actual
477
+ host activation only when the native scheduler proves that the corresponding
478
+ binding is enabled.
474
479
 
475
480
  See [Migrating to task source v4](#migrating-to-task-source-v4) above to
476
481
  convert a file out of this grammar.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akm-cli",
3
- "version": "0.9.15",
3
+ "version": "0.9.16-alpha.2",
4
4
  "type": "module",
5
5
  "description": "akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cursor.",
6
6
  "keywords": [
@@ -249,6 +249,20 @@
249
249
  },
250
250
  "additionalProperties": true
251
251
  },
252
+ "execution": {
253
+ "type": "object",
254
+ "properties": {
255
+ "allowedTools": {
256
+ "type": "array",
257
+ "items": {
258
+ "type": "string",
259
+ "minLength": 1
260
+ },
261
+ "default": []
262
+ }
263
+ },
264
+ "additionalProperties": false
265
+ },
252
266
  "index": {
253
267
  "type": "object",
254
268
  "properties": {
@@ -473,6 +487,10 @@
473
487
  "type": "string",
474
488
  "minLength": 1
475
489
  },
490
+ "credential": {
491
+ "type": "string",
492
+ "minLength": 1
493
+ },
476
494
  "writable": {
477
495
  "type": "boolean"
478
496
  },
@@ -623,7 +641,7 @@
623
641
  "maximum": 50
624
642
  }
625
643
  },
626
- "additionalProperties": true
644
+ "additionalProperties": false
627
645
  }
628
646
  },
629
647
  "additionalProperties": true
@@ -1710,6 +1728,42 @@
1710
1728
  },
1711
1729
  "additionalProperties": true
1712
1730
  },
1731
+ "scheduler": {
1732
+ "type": "object",
1733
+ "properties": {
1734
+ "enabled": {
1735
+ "type": "array",
1736
+ "items": {
1737
+ "type": "object",
1738
+ "properties": {
1739
+ "kind": {
1740
+ "type": "string",
1741
+ "enum": [
1742
+ "task",
1743
+ "workflow"
1744
+ ]
1745
+ },
1746
+ "ref": {
1747
+ "type": "string",
1748
+ "minLength": 1
1749
+ },
1750
+ "sourceId": {
1751
+ "type": "string",
1752
+ "pattern": "^sha256:[0-9a-f]{64}$"
1753
+ }
1754
+ },
1755
+ "required": [
1756
+ "kind",
1757
+ "ref",
1758
+ "sourceId"
1759
+ ],
1760
+ "additionalProperties": false
1761
+ },
1762
+ "default": []
1763
+ }
1764
+ },
1765
+ "additionalProperties": false
1766
+ },
1713
1767
  "setup": {
1714
1768
  "type": "object",
1715
1769
  "properties": {},
@@ -1722,7 +1776,7 @@
1722
1776
  "type": "boolean"
1723
1777
  }
1724
1778
  },
1725
- "additionalProperties": true
1779
+ "additionalProperties": false
1726
1780
  }
1727
1781
  },
1728
1782
  "required": [
@@ -1977,6 +2031,20 @@
1977
2031
  },
1978
2032
  "additionalProperties": true
1979
2033
  },
2034
+ "execution": {
2035
+ "type": "object",
2036
+ "properties": {
2037
+ "allowedTools": {
2038
+ "type": "array",
2039
+ "items": {
2040
+ "type": "string",
2041
+ "minLength": 1
2042
+ },
2043
+ "default": []
2044
+ }
2045
+ },
2046
+ "additionalProperties": false
2047
+ },
1980
2048
  "index": {
1981
2049
  "type": "object",
1982
2050
  "properties": {
@@ -2201,6 +2269,10 @@
2201
2269
  "type": "string",
2202
2270
  "minLength": 1
2203
2271
  },
2272
+ "credential": {
2273
+ "type": "string",
2274
+ "minLength": 1
2275
+ },
2204
2276
  "writable": {
2205
2277
  "type": "boolean"
2206
2278
  },
@@ -2351,7 +2423,7 @@
2351
2423
  "maximum": 50
2352
2424
  }
2353
2425
  },
2354
- "additionalProperties": true
2426
+ "additionalProperties": false
2355
2427
  }
2356
2428
  },
2357
2429
  "additionalProperties": true
@@ -3438,6 +3510,42 @@
3438
3510
  },
3439
3511
  "additionalProperties": true
3440
3512
  },
3513
+ "scheduler": {
3514
+ "type": "object",
3515
+ "properties": {
3516
+ "enabled": {
3517
+ "type": "array",
3518
+ "items": {
3519
+ "type": "object",
3520
+ "properties": {
3521
+ "kind": {
3522
+ "type": "string",
3523
+ "enum": [
3524
+ "task",
3525
+ "workflow"
3526
+ ]
3527
+ },
3528
+ "ref": {
3529
+ "type": "string",
3530
+ "minLength": 1
3531
+ },
3532
+ "sourceId": {
3533
+ "type": "string",
3534
+ "pattern": "^sha256:[0-9a-f]{64}$"
3535
+ }
3536
+ },
3537
+ "required": [
3538
+ "kind",
3539
+ "ref",
3540
+ "sourceId"
3541
+ ],
3542
+ "additionalProperties": false
3543
+ },
3544
+ "default": []
3545
+ }
3546
+ },
3547
+ "additionalProperties": false
3548
+ },
3441
3549
  "setup": {
3442
3550
  "type": "object",
3443
3551
  "properties": {},
@@ -3450,7 +3558,7 @@
3450
3558
  "type": "boolean"
3451
3559
  }
3452
3560
  },
3453
- "additionalProperties": true
3561
+ "additionalProperties": false
3454
3562
  }
3455
3563
  },
3456
3564
  "required": [
@@ -179,13 +179,12 @@
179
179
  "pattern": "^(?:[^\\s:.#/]+//)?commands/(?!\\.{1,2}(?:/|$))[^\\s#\\\\/\\u0000]+(?:/(?!\\.{1,2}(?:/|$))[^\\s#\\\\/\\u0000]+)*$"
180
180
  },
181
181
  "taskSourceV4ScheduleEntry": {
182
- "description": "One schedule: list entry (D2-N5: per-entry enabled defaults true; inputs are validated against inputs: at parse time and delivered to the scheduled run's own invocation, P2b).",
182
+ "description": "One schedule: list entry. Activation is host-local scheduler configuration, never task source; inputs are validated against inputs: at parse time and delivered to the scheduled run's own invocation.",
183
183
  "type": "object",
184
184
  "required": ["cron"],
185
185
  "additionalProperties": false,
186
186
  "properties": {
187
187
  "cron": { "$ref": "#/definitions/nonemptyLiteral" },
188
- "enabled": { "type": "boolean" },
189
188
  "inputs": { "$ref": "#/definitions/taskSourceV4ScheduleInputs" }
190
189
  }
191
190
  },