akm-cli 0.9.30 → 0.9.32
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 +40 -0
- package/README.md +10 -10
- package/ROADMAP.md +112 -0
- package/dist/commands/feedback-cli.js +21 -13
- package/dist/commands/improve/improve-cli.js +33 -12
- package/dist/core/errors.js +1 -0
- package/dist/core/file-lock.js +10 -1
- package/dist/indexer/usage/usage-events.js +6 -2
- package/dist/llm/client.js +33 -3
- package/dist/scripts/akm-migrate-node.js +6 -1
- package/dist/scripts/akm-migrate.js +6 -1
- package/docs/README.md +42 -41
- package/docs/agents/README.md +15 -0
- package/docs/agents/agent-install.md +14 -0
- package/docs/architecture/README.md +67 -0
- package/docs/architecture/adapters.md +272 -0
- package/docs/architecture/akm-architecture-decision-history.md +2055 -0
- package/docs/architecture/akm-core-principles.md +126 -0
- package/docs/architecture/architecture.md +579 -0
- package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +550 -0
- package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +72 -0
- package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +142 -0
- package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +189 -0
- package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +97 -0
- package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +108 -0
- package/docs/architecture/decisions/0006-task-source-version-routing.md +124 -0
- package/docs/architecture/decisions/0007-workflow-composition-bounds.md +83 -0
- package/docs/architecture/decisions/0008-task-binding-normalization.md +88 -0
- package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +80 -0
- package/docs/architecture/decisions/0010-driver-protocol-cut.md +36 -0
- package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +125 -0
- package/docs/architecture/decisions/README.md +62 -0
- package/docs/architecture/improvement.md +440 -0
- package/docs/architecture/internals/classification.md +154 -0
- package/docs/architecture/internals/fresh-host-rebuild-runbook.md +40 -0
- package/docs/architecture/internals/functional-contract-patterns.md +340 -0
- package/docs/architecture/internals/health-advisories.md +110 -0
- package/docs/architecture/internals/improve-workflow.md +713 -0
- package/docs/architecture/internals/indexing.md +498 -0
- package/docs/architecture/internals/registry-network-boundary.md +57 -0
- package/docs/architecture/internals/search.md +249 -0
- package/docs/architecture/internals/storage-locations.md +943 -0
- package/docs/architecture/persisted-data-compat.md +59 -0
- package/docs/architecture/reviews/env-secret-access.md +319 -0
- package/docs/architecture/runtime-boundary-design.md +153 -0
- package/docs/architecture/specs/0.9.0-close-out-plan.md +361 -0
- package/docs/architecture/specs/0.9.0-decisions.md +528 -0
- package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +745 -0
- package/docs/architecture/specs/0.9.0-open-items-register.md +135 -0
- package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +740 -0
- package/docs/architecture/specs/0.9.0-release-surface-review.md +636 -0
- package/docs/architecture/specs/agent-command-engine-model-design.md +513 -0
- package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +501 -0
- package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +291 -0
- package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +2059 -0
- package/docs/architecture/specs/di-seams-plan.md +539 -0
- package/docs/architecture/specs/driver-protocol-keep-or-cut.md +275 -0
- package/docs/architecture/specs/fact-asset-type.md +142 -0
- package/docs/architecture/specs/improve-collapse-churn-detector-design.md +634 -0
- package/docs/architecture/specs/okf-support.md +148 -0
- package/docs/architecture/specs/ref.md +329 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/README.md +72 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +152 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +352 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +300 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +402 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +758 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +645 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +602 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +27 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +27 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +74 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +15 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +132 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +147 -0
- package/docs/architecture/specs/stash-conventions-code-spec.md +275 -0
- package/docs/architecture/specs/stash-organization-conventions.md +377 -0
- package/docs/architecture/specs/task-workflow-format-unification.md +721 -0
- package/docs/architecture/specs/workflow-engine-buy-vs-build.md +231 -0
- package/docs/architecture/specs/workflow-format-unification.md +437 -0
- package/docs/architecture/testing/manual-testing-checklist.md +3420 -0
- package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +924 -0
- package/docs/architecture/testing/task-workflow-manual-tests.md +1817 -0
- package/docs/architecture/testing/testing-workflow.md +446 -0
- package/docs/architecture/workflow-engine.md +274 -0
- package/docs/guides/README.md +33 -0
- package/docs/guides/author-bundles.md +310 -0
- package/docs/guides/author-workflows.md +520 -0
- package/docs/guides/bundles.md +321 -0
- package/docs/guides/capture-knowledge.md +136 -0
- package/docs/guides/claude-code-vs-akm-workflows.md +30 -0
- package/docs/guides/concepts.md +93 -0
- package/docs/guides/discover-and-load.md +158 -0
- package/docs/guides/getting-started.md +240 -0
- package/docs/guides/improve-the-library.md +246 -0
- package/docs/guides/knowledge-management.md +18 -0
- package/docs/guides/recipes/headless-install.md +97 -0
- package/docs/guides/recipes/website-source.md +28 -0
- package/docs/guides/run-workflows.md +279 -0
- package/docs/guides/scheduling.md +123 -0
- package/docs/guides/use-with-any-agent.md +129 -0
- package/docs/guides/wikis.md +81 -0
- package/docs/maintainers/README.md +19 -0
- package/docs/maintainers/curate-workmap.md +336 -0
- package/docs/maintainers/eval.md +3 -0
- package/docs/maintainers/local-development.md +108 -0
- package/docs/maintainers/release-checklist.md +103 -0
- package/docs/migration/README.md +2 -2
- package/docs/migration/release-notes/0.0.13.md +1 -1
- package/docs/migration/release-notes/0.1.0.md +1 -1
- package/docs/migration/release-notes/0.2.0.md +1 -1
- package/docs/migration/release-notes/0.3.0.md +1 -1
- package/docs/migration/release-notes/0.5.0.md +1 -1
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.7.3.md +2 -2
- package/docs/migration/release-notes/0.7.4.md +1 -1
- package/docs/migration/release-notes/0.7.5.md +1 -1
- package/docs/migration/release-notes/0.8.0.md +1 -1
- package/docs/migration/release-notes/0.9.0.md +1 -1
- package/docs/migration/release-notes/0.9.14.md +1 -1
- package/docs/migration/release-notes/0.9.15.md +1 -1
- package/docs/migration/release-notes/0.9.16.md +1 -1
- package/docs/migration/release-notes/0.9.17.md +1 -1
- package/docs/migration/release-notes/0.9.19.md +1 -1
- package/docs/migration/release-notes/0.9.2.md +1 -1
- package/docs/migration/release-notes/README.md +27 -31
- package/docs/migration/v0.5-to-v0.6.md +759 -0
- package/docs/migration/v0.8-to-v0.9.md +1 -1
- package/docs/plans/0.9.2-agent-command-workflow-plan.md +423 -0
- package/docs/posts/README.md +30 -0
- package/docs/posts/akm-command-tour.md +495 -0
- package/docs/posts/akm-logo-sized.webp +0 -0
- package/docs/posts/belief-aware-memory-12.md +139 -0
- package/docs/posts/config-v2-lessons-16.md +191 -0
- package/docs/posts/improve-loop-autonomous-10.md +225 -0
- package/docs/posts/improve-pipeline-debugging-0803.md +179 -0
- package/docs/posts/intro-part-01.md +76 -0
- package/docs/posts/intro-part-02.md +221 -0
- package/docs/posts/intro-part-03.md +190 -0
- package/docs/posts/intro-part-04.md +221 -0
- package/docs/posts/llm-mode-reflect-13.md +166 -0
- package/docs/posts/openpalm-built-on-akm.md +86 -0
- package/docs/posts/progressive-disclosure-06.md +129 -0
- package/docs/posts/proposal-safety-net-15.md +112 -0
- package/docs/posts/release-0.5.0.md +247 -0
- package/docs/posts/release-0.6.0.md +117 -0
- package/docs/posts/release-0.7.0.md +159 -0
- package/docs/posts/release-0.8.0.md +332 -0
- package/docs/posts/scattered-skills-05.md +100 -0
- package/docs/posts/task-assets-persistent-workflows-11.md +222 -0
- package/docs/posts/team-skills-07.md +198 -0
- package/docs/posts/wiki-agent-knowledge-08.md +223 -0
- package/docs/posts/workflows-vaults-09.md +321 -0
- package/docs/product-surface.md +54 -0
- package/docs/reference/README.md +1 -2
- package/docs/reference/asset-types.md +168 -0
- package/docs/reference/cli.md +5 -6
- package/docs/reference/data-and-telemetry.md +6 -0
- package/docs/reference/env-and-secrets.md +126 -0
- package/docs/reference/memory.md +124 -0
- package/docs/reference/refs.md +156 -0
- package/docs/reference/registry.md +489 -0
- package/docs/reference/website-sources.md +141 -0
- package/package.json +12 -15
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Architecture: The Workflow Engine
|
|
2
|
+
|
|
3
|
+
A workflow compiles to a frozen plan, persists run and unit state, dispatches
|
|
4
|
+
its work, verifies declared gates, and resumes without replaying completed
|
|
5
|
+
units. This page is the architecture-level reference for that engine — how a
|
|
6
|
+
run's plan is frozen and stored, how dispatch and resume actually work, how
|
|
7
|
+
one engine owns a run, and how isolated file-mutating units execute. For the
|
|
8
|
+
exact frontmatter/body syntax that produces the plan, see
|
|
9
|
+
[Workflow Schema](../reference/workflow-schema.md). For the day-to-day
|
|
10
|
+
commands that drive a run, see [Running Workflows](../guides/run-workflows.md).
|
|
11
|
+
|
|
12
|
+
> **`akm workflow run` is Stable, ungated, and the only execution surface.**
|
|
13
|
+
> It is the canonical start/resume/execute command; there is no separate
|
|
14
|
+
> external-driver protocol.
|
|
15
|
+
|
|
16
|
+
## Frozen plans
|
|
17
|
+
|
|
18
|
+
The first `akm workflow run <ref>` compiles either peer source format
|
|
19
|
+
(Markdown or GitHub-Actions-style YAML) straight to the one plan type and
|
|
20
|
+
stores it as durable plan **`irVersion` 6** on the run row (`plan_json` +
|
|
21
|
+
`plan_hash`); a new start never emits an older version. `plan_ir_version` and
|
|
22
|
+
`plan_hash` are recorded provenance, not gates: a stored plan is decoded as it
|
|
23
|
+
is — irVersion 4 and 5 plans included — and one frozen by an older or newer
|
|
24
|
+
akm that still decodes simply runs (with one warning). A newer akm's plan that
|
|
25
|
+
does not decode is refused with a message naming "Upgrade akm".
|
|
26
|
+
|
|
27
|
+
The durable plan records `sourceHash`, the sha256 of the workflow source file
|
|
28
|
+
at freeze. It is used only for the resume warning below, never to refuse a
|
|
29
|
+
run.
|
|
30
|
+
|
|
31
|
+
Dispatch-significant material is immutable. The resolved request is frozen,
|
|
32
|
+
the resolved target is frozen, and runner selection is frozen.
|
|
33
|
+
Working directory (`cwd`) identity is frozen.
|
|
34
|
+
Git identity and its commit OID are frozen. The executable a unit runs is
|
|
35
|
+
resolved at dispatch, so upgrading a CLI (say, `claude`) never strands a run.
|
|
36
|
+
Exact models, inference, tools and authorization,
|
|
37
|
+
execution limits, parameter snapshots, command/script bytes, and verifier
|
|
38
|
+
selection therefore cannot drift under an in-flight run.
|
|
39
|
+
|
|
40
|
+
Workflow environment asset values are the narrow live-value exception within
|
|
41
|
+
authored workflow inputs.
|
|
42
|
+
The environment owner key set and secret-token topology are frozen.
|
|
43
|
+
Literal values remain frozen. Pass-through bindings
|
|
44
|
+
materialize at dispatch from the current process, and env/secret references
|
|
45
|
+
materialize their current values only after owner/topology checks. Durable
|
|
46
|
+
plans never store secret values or enable whole-process `inheritEnv`.
|
|
47
|
+
|
|
48
|
+
**A run executes the plan compiled at creation; edits to source need a new
|
|
49
|
+
run.** Resuming a run re-reads its workflow source only to warn, once, when
|
|
50
|
+
the source changed since the freeze — the run continues on the frozen plan.
|
|
51
|
+
Orchestration decisions are pure functions of the frozen plan, run params,
|
|
52
|
+
and journaled results.
|
|
53
|
+
|
|
54
|
+
## Child workflows
|
|
55
|
+
|
|
56
|
+
A step that composes another workflow — directly (`uses: workflows/<ref>`)
|
|
57
|
+
or through a task whose own target is a workflow (`uses: tasks/<ref>`) —
|
|
58
|
+
freezes to a `child-workflow` frozen target. Unlike the `command`/`shell`/
|
|
59
|
+
`script` targets, a `child-workflow` target carries the child's **complete
|
|
60
|
+
frozen plan, embedded**: compiling the parent recursively compiles,
|
|
61
|
+
validates, and freezes each child in full — depth-first, all of it — before
|
|
62
|
+
the parent run is ever published. Nothing about a child is re-read at
|
|
63
|
+
dispatch time; the embedded plan is authoritative. See
|
|
64
|
+
[Workflow Schema: Child workflows](../reference/workflow-schema.md#child-workflows)
|
|
65
|
+
for the authoring-side view, including the three composition bounds (depth,
|
|
66
|
+
cycle, aggregate embedded bytes) enforced at freeze.
|
|
67
|
+
|
|
68
|
+
**Decoding.** An embedded child plan is decoded by the same structural
|
|
69
|
+
decoder as its parent, recursively. Its `planHash` and the target's
|
|
70
|
+
`contentHash` are recorded provenance, carried as data and never re-verified
|
|
71
|
+
against the bytes.
|
|
72
|
+
|
|
73
|
+
**The dispatch seam.** Dispatching a step whose target is
|
|
74
|
+
`kind: "child-workflow"` is the one branch point in
|
|
75
|
+
`dispatchJournaledAttempt` (`src/workflows/exec/native-executor.ts`) that
|
|
76
|
+
does not call the ordinary unit dispatcher: it calls
|
|
77
|
+
`driveChildWorkflowUnit` instead, with everything the composing unit already
|
|
78
|
+
resolved — the frozen target, the parent's dispatch context, the child's
|
|
79
|
+
resolved params, and the unit input hash. The branch sits **inside** the
|
|
80
|
+
existing retry loop, after the parent unit's attempt row is already claimed
|
|
81
|
+
`running` (so a crash between claiming that row and publishing the child
|
|
82
|
+
leaves a recoverable `running` parent unit and no orphaned child) and
|
|
83
|
+
**before** the ordinary post-dispatch journaling (redaction, attempt
|
|
84
|
+
finishing, the worktree epilogue), which runs unchanged either way — a
|
|
85
|
+
child-workflow unit is journaled exactly like any other.
|
|
86
|
+
|
|
87
|
+
**The drive contract.** `driveChildWorkflowUnit` validates and resolves the
|
|
88
|
+
child's params through the same input-binding
|
|
89
|
+
resolution every frozen target uses, computes the child's identity key from
|
|
90
|
+
`{parentRunId, parentUnitId, unitInputHash}`, and publishes the child run —
|
|
91
|
+
idempotently: the same three inputs always resolve to the same child row,
|
|
92
|
+
so a retried or resumed composing step re-drives the run it already started
|
|
93
|
+
rather than starting a new one, and only a change to the composing step's
|
|
94
|
+
own inputs (params, an upstream step output it reads, or gate feedback from
|
|
95
|
+
a rejected verification loop) produces a different child. A child found
|
|
96
|
+
already `blocked` or `failed` is not re-driven — driving happens once per
|
|
97
|
+
call, and a terminal-but-unhealthy child surfaces through the status mapping
|
|
98
|
+
below instead. The child's final status maps onto the composing unit, and
|
|
99
|
+
from there onto the parent step and run, exactly as described in [Workflow
|
|
100
|
+
Schema: Child execution](../reference/workflow-schema.md#child-execution).
|
|
101
|
+
|
|
102
|
+
**Why `runWorkflowSteps` is reused, not a second executor.** The child drive
|
|
103
|
+
calls the exact same exported entry point `akm workflow run` calls —
|
|
104
|
+
`runWorkflowSteps(options)`, pointed at the child's run id as `target` —
|
|
105
|
+
with no special-casing for "this target is a child": resolving a run id,
|
|
106
|
+
decoding the stored plan, taking that run's own lock, and walking its spine
|
|
107
|
+
through `completeWorkflowStep` are identical to the top-level path. That
|
|
108
|
+
reuse is what makes child run locks arbitrate two-parent contention with no
|
|
109
|
+
new mechanism, and what makes a resumed parent skip a completed child step
|
|
110
|
+
with zero dispatcher calls. The child drive passes a no-op
|
|
111
|
+
`disposeDispatchResources` (the parent's `finally` remains the sole owner of
|
|
112
|
+
the process-lifecycle drain for the whole process) and no `maxSteps` or
|
|
113
|
+
`maxRetries` (the parent's own budgets count only its own spine steps). The
|
|
114
|
+
lower-level `driveRun` that `runWorkflowSteps` wraps stays module-private —
|
|
115
|
+
reaching for it directly, instead of the public entry point, would be
|
|
116
|
+
exactly the second executor this design avoids.
|
|
117
|
+
|
|
118
|
+
**Why `hashVersion` is 7, and why child composition did not move it.** The
|
|
119
|
+
version prefix mixed into a unit's input hash is 7
|
|
120
|
+
(`src/workflows/exec/step-work.ts`); 0.9.2 bumped it — a single, durable
|
|
121
|
+
5 → 7 step, since every released tag on the line carries 5 — when
|
|
122
|
+
`taskInputs`, the resolved values of a composed task's reference-kind
|
|
123
|
+
`inputBindings`, joined the preimage (see [ADR
|
|
124
|
+
0002](decisions/0002-unit-reuse-and-input-hash-scope.md)). Child composition
|
|
125
|
+
itself contributed nothing to that bump: the parent unit's input-hash
|
|
126
|
+
preimage already covers everything the child drive depends on — the frozen
|
|
127
|
+
target carries the child's ref, plan hash, content hash, binding mode, and
|
|
128
|
+
its entire embedded plan, so any change anywhere in the child changes the
|
|
129
|
+
parent unit's own input hash transitively. The child run id (minted at
|
|
130
|
+
dispatch) and its exported result are unit *outputs*, not inputs, so neither
|
|
131
|
+
belongs in the preimage — adding either would be a hashing-boundary
|
|
132
|
+
violation, not a fix.
|
|
133
|
+
|
|
134
|
+
### Run outputs
|
|
135
|
+
|
|
136
|
+
A workflow may declare `outputs:` — a run-level export projected from its
|
|
137
|
+
steps' own artifacts once every step has finished (see [Workflow Schema:
|
|
138
|
+
Workflow outputs](../reference/workflow-schema.md#workflow-outputs) for the
|
|
139
|
+
authoring grammar). Resolution happens inside the same write transaction
|
|
140
|
+
that completes the run's final step, immediately after the run's terminal
|
|
141
|
+
status is derived: each declared output is resolved from the persisted step
|
|
142
|
+
evidence and, if declared, validated against its schema. If resolution or
|
|
143
|
+
validation fails for any entry, the **whole completion rolls back** — the
|
|
144
|
+
run stays `active`, its final step stays `pending`, and no completion event
|
|
145
|
+
is emitted — rather than leaving a run `completed` with missing or invalid
|
|
146
|
+
exports. A run with no `outputs:` declaration exports `{runId, status}`
|
|
147
|
+
instead, synthesized on read and never persisted. This exported result is
|
|
148
|
+
exactly what a parent composing this workflow as a child promotes as the
|
|
149
|
+
composing unit's own result on `completed` — the same value, read through
|
|
150
|
+
the same function, whether the caller is `akm workflow status` or a parent
|
|
151
|
+
unit's dispatch.
|
|
152
|
+
|
|
153
|
+
## Resume skips completed units
|
|
154
|
+
|
|
155
|
+
Resume never re-reads config or the asset index, and reads the workflow
|
|
156
|
+
source only for the drift warning above. It consumes the frozen plan plus
|
|
157
|
+
the journaled attempts and results. A stored plan that this akm cannot
|
|
158
|
+
decode is not an error to fix in place: `akm workflow run` marks such a run
|
|
159
|
+
abandoned (status `failed`) and says to start a new run with
|
|
160
|
+
`akm workflow run <ref>`; `akm workflow status`, `list`, and `abandon` never
|
|
161
|
+
read the plan at all. A plan frozen by a newer akm that this one cannot
|
|
162
|
+
decode is left untouched, and the message names upgrading akm.
|
|
163
|
+
|
|
164
|
+
Every dispatched unit is journaled under a content-derived identity — the
|
|
165
|
+
node id plus a hash of its item for a map unit (`<node>:solo` otherwise) —
|
|
166
|
+
together with an input hash over everything the unit was asked to do (its
|
|
167
|
+
frozen instructions and target, declared `inputs:` artifacts, the params
|
|
168
|
+
snapshot, gate feedback). On
|
|
169
|
+
re-run, a unit whose journal row is `completed` is **reused**, never
|
|
170
|
+
re-dispatched; a failed or missing unit is dispatched live. The recorded
|
|
171
|
+
input hash is informational: a completed unit stays completed even when the
|
|
172
|
+
params row or an upstream artifact changed since — a fresh run is what
|
|
173
|
+
recomputes it.
|
|
174
|
+
|
|
175
|
+
## Durable attempts and at-least-once dispatch
|
|
176
|
+
|
|
177
|
+
Workflow dispatch is at-least-once. Every unit has a stable content-derived
|
|
178
|
+
unit id and an append-only sequence of attempts.
|
|
179
|
+
A crash reclaim reuses the same stable dispatchId for the interrupted attempt.
|
|
180
|
+
An explicit retry gets a new dispatchId under one stable unit id and increments the attempt number.
|
|
181
|
+
|
|
182
|
+
One driver per run (below) keeps a second engine off a run, and a finished
|
|
183
|
+
attempt accepts no second terminal write, but neither can prove whether an
|
|
184
|
+
external process completed immediately before a crash. An ambiguous crash
|
|
185
|
+
outcome may re-run and can produce a duplicate side effect. Workflow actions
|
|
186
|
+
should be idempotent or use the stable dispatch identity as their own
|
|
187
|
+
deduplication key.
|
|
188
|
+
|
|
189
|
+
## One engine drives a run (the run lock)
|
|
190
|
+
|
|
191
|
+
`akm workflow run` takes the run's **lock file** before reading the plan or
|
|
192
|
+
dispatching anything: one `O_EXCL` file per run id under the data directory
|
|
193
|
+
(`workflow-run-locks/<run id>.lock`, next to `state.db`), recording the
|
|
194
|
+
holder's pid, released when the invocation exits. A second `workflow run`
|
|
195
|
+
against a run another live process holds refuses up front with
|
|
196
|
+
`RUN_LEASE_HELD` (exit 75), naming the holder pid. A lock whose holder pid is
|
|
197
|
+
dead is reclaimed at once, so a crashed engine never wedges a run; nothing
|
|
198
|
+
expires by age and nothing renews. `workflow status` and `list` never take
|
|
199
|
+
the lock.
|
|
200
|
+
|
|
201
|
+
## Worktree isolation
|
|
202
|
+
|
|
203
|
+
A file-mutating unit can declare `isolation: worktree` in its `unit:` bag
|
|
204
|
+
(agent and sdk runners) — see
|
|
205
|
+
[Workflow Schema: Frontmatter keys](../reference/workflow-schema.md#frontmatter-keys).
|
|
206
|
+
Each unit attempt gets a fresh **detached git worktree** of the run's base
|
|
207
|
+
repository under a run-scoped temp directory; the worktree path is journaled
|
|
208
|
+
on the unit row and passed to the harness as its working directory, so
|
|
209
|
+
parallel fan-out units can never trample each other's working tree. After the
|
|
210
|
+
unit finishes, a clean worktree (`git status --porcelain` empty) is removed
|
|
211
|
+
automatically; a dirty one is retained and its path logged, so uncollected
|
|
212
|
+
work is never destroyed. Declaring worktree isolation in a non-git directory
|
|
213
|
+
fails the step cleanly before anything dispatches.
|
|
214
|
+
|
|
215
|
+
> **Warning — outputs matched by `.gitignore` are treated as disposable.** A
|
|
216
|
+
> worktree-isolated unit's output survives only if it lands on a
|
|
217
|
+
> **collectible path**: a tracked file, or an untracked file your repository
|
|
218
|
+
> does **not** `.gitignore`. Anything a unit writes to a `.gitignore`d path —
|
|
219
|
+
> build outputs, caches, logs, dependency directories like
|
|
220
|
+
> `node_modules`/`dist`, or a scratch file under an ignored directory — is
|
|
221
|
+
> **discarded** when its clean worktree is auto-removed. If a unit produces an
|
|
222
|
+
> artifact that must survive, write it to a non-ignored path, or report it as
|
|
223
|
+
> a result (a structured `output` / free-text result), before the unit
|
|
224
|
+
> returns.
|
|
225
|
+
|
|
226
|
+
The clean probe deliberately does **not** pass `--ignored`, so "uncollected
|
|
227
|
+
work" means tracked or untracked-*unignored* changes only. A worktree whose
|
|
228
|
+
only residue is files your repository's own `.gitignore` matches is treated
|
|
229
|
+
as clean and removed: those files are disposable by the repo's own
|
|
230
|
+
declaration, and retaining a worktree after every package install or build
|
|
231
|
+
would blow up disk under the temp root.
|
|
232
|
+
|
|
233
|
+
## Concurrency limits
|
|
234
|
+
|
|
235
|
+
Native fan-out (`akm workflow run`) uses the minimum of four limits: the
|
|
236
|
+
map's declared `concurrency`, the run's frozen `workflow.maxConcurrency`, the
|
|
237
|
+
selected frozen LLM engine's `concurrency` (including an SDK engine's
|
|
238
|
+
fallback LLM), and the current host's CPU-derived safety limit. Reapplying
|
|
239
|
+
host safety keeps a run safe when it resumes on a smaller machine.
|
|
240
|
+
|
|
241
|
+
- **Unset (default):** the CPU-derived value `min(16, max(1, cores − 2))` — a
|
|
242
|
+
conservative default that leaves headroom on the host and matches the
|
|
243
|
+
original Claude-Code cap.
|
|
244
|
+
- **Set:** an explicit positive integer, clamped when frozen to `[1, 64]`
|
|
245
|
+
(values above 64 are clamped down, never rejected, so one config shared
|
|
246
|
+
across machines with different core counts never hard-fails).
|
|
247
|
+
|
|
248
|
+
```console
|
|
249
|
+
$ akm config set workflow.maxConcurrency 8 # raise the frozen workflow limit
|
|
250
|
+
$ akm config get workflow.maxConcurrency
|
|
251
|
+
8
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
A workflow that fans out is authorizing **N parallel agents**, not one — see
|
|
255
|
+
[Running Workflows: workflow sources are executed code](../guides/run-workflows.md#security-workflow-sources-are-executed-code)
|
|
256
|
+
for what that means for trust.
|
|
257
|
+
|
|
258
|
+
## Run scope and persistence
|
|
259
|
+
|
|
260
|
+
Run state (`plan_json`, `plan_hash`, step statuses, and the unit journal)
|
|
261
|
+
persists in the project's `state.db`; the per-run lock file sits beside it. Run state is scoped to
|
|
262
|
+
the current project directory — the nearest `.akm/config.json`, git root,
|
|
263
|
+
bundle root, or current directory — so the same workflow can run
|
|
264
|
+
independently in separate projects, and `akm workflow list`/`status` without
|
|
265
|
+
an explicit run id only ever see runs in that scope.
|
|
266
|
+
|
|
267
|
+
## See also
|
|
268
|
+
|
|
269
|
+
- [Workflow Schema](../reference/workflow-schema.md) — exact frontmatter,
|
|
270
|
+
refs, gates, and outputs syntax
|
|
271
|
+
- [Running Workflows](../guides/run-workflows.md) — start, inspect, resume,
|
|
272
|
+
and abandon a run
|
|
273
|
+
- [Author's Guide: Writing Workflows](../guides/author-workflows.md) — writing
|
|
274
|
+
and testing a workflow definition
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Guides
|
|
2
|
+
|
|
3
|
+
Task-oriented guides and command tours for using akm.
|
|
4
|
+
|
|
5
|
+
## Getting going
|
|
6
|
+
|
|
7
|
+
- [Getting Started](getting-started.md) -- Quick setup guide
|
|
8
|
+
- [Concepts](concepts.md) -- Bundles, adapters, asset types, and refs
|
|
9
|
+
|
|
10
|
+
## Command tours
|
|
11
|
+
|
|
12
|
+
- [Use AKM With Any Agent](use-with-any-agent.md) -- Wire akm into Claude Code, OpenCode, Cursor, and other coding assistants
|
|
13
|
+
- [Discover and Load](discover-and-load.md) -- Build the index, search, curate a shortlist, and load assets by ref
|
|
14
|
+
- [Bundles](bundles.md) -- Connect local dirs, git repos, npm packages, and websites; browse the registry
|
|
15
|
+
- [Capture Knowledge](capture-knowledge.md) -- Capture memories, import docs, and store protected env/secret assets
|
|
16
|
+
- [Improve the Library](improve-the-library.md) -- Feedback, history, proposals, and automated asset improvement
|
|
17
|
+
|
|
18
|
+
## Running workflows
|
|
19
|
+
|
|
20
|
+
- [Running Workflows](run-workflows.md) -- Start, continue, check on, resume, and abandon a workflow run
|
|
21
|
+
- [Author's Guide: Writing Workflows](author-workflows.md) -- Markdown structure, a minimal complete example, and common authoring mistakes
|
|
22
|
+
- [Scheduling](scheduling.md) -- Run `akm improve` and other background tasks through cron / launchd / schtasks safely
|
|
23
|
+
|
|
24
|
+
## Building and sharing
|
|
25
|
+
|
|
26
|
+
- [Bundle Author's Guide](author-bundles.md) -- Build and share a bundle on GitHub, npm, or a network directory
|
|
27
|
+
- [Wikis](wikis.md) -- Multi-wiki knowledge bases (Karpathy-style)
|
|
28
|
+
- [Claude Code workflows vs. akm workflows](claude-code-vs-akm-workflows.md) -- Comparing the two things that share a name
|
|
29
|
+
|
|
30
|
+
## Recipes
|
|
31
|
+
|
|
32
|
+
- [Turn a Website into a Searchable Bundle](recipes/website-source.md) -- Crawl a documentation site into markdown knowledge assets
|
|
33
|
+
- [Headless Install](recipes/headless-install.md) -- A precise, no-prompts install sequence for automated or agent-driven setup
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# Bundle Author's Guide
|
|
2
|
+
|
|
3
|
+
This guide walks through building a bundle, making it discoverable, and
|
|
4
|
+
sharing it so others can install it with `akm bundle add`. It assumes you
|
|
5
|
+
already know what a bundle is; see [Bundles](bundles.md) for the concept and
|
|
6
|
+
[Reference: Asset Types](../reference/asset-types.md) for the full catalog of
|
|
7
|
+
asset types, directory conventions, and per-type examples.
|
|
8
|
+
|
|
9
|
+
## Create a Bundle
|
|
10
|
+
|
|
11
|
+
A bundle is just a directory of assets. akm classifies each asset by **file
|
|
12
|
+
extension and content**, so directory names are hints, not requirements — a
|
|
13
|
+
`.sh` file is a script whether it lives in `scripts/`, `deploy/`, or the
|
|
14
|
+
bundle root, and nesting is fully supported.
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
mkdir my-bundle && cd my-bundle
|
|
18
|
+
mkdir scripts skills commands agents knowledge
|
|
19
|
+
# add your assets, then verify locally
|
|
20
|
+
akm bundle add .
|
|
21
|
+
akm index
|
|
22
|
+
akm search "deploy"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
For the preferred directory layout, the full set of supported asset types
|
|
26
|
+
(scripts, skills, commands, agents, knowledge, memories, workflows, tasks,
|
|
27
|
+
env files, and more), and worked examples of each, see
|
|
28
|
+
[Reference: Asset Types](../reference/asset-types.md).
|
|
29
|
+
|
|
30
|
+
Add a `.meta/` directory at the bundle root to orient readers to the bundle
|
|
31
|
+
*as a whole* — what it's for, where to start, conventions to follow. `.meta/`
|
|
32
|
+
is a dot-directory, so the indexer skips it: these docs never appear in
|
|
33
|
+
`akm search` and never compete for ranking. They're read directly with
|
|
34
|
+
`akm show meta[:<name>]` (or `akm show <bundle>//meta[:<name>]` once
|
|
35
|
+
installed). See [Reference: Asset Types](../reference/asset-types.md) for the
|
|
36
|
+
`.meta/` layout and an example `index.md`.
|
|
37
|
+
|
|
38
|
+
## Write Metadata for Discovery
|
|
39
|
+
|
|
40
|
+
Metadata is not documentation for humans skimming your repo — it is the
|
|
41
|
+
signal an agent's search ranking runs on. Write descriptions that describe
|
|
42
|
+
*what the asset does and when to reach for it*, not just what it's named.
|
|
43
|
+
|
|
44
|
+
Prefer metadata that travels with the asset itself, so it can't drift out of
|
|
45
|
+
sync with the code:
|
|
46
|
+
|
|
47
|
+
- Markdown assets: a `description` in frontmatter is extracted automatically
|
|
48
|
+
with high confidence.
|
|
49
|
+
- Scripts: header comments (`@param`, `@run`, `@setup`, `@cwd`) keep
|
|
50
|
+
execution metadata next to the code it describes.
|
|
51
|
+
- Everything else: filenames and a nearby `package.json` provide fallback
|
|
52
|
+
metadata when `akm index` runs.
|
|
53
|
+
|
|
54
|
+
If you still have a legacy `.stash.json` sidecar, migrate its fields into
|
|
55
|
+
inline metadata before publishing — see the
|
|
56
|
+
[v0.7 → v0.8 migration guide](../migration/v0.7-to-v0.8.md) for the full
|
|
57
|
+
field mapping and a worked example.
|
|
58
|
+
|
|
59
|
+
**Keep `show` payloads focused.** `akm show` returns the whole asset body by
|
|
60
|
+
default (the whole document for a knowledge asset, the whole `SKILL.md` for a
|
|
61
|
+
skill). An agent that calls `show` pays for every token you put in that
|
|
62
|
+
payload. Split long reference material into headed sections so agents can
|
|
63
|
+
request one slug at a time (`akm show knowledge/guide#rate-limits`) instead of
|
|
64
|
+
the entire document, and keep skills and commands scoped to one task rather
|
|
65
|
+
than a bundle of unrelated instructions.
|
|
66
|
+
|
|
67
|
+
**Separate reusable instructions from project-specific memory.** Skills,
|
|
68
|
+
commands, and agents should describe how to do something in a way that holds
|
|
69
|
+
up across projects. Anything that's true only for *this* project or *this*
|
|
70
|
+
run — a decision made in a retro, a fact about the current deployment, a
|
|
71
|
+
lesson learned from a failure — belongs in `memories/`, `facts/`, or
|
|
72
|
+
`lessons/`, not baked into a skill's instructions. Mixing the two makes the
|
|
73
|
+
reusable asset harder to reuse elsewhere and makes the project-specific
|
|
74
|
+
context harder to find and prune later.
|
|
75
|
+
|
|
76
|
+
**Give scripts and workflows explicit safety and parameter metadata.** AKM
|
|
77
|
+
retrieves every supported capability type, but it only orchestrates execution
|
|
78
|
+
surfaces it can reason about — scripts run through `@run`/`@setup`/`@cwd`
|
|
79
|
+
declarations, workflows through their declared steps. Undocumented
|
|
80
|
+
parameters or missing execution hints don't make an asset safer to skip; they
|
|
81
|
+
make it a worse citizen of that boundary, forcing an agent (or a human) to
|
|
82
|
+
guess what a script does before running it. Document every parameter with
|
|
83
|
+
`@param`, declare the interpreter and working directory explicitly, and
|
|
84
|
+
describe destructive or irreversible steps in the body text.
|
|
85
|
+
|
|
86
|
+
## Test Before You Publish
|
|
87
|
+
|
|
88
|
+
Before sharing, install your bundle locally and confirm the assets are both
|
|
89
|
+
present and *findable*:
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
# Install from the local directory
|
|
93
|
+
akm bundle add ./my-bundle
|
|
94
|
+
akm bundle list
|
|
95
|
+
|
|
96
|
+
# Exact-name lookups
|
|
97
|
+
akm show scripts/deploy.sh
|
|
98
|
+
|
|
99
|
+
# Realistic queries -- not just the asset's own name
|
|
100
|
+
akm search "ship a release"
|
|
101
|
+
akm curate "deploy the app to staging"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Testing only exact-name search hides ranking problems your users will hit
|
|
105
|
+
immediately: someone looking for "deploy" won't necessarily type `deploy.sh`.
|
|
106
|
+
Search with the phrasing you expect users (and agents) to actually use, and
|
|
107
|
+
with `akm curate` for task-shaped queries. If results are poor or your asset
|
|
108
|
+
doesn't surface, improve the description, tags, and search hints rather than
|
|
109
|
+
renaming the file to match the query.
|
|
110
|
+
|
|
111
|
+
Run `akm lint` before you publish. It catches structural problems (missing
|
|
112
|
+
`name`/`type` on commands and agents, broken refs, malformed workflow
|
|
113
|
+
structure, invalid task YAML) as well as the dangerous-env-key scan described
|
|
114
|
+
in [Env Security](#env-security) below.
|
|
115
|
+
|
|
116
|
+
```sh
|
|
117
|
+
akm lint
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Version Bundles and Document Compatibility
|
|
121
|
+
|
|
122
|
+
Use npm versions or GitHub releases so users can pin to a known-good state
|
|
123
|
+
instead of tracking your default branch:
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
akm bundle add npm:pkg@1.2.3
|
|
127
|
+
akm bundle add github:owner/repo#v1.2.3
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Note in your `README.md` which `akm-cli` version(s) your bundle targets,
|
|
131
|
+
especially if you rely on a feature that shipped recently (a new asset type,
|
|
132
|
+
a frontmatter field, a lint rule). Breaking changes to your own bundle's
|
|
133
|
+
layout deserve the same treatment you'd want from akm itself: a note in your
|
|
134
|
+
changelog and, if the change is large, a short migration note for anyone
|
|
135
|
+
pinned to the old layout.
|
|
136
|
+
|
|
137
|
+
## Design for Local Customization
|
|
138
|
+
|
|
139
|
+
Users are expected to fork individual assets out of your bundle rather than
|
|
140
|
+
edit your source tree directly. `akm clone` copies one asset (or, for a
|
|
141
|
+
skill, its whole directory) into the user's writable bundle or a custom
|
|
142
|
+
`--dest`, and the local copy wins in subsequent searches from that point
|
|
143
|
+
forward:
|
|
144
|
+
|
|
145
|
+
```sh
|
|
146
|
+
akm clone scripts/deploy.sh
|
|
147
|
+
akm clone scripts/deploy.sh --dest ./project/.claude
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Design assets so a clone-and-edit workflow actually works: keep parameters
|
|
151
|
+
and setup steps explicit rather than hard-coded, avoid assumptions about
|
|
152
|
+
paths outside the bundle, and prefer one asset per concern so a user can
|
|
153
|
+
clone the one thing they need to change without dragging in unrelated
|
|
154
|
+
behavior. See [`akm clone`](bundles.md#akm-clone) for the full command
|
|
155
|
+
reference.
|
|
156
|
+
|
|
157
|
+
## Publish Your Bundle
|
|
158
|
+
|
|
159
|
+
Detailed, provider-by-provider behavior for `akm bundle add` (git, npm,
|
|
160
|
+
filesystem, website) lives in [Bundles](bundles.md); the summaries below
|
|
161
|
+
cover only what changes when you're the one publishing.
|
|
162
|
+
|
|
163
|
+
### Sharing on GitHub
|
|
164
|
+
|
|
165
|
+
1. Push your bundle to a GitHub repository.
|
|
166
|
+
2. Add the `akm-stash` topic to your repo so it appears in registry search
|
|
167
|
+
(`gh repo edit --add-topic akm-stash`, or from repository settings under
|
|
168
|
+
"Topics").
|
|
169
|
+
3. Others can now install it: `akm bundle add github:your-username/my-bundle`.
|
|
170
|
+
4. To pin a version, tag a release and install with a `#ref`:
|
|
171
|
+
`akm bundle add github:your-username/my-bundle#v1.0.0`. Installs are
|
|
172
|
+
git-based — an unpinned add tracks the default branch, a `#ref` pins that
|
|
173
|
+
tag/branch/commit — and the latest-release tarball is used only as a
|
|
174
|
+
fallback when git access fails.
|
|
175
|
+
|
|
176
|
+
### Sharing on npm
|
|
177
|
+
|
|
178
|
+
1. Add a `package.json` with `"akm-stash"` in `keywords`.
|
|
179
|
+
2. If your repo contains files that shouldn't ship (source, tests, CI
|
|
180
|
+
config), use `akm.include` to declare which paths to publish:
|
|
181
|
+
|
|
182
|
+
```json
|
|
183
|
+
{
|
|
184
|
+
"name": "@your-scope/my-bundle",
|
|
185
|
+
"version": "1.0.0",
|
|
186
|
+
"keywords": ["akm-stash"],
|
|
187
|
+
"akm": { "include": ["scripts", "skills", "knowledge", ".meta"] }
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Paths are relative to `package.json`; only listed directories/files are
|
|
192
|
+
copied into the install cache, and `.git` is always excluded. Remember to
|
|
193
|
+
include `.meta` explicitly — dot-directories are otherwise easy to leave
|
|
194
|
+
out of a published tarball (a GitHub tarball install includes `.meta/`
|
|
195
|
+
automatically, without needing an allowlist).
|
|
196
|
+
|
|
197
|
+
3. `npm publish --access public`.
|
|
198
|
+
4. Others can now install it: `akm bundle add @your-scope/my-bundle`.
|
|
199
|
+
|
|
200
|
+
### Sharing on a Network Directory
|
|
201
|
+
|
|
202
|
+
For teams sharing assets without a registry, mount a bundle directly:
|
|
203
|
+
|
|
204
|
+
```sh
|
|
205
|
+
akm bundle add /mnt/shared/team-bundle
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Assets appear in search results immediately, no further install step needed.
|
|
209
|
+
See [Bundles](bundles.md) for adding a mounted source to
|
|
210
|
+
`~/.config/akm/config.json` directly, and for write-safety behavior when a
|
|
211
|
+
mounted or git bundle is marked `writable`.
|
|
212
|
+
|
|
213
|
+
### Submitting to the Registry
|
|
214
|
+
|
|
215
|
+
The official [akm-registry](https://github.com/itlackey/akm-registry) lists
|
|
216
|
+
your bundle three ways: an npm package with `akm-stash` in `keywords`, the
|
|
217
|
+
`akm-stash` GitHub topic on your repo, or a PR against `manual-entries.json`
|
|
218
|
+
for a curated entry or override. Auto-discovered entries merge into
|
|
219
|
+
`index.json` on the registry's build cycle; curated entries are reviewed
|
|
220
|
+
before inclusion. For the registry's entry schema and how auto-discovered
|
|
221
|
+
and curated entries are reconciled, see
|
|
222
|
+
[Reference: Registry](../reference/registry.md).
|
|
223
|
+
|
|
224
|
+
CLI-based submission (`akm` driving the PR) is planned for a future release.
|
|
225
|
+
|
|
226
|
+
## Write-Safety Expectations
|
|
227
|
+
|
|
228
|
+
Publishing a bundle does not make it writable by default. `akm bundle add`
|
|
229
|
+
installs git, npm, and website bundles read-only unless the source is
|
|
230
|
+
explicitly marked `writable` (filesystem sources are the exception — local
|
|
231
|
+
directories are writable by default, opt out with `writable: false`), and
|
|
232
|
+
only the primary bundle or a source resolved as writable accepts changes back (via `akm sync`, `akm clone --dest`, or
|
|
233
|
+
`akm remember --bundle`). If you're publishing a bundle you expect other
|
|
234
|
+
teams to write back into — not just install and read — say so in your
|
|
235
|
+
`README.md` and document the `writable: true` configuration your users need.
|
|
236
|
+
See [`akm sync`](bundles.md#akm-sync) for exactly what gets committed and
|
|
237
|
+
when a push happens.
|
|
238
|
+
|
|
239
|
+
## Env Security
|
|
240
|
+
|
|
241
|
+
> The `vault` asset type was removed in 0.9.0; `env` replaces it. See the
|
|
242
|
+
> [0.8 → 0.9 migration guide](../migration/v0.8-to-v0.9.md).
|
|
243
|
+
|
|
244
|
+
If your bundle includes env files under `env/`, be aware of how `akm` handles
|
|
245
|
+
them during install.
|
|
246
|
+
|
|
247
|
+
**Dangerous key detection.** `akm bundle add` and `akm lint` scan env files for
|
|
248
|
+
environment variable names that can be used to hijack process execution when
|
|
249
|
+
the file is loaded via `akm env run`. The flagged names include `LD_PRELOAD`,
|
|
250
|
+
`PATH`, `DYLD_INSERT_LIBRARIES`, `NODE_OPTIONS`, and 37 others (41 literal
|
|
251
|
+
keys total), plus two pattern-based families (`BASH_FUNC_*`, Shellshock-class
|
|
252
|
+
injection; `GIT_CONFIG_*`, git config override injection). When these keys
|
|
253
|
+
are found, `akm bundle add` pauses in interactive mode and asks the user to confirm
|
|
254
|
+
before continuing. In non-interactive (CI) mode the install fails unless the
|
|
255
|
+
user passes `--allow-dangerous-env-keys`. `akm env run` applies the same scan at
|
|
256
|
+
run time: a third-party-sourced bundle is refused unless that reviewed run
|
|
257
|
+
explicitly passes `--allow-dangerous-env-keys`; a first-party bundle warns and
|
|
258
|
+
proceeds.
|
|
259
|
+
|
|
260
|
+
This is not a ban — it is a speed bump. If your bundle legitimately needs one
|
|
261
|
+
of these keys (for example, a `PATH` override for a hermetic toolchain), do
|
|
262
|
+
the following before publishing:
|
|
263
|
+
|
|
264
|
+
1. Document the reason clearly in your `README.md`. Explain which key is set,
|
|
265
|
+
why it is needed, and what the value does.
|
|
266
|
+
2. Run `akm lint` against your bundle locally to see the `dangerous-env-key`
|
|
267
|
+
findings before your users do (suppress a specific key with a
|
|
268
|
+
`# akm-lint-ok: dangerous-env-key` comment on the preceding line):
|
|
269
|
+
|
|
270
|
+
```sh
|
|
271
|
+
akm lint
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
3. Consider whether the value can be set by the user after install rather than
|
|
275
|
+
shipped in the env file. Env files that ship without values — just key names
|
|
276
|
+
and comments — do not trigger the audit.
|
|
277
|
+
|
|
278
|
+
**Key names are metadata, not secrets.** Env key names appear in `akm env list`
|
|
279
|
+
and search results by design. Only values are protected. The `--sensitive` flag
|
|
280
|
+
on `akm env create` excludes a file from both `env list` output and the search
|
|
281
|
+
index; its key names then surface only when the file is shown directly by ref.
|
|
282
|
+
|
|
283
|
+
## Bundle Structure Tips
|
|
284
|
+
|
|
285
|
+
- **Keep it focused.** A bundle with 5 great scripts is more useful than one
|
|
286
|
+
with 50 mediocre ones.
|
|
287
|
+
|
|
288
|
+
- **Write good descriptions.** The `description` field (preferably in
|
|
289
|
+
frontmatter, otherwise in script comments or `package.json`) is the primary
|
|
290
|
+
signal for search ranking.
|
|
291
|
+
|
|
292
|
+
- **Use frontmatter in markdown assets.** A `description` in frontmatter is
|
|
293
|
+
extracted automatically with high confidence (0.9), making your commands,
|
|
294
|
+
agents, and knowledge documents more discoverable.
|
|
295
|
+
|
|
296
|
+
- **Use structured header comments for scripts.** `.sh`, `.ts`, `.py`, etc. get
|
|
297
|
+
strong results from good filenames plus leading comments and tags like
|
|
298
|
+
`@param`, `@run`, `@setup`, and `@cwd`.
|
|
299
|
+
|
|
300
|
+
- **Test the search experience.** After installing your bundle, search for it
|
|
301
|
+
using the terms you expect users to try, not just the asset's own name. If
|
|
302
|
+
results are poor, improve the descriptions, tags, and search hints.
|
|
303
|
+
|
|
304
|
+
- **Document usage in the asset itself.** For skills, put the instructions in
|
|
305
|
+
`SKILL.md`. For commands, put the workflow in the markdown body. The agent
|
|
306
|
+
reads these directly.
|
|
307
|
+
|
|
308
|
+
- **Version your bundle.** Use npm versions or GitHub releases so users can pin
|
|
309
|
+
to a known-good state with `akm bundle add npm:pkg@1.2.3` or
|
|
310
|
+
`akm bundle add github:owner/repo#v1.2.3`.
|