openlanes 3.0.0

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 (466) hide show
  1. checksums.yaml +7 -0
  2. data/agents/hansolo-reviewer.md +59 -0
  3. data/agents/lando-broker.md +70 -0
  4. data/agents/leah-researcher.md +60 -0
  5. data/agents/luke-backend.md +73 -0
  6. data/agents/palpatine-planner.md +61 -0
  7. data/agents/r2d2-mechanic.md +57 -0
  8. data/agents/rey-frontend.md +68 -0
  9. data/agents/yoda-writer.md +67 -0
  10. data/bin/factory-e2e +157 -0
  11. data/bin/plan-number +164 -0
  12. data/bin/setup +26 -0
  13. data/evals/cases/hansolo-reviewer/review-medium/fail/plan/plan.md +3 -0
  14. data/evals/cases/hansolo-reviewer/review-medium/fail/plan/pull-requests.md +12 -0
  15. data/evals/cases/hansolo-reviewer/review-medium/fail/plan/spec.md +5 -0
  16. data/evals/cases/hansolo-reviewer/review-medium/fail/repo/lib/cart.rb +9 -0
  17. data/evals/cases/hansolo-reviewer/review-medium/fail/repo/spec/cart_spec.rb +7 -0
  18. data/evals/cases/hansolo-reviewer/review-medium/fail/run.json +1 -0
  19. data/evals/cases/hansolo-reviewer/review-medium/pass/plan/plan.md +3 -0
  20. data/evals/cases/hansolo-reviewer/review-medium/pass/plan/pull-requests.md +15 -0
  21. data/evals/cases/hansolo-reviewer/review-medium/pass/plan/spec.md +5 -0
  22. data/evals/cases/hansolo-reviewer/review-medium/pass/repo/lib/cart.rb +9 -0
  23. data/evals/cases/hansolo-reviewer/review-medium/pass/repo/spec/cart_spec.rb +7 -0
  24. data/evals/cases/hansolo-reviewer/review-medium/pass/run.json +1 -0
  25. data/evals/cases/hansolo-reviewer/review-medium.yml +60 -0
  26. data/evals/cases/lando-broker/unblock-fast/fail/plan/blocked.md +9 -0
  27. data/evals/cases/lando-broker/unblock-fast/fail/plan/spec.md +16 -0
  28. data/evals/cases/lando-broker/unblock-fast/fail/run.json +1 -0
  29. data/evals/cases/lando-broker/unblock-fast/pass/plan/spec.md +18 -0
  30. data/evals/cases/lando-broker/unblock-fast/pass/run.json +1 -0
  31. data/evals/cases/lando-broker/unblock-fast.yml +44 -0
  32. data/evals/cases/leah-researcher/research-deep/fail/plan/spec.md +26 -0
  33. data/evals/cases/leah-researcher/research-deep/fail/run.json +1 -0
  34. data/evals/cases/leah-researcher/research-deep/pass/plan/spec.md +39 -0
  35. data/evals/cases/leah-researcher/research-deep/pass/run.json +1 -0
  36. data/evals/cases/leah-researcher/research-deep.yml +51 -0
  37. data/evals/cases/leah-researcher/research-fast/fail/plan/spec.md +27 -0
  38. data/evals/cases/leah-researcher/research-fast/fail/run.json +1 -0
  39. data/evals/cases/leah-researcher/research-fast/pass/plan/spec.md +23 -0
  40. data/evals/cases/leah-researcher/research-fast/pass/run.json +1 -0
  41. data/evals/cases/leah-researcher/research-fast.yml +55 -0
  42. data/evals/cases/luke-backend/build-medium/fail/plan/plan-backend.md +7 -0
  43. data/evals/cases/luke-backend/build-medium/fail/plan/plan-frontend.md +1 -0
  44. data/evals/cases/luke-backend/build-medium/fail/plan/plan.md +3 -0
  45. data/evals/cases/luke-backend/build-medium/fail/plan/pull-requests.md +8 -0
  46. data/evals/cases/luke-backend/build-medium/fail/plan/spec.md +8 -0
  47. data/evals/cases/luke-backend/build-medium/fail/repo/Gemfile +2 -0
  48. data/evals/cases/luke-backend/build-medium/fail/repo/lib/cart.rb +11 -0
  49. data/evals/cases/luke-backend/build-medium/fail/repo/spec/cart_spec.rb +7 -0
  50. data/evals/cases/luke-backend/build-medium/fail/run.json +1 -0
  51. data/evals/cases/luke-backend/build-medium/pass/plan/plan-backend.md +7 -0
  52. data/evals/cases/luke-backend/build-medium/pass/plan/plan-frontend.md +1 -0
  53. data/evals/cases/luke-backend/build-medium/pass/plan/plan.md +3 -0
  54. data/evals/cases/luke-backend/build-medium/pass/plan/pull-requests.md +8 -0
  55. data/evals/cases/luke-backend/build-medium/pass/plan/spec.md +8 -0
  56. data/evals/cases/luke-backend/build-medium/pass/repo/Gemfile +2 -0
  57. data/evals/cases/luke-backend/build-medium/pass/repo/lib/cart.rb +11 -0
  58. data/evals/cases/luke-backend/build-medium/pass/repo/spec/cart_spec.rb +11 -0
  59. data/evals/cases/luke-backend/build-medium/pass/run.json +1 -0
  60. data/evals/cases/luke-backend/build-medium.yml +68 -0
  61. data/evals/cases/palpatine-planner/plan-deep/fail/plan/plan-backend.md +6 -0
  62. data/evals/cases/palpatine-planner/plan-deep/fail/plan/plan.md +8 -0
  63. data/evals/cases/palpatine-planner/plan-deep/fail/plan/spec.md +14 -0
  64. data/evals/cases/palpatine-planner/plan-deep/fail/run.json +1 -0
  65. data/evals/cases/palpatine-planner/plan-deep/pass/plan/plan-backend.md +32 -0
  66. data/evals/cases/palpatine-planner/plan-deep/pass/plan/plan-frontend.md +1 -0
  67. data/evals/cases/palpatine-planner/plan-deep/pass/plan/plan.md +28 -0
  68. data/evals/cases/palpatine-planner/plan-deep/pass/plan/spec.md +14 -0
  69. data/evals/cases/palpatine-planner/plan-deep/pass/run.json +1 -0
  70. data/evals/cases/palpatine-planner/plan-deep.yml +50 -0
  71. data/evals/cases/palpatine-planner/plan-fast/fail/plan/plan-backend.md +48 -0
  72. data/evals/cases/palpatine-planner/plan-fast/fail/plan/plan-frontend.md +1 -0
  73. data/evals/cases/palpatine-planner/plan-fast/fail/plan/plan.md +12 -0
  74. data/evals/cases/palpatine-planner/plan-fast/fail/plan/spec.md +12 -0
  75. data/evals/cases/palpatine-planner/plan-fast/fail/run.json +1 -0
  76. data/evals/cases/palpatine-planner/plan-fast/pass/plan/plan-backend.md +8 -0
  77. data/evals/cases/palpatine-planner/plan-fast/pass/plan/plan-frontend.md +1 -0
  78. data/evals/cases/palpatine-planner/plan-fast/pass/plan/plan.md +12 -0
  79. data/evals/cases/palpatine-planner/plan-fast/pass/plan/spec.md +12 -0
  80. data/evals/cases/palpatine-planner/plan-fast/pass/run.json +1 -0
  81. data/evals/cases/palpatine-planner/plan-fast.yml +47 -0
  82. data/evals/cases/r2d2-mechanic/task-fast/fail/plan/plan.md +7 -0
  83. data/evals/cases/r2d2-mechanic/task-fast/fail/plan/pull-requests.md +6 -0
  84. data/evals/cases/r2d2-mechanic/task-fast/fail/plan/spec.md +6 -0
  85. data/evals/cases/r2d2-mechanic/task-fast/fail/repo/README.md +3 -0
  86. data/evals/cases/r2d2-mechanic/task-fast/fail/repo/lib/greeter/formatter.rb +12 -0
  87. data/evals/cases/r2d2-mechanic/task-fast/fail/repo/lib/greeter.rb +15 -0
  88. data/evals/cases/r2d2-mechanic/task-fast/fail/repo/spec/greeter_spec.rb +7 -0
  89. data/evals/cases/r2d2-mechanic/task-fast/fail/run.json +1 -0
  90. data/evals/cases/r2d2-mechanic/task-fast/pass/plan/plan.md +7 -0
  91. data/evals/cases/r2d2-mechanic/task-fast/pass/plan/pull-requests.md +6 -0
  92. data/evals/cases/r2d2-mechanic/task-fast/pass/plan/spec.md +6 -0
  93. data/evals/cases/r2d2-mechanic/task-fast/pass/repo/README.md +3 -0
  94. data/evals/cases/r2d2-mechanic/task-fast/pass/repo/lib/greeter.rb +3 -0
  95. data/evals/cases/r2d2-mechanic/task-fast/pass/repo/spec/greeter_spec.rb +7 -0
  96. data/evals/cases/r2d2-mechanic/task-fast/pass/run.json +1 -0
  97. data/evals/cases/r2d2-mechanic/task-fast.yml +59 -0
  98. data/evals/cases/r2d2-mechanic/task-medium/fail/plan/plan.md +7 -0
  99. data/evals/cases/r2d2-mechanic/task-medium/fail/plan/pull-requests.md +6 -0
  100. data/evals/cases/r2d2-mechanic/task-medium/fail/plan/spec.md +6 -0
  101. data/evals/cases/r2d2-mechanic/task-medium/fail/repo/Gemfile +2 -0
  102. data/evals/cases/r2d2-mechanic/task-medium/fail/repo/lib/greeter.rb +6 -0
  103. data/evals/cases/r2d2-mechanic/task-medium/fail/repo/spec/greeter_spec.rb +11 -0
  104. data/evals/cases/r2d2-mechanic/task-medium/fail/run.json +1 -0
  105. data/evals/cases/r2d2-mechanic/task-medium/pass/plan/plan.md +7 -0
  106. data/evals/cases/r2d2-mechanic/task-medium/pass/plan/pull-requests.md +6 -0
  107. data/evals/cases/r2d2-mechanic/task-medium/pass/plan/spec.md +6 -0
  108. data/evals/cases/r2d2-mechanic/task-medium/pass/repo/Gemfile +2 -0
  109. data/evals/cases/r2d2-mechanic/task-medium/pass/repo/lib/greeter.rb +6 -0
  110. data/evals/cases/r2d2-mechanic/task-medium/pass/repo/spec/greeter_spec.rb +11 -0
  111. data/evals/cases/r2d2-mechanic/task-medium/pass/run.json +1 -0
  112. data/evals/cases/r2d2-mechanic/task-medium.yml +58 -0
  113. data/evals/cases/rey-frontend/ui-medium/fail/plan/plan-frontend.md +7 -0
  114. data/evals/cases/rey-frontend/ui-medium/fail/plan/plan.md +4 -0
  115. data/evals/cases/rey-frontend/ui-medium/fail/plan/pull-requests.md +8 -0
  116. data/evals/cases/rey-frontend/ui-medium/fail/plan/spec.md +5 -0
  117. data/evals/cases/rey-frontend/ui-medium/fail/repo/lib/cart.rb +5 -0
  118. data/evals/cases/rey-frontend/ui-medium/fail/repo/web/cart_badge.js +4 -0
  119. data/evals/cases/rey-frontend/ui-medium/fail/repo/web/cart_badge.test.js +3 -0
  120. data/evals/cases/rey-frontend/ui-medium/fail/run.json +1 -0
  121. data/evals/cases/rey-frontend/ui-medium/pass/plan/plan-frontend.md +7 -0
  122. data/evals/cases/rey-frontend/ui-medium/pass/plan/plan.md +4 -0
  123. data/evals/cases/rey-frontend/ui-medium/pass/plan/pull-requests.md +8 -0
  124. data/evals/cases/rey-frontend/ui-medium/pass/plan/spec.md +5 -0
  125. data/evals/cases/rey-frontend/ui-medium/pass/repo/lib/cart.rb +3 -0
  126. data/evals/cases/rey-frontend/ui-medium/pass/repo/web/cart_badge.js +4 -0
  127. data/evals/cases/rey-frontend/ui-medium/pass/repo/web/cart_badge.test.js +3 -0
  128. data/evals/cases/rey-frontend/ui-medium/pass/run.json +1 -0
  129. data/evals/cases/rey-frontend/ui-medium.yml +55 -0
  130. data/evals/cases/yoda-writer/spec-medium/fail/plan/plan.md +5 -0
  131. data/evals/cases/yoda-writer/spec-medium/fail/plan/spec.md +45 -0
  132. data/evals/cases/yoda-writer/spec-medium/fail/run.json +1 -0
  133. data/evals/cases/yoda-writer/spec-medium/pass/plan/plan.md +0 -0
  134. data/evals/cases/yoda-writer/spec-medium/pass/plan/spec.md +63 -0
  135. data/evals/cases/yoda-writer/spec-medium/pass/run.json +1 -0
  136. data/evals/cases/yoda-writer/spec-medium.yml +40 -0
  137. data/exe/depot +1 -0
  138. data/exe/lanes +1 -0
  139. data/exe/openlanes +32 -0
  140. data/lib/openlanes/adapters/base.rb +69 -0
  141. data/lib/openlanes/adapters/claude.rb +124 -0
  142. data/lib/openlanes/adapters/codex.rb +33 -0
  143. data/lib/openlanes/adapters/model.rb +37 -0
  144. data/lib/openlanes/adapters/pi.rb +22 -0
  145. data/lib/openlanes/adapters/stream.rb +196 -0
  146. data/lib/openlanes/adapters.rb +92 -0
  147. data/lib/openlanes/agents/agent.rb +103 -0
  148. data/lib/openlanes/agents/profile.rb +57 -0
  149. data/lib/openlanes/agents/registry.rb +151 -0
  150. data/lib/openlanes/agents/roster.rb +103 -0
  151. data/lib/openlanes/agents/routing.rb +88 -0
  152. data/lib/openlanes/agents.rb +20 -0
  153. data/lib/openlanes/cli/agents/subcommands/describe.rb +66 -0
  154. data/lib/openlanes/cli/agents/subcommands/list.rb +20 -0
  155. data/lib/openlanes/cli/base.rb +263 -0
  156. data/lib/openlanes/cli/create/create.rb +354 -0
  157. data/lib/openlanes/cli/docs/docs.rb +40 -0
  158. data/lib/openlanes/cli/eval/eval.rb +110 -0
  159. data/lib/openlanes/cli/index/index.rb +40 -0
  160. data/lib/openlanes/cli/init/init.rb +145 -0
  161. data/lib/openlanes/cli/linear/linear.rb +36 -0
  162. data/lib/openlanes/cli/linear/subcommands/import.rb +174 -0
  163. data/lib/openlanes/cli/linear/subcommands/projects.rb +55 -0
  164. data/lib/openlanes/cli/list_plans/list_plans.rb +21 -0
  165. data/lib/openlanes/cli/mail/mail.rb +31 -0
  166. data/lib/openlanes/cli/mail/subcommands/read.rb +43 -0
  167. data/lib/openlanes/cli/mail/subcommands/send.rb +43 -0
  168. data/lib/openlanes/cli/resync/subcommands/dirs.rb +48 -0
  169. data/lib/openlanes/cli/resync/subcommands/prs.rb +111 -0
  170. data/lib/openlanes/cli/run/run.rb +544 -0
  171. data/lib/openlanes/cli/skills/subcommands/install.rb +92 -0
  172. data/lib/openlanes/cli/start/start.rb +110 -0
  173. data/lib/openlanes/cli/state/state.rb +26 -0
  174. data/lib/openlanes/cli/state/subcommands/show.rb +30 -0
  175. data/lib/openlanes/cli/state/subcommands/sign.rb +48 -0
  176. data/lib/openlanes/cli/states/states.rb +15 -0
  177. data/lib/openlanes/cli/unblock/unblock.rb +235 -0
  178. data/lib/openlanes/cli/version/version.rb +13 -0
  179. data/lib/openlanes/cli/web/web.rb +100 -0
  180. data/lib/openlanes/cli/worktree/worktree.rb +85 -0
  181. data/lib/openlanes/cli.rb +162 -0
  182. data/lib/openlanes/engine/board.rb +104 -0
  183. data/lib/openlanes/engine/dispatcher.rb +1297 -0
  184. data/lib/openlanes/engine/progress_log.rb +125 -0
  185. data/lib/openlanes/engine/runner.rb +224 -0
  186. data/lib/openlanes/engine/state_file.rb +190 -0
  187. data/lib/openlanes/engine/tally.rb +177 -0
  188. data/lib/openlanes/engine.rb +19 -0
  189. data/lib/openlanes/evals/case.rb +191 -0
  190. data/lib/openlanes/evals/changes.rb +67 -0
  191. data/lib/openlanes/evals/check.rb +224 -0
  192. data/lib/openlanes/evals/evidence.rb +71 -0
  193. data/lib/openlanes/evals/live.rb +140 -0
  194. data/lib/openlanes/evals/recording.rb +38 -0
  195. data/lib/openlanes/evals/run.rb +34 -0
  196. data/lib/openlanes/evals/score.rb +24 -0
  197. data/lib/openlanes/evals/scorer.rb +42 -0
  198. data/lib/openlanes/evals/verdict.rb +18 -0
  199. data/lib/openlanes/evals.rb +56 -0
  200. data/lib/openlanes/execution/checks.rb +73 -0
  201. data/lib/openlanes/execution/child.rb +228 -0
  202. data/lib/openlanes/execution/clock.rb +121 -0
  203. data/lib/openlanes/execution/control.rb +194 -0
  204. data/lib/openlanes/execution/executor.rb +849 -0
  205. data/lib/openlanes/execution/prompt.rb +455 -0
  206. data/lib/openlanes/execution/transcript.rb +531 -0
  207. data/lib/openlanes/execution.rb +19 -0
  208. data/lib/openlanes/launcher.rb +69 -0
  209. data/lib/openlanes/lifecycle/adoption.rb +197 -0
  210. data/lib/openlanes/lifecycle/brief.rb +288 -0
  211. data/lib/openlanes/lifecycle/completion.rb +58 -0
  212. data/lib/openlanes/lifecycle/creator.rb +126 -0
  213. data/lib/openlanes/lifecycle/lanes.rb +74 -0
  214. data/lib/openlanes/lifecycle/resync.rb +428 -0
  215. data/lib/openlanes/lifecycle/unblocker.rb +236 -0
  216. data/lib/openlanes/lifecycle.rb +28 -0
  217. data/lib/openlanes/linear/api.rb +224 -0
  218. data/lib/openlanes/linear/attribution.rb +185 -0
  219. data/lib/openlanes/linear/fuzzy.rb +68 -0
  220. data/lib/openlanes/linear/import.rb +314 -0
  221. data/lib/openlanes/linear/issue.rb +187 -0
  222. data/lib/openlanes/linear/mapping.rb +116 -0
  223. data/lib/openlanes/linear/push.rb +197 -0
  224. data/lib/openlanes/linear/survey.rb +174 -0
  225. data/lib/openlanes/linear/unit.rb +274 -0
  226. data/lib/openlanes/linear.rb +41 -0
  227. data/lib/openlanes/live/claims.rb +71 -0
  228. data/lib/openlanes/live/command.rb +122 -0
  229. data/lib/openlanes/live/commands.rb +505 -0
  230. data/lib/openlanes/live/keys.rb +93 -0
  231. data/lib/openlanes/live/memory_store.rb +265 -0
  232. data/lib/openlanes/live/meter.rb +51 -0
  233. data/lib/openlanes/live/node.rb +88 -0
  234. data/lib/openlanes/live/publisher.rb +179 -0
  235. data/lib/openlanes/live/repo.rb +60 -0
  236. data/lib/openlanes/live/run_record.rb +133 -0
  237. data/lib/openlanes/live/run_state.rb +101 -0
  238. data/lib/openlanes/live/session.rb +107 -0
  239. data/lib/openlanes/live/snapshot.rb +322 -0
  240. data/lib/openlanes/live/stations.rb +67 -0
  241. data/lib/openlanes/live/store.rb +277 -0
  242. data/lib/openlanes/live.rb +109 -0
  243. data/lib/openlanes/plans/dev_work.rb +56 -0
  244. data/lib/openlanes/plans/feature.rb +131 -0
  245. data/lib/openlanes/plans/index.rb +208 -0
  246. data/lib/openlanes/plans/ledger.rb +255 -0
  247. data/lib/openlanes/plans/mailbox.rb +164 -0
  248. data/lib/openlanes/plans/ordinal.rb +92 -0
  249. data/lib/openlanes/plans/plan_state.rb +291 -0
  250. data/lib/openlanes/plans/pull_request.rb +29 -0
  251. data/lib/openlanes/plans/pull_requests.rb +229 -0
  252. data/lib/openlanes/plans/spec.rb +213 -0
  253. data/lib/openlanes/plans/state_machine.rb +433 -0
  254. data/lib/openlanes/plans/status.rb +365 -0
  255. data/lib/openlanes/plans/subject.rb +133 -0
  256. data/lib/openlanes/plans/tree.rb +79 -0
  257. data/lib/openlanes/plans.rb +39 -0
  258. data/lib/openlanes/presentation/diagram.rb +149 -0
  259. data/lib/openlanes/presentation/documentation.rb +438 -0
  260. data/lib/openlanes/presentation/reporter.rb +181 -0
  261. data/lib/openlanes/presentation/viewer.rb +62 -0
  262. data/lib/openlanes/presentation.rb +23 -0
  263. data/lib/openlanes/skills/installer.rb +68 -0
  264. data/lib/openlanes/skills/skill.rb +60 -0
  265. data/lib/openlanes/skills.rb +25 -0
  266. data/lib/openlanes/support/config.rb +217 -0
  267. data/lib/openlanes/support/frontmatter.rb +38 -0
  268. data/lib/openlanes/support/markdown.rb +56 -0
  269. data/lib/openlanes/support/project.rb +79 -0
  270. data/lib/openlanes/support/ui.rb +671 -0
  271. data/lib/openlanes/vcs/github.rb +171 -0
  272. data/lib/openlanes/vcs/publisher.rb +221 -0
  273. data/lib/openlanes/vcs/worktree.rb +248 -0
  274. data/lib/openlanes/vcs.rb +19 -0
  275. data/lib/openlanes/version.rb +10 -0
  276. data/lib/openlanes/web/app.rb +176 -0
  277. data/lib/openlanes/web/context.rb +66 -0
  278. data/lib/openlanes/web/demo.rb +169 -0
  279. data/lib/openlanes/web/demo_board.rb +286 -0
  280. data/lib/openlanes/web/events.rb +104 -0
  281. data/lib/openlanes/web/launcher.rb +143 -0
  282. data/lib/openlanes/web/server.rb +77 -0
  283. data/lib/openlanes/web/stores.rb +36 -0
  284. data/lib/openlanes/web.rb +92 -0
  285. data/lib/openlanes.rb +151 -0
  286. data/openlanes.gemspec +87 -0
  287. data/schemas/plan-state.schema.json +101 -0
  288. data/skills/openlanes/SKILL.md +48 -0
  289. data/skills/openlanes-documents/SKILL.md +61 -0
  290. data/skills/openlanes-documents/references/blocked-template.md +49 -0
  291. data/skills/openlanes-documents/references/closing-templates.md +59 -0
  292. data/skills/openlanes-documents/references/plan-template.md +61 -0
  293. data/skills/openlanes-documents/references/retroactive-spec.md +43 -0
  294. data/skills/openlanes-documents/references/spec-template.md +45 -0
  295. data/skills/openlanes-run/SKILL.md +90 -0
  296. data/skills/openlanes-setup/SKILL.md +64 -0
  297. data/skills/openlanes-spec/SKILL.md +90 -0
  298. data/skills/openlanes-status/SKILL.md +32 -0
  299. data/skills/openlanes-sync/SKILL.md +22 -0
  300. data/web/dist/assets/apl-B4CMkyY2.js +2 -0
  301. data/web/dist/assets/asciiarmor-Df11BRmG.js +2 -0
  302. data/web/dist/assets/asn1-EdZsLKOL.js +2 -0
  303. data/web/dist/assets/asterisk-B-8jnY81.js +2 -0
  304. data/web/dist/assets/barlow-condensed-latin-600-normal-BFJEwTuo.woff +0 -0
  305. data/web/dist/assets/barlow-condensed-latin-600-normal-DepVgxBB.woff2 +0 -0
  306. data/web/dist/assets/barlow-condensed-latin-ext-600-normal-18ESti3H.woff2 +0 -0
  307. data/web/dist/assets/barlow-condensed-latin-ext-600-normal-Clv9cIcR.woff +0 -0
  308. data/web/dist/assets/barlow-condensed-vietnamese-600-normal-A5AYRdjN.woff2 +0 -0
  309. data/web/dist/assets/barlow-condensed-vietnamese-600-normal-CNlPk46_.woff +0 -0
  310. data/web/dist/assets/brainfuck-C4LP7Hcl.js +2 -0
  311. data/web/dist/assets/clike-B9uivgTg.js +2 -0
  312. data/web/dist/assets/clojure-BMjYHr_A.js +2 -0
  313. data/web/dist/assets/cmake-BQqOBYOt.js +2 -0
  314. data/web/dist/assets/cobol-CWcv1MsR.js +2 -0
  315. data/web/dist/assets/coffeescript-S37ZYGWr.js +2 -0
  316. data/web/dist/assets/commonlisp-DBKNyK5s.js +2 -0
  317. data/web/dist/assets/crystal-SjHAIU92.js +2 -0
  318. data/web/dist/assets/css-BnMrqG3P.js +2 -0
  319. data/web/dist/assets/cypher-C_CwsFkJ.js +2 -0
  320. data/web/dist/assets/d-pRatUO7H.js +2 -0
  321. data/web/dist/assets/diff-DbItnlRl.js +2 -0
  322. data/web/dist/assets/dockerfile-BKs6k2Af.js +2 -0
  323. data/web/dist/assets/dtd-DF_7sFjM.js +2 -0
  324. data/web/dist/assets/dylan-DwRh75JA.js +2 -0
  325. data/web/dist/assets/ebnf-CDyGwa7X.js +2 -0
  326. data/web/dist/assets/ecl-Cabwm37j.js +2 -0
  327. data/web/dist/assets/eiffel-CnydiIhH.js +2 -0
  328. data/web/dist/assets/elm-vLlmbW-K.js +2 -0
  329. data/web/dist/assets/erlang-BNw1qcRV.js +2 -0
  330. data/web/dist/assets/factor-kuTfRLto.js +2 -0
  331. data/web/dist/assets/favicon-C8pAuqqr.png +0 -0
  332. data/web/dist/assets/fcl-Kvtd6kyn.js +2 -0
  333. data/web/dist/assets/forth-Ffai-XNe.js +2 -0
  334. data/web/dist/assets/fortran-DYz_wnZ1.js +2 -0
  335. data/web/dist/assets/gas-Bneqetm1.js +2 -0
  336. data/web/dist/assets/gherkin-heZmZLOM.js +2 -0
  337. data/web/dist/assets/groovy-D9Dt4D0W.js +2 -0
  338. data/web/dist/assets/haskell-Cw1EW3IL.js +2 -0
  339. data/web/dist/assets/haxe-H-WmDvRZ.js +2 -0
  340. data/web/dist/assets/http-DBlCnlav.js +2 -0
  341. data/web/dist/assets/idl-BEugSyMb.js +2 -0
  342. data/web/dist/assets/index-2xPC-eHt.js +2 -0
  343. data/web/dist/assets/index-8dNhRmiO.js +8 -0
  344. data/web/dist/assets/index-B7-O9ujQ.js +2 -0
  345. data/web/dist/assets/index-BdR34cXC.js +2 -0
  346. data/web/dist/assets/index-Bp7W-ZTq.js +2 -0
  347. data/web/dist/assets/index-Byyxbh_z.js +4 -0
  348. data/web/dist/assets/index-C0VmkrO-.js +2 -0
  349. data/web/dist/assets/index-CI74IkWP.js +198 -0
  350. data/web/dist/assets/index-CYxcbpRM.js +3 -0
  351. data/web/dist/assets/index-D0rmJN3h.js +2 -0
  352. data/web/dist/assets/index-DB4QwuYn.js +2 -0
  353. data/web/dist/assets/index-DDI7zoAS.js +2 -0
  354. data/web/dist/assets/index-DGLUuEXi.js +2 -0
  355. data/web/dist/assets/index-OR-odsl9.js +2 -0
  356. data/web/dist/assets/index-P3vSkiU-.js +2 -0
  357. data/web/dist/assets/index-a4EHR-u4.css +1 -0
  358. data/web/dist/assets/index-mRV4XhJZ.js +2 -0
  359. data/web/dist/assets/index-popk9wbW.js +2 -0
  360. data/web/dist/assets/index-uM88Njdj.js +2 -0
  361. data/web/dist/assets/javascript-iXu5QeM3.js +2 -0
  362. data/web/dist/assets/julia-DuME0IfC.js +2 -0
  363. data/web/dist/assets/livescript-BwQOo05w.js +2 -0
  364. data/web/dist/assets/logo-on-dark-DI9gCdN4.png +0 -0
  365. data/web/dist/assets/logo-on-light-BciwqxcJ.png +0 -0
  366. data/web/dist/assets/lua-VAEuO923.js +2 -0
  367. data/web/dist/assets/mathematica-DTrFuWx2.js +2 -0
  368. data/web/dist/assets/mbox-CNhZ1qSd.js +2 -0
  369. data/web/dist/assets/mirc-CjQqDB4T.js +2 -0
  370. data/web/dist/assets/mllike-CXdrOF99.js +2 -0
  371. data/web/dist/assets/modelica-Dc1JOy9r.js +2 -0
  372. data/web/dist/assets/mscgen-BA5vi2Kp.js +2 -0
  373. data/web/dist/assets/mumps-BT43cFF4.js +2 -0
  374. data/web/dist/assets/nginx-DdIZxoE0.js +2 -0
  375. data/web/dist/assets/nsis-LY0VT_u5.js +2 -0
  376. data/web/dist/assets/ntriples-BfvgReVJ.js +2 -0
  377. data/web/dist/assets/octave-Ck1zUtKM.js +2 -0
  378. data/web/dist/assets/overpass-cyrillic-400-normal-CZsFKZCk.woff +0 -0
  379. data/web/dist/assets/overpass-cyrillic-400-normal-tXDxWGRy.woff2 +0 -0
  380. data/web/dist/assets/overpass-cyrillic-600-normal-B-hc8bdn.woff2 +0 -0
  381. data/web/dist/assets/overpass-cyrillic-600-normal-CXB2Mrig.woff +0 -0
  382. data/web/dist/assets/overpass-cyrillic-800-normal-CP6RWG8X.woff2 +0 -0
  383. data/web/dist/assets/overpass-cyrillic-800-normal-PJW4A9xW.woff +0 -0
  384. data/web/dist/assets/overpass-cyrillic-ext-400-normal-AKUz2ZI5.woff2 +0 -0
  385. data/web/dist/assets/overpass-cyrillic-ext-400-normal-C2ZjKngx.woff +0 -0
  386. data/web/dist/assets/overpass-cyrillic-ext-600-normal-CW4Fknsm.woff2 +0 -0
  387. data/web/dist/assets/overpass-cyrillic-ext-600-normal-Zx-mtRSD.woff +0 -0
  388. data/web/dist/assets/overpass-cyrillic-ext-800-normal-CIth-cA7.woff2 +0 -0
  389. data/web/dist/assets/overpass-cyrillic-ext-800-normal-hx3cL3ZN.woff +0 -0
  390. data/web/dist/assets/overpass-latin-400-normal-BpeLJ0bs.woff2 +0 -0
  391. data/web/dist/assets/overpass-latin-400-normal-c_C8zulu.woff +0 -0
  392. data/web/dist/assets/overpass-latin-600-normal-25RhTNCi.woff2 +0 -0
  393. data/web/dist/assets/overpass-latin-600-normal-DhYQrzaY.woff +0 -0
  394. data/web/dist/assets/overpass-latin-800-normal-Bzx_XP5l.woff2 +0 -0
  395. data/web/dist/assets/overpass-latin-800-normal-D6-q4f0l.woff +0 -0
  396. data/web/dist/assets/overpass-latin-ext-400-normal-BIkXRwl6.woff2 +0 -0
  397. data/web/dist/assets/overpass-latin-ext-400-normal-DUq_h-_z.woff +0 -0
  398. data/web/dist/assets/overpass-latin-ext-600-normal-Cyj4Nio0.woff2 +0 -0
  399. data/web/dist/assets/overpass-latin-ext-600-normal-DQKKMGzp.woff +0 -0
  400. data/web/dist/assets/overpass-latin-ext-800-normal-D6WKWGNs.woff +0 -0
  401. data/web/dist/assets/overpass-latin-ext-800-normal-DZ60AB77.woff2 +0 -0
  402. data/web/dist/assets/overpass-mono-cyrillic-400-normal-B144qALP.woff2 +0 -0
  403. data/web/dist/assets/overpass-mono-cyrillic-400-normal-XK9_jwT8.woff +0 -0
  404. data/web/dist/assets/overpass-mono-cyrillic-ext-400-normal-Dgejvo4A.woff2 +0 -0
  405. data/web/dist/assets/overpass-mono-cyrillic-ext-400-normal-DgxwtUZy.woff +0 -0
  406. data/web/dist/assets/overpass-mono-latin-400-normal-DqAOLzCO.woff +0 -0
  407. data/web/dist/assets/overpass-mono-latin-400-normal-VINZG6Js.woff2 +0 -0
  408. data/web/dist/assets/overpass-mono-latin-ext-400-normal-5YIw-E8g.woff +0 -0
  409. data/web/dist/assets/overpass-mono-latin-ext-400-normal-DBdJzBs_.woff2 +0 -0
  410. data/web/dist/assets/overpass-mono-vietnamese-400-normal-DrLp_cHj.woff +0 -0
  411. data/web/dist/assets/overpass-mono-vietnamese-400-normal-jmOeL0rj.woff2 +0 -0
  412. data/web/dist/assets/overpass-vietnamese-400-normal-BKRCEiXy.woff2 +0 -0
  413. data/web/dist/assets/overpass-vietnamese-400-normal-CCWAWVG7.woff +0 -0
  414. data/web/dist/assets/overpass-vietnamese-600-normal-CjS-4vQf.woff2 +0 -0
  415. data/web/dist/assets/overpass-vietnamese-600-normal-DlMMlPfM.woff +0 -0
  416. data/web/dist/assets/overpass-vietnamese-800-normal-BB8K9-Vo.woff2 +0 -0
  417. data/web/dist/assets/overpass-vietnamese-800-normal-DZUygvj_.woff +0 -0
  418. data/web/dist/assets/oz-BzwKVEFT.js +2 -0
  419. data/web/dist/assets/pascal--L3eBynH.js +2 -0
  420. data/web/dist/assets/perl-CdXCOZ3F.js +2 -0
  421. data/web/dist/assets/pig-CevX1Tat.js +2 -0
  422. data/web/dist/assets/powershell-CFHJl5sT.js +2 -0
  423. data/web/dist/assets/properties-C78fOPTZ.js +2 -0
  424. data/web/dist/assets/protobuf-ChK-085T.js +2 -0
  425. data/web/dist/assets/pug-DeIclll2.js +2 -0
  426. data/web/dist/assets/puppet-DMA9R1ak.js +2 -0
  427. data/web/dist/assets/python-BuPzkPfP.js +2 -0
  428. data/web/dist/assets/q-pXgVlZs6.js +2 -0
  429. data/web/dist/assets/r-B6wPVr8A.js +2 -0
  430. data/web/dist/assets/rpm-CTu-6PCP.js +2 -0
  431. data/web/dist/assets/ruby-BK5aLJev.js +2 -0
  432. data/web/dist/assets/sas-B4kiWyti.js +2 -0
  433. data/web/dist/assets/scheme-C41bIUwD.js +2 -0
  434. data/web/dist/assets/shell-CjFT_Tl9.js +2 -0
  435. data/web/dist/assets/sieve-C3Gn_uJK.js +2 -0
  436. data/web/dist/assets/simple-mode-GW_nhZxv.js +2 -0
  437. data/web/dist/assets/smalltalk-CnHTOXQT.js +2 -0
  438. data/web/dist/assets/solr-DehyRSwq.js +2 -0
  439. data/web/dist/assets/sparql-DkYu6x3z.js +2 -0
  440. data/web/dist/assets/spreadsheet-BCZA_wO0.js +2 -0
  441. data/web/dist/assets/sql-D0XecflT.js +2 -0
  442. data/web/dist/assets/stex-C3f8Ysf7.js +2 -0
  443. data/web/dist/assets/stylus-B533Al4x.js +2 -0
  444. data/web/dist/assets/swift-BzpIVaGY.js +2 -0
  445. data/web/dist/assets/tcl-DVfN8rqt.js +2 -0
  446. data/web/dist/assets/textile-CnDTJFAw.js +2 -0
  447. data/web/dist/assets/tiddlywiki-DO-Gjzrf.js +2 -0
  448. data/web/dist/assets/tiki-DGYXhP31.js +2 -0
  449. data/web/dist/assets/toml-Bm5Em-hy.js +2 -0
  450. data/web/dist/assets/troff-wAsdV37c.js +2 -0
  451. data/web/dist/assets/ttcn-CfJYG6tj.js +2 -0
  452. data/web/dist/assets/ttcn-cfg-B9xdYoR4.js +2 -0
  453. data/web/dist/assets/turtle-B1tBg_DP.js +2 -0
  454. data/web/dist/assets/vb-CmGdzxic.js +2 -0
  455. data/web/dist/assets/vbscript-BuJXcnF6.js +2 -0
  456. data/web/dist/assets/velocity-D8B20fx6.js +2 -0
  457. data/web/dist/assets/verilog-C6RDOZhf.js +2 -0
  458. data/web/dist/assets/vhdl-lSbBsy5d.js +2 -0
  459. data/web/dist/assets/webidl-ZXfAyPTL.js +2 -0
  460. data/web/dist/assets/xquery-DzFWVndE.js +2 -0
  461. data/web/dist/assets/yacas-BJ4BC0dw.js +2 -0
  462. data/web/dist/assets/z80-Hz9HOZM7.js +2 -0
  463. data/web/dist/index.html +14 -0
  464. data/web/dist/vite.svg +1 -0
  465. data/web/src/api/fixtures/board.json +512 -0
  466. metadata +907 -0
@@ -0,0 +1,101 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/kigster/openlanes/blob/main/schemas/plan-state.schema.json",
4
+ "title": "OpenLanes plan state",
5
+ "description": "state.json in a .plans folder: the harness's stages, the agents' signatures, and the messages between agents. Written only through openlanes, never by hand.",
6
+ "type": "object",
7
+ "required": ["version", "plan", "stages", "signatures", "messages"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "$schema": { "type": "string" },
11
+ "version": { "type": "integer", "minimum": 1 },
12
+ "plan": {
13
+ "type": "object",
14
+ "required": ["ordinal", "slug"],
15
+ "additionalProperties": false,
16
+ "properties": {
17
+ "ordinal": { "type": ["string", "null"], "pattern": "^\\d{3}\\.\\d{2}$" },
18
+ "slug": { "type": "string" }
19
+ }
20
+ },
21
+ "state": {
22
+ "description": "The last state the harness moved the folder to. The folder name is authoritative.",
23
+ "type": ["string", "null"]
24
+ },
25
+ "updated_at": { "type": ["string", "null"], "format": "date-time" },
26
+ "stages": {
27
+ "description": "One record per agent per round, written by the harness.",
28
+ "type": "array",
29
+ "items": {
30
+ "type": "object",
31
+ "required": ["agent", "round", "status"],
32
+ "additionalProperties": false,
33
+ "properties": {
34
+ "agent": { "$ref": "#/$defs/agent" },
35
+ "round": { "type": "integer", "minimum": 1 },
36
+ "status": { "$ref": "#/$defs/status" },
37
+ "from": { "type": "string" },
38
+ "to": { "type": "string" },
39
+ "started_at": { "type": "string", "format": "date-time" },
40
+ "finished_at": { "type": "string", "format": "date-time" },
41
+ "adapter": { "enum": ["claude", "codex", "pi"] },
42
+ "model": { "type": ["string", "null"] },
43
+ "effort": { "$ref": "#/$defs/effort" },
44
+ "up": { "type": "integer", "minimum": 0 },
45
+ "down": { "type": "integer", "minimum": 0 },
46
+ "seconds": { "type": "number", "minimum": 0 },
47
+ "note": { "type": "string" },
48
+ "run": {
49
+ "description": "The harness process that dispatched it, so a restart can tell a crash from a live run.",
50
+ "type": "object",
51
+ "required": ["pid", "host"],
52
+ "additionalProperties": false,
53
+ "properties": {
54
+ "pid": { "type": "integer" },
55
+ "host": { "type": "string" }
56
+ }
57
+ }
58
+ }
59
+ }
60
+ },
61
+ "signatures": {
62
+ "description": "Ledger lines, written by agents through `openlanes state sign`.",
63
+ "type": "array",
64
+ "items": {
65
+ "type": "object",
66
+ "required": ["at", "agent", "status", "round"],
67
+ "additionalProperties": false,
68
+ "properties": {
69
+ "at": { "type": "string", "format": "date-time" },
70
+ "agent": { "$ref": "#/$defs/agent" },
71
+ "status": { "$ref": "#/$defs/status" },
72
+ "round": { "type": "integer", "minimum": 1 },
73
+ "note": { "type": "string" },
74
+ "next": { "$ref": "#/$defs/agent" }
75
+ }
76
+ }
77
+ },
78
+ "messages": {
79
+ "description": "What agents on this plan said to each other, through `openlanes mail send`.",
80
+ "type": "array",
81
+ "items": {
82
+ "type": "object",
83
+ "required": ["number", "at", "from", "to", "body"],
84
+ "additionalProperties": false,
85
+ "properties": {
86
+ "number": { "type": "integer", "minimum": 1 },
87
+ "at": { "type": "string", "format": "date-time" },
88
+ "from": { "$ref": "#/$defs/agent" },
89
+ "to": { "$ref": "#/$defs/agent" },
90
+ "body": { "type": "string", "minLength": 1 },
91
+ "command": { "type": "string", "minLength": 1, "description": "The id of the page's command that sent it (plan 004, W13), so a redelivered command appends nothing twice." }
92
+ }
93
+ }
94
+ }
95
+ },
96
+ "$defs": {
97
+ "agent": { "type": "string", "pattern": "^[\\w-]+$" },
98
+ "status": { "enum": ["Started", "Completed", "Almost completed", "Interrupted", "Blocked"] },
99
+ "effort": { "enum": ["low", "medium", "high", "xhigh", "max", null] }
100
+ }
101
+ }
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: openlanes
3
+ description: The openlanes software factory (`openlanes` CLI) that drives `.plans/` folders through spec → plan → build → review with specialist agents. Use when a project has `.plans/` or `.openlanes.yml`, when the user mentions openlanes, openlanes, plan folders or the factory, or asks how a plan moves between states, or wants to set up a project on openlanes or start the factory. Loads before openlanes-setup, openlanes-spec, openlanes-documents, openlanes-run, openlanes-status and openlanes-sync.
4
+ ---
5
+
6
+ # openlanes: the software factory
7
+
8
+ `openlanes` (aliases `depot` and `lanes`) turns a few words into a merged pull request. A human writes intent into `spec.md`; specialist agents research, plan, build and review it; `openlanes` moves the plan from state to state until nothing changes. Merge and deploy stay human.
9
+
10
+ ## Which skill does the job
11
+
12
+ | The user wants to | Load |
13
+ | ------------------------------------------------------------ | -------------- |
14
+ | set a project up on openlanes, or fix a missing project root (exit 66) | `openlanes-setup` |
15
+ | start a feature or task, pick its lane, add implementation detail | `openlanes-spec` |
16
+ | write or fix a file in a plan folder: `blocked.md`, `spec.md`, `pull-requests.md` | `openlanes-documents` |
17
+ | start the factory (`openlanes start`) or run the agents until the plans are done; clear a blocked plan | `openlanes-run` |
18
+ | see where plans stand, a plan's history, an agent's mailbox, the control room | `openlanes-status` |
19
+ | fix folder names, PR titles, or export to Linear | `openlanes-sync` |
20
+
21
+ ## Before any command
22
+
23
+ 1. `command -v openlanes` must answer. Otherwise tell the user to install the gem (`gem install openlanes`) and stop. These skills ship inside the gem; after a gem upgrade, `openlanes skills install --overwrite` refreshes them in `~/.agents/skills`.
24
+ 1. `openlanes` finds the project root by itself: the nearest ancestor holding `.openlanes.yml` or `.plans/`, else the nearest `.git`. With none of them, project commands exit 66; load `openlanes-setup`. `init`, `docs`, `states`, `agents`, `describe`, `skills`, `eval`, `completion` and `version` need no project and still work.
25
+ 1. Bundler errors inside a Ruby project (a Gemfile that is not openlanes's) come from the calling shell's Bundler variables. Re-run in a subshell: `(unset BUNDLE_GEMFILE BUNDLE_BIN_PATH BUNDLER_SETUP BUNDLER_VERSION RUBYOPT RUBYLIB; openlanes …)`.
26
+ 1. A flag these skills use being rejected (`-n`, or output saying `Re-run with --commit`) means the `openlanes` on PATH is older than the skills: an rbenv shim or a stale gem shadowing the one that installed them. `which -a openlanes` and `openlanes version` show which; call the right one by its full path and tell the user.
27
+ 1. `--help` on any command or subcommand is the source of truth for flags (`openlanes resync dirs --help`). Read it rather than guessing a flag.
28
+
29
+ ## The model in four facts
30
+
31
+ - **The folder name is the state.** `.plans/003.00-⭐️ → tax-rule-dsl` is plan `003.00`, state Planned, slug `tax-rule-dsl`. There is no database. Folder names hold emoji and spaces, so quote every path. Refer to a plan by its ordinal (`003`, `003.01`) wherever a command accepts one.
32
+ - **Numbers are identity.** `NNN.00` is a new feature; `NNN.MM` with `MM > 0` documents work that already shipped (Retroactive). An ordinal is never renumbered.
33
+ - **Lanes route a plan.** `full`: research, spec, plan, build, review. `plan`: the author's spec stands; plan, build, review. `quick`: one agent (`r2d2-mechanic`) does a short mechanical change, then review. The lane lives in `spec.md` frontmatter.
34
+ - **Blocked means a human decides.** ⭕️ is a technical block (engineer), 🅱️ a product block (product). The questions sit in the plan's `blocked.md`; agents step around the plan until they are answered.
35
+
36
+ Live references, never copied here so they cannot go stale:
37
+
38
+ - `openlanes states`: every state, its emoji, and the legal transitions.
39
+ - `openlanes agents list`: which agent handles which state, its model, its lanes.
40
+ - `openlanes docs`: the full conventions document, generated from the state machine.
41
+
42
+ ## Project config: `.openlanes.yml`
43
+
44
+ At the root, written by `openlanes init`. Keys: `project` (name), `lane` (default lane for new specs), `frontend` (whether the project has a front end; a spec's own `frontend:` wins), `jobs` (plans worked at once), `redis_url` (the Redis behind the control room), and `commands:` (per-command option defaults, e.g. `run: { timeout: 1800 }`). Precedence: CLI flag, then the plan's `spec.md`, then `.openlanes.yml`, then built-in defaults.
45
+
46
+ ## Every write is real
47
+
48
+ Commands do their work when run. `-n` / `--dry-run` previews and changes nothing. A run pushes branches and opens pull requests, so preview before a broad command whenever the user has not already said to go ahead.
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: openlanes-documents
3
+ description: "The files inside a openlanes plan folder: what spec.md, plan.md, blocked.md, pull-requests.md and the closing documents are for, the exact formats openlanes parses, and a template for each. Use when writing or fixing a file in a `.plans/NNN.MM-…` folder by hand: blocked.md questions and answers, spec.md frontmatter, a pull-requests.md table, a retroactive spec's provenance line, or a discarded, deferred, deployed or rollback note."
4
+ ---
5
+
6
+ # openlanes-documents: the files in a plan folder
7
+
8
+ Load the `openlanes` skill first if it is not in context.
9
+
10
+ A folder's contents justify the state in its name. `openlanes resync dirs` renames a folder whose contents contradict its emoji, so a file written in the wrong shape is a file the tool cannot see, and the folder stays where it was.
11
+
12
+ ## Which state needs which file
13
+
14
+ Ask the tool, never a copy of its table:
15
+
16
+ - `openlanes docs` prints every state, the files it requires, and why. `openlanes states` draws the transitions.
17
+ - `openlanes resync dirs -n` after an edit shows what your change now justifies; drop `-n` to rename.
18
+
19
+ ## The files
20
+
21
+ | File | For | Written by |
22
+ | --- | --- | --- |
23
+ | `spec.md` | what and why; its frontmatter says how to route and judge the work | `openlanes create`, the human, `leah-researcher` (`## Research`), `yoda-writer` |
24
+ | `plan.md` | units, order, the integration check; blank means "waiting for the planner" | `yoda-writer` creates it empty, `palpatine-planner` fills it |
25
+ | `plan-backend.md`, `plan-frontend.md` | each builder's units; a front-end file with no unit heading starts nobody | `palpatine-planner` |
26
+ | `blocked.md` | open questions a human must decide | any agent, or a human |
27
+ | `pull-requests.md` | the pull request table the review states are judged by | `openlanes run` when it opens the PR, `openlanes create --prs`, `openlanes resync prs` |
28
+ | `rewrite.md`, `delayed.md`, `discarded.md`, `deployed.md`, `rollback.md` | why the plan left the main path | the reviewer (`rewrite.md`), otherwise a human |
29
+ | `state.json` | stages, signatures, mailbox | the harness only; read it with `openlanes state show --plan <NNN>` |
30
+
31
+ Agents also sign a ledger inside the document they own: a `> [!NOTE]` block of `[ agent: … status: Started, round 1 ]` lines. Leave those blocks as they are; the harness reads them to decide who finished.
32
+
33
+ ## Formats openlanes parses
34
+
35
+ **spec.md frontmatter.** Keys: `lane` (full, plan, quick), `depth` (fast, medium, deep), `frontend` (true or false), `phases` (`<phase>: { adapter, model, effort }`), and `implementation_suggestions`, `implementation_requirements`, `task-completed-when`, `how-to-verify` (each text or a list of text). An unrecognised value is ignored rather than fatal, so a typo silently costs the plan its lane. Choosing the values is `openlanes-spec`'s job. The body opens with the four headings `openlanes create` scaffolds: `## What we are trying to achieve`, `## Why it matters`, `## What already exists`, `## What research needs to settle`.
36
+
37
+ **blocked.md questions and answers.** A question is a line that starts with `B<n>`, after at most four `#` and an optional `**`: `## B1 — Which rate feed?`. Its answer is a heading `## A1` with the same number. Any other numbering (`1.`, `Q1`, a bullet `- B1`) is invisible: the folder never blocks, and `openlanes unblock` finds nothing to drain. Start no other line with `B` and a digit. An answer counts only when it names who decided (a role will do), carries a date, and picks one option.
38
+
39
+ Which human a block waits on lives only in the emoji. `resync dirs` files a new `blocked.md` as ⭕️ (engineering); rename the folder's emoji to 🅱️ by hand when product owns the decision, and `resync` keeps it there.
40
+
41
+ **pull-requests.md.** openlanes reads the first markdown table whose header names a pull request (`Pull Request Number`, `PR`, `#`) and whose rows link to `/pull/<n>`. Columns are found by header words: number, name or title, status. Status words: `Open`, `Draft` or `WIP`, `Merged`, `Closed`. Escape `[`, `]` and `|` inside a title. Prose below the table is ignored.
42
+
43
+ ```markdown
44
+ | Pull Request Number | Pull Request Name | Status |
45
+ | ------------------: | :---------------- | -----: |
46
+ | 41 | [\[018.01\] Verify against filed returns](https://github.com/acme/app/pull/41) | Merged 🟣 |
47
+ ```
48
+
49
+ **Retroactive provenance line.** A plan `NNN.MM` with `MM > 0` documents work that already shipped. Its `spec.md` opens, right after the H1, with a dated note naming the pull requests it describes. `openlanes create --after <NNN> --prs <n,n>` records the PRs and has `yoda-writer` write the spec; the line and how to pick `--after` are in [`references/retroactive-spec.md`](references/retroactive-spec.md).
50
+
51
+ ## Templates
52
+
53
+ Copy the shape; replace every placeholder:
54
+
55
+ - [`references/spec-template.md`](references/spec-template.md): `spec.md`, frontmatter and the four headings.
56
+ - [`references/plan-template.md`](references/plan-template.md): `plan.md` and its unit shape.
57
+ - [`references/blocked-template.md`](references/blocked-template.md): `blocked.md` with `B<n>` and `A<n>`.
58
+ - [`references/closing-templates.md`](references/closing-templates.md): `rewrite.md`, `delayed.md`, `discarded.md`, `deployed.md`, `rollback.md`.
59
+ - [`references/retroactive-spec.md`](references/retroactive-spec.md): the provenance line and the anchor.
60
+
61
+ Done when `openlanes resync dirs -n` names nothing to rename for the folder you edited, or names exactly the state you meant it to reach.
@@ -0,0 +1,49 @@
1
+ # blocked.md template
2
+
3
+ A plan with `blocked.md` naming at least one open question is blocked: ⭕️ Technical Block (an engineer or the CTO decides) or 🅱️ Product Block (a product manager decides). Agents step around it until a human answers and runs `openlanes unblock <NNN>`, which hands the file to `lando-broker`. The broker folds each qualifying answer into `spec.md` (what and why) or `plan.md` (how and in what order), deletes the question with its answer, and deletes the file when nothing is left.
4
+
5
+ Two heading kinds, and only these: `## B<n>` for a question, `## A<n>` for its answer. openlanes counts the `B` lines; a question numbered any other way blocks nothing.
6
+
7
+ ```markdown
8
+ # Rate Feed Sync — Blocked
9
+
10
+ **Blocked since:** 2026-10-12
11
+ **Blocking:** U2 cannot start until the source of rates is chosen
12
+ **Decision needed from:** the CTO
13
+
14
+ ## B1 — Do we read rates from the vendor feed or cache them per filing period?
15
+
16
+ **What we need decided:** one sentence, phrased so that an answer is possible.
17
+
18
+ **Why it blocks:** what gets built wrong if we guess.
19
+
20
+ **Options:**
21
+
22
+ | Option | What it means | Cost or risk |
23
+ | :----- | :------------ | :----------- |
24
+ | A | | |
25
+ | B | | |
26
+
27
+ **Recommendation:** one option, and why.
28
+
29
+ **If unanswered by 2026-10-19:** the default we will take.
30
+
31
+ ## What is already decided
32
+
33
+ Anything settled that the decider need not reopen.
34
+ ```
35
+
36
+ An answer, added under its question when it arrives:
37
+
38
+ ```markdown
39
+ ## A1
40
+
41
+ Decided 2026-10-13 by the CTO: rates are read from the vendor feed, never cached across a filing period.
42
+ ```
43
+
44
+ Notes:
45
+
46
+ - An answer counts only when it names who decided (a role is enough), carries a date, and picks one option. "Leaning towards B" stays, and so does its question.
47
+ - Answer in pieces if that is how answers arrive; whatever is still open keeps the plan blocked.
48
+ - A new `blocked.md` lands at ⭕️ on the next `openlanes resync dirs`. Rename the folder's emoji to 🅱️ when product owns the decision; nothing else records which human it waits on.
49
+ - `openlanes unblock <NNN> -n` lists the questions openlanes can see. Run it after writing the file.
@@ -0,0 +1,59 @@
1
+ # Closing documents
2
+
3
+ Each of these files is what one off-path state requires (`openlanes docs` lists which). Write the file, then `openlanes resync dirs` moves the folder; rename by hand only if resync names a different state than you meant.
4
+
5
+ ## discarded.md — ❌ Discarded
6
+
7
+ Dropped for good; terminal. Say why, so nobody re-proposes it blind.
8
+
9
+ ```markdown
10
+ # Rate Feed Sync — Discarded
11
+
12
+ **Decided:** 2026-10-13 by the head of product
13
+ **Why:** the vendor withdrew the feed; filed returns carry the rates we need.
14
+ **What would change our minds:** a regulator requiring live rates.
15
+ ```
16
+
17
+ ## delayed.md — ☢️ Deferred
18
+
19
+ The work could proceed and we chose not to yet. openlanes refuses the state unless the file names a **trigger** (it looks for the words trigger, revisit, when, until or once).
20
+
21
+ ```markdown
22
+ # Rate Feed Sync — Deferred
23
+
24
+ **Deferred:** 2026-10-13 by the CTO
25
+ **Why now is wrong:** the ledger refactor in 021 rewrites the tables this touches.
26
+ **Trigger:** revisit once plan 021 is merged.
27
+ ```
28
+
29
+ ## rewrite.md — 💩 Scrapped by Review
30
+
31
+ Written by `hansolo-reviewer` when the work is missing, broken, untested, off-spec, or still failing after two rejections. The plan survives; the pull requests do not. No agent handles 💩: a human reads this and decides whether to re-plan, rewrite the spec, or discard.
32
+
33
+ ```markdown
34
+ # Rate Feed Sync — Rewrite
35
+
36
+ **Reviewed:** 2026-10-13, PR #41
37
+ **Why it was scrapped:** the sync never writes to the rates table; the spec's verification command fails.
38
+ **What the next attempt must do differently:** …
39
+ ```
40
+
41
+ ## deployed.md — 😎 Deployed
42
+
43
+ ```markdown
44
+ # Rate Feed Sync — Deployed
45
+
46
+ **Release:** v1.8.0
47
+ **Date:** 2026-10-14
48
+ **SHA:** 3f2c9ab
49
+ ```
50
+
51
+ ## rollback.md — 😱 Rolled Back
52
+
53
+ ```markdown
54
+ # Rate Feed Sync — Rolled Back
55
+
56
+ **Rolled back:** 2026-10-15, v1.8.0 → v1.7.3
57
+ **What broke:** the nightly sync locked the rates table for 40 minutes.
58
+ **What has to change before it ships again:** …
59
+ ```
@@ -0,0 +1,61 @@
1
+ # plan.md template
2
+
3
+ `palpatine-planner` writes `plan.md` from a finished `spec.md`, plus `plan-backend.md` and `plan-frontend.md` holding each builder's units. Write it by hand only when you are taking the planner's place (lane `plan` skips research, not planning).
4
+
5
+ `plan.md` stays **blank** until it is a plan: any `#`, `##` or `###` heading outside a ledger block tells openlanes the plan is written, and moves the folder from 📋 Ready for Planning to ⭐️ Planned. The whole plan lands as one pull request; more than eight units means the spec is several plans.
6
+
7
+ ```markdown
8
+ # Rate Feed Sync — Plan
9
+
10
+ **Spec:** `spec.md` in this folder
11
+ **Depends on:** plans that must land first, by number, or nothing
12
+
13
+ ## Units
14
+
15
+ ### U1 — Rates table and model
16
+
17
+ - **Discipline:** back end
18
+ - **Owns:** db/migrate/*_create_rates.rb, app/models/rate.rb
19
+ - **Must not touch:** app/views/**
20
+ - **Depends on:** nothing
21
+ - **Done when:** spec/models/rate_spec.rb passes
22
+
23
+ ### U2 — Sync command
24
+
25
+ - **Discipline:** back end
26
+ - **Owns:** lib/acme/rates/sync.rb
27
+ - **Must not touch:** app/models/rate.rb (U1)
28
+ - **Depends on:** U1
29
+ - **Done when:** spec/acme/rates/sync_spec.rb passes
30
+
31
+ ### U3 — Integration check
32
+
33
+ - **Discipline:** back end
34
+ - **Owns:** spec/integration/rates_sync_spec.rb
35
+ - **Depends on:** U2
36
+ - **Done when:** a real sync, nothing stubbed but the vendor's HTTP, stores rows the model reads back
37
+
38
+ ## Order
39
+
40
+ U1 → U2 → U3. Units that write the same file are sequential; say which can run in parallel and why.
41
+
42
+ ## Risks
43
+
44
+ | Risk | What we do about it |
45
+ | :--- | :------------------ |
46
+ | | |
47
+
48
+ ## Task completed when
49
+
50
+ - copied from spec.md's `task-completed-when`
51
+
52
+ ## How to verify
53
+
54
+ - copied from spec.md's `how-to-verify`
55
+ ```
56
+
57
+ Notes:
58
+
59
+ - Every unit appears in exactly one of `plan-backend.md` and `plan-frontend.md`, under its own `##` or `###` heading. `rey-frontend` starts only when `plan-frontend.md` has a unit heading, so a plan with no front end writes one plain line there and no heading.
60
+ - `## Task completed when` and `## How to verify` are appended by the harness when missing; a section you wrote is left alone.
61
+ - A plan stays one level above the code: signatures, routes and response shapes, not method bodies.
@@ -0,0 +1,43 @@
1
+ # Retroactive specifications: the provenance line
2
+
3
+ A plan numbered `NNN.MM` with `MM > 0` documents work that already shipped. Its `spec.md` must open by saying so.
4
+
5
+ A specification's form claims that somebody thought this through before it was built. A `spec.md` dated today and filed as an ordinary plan makes that claim falsely. The number carries the fact (`MM > 0`), but a number is easy to miss and easy to misread as containment; the opening line is what survives being copied, quoted or exported.
6
+
7
+ ## The line
8
+
9
+ Immediately after the H1, before anything else:
10
+
11
+ ```markdown
12
+ # Verify Against Filed Returns
13
+
14
+ > [!NOTE]
15
+ > **Written retroactively on 2026-08-17.** This documents work that shipped in
16
+ > #41 and #43, merged between plan 018 and plan 019. It describes what exists;
17
+ > it does not record a decision taken in advance.
18
+ ```
19
+
20
+ Three things, all load-bearing:
21
+
22
+ 1. **The date it was written**, not the date the work shipped.
23
+ 1. **The pull requests it describes**, by number: the evidence a reader checks the document against.
24
+ 1. **The disclaimer.** "Describes what exists" is the point.
25
+
26
+ ## Choosing the anchor
27
+
28
+ `openlanes create --after <NNN> --prs <n,n> <words>` takes the next free slot in the gap after plan `NNN`. Choose `NNN` by **when the work merged**, not by what it is about:
29
+
30
+ ```bash
31
+ git log --diff-filter=A --format='%ad %s' -- '.plans/018*' '.plans/019*'
32
+ gh pr view 41 --json mergedAt
33
+ ```
34
+
35
+ If the pull requests merged after 018's folder was created and before 019's, the anchor is 018. The decimal is a slot in time, not a claim about subject matter.
36
+
37
+ ## What happens next
38
+
39
+ `create --prs` writes `pull-requests.md` (the folder is born 🕰️ Retroactive) and hands the folder to `yoda-writer`, which writes `spec.md` from the diff and an empty `plan.md`. `--no-spec` stops after recording the PRs. From there the plan moves like any other; `openlanes run -n --plan <NNN.MM>` shows who takes it next.
40
+
41
+ ## What does not deserve one
42
+
43
+ Most unmatched pull requests. The test is whether somebody would need to read it: a capability with behaviour, an interface, or invariants not obvious from the code. "Fix a typo", "remove dead code" and "bump a dependency" belong to no plan; `openlanes docs` names the prefix their titles carry instead.
@@ -0,0 +1,45 @@
1
+ # spec.md template
2
+
3
+ `openlanes create <words> --lane <lane> --depth <depth>` writes the title, the frontmatter for the flags it was given, and the four headings; without `--no-draft` it also drafts them from the project's own docs. Fill what it left, keeping the headings in order. Frontmatter keys you do not need can be left out; `lane` defaults to `full`.
4
+
5
+ ```markdown
6
+ ---
7
+ lane: full # full | plan | quick
8
+ depth: medium # fast | medium | deep
9
+ frontend: false # omit to inherit .openlanes.yml; true forces the front-end agent, false forbids it
10
+ implementation_suggestions: # offered to agents, who may take a better route and say why
11
+ - Reuse the HTTP client already in lib/acme/http.rb
12
+ implementation_requirements: # met exactly as written, or the agent blocks and asks
13
+ - Every money column is numeric(19,4)
14
+ task-completed-when: # copied into plan.md as "## Task completed when"
15
+ - "`acme rates sync` stores today's rates and prints how many changed"
16
+ how-to-verify: # copied into plan.md as "## How to verify"
17
+ - "bundle exec rspec spec/acme/rates_spec.rb"
18
+ phases: # optional, per phase: adapter, model, effort
19
+ build: { model: opus }
20
+ ---
21
+ # Rate Feed Sync
22
+
23
+ ## What we are trying to achieve
24
+
25
+ The outcome, in a few sentences: what a user or the system can do afterwards.
26
+
27
+ ## Why it matters
28
+
29
+ Who needs it and what it unblocks. A line from the project's backlog counts.
30
+
31
+ ## What already exists
32
+
33
+ Specific files, modules and prior plans this builds on, by path.
34
+
35
+ ## What research needs to settle
36
+
37
+ The open questions. Where nothing is known, say so in one line; research reads the gaps as its assignment.
38
+ ```
39
+
40
+ Notes:
41
+
42
+ - Quote a list item that holds `: `, ` #`, a backtick, `{`, or starts with `?`; YAML otherwise reads it as something other than text.
43
+ - Leave out "tests and linters pass": openlanes tells every builder and the reviewer that already.
44
+ - `leah-researcher` appends `## Research` (that chapter is what makes the folder 🔎 Researched); `yoda-writer` then rewrites the body into the full specification. Neither needs a heading from you beyond these four.
45
+ - A retroactive plan (`NNN.MM`, `MM > 0`) opens with the provenance line in `retroactive-spec.md` instead of the four headings.
@@ -0,0 +1,90 @@
1
+ ---
2
+ name: openlanes-run
3
+ description: Start the openlanes factory with `openlanes start` (engine plus control room, up until Stop All Local or Ctrl-C, questions answered and plans created on the page), or run openlanes's specialist agents to a fixed point with `openlanes run --until-settled` and clear blocked plans with `openlanes unblock`. Use when the user wants to start, run, resume or finish the agents, build or ship a plan, or unblock a ⭕️ / 🅱️ plan.
4
+ ---
5
+
6
+ # openlanes-run: drive the plans
7
+
8
+ Load the `openlanes` skill first if it is not in context.
9
+
10
+ ## `openlanes start`: the factory with its control room
11
+
12
+ `openlanes start` is the way to run the factory for a person. It is `openlanes run` with the control room on, and it does not stop at a fixed point: when a plan blocks, palpatine-planner's questions included, it idles, shows the questions in **Needs You** on the page, takes the answer from there, drains it, and hands the plan back to its agent. It picks up plans created on the page, by `openlanes create` in another terminal, or edited by hand, rescanning `.plans/` every 5 s (`--rescan`).
13
+
14
+ ```bash
15
+ openlanes start # engine and control room on http://127.0.0.1:11000, browser opened
16
+ openlanes start --no-open # print the URL only
17
+ ```
18
+
19
+ - It takes `run`'s flags except `-n` and `--no-web`. It needs Redis and refuses without it (exit 69).
20
+ - Every human decision goes through the page: answers, hold, wrap up, stop, models, new plans. **Stop All Local** stops this machine's agents, then its engine and the page; nothing else on the page ends the run. The terminal is output only.
21
+ - It never ends on its own, not even once every plan is finished: the page can create the next one. A project with no plans waits for the first. Stop All Local, Ctrl-C or `kill -TERM` end it, with exit 0; agents get the graceful stop and the page goes down with it.
22
+ - Start it in the background, give the user the URL, and leave the answering to them on the page. Steps 1 to 5 below are the scripted, headless alternative.
23
+
24
+ `openlanes run` loops in rounds. Each round hands every movable plan to the agent its state and lane call for and renames the folder when the agent finishes. When a builder lands a plan at 🟢 Ready for Review, `openlanes` pushes its branch and opens the pull request, titled `[NNN.MM]`; `hansolo-reviewer` then reviews that pull request. With `--until-settled` it stops at a **fixed point**: a round in which no plan changed state. Without it, a run whose control room came up stays up like `start` and never returns, so a scripted run always passes `--until-settled` (or `--no-web`). Your job is to start it, watch it, and turn what it stops on into questions for the human.
25
+
26
+ ## 1. Scope and preview
27
+
28
+ Decide the scope from what the user asked: the whole tree, or `--plan 003,005.01`. Then preview, unless the user has already told you to run:
29
+
30
+ ```bash
31
+ openlanes run -n --until-settled --plan <NNN,...>
32
+ ```
33
+
34
+ Each line names a plan, the agent it would get, and the round. Show the user the lines that matter in a few bullets and ask once: "Run these?" One yes covers the whole loop below.
35
+
36
+ Pick flags from the situation, and read `openlanes run --help` for the rest:
37
+
38
+ | Situation | Flag |
39
+ | ------------------------------------------------ | ------------------------------------ |
40
+ | limit machine load or API spend | `-j <n>`, `--max-tokens <n>` |
41
+ | the repository has no git | `--isolation shared` (serial; see below) |
42
+ | one agent is misbehaving | `--skip <agent>` |
43
+ | re-drive one agent with extra guidance | `--agent <name> --prompt "<text>"` |
44
+ | no browser (CI, a remote shell), or no page at all | `--no-open`; `--no-web` (`openlanes web` can serve it later) |
45
+ | port 11000 taken, or Redis elsewhere | `--port <n>`, `--redis-url <url>` |
46
+
47
+ Keep the defaults (`--isolation worktree`, pushing on) whenever the user wants plans reviewed. `--isolation shared` and `--no-git-push` open no pull request, so every plan stops at 🟢 and the reviewer never starts; `openlanes run` warns when that is the case. Use them only when the user asks to keep work local, and say that review waits for a PR they open (`openlanes resync prs` then records it).
48
+
49
+ ## 2. Run it
50
+
51
+ ```bash
52
+ openlanes run --until-settled --plan <NNN,...>
53
+ ```
54
+
55
+ A run takes minutes to hours: each agent may take up to 15 minutes per round, over several rounds. Start it in the background and wait for it to exit; it prints its progress log path at the start, which is what to read when the user asks how it is going. Avoid polling in a tight loop.
56
+
57
+ When Redis answers, the run also serves the control room (it still ends at the fixed point, because of `--until-settled`) on `http://127.0.0.1:11000` and opens it in the browser: the user watches the board there and can message, interrupt or stop an agent. Without Redis the run warns once and goes on headless; that is not a failure. To get the page, start `redis-server` (or pass `--redis-url`) before the run; `openlanes-setup` has the details.
58
+
59
+ A warning about `ANTHROPIC_API_KEY` (or a similar variable) at the start means every agent will authenticate with that key instead of the user's claude.ai login. Stop and ask before running with it; a stale key fails every agent with `401` after minutes each.
60
+
61
+ ## 3. Read where it stopped
62
+
63
+ When it exits, `openlanes status` shows where each plan stands. Sort them into three groups:
64
+
65
+ - **Advanced to a human gate**: at ✅ Approved & Merged the reviewer has approved, and merging and deploying are the human's. Report the PR links (`gh pr list`).
66
+ - **Blocked** ⭕️ / 🅱️: go to step 4.
67
+ - **Unmoved without a block**: an agent failed or ran out of rounds. Read the plan's history with `openlanes state show --plan <NNN>` and say which agent stopped and why. Re-run with a fix (`--agent`, `--prompt`, `--timeout`) only after telling the user what you will change.
68
+
69
+ ## 4. Unblock
70
+
71
+ For each blocked plan:
72
+
73
+ 1. `openlanes unblock <NNN> -n` prints the open questions.
74
+ 1. Put them to the human **one at a time**. ⭕️ questions are for an engineer, 🅱️ for product; say which.
75
+ 1. Write each answer into the plan's `blocked.md` under `## A<n>`, matching its `## B<n>` (the format is in `openlanes-documents`). An answer counts only when it names who decided (a role is enough), carries today's date, and settles the question. "Leaning towards B" does not count, and the broker will leave it in place.
76
+
77
+ ```markdown
78
+ ## A2
79
+ Decided 2026-10-12 by the CTO: rates are read from the vendor feed, never cached.
80
+ ```
81
+
82
+ 1. `openlanes unblock <NNN>` folds the answers into `spec.md` / `plan.md` and renames the folder.
83
+
84
+ ## 5. Loop
85
+
86
+ Go back to step 2 for the plans that moved. Done when a run ends at a fixed point with every remaining plan at a human gate or blocked on a question the human has chosen not to answer yet. Report:
87
+
88
+ - [x] plans that reached review or merge, with PR links
89
+ - [ ] plans still blocked, and whose decision each waits on
90
+ - [ ] plans that failed, and the reason
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: openlanes-setup
3
+ description: "Set a project up on openlanes: check the prerequisites, run `openlanes init`, install the skills, and create the first plan. Use when the user wants to set up a new project on openlanes, bring an existing repository onto it, or when a openlanes command exits 66 with no project root."
4
+ ---
5
+
6
+ # openlanes-setup: put a project on openlanes
7
+
8
+ Load the `openlanes` skill first if it is not in context. Read `<command> --help` before using a flag here.
9
+
10
+ ## 1. Prerequisites
11
+
12
+ Check each, then report every gap at once with its fix. Ask before installing anything system-wide.
13
+
14
+ | Check | Fix when it fails |
15
+ | --- | --- |
16
+ | `command -v openlanes && openlanes version` | `gem install openlanes` |
17
+ | `git rev-parse --show-toplevel` | offer `git init`; without git, `openlanes run` needs `--isolation shared` and opens no pull request |
18
+ | `gh auth status` | `gh auth login`; a "token in GH_TOKEN is invalid" line means `unset GH_TOKEN` and retry |
19
+ | the agents' CLI: `command -v claude`, the default adapter, or `codex` / `pi` when the plans' `spec.md` select them per phase | install the CLI the plans use; `openlanes agents list` shows each agent's adapter |
20
+ | Redis answers at the URL openlanes will use (order below): `url=$(ruby -ryaml -e 'puts((YAML.safe_load_file(".openlanes.yml") rescue {}).to_h["redis_url"])' 2>/dev/null); redis-cli -u "${url:-${REDIS_URL:-redis://localhost:6379/0}}" ping` | start `redis-server`, or point openlanes at another Redis (below) |
21
+
22
+ Redis carries the control room, its commands and plan claims. `openlanes start` refuses to run without it (exit 69); `openlanes run` still works, headless, and says so. openlanes looks for it in `--redis-url`, then `redis_url:` in `.openlanes.yml`, then `$REDIS_URL`, then `redis://localhost:6379/0`; `openlanes web` checks `$OPENLANES_REDIS_URL` before all of those but the flag.
23
+
24
+ ## 2. `openlanes init`
25
+
26
+ Run it at the repository root. Infer values from the repository, say them in one line, and wait for a yes:
27
+
28
+ - `--project`: the product's name, else the directory name.
29
+ - `--lane`: `full` unless the user writes complete specs themselves (`plan`).
30
+ - `--[no-]frontend`: `--frontend` when there is a `web/`, `app/javascript/`, `package.json` with a UI framework, or views; `--no-frontend` for a library or CLI; leave it out when plans differ.
31
+ - `-j`: leave the default unless the user wants to limit load.
32
+
33
+ > Project **Acme**, lane **full**, **front end** (a `web/` React app), default jobs. OK?
34
+
35
+ Then `openlanes init -y <flags> -n` to show the file, and the same without `-n` to write `.openlanes.yml` and create `.plans/`. An existing `.openlanes.yml` is kept unless `--overwrite`.
36
+
37
+ If the repository has a database and a `CLAUDE.md` or `AGENTS.md`, offer one line there naming its PostgreSQL class (`PG-lax`, `PG-strict` or `PG-analytics`), so every agent assumes the same rules.
38
+
39
+ ## 3. Skills
40
+
41
+ ```bash
42
+ openlanes skills install -n # what would be installed, kept, replaced
43
+ openlanes skills install # into ~/.agents/skills
44
+ openlanes skills install --into ~/.claude/skills # when the user's agent reads another directory
45
+ ```
46
+
47
+ After a gem upgrade, `--overwrite` replaces the copies already there.
48
+
49
+ ## 4. The first plan
50
+
51
+ Hand off to `openlanes-spec` to create and write the first plan. A new project's first plan is `000.00`. Then:
52
+
53
+ ```bash
54
+ openlanes run -n --plan 000
55
+ ```
56
+
57
+ and offer `openlanes-run` to start the agents.
58
+
59
+ ## Done when
60
+
61
+ - [ ] `openlanes status` lists the plan.
62
+ - [ ] `openlanes run -n --plan 000` names its first agent.
63
+ - [ ] With Redis up, `openlanes web --demo` opens the control room on a sample run (Ctrl-C to stop).
64
+ - [ ] `openlanes start` is running: the factory and its control room, up until Stop All Local or Ctrl-C. From here the user works on the page (see `openlanes-run`).