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.
Files changed (165) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +10 -10
  3. package/ROADMAP.md +112 -0
  4. package/dist/commands/feedback-cli.js +21 -13
  5. package/dist/commands/improve/improve-cli.js +33 -12
  6. package/dist/core/errors.js +1 -0
  7. package/dist/core/file-lock.js +10 -1
  8. package/dist/indexer/usage/usage-events.js +6 -2
  9. package/dist/llm/client.js +33 -3
  10. package/dist/scripts/akm-migrate-node.js +6 -1
  11. package/dist/scripts/akm-migrate.js +6 -1
  12. package/docs/README.md +42 -41
  13. package/docs/agents/README.md +15 -0
  14. package/docs/agents/agent-install.md +14 -0
  15. package/docs/architecture/README.md +67 -0
  16. package/docs/architecture/adapters.md +272 -0
  17. package/docs/architecture/akm-architecture-decision-history.md +2055 -0
  18. package/docs/architecture/akm-core-principles.md +126 -0
  19. package/docs/architecture/architecture.md +579 -0
  20. package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +550 -0
  21. package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +72 -0
  22. package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +142 -0
  23. package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +189 -0
  24. package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +97 -0
  25. package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +108 -0
  26. package/docs/architecture/decisions/0006-task-source-version-routing.md +124 -0
  27. package/docs/architecture/decisions/0007-workflow-composition-bounds.md +83 -0
  28. package/docs/architecture/decisions/0008-task-binding-normalization.md +88 -0
  29. package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +80 -0
  30. package/docs/architecture/decisions/0010-driver-protocol-cut.md +36 -0
  31. package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +125 -0
  32. package/docs/architecture/decisions/README.md +62 -0
  33. package/docs/architecture/improvement.md +440 -0
  34. package/docs/architecture/internals/classification.md +154 -0
  35. package/docs/architecture/internals/fresh-host-rebuild-runbook.md +40 -0
  36. package/docs/architecture/internals/functional-contract-patterns.md +340 -0
  37. package/docs/architecture/internals/health-advisories.md +110 -0
  38. package/docs/architecture/internals/improve-workflow.md +713 -0
  39. package/docs/architecture/internals/indexing.md +498 -0
  40. package/docs/architecture/internals/registry-network-boundary.md +57 -0
  41. package/docs/architecture/internals/search.md +249 -0
  42. package/docs/architecture/internals/storage-locations.md +943 -0
  43. package/docs/architecture/persisted-data-compat.md +59 -0
  44. package/docs/architecture/reviews/env-secret-access.md +319 -0
  45. package/docs/architecture/runtime-boundary-design.md +153 -0
  46. package/docs/architecture/specs/0.9.0-close-out-plan.md +361 -0
  47. package/docs/architecture/specs/0.9.0-decisions.md +528 -0
  48. package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +745 -0
  49. package/docs/architecture/specs/0.9.0-open-items-register.md +135 -0
  50. package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +740 -0
  51. package/docs/architecture/specs/0.9.0-release-surface-review.md +636 -0
  52. package/docs/architecture/specs/agent-command-engine-model-design.md +513 -0
  53. package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +501 -0
  54. package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +291 -0
  55. package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +2059 -0
  56. package/docs/architecture/specs/di-seams-plan.md +539 -0
  57. package/docs/architecture/specs/driver-protocol-keep-or-cut.md +275 -0
  58. package/docs/architecture/specs/fact-asset-type.md +142 -0
  59. package/docs/architecture/specs/improve-collapse-churn-detector-design.md +634 -0
  60. package/docs/architecture/specs/okf-support.md +148 -0
  61. package/docs/architecture/specs/ref.md +329 -0
  62. package/docs/architecture/specs/reviews/task-workflow-unification/README.md +72 -0
  63. package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +152 -0
  64. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +352 -0
  65. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +300 -0
  66. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +402 -0
  67. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +758 -0
  68. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +645 -0
  69. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +602 -0
  70. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +27 -0
  71. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +27 -0
  72. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +74 -0
  73. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +15 -0
  74. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +132 -0
  75. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +147 -0
  76. package/docs/architecture/specs/stash-conventions-code-spec.md +275 -0
  77. package/docs/architecture/specs/stash-organization-conventions.md +377 -0
  78. package/docs/architecture/specs/task-workflow-format-unification.md +721 -0
  79. package/docs/architecture/specs/workflow-engine-buy-vs-build.md +231 -0
  80. package/docs/architecture/specs/workflow-format-unification.md +437 -0
  81. package/docs/architecture/testing/manual-testing-checklist.md +3420 -0
  82. package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +924 -0
  83. package/docs/architecture/testing/task-workflow-manual-tests.md +1817 -0
  84. package/docs/architecture/testing/testing-workflow.md +446 -0
  85. package/docs/architecture/workflow-engine.md +274 -0
  86. package/docs/guides/README.md +33 -0
  87. package/docs/guides/author-bundles.md +310 -0
  88. package/docs/guides/author-workflows.md +520 -0
  89. package/docs/guides/bundles.md +321 -0
  90. package/docs/guides/capture-knowledge.md +136 -0
  91. package/docs/guides/claude-code-vs-akm-workflows.md +30 -0
  92. package/docs/guides/concepts.md +93 -0
  93. package/docs/guides/discover-and-load.md +158 -0
  94. package/docs/guides/getting-started.md +240 -0
  95. package/docs/guides/improve-the-library.md +246 -0
  96. package/docs/guides/knowledge-management.md +18 -0
  97. package/docs/guides/recipes/headless-install.md +97 -0
  98. package/docs/guides/recipes/website-source.md +28 -0
  99. package/docs/guides/run-workflows.md +279 -0
  100. package/docs/guides/scheduling.md +123 -0
  101. package/docs/guides/use-with-any-agent.md +129 -0
  102. package/docs/guides/wikis.md +81 -0
  103. package/docs/maintainers/README.md +19 -0
  104. package/docs/maintainers/curate-workmap.md +336 -0
  105. package/docs/maintainers/eval.md +3 -0
  106. package/docs/maintainers/local-development.md +108 -0
  107. package/docs/maintainers/release-checklist.md +103 -0
  108. package/docs/migration/README.md +2 -2
  109. package/docs/migration/release-notes/0.0.13.md +1 -1
  110. package/docs/migration/release-notes/0.1.0.md +1 -1
  111. package/docs/migration/release-notes/0.2.0.md +1 -1
  112. package/docs/migration/release-notes/0.3.0.md +1 -1
  113. package/docs/migration/release-notes/0.5.0.md +1 -1
  114. package/docs/migration/release-notes/0.6.0.md +1 -1
  115. package/docs/migration/release-notes/0.7.0.md +1 -1
  116. package/docs/migration/release-notes/0.7.3.md +2 -2
  117. package/docs/migration/release-notes/0.7.4.md +1 -1
  118. package/docs/migration/release-notes/0.7.5.md +1 -1
  119. package/docs/migration/release-notes/0.8.0.md +1 -1
  120. package/docs/migration/release-notes/0.9.0.md +1 -1
  121. package/docs/migration/release-notes/0.9.14.md +1 -1
  122. package/docs/migration/release-notes/0.9.15.md +1 -1
  123. package/docs/migration/release-notes/0.9.16.md +1 -1
  124. package/docs/migration/release-notes/0.9.17.md +1 -1
  125. package/docs/migration/release-notes/0.9.19.md +1 -1
  126. package/docs/migration/release-notes/0.9.2.md +1 -1
  127. package/docs/migration/release-notes/README.md +27 -31
  128. package/docs/migration/v0.5-to-v0.6.md +759 -0
  129. package/docs/migration/v0.8-to-v0.9.md +1 -1
  130. package/docs/plans/0.9.2-agent-command-workflow-plan.md +423 -0
  131. package/docs/posts/README.md +30 -0
  132. package/docs/posts/akm-command-tour.md +495 -0
  133. package/docs/posts/akm-logo-sized.webp +0 -0
  134. package/docs/posts/belief-aware-memory-12.md +139 -0
  135. package/docs/posts/config-v2-lessons-16.md +191 -0
  136. package/docs/posts/improve-loop-autonomous-10.md +225 -0
  137. package/docs/posts/improve-pipeline-debugging-0803.md +179 -0
  138. package/docs/posts/intro-part-01.md +76 -0
  139. package/docs/posts/intro-part-02.md +221 -0
  140. package/docs/posts/intro-part-03.md +190 -0
  141. package/docs/posts/intro-part-04.md +221 -0
  142. package/docs/posts/llm-mode-reflect-13.md +166 -0
  143. package/docs/posts/openpalm-built-on-akm.md +86 -0
  144. package/docs/posts/progressive-disclosure-06.md +129 -0
  145. package/docs/posts/proposal-safety-net-15.md +112 -0
  146. package/docs/posts/release-0.5.0.md +247 -0
  147. package/docs/posts/release-0.6.0.md +117 -0
  148. package/docs/posts/release-0.7.0.md +159 -0
  149. package/docs/posts/release-0.8.0.md +332 -0
  150. package/docs/posts/scattered-skills-05.md +100 -0
  151. package/docs/posts/task-assets-persistent-workflows-11.md +222 -0
  152. package/docs/posts/team-skills-07.md +198 -0
  153. package/docs/posts/wiki-agent-knowledge-08.md +223 -0
  154. package/docs/posts/workflows-vaults-09.md +321 -0
  155. package/docs/product-surface.md +54 -0
  156. package/docs/reference/README.md +1 -2
  157. package/docs/reference/asset-types.md +168 -0
  158. package/docs/reference/cli.md +5 -6
  159. package/docs/reference/data-and-telemetry.md +6 -0
  160. package/docs/reference/env-and-secrets.md +126 -0
  161. package/docs/reference/memory.md +124 -0
  162. package/docs/reference/refs.md +156 -0
  163. package/docs/reference/registry.md +489 -0
  164. package/docs/reference/website-sources.md +141 -0
  165. package/package.json +12 -15
@@ -0,0 +1,275 @@
1
+ # The External Driver Protocol: Keep, Cut, or Cheapen
2
+
3
+ Status: RESOLVED (2026-08-27) — Option B, cut. Executed ahead of this
4
+ record by the 0.9.2 reconstruction. See §10 for the decision and its
5
+ verification evidence.
6
+ Date: 2026-08-02
7
+ Baseline: `origin/main` @ `17a0dca`
8
+ Subject: `akm workflow brief` / `akm workflow report` (+ `report --settle`)
9
+ Related: [`workflow-engine-buy-vs-build.md`](./workflow-engine-buy-vs-build.md)
10
+ (which flagged this surface as the subsystem's largest removable block),
11
+ [`task-workflow-format-unification.md`](./task-workflow-format-unification.md)
12
+
13
+ ---
14
+
15
+ ## 1. The question
16
+
17
+ The driver protocol is 2,690 LOC of source — **31% of the workflow
18
+ engine** — plus a test surface of comparable size. It is Experimental,
19
+ opt-in behind `experimental.workflowEngine`, and has exactly three
20
+ non-test callers (all CLI handlers in `src/commands/workflow-cli.ts`). It
21
+ is a leaf.
22
+
23
+ Is the capability worth its cost, now that `akm workflow run` is the
24
+ canonical, Stable, ungated orchestrator?
25
+
26
+ ## 2. What it actually is
27
+
28
+ `brief` (713 LOC) is **read-only**: resolve a run, project the active
29
+ step's work-list, emit JSON. Most of its length is the published contract
30
+ — seven exported interfaces external harnesses code against.
31
+
32
+ `report` (1,977 LOC) is the **mutating** half, and the weight is not
33
+ duplicated engine logic. Its header states a "no duplicated semantics
34
+ (the cardinal rule)" and it imports 19 shared functions from
35
+ `step-work.ts` — the same `computeStepWorkList`, `reduceStepOutcomes`,
36
+ `finalizeExecutedStep` the native executor calls. `driver-parity.test.ts`
37
+ asserts the R4 contract: an engine-driven run and a driver-driven run of
38
+ the same frozen plan produce **byte-identical unit graphs**.
39
+
40
+ The lines are the cost of exposing the engine's step transitions to an
41
+ external actor safely:
42
+
43
+ | Concern | ~LOC |
44
+ |---|---|
45
+ | Transactional phases (load → resolve → write → finalize) | ~605 |
46
+ | Step finalization (reducers, gates, spine advance) | ~491 |
47
+ | Claim + hash-divergence guards | ~212 |
48
+ | Helpers incl. returned-text redaction | ~216 |
49
+ | The `settle` verb (route-only/empty steps) | ~168 |
50
+ | Published contract interfaces | ~106 |
51
+
52
+ It must assume a hostile or buggy caller, tolerate two drivers racing
53
+ plus a possibly-live engine lease, treat a re-report with a matching hash
54
+ as idempotent and a differing hash as replay divergence, enforce budgets,
55
+ and redact text the driver hands back. The engine skips nearly all of
56
+ this because it trusts its own call stack.
57
+
58
+ **This is a fixed floor, not bloat.** Slimming it is not the lever;
59
+ scoping it is.
60
+
61
+ ## 3. Two corrections to the case for keeping
62
+
63
+ Both were assumptions I had asserted and have since verified false or
64
+ overstated. They materially narrow the keep-argument, so they lead.
65
+
66
+ **(a) "Harness coverage collapses" — largely false.** Native dispatch is
67
+ not limited to claude/opencode. `HARNESS_ID_TABLE`
68
+ (`src/integrations/harnesses/ids.ts:34-45`) lists **ten** harnesses, all
69
+ `agentDispatch: true`: opencode, claude, opencode-sdk, codex, copilot,
70
+ pi, gemini, aider, amazonq, openhands.
71
+
72
+ **(b) The protocol's own documented users are, with one exception,
73
+ natively dispatchable.** `docs/reference/workflows.md:418` names them:
74
+ *"any agent session — Claude Code, opencode, Codex, or a human at a
75
+ shell."* Three of those four are in the table above.
76
+
77
+ ## 4. What genuinely survives as unique value
78
+
79
+ Not harness neutrality — **in-session execution**. `run` with
80
+ `defaults.engine: claude` spawns a fresh `claude -p` subprocess. The
81
+ driver protocol lets the session you are *already in* do the work. Even
82
+ for a natively-dispatchable harness these differ:
83
+
84
+ - **Tooling.** A spawned subprocess does not inherit the calling
85
+ session's MCP servers or loaded tools. Work requiring them can only run
86
+ in-session.
87
+ - **Engine-free operation.** `run` hard-fails without a configured engine
88
+ (`freeze.ts:54`, `INVALID_CONFIG_FILE`, exit 78). In a bare container
89
+ or CI image where the operator *is* an agent but no agent CLI is
90
+ configured, the driver protocol works and `run` does not.
91
+ - **Harnesses outside the ten** — Cursor, Zed, Windsurf — and a human at
92
+ a shell.
93
+
94
+ Counter-consideration, stated fairly: fresh context per unit is often a
95
+ *feature* (the subagent argument), so "nested agent" is not by itself a
96
+ cost.
97
+
98
+ ## 5. The cost of keeping
99
+
100
+ - **~2,690 LOC of the highest-risk code in the subsystem.** Untrusted
101
+ mutation, claim races, lease contention, crash-mid-finalize.
102
+ - **It constrains engine evolution.** `report` is built on the
103
+ `WorkflowRunUnitRow` shape via `withWorkflowRunsRepo` (no raw SQL — the
104
+ coupling is through the repository layer, which is the good case, but
105
+ it is still a second consumer). The R4 parity contract additionally
106
+ requires `step-work.ts` to stay provably identical across two callers.
107
+ The companion spec's IR v4 / hashVersion 5 work must keep both working.
108
+ - **A whole stability tier**: the `experimental.workflowEngine` gate, its
109
+ refusal envelopes, `task doctor` reporting, and doc surface across five
110
+ files.
111
+
112
+ ## 6. The cost of cutting — measured, not estimated
113
+
114
+ **Fully deletable test files (4,013 LOC):** `brief.test.ts` (850),
115
+ `report.test.ts` (1,844), `conformance/driver-parity.test.ts` (1,319).
116
+
117
+ **Not deletable — rewrite required.** Five suites use the protocol as a
118
+ *test harness* for unrelated invariants and would need porting to `run`:
119
+
120
+ | Suite | LOC | Protocol call-sites |
121
+ |---|---|---|
122
+ | `chaos.test.ts` | 1,175 | 11 |
123
+ | `step-work.test.ts` | 1,127 | 4 |
124
+ | `run-lease.test.ts` | 841 | 5 |
125
+ | `frozen-plan.test.ts` | 342 | 5 |
126
+ | `params-validation.test.ts` | 159 | 5 |
127
+
128
+ That is ~3,644 LOC of coverage that must be **preserved through a
129
+ rewrite**, not deleted — and `chaos.test.ts` in particular uses `report`
130
+ to inject precisely the interleavings that make crash-safety testable
131
+ from outside the engine. Losing the ability to drive a run step-by-step
132
+ from a test is a real, under-appreciated cost of cutting.
133
+
134
+ **Documentation.** `docs/guides/claude-code-vs-akm-workflows.md:288`
135
+ calls the protocol *"the sharpest point of contact between the two
136
+ systems in this whole comparison."* Cutting means rewriting a
137
+ positioning guide, not just deleting code.
138
+
139
+ **It is the last external-driving mechanism.** `start`/`next`/`complete`
140
+ — the cheap manual-stepping loop that served the same need — were removed
141
+ when `run` became canonical. This is not "cut the expensive one, keep the
142
+ cheap one." Cut it and native dispatch is the only execution model,
143
+ permanently.
144
+
145
+ ## 7. The three options
146
+
147
+ ### Option A — Keep as-is
148
+ Accept ~2,690 LOC and the R4 constraint as the price of in-session
149
+ execution and test-harness driving. Reasonable if akm intends execution
150
+ neutrality as a product property.
151
+ *Cost:* the engine's hardest surface stays, and every IR change carries a
152
+ second consumer.
153
+
154
+ ### Option B — Cut both verbs
155
+ Delete `brief`, `report`, `--settle`, the experimental gate, and 4,013
156
+ LOC of tests; port ~3,644 LOC of chaos/lease/frozen-plan coverage to
157
+ `run`; rewrite the positioning guide; accept that only the ten
158
+ natively-dispatchable harnesses can execute workflows and that a
159
+ configured engine becomes mandatory.
160
+ *Gain:* the largest single simplification available to the subsystem —
161
+ ~4× more code than the best third-party adoption would have removed, with
162
+ no new dependency.
163
+ *Risk:* irreversible in practice, and it forecloses in-session execution.
164
+
165
+ ### Option C — Cheapen: single-driver mode *(recommended for evaluation)*
166
+ Keep the capability, shed the concurrency machinery it no longer needs.
167
+
168
+ When the protocol was designed, `start`/`next`/`complete` still existed
169
+ and multiple actors could touch a run. Today the **run lease already
170
+ arbitrates exclusivity** — `run` takes it, and `report` already refuses
171
+ while a live engine lease is held. If the protocol declares
172
+ *one driver at a time, enforced by a driver lease*, then per-unit claim
173
+ ownership, contention resolution, and the contended-finalize paths become
174
+ redundant with a guard already in place.
175
+
176
+ What must stay regardless: **hash-divergence detection** (the replay
177
+ contract), budget enforcement, redaction of returned text, and the shared
178
+ `step-work.ts` semantics that make R4 hold.
179
+
180
+ What plausibly goes: `assertClaimHeldByOrFree`, the contended-finalize
181
+ result paths, and parts of the barrier decomposition — the ~212-LOC guard
182
+ block plus a share of the phase machinery. **I am not putting a number on
183
+ the saving without a design pass**; the honest claim is that the
184
+ machinery targeted was built for a concurrency model the current
185
+ architecture no longer permits.
186
+
187
+ *Gain:* keeps in-session execution and the chaos-test harness; removes
188
+ the hardest correctness surface.
189
+ *Cost:* one design pass; concurrent drivers become an explicit refusal
190
+ rather than a resolved race.
191
+
192
+ ## 8. Recommendation
193
+
194
+ **Evaluate C first, decide between A and B only if C fails.** The
195
+ strongest argument for cutting was never code size — it was that the
196
+ protocol carries concurrency machinery for a world that no longer exists.
197
+ If C confirms that, akm keeps a genuine capability at a fraction of the
198
+ maintenance cost, and the R4 constraint is the only thing left to weigh.
199
+
200
+ If C does not hold up, the tiebreaker is a product question rather than
201
+ an engineering one: **is executing akm workflows from inside an arbitrary
202
+ agent session a property akm wants to guarantee?**
203
+
204
+ - **Yes → A.** Then stop treating ~2,690 LOC as a liability; it is close
205
+ to the floor for a safe mutating protocol, and §2 shows the weight is
206
+ structural.
207
+ - **No → B.** Native dispatch covers ten harnesses; take the largest
208
+ simplification available and budget the test-port work honestly.
209
+
210
+ What should *not* happen is the status quo by default: an Experimental,
211
+ opt-in surface holding 31% of the engine and a parity constraint on every
212
+ future IR change, with no decision recorded either way.
213
+
214
+ ## 9. Sequencing note
215
+
216
+ If B is chosen, it should land **before** the task/workflow unification
217
+ work, not after. That change is already an IR v4 + hashVersion 5 + schema
218
+ migration; doing it with one consumer of `workflow_run_units` and no R4
219
+ parity obligation is materially cheaper than doing it with two. If A or C
220
+ is chosen, the unification spec's existing accounting already covers the
221
+ second consumer and needs no revision.
222
+
223
+ This condition is satisfied: B landed before the task/workflow unification
224
+ work. `workflow_run_units` had exactly one consumer (the native executor)
225
+ throughout P1–P3, and P3a's `irVersion` 5 + `hashVersion` 6 bump (the
226
+ "schema migration" this note anticipated) was done against that
227
+ single-consumer reality — there was never a second R4 parity obligation to
228
+ carry through it.
229
+
230
+ ## 10. Decision and evidence (2026-08-27)
231
+
232
+ **Decision: Option B — cut both verbs.** `brief`, `report`, `--settle`, and
233
+ the `experimental.workflowEngine` gate are gone. This was not reached by
234
+ this document's own §8 process (evaluate C, fall back to A/B) — the 0.9.2
235
+ task/workflow reconstruction deleted the subject before this record was
236
+ ever flipped from PROPOSAL. §9's sequencing note turned out to hold
237
+ anyway, by construction rather than by decision: the reconstruction was
238
+ never built with a driver-protocol consumer in the first place, so there
239
+ was nothing to sequence around. This record is therefore ratified **after
240
+ the fact** — ticking a box the code had already made true — not evaluated
241
+ in the forward-looking sense §7/§8 describe. A future reader should not
242
+ infer that Option C was tried and found wanting; it was never evaluated,
243
+ because the code was gone before the question was revisited.
244
+
245
+ **Verification.** All three greps return zero results against the current
246
+ tree, confirming no trace of the protocol, its experimental gate, or its
247
+ CLI verbs survives:
248
+
249
+ ```
250
+ $ rg -n 'brief\.ts|report\.ts' src/workflows/exec/
251
+ (no output)
252
+
253
+ $ rg -n 'experimental\.workflowEngine|workflowEngine' src/
254
+ (no output)
255
+
256
+ $ rg -n 'workflow (brief|report)|--settle' src/commands/
257
+ (no output)
258
+ ```
259
+
260
+ **Cross-references.**
261
+
262
+ - [`workflow-engine-buy-vs-build.md`](./workflow-engine-buy-vs-build.md) §7
263
+ (Recommendation) — the build verdict this decision completes. That
264
+ document recommended building AKM's own native engine rather than
265
+ adopting a third-party one; this record settles the one piece of the
266
+ native engine's own surface (the external driver protocol) that was
267
+ still an open question at PROPOSAL status.
268
+ - `docs/plans/0.9.2-architecture-deletion-audit.md`'s "Deleted
269
+ architecture" table carries the corresponding row: *External driver
270
+ protocol (`workflow brief` / `workflow report` / `--settle`) — Removed;
271
+ decision record RESOLVED (Option B).*
272
+
273
+ **§9's sequencing condition:** satisfied, as recorded in §9 above — B
274
+ landed before the task/workflow unification work, so `workflow_run_units`
275
+ had one consumer throughout P3a's `irVersion` 5 + `hashVersion` 6 bump.
@@ -0,0 +1,142 @@
1
+ # Design: the `fact` asset type — durable bundle-level knowledge
2
+
3
+ Status: accepted (phase 1 implemented)
4
+ Author: akm
5
+ Date: 2026-06-20
6
+
7
+ ## Problem
8
+
9
+ akm has no home for **durable, mostly-static facts about a user, team, or
10
+ project**. Concretely, users want a bundle to carry things like:
11
+
12
+ - **Personal** — name, email, address, timezone, favorite blogs, writing/working style.
13
+ - **Team** — tool stacks, primary languages, CI/CD platform, deployment targets, web addresses.
14
+ - **Conventions / constitution** — coding conventions, architecture principles, lint rules.
15
+ - **Bundle meta** — folder organization, naming conventions, expected frontmatter, the active-projects list.
16
+
17
+ Today these have nowhere first-class to live:
18
+
19
+ - `memory` is **episodic** — recency-decayed, belief-state ranked, captured ad-hoc via `akm remember`. It models "what I observed in a session," not "what is durably true about this bundle."
20
+ - `knowledge` is curated **reference material** — documents an agent reads on demand, not bundle-level identity/conventions injected as context.
21
+ - `lesson` is a **`when_to_use` trigger** distilled from feedback.
22
+ - The `.meta/` convention (`src/core/asset/stash-meta.ts`, see also `docs/guides/concepts.md`) is **documentary only**: not indexed, not searchable, not ranked, and not surfaced to agents automatically.
23
+
24
+ ## Conceptual grounding
25
+
26
+ The agent-memory literature splits long-term memory three ways (CoALA,
27
+ *Cognitive Architectures for Language Agents*, arXiv:2309.02427; echoed by
28
+ LangMem and Letta/MemGPT). akm already covers two of the three:
29
+
30
+ | Memory class | "answers" | akm |
31
+ | --- | --- | --- |
32
+ | **Episodic** — timestamped events | "what happened" | `session` (#561) |
33
+ | **Procedural** — executable how-to | "how to do X" | `skill`, `command`, `workflow` |
34
+ | **Semantic** — durable facts/identity | "what is true" | **`fact` (this doc)** |
35
+
36
+ Karpathy's operating-system analogy frames the design: model weights are the
37
+ CPU/ROM (can't retrain), the context window is scarce RAM, and everything else
38
+ is disk that must be *paged in*. A fact is **disk-resident knowledge selectively
39
+ loaded into RAM** — neither baked into weights nor permanently pinned in the
40
+ system prompt. Anthropic's *Effective context engineering for AI agents*
41
+ reinforces this: curate aggressively, prefer just-in-time retrieval, and pin
42
+ only a small high-signal core (cf. CLAUDE.md, kept short).
43
+
44
+ ## Design
45
+
46
+ ### Type: `fact`
47
+
48
+ A first-class, indexed, searchable markdown asset type. Stored under
49
+ `facts/` in a bundle; ref form `fact:<name>` (nesting allowed, e.g.
50
+ `fact:team/tool-stack`). Singular name matches akm convention
51
+ (`skill`, `memory`, `lesson`, `task`, `session`).
52
+
53
+ ```
54
+ <stash>/facts/
55
+ personal/identity.md # fact:personal/identity
56
+ personal/writing-style.md
57
+ team/tool-stack.md
58
+ conventions/coding.md # the "constitution"
59
+ meta/naming-conventions.md
60
+ meta/active-projects.md
61
+ ```
62
+
63
+ ### One type, categorized — not a type explosion
64
+
65
+ Rather than separate `fact` / `constitution` / `profile` types, a single
66
+ `fact` type carries a `category` frontmatter dimension. This keeps akm's
67
+ minimalist type set and matches the LangMem "namespace/scope" approach.
68
+ Recommended values: `personal`, `team`, `project`, `convention`, `meta`.
69
+ Normative facts (the "constitution") are stored as facts and phrased as
70
+ guidance at injection time.
71
+
72
+ ### Frontmatter
73
+
74
+ ```yaml
75
+ ---
76
+ description: <one-line, indexed for search> # like other markdown types
77
+ category: personal|team|project|convention|meta
78
+ pinned: false # true → part of the always-injected core (keep this set small)
79
+ updated: 2026-06-20
80
+ ---
81
+ ```
82
+
83
+ `description` and `category` are the curation surface; `pinned` selects the
84
+ small always-on core. Additional keys (`source`, `status`, …) are accepted
85
+ but not required in phase 1.
86
+
87
+ ### Retrieval & injection model: pinned core + JIT retrieval
88
+
89
+ Two tiers, matching the context-engineering guidance:
90
+
91
+ 1. **`pinned: true` facts** form the small always-injected core (CLAUDE.md
92
+ style — keep it short). Phase 1 makes `pinned` a real, captured, query-
93
+ surfaceable property (tag + search hint + ranking boost); **phase 2** wires
94
+ the assembled pinned-core into harness system prompts.
95
+ 2. **Everything else** stays on "disk" and is surfaced through normal
96
+ `akm search` / `akm curate` / `akm show` (JIT retrieval). This works the
97
+ day the type ships — no new retrieval path required.
98
+
99
+ ### Ranking
100
+
101
+ `fact` gets a high `TYPE_BOOST` (authoritative, like `knowledge`), plus a
102
+ modest additional boost for `pinned` facts so the core outranks ordinary
103
+ facts on otherwise-equal queries.
104
+
105
+ ## Implementation (phase 1)
106
+
107
+ Following the `session`/`task` template, metadata is encoded as tags +
108
+ search hints (no new DB columns or `StashEntry` fields):
109
+
110
+ | Concern | File |
111
+ | --- | --- |
112
+ | Type spec | `PLACEMENT_SPECS` in `src/core/asset/asset-placement.ts` — `fact: { stashDir: "facts", ...markdownSpec }` |
113
+ | Renderer + action | `TYPE_PRESENTATION` in `src/core/type-presentation.ts` (supersedes the earlier `TYPE_TO_RENDERER`/`ACTION_BUILDERS` split) |
114
+ | Renderer + metadata | `src/output/renderers.ts` — `factMdRenderer` (frontmatter `category`/`pinned` parsed inline in `buildShowResponse`) |
115
+ | File classification | `src/indexer/walk/matchers.ts` — `DIR_TYPE_MAP` `facts/` |
116
+ | Ranking | `src/indexer/search/ranking-contributors.ts` — `TYPE_BOOST` + `pinnedFactRankingContributor` |
117
+ | Lint | `factDiagnostics` in `src/core/adapter/adapters/akm-lint.ts`, called from `src/commands/lint/index.ts` (warns `missing-category` on absent/unrecognized `category`) |
118
+ | Authoring hint | `src/integrations/agent/prompts.ts` — `TYPE_HINTS.fact` |
119
+ | Graph extraction (opt-in) | not currently wired: `graphExtractionIncludeTypes` (`src/core/config/schema/index-config.ts`) takes any string, but the runtime consumer's `SUPPORTED_GRAPH_EXTRACTION_INCLUDE_TYPES` set (`src/indexer/graph/graph-extraction.ts`) does not include `fact` — configuring it is a silent no-op today |
120
+ | Type union | `KNOWN_TYPES` in `src/core/recognition-util.ts`, which includes `fact` |
121
+
122
+ `fact:` refs resolve automatically — the ref resolver derives its type set
123
+ from `PLACEMENT_SPECS`, not `KNOWN_TYPES`: `typeNameFromConceptId`
124
+ (`src/core/asset/resolve-ref.ts`) calls `typeForStashDir`
125
+ (`src/core/asset/asset-placement.ts`), and `fact` has a `PLACEMENT_SPECS`
126
+ entry (`stashDir: "facts"`). The ref-resolver contract note in
127
+ `src/commands/lint/base-linter.ts` confirms the same split: `refToRelPath` is
128
+ "DERIVED FROM THE PLACEMENT SPECS ... rather than hand-encoded."
129
+
130
+ ## Phase 2 (follow-up, not in this change)
131
+
132
+ - Assemble the pinned-fact core and inject it into harness system prompts
133
+ (`src/integrations/agent/**`, per-harness builders).
134
+ - Optional `akm fact` CLI surface and a hot-capture path (à la `akm remember`).
135
+ - Staleness/conflict handling (`status: active|stale|superseded`), since the
136
+ documented failure mode of fact stores is update, not storage.
137
+
138
+ ## Relationship to `.meta/`
139
+
140
+ `.meta/` stays the human-oriented, non-indexed orientation convention.
141
+ `fact` is its machine-facing sibling: indexed, searchable, rankable, and
142
+ (phase 2) agent-injected.