akm-cli 0.9.0-rc.4 → 0.9.0-rc.6

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 (438) hide show
  1. package/CHANGELOG.md +122 -26
  2. package/README.md +7 -7
  3. package/SECURITY.md +11 -10
  4. package/dist/akm +2 -2
  5. package/dist/akm-migrate-storage +2 -2
  6. package/dist/assets/hints/cli-hints-full.md +60 -73
  7. package/dist/assets/hints/cli-hints-short.md +8 -12
  8. package/dist/assets/improve-strategies/default.json +5 -7
  9. package/dist/assets/improve-strategies/frequent.json +2 -2
  10. package/dist/assets/improve-strategies/proactive-maintenance.json +2 -2
  11. package/dist/assets/improve-strategies/quick.json +1 -1
  12. package/dist/assets/improve-strategies/reflect-distill.json +3 -3
  13. package/dist/assets/improve-strategies/thorough.json +1 -1
  14. package/dist/assets/prompts/consolidate-system.md +5 -5
  15. package/dist/assets/prompts/extract-session.md +2 -6
  16. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  17. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  18. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  19. package/dist/assets/stash-skeleton/README.md +10 -11
  20. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +1 -1
  21. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +1 -1
  22. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +1 -1
  23. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -2
  24. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -2
  25. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +1 -1
  26. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -2
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +1 -1
  28. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +18 -18
  29. package/dist/assets/stash-skeleton/facts/conventions/domains.md +8 -9
  30. package/dist/assets/stash-skeleton/facts/conventions/organization.md +13 -15
  31. package/dist/assets/tasks/core/extract.yml +2 -2
  32. package/dist/assets/tasks/core/improve.yml +1 -1
  33. package/dist/assets/templates/html/health.html +2 -3
  34. package/dist/cli/config-migrate.js +1328 -101
  35. package/dist/cli/invocation.js +255 -0
  36. package/dist/cli/parse-args.js +20 -83
  37. package/dist/cli/shared.js +15 -37
  38. package/dist/cli.js +18 -49
  39. package/dist/commands/agent/agent-dispatch.js +2 -2
  40. package/dist/commands/agent/contribute-cli.js +5 -4
  41. package/dist/commands/bundle/bundle-cli.js +68 -0
  42. package/dist/commands/bundle/bundle.js +219 -0
  43. package/dist/commands/completions.js +2 -2
  44. package/dist/commands/config-cli.js +6 -3
  45. package/dist/commands/env/env-binding.js +13 -9
  46. package/dist/commands/env/env-cli.js +49 -48
  47. package/dist/commands/env/secret-cli.js +24 -10
  48. package/dist/commands/events.js +2 -2
  49. package/dist/commands/feedback-cli.js +59 -33
  50. package/dist/commands/graph/graph.js +6 -4
  51. package/dist/commands/health/advisories.js +4 -4
  52. package/dist/commands/health/html-report.js +190 -593
  53. package/dist/commands/health/improve-metrics.js +240 -188
  54. package/dist/commands/health/metrics.js +9 -17
  55. package/dist/commands/health/report-view-model.js +509 -0
  56. package/dist/commands/health/surfaces.js +6 -3
  57. package/dist/commands/health/types-checks.js +4 -0
  58. package/dist/commands/health/types-improve.js +22 -0
  59. package/dist/commands/health/types-metrics.js +4 -0
  60. package/dist/commands/health/types-result.js +7 -0
  61. package/dist/commands/health/types-runs.js +4 -0
  62. package/dist/commands/health/types-session-log.js +4 -0
  63. package/dist/commands/health/types-windows.js +4 -0
  64. package/dist/commands/health/types.js +26 -21
  65. package/dist/commands/health/windows.js +1 -2
  66. package/dist/commands/health.js +219 -161
  67. package/dist/commands/improve/collapse-detector.js +25 -14
  68. package/dist/commands/improve/consolidate/chunking.js +7 -5
  69. package/dist/commands/improve/consolidate.js +640 -740
  70. package/dist/commands/improve/content-hash.js +39 -0
  71. package/dist/commands/improve/distill/content-repair.js +4 -10
  72. package/dist/commands/improve/distill/promote-memory.js +79 -49
  73. package/dist/commands/improve/distill/quality-gate.js +113 -35
  74. package/dist/commands/improve/distill-promotion-policy.js +24 -885
  75. package/dist/commands/improve/distill.js +565 -337
  76. package/dist/commands/improve/eligibility.js +75 -36
  77. package/dist/commands/improve/extract-cli.js +6 -6
  78. package/dist/commands/improve/extract-prompt.js +5 -34
  79. package/dist/commands/improve/extract.js +526 -357
  80. package/dist/commands/improve/feedback-valence.js +2 -12
  81. package/dist/commands/improve/improve-cli.js +11 -20
  82. package/dist/commands/improve/improve-result-file.js +7 -6
  83. package/dist/commands/improve/improve-run-types.js +4 -0
  84. package/dist/commands/improve/improve-strategies.js +3 -9
  85. package/dist/commands/improve/improve.js +822 -727
  86. package/dist/commands/improve/locks.js +27 -95
  87. package/dist/commands/improve/loop-stages.js +941 -963
  88. package/dist/commands/improve/memory/derived-ref.js +122 -0
  89. package/dist/commands/improve/memory/memory-contradiction-detect.js +35 -38
  90. package/dist/commands/improve/memory/memory-improve.js +24 -37
  91. package/dist/commands/improve/outcome-loop.js +13 -33
  92. package/dist/commands/improve/preparation.js +889 -691
  93. package/dist/commands/improve/proactive-maintenance.js +37 -9
  94. package/dist/commands/improve/proposal-envelope.js +31 -0
  95. package/dist/commands/improve/reflect.js +974 -588
  96. package/dist/commands/improve/run-context.js +119 -0
  97. package/dist/commands/improve/salience.js +8 -4
  98. package/dist/commands/improve/session-asset.js +7 -3
  99. package/dist/commands/improve/shared.js +14 -40
  100. package/dist/commands/improve/source-identity.js +39 -26
  101. package/dist/commands/improve/triage.js +20 -17
  102. package/dist/commands/lint/base-linter.js +288 -295
  103. package/dist/commands/lint/index.js +132 -19
  104. package/dist/commands/mv-cli.js +257 -234
  105. package/dist/commands/observability-cli.js +2 -1
  106. package/dist/commands/proposal/diff-format.js +50 -0
  107. package/dist/commands/proposal/drain-policies.js +0 -6
  108. package/dist/commands/proposal/drain.js +17 -16
  109. package/dist/commands/proposal/proposal-cli.js +40 -77
  110. package/dist/commands/proposal/proposal-types.js +56 -0
  111. package/dist/commands/proposal/proposal.js +39 -1
  112. package/dist/commands/proposal/propose.js +41 -19
  113. package/dist/commands/proposal/repository.js +566 -486
  114. package/dist/commands/proposal/validators/proposal-quality-validators.js +22 -6
  115. package/dist/commands/proposal/validators/proposal-validators.js +6 -5
  116. package/dist/commands/proposal/validators/proposals.js +5 -4
  117. package/dist/commands/read/curate.js +50 -28
  118. package/dist/commands/read/knowledge.js +25 -16
  119. package/dist/commands/read/remember-cli.js +12 -4
  120. package/dist/commands/read/search-cli.js +33 -33
  121. package/dist/commands/read/search.js +68 -55
  122. package/dist/commands/read/show.js +54 -135
  123. package/dist/commands/remember.js +7 -5
  124. package/dist/commands/sources/add-cli.js +10 -24
  125. package/dist/commands/sources/bundle-config-ops.js +58 -0
  126. package/dist/commands/sources/history.js +13 -8
  127. package/dist/commands/sources/info.js +10 -11
  128. package/dist/commands/sources/init.js +12 -21
  129. package/dist/commands/sources/installed-stashes.js +151 -138
  130. package/dist/commands/sources/schema-repair.js +5 -3
  131. package/dist/commands/sources/self-update.js +9 -7
  132. package/dist/commands/sources/source-add.js +116 -154
  133. package/dist/commands/sources/source-clone.js +33 -14
  134. package/dist/commands/sources/source-manage.js +43 -32
  135. package/dist/commands/sources/sources-cli.js +12 -7
  136. package/dist/commands/sources/stash-cli.js +12 -5
  137. package/dist/commands/sources/stash-skeleton.js +1 -1
  138. package/dist/commands/tasks/default-tasks.js +13 -13
  139. package/dist/commands/tasks/tasks-cli.js +3 -3
  140. package/dist/commands/tasks/tasks.js +71 -31
  141. package/dist/commands/workflow-cli.js +22 -26
  142. package/dist/core/action-contributors.js +1 -1
  143. package/dist/core/activation-policy.js +49 -0
  144. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  145. package/dist/core/adapter/adapters/akm-adapter.js +509 -0
  146. package/dist/core/adapter/adapters/akm-lint.js +381 -0
  147. package/dist/core/adapter/adapters/akm-metadata.js +416 -0
  148. package/dist/core/adapter/adapters/akm-task-adapter.js +150 -0
  149. package/dist/core/adapter/adapters/akm-workflow-adapter.js +196 -0
  150. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  151. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  152. package/dist/core/adapter/adapters/generic-files-adapter.js +117 -0
  153. package/dist/core/adapter/adapters/index.js +80 -0
  154. package/dist/core/adapter/adapters/llm-wiki-adapter.js +413 -0
  155. package/dist/core/adapter/adapters/okf-adapter.js +223 -0
  156. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  157. package/dist/core/adapter/adapters/shared.js +286 -0
  158. package/dist/core/adapter/adapters/tool-dir-shared.js +212 -0
  159. package/dist/core/adapter/adapters/website-snapshot-adapter.js +154 -0
  160. package/dist/core/adapter/bundle-adapter.js +4 -0
  161. package/dist/core/adapter/recognize-match.js +42 -0
  162. package/dist/core/adapter/registry.js +56 -0
  163. package/dist/core/adapter/types.js +4 -0
  164. package/dist/core/asset/asset-placement.js +229 -0
  165. package/dist/core/asset/asset-ref.js +107 -78
  166. package/dist/core/asset/asset-serialize.js +20 -0
  167. package/dist/core/asset/frontmatter.js +1 -1
  168. package/dist/core/asset/resolve-ref.js +223 -0
  169. package/dist/core/asset/stash-meta.js +1 -1
  170. package/dist/core/common.js +141 -49
  171. package/dist/core/config/config-io.js +0 -108
  172. package/dist/core/config/config-schema.js +94 -1039
  173. package/dist/core/config/config-sources.js +115 -36
  174. package/dist/core/config/config-types.js +16 -11
  175. package/dist/core/config/config-walker.js +4 -2
  176. package/dist/core/config/config.js +21 -26
  177. package/dist/core/config/engine-semantics.js +0 -4
  178. package/dist/core/config/schema/embedding.js +38 -0
  179. package/dist/core/config/schema/engines.js +116 -0
  180. package/dist/core/config/schema/feedback.js +31 -0
  181. package/dist/core/config/schema/improve-processes.js +395 -0
  182. package/dist/core/config/schema/improve.js +76 -0
  183. package/dist/core/config/schema/index-config.js +183 -0
  184. package/dist/core/config/schema/output.js +15 -0
  185. package/dist/core/config/schema/primitives.js +94 -0
  186. package/dist/core/config/schema/search.js +30 -0
  187. package/dist/core/config/schema/setup.js +27 -0
  188. package/dist/core/config/schema/sources-bundles.js +164 -0
  189. package/dist/core/config/schema/workflow.js +29 -0
  190. package/dist/core/env-secret-ref.js +113 -8
  191. package/dist/core/errors.js +1 -1
  192. package/dist/core/events-types.js +4 -0
  193. package/dist/core/extra-params.js +1 -0
  194. package/dist/core/file-change.js +16 -0
  195. package/dist/core/fs-txn.js +316 -0
  196. package/dist/core/git-message.js +59 -0
  197. package/dist/core/improve-result.js +9 -1
  198. package/dist/core/logs-db.js +1 -1
  199. package/dist/core/maintenance-barrier.js +16 -0
  200. package/dist/core/migration-backup.js +332 -160
  201. package/dist/core/paths.js +3 -6
  202. package/dist/core/platform.js +10 -0
  203. package/dist/core/recognition-util.js +130 -0
  204. package/dist/core/redaction.js +2 -2
  205. package/dist/core/standards/resolve-standards-context.js +47 -64
  206. package/dist/core/standards/resolve-type-conventions.js +3 -3
  207. package/dist/core/state/migrations.js +201 -8
  208. package/dist/core/state-db.js +38 -2
  209. package/dist/core/subprocess.js +303 -0
  210. package/dist/core/time.js +20 -0
  211. package/dist/core/type-presentation.js +130 -0
  212. package/dist/core/write-source.js +39 -67
  213. package/dist/indexer/bundle-identity-guard.js +91 -0
  214. package/dist/indexer/db/graph-db.js +1 -1
  215. package/dist/indexer/db/llm-cache.js +1 -1
  216. package/dist/indexer/ensure-index.js +29 -9
  217. package/dist/indexer/graph/graph-boost.js +28 -24
  218. package/dist/indexer/graph/graph-extraction.js +5 -6
  219. package/dist/indexer/graph/graph-types.js +4 -0
  220. package/dist/indexer/index-written-assets.js +44 -17
  221. package/dist/indexer/indexer.js +289 -153
  222. package/dist/indexer/init.js +18 -25
  223. package/dist/indexer/installations.js +224 -0
  224. package/dist/indexer/passes/dir-staleness.js +2 -1
  225. package/dist/indexer/passes/memory-inference.js +8 -4
  226. package/dist/indexer/passes/metadata.js +96 -243
  227. package/dist/indexer/scan/doc-to-entry.js +123 -0
  228. package/dist/indexer/scan/drain-dir.js +144 -0
  229. package/dist/indexer/search/db-search.js +171 -99
  230. package/dist/indexer/search/fts-query.js +1 -1
  231. package/dist/indexer/search/ranking-contributors.js +57 -7
  232. package/dist/indexer/search/ranking-types.js +4 -0
  233. package/dist/indexer/search/ranking.js +31 -6
  234. package/dist/indexer/search/search-attribution.js +67 -0
  235. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  236. package/dist/indexer/search/search-source.js +109 -52
  237. package/dist/indexer/search/semantic-status.js +4 -1
  238. package/dist/indexer/usage/unmigrated-vaults-guard.js +2 -1
  239. package/dist/indexer/usage/usage-events.js +72 -9
  240. package/dist/indexer/walk/file-context.js +1 -44
  241. package/dist/indexer/walk/matchers.js +16 -32
  242. package/dist/indexer/walk/path-resolver.js +6 -5
  243. package/dist/indexer/walk/walker.js +4 -2
  244. package/dist/integrations/agent/engine-resolution.js +22 -0
  245. package/dist/integrations/agent/model-aliases.js +1 -1
  246. package/dist/integrations/agent/prompts.js +35 -11
  247. package/dist/integrations/agent/spawn.js +41 -270
  248. package/dist/integrations/harnesses/aider/agent-builder.js +2 -2
  249. package/dist/integrations/harnesses/aider/index.js +2 -11
  250. package/dist/integrations/harnesses/amazonq/agent-builder.js +1 -9
  251. package/dist/integrations/harnesses/amazonq/index.js +3 -16
  252. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  253. package/dist/integrations/harnesses/claude/index.js +1 -12
  254. package/dist/integrations/harnesses/claude/session-log.js +27 -65
  255. package/dist/integrations/harnesses/codex/agent-builder.js +1 -2
  256. package/dist/integrations/harnesses/codex/index.js +2 -12
  257. package/dist/integrations/harnesses/copilot/agent-builder.js +2 -3
  258. package/dist/integrations/harnesses/copilot/index.js +1 -12
  259. package/dist/integrations/harnesses/gemini/agent-builder.js +1 -3
  260. package/dist/integrations/harnesses/gemini/index.js +1 -12
  261. package/dist/integrations/harnesses/ids.js +24 -0
  262. package/dist/integrations/harnesses/index.js +27 -2
  263. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  264. package/dist/integrations/harnesses/opencode/index.js +1 -12
  265. package/dist/integrations/harnesses/opencode/session-log.js +67 -110
  266. package/dist/integrations/harnesses/opencode-sdk/harness.js +2 -11
  267. package/dist/integrations/harnesses/openhands/agent-builder.js +3 -3
  268. package/dist/integrations/harnesses/openhands/index.js +2 -11
  269. package/dist/integrations/harnesses/pi/agent-builder.js +3 -11
  270. package/dist/integrations/harnesses/pi/index.js +3 -15
  271. package/dist/integrations/harnesses/shared.js +17 -0
  272. package/dist/integrations/harnesses/types.js +37 -2
  273. package/dist/integrations/lockfile.js +36 -0
  274. package/dist/integrations/session-logs/index.js +21 -12
  275. package/dist/integrations/session-logs/provider-base.js +113 -0
  276. package/dist/llm/client.js +7 -5
  277. package/dist/llm/embedders/deterministic.js +2 -2
  278. package/dist/llm/embedders/remote.js +8 -4
  279. package/dist/llm/graph-extract.js +7 -2
  280. package/dist/llm/metadata-enhance.js +43 -26
  281. package/dist/llm/structured-call.js +15 -7
  282. package/dist/migrate/legacy/config-source-migration.js +223 -0
  283. package/dist/migrate/legacy/content-migration.js +305 -0
  284. package/dist/migrate/legacy/legacy-layout.js +779 -0
  285. package/dist/migrate/legacy/legacy-paths.js +25 -0
  286. package/dist/migrate/legacy/legacy-stash-json.js +72 -0
  287. package/dist/migrate/legacy/proposal-fs-import.js +168 -0
  288. package/dist/migrate/legacy/task-target-ref-migration.js +272 -0
  289. package/dist/migrate/legacy/three-db-cutover.js +840 -0
  290. package/dist/migrate/legacy/workflow-migrations-bodies.js +52 -0
  291. package/dist/migrate/legacy/workflow-migrations-frozen.js +21 -0
  292. package/dist/migrate/legacy-ref-grammar.js +209 -0
  293. package/dist/output/command-registry.js +27 -0
  294. package/dist/output/html-render.js +11 -16
  295. package/dist/output/renderers.js +32 -276
  296. package/dist/output/shapes/passthrough.js +3 -9
  297. package/dist/output/shapes/registry.js +12 -6
  298. package/dist/output/text/command-format.js +547 -0
  299. package/dist/output/text/helpers.js +15 -1377
  300. package/dist/output/text/proposal-format.js +230 -0
  301. package/dist/output/text/registry.js +12 -6
  302. package/dist/output/text/show-directives.js +107 -0
  303. package/dist/output/text/show-format.js +103 -0
  304. package/dist/output/text/workflow-format.js +345 -0
  305. package/dist/output/text.js +1 -3
  306. package/dist/registry/build-index.js +13 -17
  307. package/dist/registry/providers/static-index.js +2 -2
  308. package/dist/registry/resolve.js +4 -90
  309. package/dist/registry/semver.js +93 -0
  310. package/dist/runtime.js +90 -0
  311. package/dist/schemas/akm-config.json +2956 -14890
  312. package/dist/schemas/akm-task.json +2 -2
  313. package/dist/schemas/akm-workflow.json +2 -2
  314. package/dist/scripts/migrate-storage.js +2312 -19642
  315. package/dist/setup/detect.js +5 -7
  316. package/dist/setup/engine-config.js +2 -1
  317. package/dist/setup/registry-stash-loader.js +1 -1
  318. package/dist/setup/semantic-assets.js +12 -9
  319. package/dist/setup/setup.js +109 -39
  320. package/dist/setup/steps/connection-shared.js +120 -0
  321. package/dist/setup/steps/connection.js +50 -274
  322. package/dist/setup/steps/platforms.js +1 -0
  323. package/dist/setup/steps/sources.js +13 -6
  324. package/dist/setup/steps/stashdir.js +5 -2
  325. package/dist/sources/freshness.js +39 -0
  326. package/dist/sources/providers/git-provider.js +29 -33
  327. package/dist/sources/providers/git-stash.js +10 -5
  328. package/dist/sources/providers/provider-utils.js +40 -18
  329. package/dist/sources/providers/website.js +1 -1
  330. package/dist/sources/resolve.js +5 -5
  331. package/dist/sources/snapshot-fetchers/types.js +4 -0
  332. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +105 -39
  333. package/dist/storage/database.js +47 -3
  334. package/dist/storage/engines/sqlite-migrations.js +34 -16
  335. package/dist/storage/locations.js +1 -2
  336. package/dist/storage/repositories/improve-runs-repository.js +0 -20
  337. package/dist/storage/repositories/index-connection.js +80 -0
  338. package/dist/storage/repositories/index-db.js +4 -3
  339. package/dist/storage/repositories/index-entries-repository.js +952 -0
  340. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +15 -2
  341. package/dist/storage/repositories/index-entry-types.js +4 -0
  342. package/dist/storage/repositories/index-fts-repository.js +164 -0
  343. package/dist/storage/repositories/index-llm-cache-repository.js +109 -0
  344. package/dist/storage/repositories/index-meta-repository.js +50 -0
  345. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +241 -100
  346. package/dist/storage/repositories/index-sql.js +12 -0
  347. package/dist/storage/repositories/index-utility-repository.js +369 -0
  348. package/dist/storage/repositories/index-vec-repository.js +245 -0
  349. package/dist/storage/repositories/proposals-repository.js +41 -50
  350. package/dist/storage/repositories/registry-cache.js +1 -1
  351. package/dist/storage/repositories/workflow-runs-repository.js +17 -11
  352. package/dist/tasks/backends/cron.js +5 -5
  353. package/dist/tasks/backends/exec-utils.js +21 -0
  354. package/dist/tasks/backends/index.js +6 -9
  355. package/dist/tasks/backends/launchd.js +16 -17
  356. package/dist/tasks/backends/schtasks.js +33 -41
  357. package/dist/tasks/backends/types.js +4 -0
  358. package/dist/tasks/parser.js +25 -5
  359. package/dist/tasks/runner.js +33 -39
  360. package/dist/tasks/validator.js +5 -6
  361. package/dist/workflows/authoring/authoring.js +8 -11
  362. package/dist/workflows/exec/brief.js +10 -7
  363. package/dist/workflows/exec/report.js +261 -156
  364. package/dist/workflows/exec/run-workflow.js +2 -1
  365. package/dist/workflows/exec/step-work.js +3 -9
  366. package/dist/workflows/program/parser.js +4 -60
  367. package/dist/workflows/renderer.js +11 -60
  368. package/dist/workflows/runtime/checkin.js +1 -1
  369. package/dist/workflows/runtime/plan-classifier.js +7 -4
  370. package/dist/workflows/runtime/runs.js +11 -10
  371. package/dist/workflows/runtime/unit-checkin.js +1 -1
  372. package/dist/workflows/runtime/unit-phases.js +20 -0
  373. package/dist/workflows/runtime/workflow-asset-loader.js +27 -16
  374. package/dist/workflows/validate-summary.js +2 -2
  375. package/dist/workflows/validator.js +18 -2
  376. package/docs/migration/release-notes/0.9.0.md +45 -3
  377. package/docs/migration/v0.8-to-v0.9.md +466 -262
  378. package/docs/{data-and-telemetry.md → reference/data-and-telemetry.md} +61 -17
  379. package/package.json +10 -9
  380. package/schemas/akm-config.json +2956 -14890
  381. package/schemas/akm-task.json +2 -2
  382. package/schemas/akm-workflow.json +2 -2
  383. package/dist/assets/help/help-accept.md +0 -12
  384. package/dist/assets/help/help-improve.md +0 -84
  385. package/dist/assets/help/help-proposals.md +0 -17
  386. package/dist/assets/help/help-propose.md +0 -17
  387. package/dist/assets/help/help-reject.md +0 -11
  388. package/dist/assets/improve-strategies/recombine-only.json +0 -23
  389. package/dist/assets/improve-strategies/synthesize.json +0 -17
  390. package/dist/assets/prompts/procedural-system.md +0 -44
  391. package/dist/assets/prompts/recombine-system.md +0 -40
  392. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  393. package/dist/assets/templates/html/default.html +0 -78
  394. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  395. package/dist/assets/wiki/index-template.md +0 -12
  396. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  397. package/dist/assets/wiki/log-template.md +0 -8
  398. package/dist/assets/wiki/schema-template.md +0 -61
  399. package/dist/commands/improve/calibration.js +0 -161
  400. package/dist/commands/improve/dedup.js +0 -482
  401. package/dist/commands/improve/hot-probation.js +0 -45
  402. package/dist/commands/improve/improve-auto-accept.js +0 -262
  403. package/dist/commands/improve/procedural.js +0 -403
  404. package/dist/commands/improve/recombine.js +0 -843
  405. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  406. package/dist/commands/lint/agent-linter.js +0 -44
  407. package/dist/commands/lint/command-linter.js +0 -44
  408. package/dist/commands/lint/default-linter.js +0 -16
  409. package/dist/commands/lint/fact-linter.js +0 -39
  410. package/dist/commands/lint/knowledge-linter.js +0 -16
  411. package/dist/commands/lint/memory-linter.js +0 -61
  412. package/dist/commands/lint/registry.js +0 -41
  413. package/dist/commands/lint/skill-linter.js +0 -45
  414. package/dist/commands/lint/task-linter.js +0 -50
  415. package/dist/commands/lint/workflow-linter.js +0 -81
  416. package/dist/commands/proposal/legacy-import.js +0 -115
  417. package/dist/commands/wiki-cli.js +0 -291
  418. package/dist/core/asset/asset-registry.js +0 -76
  419. package/dist/core/asset/asset-spec.js +0 -316
  420. package/dist/core/eval/rank-metrics.js +0 -113
  421. package/dist/core/ripgrep/install.js +0 -163
  422. package/dist/core/ripgrep/resolve.js +0 -81
  423. package/dist/indexer/db/db.js +0 -1585
  424. package/dist/indexer/manifest.js +0 -170
  425. package/dist/indexer/passes/metadata-contributors.js +0 -31
  426. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
  427. package/dist/output/text/wiki.js +0 -16
  428. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -18228
  429. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  430. package/dist/storage/repositories/consolidation-repository.js +0 -38
  431. package/dist/storage/repositories/recombine-repository.js +0 -213
  432. package/dist/wiki/wiki-templates.js +0 -15
  433. package/dist/wiki/wiki.js +0 -1013
  434. package/dist/workflows/db.js +0 -413
  435. package/docs/README.md +0 -103
  436. package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
  437. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  438. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -0,0 +1,316 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * The ONE durable filesystem-transaction engine (plan §2.2 / §4.5, Chunk 6
6
+ * WI-6.3). Replaces the three (+1) per-domain journal engines — proposal
7
+ * accept/revert, proposal reject, mv, consolidate — with a single journal
8
+ * home, journal format, fsync discipline, phase runner, and recovery scanner.
9
+ *
10
+ * ## Journal home
11
+ *
12
+ * `getDataDir()/txn/<rootNs24>/<transactionId>/journal.json`, namespaced by
13
+ * the sha256 of the resolved root the transaction mutates. Every legacy home
14
+ * (`proposal-transactions/`, `proposal-rejections/`, in-stash
15
+ * `.akm/mv-transactions/`, in-stash `consolidate-journal.json`) collapses
16
+ * onto this one.
17
+ *
18
+ * ## Phase model
19
+ *
20
+ * Each transaction KIND declares its ordered phase vocabulary and a commit
21
+ * point. A journal found at a phase strictly BEFORE the commit point rolls
22
+ * BACK (the batch never happened); at or after it rolls FORWARD (the kind's
23
+ * `finalize` resumes idempotently from the recorded phase). Phase writes are
24
+ * durable: tmp + fsync + rename + parent-dir fsync — the exact discipline
25
+ * every legacy engine used, now in one place.
26
+ *
27
+ * ## Kind handlers
28
+ *
29
+ * Domain logic (what the files are, how to roll back, which DB/index/event
30
+ * steps finalize) stays with the domain: each kind registers a
31
+ * {@link TxnKindHandler}. The engine owns discovery, safety fencing, journal
32
+ * I/O, ordering, and cleanup. Recovery entry points call
33
+ * {@link recoverTxnsForRoot} (after importing the domain registrar so the
34
+ * kinds are registered).
35
+ *
36
+ * ## Crash-window test seam
37
+ *
38
+ * `_setTxnMutationHookForTests` replaces the per-engine hooks; domain code
39
+ * fires named points through {@link txnMutationHook} exactly where the legacy
40
+ * engines fired theirs, so the subprocess crash runners re-key mechanically.
41
+ */
42
+ import { createHash, randomUUID } from "node:crypto";
43
+ import fs from "node:fs";
44
+ import path from "node:path";
45
+ import { getDataDir } from "./paths.js";
46
+ import { warn } from "./warn.js";
47
+ // ── Registry ─────────────────────────────────────────────────────────────────
48
+ const kinds = new Map();
49
+ /**
50
+ * Register (or replace) the handler for a transaction kind. Handlers are
51
+ * stored payload-erased; beginTxn/recovery re-associate `P` via the kind tag.
52
+ */
53
+ export function registerTxnKind(kind, handler) {
54
+ kinds.set(kind, handler);
55
+ }
56
+ function requireKind(kind) {
57
+ const handler = kinds.get(kind);
58
+ if (!handler)
59
+ throw new Error(`No transaction handler registered for kind "${kind}".`);
60
+ return handler;
61
+ }
62
+ // ── Test seam ────────────────────────────────────────────────────────────────
63
+ let mutationHookForTests;
64
+ /** TEST-ONLY crash-window hook used by subprocess recovery tests. */
65
+ export function _setTxnMutationHookForTests(hook) {
66
+ mutationHookForTests = hook;
67
+ }
68
+ /** Fire a named crash-window point (no-op outside tests). */
69
+ export function txnMutationHook(point) {
70
+ mutationHookForTests?.(point);
71
+ }
72
+ // ── Durable file I/O primitives (shared fsync discipline) ────────────────────
73
+ export function txnHash(content) {
74
+ return createHash("sha256").update(content).digest("hex");
75
+ }
76
+ export function txnFileHash(filePath) {
77
+ return txnHash(fs.readFileSync(filePath));
78
+ }
79
+ export function fsyncTxnFile(filePath) {
80
+ const fd = fs.openSync(filePath, "r");
81
+ try {
82
+ fs.fsyncSync(fd);
83
+ }
84
+ finally {
85
+ fs.closeSync(fd);
86
+ }
87
+ }
88
+ export function fsyncTxnDir(dirPath) {
89
+ try {
90
+ fsyncTxnFile(dirPath);
91
+ }
92
+ catch {
93
+ // Directory fsync is unavailable on some platforms.
94
+ }
95
+ }
96
+ /** Durably write `content` to `filePath` (tmp + fsync + rename + dir fsync). */
97
+ export function writeTxnFileDurably(filePath, content, mode = 0o600) {
98
+ const tempPath = `${filePath}.tmp`;
99
+ fs.writeFileSync(tempPath, content, { mode });
100
+ fsyncTxnFile(tempPath);
101
+ fs.renameSync(tempPath, filePath);
102
+ fsyncTxnDir(path.dirname(filePath));
103
+ }
104
+ // ── Journal home / discovery ─────────────────────────────────────────────────
105
+ /**
106
+ * Canonical spelling of a transaction root: realpath when the root exists
107
+ * (so symlinked spellings — e.g. a stash reached through macOS /tmp — hash
108
+ * to the SAME namespace and bind-compare equal), resolved otherwise.
109
+ */
110
+ export function canonicalTxnRoot(root) {
111
+ try {
112
+ return fs.realpathSync(path.resolve(root));
113
+ }
114
+ catch {
115
+ return path.resolve(root);
116
+ }
117
+ }
118
+ /** Namespace directory for all transactions mutating `root`. */
119
+ export function txnNamespaceDir(root) {
120
+ const ns = txnHash(canonicalTxnRoot(root)).slice(0, 24);
121
+ return path.join(getDataDir(), "txn", ns);
122
+ }
123
+ /** Mint a transaction id ahead of {@link beginTxn} (see its `transactionId`). */
124
+ export function mintTxnId() {
125
+ return randomUUID();
126
+ }
127
+ /** The directory a transaction with `transactionId` on `root` will own. */
128
+ export function txnDirFor(root, transactionId) {
129
+ return path.join(txnNamespaceDir(root), transactionId);
130
+ }
131
+ function writeJournal(txn) {
132
+ writeTxnFileDurably(txn.journalPath, `${JSON.stringify(txn.journal, null, 2)}\n`);
133
+ }
134
+ /** Durably record `phase` on the journal, then mirror it in memory. */
135
+ export function advanceTxn(txn, phase) {
136
+ const handler = requireKind(txn.journal.kind);
137
+ if (!handler.phases.includes(phase)) {
138
+ throw new Error(`Unknown phase "${phase}" for transaction kind "${txn.journal.kind}".`);
139
+ }
140
+ const next = { ...txn.journal, phase };
141
+ writeTxnFileDurably(txn.journalPath, `${JSON.stringify(next, null, 2)}\n`);
142
+ txn.journal.phase = phase;
143
+ }
144
+ /**
145
+ * Open a new transaction: mint the id, create its directory, and durably
146
+ * write the journal at the kind's initial phase. The caller stages sidecar
147
+ * files under `txn.dir` and then applies/finalizes through the kind handler.
148
+ */
149
+ export function beginTxn(args) {
150
+ const handler = requireKind(args.kind);
151
+ const transactionId = args.transactionId ?? randomUUID();
152
+ if (!/^[A-Za-z0-9._-]+$/.test(transactionId) || transactionId === "." || transactionId === "..") {
153
+ throw new Error(`Invalid transaction id "${transactionId}" — must be a plain path segment.`);
154
+ }
155
+ const dir = path.join(txnNamespaceDir(args.root), transactionId);
156
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
157
+ const journal = {
158
+ version: 1,
159
+ kind: args.kind,
160
+ phase: handler.phases[0],
161
+ transactionId,
162
+ root: canonicalTxnRoot(args.root),
163
+ changes: args.changes,
164
+ decidedAt: args.decidedAt ?? new Date().toISOString(),
165
+ payload: args.payload,
166
+ };
167
+ const txn = { journal, journalPath: path.join(dir, "journal.json"), dir };
168
+ writeJournal(txn);
169
+ return txn;
170
+ }
171
+ /** Remove a transaction directory (and its namespace dir when empty). */
172
+ export function cleanupTxn(dir) {
173
+ try {
174
+ fs.rmSync(dir, { recursive: true, force: true });
175
+ try {
176
+ fs.rmdirSync(path.dirname(dir));
177
+ }
178
+ catch {
179
+ // Other transactions may still exist in the namespace.
180
+ }
181
+ return null;
182
+ }
183
+ catch (error) {
184
+ const message = `transaction committed but cleanup failed at ${dir}: ${error instanceof Error ? error.message : String(error)}`;
185
+ warn(`[txn] ${message}`);
186
+ return message;
187
+ }
188
+ }
189
+ /**
190
+ * Sweep a transaction directory that has NO journal — but only when it is
191
+ * demonstrably stale. All kinds share one namespace per root, so a scanner
192
+ * may encounter a SIBLING transaction inside `beginTxn`'s mkdir→journal
193
+ * window; a grace period keeps the sweep from racing it. Returns true when
194
+ * the directory was removed.
195
+ */
196
+ export function sweepJournallessTxnDir(dir, graceMs = 300_000) {
197
+ try {
198
+ const age = Date.now() - fs.statSync(dir).mtimeMs;
199
+ if (age < graceMs)
200
+ return false;
201
+ fs.rmSync(dir, { recursive: true, force: true });
202
+ return true;
203
+ }
204
+ catch {
205
+ return false;
206
+ }
207
+ }
208
+ /** True when `candidate` is inside `root` (both resolved). */
209
+ export function isWithinTxnRoot(candidate, root) {
210
+ const rel = path.relative(path.resolve(root), path.resolve(candidate));
211
+ return rel !== "" && !rel.startsWith("..") && !path.isAbsolute(rel);
212
+ }
213
+ function readJournal(journalPath) {
214
+ let journal;
215
+ try {
216
+ journal = JSON.parse(fs.readFileSync(journalPath, "utf8"));
217
+ }
218
+ catch (error) {
219
+ throw new Error(`Cannot read transaction journal at ${journalPath}: ${error instanceof Error ? error.message : String(error)}`);
220
+ }
221
+ if (journal.version !== 1 || typeof journal.kind !== "string" || typeof journal.phase !== "string") {
222
+ throw new Error(`Refusing unsafe transaction journal at ${journalPath}.`);
223
+ }
224
+ return journal;
225
+ }
226
+ /** Engine-level safety fences shared by every kind. */
227
+ function fenceJournal(journal, txnDir, root, journalPath) {
228
+ if (canonicalTxnRoot(journal.root) !== canonicalTxnRoot(root)) {
229
+ throw new Error(`Refusing transaction journal bound to a different root at ${journalPath}.`);
230
+ }
231
+ const handler = requireKind(journal.kind);
232
+ if (!handler.phases.includes(journal.phase)) {
233
+ throw new Error(`Refusing transaction journal with unknown phase "${journal.phase}" at ${journalPath}.`);
234
+ }
235
+ for (const change of journal.changes) {
236
+ if (typeof change.path !== "string" || !isWithinTxnRoot(change.path, root)) {
237
+ throw new Error(`Refusing transaction journal touching paths outside its root at ${journalPath}.`);
238
+ }
239
+ }
240
+ handler.validate?.(journal, txnDir, root);
241
+ }
242
+ /** True when `journal.phase` is at or after the kind's commit point. */
243
+ export function isCommittedPhase(journal) {
244
+ const handler = requireKind(journal.kind);
245
+ return handler.phases.indexOf(journal.phase) >= handler.phases.indexOf(handler.commitPhase);
246
+ }
247
+ /**
248
+ * Recover every interrupted transaction under `root`'s namespace: journals
249
+ * before their kind's commit point roll BACK; the rest roll FORWARD through
250
+ * the kind's `finalize`. Fully-finalized directories are swept. The domain
251
+ * registrar (which registers the kinds) must be imported by the caller.
252
+ *
253
+ * `filter` optionally narrows recovery (e.g. one kind, one proposal id).
254
+ */
255
+ export async function recoverTxnsForRoot(root, filter) {
256
+ const nsDir = txnNamespaceDir(root);
257
+ const recovered = [];
258
+ if (!fs.existsSync(nsDir))
259
+ return recovered;
260
+ for (const entry of fs.readdirSync(nsDir, { withFileTypes: true })) {
261
+ if (!entry.isDirectory())
262
+ continue;
263
+ const dir = path.join(nsDir, entry.name);
264
+ const journalPath = path.join(dir, "journal.json");
265
+ if (!fs.existsSync(journalPath)) {
266
+ sweepJournallessTxnDir(dir);
267
+ continue;
268
+ }
269
+ const journal = readJournal(journalPath);
270
+ if (filter && !filter(journal))
271
+ continue;
272
+ fenceJournal(journal, dir, root, journalPath);
273
+ const handler = requireKind(journal.kind);
274
+ const txn = { journal, journalPath, dir };
275
+ const terminal = handler.phases[handler.phases.length - 1];
276
+ if (!isCommittedPhase(journal)) {
277
+ await handler.rollback(txn);
278
+ }
279
+ else if (journal.phase !== terminal) {
280
+ await handler.finalize(txn);
281
+ }
282
+ recovered.push(journal);
283
+ cleanupTxn(dir);
284
+ }
285
+ return recovered;
286
+ }
287
+ /**
288
+ * Enumerate (without recovering) every journal across ALL namespaces that
289
+ * matches `predicate`. Used by stash-scoped recovery entry points that don't
290
+ * know which roots their interrupted transactions were bound to.
291
+ */
292
+ export function listTxnJournals(predicate) {
293
+ const home = path.join(getDataDir(), "txn");
294
+ const matches = [];
295
+ if (!fs.existsSync(home))
296
+ return matches;
297
+ for (const ns of fs.readdirSync(home, { withFileTypes: true })) {
298
+ if (!ns.isDirectory())
299
+ continue;
300
+ const nsDir = path.join(home, ns.name);
301
+ for (const entry of fs.readdirSync(nsDir, { withFileTypes: true })) {
302
+ if (!entry.isDirectory())
303
+ continue;
304
+ const journalPath = path.join(nsDir, entry.name, "journal.json");
305
+ if (!fs.existsSync(journalPath))
306
+ continue;
307
+ // Unreadable/invalid journals fail LOUDLY: a caller deciding what to
308
+ // recover must never silently overlook a damaged journal (it may fence
309
+ // an interrupted, irreversible mutation).
310
+ const journal = readJournal(journalPath);
311
+ if (predicate(journal))
312
+ matches.push(journal);
313
+ }
314
+ }
315
+ return matches;
316
+ }
@@ -0,0 +1,59 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * Leaf util for sanitizing git commit messages.
6
+ *
7
+ * Split out of `core/write-source.ts` so that `sources/providers/git-stash.ts`
8
+ * (which `core/write-source.ts` imports `getCachePaths`/`listGitChangedPaths`/
9
+ * `parseGitRepoUrl`/`saveGitStash` from, via the `sources/providers/git`
10
+ * barrel, by value) does not need to import back into `write-source.ts` just
11
+ * for this helper — that back-edge was a 3-file static-graph cycle
12
+ * (write-source.ts → git.ts → git-stash.ts → write-source.ts; chunk 9 WI-9.8
13
+ * KILL 6 sever). `write-source.ts` re-exports `sanitizeCommitMessage` so
14
+ * existing import sites are unaffected.
15
+ */
16
+ /**
17
+ * Maximum length of a sanitized git commit message. Git itself imposes no
18
+ * fixed limit, but message strings come from refs and `--message` flags that
19
+ * can be supplied by users or upstream config. A 4096-char clamp keeps audit
20
+ * trails readable and prevents pathological payloads from bloating the log
21
+ * stream a downstream consumer parses.
22
+ */
23
+ const COMMIT_MESSAGE_MAX_LENGTH = 4096;
24
+ /**
25
+ * Sanitize a string before passing it as `git commit -m <message>`.
26
+ *
27
+ * Defenses, in order:
28
+ * 1. Strip NUL bytes (`\0`) — git rejects them anyway, but we never want
29
+ * them in argv.
30
+ * 2. Replace any CR/LF (`\r`, `\n`) and other ASCII control chars with a
31
+ * single space. This collapses newline-injection attempts that would
32
+ * otherwise turn a single-line commit subject into a forged trailer
33
+ * block.
34
+ * 3. Collapse runs of whitespace into a single space and trim.
35
+ * 4. Clamp to {@link COMMIT_MESSAGE_MAX_LENGTH} characters.
36
+ *
37
+ * If the result is empty after sanitization the caller should substitute a
38
+ * default — this helper returns `""` rather than throwing because not every
39
+ * callsite has a sensible "invalid input" exit code, and "empty" is a
40
+ * recoverable signal.
41
+ */
42
+ export function sanitizeCommitMessage(input) {
43
+ if (typeof input !== "string")
44
+ return "";
45
+ // 1. Strip NULs outright.
46
+ let out = input.replace(/\0/g, "");
47
+ // 2. Replace CR/LF + other C0 control characters (0x00-0x1F, 0x7F) with a
48
+ // space. Tab (0x09) is included intentionally — commit subjects should
49
+ // be a single visual line.
50
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: intentional sanitization
51
+ out = out.replace(/[\x00-\x1F\x7F]/g, " ");
52
+ // 3. Collapse whitespace runs and trim.
53
+ out = out.replace(/\s+/g, " ").trim();
54
+ // 4. Clamp length.
55
+ if (out.length > COMMIT_MESSAGE_MAX_LENGTH) {
56
+ out = out.slice(0, COMMIT_MESSAGE_MAX_LENGTH).trimEnd();
57
+ }
58
+ return out;
59
+ }
@@ -37,6 +37,7 @@ const COMMON_FIELDS = [
37
37
  "gateAutoAcceptFailedCount",
38
38
  "triage",
39
39
  "proactiveMaintenance",
40
+ // Retired producers still exist in the persisted 90-day improve-run ledger.
40
41
  "recombination",
41
42
  "proceduralCompilation",
42
43
  "cycleMetrics",
@@ -44,7 +45,13 @@ const COMMON_FIELDS = [
44
45
  "sync",
45
46
  "terminated",
46
47
  ];
47
- const V1_FIELDS = new Set([...COMMON_FIELDS, "profile", "profileFilteredRefs", "stalenessDetection"]);
48
+ const V1_FIELDS = new Set([
49
+ ...COMMON_FIELDS,
50
+ "profile",
51
+ "profileFilteredRefs",
52
+ "stalenessDetection",
53
+ "executionLogCandidates",
54
+ ]);
48
55
  const V2_FIELDS = new Set([...COMMON_FIELDS, "strategy", "strategyFilteredRefs"]);
49
56
  const STALENESS_DETECTION_FIELDS = new Set([
50
57
  "considered",
@@ -131,6 +138,7 @@ function validateCommon(value) {
131
138
  "extract",
132
139
  "coverageGaps",
133
140
  "deadUrls",
141
+ "executionLogCandidates",
134
142
  ]) {
135
143
  if (value[field] !== undefined && !Array.isArray(value[field]))
136
144
  fail(`${field} must be an array`);
@@ -9,7 +9,7 @@
9
9
  * The strategic direction (stop scattering data across files/folders) means
10
10
  * every NEW log consumer queries this database; the per-run text file written
11
11
  * by the task runner is retained only as a transitional tail for humans —
12
- * see docs/technical/logs-audit.md for the full producer audit.
12
+ * per the #579 logs audit of every producer.
13
13
  *
14
14
  * ## Why a separate database from state.db
15
15
  *
@@ -47,6 +47,22 @@ export function withMaintenanceStartBarrier(run) {
47
47
  release();
48
48
  }
49
49
  }
50
+ /** Run while holding the start barrier, or return undefined when it is busy. */
51
+ export function tryWithMaintenanceStartBarrier(run) {
52
+ if (heldBarrierContext.getStore()?.active)
53
+ return run();
54
+ const release = tryAcquireMaintenanceBarrier();
55
+ if (!release)
56
+ return undefined;
57
+ const ownership = { active: true };
58
+ try {
59
+ return heldBarrierContext.run(ownership, run);
60
+ }
61
+ finally {
62
+ ownership.active = false;
63
+ release();
64
+ }
65
+ }
50
66
  async function acquireMaintenanceBarrierAsync() {
51
67
  const deadline = Date.now() + 5_000;
52
68
  while (true) {