usesteady 0.1.0-alpha.7 → 0.1.0-alpha.70

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 (516) hide show
  1. package/CHANGELOG.md +2527 -0
  2. package/README.md +356 -25
  3. package/dist/server.d.ts.map +1 -1
  4. package/dist/server.js +175 -5
  5. package/dist/server.js.map +1 -1
  6. package/dist/src/b.d.ts +2 -0
  7. package/dist/src/b.d.ts.map +1 -0
  8. package/dist/src/b.js +2 -0
  9. package/dist/src/b.js.map +1 -0
  10. package/dist/src/claude/adapters/multi-llm-adapter.d.ts +72 -0
  11. package/dist/src/claude/adapters/multi-llm-adapter.d.ts.map +1 -0
  12. package/dist/src/claude/adapters/multi-llm-adapter.js +423 -0
  13. package/dist/src/claude/adapters/multi-llm-adapter.js.map +1 -0
  14. package/dist/src/claude/adapters/multi-llm-types.d.ts +246 -0
  15. package/dist/src/claude/adapters/multi-llm-types.d.ts.map +1 -0
  16. package/dist/src/claude/adapters/multi-llm-types.js +262 -0
  17. package/dist/src/claude/adapters/multi-llm-types.js.map +1 -0
  18. package/dist/src/claude/adapters/openai-compatible-adapter.d.ts +99 -0
  19. package/dist/src/claude/adapters/openai-compatible-adapter.d.ts.map +1 -0
  20. package/dist/src/claude/adapters/openai-compatible-adapter.js +424 -0
  21. package/dist/src/claude/adapters/openai-compatible-adapter.js.map +1 -0
  22. package/dist/src/claude/index.d.ts +6 -0
  23. package/dist/src/claude/index.d.ts.map +1 -1
  24. package/dist/src/claude/index.js +4 -0
  25. package/dist/src/claude/index.js.map +1 -1
  26. package/dist/src/config/providers.d.ts +61 -0
  27. package/dist/src/config/providers.d.ts.map +1 -0
  28. package/dist/src/config/providers.js +57 -0
  29. package/dist/src/config/providers.js.map +1 -0
  30. package/dist/src/control/compiler.d.ts.map +1 -1
  31. package/dist/src/control/compiler.js +53 -4
  32. package/dist/src/control/compiler.js.map +1 -1
  33. package/dist/src/control/discover-boundary.d.ts +88 -0
  34. package/dist/src/control/discover-boundary.d.ts.map +1 -0
  35. package/dist/src/control/discover-boundary.js +172 -0
  36. package/dist/src/control/discover-boundary.js.map +1 -0
  37. package/dist/src/control/verify-and-resolve.d.ts +82 -0
  38. package/dist/src/control/verify-and-resolve.d.ts.map +1 -0
  39. package/dist/src/control/verify-and-resolve.js +207 -0
  40. package/dist/src/control/verify-and-resolve.js.map +1 -0
  41. package/dist/src/cursor/adapters/inprocess-adapter.d.ts +71 -2
  42. package/dist/src/cursor/adapters/inprocess-adapter.d.ts.map +1 -1
  43. package/dist/src/cursor/adapters/inprocess-adapter.js +559 -23
  44. package/dist/src/cursor/adapters/inprocess-adapter.js.map +1 -1
  45. package/dist/src/cursor/artifact-mapper.js +1 -0
  46. package/dist/src/cursor/artifact-mapper.js.map +1 -1
  47. package/dist/src/cursor/ocd-evaluator.d.ts.map +1 -1
  48. package/dist/src/cursor/ocd-evaluator.js +64 -3
  49. package/dist/src/cursor/ocd-evaluator.js.map +1 -1
  50. package/dist/src/cursor/types.d.ts +1 -1
  51. package/dist/src/cursor/types.d.ts.map +1 -1
  52. package/dist/src/execution/cursor/cursor-execution-coordinator.js +2 -0
  53. package/dist/src/execution/cursor/cursor-execution-coordinator.js.map +1 -1
  54. package/dist/src/execution/unresolved-classification.d.ts +5 -0
  55. package/dist/src/execution/unresolved-classification.d.ts.map +1 -0
  56. package/dist/src/execution/unresolved-classification.js +26 -0
  57. package/dist/src/execution/unresolved-classification.js.map +1 -0
  58. package/dist/src/friction/activation.d.ts.map +1 -1
  59. package/dist/src/friction/activation.js +9 -0
  60. package/dist/src/friction/activation.js.map +1 -1
  61. package/dist/src/friction/github-issues.d.ts +6 -0
  62. package/dist/src/friction/github-issues.d.ts.map +1 -1
  63. package/dist/src/friction/github-issues.js +9 -0
  64. package/dist/src/friction/github-issues.js.map +1 -1
  65. package/dist/src/friction/posthog.d.ts +33 -0
  66. package/dist/src/friction/posthog.d.ts.map +1 -0
  67. package/dist/src/friction/posthog.js +106 -0
  68. package/dist/src/friction/posthog.js.map +1 -0
  69. package/dist/src/history/timeline-projection.d.ts +46 -0
  70. package/dist/src/history/timeline-projection.d.ts.map +1 -0
  71. package/dist/src/history/timeline-projection.js +95 -0
  72. package/dist/src/history/timeline-projection.js.map +1 -0
  73. package/dist/src/history/workflow-history.d.ts.map +1 -1
  74. package/dist/src/history/workflow-history.js +48 -23
  75. package/dist/src/history/workflow-history.js.map +1 -1
  76. package/dist/src/index.d.ts +4 -2
  77. package/dist/src/index.d.ts.map +1 -1
  78. package/dist/src/index.js +3 -1
  79. package/dist/src/index.js.map +1 -1
  80. package/dist/src/input/cli-error.d.ts +177 -0
  81. package/dist/src/input/cli-error.d.ts.map +1 -0
  82. package/dist/src/input/cli-error.js +57 -0
  83. package/dist/src/input/cli-error.js.map +1 -0
  84. package/dist/src/input/feasibility-validator.d.ts +160 -0
  85. package/dist/src/input/feasibility-validator.d.ts.map +1 -0
  86. package/dist/src/input/feasibility-validator.js +961 -0
  87. package/dist/src/input/feasibility-validator.js.map +1 -0
  88. package/dist/src/input/index.d.ts +22 -0
  89. package/dist/src/input/index.d.ts.map +1 -0
  90. package/dist/src/input/index.js +26 -0
  91. package/dist/src/input/index.js.map +1 -0
  92. package/dist/src/input/ir-to-draft.d.ts +58 -0
  93. package/dist/src/input/ir-to-draft.d.ts.map +1 -0
  94. package/dist/src/input/ir-to-draft.js +132 -0
  95. package/dist/src/input/ir-to-draft.js.map +1 -0
  96. package/dist/src/input/ir.d.ts +154 -0
  97. package/dist/src/input/ir.d.ts.map +1 -0
  98. package/dist/src/input/ir.js +37 -0
  99. package/dist/src/input/ir.js.map +1 -0
  100. package/dist/src/input/json-to-ir.d.ts +131 -0
  101. package/dist/src/input/json-to-ir.d.ts.map +1 -0
  102. package/dist/src/input/json-to-ir.js +386 -0
  103. package/dist/src/input/json-to-ir.js.map +1 -0
  104. package/dist/src/input/nl-to-ir.d.ts +132 -0
  105. package/dist/src/input/nl-to-ir.d.ts.map +1 -0
  106. package/dist/src/input/nl-to-ir.js +677 -0
  107. package/dist/src/input/nl-to-ir.js.map +1 -0
  108. package/dist/src/input/op-registry.d.ts +118 -0
  109. package/dist/src/input/op-registry.d.ts.map +1 -0
  110. package/dist/src/input/op-registry.js +173 -0
  111. package/dist/src/input/op-registry.js.map +1 -0
  112. package/dist/src/input/parse-json-input.d.ts +31 -0
  113. package/dist/src/input/parse-json-input.d.ts.map +1 -0
  114. package/dist/src/input/parse-json-input.js +216 -0
  115. package/dist/src/input/parse-json-input.js.map +1 -0
  116. package/dist/src/input/public-json-schema.d.ts +92 -0
  117. package/dist/src/input/public-json-schema.d.ts.map +1 -0
  118. package/dist/src/input/public-json-schema.js +131 -0
  119. package/dist/src/input/public-json-schema.js.map +1 -0
  120. package/dist/src/intake/intake-service.d.ts +26 -0
  121. package/dist/src/intake/intake-service.d.ts.map +1 -1
  122. package/dist/src/intake/intake-service.js +46 -0
  123. package/dist/src/intake/intake-service.js.map +1 -1
  124. package/dist/src/intake/intent-families.d.ts +85 -0
  125. package/dist/src/intake/intent-families.d.ts.map +1 -0
  126. package/dist/src/intake/intent-families.js +69 -0
  127. package/dist/src/intake/intent-families.js.map +1 -0
  128. package/dist/src/intake/llm-classifier.d.ts +46 -0
  129. package/dist/src/intake/llm-classifier.d.ts.map +1 -0
  130. package/dist/src/intake/llm-classifier.js +177 -0
  131. package/dist/src/intake/llm-classifier.js.map +1 -0
  132. package/dist/src/interaction/guidance-order.js +3 -3
  133. package/dist/src/interaction/guidance-order.js.map +1 -1
  134. package/dist/src/kernel/artifact.d.ts +32 -0
  135. package/dist/src/kernel/artifact.d.ts.map +1 -0
  136. package/dist/src/kernel/artifact.js +55 -0
  137. package/dist/src/kernel/artifact.js.map +1 -0
  138. package/dist/src/kernel/classifier.d.ts +69 -0
  139. package/dist/src/kernel/classifier.d.ts.map +1 -0
  140. package/dist/src/kernel/classifier.js +197 -0
  141. package/dist/src/kernel/classifier.js.map +1 -0
  142. package/dist/src/kernel/command-classifier.d.ts +110 -0
  143. package/dist/src/kernel/command-classifier.d.ts.map +1 -0
  144. package/dist/src/kernel/command-classifier.js +143 -0
  145. package/dist/src/kernel/command-classifier.js.map +1 -0
  146. package/dist/src/kernel/error-codes.d.ts +252 -0
  147. package/dist/src/kernel/error-codes.d.ts.map +1 -0
  148. package/dist/src/kernel/error-codes.js +278 -0
  149. package/dist/src/kernel/error-codes.js.map +1 -0
  150. package/dist/src/kernel/execution-replay.d.ts +73 -0
  151. package/dist/src/kernel/execution-replay.d.ts.map +1 -0
  152. package/dist/src/kernel/execution-replay.js +439 -0
  153. package/dist/src/kernel/execution-replay.js.map +1 -0
  154. package/dist/src/kernel/inline-js-classifier.d.ts +126 -0
  155. package/dist/src/kernel/inline-js-classifier.d.ts.map +1 -0
  156. package/dist/src/kernel/inline-js-classifier.js +275 -0
  157. package/dist/src/kernel/inline-js-classifier.js.map +1 -0
  158. package/dist/src/kernel/persist.d.ts +24 -0
  159. package/dist/src/kernel/persist.d.ts.map +1 -0
  160. package/dist/src/kernel/persist.js +32 -0
  161. package/dist/src/kernel/persist.js.map +1 -0
  162. package/dist/src/kernel/replay.d.ts +27 -0
  163. package/dist/src/kernel/replay.d.ts.map +1 -0
  164. package/dist/src/kernel/replay.js +59 -0
  165. package/dist/src/kernel/replay.js.map +1 -0
  166. package/dist/src/kernel/result-equality.d.ts +19 -0
  167. package/dist/src/kernel/result-equality.d.ts.map +1 -0
  168. package/dist/src/kernel/result-equality.js +24 -0
  169. package/dist/src/kernel/result-equality.js.map +1 -0
  170. package/dist/src/kernel/sandbox.d.ts +35 -0
  171. package/dist/src/kernel/sandbox.d.ts.map +1 -0
  172. package/dist/src/kernel/sandbox.js +47 -0
  173. package/dist/src/kernel/sandbox.js.map +1 -0
  174. package/dist/src/kernel/types.d.ts +55 -0
  175. package/dist/src/kernel/types.d.ts.map +1 -0
  176. package/dist/src/kernel/types.js +15 -0
  177. package/dist/src/kernel/types.js.map +1 -0
  178. package/dist/src/observe/drl-ledger-writer.d.ts +13 -0
  179. package/dist/src/observe/drl-ledger-writer.d.ts.map +1 -0
  180. package/dist/src/observe/drl-ledger-writer.js +8 -0
  181. package/dist/src/observe/drl-ledger-writer.js.map +1 -0
  182. package/dist/src/product/claude-product-session.d.ts +2 -1
  183. package/dist/src/product/claude-product-session.d.ts.map +1 -1
  184. package/dist/src/product/claude-product-session.js +2 -2
  185. package/dist/src/product/claude-product-session.js.map +1 -1
  186. package/dist/src/product/cursor-product-session.d.ts +24 -2
  187. package/dist/src/product/cursor-product-session.d.ts.map +1 -1
  188. package/dist/src/product/cursor-product-session.js +312 -10
  189. package/dist/src/product/cursor-product-session.js.map +1 -1
  190. package/dist/src/prv/patterns.d.ts.map +1 -1
  191. package/dist/src/prv/patterns.js +10 -1
  192. package/dist/src/prv/patterns.js.map +1 -1
  193. package/dist/src/safety/canonicalize.d.ts +65 -0
  194. package/dist/src/safety/canonicalize.d.ts.map +1 -0
  195. package/dist/src/safety/canonicalize.js +126 -0
  196. package/dist/src/safety/canonicalize.js.map +1 -0
  197. package/dist/src/safety/detectors/arbitrary-exec.detector.d.ts.map +1 -1
  198. package/dist/src/safety/detectors/arbitrary-exec.detector.js +21 -4
  199. package/dist/src/safety/detectors/arbitrary-exec.detector.js.map +1 -1
  200. package/dist/src/safety/detectors/destructive.detector.d.ts.map +1 -1
  201. package/dist/src/safety/detectors/destructive.detector.js +14 -1
  202. package/dist/src/safety/detectors/destructive.detector.js.map +1 -1
  203. package/dist/src/safety/filename-safety.d.ts +287 -0
  204. package/dist/src/safety/filename-safety.d.ts.map +1 -0
  205. package/dist/src/safety/filename-safety.js +821 -0
  206. package/dist/src/safety/filename-safety.js.map +1 -0
  207. package/dist/src/safety/path-segment-semantics.d.ts +25 -0
  208. package/dist/src/safety/path-segment-semantics.d.ts.map +1 -0
  209. package/dist/src/safety/path-segment-semantics.js +60 -0
  210. package/dist/src/safety/path-segment-semantics.js.map +1 -0
  211. package/dist/src/safety/safety-gate.d.ts +7 -0
  212. package/dist/src/safety/safety-gate.d.ts.map +1 -1
  213. package/dist/src/safety/safety-gate.js +24 -2
  214. package/dist/src/safety/safety-gate.js.map +1 -1
  215. package/dist/src/session/controller.d.ts +259 -0
  216. package/dist/src/session/controller.d.ts.map +1 -0
  217. package/dist/src/session/controller.js +286 -0
  218. package/dist/src/session/controller.js.map +1 -0
  219. package/dist/src/session/index.d.ts +12 -0
  220. package/dist/src/session/index.d.ts.map +1 -0
  221. package/dist/src/session/index.js +12 -0
  222. package/dist/src/session/index.js.map +1 -0
  223. package/dist/src/shell/cli/audit-export.d.ts +70 -0
  224. package/dist/src/shell/cli/audit-export.d.ts.map +1 -0
  225. package/dist/src/shell/cli/audit-export.js +168 -0
  226. package/dist/src/shell/cli/audit-export.js.map +1 -0
  227. package/dist/src/shell/cli/capabilities.d.ts +76 -0
  228. package/dist/src/shell/cli/capabilities.d.ts.map +1 -0
  229. package/dist/src/shell/cli/capabilities.js +116 -0
  230. package/dist/src/shell/cli/capabilities.js.map +1 -0
  231. package/dist/src/shell/cli/claude-setup.d.ts +43 -0
  232. package/dist/src/shell/cli/claude-setup.d.ts.map +1 -0
  233. package/dist/src/shell/cli/claude-setup.js +218 -0
  234. package/dist/src/shell/cli/claude-setup.js.map +1 -0
  235. package/dist/src/shell/cli/config-hydration.d.ts +37 -0
  236. package/dist/src/shell/cli/config-hydration.d.ts.map +1 -0
  237. package/dist/src/shell/cli/config-hydration.js +68 -0
  238. package/dist/src/shell/cli/config-hydration.js.map +1 -0
  239. package/dist/src/shell/cli/doctor.d.ts +44 -0
  240. package/dist/src/shell/cli/doctor.d.ts.map +1 -0
  241. package/dist/src/shell/cli/doctor.js +337 -0
  242. package/dist/src/shell/cli/doctor.js.map +1 -0
  243. package/dist/src/shell/cli/draft/intent-to-tasks.d.ts +68 -0
  244. package/dist/src/shell/cli/draft/intent-to-tasks.d.ts.map +1 -0
  245. package/dist/src/shell/cli/draft/intent-to-tasks.js +355 -0
  246. package/dist/src/shell/cli/draft/intent-to-tasks.js.map +1 -0
  247. package/dist/src/shell/cli/examples.d.ts +94 -0
  248. package/dist/src/shell/cli/examples.d.ts.map +1 -0
  249. package/dist/src/shell/cli/examples.js +173 -0
  250. package/dist/src/shell/cli/examples.js.map +1 -0
  251. package/dist/src/shell/cli/execution-policy.d.ts +67 -0
  252. package/dist/src/shell/cli/execution-policy.d.ts.map +1 -0
  253. package/dist/src/shell/cli/execution-policy.js +73 -0
  254. package/dist/src/shell/cli/execution-policy.js.map +1 -0
  255. package/dist/src/shell/cli/execution-summary.d.ts +115 -0
  256. package/dist/src/shell/cli/execution-summary.d.ts.map +1 -0
  257. package/dist/src/shell/cli/execution-summary.js +166 -0
  258. package/dist/src/shell/cli/execution-summary.js.map +1 -0
  259. package/dist/src/shell/cli/friction-report.d.ts.map +1 -1
  260. package/dist/src/shell/cli/friction-report.js +16 -8
  261. package/dist/src/shell/cli/friction-report.js.map +1 -1
  262. package/dist/src/shell/cli/ir-to-spec-fields.d.ts +57 -0
  263. package/dist/src/shell/cli/ir-to-spec-fields.d.ts.map +1 -0
  264. package/dist/src/shell/cli/ir-to-spec-fields.js +169 -0
  265. package/dist/src/shell/cli/ir-to-spec-fields.js.map +1 -0
  266. package/dist/src/shell/cli/main.d.ts +70 -24
  267. package/dist/src/shell/cli/main.d.ts.map +1 -1
  268. package/dist/src/shell/cli/main.js +1138 -165
  269. package/dist/src/shell/cli/main.js.map +1 -1
  270. package/dist/src/shell/cli/normalize-prompt-text.d.ts +67 -0
  271. package/dist/src/shell/cli/normalize-prompt-text.d.ts.map +1 -0
  272. package/dist/src/shell/cli/normalize-prompt-text.js +100 -0
  273. package/dist/src/shell/cli/normalize-prompt-text.js.map +1 -0
  274. package/dist/src/shell/cli/onboarding.d.ts +6 -2
  275. package/dist/src/shell/cli/onboarding.d.ts.map +1 -1
  276. package/dist/src/shell/cli/onboarding.js +89 -23
  277. package/dist/src/shell/cli/onboarding.js.map +1 -1
  278. package/dist/src/shell/cli/quickstart.d.ts +41 -0
  279. package/dist/src/shell/cli/quickstart.d.ts.map +1 -0
  280. package/dist/src/shell/cli/quickstart.js +159 -0
  281. package/dist/src/shell/cli/quickstart.js.map +1 -0
  282. package/dist/src/shell/cli/resolve-spec-path.d.ts +62 -0
  283. package/dist/src/shell/cli/resolve-spec-path.d.ts.map +1 -0
  284. package/dist/src/shell/cli/resolve-spec-path.js +56 -0
  285. package/dist/src/shell/cli/resolve-spec-path.js.map +1 -0
  286. package/dist/src/shell/cli/spec-nl-synth.d.ts +96 -0
  287. package/dist/src/shell/cli/spec-nl-synth.d.ts.map +1 -0
  288. package/dist/src/shell/cli/spec-nl-synth.js +108 -0
  289. package/dist/src/shell/cli/spec-nl-synth.js.map +1 -0
  290. package/dist/src/shell/cli/spec-task-builder.d.ts +114 -0
  291. package/dist/src/shell/cli/spec-task-builder.d.ts.map +1 -0
  292. package/dist/src/shell/cli/spec-task-builder.js +205 -0
  293. package/dist/src/shell/cli/spec-task-builder.js.map +1 -0
  294. package/dist/src/shell/cli/templates.d.ts +142 -0
  295. package/dist/src/shell/cli/templates.d.ts.map +1 -0
  296. package/dist/src/shell/cli/templates.js +449 -0
  297. package/dist/src/shell/cli/templates.js.map +1 -0
  298. package/dist/src/shell/cli/timeline.d.ts +28 -0
  299. package/dist/src/shell/cli/timeline.d.ts.map +1 -0
  300. package/dist/src/shell/cli/timeline.js +117 -0
  301. package/dist/src/shell/cli/timeline.js.map +1 -0
  302. package/dist/src/shell/cli/use-steady.d.ts +196 -17
  303. package/dist/src/shell/cli/use-steady.d.ts.map +1 -1
  304. package/dist/src/shell/cli/use-steady.js +2377 -81
  305. package/dist/src/shell/cli/use-steady.js.map +1 -1
  306. package/dist/src/shell/cli/workflow-inspect-target-tree.d.ts +121 -0
  307. package/dist/src/shell/cli/workflow-inspect-target-tree.d.ts.map +1 -0
  308. package/dist/src/shell/cli/workflow-inspect-target-tree.js +256 -0
  309. package/dist/src/shell/cli/workflow-inspect-target-tree.js.map +1 -0
  310. package/dist/src/shell/cli/workflow-inspect-task-to-ir.d.ts +67 -0
  311. package/dist/src/shell/cli/workflow-inspect-task-to-ir.d.ts.map +1 -0
  312. package/dist/src/shell/cli/workflow-inspect-task-to-ir.js +198 -0
  313. package/dist/src/shell/cli/workflow-inspect-task-to-ir.js.map +1 -0
  314. package/dist/src/shell/cli/workflow-inspect.d.ts +142 -0
  315. package/dist/src/shell/cli/workflow-inspect.d.ts.map +1 -0
  316. package/dist/src/shell/cli/workflow-inspect.js +381 -0
  317. package/dist/src/shell/cli/workflow-inspect.js.map +1 -0
  318. package/dist/src/shell/cli/workflow-outcome-file.d.ts +13 -0
  319. package/dist/src/shell/cli/workflow-outcome-file.d.ts.map +1 -0
  320. package/dist/src/shell/cli/workflow-outcome-file.js +43 -0
  321. package/dist/src/shell/cli/workflow-outcome-file.js.map +1 -0
  322. package/dist/src/shell/cli/workflow-resume-info.d.ts +93 -0
  323. package/dist/src/shell/cli/workflow-resume-info.d.ts.map +1 -0
  324. package/dist/src/shell/cli/workflow-resume-info.js +185 -0
  325. package/dist/src/shell/cli/workflow-resume-info.js.map +1 -0
  326. package/dist/src/shell/cli/workflow-spec-loader.d.ts +69 -0
  327. package/dist/src/shell/cli/workflow-spec-loader.d.ts.map +1 -0
  328. package/dist/src/shell/cli/workflow-spec-loader.js +303 -0
  329. package/dist/src/shell/cli/workflow-spec-loader.js.map +1 -0
  330. package/dist/src/shell/cli/workflow-terminal.d.ts +44 -0
  331. package/dist/src/shell/cli/workflow-terminal.d.ts.map +1 -0
  332. package/dist/src/shell/cli/workflow-terminal.js +69 -0
  333. package/dist/src/shell/cli/workflow-terminal.js.map +1 -0
  334. package/dist/src/shell/defaults.d.ts +8 -0
  335. package/dist/src/shell/defaults.d.ts.map +1 -1
  336. package/dist/src/shell/defaults.js +11 -0
  337. package/dist/src/shell/defaults.js.map +1 -1
  338. package/dist/src/shell/index.d.ts +2 -2
  339. package/dist/src/shell/index.d.ts.map +1 -1
  340. package/dist/src/shell/index.js +2 -2
  341. package/dist/src/shell/index.js.map +1 -1
  342. package/dist/src/shell/render-escape.d.ts +81 -0
  343. package/dist/src/shell/render-escape.d.ts.map +1 -0
  344. package/dist/src/shell/render-escape.js +104 -0
  345. package/dist/src/shell/render-escape.js.map +1 -0
  346. package/dist/src/shell/render.d.ts.map +1 -1
  347. package/dist/src/shell/render.js +3 -1
  348. package/dist/src/shell/render.js.map +1 -1
  349. package/dist/src/shell/repl-guide-presenter.d.ts +25 -0
  350. package/dist/src/shell/repl-guide-presenter.d.ts.map +1 -0
  351. package/dist/src/shell/repl-guide-presenter.js +45 -0
  352. package/dist/src/shell/repl-guide-presenter.js.map +1 -0
  353. package/dist/src/shell/timeline-render.d.ts +16 -0
  354. package/dist/src/shell/timeline-render.d.ts.map +1 -0
  355. package/dist/src/shell/timeline-render.js +170 -0
  356. package/dist/src/shell/timeline-render.js.map +1 -0
  357. package/dist/src/shell/tui/app.d.ts +8 -0
  358. package/dist/src/shell/tui/app.d.ts.map +1 -0
  359. package/dist/src/shell/tui/app.js +5 -0
  360. package/dist/src/shell/tui/app.js.map +1 -0
  361. package/dist/src/shell/tui/components/BlockedReasonPanel.d.ts +21 -0
  362. package/dist/src/shell/tui/components/BlockedReasonPanel.d.ts.map +1 -0
  363. package/dist/src/shell/tui/components/BlockedReasonPanel.js +9 -0
  364. package/dist/src/shell/tui/components/BlockedReasonPanel.js.map +1 -0
  365. package/dist/src/shell/tui/components/ConsensusPanel.d.ts +27 -0
  366. package/dist/src/shell/tui/components/ConsensusPanel.d.ts.map +1 -0
  367. package/dist/src/shell/tui/components/ConsensusPanel.js +14 -0
  368. package/dist/src/shell/tui/components/ConsensusPanel.js.map +1 -0
  369. package/dist/src/shell/tui/components/StepList.d.ts +14 -0
  370. package/dist/src/shell/tui/components/StepList.d.ts.map +1 -0
  371. package/dist/src/shell/tui/components/StepList.js +34 -0
  372. package/dist/src/shell/tui/components/StepList.js.map +1 -0
  373. package/dist/src/shell/tui/components/SystemWillPanel.d.ts +12 -0
  374. package/dist/src/shell/tui/components/SystemWillPanel.d.ts.map +1 -0
  375. package/dist/src/shell/tui/components/SystemWillPanel.js +9 -0
  376. package/dist/src/shell/tui/components/SystemWillPanel.js.map +1 -0
  377. package/dist/src/shell/tui/components/WorkflowView.d.ts +11 -0
  378. package/dist/src/shell/tui/components/WorkflowView.d.ts.map +1 -0
  379. package/dist/src/shell/tui/components/WorkflowView.js +21 -0
  380. package/dist/src/shell/tui/components/WorkflowView.js.map +1 -0
  381. package/dist/src/shell/tui/hooks/useWorkflowState.d.ts +10 -0
  382. package/dist/src/shell/tui/hooks/useWorkflowState.d.ts.map +1 -0
  383. package/dist/src/shell/tui/hooks/useWorkflowState.js +28 -0
  384. package/dist/src/shell/tui/hooks/useWorkflowState.js.map +1 -0
  385. package/dist/src/shell/tui/index.d.ts +8 -0
  386. package/dist/src/shell/tui/index.d.ts.map +1 -0
  387. package/dist/src/shell/tui/index.js +10 -0
  388. package/dist/src/shell/tui/index.js.map +1 -0
  389. package/dist/src/shell/tui/state-bridge.d.ts +37 -0
  390. package/dist/src/shell/tui/state-bridge.d.ts.map +1 -0
  391. package/dist/src/shell/tui/state-bridge.js +137 -0
  392. package/dist/src/shell/tui/state-bridge.js.map +1 -0
  393. package/dist/src/shell/tui/types.d.ts +56 -0
  394. package/dist/src/shell/tui/types.d.ts.map +1 -0
  395. package/dist/src/shell/tui/types.js +9 -0
  396. package/dist/src/shell/tui/types.js.map +1 -0
  397. package/dist/src/shell/workflow-render.d.ts +26 -1
  398. package/dist/src/shell/workflow-render.d.ts.map +1 -1
  399. package/dist/src/shell/workflow-render.js +430 -8
  400. package/dist/src/shell/workflow-render.js.map +1 -1
  401. package/dist/src/ucp/envelope.d.ts +13 -1
  402. package/dist/src/ucp/envelope.d.ts.map +1 -1
  403. package/dist/src/ucp/envelope.js +16 -0
  404. package/dist/src/ucp/envelope.js.map +1 -1
  405. package/dist/src/ucp/mappers/map-json-op-command.d.ts +15 -0
  406. package/dist/src/ucp/mappers/map-json-op-command.d.ts.map +1 -0
  407. package/dist/src/ucp/mappers/map-json-op-command.js +16 -0
  408. package/dist/src/ucp/mappers/map-json-op-command.js.map +1 -0
  409. package/dist/src/ucp/mappers/map-workflow-execution-result.d.ts +16 -0
  410. package/dist/src/ucp/mappers/map-workflow-execution-result.d.ts.map +1 -0
  411. package/dist/src/ucp/mappers/map-workflow-execution-result.js +17 -0
  412. package/dist/src/ucp/mappers/map-workflow-execution-result.js.map +1 -0
  413. package/dist/src/ucp/types.d.ts +28 -1
  414. package/dist/src/ucp/types.d.ts.map +1 -1
  415. package/dist/src/understand/completion/completion.d.ts.map +1 -1
  416. package/dist/src/understand/completion/completion.js +19 -8
  417. package/dist/src/understand/completion/completion.js.map +1 -1
  418. package/dist/src/understand/completion/rules.d.ts +74 -2
  419. package/dist/src/understand/completion/rules.d.ts.map +1 -1
  420. package/dist/src/understand/completion/rules.js +341 -11
  421. package/dist/src/understand/completion/rules.js.map +1 -1
  422. package/dist/src/understand/disambiguation/detectors/missing-context.detector.d.ts.map +1 -1
  423. package/dist/src/understand/disambiguation/detectors/missing-context.detector.js +10 -8
  424. package/dist/src/understand/disambiguation/detectors/missing-context.detector.js.map +1 -1
  425. package/dist/src/understand/intent-interpretation/intent-interpretation.js +6 -6
  426. package/dist/src/understand/intent-interpretation/intent-interpretation.js.map +1 -1
  427. package/dist/src/understand/intent-interpretation/types.d.ts +20 -0
  428. package/dist/src/understand/intent-interpretation/types.d.ts.map +1 -1
  429. package/dist/src/understand/interpretation/parser.d.ts +1 -1
  430. package/dist/src/understand/interpretation/parser.d.ts.map +1 -1
  431. package/dist/src/understand/interpretation/parser.js +93 -15
  432. package/dist/src/understand/interpretation/parser.js.map +1 -1
  433. package/dist/src/understand/interpretation/types.d.ts +11 -0
  434. package/dist/src/understand/interpretation/types.d.ts.map +1 -1
  435. package/dist/src/understand/interpretation/types.js.map +1 -1
  436. package/dist/src/understand/silent-guidance/selector.d.ts +4 -3
  437. package/dist/src/understand/silent-guidance/selector.d.ts.map +1 -1
  438. package/dist/src/understand/silent-guidance/selector.js +18 -3
  439. package/dist/src/understand/silent-guidance/selector.js.map +1 -1
  440. package/dist/src/understand/silent-guidance/templates.d.ts.map +1 -1
  441. package/dist/src/understand/silent-guidance/templates.js +35 -7
  442. package/dist/src/understand/silent-guidance/templates.js.map +1 -1
  443. package/dist/src/understand/silent-guidance/types.d.ts +2 -1
  444. package/dist/src/understand/silent-guidance/types.d.ts.map +1 -1
  445. package/dist/src/utils/credentials.d.ts +70 -0
  446. package/dist/src/utils/credentials.d.ts.map +1 -0
  447. package/dist/src/utils/credentials.js +101 -0
  448. package/dist/src/utils/credentials.js.map +1 -0
  449. package/dist/src/workflow/coordinator.d.ts.map +1 -1
  450. package/dist/src/workflow/coordinator.js +282 -20
  451. package/dist/src/workflow/coordinator.js.map +1 -1
  452. package/dist/src/workflow/index.d.ts +2 -0
  453. package/dist/src/workflow/index.d.ts.map +1 -1
  454. package/dist/src/workflow/index.js +2 -0
  455. package/dist/src/workflow/index.js.map +1 -1
  456. package/dist/src/workflow/resume-content-hash.d.ts +21 -0
  457. package/dist/src/workflow/resume-content-hash.d.ts.map +1 -0
  458. package/dist/src/workflow/resume-content-hash.js +33 -0
  459. package/dist/src/workflow/resume-content-hash.js.map +1 -0
  460. package/dist/src/workflow/resume-token-builder.d.ts +54 -0
  461. package/dist/src/workflow/resume-token-builder.d.ts.map +1 -0
  462. package/dist/src/workflow/resume-token-builder.js +71 -0
  463. package/dist/src/workflow/resume-token-builder.js.map +1 -0
  464. package/dist/src/workflow/resume-token-io.d.ts +99 -0
  465. package/dist/src/workflow/resume-token-io.d.ts.map +1 -0
  466. package/dist/src/workflow/resume-token-io.js +198 -0
  467. package/dist/src/workflow/resume-token-io.js.map +1 -0
  468. package/dist/src/workflow/resume-token-types.d.ts +131 -0
  469. package/dist/src/workflow/resume-token-types.d.ts.map +1 -0
  470. package/dist/src/workflow/resume-token-types.js +36 -0
  471. package/dist/src/workflow/resume-token-types.js.map +1 -0
  472. package/dist/src/workflow/resume-token-validator.d.ts +48 -0
  473. package/dist/src/workflow/resume-token-validator.d.ts.map +1 -0
  474. package/dist/src/workflow/resume-token-validator.js +161 -0
  475. package/dist/src/workflow/resume-token-validator.js.map +1 -0
  476. package/dist/src/workflow/resume-verifier-types.d.ts +104 -0
  477. package/dist/src/workflow/resume-verifier-types.d.ts.map +1 -0
  478. package/dist/src/workflow/resume-verifier-types.js +19 -0
  479. package/dist/src/workflow/resume-verifier-types.js.map +1 -0
  480. package/dist/src/workflow/resume-verifier.d.ts +75 -0
  481. package/dist/src/workflow/resume-verifier.d.ts.map +1 -0
  482. package/dist/src/workflow/resume-verifier.js +335 -0
  483. package/dist/src/workflow/resume-verifier.js.map +1 -0
  484. package/dist/src/workflow/spec-hash.d.ts +76 -0
  485. package/dist/src/workflow/spec-hash.d.ts.map +1 -0
  486. package/dist/src/workflow/spec-hash.js +116 -0
  487. package/dist/src/workflow/spec-hash.js.map +1 -0
  488. package/dist/src/workflow/team-policy-pack.d.ts +37 -0
  489. package/dist/src/workflow/team-policy-pack.d.ts.map +1 -0
  490. package/dist/src/workflow/team-policy-pack.js +107 -0
  491. package/dist/src/workflow/team-policy-pack.js.map +1 -0
  492. package/dist/src/workflow/types.d.ts +117 -3
  493. package/dist/src/workflow/types.d.ts.map +1 -1
  494. package/package.json +56 -7
  495. package/dist/server-admin.d.ts +0 -11
  496. package/dist/server-admin.d.ts.map +0 -1
  497. package/dist/server-admin.js +0 -188
  498. package/dist/server-admin.js.map +0 -1
  499. package/dist/src/shell/cli/friction-admin.d.ts +0 -14
  500. package/dist/src/shell/cli/friction-admin.d.ts.map +0 -1
  501. package/dist/src/shell/cli/friction-admin.js +0 -276
  502. package/dist/src/shell/cli/friction-admin.js.map +0 -1
  503. package/ui/README.md +0 -73
  504. package/ui/dist/ai.txt +0 -14
  505. package/ui/dist/apple-icon.png +0 -0
  506. package/ui/dist/assets/index-C_i9832M.js +0 -268
  507. package/ui/dist/assets/index-D_rglT6E.css +0 -2
  508. package/ui/dist/favicon-16.png +0 -0
  509. package/ui/dist/favicon-32.png +0 -0
  510. package/ui/dist/favicon.svg +0 -22
  511. package/ui/dist/icon-192.png +0 -0
  512. package/ui/dist/icon-512.png +0 -0
  513. package/ui/dist/icon.png +0 -0
  514. package/ui/dist/icons.svg +0 -24
  515. package/ui/dist/index.html +0 -19
  516. package/ui/dist/robots.txt +0 -71
package/CHANGELOG.md ADDED
@@ -0,0 +1,2527 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0-alpha.70 - USESTEADY_STORE_DIR read/write parity (P2 trust/friction patch)
4
+
5
+ ### Summary
6
+
7
+ Patch release. Centralizes `USESTEADY_STORE_DIR` resolution so `run`, `history`,
8
+ `timeline`, and `doctor` read and write the same UCP store when the env var is
9
+ set. Unset-env behavior unchanged. No migration or multi-store support.
10
+
11
+ ### What changed
12
+
13
+ - Honor `USESTEADY_STORE_DIR` across CLI workflow write/read paths (#380).
14
+ - Add shared `resolveStoreDir()` in `src/shell/defaults.ts`.
15
+ - Resume tokens remain workspace-local; explicit `history <store-dir>` override unchanged.
16
+ - No parser, LLM, approval, or execution expansion.
17
+
18
+ ## 0.1.0-alpha.69 - CLI/Web recovery parity (P1 consistency patch)
19
+
20
+ ### Summary
21
+
22
+ Patch release. Aligns CLI vague natural-language recovery with the web UI's
23
+ existing `skipped_by_intake` path. Recovery-eligible `parse_error` inputs
24
+ enter workflow intake recovery instead of hard-failing at spec load or
25
+ `--prompt` normalize. No new capability.
26
+
27
+ ### What changed
28
+
29
+ - Align CLI vague NL recovery with web `skipped_by_intake` behavior.
30
+ - Allow recovery-eligible `parse_error` tasks to enter workflow recovery instead of hard-failing at load.
31
+ - Preserve safety behavior for destructive vague inputs (skipped, not executed).
32
+ - Keep R4 `ambiguous_match` hard-fail behavior unchanged.
33
+ - No parser, LLM, approval, or execution expansion.
34
+
35
+ ## 0.1.0-alpha.68 - History bulk-read index drift hardening
36
+
37
+ ### Summary
38
+
39
+ Patch release. Hardens bulk history reads so `usesteady history` and
40
+ `usesteady timeline --last` tolerate misindexed UCP store entries without
41
+ throwing. No new capability.
42
+
43
+ ### What changed
44
+
45
+ - Fix `usesteady history` crash when workflow_run index contains misindexed envelopes.
46
+ - Fix `usesteady timeline --last` crash on stores with index drift.
47
+ - Preserve valid workflow runs while skipping invalid index entries.
48
+ - No new capability.
49
+
50
+ ## 0.1.0-alpha.67 - Read-only workflow timeline
51
+
52
+ ### Summary
53
+
54
+ Adds `usesteady timeline`, a read-only chronological view of one terminal
55
+ workflow run. v1.1 extends the command with an honest incomplete-run banner
56
+ when no terminal workflow record exists and with `--output json` for scripts.
57
+ Timeline remains zero-authority: no resume, no replay, no live-runs parsing,
58
+ no RunTimeline merge, and no execution changes.
59
+
60
+ ### What changed
61
+
62
+ - Add `usesteady timeline --last`.
63
+ - Add `usesteady timeline --run-id <id>`.
64
+ - Add incomplete-run banner for missing terminal workflow records.
65
+ - Add `usesteady timeline --output json`.
66
+ - Keep timeline read-only: no resume, no replay, no live-runs parsing, no RunTimeline merge, no execution changes.
67
+
68
+ ## 0.1.0-alpha.66 - npm README image rendering fix
69
+
70
+ ### Summary
71
+
72
+ Packaging-only release. Updates the npm registry README so demo images render
73
+ on registry.npmjs.org. No runtime, CLI, workflow, doctor, or execution behavior
74
+ changes relative to `0.1.0-alpha.65`.
75
+
76
+ ### What changed
77
+
78
+ - Fix npm README image rendering by replacing package-relative demo image paths with absolute raw GitHub URLs.
79
+ - No runtime, CLI, workflow, doctor, or execution behavior changes.
80
+
81
+ ## 0.1.0-alpha.64 - Governed kernel widening: workflow inspect, resume tokens, bounded node -e replay
82
+
83
+ ### Summary
84
+
85
+ This release widens the governed kernel layer along three independent
86
+ axes -- workflow inspect, resume tokens, and bounded `node -e` inline JS
87
+ replay -- without changing any public-wire contract. The published CLI
88
+ shape, JSON adapter schema, capability advertisement, and rejection
89
+ diagnostics are byte-identical to alpha.63 for every input the prior
90
+ release accepted. Operators upgrading from alpha.63 see new surfaces
91
+ appear; nothing previously working changes shape.
92
+
93
+ The kernel work is the headline. K6 closes the bounded-`node -e`
94
+ replayability question that K1-K5 deferred: a tightly constrained
95
+ subset of `node -e "<BODY>"` invocations are now deterministically
96
+ replayable under `usesteady replay --execute`. Everything outside that
97
+ closed structural predicate continues to refuse, with the refusal
98
+ reason refined for diagnosability. K5 echo byte-for-byte preservation
99
+ is restored after a transient byte-layer regression introduced during
100
+ K6 implementation.
101
+
102
+ ### What changed (user-visible)
103
+
104
+ **1. Kernel -- K6: bounded `node -e` deterministic replay.**
105
+
106
+ A new closed structural predicate admits `node -e "<BODY>"` invocations
107
+ for replay-under-execution when `<BODY>` is one of five `console.log`
108
+ atom forms (single-quoted string, signed integer literal, boolean
109
+ literal, `null` literal; the double-quoted string form is admissible by
110
+ the inline-JS predicate but unreachable via the v1.0 wire-level quoting
111
+ of the outer command). Two-gate defense in depth: a token denylist
112
+ (`require`, `process`, `fs`, `eval`, `Date`, `Math.random`, ...) and a
113
+ syntax denylist (backticks, `${`, `//`, `/*`, optional chaining,
114
+ dynamic property access) both run before the closed allow-list. The
115
+ K6 prefix probe runs before the K5 denylist so the leading `node -e "`
116
+ shape is not collaterally refused by K5's shell-metacharacter screen.
117
+ Full design contract: `docs/KERNEL_RUN_COMMAND_K6_DESIGN.md` v1.0.
118
+
119
+ **2. Kernel -- new refusal reason `non_deterministic_inline_js`.**
120
+
121
+ `ExecutionReplayVerdict.refused.reason` and `ClassifierResult.reason`
122
+ gain the value `"non_deterministic_inline_js"`. Emitted when a command
123
+ matches the K6 `node -e "<BODY>"` prefix shape but its body fails the
124
+ inline-JS predicate (denied token, denied syntax fragment, or unmatched
125
+ allow-list atom). Out-of-scope `node` invocations that do not match
126
+ the K6 prefix shape (`node -p`, `node script.js`, etc.) continue to
127
+ refuse with the existing K5-era reason `"non_deterministic_command"`.
128
+ All `switch` sites on these discriminated unions are exhaustively
129
+ updated; TypeScript exhaustiveness guarantees no default fallthrough
130
+ hides a missing branch.
131
+
132
+ **3. Kernel -- K6 execution is host-shell-free (`shell: false`).**
133
+
134
+ K6 inline-JS replay invokes `spawnSync('node', ['-e', body], { shell:
135
+ false, cwd: <K4-sandbox>, ... })`. The `shell: false` flag is the K6
136
+ hermeticity invariant: the body string is never reparsed by an
137
+ intermediate host shell, so no platform-specific quoting, glob, or
138
+ metacharacter expansion can mutate observable behavior between
139
+ artifact capture and replay. Execution still binds to the K4 sandbox
140
+ `cwd`; no `KernelResult` widening for stdout, stderr, or exit code.
141
+
142
+ **4. Kernel -- K5 echo byte-for-byte spawn preservation restored.**
143
+
144
+ The K6 implementation transiently widened the K5 `echo` executor to
145
+ spawn the trimmed form of the command instead of the raw command
146
+ bytes from the spec. Observable behavior was identical across every
147
+ supported host shell (all strip surrounding whitespace before
148
+ parsing), but the strict byte-for-byte K5 contract from alpha.59 was
149
+ technically violated. Alpha.64 restores the original byte-preservation
150
+ behavior and pins it with a regression-guard test for whitespace-
151
+ padded `echo` invocations.
152
+
153
+ **5. New CLI surface -- `usesteady workflow inspect <spec>` (P7-min).**
154
+
155
+ A read-only structural-inspection surface for `WorkflowSpec` files.
156
+ Renders the per-task target tree and IR mapping for a spec without
157
+ executing, persisting state, or producing a `KernelArtifact`. Useful
158
+ for validating spec shape before commit, for triaging
159
+ `run <spec.json>` failures, and for review-time spec audits. The
160
+ surface is purely additive: not invoked by any existing flow, never
161
+ mutates filesystem state, and never advertises beyond its own help
162
+ text.
163
+
164
+ **6. New CLI surface -- P2-min resume tokens.**
165
+
166
+ A new resume-token builder, validator, and verifier provide
167
+ survivability for long-running workflows without hidden continuation
168
+ state. Operators can capture a workflow's mid-run state into an
169
+ explicit resume token, inspect it via `usesteady workflow
170
+ resume-info <token>`, and feed it back to resume execution. No
171
+ existing `--prompt` / `run <spec.json>` invocation changes shape; the
172
+ resume surface is opt-in and additive.
173
+
174
+ **7. Public-surface productization: survivability wedge.**
175
+
176
+ `README.md`, the marketing landing surface, and the npm description
177
+ field are aligned to the survivability + governed-replay wedge.
178
+ Em-dash and arrow glyphs replaced with ASCII per encoding governance
179
+ (no public-facing file regresses ASCII-cleanliness). Deterministic
180
+ demo recording assets shipped under `docs/demo/` and
181
+ `marketing/public/demo/`: one hero `multistep-refactor` demo plus a
182
+ four-part survivability sequence (kill-mid-run, diverged-fs,
183
+ non-idempotent, resume-info), each as `.cast`, `.svg`, `.preview.svg`,
184
+ and `.session.txt` so all rendering paths are reproducible. Public
185
+ demo links repointed to anonymous-reachable URLs (P0 marketing fix).
186
+
187
+ **8. No public-wire breaks.**
188
+
189
+ `KernelResult` shape, the `--json` op schema, `usesteady capabilities`
190
+ output (text and JSON), and rejection-message structure are
191
+ byte-identical to alpha.63 for every input the prior release
192
+ accepted. No CLI flag has been retired or renamed. No JSON adapter
193
+ field has been retired or renamed. The K6 widening expands which
194
+ commands `replay --execute` admits without changing the response
195
+ shape for either the admit path (verdict `match` / `mismatch`) or the
196
+ refuse path (verdict `refused` -- the `reason` enum now carries one
197
+ additional value `non_deterministic_inline_js`, but all prior values
198
+ remain emitted unchanged).
199
+
200
+ ### Files added / changed (release-relevant)
201
+
202
+ - `src/kernel/inline-js-classifier.ts` -- NEW. Closed structural
203
+ predicate for K6 inline-JS bodies plus the command-shape prefix
204
+ probe and body extraction.
205
+ - `src/kernel/command-classifier.ts` -- K6 routing precedence + new
206
+ `InScopeCommand` discriminated union for the executor.
207
+ - `src/kernel/classifier.ts` -- K6 refusal-reason precedence.
208
+ - `src/kernel/execution-replay.ts` -- K6 `node -e` execution path
209
+ (`shell: false`) + K5 echo byte-preservation restoration.
210
+ - `src/kernel/types.ts` -- additive widening of
211
+ `ExecutionReplayVerdict.refused.reason` and `ClassifierResult.reason`.
212
+ - `src/shell/cli/use-steady.ts` -- help-text refresh for K6 shape;
213
+ workflow inspect + resume-info surfaces.
214
+ - `src/shell/cli/workflow-inspect*.ts`, `workflow-resume-info.ts`,
215
+ `workflow-spec-loader.ts` -- new workflow inspect and resume-info
216
+ surfaces (P7-min, P2-min).
217
+ - `src/workflow/resume-token-*.ts`, `resume-verifier*.ts` -- new
218
+ resume-token builder, validator, verifier.
219
+ - `tests/kernel/inline-js-classifier.test.ts` -- NEW. 90+ unit tests.
220
+ - `tests/kernel/{classifier, command-classifier, execution-replay}.test.ts`
221
+ -- additive K6 sections plus K5 byte-preservation regression guard.
222
+ - `tests/shell/workflow-inspect*.test.ts`,
223
+ `tests/shell/workflow-resume-*.test.ts`,
224
+ `tests/workflow/resume-*.test.ts` -- new workflow inspect and resume
225
+ test suites.
226
+ - `docs/KERNEL_RUN_COMMAND_K6_DESIGN.md` -- v1.0 design contract.
227
+ - `docs/product/k6-kickoff-report-v1.md`,
228
+ `p2-min-resume-token-design-v1.md`,
229
+ `p7-min-workflow-inspect-design-v1.md`,
230
+ `governed-workflow-primitives-investigation-v1.md`,
231
+ `workflow-survivability-pressure-report-v1.md`,
232
+ `public-launch-pack-v1.md`,
233
+ `messaging-compression-v1.md`,
234
+ `launch-thread-v1.md` -- design and product docs.
235
+ - `docs/demo/`, `marketing/public/demo/` -- deterministic demo
236
+ recording assets (hero + four-part survivability).
237
+ - `README.md`, `marketing/src/pages/Landing.tsx`, `package.json`
238
+ description -- survivability-wedge productization, ASCII encoding.
239
+
240
+ ### Out of scope for alpha.64
241
+
242
+ - No K7 work.
243
+ - No timeout policy on K6 execution.
244
+ - No multi-segment shell support.
245
+ - No `stdout` / `stderr` / `exitCode` persistence in `KernelResult`.
246
+ - No public-product surface changes beyond the additive workflow
247
+ inspect, resume-info, and demo / marketing routing.
248
+
249
+ ## 0.1.0-alpha.63 - JSON adapter publication-truthfulness alignment
250
+
251
+ ### Publication-truthfulness consolidation after alpha.62's #45 fix
252
+
253
+ This release consolidates the publication-truthfulness work shipped in
254
+ alpha.62. The alpha.62 fix made the executor and validator tell the truth
255
+ about which `replace` occurrence directives the runtime actually honors;
256
+ alpha.63 makes the JSON adapter's *rejection messages* and the published
257
+ `replace` *example* tell the same truth.
258
+
259
+ This release does **not** close a `usesteady-public` friction issue. No
260
+ `status/accepted` issues transition in this release. It is an internal
261
+ publication-surface alignment, framed accurately so prior friction
262
+ closures are not back-credited.
263
+
264
+ ### What changed (user-visible)
265
+
266
+ **1. Missing-field diagnostic on `--json` / `batch` rejection.**
267
+
268
+ Before alpha.63, a malformed JSON op produced a generic stderr line:
269
+
270
+ Error: unknown or invalid operation: {"type":"replace","to":"NEW","file":"x.ts"}
271
+ See `usesteady capabilities` for the full per-op JSON schema
272
+ ...
273
+
274
+ The operator had to consult `usesteady capabilities` to discover which
275
+ required field was missing. Alpha.63 names the specific missing
276
+ **public-wire** field inline:
277
+
278
+ Error: unknown or invalid operation: {"type":"replace","to":"NEW","file":"x.ts"}
279
+ op type "replace" requires field "from" but it was not provided.
280
+ See `usesteady capabilities` for the full per-op JSON schema
281
+ ...
282
+
283
+ The diagnostic uses the exact key the operator would type. This matters
284
+ because several public-wire field names diverge from IR-canonical names
285
+ (legacy DraftTask naming preserved per design note section 10 #7):
286
+
287
+ - `create_dir` missing `path` -> diagnostic names `"path"`, not `"file"`.
288
+ - `run` missing `to` -> diagnostic names `"to"`, not `"command"`.
289
+ - `append` / `prepend` missing `to` -> diagnostic names `"to"`, not `"text"`.
290
+
291
+ The diagnostic appears only when a specific required public-wire field is
292
+ absent (or present-but-not-a-string). For content-level rejections (empty
293
+ strings after trim, invalid `occurrence` shape) and structural cases
294
+ (non-object input, missing/invalid `type`, unknown op type) the existing
295
+ generic message remains correct and is emitted unchanged.
296
+
297
+ **2. Published `replace` example carries `occurrence:"first"`.**
298
+
299
+ `usesteady capabilities` text + JSON output, the `HELP_TEXT` JSON op
300
+ schema block, and the README capabilities sample now all show:
301
+
302
+ {"type":"replace","file":"src/Button.tsx","from":"old text","to":"new text","occurrence":"first"}
303
+
304
+ Using `"first"` makes the example a *working* invocation. The capabilities
305
+ summary continues to disclose -- byte-identical to alpha.62 -- that
306
+ `"all"` and `{ index: N }` are refused at validate stage. The example
307
+ shift does not erase that disclosure; it complements it by demonstrating
308
+ the directive that *does* round-trip.
309
+
310
+ ### What did NOT change
311
+
312
+ **1. Accept/reject boundary unchanged.**
313
+
314
+ `jsonOpToIROperation` is byte-identical to alpha.62. Every JSON op that
315
+ alpha.62 accepted is still accepted byte-for-byte. Every JSON op that
316
+ alpha.62 rejected is still rejected. The new `diagnoseInvalidJsonOp`
317
+ helper is consulted only *after* `jsonOpToIROperation` has already
318
+ returned `null`, to enrich the stderr text. It does not gate anything.
319
+ The byte-for-byte parity is pinned by the legacy
320
+ `json-to-ir.identical-behavior.test.ts` suite.
321
+
322
+ **2. JSON output payload for rejections unchanged.**
323
+
324
+ `{ "success": false, "error": "invalid_op" }` is the rejection payload on
325
+ `--output json`, byte-identical to alpha.62. The diagnostic enrichment
326
+ lives on stderr only. Programmatic consumers that match on
327
+ `obj.error === "invalid_op"` continue to work without change.
328
+
329
+ **3. Unknown extra-field tolerance unchanged.**
330
+
331
+ A JSON op carrying an unrecognized key (for example,
332
+ `{"type":"create","file":"x.ts","garbageField":123}`) is still accepted
333
+ and the extra key is silently dropped, exactly as in alpha.62. Alpha.63
334
+ introduces no unknown-field rejection. Tightening that surface would be
335
+ a public-contract change and is explicitly deferred.
336
+
337
+ **4. `op-registry.ts` untouched and remains non-authoritative.**
338
+
339
+ The IR-canonical OperationRegistry has not changed. The new
340
+ `public-json-schema.ts` companion sits *beside* the registry, records
341
+ public-wire field names (which intentionally diverge from IR-canonical
342
+ names for several ops), and is **descriptive-only**:
343
+
344
+ - Not consumed by the executor.
345
+ - Not consumed by the validator (`feasibility-validator.ts`).
346
+ - Not consumed by the NL parser (`nl-to-ir.ts`).
347
+ - Not consumed by the workflow coordinator.
348
+ - Not consumed by UCP mappers.
349
+
350
+ It is consumed solely by `json-to-ir.ts`'s diagnostic helper. The
351
+ boundary is pinned by contract tests asserting both frozenness and the
352
+ public-wire-vs-IR divergence per op.
353
+
354
+ **5. No occurrence-aware replace execution.**
355
+
356
+ Executor surfaces in `src/execution/` are untouched. Occurrence-aware
357
+ `replace` (the Option B from the #45 investigation) is not in this
358
+ release. `occurrence:"first"` flows through the executor exactly as it
359
+ did in alpha.62; `"all"` and `{ index: N }` continue to be refused at
360
+ validate stage with the alpha.62 truthfulness signaling.
361
+
362
+ ### Out of scope (deliberate)
363
+
364
+ - **No friction closure.** No `status/accepted` -> `status/shipped`
365
+ transition. The alpha.62 #45 closure stands; alpha.63 does not
366
+ re-credit it.
367
+ - **No registry authority expansion.** R-alpha-full / registry-driven
368
+ required/optional validation is explicitly deferred per the R-alpha
369
+ investigation recommendation.
370
+ - **No NL surface changes.** `nl-to-ir.ts` is untouched.
371
+ - **No feasibility-validator changes.**
372
+ - **No UCP mapper widening.**
373
+ - **No `create.contents` exposure/removal.**
374
+ - **No timeline / doctor / K6 / marketing-site work.**
375
+ - **No dependency bumps.**
376
+ - **No HELP_TEXT auto-generation.** The one-line `replace`-example
377
+ update in HELP_TEXT was the minimal manual sync to match the
378
+ capabilities catalog.
379
+
380
+ ### Verification
381
+
382
+ - `npm run build` clean.
383
+ - `npm run release:gate` 148 files / 5496 passed / 4 skipped / 0 failed.
384
+ - No dependency drift since `v0.1.0-alpha.62`.
385
+ - Cross-surface regression: alpha.60 protected-paths (309 tests),
386
+ alpha.60 #42 OCD warning truthfulness (38 tests), alpha.61 #49
387
+ create_dir truthfulness (169 tests), alpha.62 #45 occurrence
388
+ truthfulness (52 tests) all green on the alpha.63 candidate.
389
+
390
+ ### Files changed since `v0.1.0-alpha.62`
391
+
392
+ - `src/input/public-json-schema.ts` (new, descriptive companion)
393
+ - `src/input/json-to-ir.ts` (additive: imports companion, exports
394
+ `diagnoseInvalidJsonOp`; existing functions byte-identical)
395
+ - `src/shell/cli/use-steady.ts` (HELP_TEXT replace example +
396
+ rejection-path stderr enrichment in `processJsonInput`)
397
+ - `src/shell/cli/capabilities.ts` (PUBLIC_JSON_EXAMPLES.replace adds
398
+ `occurrence:"first"`)
399
+ - `README.md` (capabilities sample replace example mirrors catalog)
400
+ - `tests/input/public-json-schema.test.ts` (new contract suite)
401
+ - `tests/input/json-to-ir.test.ts` (new diagnoseInvalidJsonOp suites,
402
+ accept/reject parity re-pinned)
403
+ - `tests/shell/capabilities.test.ts` (new R-alpha-min pins)
404
+ - `tests/shell/json-input.test.ts` (new CLI-surface R-alpha-min suite)
405
+
406
+ ### Issue mapping
407
+
408
+ | Item | Disposition |
409
+ |---|---|
410
+ | `usesteady-public` issues closed | none |
411
+ | Status label transitions | none |
412
+ | Indirect linkage | Consolidates alpha.62's [`usesteady-public#45`](https://github.com/shortgigs/usesteady-public/issues/45) (already `status/shipped`) by closing the *internal* publication-truthfulness gap identified in the R-alpha investigation. |
413
+
414
+ ## 0.1.0-alpha.62 - replace occurrence-directive truthfulness
415
+
416
+ ### Execution truthfulness: replace occurrence directives are no longer silently ignored
417
+
418
+ Addresses [shortgigs/usesteady-public#45](https://github.com/shortgigs/usesteady-public/issues/45)
419
+ (P1, `status/accepted`). Bounded fix only -- the executor still does not
420
+ honor occurrence selection; this delta makes the system tell the truth
421
+ about that.
422
+
423
+ **Pre-fix behavior (alpha.61 and earlier).** Users who specified an
424
+ occurrence directive on a replace -- "first occurrence" / "all
425
+ occurrences" / "third occurrence" via natural language, or
426
+ `{"occurrence":"all"}` / `{"occurrence":{"index":3}}` via `--json` /
427
+ `batch` -- ran into one of three misleading failure modes:
428
+
429
+ - **NL surface, "first" + multi-match file:** generic
430
+ `ambiguous_match` from the executor with no acknowledgment that the
431
+ user's "first" directive was even seen.
432
+ - **NL surface, "all" / N-th:** refused at spec-load with a diagnostic
433
+ that pointed the user at *"the IR-shape replace op (via --json /
434
+ batch) which carries full occurrence semantics"* -- but the JSON
435
+ adapter silently stripped `occurrence` at parse, so following the
436
+ pointer led to the same generic `ambiguous_match` refusal.
437
+ - **JSON / batch surface, any `occurrence`:** silently dropped at
438
+ parse. The `usesteady capabilities` output advertised the field as
439
+ optional and listed `first | all | { index }` as accepted shapes,
440
+ even though only first-match behavior reached the executor.
441
+
442
+ **Post-fix behavior.** The IR carries the user's explicit directive on
443
+ a new optional `requestedOccurrence` slot, populated only when the user
444
+ actually said so (NL surface always; JSON surface only when the public
445
+ op contained the field). The feasibility validator now refuses at
446
+ validate stage when that slot is "all" or `{ index: N }`, with a
447
+ diagnostic that quotes the directive verbatim and points at
448
+ `usesteady-public#45`. "first" still flows through to the executor
449
+ unchanged. The `--output json` payload surfaces `requested_occurrence`
450
+ on these refusals so machine consumers can see what the user asked for.
451
+
452
+ Concretely:
453
+
454
+ - **NL surface.**
455
+ - `... first occurrence` on a 1-match file: unchanged (executor
456
+ succeeds).
457
+ - `... first occurrence` on a >1-match file: unchanged (executor
458
+ refuses with `ambiguous_match`).
459
+ - `... all occurrences` / `... 3rd occurrence`: refused at
460
+ spec-load. Diagnostic now reads *"replace with `all occurrences`
461
+ is not yet supported. The executor does not honor occurrence
462
+ selection today (the replace step picks the first match and
463
+ refuses with `ambiguous_match` when more than one exists).
464
+ Tracked at usesteady-public#45. Workaround: narrow `from` to a
465
+ unique span in the file, or apply the change manually for now."*
466
+ The misleading `--json` / `batch` pointer is gone.
467
+ - **JSON / batch surface.**
468
+ - No `occurrence` field: byte-identical to pre-fix (preserves
469
+ legacy behavior for callers who don't opt in).
470
+ - `"occurrence":"first"`: passes through to the executor; same
471
+ result as no field on multi-match files.
472
+ - `"occurrence":"all"` / `"occurrence":{"index":N}`: refused at
473
+ validate stage. JSON payload:
474
+ `{"success":false,"error":"ambiguous_match","requested_occurrence":"all"}`
475
+ (or `"3rd"`, `"22nd"`, etc.).
476
+ - Invalid `occurrence` shape (unknown string, non-integer index,
477
+ zero/negative index, array, etc.): the whole op is rejected
478
+ upstream as `invalid_op` rather than silently stripping the
479
+ field. This closes the "advertise it, drop it" trap that the
480
+ original friction described.
481
+ - **`usesteady capabilities` output.** The `replace` summary now
482
+ truthfully describes the support state:
483
+ *"Replace `<from>` with `<to>` in `<file>`. The optional
484
+ `occurrence` field is parsed but the executor does not yet honor
485
+ occurrence selection (only "first" passes through; "all" and
486
+ `{ index: N }` are refused at validate stage). Tracked at
487
+ usesteady-public#45."*
488
+
489
+ **What this PR does not change.**
490
+
491
+ - **Executor authority is unchanged.** The replace executor still
492
+ picks the first match and refuses with `ambiguous_match` on >1
493
+ matches. `requestedOccurrence` is diagnostics / preview only --
494
+ `WorkflowTaskSpec.structuredReplace` does not gain an occurrence
495
+ slot, and the in-process adapter does not branch on the new field.
496
+ - **No new public `CliErrorCode`.** The validate-stage refusal reuses
497
+ `ambiguous_match` (design note 6.5.1 rule 3 / 6.6.1 rule 7).
498
+ - **No exit-code drift.** The refusal still exits with status 1.
499
+ - **No new approval / refusal semantics.** "first" still reaches the
500
+ executor; only "all" and `{ index: N }` refuse earlier than before.
501
+ - **Public JSON schema is unchanged.** `occurrence` was already in
502
+ `optional` for `replace`; it remains there.
503
+ - **Out of scope:** full occurrence-aware execution (would require a
504
+ new `WorkflowTaskSpec.structuredReplace.occurrence` slot, an
505
+ adapter-side `n-th match` algorithm, and replay-artifact-schema
506
+ coordination -- deferred).
507
+
508
+ **Coverage added.** NL paths verify `requestedOccurrence` is mirrored
509
+ from the parsed clause for `all` and `Nth`; JSON-to-IR pins the
510
+ absent/first/all/index parsing and the invalid-shape rejection; the
511
+ validator pins the new refusal with the ordinal-suffix wording
512
+ ("1st" / "3rd" / "11th" / "22nd"); end-to-end `--output json` tests
513
+ pin the JSON payload shape with and without `requested_occurrence`
514
+ present, and verify that "first" still flows through; the op-registry
515
+ test pins the truthful summary and explicitly forbids the old
516
+ `first | all | { index }` phrasing.
517
+
518
+ ## 0.1.0-alpha.61 - create_dir execution-truthfulness alignment
519
+
520
+ **Released:** May 2026
521
+ **npm tag:** `alpha` - `npm install -g usesteady@alpha`
522
+
523
+ Post-alpha.60 delta. Closes 1 accepted friction across 1 trust surface:
524
+ execution truthfulness (#49). No new public `CliErrorCode`, no new
525
+ approval semantics, no new operation type, no exit-code change.
526
+
527
+ Included PR: [#322](https://github.com/shortgigs/usesteady-core/pull/322).
528
+ No other deltas since alpha.60 (`a6c1264`) other than the release-
529
+ process documentation merged via [#321](https://github.com/shortgigs/usesteady-core/pull/321)
530
+ (`docs/RELEASE.md` -- process hygiene, no product surface impact).
531
+
532
+ This is also the first release under the
533
+ [`docs/RELEASE.md`](./docs/RELEASE.md) runbook merged after the
534
+ alpha.41-alpha.60 release-hygiene postmortem. The V1-V5 post-publish
535
+ verification block in the release PR exists to prove
536
+ publish-success-implies-release-success, addressing the silent
537
+ alpha-dist-tag and git-tag drift identified in that postmortem.
538
+
539
+ ### Execution truthfulness: `create_dir` aligns with `create` on `target_exists`
540
+
541
+ Closes [shortgigs/usesteady-public#49](https://github.com/shortgigs/usesteady-public/issues/49)
542
+ (P2, `status/accepted` since alpha.58).
543
+
544
+ **Pre-fix behavior (alpha.59 and earlier).** `create_dir` against an
545
+ existing directory was not refused at the feasibility validator, and the
546
+ in-process adapter called `mkdirSync(..., { recursive: true })`, which
547
+ silently succeeds on `EEXIST`. The run then reported
548
+ `{"success":true,"error":null,...}` on `--output json` (and "Completed
549
+ successfully" on the text path) for a no-op. Files inside the existing
550
+ directory were untouched -- there was no destructive side effect -- but
551
+ the success banner lied about what happened, breaking the
552
+ execution-truthfulness contract that `create` (write_file) has held since
553
+ M3.
554
+
555
+ **Post-fix behavior.** Both the feasibility validator (primary
556
+ enforcement) and the in-process adapter (defense-in-depth, mirroring the
557
+ S2/#36 and Cluster B Iter 4 / #60-#67 posture) refuse `create_dir`
558
+ against an existing path with the existing public `target_exists`
559
+ `CliErrorCode` -- the same code `create` (write_file) already used for
560
+ the analogous shape. `--output json` now emits
561
+ `{"success":false,"error":"target_exists",...}` and the text path
562
+ prints "Refusing to create directory: target already exists at <abs>"
563
+ before the executor is reached.
564
+
565
+ **Scope discipline (mirrors PR review-posture).**
566
+
567
+ - No new public `CliErrorCode`: `target_exists` already covered `create`
568
+ and `rename`; this fix extends it to `create_dir` without inventing
569
+ new vocabulary.
570
+ - No new approval-bypass affordance, no new exit code, no execution-
571
+ summary widening, no new operation type.
572
+ - No new symlink check on `create_dir` (would be a new refusal class).
573
+ `existsSync` follows symlinks, so a symlink that resolves to an
574
+ existing path is caught via the same code path; a symlink to a
575
+ non-existent target still passes this check (pre-existing behavior,
576
+ unchanged).
577
+ - Nested-directory behavior preserved: only the leaf is probed. For a
578
+ new leaf whose parents do not yet exist, the executor's
579
+ `mkdirSync(..., { recursive: true })` still creates parents in one
580
+ shot. Only the case where the leaf path itself already exists is
581
+ refused.
582
+ - No work on [#45](https://github.com/shortgigs/usesteady-public/issues/45)
583
+ (occurrence-directive divergence on replace ops, P1) -- that is a
584
+ separate PR with a different shape.
585
+
586
+ **Tests.** Validator-stage refusal of `create_dir` on existing empty
587
+ directory, existing populated directory (with files preserved), happy
588
+ path of fresh leaf, happy path of fresh nested leaf, happy path of
589
+ fresh leaf with existing parents; ordering against `prohibited_path`
590
+ and `invalid_filename_chars` (more-specific refusals still win);
591
+ public-code parity with `create`. Adapter-stage defense-in-depth
592
+ covering all of the above plus the file-at-target case (existing file
593
+ occupies the target path -- no clobber, refused with `target_exists`).
594
+ End-to-end CLI test on `--json --output json` confirms exit code 1,
595
+ `success:false`, `error:"target_exists"`, and that files inside the
596
+ pre-existing directory are preserved verbatim.
597
+
598
+ **Truthfulness invariant added by this fix.** For every path-bearing
599
+ creation op (`create`, `create_dir`, `rename`'s `newPath`), a
600
+ public-surface success result now implies the executor performed the
601
+ creation. Previously this held for `create` and `rename` but failed
602
+ silently for `create_dir`.
603
+
604
+ ## 0.1.0-alpha.60 - Protected paths + filename hygiene + OCD warning truthfulness
605
+
606
+ **Released:** May 2026
607
+ **npm tag:** `alpha` - `npm install -g usesteady@alpha`
608
+
609
+ Post-alpha.59 delta. Closes 4 accepted frictions across 2 trust surfaces:
610
+ filesystem location safety (Cluster B Iter 4: #60, #67, #68) and
611
+ execution truthfulness (#42). One new public `CliErrorCode`
612
+ (`prohibited_path`); no new approval semantics, no new operation types,
613
+ no exit-code change, OCD remains non-blocking.
614
+
615
+ Included PRs: #318 (Cluster B Iter 4) and #319 (#42 OCD warning
616
+ alignment). No other deltas since alpha.59 (`4cbac6c`).
617
+
618
+ ### Cluster B Iteration 4 - Protected Paths Registry + whitespace-bounded filenames
619
+
620
+ Design rationale: [`docs/adr/ADR-cluster-b-iteration-4-protected-paths.md`](./docs/adr/ADR-cluster-b-iteration-4-protected-paths.md).
621
+
622
+ Closes three accepted frictions in one coherent feature, following
623
+ the flat pure-function style of Iter 2 / Iter 3 / Iter 3.5 / Iter 3.6.
624
+
625
+ - **shortgigs/usesteady-public#60** (`create_dir` into `.git/hooks`):
626
+ refused at the validate stage with the new public `prohibited_path`
627
+ code; defense-in-depth re-check at the cursor adapter mirrors the
628
+ S2/#36 posture (every fs-op site).
629
+ - **shortgigs/usesteady-public#67** (silent `delete` of `.git/HEAD`):
630
+ same refusal class, applied symmetrically to delete / rename
631
+ (both from and to) / append / prepend / replace. Unlike filename-
632
+ hygiene checks (Iter 2/3), the protected-path check runs on
633
+ `delete` -- the friction shape is symmetric.
634
+ - **shortgigs/usesteady-public#68** (leading/trailing whitespace in
635
+ filenames): refused at validate/executor; folds under the existing
636
+ `invalid_filename_chars` public code (internal discriminant
637
+ `invalid_filename_whitespace`). Per-segment check catches
638
+ intermediate-directory whitespace too, not just basenames.
639
+
640
+ #### Authority surface
641
+
642
+ - One new public `CliErrorCode`: `prohibited_path`. Strongly justified
643
+ (distinct semantic from `invalid_filename_chars`: path is well-
644
+ formed and inside the workspace; the LOCATION is off-limits;
645
+ remediation is "use git directly," not "rename").
646
+ - No new operation types, no new approval semantics, no new
647
+ approval-bypass affordances.
648
+ - V1 protected set: any segment exactly equal to `.git` (case-
649
+ insensitive). Regular workspace files like `.gitignore`,
650
+ `.gitattributes`, and `.gitkeep` are NOT protected.
651
+
652
+ #### Invariants preserved
653
+
654
+ - All Iter 1-3.6 invariants hold (1097 passing tests across
655
+ `tests/input`, `tests/safety`, `tests/cursor`).
656
+ - Ordering: codepoint check -> reserved-name check -> whitespace
657
+ check -> canonicalization check -> protected-path check, so the
658
+ most actionable diagnostic wins (e.g. `"CON "` surfaces as
659
+ reserved-name with rename suggestion, not as whitespace).
660
+ - Pure functions, no fs / time / global state. Same input, same
661
+ output on every host.
662
+
663
+ #### Out of scope
664
+
665
+ - Other VCS internals (`.svn/`, `.hg/`), secrets directories
666
+ (`.env*`), `node_modules/`. No friction signal yet -- extension
667
+ requires a real reporter case (AGENTS.md "no new authority without
668
+ a current user flow").
669
+ - Protected-path receive-side defense-in-depth at the replace gate.
670
+ The validator catches it pre-receive; the adapter's `receive()`
671
+ path defers to that (consistent with how filename-safety is wired).
672
+
673
+ #### Friction -> fix mapping
674
+
675
+ | Friction (usesteady-public) | Fix surface |
676
+ |----------------------------------------------|---------------------------------------------------|
677
+ | #60 - create_dir into .git/hooks | `validateProtectedPath` + per-op wiring |
678
+ | #67 - silent delete of .git/HEAD | `validateProtectedPath` covers delete (new scope) |
679
+ | #68 - leading/trailing whitespace in name | `validateFilenameSafety` whitespace extension |
680
+
681
+ ### Issue #42 - OCD warning vs success reporting alignment
682
+
683
+ Closes shortgigs/usesteady-public#42. The OCD evaluator already
684
+ surfaces the conflict frame as `WARNING - OCD conflict detected
685
+ (non-blocking)` with "System will execute on approval." text (S4
686
+ fix, alpha.5x). The remaining trust gap was the END-OF-RUN summary:
687
+ a run that printed a WARNING frame and then executed under `--yes`
688
+ announced "Completed successfully" with no acknowledgement that a
689
+ warning had been accepted.
690
+
691
+ #### Change
692
+
693
+ - `WorkflowTask` gains an optional `conflictsAccepted?: number`
694
+ counter, incremented inside `acceptWorkflowConflict` whenever the
695
+ user (or `--yes`) accepts an OCD conflict warning for that task.
696
+ - `ExecutionSummary` gains a required `warnings_accepted: number`
697
+ field, summed only across tasks that actually ran (`outcome ===
698
+ "accepted"`).
699
+ - `renderExecutionSummaryLines` reports `! Completed with N
700
+ warning(s) accepted` instead of `Completed successfully` when
701
+ `summary.success && summary.warnings_accepted > 0`. Plural/singular
702
+ agreement preserved. Failure / neutral forms unchanged.
703
+ - `--output json` surface gains `warnings_accepted: <number>` so
704
+ machine consumers (CI scripts, agent integrations) can surface the
705
+ same trust signal the human banner now shows. Strictly additive --
706
+ pre-#42 consumers reading `success` / `error` / `failed_at_step` /
707
+ `executed_steps` / `total_steps` are unaffected. The field is
708
+ always emitted on post-#42 runs (zero when no warning was
709
+ accepted); pre-#42 result-file fixtures are tolerated via guarded
710
+ projection (field omitted when the upstream result does not carry
711
+ it -- no invented data).
712
+
713
+ #### Invariants preserved
714
+
715
+ - OCD evaluator behavior unchanged (still non-blocking).
716
+ - Conflict-frame text unchanged.
717
+ - Exit code unchanged (0 on success, warnings or not).
718
+ - JSON `success` key unchanged (the run still succeeded).
719
+ - Public CliErrorCode surface unchanged.
720
+ - Pre-#42 runs with zero warnings still see the verbatim
721
+ `Completed successfully` banner (regression-guarded).
722
+ - Pre-#42 result-file fixtures (without `warnings_accepted`) still
723
+ produce a valid `--output json` payload -- the field is simply
724
+ absent rather than invented.
725
+
726
+ ## 0.1.0-alpha.59 - Bundled stabilization (E2E baseline, Cluster B Iter 2+3+3.5+3.6, K2 cleanup, K5 run_command replay, CLI well-formedness guardrail)
727
+
728
+ **Released:** May 2026
729
+ **npm tag:** `alpha` - `npm install -g usesteady@alpha`
730
+
731
+ **Bundled-stabilization release. Multiple stabilized sprint surfaces
732
+ converge into a single trustworthy alpha. No new authority. No new
733
+ operation types. No new approval semantics. No generalized shell
734
+ execution. No autonomous execution. No semantic replay. No AI
735
+ runtime orchestration.**
736
+
737
+ This release is the result of seven sprint surfaces that were
738
+ implemented, regression-tested, and operationally observed prior
739
+ to packaging. Each surface stayed inside an existing authority
740
+ boundary; this release commit assembles them.
741
+
742
+ ### What shipped
743
+
744
+ #### E2E baseline + UI-W1 invariant restoration (Sprint 1)
745
+
746
+ The alpha.53-alpha.58 intake + UI drift left the Playwright E2E
747
+ suite at 20 / 27 red. One failure was a real product regression:
748
+ `server.ts /api/workflow/start` did not run NL synthesis on
749
+ web-UI tasks, so tasks the CLI would have classified as
750
+ `skipped_by_intake` were emitted as `task_failed` from the web
751
+ UI. The UI-W1 invariant (intake refusal is the same outcome on
752
+ every entrypoint) was broken silently.
753
+
754
+ - `server.ts`: `synthesizeStructuredFieldsFromNL` is now called
755
+ idempotently per task.
756
+ - `src/workflow/coordinator.ts`: routes `!isDeterministicTaskSpec`
757
+ to `skipped_by_intake`.
758
+ - E2E selectors updated to current alpha.55-alpha.58 UI labels.
759
+
760
+ #### Cluster B Iteration 2 wiring + Iteration 3 OS-reserved names + Iteration 3.6 message polish (Sprints 2 + 4)
761
+
762
+ Cluster B continues to harden the filesystem layer. Three
763
+ sub-classes of the same friction (filename that looks valid in
764
+ the developer's editor but breaks elsewhere) are now refused at
765
+ the safety adjacency, before preview / before approval:
766
+
767
+ 1. **Invisible / canonical-divergence filenames** (`#50`, `#51`,
768
+ from a prior public reproducer) -- already partially handled
769
+ in alpha.52; this release ships the unified adjacency.
770
+ 2. **BIDI / zero-width / control codepoints in `replace.newValue`**
771
+ (`#52`) -- new refusal at the executor with the new error
772
+ code `invalid_replacement_chars`.
773
+ 3. **OS-reserved device names on Windows** (CON, NUL, AUX,
774
+ COM1-9, LPT1-9) -- new refusal with the new error code
775
+ `invalid_filename_reserved_name`. Cross-platform: a Linux
776
+ developer creating `CON.tsx` no longer corrupts a Windows
777
+ teammate's clone on pull.
778
+
779
+ Implementation:
780
+ - New flat-adjacency module `src/safety/filename-safety.ts`
781
+ exporting `validateFilenameSafety`,
782
+ `validateReplacementTextSafety`, and the canonical-divergence
783
+ classifier. No new policy class. No new abstraction layer.
784
+ - Wired at three call sites: `FeasibilityValidator`,
785
+ `CursorInProcessAdapter.executeFsOp`, and the
786
+ `CursorInProcessAdapter` replacement-text gate.
787
+ - Two new `CliErrorCode` discriminants:
788
+ `invalid_replacement_chars`, `invalid_filename_reserved_name`.
789
+ - One new `CursorExecutionErrorCode` discriminant:
790
+ `invalid_replacement_chars` (matching `formatErrorHeadline`
791
+ case added so the exhaustive switch stays exhaustive --
792
+ this was a Sprint 2 type-union gap caught and closed during
793
+ alpha.59 `tsc -p tsconfig.build.json`).
794
+ - Bug fix: the adapter and validator were previously collapsing
795
+ all specific codes to `invalid_filename_chars`. Specific
796
+ codes now propagate so reserved-name refusals are visible.
797
+
798
+ Message polish (Iter 3.6):
799
+ - `NAMED_CODEPOINTS`, `formatCodepoint`, `buildOffenderDetail`,
800
+ `describeClasses`, `suggestReservedNameRename` added to
801
+ `filename-safety.ts`. No new `CliErrorCode` from polish.
802
+ - Reserved-name suggestion preserves file extensions
803
+ (bug caught and fixed by test in this release).
804
+ - Per-discriminant summary phrases in `feasibility-validator.ts`
805
+ sharpened.
806
+
807
+ #### Cluster B Iteration 3.5 NL delete safety gate + Iter 3.6 vague-delete message polish (Sprints 3 + 4)
808
+
809
+ Sprint 1's E2E baseline pass surfaced a real safety regression:
810
+ NL synthesis was converting vague delete targets ("delete
811
+ everything", "remove all") into concrete `delete_file`
812
+ operations. The IR layer accepted the synthesized op; only
813
+ approval-stage vigilance stood between intent and execution.
814
+
815
+ This release refuses vague delete targets at the NL parse stage
816
+ so they never become concrete `delete_file` operations:
817
+
818
+ - `VAGUE_DELETE_TARGETS` set + `isVagueDeleteTarget` guard
819
+ added to `src/input/nl-to-ir.ts`.
820
+ - `matchDelete` returns `parse_error` for vague targets, which
821
+ routes through `skipped_by_intake` ("Could not understand").
822
+ - Polished `parse_error` message wording.
823
+
824
+ No new `CliErrorCode`. The refusal surfaces through the
825
+ existing intake-failure path -- vague intent is an intake
826
+ failure, not a safety detector hit.
827
+
828
+ #### K2 parse_error precedence cleanup + structuredReplace drift guard + K5 design lock (Sprint 6)
829
+
830
+ Three kernel maintenance items from the Sprint 5 read-only
831
+ Kernel Audit:
832
+
833
+ - **K2 parse_error precedence**: extracted private
834
+ `synthesizeRawErrorCode` helper. New invariant **INV-K2-PE-1**
835
+ documents the three origins of `parse_error` and the
836
+ precedence rule. Subtle empty-string-falsy regression
837
+ caught and fixed. Behavior preserved byte-for-byte against
838
+ the prior K2 test suite.
839
+ - **structuredReplace drift guard**: new
840
+ `tests/kernel/structuredReplace-drift.test.ts` -- 13 fixtures
841
+ across `accepted`, `file_not_found`, `old_value_not_found`,
842
+ `ambiguous_match`. Asserts byte-identical normalized
843
+ outcomes between the K4 inline path and the production
844
+ adapter path. Self-verified by injected-bug exercise.
845
+ `executeStructuredReplace` and `TaskReplayOutcome` exposed as
846
+ `@internal` test seams only.
847
+ - **K5 design doc** locked at v1.0 (drafted v0.1 here, the
848
+ v1.0 update lands in the Sprint 7 commit). Eight new
849
+ invariants **K5-I11..I18**. Section 11 open questions
850
+ resolved: `node -e` deferred to K6, K2 parse_error split
851
+ deferred to a parallel PR, `mkdir -p` / `rm -rf` dropped
852
+ from the allow-list as redundant with existing operation
853
+ types, `true` / `false` short-circuit in pure Node.
854
+
855
+ #### K5 run_command deterministic replay (Sprint 7)
856
+
857
+ The Kernel Audit's #1 priority surface. Adds deterministic
858
+ replay support for a strictly-bounded `run_command` allow-list.
859
+ **The allow-list is `echo <args>`, `true`, `false` and nothing
860
+ else.** No shell escape. No environment widening. No new
861
+ authority. No new approval semantics. Operator approval is still
862
+ required for every `run_command` op.
863
+
864
+ - New `src/kernel/command-classifier.ts` -- two-gate
865
+ `isReplayableCommandShape`: denylist first
866
+ (defense-in-depth), then allow-list regex. Classifier never
867
+ executes; only classifies.
868
+ - `src/kernel/types.ts` widened additively only:
869
+ `ClassifierResult.reason?` and
870
+ `ExecutionReplayVerdict.refused.reason` become
871
+ discriminated unions. Existing consumers unchanged.
872
+ - `src/kernel/classifier.ts` consults the classifier for
873
+ `run_command`. `classifyForReplay` emits the K5 `reason`
874
+ discriminant so downstream surfaces can name the precise
875
+ refusal class.
876
+ - `src/kernel/execution-replay.ts` adds `executeRunCommand`:
877
+ `echo` via `spawnSync(shell: true)` inside the sandbox;
878
+ `true` / `false` short-circuit in pure Node (no spawn).
879
+ - HELP_TEXT in `src/shell/cli/use-steady.ts` documents the
880
+ K5 allow-list.
881
+
882
+ #### CLI entrypoint well-formedness guardrail (Sprint 8)
883
+
884
+ Converts Sprint 7's HELP_TEXT lesson into a cheap pre-merge
885
+ guardrail. An early Sprint 7 HELP_TEXT edit used backticks
886
+ INSIDE the existing HELP_TEXT template literal, breaking
887
+ esbuild transform for the entire CLI. The kernel-suite did not
888
+ catch this -- it was only visible to full-vitest, via 36
889
+ downstream CLI-subprocess test failures with confusing surface
890
+ symptoms.
891
+
892
+ - New `tests/shell/cli-entrypoint-wellformed.test.ts` -- one
893
+ test, ~200 ms, spawns `usesteady --help` and asserts exit 0
894
+ + non-empty stdout. Inlines the esbuild error
895
+ (`file:line:col`) into the failure message so a future
896
+ reader sees the bug on the first failed assertion.
897
+ - No new dependencies. No runtime change.
898
+
899
+ ### What remains intentionally refused
900
+
901
+ These surfaces were considered and deliberately left out of
902
+ alpha.59. Each has an explicit reason in scope discipline.
903
+
904
+ - **`run_command` outside `echo` / `true` / `false`** -- shells
905
+ out beyond the K5 allow-list. K6 territory; not authorized.
906
+ - **`node -e` arbitrary script execution** -- K6 territory;
907
+ deferred (alpha.59 is not a generalized-shell-execution
908
+ release).
909
+ - **`mkdir -p` / `rm -rf` as `run_command` shapes** -- redundant
910
+ with `operationType: "create_dir"` / `"delete_file"`, and
911
+ `cmd.exe` semantics for `mkdir -p` differ from POSIX. Adding
912
+ them would widen the allow-list without operator benefit.
913
+ - **K2 `parse_error` discriminant split** -- a separate parallel
914
+ PR after alpha.59 review. Not a regression; the existing
915
+ ladder is documented (INV-K2-PE-1) and preserved.
916
+ - **Execution timeline implementation** -- PR #315 is design-only
917
+ and remains design-only. No runtime in alpha.59.
918
+ - **Workflow doctor surface** -- not in scope. No design lock.
919
+ - **Reactive fix for public#50 U+202E bare-create coverage gap**
920
+ -- classified as uncovered Cluster B sub-class; explicitly
921
+ not addressed in alpha.59. Future work must be separately
922
+ scoped, bounded, reviewed, released.
923
+ - **Clarifying fix for public#51 NFD/NFC behavior** -- the
924
+ `ambiguous_match` refusal is the intended fail-closed
925
+ canonicalization gate; no runtime change. A wording
926
+ clarification may follow in a future cycle if operator
927
+ misreading repeats.
928
+ - **AI command generation / autonomous execution** -- not in
929
+ scope. Out of every track UseSteady is building.
930
+
931
+ ### Preserved invariants
932
+
933
+ - **Replay hermeticity**: identical inputs yield identical
934
+ replay bytes. K5 widens the replayable shape set; it does
935
+ not weaken determinism.
936
+ - **Approval-before-execution**: every `run_command`, every
937
+ `replace`, every fs op still requires operator approval at
938
+ the SYSTEM WILL surface. K5 changes WHICH commands can be
939
+ classified, not WHEN approval is required.
940
+ - **Safety-gate runs before approval**: the credential /
941
+ secret detector, the canonicalization gate, the filename
942
+ adjacency, and the new vague-delete intake refusal all
943
+ fire pre-preview.
944
+ - **UI-W1 entrypoint parity**: CLI `--prompt`, `run <spec.json>`,
945
+ `--json`, `batch <file>`, and web UI all route intake
946
+ refusal to `skipped_by_intake`. No entrypoint silently
947
+ promotes to `task_failed`.
948
+ - **Additive widening only**: `ClassifierResult` and
949
+ `ExecutionReplayVerdict` unions widened; no breaking
950
+ removal. Existing consumers unchanged.
951
+ - **One-source-of-truth**: every operation type in every
952
+ template still maps to `ALL_OPERATION_TYPES`. HELP_TEXT
953
+ still documents every public op. The IR-shape-validity test
954
+ still passes against every template.
955
+
956
+ ### Stabilization hardening added
957
+
958
+ - **TS2322 closure** in `CursorExecutionErrorCode` -- the
959
+ Sprint 2 type-union gap is closed. `npm run build` is clean.
960
+ - **structuredReplace drift guard** -- behavioral divergence
961
+ between the K4 inline path and the production adapter path
962
+ is now a localised assertion failure with a precise hint,
963
+ not a downstream mystery.
964
+ - **K2 parse_error precedence is documented and tested** --
965
+ INV-K2-PE-1 names the three origins and the precedence
966
+ ladder. Future edits to error-codes.ts can be reviewed
967
+ against the invariant.
968
+ - **CLI entrypoint smoke test** -- `usesteady --help` cannot
969
+ silently fail to load. A future HELP_TEXT edit that breaks
970
+ esbuild transform will be caught in ~200 ms, not via 36
971
+ downstream test failures.
972
+ - **Specific filename-safety error codes propagate** -- the
973
+ adapter and validator no longer collapse all sub-classes
974
+ to `invalid_filename_chars`. Operators see the exact
975
+ refusal class.
976
+
977
+ ### Known intentionally-deferred scope
978
+
979
+ - K6 `node -e` replayability (separate authorization required).
980
+ - K2 `parse_error` discriminant split (separate PR after
981
+ alpha.59 review).
982
+ - Public#50 U+202E bare-`create` coverage gap (uncovered
983
+ Cluster B sub-class; not a regression).
984
+ - Execution timeline implementation (PR #315 stays
985
+ design-only).
986
+ - Cross-platform CI runners.
987
+ - Workflow doctor surface.
988
+ - New ergonomics capability candidates.
989
+
990
+ ### Friction -> fix -> guardrail
991
+
992
+ | Friction class | Refused as / fixed where | Guardrail |
993
+ |---|---|---|
994
+ | `public#50` -- path-traversal canonical divergence | `validateFilenameSafety` + path adjacency at validator + executor + replace-match gate | filename-safety.test.ts (Iter 2 cases) |
995
+ | `public#52` -- BIDI / zero-width / control in `replace.newValue` | Executor refuses with `invalid_replacement_chars` before write | canonicalize-adjacent-surfaces.test.ts + filename-safety.test.ts |
996
+ | OS-reserved names on Windows (`CON.tsx`, `COM1.ts`, etc.) | Validator + executor refuse with `invalid_filename_reserved_name` cross-platform | feasibility-validator.invalid-filename-chars.test.ts |
997
+ | Vague NL delete intent ("delete everything") | `nl-to-ir.matchDelete` returns `parse_error` -> `skipped_by_intake` | +37 tests in nl-to-ir.test.ts |
998
+ | UI-W1 intake parity broken on web UI | `server.ts` runs NL synthesis; coordinator routes non-deterministic specs to `skipped_by_intake` | E2E specs assert parity |
999
+ | K4 inline vs production-adapter `replace` divergence (would be silent) | Drift matrix in structuredReplace-drift.test.ts | 13 deterministic fixtures across 4 outcome classes |
1000
+ | K2 `parse_error` precedence ambiguous in source | Helper extracted; INV-K2-PE-1 documents the ladder | K2 suite preserved byte-for-byte; new invariant in source |
1001
+ | HELP_TEXT esbuild break (Sprint 7 incident) | One ~200 ms test asserts `usesteady --help` loads | cli-entrypoint-wellformed.test.ts |
1002
+
1003
+ ### Verification
1004
+
1005
+ - `npm run build`: clean.
1006
+ - `npm run release:gate`: green -- **142 test files, 5256
1007
+ passed, 4 skipped, 0 failed**.
1008
+ - Kernel suite: 301 / 301 green.
1009
+ - Playwright E2E suite green against this delta.
1010
+ - No dependency drift.
1011
+ - Changelog reflects only the committed delta in this PR.
1012
+
1013
+ ### Versioning posture
1014
+
1015
+ This is `0.1.0-alpha.59`. Alpha only. Not beta. Not
1016
+ "production-ready." The replay scope is widened to three
1017
+ allow-list commands (`echo`, `true`, `false`); it is not
1018
+ generalized shell execution.
1019
+
1020
+ `npm publish` is **not** authorized by this PR. Publish
1021
+ happens after explicit approval following merge.
1022
+
1023
+ ## 0.1.0-alpha.58 - Domain-specific recipe templates
1024
+
1025
+ **Released:** May 2026
1026
+ **npm tag:** `alpha` - `npm install -g usesteady@alpha`
1027
+
1028
+ **Ergonomics continuation release. Capability-track section 3.2
1029
+ extension. No new template engine, no parameter DSL, no dynamic
1030
+ generation, no new operation types, no runtime semantic changes,
1031
+ no dependency additions.**
1032
+
1033
+ ### What this release fixes
1034
+
1035
+ The alpha.57 walkthrough confirmed users could now reliably pick
1036
+ the right command for the right JSON shape (`--json` / `batch` /
1037
+ `run`). The next-highest authoring friction was "how do I safely
1038
+ do X?" -- a first-time operator who knew the invocation surface
1039
+ still had no concrete worked example for common dev tasks
1040
+ (version bump, adding an import, updating a dotenv key).
1041
+
1042
+ The alpha.54 starter templates covered append, rename,
1043
+ multi-file-replace, create-dir-then-rename, and create-then-append,
1044
+ but did not cover three high-volume real-world patterns:
1045
+
1046
+ - **F-A57-AUTH-1** -- no template demonstrated a coordinated
1047
+ cross-file edit (e.g. version bump in package.json + matching
1048
+ CHANGELOG entry). Operators authored these by hand, repeatedly,
1049
+ with no canonical safe example to copy.
1050
+ - **F-A57-AUTH-2** -- no template demonstrated `prepend`. The
1051
+ operation type was reachable via `usesteady capabilities` but
1052
+ had no worked example, so first-time operators defaulted to
1053
+ `append` for "add an import" tasks where `prepend` is actually
1054
+ correct -- producing imports at the end of files.
1055
+ - **F-A57-AUTH-3** -- no template demonstrated a `replace` against
1056
+ a non-JSON line-based format (dotenv, ini-style). Operators had
1057
+ to infer that exact-line `replace` works for `KEY=value` lines,
1058
+ including the runtime difference that `replace` refuses
1059
+ `file_not_found` on missing files (unlike append/prepend, which
1060
+ create them).
1061
+
1062
+ ### What ships
1063
+
1064
+ #### Three new recipe templates
1065
+
1066
+ All three reuse the existing `TEMPLATE_REGISTRY` shape verbatim.
1067
+ No template engine, no parameter DSL, no dynamic generation. Each
1068
+ is a static JSON asset like the alpha.54 starter templates.
1069
+
1070
+ - **`bump-version`** -- `replace` `"version"` in package.json +
1071
+ `append` matching CHANGELOG.md entry (2 ops across 2 files).
1072
+ Demonstrates coordinated cross-file edits. Safety notes are
1073
+ explicit that the recipe does NOT run `git`, `git tag`, `npm
1074
+ version`, `npm publish`, or any command, and does NOT update
1075
+ lock files. Names all three `replace` failure classes
1076
+ (`file_not_found`, `old_value_not_found`, `ambiguous_match`).
1077
+ Documents the prepend-instead-of-append alternative for
1078
+ newest-at-top CHANGELOGs.
1079
+
1080
+ - **`add-import`** -- `prepend` an import statement to the top of
1081
+ a source file (1 op). First template to demonstrate `prepend`.
1082
+ Safety notes are explicit that prepend lands BEFORE any license
1083
+ header, shebang, or `"use strict";`, and that the recipe does
1084
+ NOT sort, group, or de-duplicate imports. Tells the operator
1085
+ to terminate the imported line with `\n` so it lands on its own
1086
+ line.
1087
+
1088
+ - **`safe-env-update`** -- `replace` one `KEY=value` line in a
1089
+ dotenv-style file (1 op). First template to target a non-JSON
1090
+ line-based format. Safety notes are explicit that `replace`
1091
+ refuses `file_not_found` on missing files (does NOT auto-create
1092
+ unlike append/prepend), that quoting/whitespace/inline comments
1093
+ change the match, that dotenv files often hold secrets (use the
1094
+ SYSTEM WILL preview), and that gitignored .env files should be
1095
+ paired with a tracked `.env.example`.
1096
+
1097
+ Every safety note is verified against runtime behavior in
1098
+ `src/cursor/adapters/inprocess-adapter.ts`. The test suite
1099
+ asserts the exact runtime-class strings appear in the relevant
1100
+ notes so a future edit cannot regress wording silently.
1101
+
1102
+ ### Hard constraints honored
1103
+
1104
+ - No new template engine, parameter DSL, or dynamic generation
1105
+ - No new operation types (every op uses `replace`, `append`, or
1106
+ `prepend` -- all already in `ALL_OPERATION_TYPES`)
1107
+ - No recipe-specific authority or runtime semantic changes
1108
+ - No semantic-review layer
1109
+ - No autonomous workflow generation
1110
+ - No parser expansion
1111
+ - No dependency additions
1112
+ - No multi-surface capability wave (templates surface only)
1113
+ - No hidden execution semantics
1114
+ - Runtime-truthful wording (every safety claim asserted against
1115
+ runtime behavior in tests)
1116
+ - Byte-deterministic output (existing template determinism
1117
+ contract extended to the three new entries)
1118
+
1119
+ ### Test coverage
1120
+
1121
+ 17 new tests in `tests/shell/templates.test.ts`:
1122
+
1123
+ - **T10b**: the 3 alpha.58 recipes are present in `TEMPLATE_NAMES`
1124
+ - **IR-shape-validity**: every operation in every template parses
1125
+ cleanly through `jsonOpToIROperation` -- locks down the wire-
1126
+ shape contract so a future template addition cannot ship a shape
1127
+ that the `--json` / `batch` adapter rejects
1128
+ - Per-recipe content + safety-note vs runtime alignment for each
1129
+ of `bump-version`, `add-import`, `safe-env-update`
1130
+
1131
+ Full suite: **4889 passed** (was 4870; +19), 4 pre-existing skips.
1132
+ 137 test files. `npm run release:gate` -- PASS.
1133
+
1134
+ ### Friction-to-usability mapping
1135
+
1136
+ | Friction (alpha.57 walkthrough) | Recipe (alpha.58) |
1137
+ | --- | --- |
1138
+ | F-A57-AUTH-1 (no cross-file safe example) | `bump-version` |
1139
+ | F-A57-AUTH-2 (no `prepend` worked example) | `add-import` |
1140
+ | F-A57-AUTH-3 (no dotenv replace example) | `safe-env-update` |
1141
+
1142
+ ---
1143
+
1144
+ ## 0.1.0-alpha.57 - Workflow invocation shape ergonomics
1145
+
1146
+ **Released:** May 2026
1147
+ **npm tag:** `alpha` - `npm install -g usesteady@alpha`
1148
+
1149
+ **Ergonomics/clarity release. No new capability surface beyond the
1150
+ read-only `examples` catalog. No execution-model, planner, approval-
1151
+ model, schema, operation-set, or dependency changes.**
1152
+
1153
+ ### What this release fixes
1154
+
1155
+ The alpha.56 walkthrough surfaced the highest-leverage onboarding
1156
+ friction: operational confusion across the four workflow-invocation
1157
+ surfaces.
1158
+
1159
+ - **F-A56-OPS-1** -- a first-time operator could not predict which
1160
+ command (`--json`, `batch <file>`, `run <file>`) accepted which
1161
+ JSON envelope shape (single op vs. op array vs. WorkflowSpec).
1162
+ Help text covered each individually; no single surface explained
1163
+ the mapping shape -> command.
1164
+ - **F-A56-OPS-2** -- shape-mismatch error messages named only the
1165
+ generic contract ("not valid JSON", "unknown or invalid
1166
+ operation", "Workflow spec was not recognized"). They did not
1167
+ point the operator at the matching command form OR at a copyable
1168
+ example. Recovery required reading the help text and guessing.
1169
+ - **F-A56-OPS-3** -- documenting "use this command for this shape"
1170
+ required reading three separate help-text blocks and inferring
1171
+ the mapping. There was no canonical reference for the mapping.
1172
+
1173
+ ### What ships
1174
+
1175
+ #### `usesteady examples` (new read-only subcommand)
1176
+
1177
+ Pure module `src/shell/cli/examples.ts`. Renders the three accepted
1178
+ invocation shapes with their command form, when-to-use guidance,
1179
+ and a minimal copyable JSON example each:
1180
+
1181
+ | id | command | shape |
1182
+ | --- | --- | --- |
1183
+ | `json` | `usesteady --json '<inline op>' --yes` | single JSON op object |
1184
+ | `batch` | `usesteady batch <file> --yes` | JSON array of op objects |
1185
+ | `run` | `usesteady run <file>` | WorkflowSpec object (also auto-wraps single op + array) |
1186
+
1187
+ Each pattern carries an identical canonical content shape (append-
1188
+ to-`NOTES.md`) so the operator sees the same body in every form,
1189
+ making the "what changed across shapes" question trivially
1190
+ inspectable. Quick rule-of-thumb block reinforces shape -> command.
1191
+ Sibling cross-references to `quickstart` / `capabilities` /
1192
+ `templates` / `help` so the operator can navigate from one place.
1193
+
1194
+ Authority pattern matches `capabilities` / `quickstart` /
1195
+ `templates`:
1196
+
1197
+ - in `PURE_SUBCOMMANDS` (never reads stdin, never executes);
1198
+ - exempt from the `--output json` requires `--yes` rule (catalog
1199
+ is informational, no execution to gate);
1200
+ - deterministic byte-identical output across runs for a given
1201
+ build;
1202
+ - single-line stable-key JSON shape;
1203
+ - never imports the planner, safety gate, executor, or approval
1204
+ surface.
1205
+
1206
+ #### Shape-aware error guidance (three surfaces)
1207
+
1208
+ | Surface | Pre-alpha.57 first line (unchanged) | Alpha.57 addition |
1209
+ | --- | --- | --- |
1210
+ | `--json <bad>` invalid JSON | `Error: input is not valid JSON` | Names the `--json` contract ("single inline JSON op object (or an array)"); pointer to `usesteady examples`. |
1211
+ | `batch <bad-json>` invalid JSON | same first line | Names the `batch` contract ("JSON array of op objects"); pointer to `usesteady examples`. |
1212
+ | `--json` / `batch` invalid op | `Error: unknown or invalid operation: <op>` | Pointers to `usesteady capabilities` (per-op schema) and `usesteady examples`. |
1213
+ | `run <file>` shape mismatch (`RUN_SPEC_ACCEPTED_SHAPES_MESSAGE`) | `Workflow spec was not recognized. Accepted shapes: ...` | New `Command form per shape:` block mapping each shape to its matching command; pointers to `usesteady examples`, `usesteady capabilities`, `usesteady --help`. |
1214
+
1215
+ Error classes (`invalid_json`, `invalid_op`), exit codes (2 / 1),
1216
+ and the `--output json` machine-readable body are byte-identical.
1217
+ Only human prose extended.
1218
+
1219
+ #### Pre-existing contract preserved
1220
+
1221
+ The `Accepted shapes` / `WorkflowSpec` / `JSON op` tokens that the
1222
+ governance and shell shape-error regex suites assert against are
1223
+ preserved verbatim:
1224
+
1225
+ - `tests/governance/input-surface-integrity.test.ts`
1226
+ - `tests/shell/shell-workflow-spec.test.ts`
1227
+
1228
+ No machine consumer of these messages breaks.
1229
+
1230
+ #### README minimal addition
1231
+
1232
+ One new "Workflow Shapes" section between "Discover what UseSteady
1233
+ can do" and "Core idea". Three-row table mapping shape -> command
1234
+ -> when-to-use, plus the `usesteady examples` pointer. No other
1235
+ README changes.
1236
+
1237
+ #### Help text
1238
+
1239
+ `HELP_TEXT` advertises `usesteady examples` and `usesteady examples
1240
+ --output json` alongside the existing pure-subcommand block.
1241
+
1242
+ ### Friction -> Fix mapping (alpha.56-walkthrough-grounded)
1243
+
1244
+ | Friction observed | Fix in alpha.57 |
1245
+ | --- | --- |
1246
+ | Operator could not predict command-per-shape | `usesteady examples` catalog with explicit mapping |
1247
+ | `--json` invalid JSON did not name the expected shape | Surface-aware addendum ("single inline JSON op object") + pointer |
1248
+ | `batch` invalid JSON did not name the expected shape | Surface-aware addendum ("JSON array of op objects") + pointer |
1249
+ | `--json` / `batch` invalid op forced help-text guessing | Pointer to `usesteady capabilities` for the per-op schema |
1250
+ | `run <file>` shape mismatch did not name the matching command | `Command form per shape:` block + pointer to `usesteady examples` |
1251
+ | Three help-text blocks required to derive shape -> command mapping | README "Workflow Shapes" table + canonical `examples` catalog |
1252
+
1253
+ ### Authority story
1254
+
1255
+ Pure module. Reuses `capabilities` / `quickstart` / `templates`
1256
+ infrastructure (PURE_SUBCOMMANDS gate, `--yes` exemption,
1257
+ deterministic-output contract). The new error-message hints are
1258
+ strings only -- no new error classes, no new exit codes, no parser
1259
+ changes, no envelope coercion. `loadWorkflowSpecFromFile` auto-wrap
1260
+ behavior is byte-identical. The catalog reuses the same op-shape
1261
+ conventions `jsonOpToIROperation` already accepts so no second
1262
+ source of truth is introduced.
1263
+
1264
+ ### What does NOT change
1265
+
1266
+ - Execution engine: byte-identical to alpha.56.
1267
+ - Planner: byte-identical.
1268
+ - Approval model: byte-identical.
1269
+ - Operation set: same 8 operation types.
1270
+ - Parser: byte-identical -- no hidden coercion between formats,
1271
+ no automatic envelope conversion, no AI generation.
1272
+ - Dependencies: zero additions.
1273
+ - Spec hash semantics, replay, audit envelope: byte-identical.
1274
+ - Pre-alpha.57 valid `--json '<op>' --yes` and `run <WorkflowSpec
1275
+ -file>` calls behave byte-identically.
1276
+
1277
+ ### Tests
1278
+
1279
+ `tests/shell/examples.test.ts` -- 26 new tests:
1280
+
1281
+ - Pure formatter unit tests: catalog order (json, batch, run),
1282
+ command form per id, minimal-example JSON round-trip, frozen
1283
+ catalog, determinism (I1, I6, I7).
1284
+ - JSON render: single-line + trailing newline, valid JSON shape,
1285
+ byte-determinism (I2).
1286
+ - Text render: byte-determinism, sibling cross-references
1287
+ (quickstart / capabilities / templates / help), explicit
1288
+ read-only language (I3, I8).
1289
+ - CLI integration: no `--yes` needed, `--output json` exempt from
1290
+ `--yes`, `--help` form, global `HELP_TEXT` advertises the
1291
+ subcommand, deterministic across invocations (I4, I5).
1292
+ - Invocation-shape error guidance: `--json <bad>`, `batch <bad>`,
1293
+ `--json <unknown op>`, `run <bad-spec>` -- each error keeps its
1294
+ canonical first line AND adds the matching command-form hint
1295
+ AND the pointer to `usesteady examples` (I9).
1296
+ - Backward compatibility: a valid `--json` op and a valid `run
1297
+ <WorkflowSpec>` do NOT regress to exit code 2.
1298
+
1299
+ Existing governance + shell shape-error suites pass unchanged.
1300
+
1301
+ Full suite: 4870 passed (was 4844; +26 from this suite), 4
1302
+ pre-existing skips. No regressions in `governance`, `shell`,
1303
+ `capabilities`, `templates`, `quickstart`, `phase-11d`,
1304
+ `workflow-coordinator`, `shell-workflow-render`,
1305
+ `system-will-preview`, or `adjacent-surface-consistency` suites.
1306
+
1307
+ ### Release engineering
1308
+
1309
+ - `npm run release:gate` continues to use `test:release` with
1310
+ `--retry=2` for pre-existing test-order-dependent shell-spawn
1311
+ flakes documented in alpha.52 release engineering notes.
1312
+ - `check-stdin-ownership` continues to scan git-tracked files
1313
+ only.
1314
+
1315
+ Implementation PR:
1316
+
1317
+ - `shortgigs/usesteady-core#311` -- workflow invocation shapes
1318
+ (`examples` + shape-aware error guidance).
1319
+
1320
+ ### Posture after alpha.57
1321
+
1322
+ This is an **ergonomics stabilization release** -- not a capability
1323
+ expansion. The two-track rhythm continues:
1324
+
1325
+ - **Integrity track** -- alpha.55 SYSTEM WILL Preview monitoring
1326
+ window and alpha.56 adjacent-surface escape parity monitoring
1327
+ window both remain open.
1328
+ - **Capability track** -- alpha.57 monitoring window opens for the
1329
+ `examples` catalog and the four shape-aware error messages.
1330
+
1331
+ Watch for:
1332
+
1333
+ - Operators still arriving at a shape-mismatch error without
1334
+ reaching `usesteady examples` (could indicate the error-message
1335
+ pointer is being missed; would be a wording iteration, not a
1336
+ parser change).
1337
+ - Confusion about the auto-wrap behavior of `run <file>` (it
1338
+ accepts all three shapes; `--json` and `batch` only accept
1339
+ their own). Surfaced by the `examples` catalog explicitly.
1340
+ - Operators trying invocation shapes that aren't on the list
1341
+ (e.g. `--json @file.json`, `run <ops-array-stdin>`); these
1342
+ remain unsupported by design and should produce the existing
1343
+ error paths.
1344
+ - Any new render surface bypassing the four error-message
1345
+ addendums.
1346
+
1347
+ When this monitoring window resolves without signal, the next
1348
+ capability NOW pick remains section 3.11 workflow health
1349
+ diagnostics or section 3.6 execution timeline per the prior
1350
+ preference order, selected against observed signal.
1351
+
1352
+ ---
1353
+
1354
+ ## 0.1.0-alpha.56 - Adjacent-surface trust-language consistency
1355
+
1356
+ **Released:** May 2026
1357
+ **npm tag:** `alpha` - `npm install -g usesteady@alpha`
1358
+
1359
+ **Trust-consistency refinement release. No new capability surface.
1360
+ No authority-model change.** This is the final trust-clarity
1361
+ stabilization pass before opening another capability surface.
1362
+
1363
+ ### What this release fixes
1364
+
1365
+ The alpha.55 walkthrough closed the SYSTEM WILL trust gap for the
1366
+ `Preview:` block, but the real fresh-install pass exposed three
1367
+ remaining gaps at adjacent pre-approval surfaces:
1368
+
1369
+ - **F-A55-1** -- pre-approval intake echo (`[ok] Step N: Append
1370
+ "<value>" to <file>`) forged a second visual line whenever
1371
+ `<value>` contained a newline. The Preview block immediately
1372
+ below rendered the same content correctly. A user reading both
1373
+ saw two different representations of the same string.
1374
+ - **F-A55-2** -- `You asked:` line inside `task_ready` and
1375
+ `task_conflict` had the same root cause: the canonical input
1376
+ string carries user content verbatim, including embedded
1377
+ newlines, and was rendered without inline escaping.
1378
+ - **F-A55-3** -- pre-approval glyph was `[ok]`, which read as
1379
+ "completed successfully" -- the same semantic shape the
1380
+ COMPLETED frame's `[done]` glyph already owns. A first-time
1381
+ user could conclude a step had already run before any approval
1382
+ prompt.
1383
+ - **F-A55-4** -- `templates append-to-file` safety note told the
1384
+ operator to verify the target file exists, while runtime
1385
+ creates the file if missing. Pre-existing wording misalignment;
1386
+ not introduced by alpha.55 but visible at the new Preview
1387
+ surface.
1388
+
1389
+ ### What ships
1390
+
1391
+ Render-only changes. No execution-engine, planner, approval-model,
1392
+ operation-set, dependency, spec-hash, replay, or audit-envelope
1393
+ changes.
1394
+
1395
+ #### One shared primitive
1396
+
1397
+ New module `src/shell/render-escape.ts`. Single source of truth for
1398
+ the escape rule and for the lifecycle-stage glyphs every adjacent
1399
+ surface uses.
1400
+
1401
+ - `escapeControlForInline(raw)` -- escapes `\t` / `\r` / `\n` as
1402
+ C-style escape sequences. Leaves `\` and `"` alone so
1403
+ canonical-form bytes are preserved (the intake parser depends
1404
+ on those characters retaining grammar meaning).
1405
+ - `LIFECYCLE_PARSED = "[parsed]"`, `LIFECYCLE_NEEDS_CONFIRMATION
1406
+ = "[ ? ]"`, `LIFECYCLE_DONE = "[done]"` -- glyph constants for
1407
+ the lifecycle stages.
1408
+
1409
+ Pure, deterministic, zero deps. The Preview block's `previewInline`
1410
+ now delegates control-char escaping to this primitive so all
1411
+ adjacent surfaces share one byte-level escape contract.
1412
+
1413
+ #### F-A55-1 -- intake echo escapes user content
1414
+
1415
+ `formatDraftTask` (`src/shell/cli/draft/intent-to-tasks.ts`)
1416
+ routes every user value (`task.from` / `task.to` / `task.file` /
1417
+ `task.rawText`) through `escapeControlForInline`. Multi-line
1418
+ content can no longer forge a second visual line in the
1419
+ pre-approval echo.
1420
+
1421
+ #### F-A55-2 -- You asked: anchor escapes user content
1422
+
1423
+ `truthfulInputDisplay` (`src/shell/workflow-render.ts`) escapes
1424
+ the raw NL input via the shared primitive. The `structuredReplace`
1425
+ path additionally escapes `\` and `"` first (existing behavior),
1426
+ then control chars. `You asked:` is now single-line for any user
1427
+ content while remaining truthful (the line still contains the
1428
+ exact bytes the operator typed, only made inline-safe).
1429
+
1430
+ #### F-A55-3 -- lifecycle glyph clarification
1431
+
1432
+ Three intake-echo sites in `src/shell/cli/use-steady.ts`:
1433
+
1434
+ - `[ok] Step N: ...` -> `[parsed] Step N: ...`
1435
+ - Section header changes from "I translated your request into
1436
+ safe steps:" to "Parsed your request into safe steps (not yet
1437
+ executed):"
1438
+ - The `needs_confirmation` case becomes `[ ? ]` to stay visually
1439
+ separated from parsed steps.
1440
+
1441
+ No state-machine change, no execution path change -- only the
1442
+ visible tag and the section header.
1443
+
1444
+ #### F-A55-4 -- template / runtime wording alignment (PR #306)
1445
+
1446
+ Two `usesteady templates` safety-note misalignments closed:
1447
+
1448
+ - `append-to-file` safety note now says "If the target file does
1449
+ not exist, it will be created" instead of "verify the target
1450
+ file path exists before approving".
1451
+ - `git-safe-review-flow` safety note now says `create` on an
1452
+ existing file is refused with `target_exists` instead of
1453
+ ambiguous "is treated as ambiguous".
1454
+
1455
+ Both notes now match runtime behavior in
1456
+ `src/cursor/adapters/inprocess-adapter.ts`.
1457
+
1458
+ ### Lifecycle vocabulary after this release
1459
+
1460
+ | Stage | Glyph | Surface |
1461
+ | --- | --- | --- |
1462
+ | parsed/prepared | `[parsed]` | pre-approval intake echo |
1463
+ | needs-confirm | `[ ? ]` | unparseable clause |
1464
+ | review | numbered, no glyph | REVIEW frame |
1465
+ | approve | `->` | SYSTEM WILL anchor |
1466
+ | completed | `[done]` | terminal COMPLETED frame |
1467
+
1468
+ No two stages share a glyph. `parsed != approved != completed` is
1469
+ now visually guaranteed.
1470
+
1471
+ ### Friction -> Fix mapping (walkthrough-grounded)
1472
+
1473
+ | Friction observed in alpha.55 walkthrough | Fix in alpha.56 |
1474
+ | --- | --- |
1475
+ | Intake echo forged visual lines for multi-line content | `formatDraftTask` routes through `escapeControlForInline` |
1476
+ | `You asked:` line forged visual lines for multi-line content | `truthfulInputDisplay` routes through `escapeControlForInline` |
1477
+ | `[ok]` glyph readable as "completed" before approval | `[parsed]` glyph + "(not yet executed)" header |
1478
+ | Template safety notes contradicted runtime behavior | PR #306 wording alignment |
1479
+ | Adjacent surfaces rendered same content differently | Shared escape primitive used by all three surfaces |
1480
+
1481
+ ### Authority story
1482
+
1483
+ The renderer remains pure. The shared escape primitive is a
1484
+ 5-line pure function. The Preview block, the `You asked:` anchor,
1485
+ and the intake echo all consume the same primitive so a single
1486
+ byte-level escape contract governs every pre-approval render
1487
+ surface. The workflow spec hash (Row 2) continues to cover the
1488
+ spec end-to-end; the preview cannot drift from execution without
1489
+ the hash mismatching and the run aborting before any filesystem
1490
+ effect.
1491
+
1492
+ No new authority surface. No new operation type. No new approval
1493
+ mode. No semantic interpretation, no AI summarization, no
1494
+ autonomous decision-making.
1495
+
1496
+ ### What does NOT change
1497
+
1498
+ - Execution engine: byte-identical to alpha.55.
1499
+ - Planner: byte-identical.
1500
+ - Approval model: `task_ready` still produces a `confirm` prompt;
1501
+ nothing is auto-approved.
1502
+ - Operation set: same 8 operation types.
1503
+ - Dependencies: zero additions.
1504
+ - Spec hash semantics, replay, audit envelope: byte-identical.
1505
+ - Pre-alpha.56 fixtures (no control chars in user content) render
1506
+ byte-identically.
1507
+
1508
+ ### Tests
1509
+
1510
+ `tests/shell/adjacent-surface-consistency.test.ts` -- 46 new
1511
+ tests:
1512
+
1513
+ - `escapeControlForInline` primitive: newline / CR / tab / CRLF /
1514
+ multi-control / idempotence / determinism / single-line
1515
+ guarantee / empty-string identity / backslash and quote
1516
+ preservation.
1517
+ - F-A55-1: `formatDraftTask` escapes every value for every op
1518
+ type (append / prepend / replace / rename / create / delete /
1519
+ run_command / needs_confirmation).
1520
+ - F-A55-2: `task_ready` and `task_conflict` `You asked:` anchors
1521
+ never include literal newlines; `structuredReplace` path
1522
+ escapes from/to control chars.
1523
+ - Backward compat: non-control input renders byte-identically to
1524
+ pre-alpha.56 (phase-11d fixture regression guard).
1525
+ - Cross-surface parity: 9 representative content samples; inline-
1526
+ escaped bytes match across intake echo, `You asked:`, and
1527
+ Preview content.
1528
+ - Block vs inline: multi-line content uses Preview block mode AND
1529
+ single-line escaped `You asked:` simultaneously.
1530
+ - F-A55-3: glyph constants correct and pairwise distinct.
1531
+ - Approval-semantics regression guard: `task_ready` still
1532
+ produces a `confirm` prompt; render is pure.
1533
+
1534
+ PR #306 also added 4 wording-alignment tests on
1535
+ `tests/shell/templates.test.ts`.
1536
+
1537
+ Full suite: 4844 passed, 4 pre-existing skips. No regressions in
1538
+ `phase-11d` / `workflow-coordinator` / `shell-workflow-render` /
1539
+ `system-will-preview` / `templates` / `quickstart` /
1540
+ `capabilities` suites.
1541
+
1542
+ ### Release engineering
1543
+
1544
+ - `npm run release:gate` continues to use `test:release` with
1545
+ `--retry=2` for pre-existing test-order-dependent shell-spawn
1546
+ flakes documented in alpha.52 release engineering notes.
1547
+ - `check-stdin-ownership` continues to scan git-tracked files
1548
+ only.
1549
+
1550
+ Implementation PRs:
1551
+
1552
+ - `shortgigs/usesteady-core#306` -- template / runtime wording
1553
+ alignment.
1554
+ - `shortgigs/usesteady-core#309` -- adjacent-surface render
1555
+ consistency (F-A55-1 / F-A55-2 / F-A55-3).
1556
+
1557
+ ### Posture after alpha.56
1558
+
1559
+ This is the **final trust-clarity stabilization pass** before
1560
+ opening another capability surface. The two-track rhythm
1561
+ continues:
1562
+
1563
+ - **Integrity track** -- monitoring window for the alpha.55
1564
+ Preview block remains open; alpha.56 monitoring window opens
1565
+ for the adjacent-surface escape parity and lifecycle glyph
1566
+ vocabulary.
1567
+ - **Capability track** -- when the alpha.56 monitoring window
1568
+ resolves, the next bounded NOW pick remains section 3.11
1569
+ workflow health diagnostics or section 3.6 execution timeline,
1570
+ selected against observed signal.
1571
+
1572
+ Watch for:
1573
+
1574
+ - Confusion at the lifecycle vocabulary (parsed vs done vs review
1575
+ vs approve).
1576
+ - Operator running into the escape rule unexpectedly (e.g.
1577
+ literal `\n` in a string they wanted to be a real newline).
1578
+ - Adjacent-surface parity at large N (>5 tasks) review frames.
1579
+ - Any new render surface added in the next capability work that
1580
+ bypasses the shared primitive.
1581
+
1582
+ No proactive next capability surface this cycle. Trust-language
1583
+ coherence is the deliverable.
1584
+
1585
+ ---
1586
+
1587
+ ## 0.1.0-alpha.55 - SYSTEM WILL preview block (trust-clarity refinement)
1588
+
1589
+ **Released:** May 2026
1590
+ **npm tag:** `alpha` - `npm install -g usesteady@alpha`
1591
+
1592
+ **Not a new capability release.** A focused usability and explain-
1593
+ before-execute trust refinement. Renderer-only change. The
1594
+ execution engine, planner, approval model, operation set, and
1595
+ dependency set are byte-identical to alpha.54.
1596
+
1597
+ ### What this release fixes
1598
+
1599
+ The alpha.54 fresh-install walkthrough exposed a real onboarding-
1600
+ tail gap: at the `APPROVE?` frame for an `append` operation,
1601
+ `SYSTEM WILL` showed only the headline ("Append to NOTES.md") and
1602
+ the raw user input. The literal text being appended, the target
1603
+ file, and the file-creation behavior were all absent at the exact
1604
+ moment the operator was being asked to approve. Trust clarity
1605
+ collapsed at the highest-leverage approval surface.
1606
+
1607
+ ### What ships
1608
+
1609
+ A deterministic `Preview:` block embedded in the `task_ready` and
1610
+ `task_conflict` frames, plus a per-task summary in the `reviewing`
1611
+ phase. All preview content is sourced from the same
1612
+ `WorkflowTaskSpec` structured fields the executor consumes.
1613
+
1614
+ For an append op the operator now sees, before approving:
1615
+
1616
+ ```
1617
+ SYSTEM WILL
1618
+ -> Append to NOTES.md
1619
+ You asked: append "hello from usesteady" to NOTES.md
1620
+ Preview:
1621
+ Operation: append (text added to end of file)
1622
+ Target: NOTES.md
1623
+ Content: "hello from usesteady"
1624
+ File note: If NOTES.md does not exist, it will be created.
1625
+ ```
1626
+
1627
+ Per op type, the preview answers four questions: what kind of
1628
+ change, where, what literal text (verbatim, never paraphrased),
1629
+ and whether a missing/existing file changes runtime behavior.
1630
+
1631
+ | Op | Shape | File note (mirrors runtime) |
1632
+ | --- | --- | --- |
1633
+ | `append_file` | Operation / Target / Content | "If <file> does not exist, it will be created." |
1634
+ | `prepend_file` | Operation / Target / Content | same |
1635
+ | `write_file` | Operation / Target / Content | "If <file> already exists, the operation will fail (target_exists)." |
1636
+ | `replace` | Operation / Target / From / To | (no file note) |
1637
+ | `rename` | Operation / From / To | "If <newPath> already exists, the operation will fail (target_exists)." |
1638
+ | `delete_file` | Operation / Target | "Deletion is permanent within this workspace; verify the path." |
1639
+ | `create_dir` | Operation / Path | (no file note) |
1640
+ | `run_command` | Operation / Command | (no file note) |
1641
+
1642
+ The `reviewing` phase keeps the existing ` N. [runtime] label`
1643
+ header byte-for-byte (phase-11d tests assert on the numbering
1644
+ format), adds an indented compact summary beneath each task, and
1645
+ inserts a thin ` -----` separator between adjacent tasks.
1646
+ Single-task workflows render no separator. Unstructured (raw NL)
1647
+ tasks render the header only.
1648
+
1649
+ ### Deterministic truncation
1650
+
1651
+ - Inline content > 72 chars: visible head + `(truncated; N chars total)`.
1652
+ - Multi-line content: `Content (L lines, M chars):` header, body lines
1653
+ prefixed `| `, capped at 6 lines and 76 chars per line, tail
1654
+ `K more lines truncated` with singular/plural agreement.
1655
+ - C-style escapes (`\t`, `\r`, `\n`, `\"`, `\\`) so multi-line
1656
+ values cannot forge new visual lines inside an inline preview.
1657
+
1658
+ ### Friction -> Fix -> Invariant mapping
1659
+
1660
+ The walkthrough-recorded friction items closed by alpha.55:
1661
+
1662
+ | Friction (walkthrough) | Coverage | Invariant improved |
1663
+ | --- | --- | --- |
1664
+ | Append content invisible at approval | Full | Preview block sourced from spec, not from intake interpretation. |
1665
+ | File-create behavior implicit | Full | Each preview includes the runtime statement (`will be created` / `target_exists` / `permanent`). |
1666
+ | Batch workflows blurred together at review | Full | `reviewing` phase per-task block + N-1 separator. |
1667
+ | Long content risked terminal flood | Full | Deterministic truncation rules with explicit char/line counts. |
1668
+ | Multi-line content could forge visual lines | Full | C-style escape for tab/CR/newline/quote in inline previews. |
1669
+
1670
+ ### Authority story
1671
+
1672
+ The renderer remains pure (WS1). The preview is read from the same
1673
+ `WorkflowTaskSpec` fields the executor consumes. The workflow spec
1674
+ hash (Row 2) covers that spec end-to-end, so the preview cannot
1675
+ drift from the executed change without the hash mismatching and
1676
+ the run aborting before any filesystem effect.
1677
+
1678
+ The preview never paraphrases content; the operation-kind label is
1679
+ a fixed factual constant per type. No semantic interpretation, no
1680
+ AI summarization, no autonomous decision-making.
1681
+
1682
+ ### What does NOT change
1683
+
1684
+ - Execution engine: byte-identical.
1685
+ - Planner: byte-identical.
1686
+ - Approval model: `task_ready` still produces a `confirm` prompt;
1687
+ nothing is auto-approved.
1688
+ - Operation set: same 8 operation types as alpha.54.
1689
+ - Dependencies: zero additions.
1690
+ - Hidden execution: still zero.
1691
+ - Autonomy: still zero.
1692
+ - Spec hash semantics, replay, audit envelope: byte-identical.
1693
+
1694
+ ### Tests
1695
+
1696
+ `tests/shell/system-will-preview.test.ts` - 41 new tests covering:
1697
+
1698
+ - Per-op preview rendering (all 8 op types).
1699
+ - File-create messaging assertions per type.
1700
+ - Inline truncation at 72 chars; multi-line block at 6 lines / 76
1701
+ chars; singular/plural wording.
1702
+ - Escape rules for `\t`, `\r`, `\n`, `\"`, `\\`.
1703
+ - Fallback to `[]` for raw NL / missing fields.
1704
+ - `task_ready` ordering invariant (SYSTEM WILL -> headline ->
1705
+ You asked -> Preview).
1706
+ - `task_conflict` parity (same preview before
1707
+ `System will execute on approval.`).
1708
+ - `reviewing` phase: 1-based numbering preserved (regression
1709
+ guard), `[cursor]` / `[claude]` tags preserved, N-1 separators
1710
+ for N tasks, single-task no separator, mixed structured /
1711
+ unstructured tasks.
1712
+ - Byte-determinism across calls.
1713
+ - Renderer purity (no run mutation).
1714
+ - Confirm prompt still required.
1715
+
1716
+ Full suite: 4794 passed, 4 pre-existing skips. No regressions in
1717
+ `phase-11d` / `workflow-coordinator` / `shell-workflow-render`.
1718
+
1719
+ ### Release engineering
1720
+
1721
+ - `npm run release:gate` continues to use `test:release` with
1722
+ `--retry=2` for the pre-existing test-order-dependent shell-
1723
+ spawn flakes documented in alpha.52 release engineering notes.
1724
+ - `check-stdin-ownership` continues to scan git-tracked files only.
1725
+
1726
+ Implementation PR: `shortgigs/usesteady-core#307`.
1727
+ Implementation module: `src/shell/workflow-render.ts`
1728
+ (`operationPreviewLines`, `operationReviewSummaryLines`, plus
1729
+ `previewInline` / `previewBlock` helpers).
1730
+
1731
+ ### Posture after alpha.55
1732
+
1733
+ Trust-clarity refinement releases complete a friction -> fix -> release
1734
+ cycle from a real walkthrough. The next cycle starts with another
1735
+ real walkthrough on alpha.55. Hold for one operational cycle:
1736
+
1737
+ - Watch for confusion at the new Preview surface (off-spec
1738
+ expectations, line-cap surprises, escape misreads).
1739
+ - Watch for `reviewing` phase readability issues at large N (>5
1740
+ tasks).
1741
+ - Watch for truncation complaints (does a real user need a way to
1742
+ see the full content before approval, or do they need to abort
1743
+ and re-author the spec).
1744
+
1745
+ No proactive next capability surface this cycle. Trust-clarity
1746
+ refinements compose with onboarding; the next bounded NOW pick
1747
+ remains 3.11 workflow health diagnostics or 3.6 execution timeline,
1748
+ selected when the alpha.55 monitoring window resolves.
1749
+
1750
+ ---
1751
+
1752
+ ## 0.1.0-alpha.54 - Onboarding quickstart and starter templates
1753
+
1754
+ **Released:** May 2026
1755
+ **npm tag:** `alpha` - `npm install -g usesteady@alpha`
1756
+
1757
+ Second ship from the **Product Capability Track**. Goal: a brand-new
1758
+ user can go from install to a successful, reviewed workflow in under
1759
+ five minutes, without reading internal docs. Bounded scope: two new
1760
+ read-only subcommands and a README walkthrough. Zero authority impact.
1761
+
1762
+ ### What ships
1763
+
1764
+ Three onboarding surfaces, all read-only:
1765
+
1766
+ - `usesteady quickstart` - one-screen orientation. What UseSteady is,
1767
+ how to discover capabilities, how to pick a template, how to
1768
+ customize and run, plain-language approval explanation, where
1769
+ workflows execute, and how to stop safely. Pure text renderer;
1770
+ byte-for-byte deterministic.
1771
+ - `usesteady templates` - prints a list of safe starter workflows
1772
+ with one-line purposes.
1773
+ - `usesteady templates <name>` - prints one template in detail
1774
+ (purpose, required/optional fields, example values, safety notes,
1775
+ runnable JSON operations). `--output json` for machine-readable.
1776
+
1777
+ Five initial templates:
1778
+
1779
+ | Template | Operations |
1780
+ |---|---|
1781
+ | `append-to-file` | `append` |
1782
+ | `safe-rename` | `rename` |
1783
+ | `multi-file-replace` | `replace` (x3) |
1784
+ | `non-destructive-cleanup` | `create_dir` + `rename` (x2) |
1785
+ | `git-safe-review-flow` | `create` + `append` |
1786
+
1787
+ **No starter template uses `delete` or `run`.** Tests enforce this:
1788
+ starter templates are deliberately non-destructive and command-free.
1789
+ Every operation in every template is a member of `ALL_OPERATION_TYPES`
1790
+ (`src/input/op-registry.ts`); the registry is the single source of
1791
+ truth and tests assert there is no second op list to drift against.
1792
+
1793
+ README adds a "First 5 Minutes with UseSteady" section that walks
1794
+ the exact happy path: `quickstart` -> `capabilities` -> `templates` ->
1795
+ customize -> `batch` run -> approval / stop. No internal-doc
1796
+ references required.
1797
+
1798
+ Implementation PR: `shortgigs/usesteady-core#304`.
1799
+ Implementation modules: `src/shell/cli/quickstart.ts` and
1800
+ `src/shell/cli/templates.ts` (pure functions only; no I/O, no
1801
+ `process.exit`, no execution).
1802
+
1803
+ ### Friction -> Fix -> Invariant mapping
1804
+
1805
+ The Product Capability Track frictions are internally referenced as
1806
+ F-1..F-9 in the design doc. This release closes:
1807
+
1808
+ | Friction (track ref) | Coverage | Invariant improved |
1809
+ |---|---|---|
1810
+ | F-1 Manual batch JSON loading | full | Operators can copy a complete runnable JSON operation set from any template; no hand-crafting from registry summaries. |
1811
+ | F-7 Unclear first-run path | full | `usesteady quickstart` is the documented first command. README "First 5 Minutes" walks the full path without internal-doc references. |
1812
+ | F-8 Command authoring friction | full | Templates surface required/optional fields, example values, and safety notes for each starter workflow before invocation. |
1813
+ | F-2 Workflow scaffolding gap | partial | Five non-destructive templates cover the most common safe starting patterns. Custom workflows still require hand-authoring; that gap is deliberate. |
1814
+ | F-5 Approval surprise / opaque flow | partial | Quickstart explains the approval gate, `--yes` semantics, and how to stop safely in plain language; the runtime approval surface itself is unchanged. |
1815
+
1816
+ ### Authority story
1817
+
1818
+ - Deterministic approval model: unchanged.
1819
+ - No hidden execution: both new subcommands only print. Quickstart
1820
+ renders static text. Templates renders static catalog data. Neither
1821
+ module imports the planner, the safety gate, the executor, or any
1822
+ approval surface.
1823
+ - No autonomous authority expansion: no new authority granted. The
1824
+ set of executable operations did NOT grow. Only inspection
1825
+ surfaces grew.
1826
+ - Explain-before-execute: strengthened. Operators now see a
1827
+ pre-formatted, safety-noted recipe before authoring a workflow.
1828
+ - Bounded execution semantics: unchanged. Templates are static data;
1829
+ printing a template is not running one.
1830
+ - `--yes` semantics: unchanged. `quickstart` and `templates` join
1831
+ `capabilities` in the documented `--yes`-exempt list because they
1832
+ never execute. Every other path still requires `--yes` for
1833
+ `--output json` execution.
1834
+
1835
+ ### What does NOT change
1836
+
1837
+ - No `src/input/` change. No registry change. No IR change.
1838
+ - No safety detector, drift detector, sanitizer, or canonicalizer
1839
+ change. PRs #293 / #294 / #297 surfaces are untouched.
1840
+ - No execution engine change. Planner, executor, and approval
1841
+ surfaces are byte-identical to alpha.53.
1842
+ - No new operation types. Templates compose only operations from the
1843
+ existing `ALL_OPERATION_TYPES`.
1844
+ - No new runtime dependencies.
1845
+ - No model-insertion path change. No new prompt surfaces. No AI
1846
+ workflow generation. Templates are hand-authored static data.
1847
+ - No edits to ShortGigs, YODHA, StructureGuard, or SteadyHealth.
1848
+
1849
+ ### Tests
1850
+
1851
+ 73 of 73 tests pass across the three onboarding-adjacent surfaces:
1852
+
1853
+ - `tests/shell/capabilities.test.ts` (17, regression)
1854
+ - `tests/shell/templates.test.ts` (41 new)
1855
+ - `tests/shell/quickstart.test.ts` (15 new)
1856
+
1857
+ Key invariants enforced by tests:
1858
+
1859
+ - Every operation in every template uses a registered op type.
1860
+ - No starter template uses `delete` or `run`.
1861
+ - Quickstart text and template output are byte-for-byte deterministic.
1862
+ - `--output json` works without `--yes` on all three read-only paths.
1863
+ - Unknown template names exit non-zero with a helpful stderr line.
1864
+ - Negative-content guarantees on quickstart: no "autonomous", no
1865
+ "ai will fix", no "agent will" language anywhere in the orientation.
1866
+
1867
+ ### Release engineering
1868
+
1869
+ No changes to the release gate. `test:release` retains the `--retry=2`
1870
+ flake mitigation from alpha.52. `check-stdin-ownership` runs the same
1871
+ git-tracked-only scan.
1872
+
1873
+ ### Surface-specific monitoring
1874
+
1875
+ Stabilization window for the onboarding surface opens with this
1876
+ release. Watch for:
1877
+
1878
+ - Confusion in the quickstart text (specific lines that mislead a
1879
+ first-time user).
1880
+ - Template copy/paste failures (JSON that doesn't parse cleanly
1881
+ when pasted, escape-sequence misreads).
1882
+ - Approval-flow surprises after following the quickstart (anything
1883
+ the operator sees at run time that the quickstart did not prepare
1884
+ them for).
1885
+ - Trust/perception issues (any place where the operator cannot tell
1886
+ whether something is "just printing" or "about to run").
1887
+
1888
+ If real friction surfaces in this window, one bounded follow-up PR
1889
+ ships. No multi-candidate expansion.
1890
+
1891
+ ---
1892
+
1893
+ ## 0.1.0-alpha.53 - Capability explorer (first Product Capability Track ship)
1894
+
1895
+ **Released:** May 2026
1896
+ **npm tag:** `alpha` - `npm install -g usesteady@alpha`
1897
+
1898
+ First implementation candidate from the **Product Capability Track**
1899
+ (`docs/product/useability-and-guided-execution-track.md` section 3.1,
1900
+ merged in shortgigs/usesteady-core#299). Bounded scope: one new
1901
+ read-only subcommand. Zero authority impact.
1902
+
1903
+ ### What ships
1904
+
1905
+ `usesteady capabilities` - prints a structured catalog of every IR
1906
+ operation this build supports. Reads directly from
1907
+ `src/input/op-registry.ts` (`ALL_OPERATION_TYPES` +
1908
+ `OPERATION_REGISTRY`); no second source of truth.
1909
+
1910
+ - Default output: human-readable text.
1911
+ - `--output json`: deterministic single-line JSON catalog. Exempt
1912
+ from the global `--output json` + `--yes` rule because the
1913
+ catalog has no execution path; `--yes` is meaningless for it.
1914
+ - `--help` on the subcommand: subcommand-specific usage.
1915
+ - Listed in `PURE_SUBCOMMANDS` (no stdin sampling).
1916
+ - Listed in `HELP_TEXT` for global discoverability.
1917
+
1918
+ Implementation PR: `shortgigs/usesteady-core#300`.
1919
+ Implementation module: `src/shell/cli/capabilities.ts` (pure
1920
+ functions only; no I/O, no `process.exit`, no execution).
1921
+
1922
+ ### Friction -> Fix -> Invariant mapping
1923
+
1924
+ The Product Capability Track frictions are internally referenced
1925
+ as F-1..F-9 in the design doc (not public issue numbers, since
1926
+ they were proactively identified rather than reported). This
1927
+ release closes:
1928
+
1929
+ | Friction (track ref) | Coverage | Invariant improved |
1930
+ |---|---|---|
1931
+ | F-9 Weak discoverability of supported operations | full | Every operation the build supports is enumerable from inside the product itself. No external doc lookup required. |
1932
+ | F-1 Manual batch JSON loading | partial | Operators can copy a public-JSON shape from the catalog instead of hand-crafting from source. Curated workflow templates (track section 3.2) remain queued. |
1933
+ | F-8 Command authoring friction | partial | Required and optional fields per op surface before invocation. Authoring errors are now visible at catalog read time, not at safety-gate-rejection time. |
1934
+
1935
+ ### Authority story (preserved verbatim from track section 6)
1936
+
1937
+ - Deterministic approval model: unchanged. Catalog never approves.
1938
+ - No hidden execution: catalog cannot mutate state. No side effects
1939
+ on import or invocation.
1940
+ - No autonomous authority expansion: no new authority granted.
1941
+ - Explain-before-execute: unchanged.
1942
+ - Replayability: unchanged.
1943
+ - Bounded execution semantics: the set of executable operations did
1944
+ NOT grow. Only the surface to **inspect** them grew. This
1945
+ distinction is load-bearing (track section 6.6).
1946
+
1947
+ ### What does NOT change
1948
+
1949
+ - No `src/input/` change. No registry change. No IR change.
1950
+ - No safety detector, drift detector, sanitizer, or canonicalizer
1951
+ touch.
1952
+ - No approval state machine change.
1953
+ - No UCP envelope schema change.
1954
+ - No K5 boundary change. No `MODEL_INSERTION_POLICY` touch.
1955
+ - No new doctrine, ADR, or governance document.
1956
+ - No NL-intake involvement. The catalog is built from the static
1957
+ registry, not from any model.
1958
+
1959
+ ### Tests
1960
+
1961
+ - `tests/shell/capabilities.test.ts` (new): 17 tests covering
1962
+ invariants I1..I7 (catalog coverage of `ALL_OPERATION_TYPES`,
1963
+ deterministic byte-for-byte output, `--yes` not required,
1964
+ `--output json` works without `--yes`, every op has a parseable
1965
+ JSON example, catalog is frozen, registry fields surface
1966
+ verbatim).
1967
+ - No existing test modified. Governance test
1968
+ (`tests/governance/input-surface-integrity.test.ts`) and registry
1969
+ test (`tests/input/op-registry.test.ts`) unchanged: 141/141 pass.
1970
+
1971
+ Full suite: 4697 passed, 4 skipped (132 files).
1972
+
1973
+ ### Public demonstration
1974
+
1975
+ `README.md` updated with a "Discover what UseSteady can do"
1976
+ section under Install, showing the command, its output, and the
1977
+ `--output json` variant. The README explicitly notes the catalog
1978
+ shares the same registry the executor uses (no doc drift).
1979
+
1980
+ ### Sequencing posture
1981
+
1982
+ - Product Capability Track NOW queue: section 3.1 SHIPPED in this release.
1983
+ Remaining NOW: section 3.2 (curated templates), section 3.6 (execution
1984
+ timeline view), section 3.11 (workflow health diagnostics). Per track
1985
+ section 7, one PR per candidate; the next NOW candidate opens only
1986
+ after this surface stabilizes through one monitoring window.
1987
+ - Cluster B (alpha.52) monitoring window: still active through
1988
+ 2026-05-18 unless triggers fire. This release does not touch
1989
+ any Cluster B surface; window unaffected.
1990
+ - `capabilities` opens its own observation window on landing.
1991
+ Read-only surface; thresholds calibrated narrow:
1992
+ - regression trigger: any deterministic-output drift, any
1993
+ catalog coverage gap (op missing or extra), any exit-code
1994
+ change.
1995
+ - volume trigger: 3+ reports of operator confusion mapped to
1996
+ F-9 / F-1 / F-8 within 14 days indicating the catalog is
1997
+ surfacing the wrong information.
1998
+
1999
+ ### Release engineering
2000
+
2001
+ No changes to `scripts/check-stdin-ownership.mjs` or
2002
+ `release:gate`. The alpha.52 release-engineering deltas (scanner
2003
+ gitignore-respect; `vitest run --retry=2` in `release:gate`)
2004
+ remain in place.
2005
+
2006
+ ---
2007
+
2008
+ ## 0.1.0-alpha.52 - Canonicalization, Workflow Integrity, Process Lifecycle Anchor
2009
+
2010
+ **Released:** May 2026
2011
+ **npm tag:** `alpha` - `npm install -g usesteady@alpha`
2012
+
2013
+ Three implementation-level fixes plus one definitional anchor. All three
2014
+ fixes share a common invariant theme - surface-spanning consistency -
2015
+ applied across distinct axes:
2016
+
2017
+ - Row 1 (PR shortgigs/usesteady-core#293): input canonicalization in
2018
+ front of every safety detector.
2019
+ - Row 2 (PR shortgigs/usesteady-core#294): deterministic workflow spec
2020
+ hash with revalidation before every advancement.
2021
+ - Cluster B (PR shortgigs/usesteady-core#297): extends the Row 1
2022
+ canonical view to four adjacent surfaces where two views of the same
2023
+ string could otherwise diverge.
2024
+ - Cluster A anchor (PR shortgigs/usesteady-core#296): docs-only
2025
+ definitional anchor for CLI process lifecycle authority. No runtime
2026
+ code in this release. Implementation gated on this design.
2027
+
2028
+ ### Friction -> Fix -> Invariant mapping (Cluster B)
2029
+
2030
+ This release closes the implementation-ready portion of Cluster B from
2031
+ the May 2026 friction wave. The cluster map for the wave lives at
2032
+ `shortgigs/usesteady-public#75`.
2033
+
2034
+ | Friction | Issue | Severity | Fix surface | Invariant improved |
2035
+ |---|---|---|---|---|
2036
+ | U+202E in filename accepted without validation | shortgigs/usesteady-public#50 | P0 | `pathEscapesWorkspace` (filename validation) + OCD path comparison + adapter `allowedFiles` check | A path that escapes the workspace in canonical form is refused even when the original-form regex would have let it through. Adjacent surfaces (validator, OCD, adapter) see the same canonical interpretation. |
2037
+ | Literal string matching ignores Unicode normalization (NFC vs NFD) | shortgigs/usesteady-public#51 | P2 | `inprocess-adapter.receive` replace-match: canonical/original occurrence-count gate | Original-form and canonical-form occurrence counts must agree before a replace is allowed. NFC vs NFD divergence is detected and refused rather than silently mis-matching. |
2038
+ | U+202E in replacement text accepted | shortgigs/usesteady-public#52 | P0 | `inprocess-adapter.receive` replace-match gate; `searchForOldValue` cross-file gate | Replace `oldValue` must canonicalize to itself; a `oldValue` whose canonical form differs is refused (`ambiguous_match`, "match-count mismatch"). Same gate applies to multi-file search. |
2039
+ | Mixed-script homograph filenames (Cyrillic vs Latin) | shortgigs/usesteady-public#53 | P2 | Partial - Cluster B catches mixed-script when combined with other obfuscation (canonical-form path comparison divergence); pure NFKC does NOT fold scripts | This release does NOT fully resolve pure-script homograph spoofing. NFKC normalization is the wrong tool for script-level confusion. The issue remains `status/accepted` pending a separate script-detection track. |
2040
+
2041
+ ### Row 1 - Input canonicalization (foundation)
2042
+
2043
+ Source: SafeHarness research finding (`docs/architecture/usesteady-safeharness-hardening-map.md`, Row 1). No specific friction issue.
2044
+
2045
+ What changes:
2046
+ - New module `src/safety/canonicalize.ts` exporting
2047
+ `canonicalizeForSafety` and `CanonicalizationError`.
2048
+ - Transform (fixed order): NFKC normalize -> strip zero-width
2049
+ codepoints (U+200B, U+200C, U+200D, U+2060, U+FEFF) -> strip
2050
+ bidirectional controls (U+200E, U+200F, U+202A-U+202E,
2051
+ U+2066-U+2069).
2052
+ - Hooked at: `src/safety/safety-gate.ts` (canonicalize before every
2053
+ detector), `src/control/compiler.ts` (canonicalize `rawRequest`,
2054
+ `plannedChanges.summary[]`, `plannedChanges.files[]` before the
2055
+ drift detector).
2056
+ - Fail-closed: `CanonicalizationError` produces a blocked verdict
2057
+ with reason `evasion_or_rule_bypass` (safety gate) or
2058
+ `canonicalization_failed` (control compiler).
2059
+ - Original (raw) strings are preserved on audit fields verbatim.
2060
+
2061
+ Invariant: detectors see the canonical form; audit retains the raw
2062
+ form. Replay determinism unchanged.
2063
+
2064
+ ### Row 2 - Workflow spec deterministic hash + revalidation
2065
+
2066
+ Source: SafeHarness research finding (hardening map Row 2). No
2067
+ specific friction issue.
2068
+
2069
+ What changes:
2070
+ - New module `src/workflow/spec-hash.ts` exporting
2071
+ `computeWorkflowSpecHash` and `verifyWorkflowSpecHash`.
2072
+ - `WorkflowRun` carries `workflowSpecHash: string` (set at
2073
+ `createWorkflowRun`, never mutated).
2074
+ - `advanceWorkflow` and `deliverWorkflowTask` revalidate the hash
2075
+ before every transition. Mismatch aborts the run.
2076
+ - Hash stays in execution/session metadata only. No signing system,
2077
+ no distributed trust, no network dependency.
2078
+
2079
+ Invariant: the executing run is bit-for-bit the run that was
2080
+ approved. Spec drift between approval and execution aborts rather
2081
+ than executing silently.
2082
+
2083
+ ### Cluster A - CLI process lifecycle authority boundary (anchor only)
2084
+
2085
+ Source: friction wave issues shortgigs/usesteady-public#70-#74.
2086
+
2087
+ What changes:
2088
+ - New design document `docs/architecture/cli-process-lifecycle-authority-boundary.md` (390 lines).
2089
+ - Defines the load-bearing invariant: a CLI invocation's authority
2090
+ over OS processes is limited to the invocation interval; every
2091
+ spawned process must terminate within the interval or be
2092
+ explicitly enumerated as an authorized outlive-exception.
2093
+ - Names two violation classes (unauthorized outliving, unauthorized
2094
+ invocation replacement via `exec`); defines a closed-class
2095
+ outlive-exception mechanism shape; sketches the containment
2096
+ surface (per-invocation process registry + syscall refusal list
2097
+ + teardown protocol).
2098
+ - NOT implemented in this release. Implementation is gated on the
2099
+ decisions in section 11 of the design document.
2100
+
2101
+ Invariant established (not yet enforced): no process whose
2102
+ existence cannot be accounted for by the operator at invocation-end
2103
+ is authorized.
2104
+
2105
+ ### What does NOT change
2106
+
2107
+ - No new approval state, UCP envelope schema, or ControlEnvelope
2108
+ schema.
2109
+ - No SafetyResult schema change. No detector logic change.
2110
+ - No K5 boundary change. No MODEL_INSERTION_POLICY change.
2111
+ - No replay determinism change.
2112
+ - No new doctrine file. No new ADR.
2113
+ - No autonomous-execution surface. No semantic-review surface.
2114
+ - No NL grammar change.
2115
+
2116
+ ### Tests
2117
+
2118
+ - `tests/safety/canonicalize.test.ts` (new with Row 1): 28 tests.
2119
+ - `tests/safety/safety-gate.test.ts`: +8 tests for canonicalization
2120
+ bypass attempts (clean inputs unchanged).
2121
+ - `tests/control/control-envelope.test.ts`: +6 tests for canonical
2122
+ control compilation.
2123
+ - `tests/workflow/spec-hash.test.ts` (new with Row 2): 14 tests.
2124
+ - `tests/workflow/workflow-coordinator.test.ts`: +existing
2125
+ revalidation coverage.
2126
+ - `tests/safety/canonicalize-adjacent-surfaces.test.ts` (new with
2127
+ Cluster B): 44 tests across all five required categories (U+202E,
2128
+ NFC/NFD equivalence, BIDI controls, replacement-text matching,
2129
+ filename/path denylist).
2130
+
2131
+ Full suite: 4680 passed, 4 skipped.
2132
+
2133
+ ### Release engineering
2134
+
2135
+ - `scripts/check-stdin-ownership.mjs` now scans only git-tracked files
2136
+ via `git ls-files src`. Locally-added or `.gitignore`'d tools (e.g.
2137
+ the proprietary `friction-admin.ts` that ships in a separate repo)
2138
+ no longer trip the public single-stdin-owner invariant guard. Falls
2139
+ back to scanning everything when `git` is unavailable.
2140
+ - `npm run release:gate` now runs `vitest run --retry=2` instead of
2141
+ `vitest run`. Local `npm test` is unchanged. The retry is bounded
2142
+ and only papers over stochastic process-spawn races in tests that
2143
+ shell out to the CLI; a test failing three times in a row is still
2144
+ a real failure.
2145
+
2146
+ ### Issue label transitions
2147
+
2148
+ After publish, the following issues transition from
2149
+ `status/accepted` to `status/shipped` in
2150
+ `shortgigs/usesteady-public`:
2151
+
2152
+ - #50, #51, #52 (Cluster B fixes shipped here)
2153
+
2154
+ The following remain `status/accepted` pending further work:
2155
+
2156
+ - #53 (Cluster B partial; pure-script homograph spoofing requires
2157
+ a separate detection track)
2158
+ - #70-#74 (Cluster A; anchor landed, implementation deferred)
2159
+ - All other May 2026 wave issues (clusters C-H and lower-priority
2160
+ distinct items)
2161
+
2162
+ ---
2163
+
2164
+ ## 0.1.0-alpha.51 - S4: Trust & Surface Integrity Completion
2165
+
2166
+ **Released:** April 2026
2167
+ **npm tag:** `alpha` - `npm install -g usesteady@alpha`
2168
+
2169
+ Stabilization Pass 4 (S4). Closes friction reports #44 (P1, Input
2170
+ Surface Integrity), #42 (P2, Trust frame), #43 (P3, Trust display).
2171
+ Issue #41 (batch rollback) remains parked.
2172
+
2173
+ ### Breaking change - R4 uniform (Option alpha)
2174
+
2175
+ Pre-S4 the WorkflowSpec input surface accepted bare-NL `replace` forms
2176
+ without an explicit occurrence clause:
2177
+
2178
+ ```jsonc
2179
+ { "tasks": [{ "input": "replace \"X\" with \"Y\" in file.ts" }] }
2180
+ ```
2181
+
2182
+ The legacy coordinator NL fallback (`parseChange`) silently treated
2183
+ this as "first occurrence." The same NL string typed at `--prompt` was
2184
+ already rejected with R4 ("explicit occurrence required") - so
2185
+ identical NL input behaved differently across surfaces, breaking the
2186
+ alpha.49 contract: *same NL string -> same behavior everywhere*.
2187
+
2188
+ S4 closes the gap. `normalizeNLToIR` is now the single NL parser;
2189
+ `tasks[].input` is normalized at spec-load time; R4 is enforced
2190
+ uniformly across `--prompt`, `WorkflowSpec`, and any future NL
2191
+ surface. No coordinator fallback. No spec-load shortcut. No hidden
2192
+ public surface.
2193
+
2194
+ **Migration.** Any `replace` task in a `WorkflowSpec` MUST now include
2195
+ an explicit occurrence clause:
2196
+
2197
+ | Before (now fails with `invalid_op`) | After |
2198
+ |------------------------------------------|-----------------------------------------------------------------|
2199
+ | `replace "X" with "Y" in file.ts` | `replace "X" with "Y" in file.ts first occurrence` |
2200
+ | | `replace "X" with "Y" in file.ts all occurrences` |
2201
+ | | `replace "X" with "Y" in file.ts <Nth> occurrence` |
2202
+
2203
+ Programmatic alternatives are unchanged: pass `structuredReplace`
2204
+ (`{oldValue, newValue, filePath}`) directly, or use a JSON op shape
2205
+ (`{ "type": "replace", "file": ..., "from": ..., "to": ... }`) - both
2206
+ already mean "first occurrence" by construction.
2207
+
2208
+ This is a controlled breaking fix in favor of trust consistency.
2209
+
2210
+ ### What changed
2211
+
2212
+ **#44 - WorkflowSpec NL parity (P1, Input Surface Integrity)**
2213
+
2214
+ - New `src/shell/cli/spec-nl-synth.ts`. `loadWorkflowSpecFromFile`
2215
+ routes `tasks[].input` through `normalizeNLToIR` and synthesizes
2216
+ structured fields (`operationType`, `content`, `targetFiles`,
2217
+ `structuredReplace`, ...) at the input boundary.
2218
+ - New shared `src/shell/cli/ir-to-spec-fields.ts` - single canonical
2219
+ `Operation -> WorkflowTaskSpec structured-fields` mapper, used by
2220
+ both the NL synthesizer and `buildSpecTasksFromIROps` so the JSON-op
2221
+ and NL paths cannot drift again.
2222
+ - `src/workflow/coordinator.ts` no longer imports `parseChange` and
2223
+ no longer defines `hasDeterministicReplaceInput`. The runtime NL
2224
+ fallback inside `advanceWorkflow` is gone. `isDeterministicTaskSpec`
2225
+ only inspects structured fields.
2226
+ - User-supplied `targetFiles` continue to win over synthesizer-
2227
+ produced ones; only synthesizer-derived fields fill gaps.
2228
+
2229
+ **#43 - `replace` placeholder lie (P3, Trust display)**
2230
+
2231
+ `src/shell/workflow-render.ts` adds `truthfulInputDisplay`. When a
2232
+ task carries `structuredReplace`, the `You asked:` line is derived
2233
+ from `oldValue`/`newValue`/`filePath` - the executor's actual inputs
2234
+ - instead of the parser-stable placeholder produced by
2235
+ `buildSpecTasksFromIROps`. NL surfaces (where `input` is the literal
2236
+ user text) are unchanged. Render-only transform; `taskSpec.input`
2237
+ stays parser-stable so intake classification is unaffected.
2238
+
2239
+ **#42 - OCD `CONFLICT` frame (P2, Trust frame)**
2240
+
2241
+ `task_conflict` header renamed: `CONFLICT` ->
2242
+ `WARNING - OCD conflict detected (non-blocking)`. Frame body now ends
2243
+ with `System will execute on approval.` so the rendered severity
2244
+ matches the actual gate (the system never blocks; H gates). Confirm
2245
+ prompt updated to `Accept warning and approve task? (y/n)`. Pure
2246
+ renderer change. State machine, OCD evaluator, and policy untouched.
2247
+
2248
+ ### Governance lock extension
2249
+
2250
+ `tests/governance/input-surface-integrity.test.ts` adds:
2251
+
2252
+ - WorkflowSpec NL parity assertions ("same NL string -> same
2253
+ behavior everywhere"): every form `--prompt` rejects is also
2254
+ rejected via `loadWorkflowSpecFromFile`; every form it accepts
2255
+ synthesizes the same `operationType`.
2256
+ - Structural invariants: `src/workflow/coordinator.ts` no longer
2257
+ imports `parseChange` and no longer defines
2258
+ `hasDeterministicReplaceInput`. Future regressions caught at
2259
+ test time, not at runtime.
2260
+
2261
+ ### Real proof (workflow-04)
2262
+
2263
+ `tests/governance/nl-real-workflow-replay.test.ts` adds workflow-04:
2264
+ write a `WorkflowSpec` with a single NL `append` task, run
2265
+ `usesteady run spec.json --yes`, verify file mutation, verify the
2266
+ persisted artifact carries `operationType: "append_file"` (the smoking
2267
+ gun for #44 - pre-S4 the artifact lacked this), and verify replay
2268
+ match.
2269
+
2270
+ `labs/shortgigs-workflow-03/README.md` extends the locked runbook
2271
+ with Spec D (`WorkflowSpec NL parity / S4 / #44`), pinning the same
2272
+ proof against published binaries.
2273
+
2274
+ ### Out of scope (locked)
2275
+
2276
+ #41 (batch rollback), executor changes, kernel changes, safety changes,
2277
+ feasibility validator changes, NL grammar additions, K5, ShortGigs
2278
+ integration, error code names, exit codes.
2279
+
2280
+ ### Pre-publish gates
2281
+
2282
+ - `npm run build` -> ok
2283
+ - `npm test` -> 4535 / 4539 pass, 4 skipped
2284
+ - `npm run verify:pack-clean` -> ok (933 files, 0 private artifacts)
2285
+ - Lab proof workflow-04 (post-merge on master) -> exit 0, file
2286
+ mutated, artifact `f97322b40320d473a7ad150a27ab38cc2d06735fc48a0c7cf3adad0c569a49c1`
2287
+ carries `operationType: "append_file"`, replay -> `match`
2288
+ - Lab proof workflow-03 A/B/C/D (post-merge) -> all four specs
2289
+ succeed
2290
+ - R4 negative path -> a WorkflowSpec replace without occurrence exits
2291
+ 1 with `invalid_op` and the canonical migration message
2292
+
2293
+ ## 0.1.0-alpha.43 - Kernel v1
2294
+
2295
+ **Released:** April 2026
2296
+ **npm tag:** `alpha` - opt in with `npm install -g usesteady@alpha`
2297
+ **Latest stable tag:** `0.1.0-alpha.4` (unchanged)
2298
+
2299
+ First alpha cut of the Kernel v1 trust surface. Nothing in the workflow
2300
+ coordinator, approval model, safety gate, or policy engine changed. What
2301
+ changed is the determinism surface the CLI now emits, how errors are
2302
+ classified before they reach that surface, and how human output is
2303
+ shaped at the end of a run. Landed as three kernel PRs plus one
2304
+ release-gate hotfix.
2305
+
2306
+ ### What changed
2307
+
2308
+ **Deterministic replay artifact (PR-K1, #239)**
2309
+
2310
+ Every successful CLI run now persists a content-addressed artifact at
2311
+ `<storeDir>/replay/<checksum>.artifact.json` containing:
2312
+
2313
+ ```
2314
+ { version, ir, result, checksum }
2315
+ ```
2316
+
2317
+ `ir` is the existing `WorkflowSpec` (reused, not reinvented). `result`
2318
+ is a strictly deterministic summary (`success`, `error`,
2319
+ `executed_steps`, `failed_at_step`, `total_steps`) - no timestamps, no
2320
+ paths, no stdout, no randomness. `checksum` is `sha256` over the
2321
+ canonical JSON of `{ ir, result }` with stable key ordering. Identical
2322
+ runs produce identical filenames.
2323
+
2324
+ New subcommand `usesteady replay <artifact-file>` performs integrity
2325
+ verification only:
2326
+
2327
+ ```
2328
+ { "replay": "match" | "mismatch", "original_checksum": "...", "new_checksum": "..." }
2329
+ ```
2330
+
2331
+ No workflow re-execution, no `process.argv` mutation, no side effect
2332
+ beyond reading the artifact file. Full execution replay is deferred.
2333
+
2334
+ **Canonical CLI error-code taxonomy (PR-K2, #240)**
2335
+
2336
+ A single closed `CanonicalErrorCode` enum now backs every error string
2337
+ that reaches the final CLI summary, the kernel result, or the artifact
2338
+ result. A central `finalizeErrorCode` choke point normalizes codes
2339
+ before `_errorCode` materialization. Consensus-layer capture was widened
2340
+ beyond `runtime === "cursor"` so Claude consensus codes survive to the
2341
+ final surface.
2342
+
2343
+ No public shape change. `KernelResult.error` and the CLI JSON `error`
2344
+ field stay `string | null`; the enum is internal. What changes is that
2345
+ different failures no longer collapse into a generic `execution_error`.
2346
+
2347
+ **Single-voice human output (PR-K3, #241)**
2348
+
2349
+ Pre-PR-K3 every terminal run printed three different vocabularies to
2350
+ stdout: a workflow-render frame, a `Terminal outcome:` classifier line,
2351
+ and the PR-2 summary block. K3 keeps only the PR-2 summary block as the
2352
+ user-facing final result. The `Terminal outcome:`,
2353
+ `COMPLETED:`/`STOPPED_BY_USER:`/`FAILED_EXPLICIT:` lines no longer reach
2354
+ stdout. `persistWorkflowTerminalOutcome` writes the record to disk
2355
+ unchanged; classifier message strings in that record are identical;
2356
+ exit codes propagate as before.
2357
+
2358
+ `loadWorkflowSpecFromFile` now throws `WorkflowSpecLoadError` with a
2359
+ canonical K2 code and a single-sentence message (no Node-errno dialect,
2360
+ no duplicated path). The interactive workflow/history banner is
2361
+ suppressed under `--yes`; the `UseSteady ? Workflow` separator
2362
+ (mojibake-to-`?`) is now clean ASCII `UseSteady - Workflow`.
2363
+
2364
+ One narrow JSON parity fix: `usesteady run <missing>.json --yes
2365
+ --output json` now emits a canonical JSON error to stdout instead of
2366
+ exiting silently with human stderr only. Other JSON parity gaps
2367
+ (`batch`, `replay`, unknown-subcommand, `--output json` without
2368
+ `--yes`) remain deferred.
2369
+
2370
+ **Release-gate hotfix (#242)**
2371
+
2372
+ K1 shipped two kernel files using `import fs from "node:fs"` default
2373
+ imports, which the repo's `"esModuleInterop": false` tsconfig rejects.
2374
+ On master `npm run build` exited 2 and silently broke `prepublishOnly`.
2375
+ Switched to named imports (`mkdirSync`, `writeFileSync`, `join`,
2376
+ `readFileSync`) - the style used elsewhere in `src/shell/cli/`. No
2377
+ behavior change.
2378
+
2379
+ ### What was not changed
2380
+
2381
+ - The workflow coordinator, approval model, and execution path
2382
+ - The safety gate, detectors, and category routing
2383
+ - The consensus policy and `ConsensusAuditRecord` type
2384
+ - The public CLI summary shape (`success`, `error`, `failed_at_step`, `executed_steps`, `total_steps`)
2385
+ - All INV-ML-, INV-CE- invariants
2386
+ - The on-disk `WorkflowTerminalRecord` or its classifier strings
2387
+ - Exit codes for any path
2388
+ - The `SYSTEM WILL` format or any marketing surface
2389
+
2390
+ ### Deferred to later kernel PRs
2391
+
2392
+ - Full execution replay (PR-K1 is artifact-integrity replay only)
2393
+ - JSON parity for `batch`, `replay`, unknown-subcommand, and `--output json` without `--yes`
2394
+ - Widening the canonical error taxonomy through the shadow envelope and terminal record (K2 D5)
2395
+ - Conflict-frame retuning, REVIEW-frame dedupe, friction-footer coalescing, consensus-block output work (K3 non-goals)
2396
+ - `ci(release): run npm run build in Repo validation` and `chore(release): wire release:gate into prepublishOnly` (governance follow-ups)
2397
+
2398
+ ---
2399
+
2400
+ ## 0.1.0-alpha.10 - UX Clarity Layer
2401
+
2402
+ **Released:** April 2026
2403
+ **npm tag:** `alpha` - opt in with `npm install -g usesteady@alpha`
2404
+ **Latest stable tag:** `0.1.0-alpha.4` (unchanged)
2405
+
2406
+ This release adds a clarity layer on top of the existing execution core. Nothing
2407
+ in the coordinator, policy engine, or consensus system was changed. What changed
2408
+ is everything the user sees before and after execution runs.
2409
+
2410
+ ### What changed
2411
+
2412
+ **Draft Mode** (`usesteady "plain English instruction"`)
2413
+
2414
+ The CLI now accepts free-text input directly. It translates the intent into
2415
+ structured steps, shows them with `OK` / `?` indicators, and asks for
2416
+ confirmation before routing to the existing execution pipeline. Unrecognised
2417
+ clauses are marked `needs_confirmation: true` and pass through with the original
2418
+ text preserved - nothing is silently dropped.
2419
+
2420
+ **`usesteady help` command**
2421
+
2422
+ New `help` subcommand shows supported actions, exact formats, and an honest
2423
+ description of plain-English input. Distinct from `--help`, which shows
2424
+ command-line options.
2425
+
2426
+ **Consensus explanation in CLI**
2427
+
2428
+ After a workflow completes, the CLI prints a human-readable consensus result
2429
+ when multi-model mode was active. Uses file-offset correlation so the output
2430
+ matches this run only. Shows "Passed (N rounds)" on success, or the specific
2431
+ disagreement reason (capability / scope / semantic) on block. No hashes or
2432
+ internal enum names exposed.
2433
+
2434
+ **Intake failure guidance**
2435
+
2436
+ When one or more workflow steps are skipped by the intake parser
2437
+ (`skipped_by_intake`), the completed/stopped CLI frame now appends the
2438
+ supported format examples - matching the guidance already shown in the web UI.
2439
+
2440
+ **UI copy updates**
2441
+
2442
+ - Consensus indicator: `"multi | OK Unanimous 2r"` -> `"Multi-model check: OK Passed (2 rounds)"`
2443
+ - Policy block label: `"Blocked by policy"` -> `"Blocked - models did not agree on execution"`
2444
+
2445
+ **Marketing site - story shift**
2446
+
2447
+ Landing page: new `FlowSection` with the four-step Describe -> Preview -> Approve
2448
+ -> Execute flow. CLI demo updated to show Draft Mode. Consensus section updated
2449
+ to show concrete pass/block examples instead of abstract architecture copy.
2450
+
2451
+ Docs page: restructured to be usable-first. New sections: Supported Actions,
2452
+ Examples (six real commands), When Blocked (three reasons with fixes). No
2453
+ internal terms, no invariant documentation, no architecture theory in the
2454
+ user-facing path.
2455
+
2456
+ ### What was not changed
2457
+
2458
+ - The coordinator, Forge execution loop, and all advance functions
2459
+ - The multi-LLM consensus policy and `ConsensusAuditRecord` type
2460
+ - All INV-ML-, INV-CE- invariants
2461
+ - The `SYSTEM WILL` format
2462
+ - The approval authority model - human approval required before every step
2463
+
2464
+ ---
2465
+
2466
+ ## 0.1.0-alpha.9 - Deterministic Execution Runtime
2467
+
2468
+ **Released:** April 2026
2469
+ **npm tag:** `alpha` - opt in with `npm install -g usesteady@alpha`
2470
+ **Latest stable tag:** `0.1.0-alpha.4` (unchanged)
2471
+
2472
+ This release formalises the execution layer that has been running in controlled
2473
+ environments since the public alpha. The core guarantee - nothing runs without
2474
+ explicit human approval - is unchanged. What is new is the architectural depth
2475
+ behind that guarantee.
2476
+
2477
+ ### What changed
2478
+
2479
+ **Deterministic workflow execution**
2480
+
2481
+ The workflow coordinator sequences approved tasks through a fixed state machine:
2482
+ `approve -> execute -> observe -> resolve`. Every transition is explicit. No step
2483
+ is inferred, skipped, or reordered. The same input produces the same approval
2484
+ request every time.
2485
+
2486
+ **Optional multi-model policy enforcement**
2487
+
2488
+ When `USESTEADY_LLM_MODE=multi` is set, execution requests require agreement
2489
+ across models before proceeding. Agreement is defined as matching normalised
2490
+ decision hashes - not just multiple "accepted" responses. If models disagree,
2491
+ execution is blocked. This is disabled by default.
2492
+
2493
+ **Fail-closed behaviour**
2494
+
2495
+ Policy disagreement is a hard stop, not a fallback. The system does not proceed
2496
+ on partial agreement, does not fall back to a single model's verdict, and does
2497
+ not silently degrade. When the policy layer blocks execution, the failure note
2498
+ says why.
2499
+
2500
+ **Full audit trail**
2501
+
2502
+ Every execution decision is logged with its outcome, reason, and - in
2503
+ multi-model mode - the consensus record for that request. The log is
2504
+ append-only. Nothing that ran is absent from the record.
2505
+
2506
+ ### Notes
2507
+
2508
+ - Multi-model mode is optional and inactive by default. Enable it with
2509
+ `USESTEADY_LLM_MODE=multi` and the appropriate API keys.
2510
+ - No UI code is included in this package. The runtime is fully standalone.
2511
+ - The approval authority model is unchanged. Human approval is required before
2512
+ any step executes, regardless of what the policy layer returns.
2513
+ - Consensus verdicts are input signals to the coordinator. They do not override
2514
+ human approval authority.
2515
+
2516
+ ### What was not changed
2517
+
2518
+ - The approval flow visible to users
2519
+ - The `SYSTEM WILL` format
2520
+ - The CLI interface
2521
+ - Any existing workflow spec format
2522
+
2523
+ ---
2524
+
2525
+ ## 0.1.0-alpha.9 and earlier
2526
+
2527
+ See git history for the public alpha changelog.