@jr2/orchestrator 0.6.0 → 0.7.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 (301) hide show
  1. package/console/components/app.ts +55 -15
  2. package/console/components/bottom-drawer.ts +259 -0
  3. package/console/components/drawer.ts +14 -6
  4. package/console/components/fleet.ts +36 -13
  5. package/console/components/machine-pane.ts +61 -5
  6. package/console/components/nav.ts +54 -8
  7. package/console/conversation.ts +161 -0
  8. package/console/login.ts +123 -0
  9. package/console/main.ts +600 -60
  10. package/console/store.ts +611 -64
  11. package/console/style.css +231 -0
  12. package/docs/agents-block.md +2 -2
  13. package/docs/concepts/agents-and-turns.md +86 -9
  14. package/docs/concepts/architecture.md +41 -28
  15. package/docs/concepts/callers-and-hooks.md +205 -0
  16. package/docs/concepts/charts.md +7 -5
  17. package/docs/concepts/composition.md +10 -1
  18. package/docs/concepts/converge.md +4 -2
  19. package/docs/concepts/durable-runs.md +43 -16
  20. package/docs/concepts/effects.md +50 -22
  21. package/docs/concepts/gates.md +95 -25
  22. package/docs/concepts/machines-and-workflows.md +5 -4
  23. package/docs/concepts/pools-and-sources.md +187 -11
  24. package/docs/concepts/secrets-and-trust.md +73 -33
  25. package/docs/concepts/the-menu.md +11 -0
  26. package/docs/concepts/workspaces.md +6 -5
  27. package/docs/get-started/a-model-decides.md +14 -13
  28. package/docs/get-started/an-agent-in-a-sandbox.md +43 -34
  29. package/docs/get-started/connect-a-model.md +1 -1
  30. package/docs/get-started/create-an-instance.md +17 -14
  31. package/docs/guides/add-tools-to-the-sandbox.md +55 -11
  32. package/docs/guides/answer-a-gate-from-a-forge.md +304 -0
  33. package/docs/guides/answer-a-gate.md +74 -37
  34. package/docs/guides/bind-open-parts.md +24 -8
  35. package/docs/guides/call-an-mcp-tool-from-a-machine.md +572 -0
  36. package/docs/guides/cancel-a-run.md +26 -16
  37. package/docs/guides/fix-a-failed-converge.md +18 -6
  38. package/docs/guides/give-a-caller-a-scope.md +203 -0
  39. package/docs/guides/give-an-agent-mcp-tools.md +422 -0
  40. package/docs/guides/iterate-on-a-machine-on-kind.md +10 -9
  41. package/docs/guides/let-an-agent-write-a-chart.md +9 -6
  42. package/docs/guides/look-inside-a-sandbox.md +101 -31
  43. package/docs/guides/open-the-console.md +63 -14
  44. package/docs/guides/read-a-conversation.md +225 -0
  45. package/docs/guides/run-a-chart-by-name.md +17 -16
  46. package/docs/guides/run-one-worker-per-item.md +15 -9
  47. package/docs/guides/set-an-agents-access-and-dials.md +2 -0
  48. package/docs/guides/start-a-run-for-each-alert.md +290 -0
  49. package/docs/guides/start-a-run-from-a-run.md +18 -16
  50. package/docs/guides/start-a-run.md +24 -18
  51. package/docs/guides/steer-an-agent.md +332 -0
  52. package/docs/guides/use-a-hosted-provider.md +1 -1
  53. package/docs/guides/watch-a-run.md +127 -121
  54. package/docs/guides/write-a-hook-kind.md +238 -0
  55. package/docs/guides/write-a-tool-as-an-mcp-server.md +351 -0
  56. package/docs/guides/write-a-workflow.md +17 -7
  57. package/docs/llms.txt +81 -15
  58. package/docs/reference/authoring-surface/agent.md +1 -1
  59. package/docs/reference/authoring-surface/answer.md +1 -1
  60. package/docs/reference/authoring-surface/arg.md +1 -1
  61. package/docs/reference/authoring-surface/basic.md +1 -1
  62. package/docs/reference/authoring-surface/bearer.md +1 -1
  63. package/docs/reference/authoring-surface/branchname.md +1 -1
  64. package/docs/reference/authoring-surface/carry.md +23 -0
  65. package/docs/reference/authoring-surface/chartschema.md +1 -1
  66. package/docs/reference/authoring-surface/chartschemafor.md +1 -1
  67. package/docs/reference/authoring-surface/command.md +1 -1
  68. package/docs/reference/authoring-surface/customize.md +4 -1
  69. package/docs/reference/authoring-surface/defineconfig.md +1 -1
  70. package/docs/reference/authoring-surface/defineevent.md +1 -1
  71. package/docs/reference/authoring-surface/dispatch.md +5 -4
  72. package/docs/reference/authoring-surface/fail.md +1 -1
  73. package/docs/reference/authoring-surface/file.md +1 -1
  74. package/docs/reference/authoring-surface/frompick.md +1 -1
  75. package/docs/reference/authoring-surface/gate.md +118 -0
  76. package/docs/reference/authoring-surface/group-agents.md +15 -0
  77. package/docs/reference/authoring-surface/group-charts.md +16 -0
  78. package/docs/reference/authoring-surface/group-composition.md +25 -0
  79. package/docs/reference/authoring-surface/group-config.md +17 -0
  80. package/docs/reference/authoring-surface/group-effects.md +48 -0
  81. package/docs/reference/authoring-surface/group-failure.md +13 -0
  82. package/docs/reference/authoring-surface/group-gates.md +16 -0
  83. package/docs/reference/authoring-surface/group-machine-and-events.md +15 -0
  84. package/docs/reference/authoring-surface/group-steering.md +12 -0
  85. package/docs/reference/authoring-surface/group-types-these-signatures-name.md +137 -0
  86. package/docs/reference/authoring-surface/group-workspaces-and-repos.md +15 -0
  87. package/docs/reference/authoring-surface/http.md +1 -1
  88. package/docs/reference/authoring-surface/isfailure.md +1 -1
  89. package/docs/reference/authoring-surface/isready.md +1 -1
  90. package/docs/reference/authoring-surface/jr2setup.md +13 -3
  91. package/docs/reference/authoring-surface/mcp.md +107 -0
  92. package/docs/reference/authoring-surface/open.md +5 -3
  93. package/docs/reference/authoring-surface/openbody.md +1 -1
  94. package/docs/reference/authoring-surface/paramsof.md +1 -1
  95. package/docs/reference/authoring-surface/pool.md +77 -9
  96. package/docs/reference/authoring-surface/push.md +1 -1
  97. package/docs/reference/authoring-surface/readyof.md +1 -1
  98. package/docs/reference/authoring-surface/reread.md +19 -0
  99. package/docs/reference/authoring-surface/secret.md +1 -1
  100. package/docs/reference/authoring-surface/sentby.md +1 -1
  101. package/docs/reference/authoring-surface/skip.md +22 -0
  102. package/docs/reference/authoring-surface/source.md +56 -1
  103. package/docs/reference/authoring-surface/steer.md +93 -0
  104. package/docs/reference/authoring-surface/text.md +1 -1
  105. package/docs/reference/authoring-surface/type-agentdefinition.md +14 -1
  106. package/docs/reference/authoring-surface/type-agentmcpserver.md +54 -0
  107. package/docs/reference/authoring-surface/type-anyframepath.md +1 -1
  108. package/docs/reference/authoring-surface/type-anyworktreepath.md +1 -1
  109. package/docs/reference/authoring-surface/type-binding.md +1 -1
  110. package/docs/reference/authoring-surface/type-caller.md +40 -0
  111. package/docs/reference/authoring-surface/type-callerrecord.md +32 -0
  112. package/docs/reference/authoring-surface/type-carry.md +19 -0
  113. package/docs/reference/authoring-surface/type-chainlink.md +3 -3
  114. package/docs/reference/authoring-surface/type-commandoutput.md +1 -1
  115. package/docs/reference/authoring-surface/type-customize.md +16 -1
  116. package/docs/reference/authoring-surface/type-delivered.md +17 -0
  117. package/docs/reference/authoring-surface/type-deliveredevent.md +18 -0
  118. package/docs/reference/authoring-surface/type-dispatchdefinition.md +4 -3
  119. package/docs/reference/authoring-surface/type-dispatchoutput.md +1 -1
  120. package/docs/reference/authoring-surface/type-effectbinding.md +12 -2
  121. package/docs/reference/authoring-surface/type-framepath.md +1 -1
  122. package/docs/reference/authoring-surface/type-gatebinding.md +15 -0
  123. package/docs/reference/authoring-surface/type-gatehooks.md +12 -0
  124. package/docs/reference/authoring-surface/type-gatelook.md +37 -0
  125. package/docs/reference/authoring-surface/type-gateoutcome.md +32 -0
  126. package/docs/reference/authoring-surface/type-gatereply.md +19 -0
  127. package/docs/reference/authoring-surface/type-gateslot.md +21 -0
  128. package/docs/reference/authoring-surface/type-gateslotinput.md +13 -0
  129. package/docs/reference/authoring-surface/type-gateslotparts.md +18 -0
  130. package/docs/reference/authoring-surface/type-gateslots.md +12 -0
  131. package/docs/reference/authoring-surface/type-gatetypesat.md +13 -0
  132. package/docs/reference/authoring-surface/type-hostinjectedinput.md +1 -1
  133. package/docs/reference/authoring-surface/type-httpoutput.md +1 -1
  134. package/docs/reference/authoring-surface/type-jr2config.md +37 -2
  135. package/docs/reference/authoring-surface/type-lateroutcome.md +1 -1
  136. package/docs/reference/authoring-surface/type-lends.md +5 -1
  137. package/docs/reference/authoring-surface/type-lookoutput.md +14 -0
  138. package/docs/reference/authoring-surface/type-mcpcalloutput.md +78 -0
  139. package/docs/reference/authoring-surface/type-mcpnotreturned.md +42 -0
  140. package/docs/reference/authoring-surface/type-mcpoptions.md +47 -0
  141. package/docs/reference/authoring-surface/type-mcpoutput.md +50 -0
  142. package/docs/reference/authoring-surface/type-mcpreadoutput.md +53 -0
  143. package/docs/reference/authoring-surface/type-mcpremoteserver.md +50 -0
  144. package/docs/reference/authoring-surface/type-mcpserver.md +41 -0
  145. package/docs/reference/authoring-surface/type-mcpstdioserver.md +42 -0
  146. package/docs/reference/authoring-surface/type-namedsecret.md +4 -4
  147. package/docs/reference/authoring-surface/type-openbodydeclaration.md +1 -1
  148. package/docs/reference/authoring-surface/type-openbodyoutput.md +1 -1
  149. package/docs/reference/authoring-surface/type-poolnextinput.md +1 -1
  150. package/docs/reference/authoring-surface/type-poolspec.md +11 -6
  151. package/docs/reference/authoring-surface/type-pushoutput.md +1 -1
  152. package/docs/reference/authoring-surface/type-pushsourcespec.md +38 -0
  153. package/docs/reference/authoring-surface/type-readsourcespec.md +47 -0
  154. package/docs/reference/authoring-surface/type-reposlot.md +1 -1
  155. package/docs/reference/authoring-surface/type-reread.md +18 -0
  156. package/docs/reference/authoring-surface/type-runsconfig.md +41 -0
  157. package/docs/reference/authoring-surface/type-sender.md +26 -1
  158. package/docs/reference/authoring-surface/type-sendercallerfield.md +14 -0
  159. package/docs/reference/authoring-surface/type-size.md +1 -1
  160. package/docs/reference/authoring-surface/type-skip.md +19 -0
  161. package/docs/reference/authoring-surface/type-sourcehooks.md +23 -0
  162. package/docs/reference/authoring-surface/type-sourcein.md +25 -0
  163. package/docs/reference/authoring-surface/type-sourcereply.md +18 -0
  164. package/docs/reference/authoring-surface/type-sourcespec.md +16 -7
  165. package/docs/reference/authoring-surface/type-sourceverdict.md +49 -0
  166. package/docs/reference/authoring-surface/type-standingpoolmachine.md +12 -0
  167. package/docs/reference/authoring-surface/type-standingpoolspec.md +51 -0
  168. package/docs/reference/authoring-surface/type-steerargs.md +20 -0
  169. package/docs/reference/authoring-surface/type-thinkinglevel.md +1 -1
  170. package/docs/reference/authoring-surface/type-usercontainer.md +1 -1
  171. package/docs/reference/authoring-surface/type-workspaced.md +1 -1
  172. package/docs/reference/authoring-surface/type-worktreefound.md +3 -3
  173. package/docs/reference/authoring-surface/type-worktreeinput.md +1 -1
  174. package/docs/reference/authoring-surface/type-worktreeoptions.md +1 -1
  175. package/docs/reference/authoring-surface/type-worktreeoutput.md +1 -1
  176. package/docs/reference/authoring-surface/type-worktreepath.md +1 -1
  177. package/docs/reference/authoring-surface/type-worktreeready.md +1 -1
  178. package/docs/reference/authoring-surface/type-worktreerefused.md +4 -4
  179. package/docs/reference/authoring-surface/workspace.md +1 -1
  180. package/docs/reference/authoring-surface/worktree.md +1 -1
  181. package/docs/reference/authoring-surface.md +88 -167
  182. package/docs/reference/cli.md +413 -74
  183. package/docs/reference/config.md +235 -2
  184. package/docs/reference/decisions/0002-duplex-streaming-actor.md +71 -11
  185. package/docs/reference/decisions/0005-sandbox-pod-composition.md +14 -10
  186. package/docs/reference/decisions/0006-agent-control-surface.md +4 -4
  187. package/docs/reference/decisions/0007-durable-machine-state.md +1 -1
  188. package/docs/reference/decisions/0009-cli-and-instance-interface.md +150 -49
  189. package/docs/reference/decisions/0010-bdd-acceptance-tests.md +5 -3
  190. package/docs/reference/decisions/0011-workflow-defined-events.md +256 -12
  191. package/docs/reference/decisions/0012-workspace-wrapper-machine.md +9 -2
  192. package/docs/reference/decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md +20 -14
  193. package/docs/reference/decisions/0014-observation-is-open-run-state-is-not.md +53 -27
  194. package/docs/reference/decisions/0015-authoring-surface-absorbs-the-mechanism.md +18 -14
  195. package/docs/reference/decisions/0017-pool-over-a-source-port.md +226 -12
  196. package/docs/reference/decisions/0018-instance-agents-are-definitions-jr2-assembles-the-harness.md +15 -7
  197. package/docs/reference/decisions/0019-one-converging-command-against-the-current-context.md +32 -18
  198. package/docs/reference/decisions/0021-workspace-continuity-is-a-lease-that-answers-back.md +14 -1
  199. package/docs/reference/decisions/0022-observation-is-a-level-triggered-feed.md +4 -4
  200. package/docs/reference/decisions/0023-the-harness-prints-the-conversation.md +116 -34
  201. package/docs/reference/decisions/0024-an-agents-turn-ends-with-the-state-that-asked-for-it.md +38 -37
  202. package/docs/reference/decisions/0025-cancel-ends-a-run-stop-parks-it.md +10 -5
  203. package/docs/reference/decisions/0027-the-harness-is-jr2s-own-server-flue-retires-the-wire-stays.md +7 -6
  204. package/docs/reference/decisions/0028-what-an-agent-may-do-to-the-workspace-is-part-of-its-definition.md +23 -7
  205. package/docs/reference/decisions/0029-a-menu-is-fixed-for-a-conversation-and-a-turn-is-told-its-allowed-picks.md +18 -10
  206. package/docs/reference/decisions/0030-a-snapshot-names-the-machine-it-was-written-under.md +3 -2
  207. package/docs/reference/decisions/0031-menu-only-agents-run-on-the-instance-harness.md +23 -18
  208. package/docs/reference/decisions/0032-the-console-unlocks-with-a-callers-credential.md +101 -0
  209. package/docs/reference/decisions/0033-a-machine-declares-the-input-that-starts-it.md +4 -3
  210. package/docs/reference/decisions/0034-the-console-renders-with-preact-and-the-server-erases-the-types.md +6 -6
  211. package/docs/reference/decisions/0037-an-instance-builds-its-sandbox-images-jr2-injects-the-harness.md +5 -4
  212. package/docs/reference/decisions/0049-a-machine-carries-its-parts-and-composes-by-invoke.md +19 -19
  213. package/docs/reference/decisions/0050-what-code-names-config-declares-what-the-cli-names-discovery-finds.md +6 -1
  214. package/docs/reference/decisions/0054-the-kit-ships-machines-and-a-shipped-machine-leaves-its-parts-open.md +55 -40
  215. package/docs/reference/decisions/0055-a-release-is-a-pushed-tag-and-the-publish-guard-is-the-credential.md +14 -13
  216. package/docs/reference/decisions/0057-a-turn-is-its-frame-its-dials-and-whether-it-continues.md +7 -0
  217. package/docs/reference/decisions/0058-a-harness-answers-the-orchestrator-alone.md +13 -7
  218. package/docs/reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md +38 -30
  219. package/docs/reference/decisions/0062-jr2-briefs-the-agent-on-its-seat-never-on-its-task.md +64 -17
  220. package/docs/reference/decisions/0063-the-orchestrator-watches-the-cluster.md +2 -1
  221. package/docs/reference/decisions/0064-a-workspace-waits-for-capacity.md +2 -2
  222. package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-kept-for-a-set-time.md +109 -0
  223. package/docs/reference/decisions/0066-a-model-tier-runs-a-real-model-and-a-change-to-what-it-reads-runs-the-tier.md +51 -23
  224. package/docs/reference/decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md +94 -54
  225. package/docs/reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md +101 -47
  226. package/docs/reference/decisions/0069-the-orchestrator-is-a-kit-image-and-an-instance-publishes-its-assembly.md +32 -9
  227. package/docs/reference/decisions/0070-a-machine-lends-its-parts-to-a-chart.md +17 -13
  228. package/docs/reference/decisions/0071-a-run-starts-a-run-through-a-dispatch-effect.md +56 -30
  229. package/docs/reference/decisions/0072-the-docs-ship-inside-the-kit-and-an-instances-agents-md-indexes-them.md +35 -25
  230. package/docs/reference/decisions/0075-a-machine-cuts-a-worktree-and-the-workspace-only-clones.md +4 -3
  231. package/docs/reference/decisions/0076-an-agents-control-credential-lives-only-where-no-workspace-code-runs.md +37 -10
  232. package/docs/reference/decisions/0078-a-caller-comes-from-one-authenticator-seam-and-acts-within-its-scopes.md +285 -0
  233. package/docs/reference/decisions/0079-an-agent-holds-mcp-tools-a-machine-calls-them-as-an-effect-and-the-machine-is-the-approval.md +198 -0
  234. package/docs/reference/decisions.md +6 -4
  235. package/docs/reference/glossary.md +96 -42
  236. package/docs/reference/hooks.md +1077 -0
  237. package/docs/reference/http-api.md +976 -149
  238. package/docs/why.md +2 -1
  239. package/package.json +10 -3
  240. package/src/actor.ts +36 -10
  241. package/src/agent.ts +50 -0
  242. package/src/assembly-checks.ts +530 -4
  243. package/src/callers.ts +245 -0
  244. package/src/chart.ts +52 -7
  245. package/src/config.ts +550 -1
  246. package/src/conversations.ts +453 -0
  247. package/src/custodian.ts +8 -2
  248. package/src/customize.ts +143 -4
  249. package/src/dispatch-effect.ts +142 -26
  250. package/src/durability.ts +2 -0
  251. package/src/duration.ts +20 -0
  252. package/src/effect-checks.ts +2 -1
  253. package/src/effect.ts +60 -7
  254. package/src/effector-wire.ts +272 -27
  255. package/src/gate-brand.ts +16 -0
  256. package/src/gate.ts +634 -48
  257. package/src/harness-client.ts +10 -4
  258. package/src/held-secrets.ts +72 -23
  259. package/src/holds.ts +2 -2
  260. package/src/hook-kinds/discord.ts +92 -0
  261. package/src/hook-kinds/door.ts +107 -0
  262. package/src/hook-kinds/github.ts +89 -0
  263. package/src/hook-kinds/gitlab.ts +72 -0
  264. package/src/hook-kinds/hook.ts +7 -0
  265. package/src/hook-kinds/index.ts +465 -0
  266. package/src/hook-kinds/slack.ts +151 -0
  267. package/src/hook-kinds/webhook.ts +113 -0
  268. package/src/hooks.ts +506 -0
  269. package/src/http-effect.ts +76 -38
  270. package/src/http.ts +889 -94
  271. package/src/index.ts +16 -5
  272. package/src/instance.ts +196 -26
  273. package/src/internal.ts +22 -3
  274. package/src/machine-doc.ts +26 -1
  275. package/src/mcp-effect.ts +424 -0
  276. package/src/mount-digest.ts +41 -7
  277. package/src/names.ts +64 -2
  278. package/src/notices.ts +138 -10
  279. package/src/open-body.ts +25 -11
  280. package/src/open-effect.ts +17 -4
  281. package/src/open.ts +4 -2
  282. package/src/parts.ts +87 -9
  283. package/src/party.ts +2 -1
  284. package/src/pick.ts +2 -2
  285. package/src/pool.ts +1142 -163
  286. package/src/registration.ts +203 -13
  287. package/src/run-host.ts +1509 -171
  288. package/src/run-list.ts +191 -0
  289. package/src/sandbox-kube.ts +53 -5
  290. package/src/secret-placement.ts +239 -33
  291. package/src/server.ts +53 -4
  292. package/src/setup.ts +72 -32
  293. package/src/snapshot-store.ts +565 -48
  294. package/src/steer.ts +111 -0
  295. package/src/stub-harness.ts +6 -2
  296. package/src/tokens.ts +263 -22
  297. package/src/wire.ts +17 -0
  298. package/src/workspace.ts +50 -6
  299. package/src/worktree.ts +3 -3
  300. package/docs/reference/decisions/0032-the-console-unlocks-with-the-instance-token.md +0 -61
  301. package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-a-week.md +0 -65
@@ -11,42 +11,47 @@ Open a shell in the [Sandbox](../reference/glossary.md#sandbox) of a run, and re
11
11
  A [Workspace](../reference/glossary.md#workspace) of the run makes the Sandbox, and deletes it when the body of the
12
12
  Workspace gets to its final state or fails. The [Rules](#rules) give the cases in which the Sandbox stays. The Sandbox
13
13
  is a pod. Its `harness` container runs the [Harness](../reference/glossary.md#harness), and the Agent's
14
- [Working tools](../reference/glossary.md#working-tools) run in it. When you use `kubectl exec`, you get a shell in the
15
- same container. An Agent that has only the [Menu](../reference/glossary.md#menu) has no Sandbox. To read its
16
- conversation, see [Watch a run](watch-a-run.md).
14
+ [Working tools](../reference/glossary.md#working-tools) run in it. `jr2 workspace shell` gives you a shell in the same
15
+ container, as the Agent's tools run. An Agent that has only the [Menu](../reference/glossary.md#menu) has no Sandbox. To
16
+ read what an Agent said and did, see [Read a conversation](read-a-conversation.md).
17
17
 
18
- In the commands on this page, replace these values:
18
+ In the commands on this page, replace `<run id>` with the run id, or its first 4 characters or more.
19
+ [`jr2 run`](../reference/cli.md#run) prints it in the line `run <run id> (<workflow>) — attached`.
20
+ [`jr2 runs`](../reference/cli.md#runs) prints the `runId` of each live run.
19
21
 
20
- - `<namespace>`: the namespace of your [Instance](../reference/glossary.md#instance). It is the
21
- [`name`](../reference/config.md#name) in `jr2.config.ts`. When `jr2.config.ts` sets no `name`, it is the name of the
22
- Instance folder.
23
- - `<run id>`: the full run id. [`jr2 run`](../reference/cli.md#run) prints it in the line
24
- `run <run id> (<workflow>) — attached`. [`jr2 runs`](../reference/cli.md#runs) prints the `runId` of each live run. A
25
- prefix does not work here, because `kubectl` does not know the run ids.
26
-
27
- Give each `jr2` command in the Instance folder.
22
+ Give each `jr2` command in the [Instance](../reference/glossary.md#instance) folder. The `jr2 workspace` commands read
23
+ the Sandbox resources from the cluster with your kubectl credentials. They do not use the
24
+ [Orchestrator](../reference/glossary.md#orchestrator), so they also work when the Orchestrator is down.
28
25
 
29
26
  ## Find the Sandbox
30
27
 
31
- The label `jr2.dev/run` on each Sandbox holds the full id of its run:
28
+ Run [`jr2 workspace ls`](../reference/cli.md#workspace-ls) with the run id. Without a run id, it lists each Workspace of
29
+ the Instance:
32
30
 
33
31
  ```sh
34
- kubectl -n <namespace> get sandboxes -l jr2.dev/run=<run id>
32
+ jr2 workspace ls <run id>
35
33
  ```
36
34
 
37
35
  ```text
38
- NAME PHASE ENDPOINT AGE
39
- ws-a1322024-x-2-h8pgwk Ready http://ws-a1322024-x-2-h8pgwk.my-instance.svc:8080 16s
36
+ → context <context> / namespace <namespace>
37
+ WORKSPACE SANDBOX WORKFLOW PHASE AGE RUN
38
+ 7a0e8b50/x:0 ws-7a0e8b50-x-0-1eolpdi task Ready 32s held
40
39
  ```
41
40
 
42
- - `NAME` is the name of the Sandbox, here `ws-a1322024-x-2-h8pgwk`. Your name is different. It starts with `ws-`, then
43
- the first 8 characters of the run id. The pod has the same name. In the commands below, write it in place of
44
- `<sandbox>`.
41
+ - `WORKSPACE` is the handle of the Workspace: the first 8 characters of the run id, then the path of the Workspace in
42
+ the run. In the commands below, write it in place of `<workspace>`. You can also give the name of the Sandbox, or the
43
+ first characters of the run id, then `/` and the path.
44
+ - `SANDBOX` is the name of the Sandbox, here `ws-7a0e8b50-x-0-1eolpdi`. Your name is different. The pod has the same
45
+ name.
45
46
  - A run that has two Workspaces at the same time has two rows.
46
- - `PHASE` is `Pending` until the pod is ready and its node has a fresh cache of each Repo. Then it is `Ready`. It is
47
- `Lost` when the pod is gone, and a `Lost` Sandbox does not get a new pod. A delete removes the Sandbox at once, so you
48
- seldom see the phase `Terminating`.
49
- - When the run has no Sandbox now, `kubectl` prints `No resources found in <namespace> namespace.`
47
+ - `PHASE` is `Pending` until the pod is ready and its node has a fresh cache of each
48
+ [Repo](../reference/glossary.md#repo). Then it is `Ready`. It is `Lost` when the pod is gone, and a `Lost` Sandbox
49
+ does not get a new pod. A delete removes the Sandbox at once, so you seldom see the phase `Terminating`.
50
+ - `RUN` tells if a run holds the Sandbox. `held`: a run holds it, or an Orchestrator that stopped held it. `released`:
51
+ its run does not hold it now. `idle`: nothing renewed its [Lease](../reference/glossary.md#lease) for its idle time.
52
+ `unknown`: the Sandbox has no mark.
53
+ - When the run has no Sandbox now, the table has only its header.
54
+ - `--json` prints the list as one JSON object.
50
55
  - [`jr2 status <run id>`](../reference/cli.md#status) prints each [Worktree](../reference/glossary.md#worktree) that the
51
56
  run cut, with its path and its branch, in `worktrees` and in one `worktree:` line for each cut. Give this command on
52
57
  your computer, not in the Sandbox.
@@ -56,18 +61,39 @@ ws-a1322024-x-2-h8pgwk Ready http://ws-a1322024-x-2-h8pgwk.my-instance.svc:8
56
61
 
57
62
  ## Open a shell
58
63
 
64
+ Run [`jr2 workspace shell`](../reference/cli.md#workspace-shell) with the handle:
65
+
59
66
  ```sh
60
- kubectl -n <namespace> exec -it <sandbox> -c harness -- bash
67
+ jr2 workspace shell <workspace>
61
68
  ```
62
69
 
63
- The default [Sandbox Image](../reference/glossary.md#sandbox-image) that [`jr2 init`](../reference/cli.md#init) writes
64
- starts from `node:24-slim`, which has `bash`. If your Sandbox Image has no `bash`, use `sh`.
70
+ `jr2 completion bash|zsh|fish` completes the handles; see [`jr2 completion`](../reference/cli.md#completion).
71
+
72
+ The shell runs as the Agent's tools run. The Harness starts it in the same Landlock domain as the Agents, in `/work`.
73
+ Thus it has the same files, the same limits and the same [Stand-ins](../reference/glossary.md#stand-in) as an Agent's
74
+ `bash`, and it cannot read the credential with which the Harness speaks for the Agents. It can see and stop a process
75
+ that an Agent started, such as a dev server. The shell is `bash`, or `sh` when the image has no `bash`. The default
76
+ [Sandbox Image](../reference/glossary.md#sandbox-image) that [`jr2 init`](../reference/cli.md#init) writes starts from
77
+ `node:24-slim`, which has `bash`.
78
+
79
+ To run one command and not a shell, give it after `--`:
80
+
81
+ ```sh
82
+ jr2 workspace shell <workspace> -- git -C /work status
83
+ ```
84
+
85
+ A command after `--` has no terminal. Ctrl-C stops `jr2`, and the command gets the end of its input but no signal. Thus
86
+ a command that does not stop at the end of its input, such as a dev server, can continue to run.
87
+
88
+ When the Workspace has a [User Container](../reference/glossary.md#user-container), add `--user` to open a shell in it.
89
+ [Add tools to the Sandbox](add-tools-to-the-sandbox.md#run-a-service-beside-the-agent) tells how to reach a service in
90
+ it.
65
91
 
66
92
  ## Find the Worktree
67
93
 
68
94
  Each [Repo Slot](../reference/glossary.md#repo-slot) of the Workspace has a folder in `/work`. In it, `default` is a
69
- clone of the [Repo](../reference/glossary.md#repo), and each [Worktree](../reference/glossary.md#worktree) that the
70
- Machine cut is beside it. To show the folders of the Repo Slots, use this command:
95
+ clone of the Repo, and each [Worktree](../reference/glossary.md#worktree) that the Machine cut is beside it. To show the
96
+ folders of the Repo Slots, use this command:
71
97
 
72
98
  ```sh
73
99
  ls /work
@@ -82,8 +108,8 @@ git -C /work/<Repo Slot>/default worktree list
82
108
  For the slot `target` of a run of `task`, the output is:
83
109
 
84
110
  ```text
85
- /work/target/default 7f258f6 (detached HEAD)
86
- /work/target/task e467788 [jr2/task-1f34eef3-5749-4d7c-a16b-488c56ec88cd]
111
+ /work/target/default 9f67321f (detached HEAD)
112
+ /work/target/task 9f67321f [jr2/task-48ebf9ad-1e5d-4997-a330-d91ec762f83c]
87
113
  ```
88
114
 
89
115
  The first line is the clone, on the base of the Repo Slot. Here the base is a tag, so the clone is detached. On a
@@ -126,7 +152,7 @@ git show --stat HEAD
126
152
  You can also give one command, with no shell:
127
153
 
128
154
  ```sh
129
- kubectl -n <namespace> exec <sandbox> -c harness -- git -C /work/<Repo Slot>/<worktree> log --oneline
155
+ jr2 workspace shell <workspace> -- git -C /work/<Repo Slot>/<worktree> log --oneline
130
156
  ```
131
157
 
132
158
  ## Push the branch
@@ -150,6 +176,23 @@ A [Machine](../reference/glossary.md#machine) can also push the branch with an
150
176
  > The Agent works in the same files as your shell, so it sees each change that you make there. When the Sandbox goes, a
151
177
  > commit that you did not push goes with it.
152
178
 
179
+ ## Remove a Sandbox that no run holds
180
+
181
+ A Sandbox that a cancel with `--keep` or a fault left stays until the operator deletes it. To delete it before then, run
182
+ [`jr2 workspace rm`](../reference/cli.md#workspace-rm):
183
+
184
+ ```sh
185
+ jr2 workspace rm <workspace>
186
+ ```
187
+
188
+ ```text
189
+ → context <context> / namespace <namespace>
190
+ removed Workspace 7a0e8b50/x:0 (ws-7a0e8b50-x-0-1eolpdi)
191
+ ```
192
+
193
+ `jr2 workspace rm` removes only a Sandbox that `jr2 workspace ls` shows as `released` or `idle`. To remove the Sandbox
194
+ of a live run, cancel the run. See [Cancel a run](cancel-a-run.md).
195
+
153
196
  ## Rules
154
197
 
155
198
  - The Workspace deletes its Sandbox when its body gets to its final state. When the body of each Workspace of the run
@@ -166,6 +209,29 @@ A [Machine](../reference/glossary.md#machine) can also push the branch with an
166
209
  its Workspace. The operator deletes the Sandbox 30 minutes after the last renewal.
167
210
  - A Workspace in [Placing](../reference/glossary.md#placing) deletes its Sandbox at once, also after a fault and after a
168
211
  CANCEL with `--keep`. Its Sandbox has no node yet, so it has nothing to look inside.
212
+ - The `jr2 workspace` commands need your kubectl credentials to list the Sandbox resources. Without them, the command
213
+ says: `cannot list the Sandboxes in namespace <namespace>: <message>`
214
+ - With no kube context, the `jr2 workspace` commands say:
215
+ ``no kube context — `kind create cluster` (or point kubectl at one), then `jr2 up` ``
216
+ - A handle that names no Workspace is an error. The command exits with `1`:
217
+ ``no Workspace "<handle>" — `jr2 workspace ls` lists them``
218
+ - A handle that names more than one Workspace is an error. The command lists each Workspace that it names, and exits
219
+ with `1`: `"<handle>" names <n> Workspaces — give more of the run id:`
220
+ - `jr2 workspace rm` refuses the Sandbox of a live run, and exits with `1`. There is no option to force it:
221
+ ``Workspace <handle> (<sandbox>) is not removed: run <run id> holds it — cancel the run first (`jr2 send <run id> --event CANCEL`)``
222
+ - `jr2 workspace rm` refuses a Sandbox with no hold mark (`RUN` is `unknown`), and exits with `1`:
223
+ ``Workspace <handle> (<sandbox>) is not removed: it has no hold mark, so it may be held by run <run id> — cancel the run first (`jr2 send <run id> --event CANCEL`)``
224
+ - `jr2 workspace rm` refuses a Sandbox that a run started to hold again after `jr2 workspace rm` read it:
225
+ ``Workspace <handle> (<sandbox>) is not removed: it changed after it was read, so a run may hold it again — run `jr2 workspace ls` and try again``
226
+ - `jr2 workspace shell --user` refuses a Workspace with no User Container, and exits with `1`:
227
+ ``Workspace <handle> has no User Container: its workspace() names no `user` image``
228
+ - A refusal of the Harness starts with `jr2 workspace shell: `.
229
+ - `jr2 workspace shell` needs `bash` or `sh` on the `PATH` of the Sandbox Image. When it has neither, the command says:
230
+ `jr2 workspace shell: the Sandbox Image has no bash and no sh on its PATH`
231
+ - `jr2 workspace shell --user` with no command needs `sh` in the image of the User Container. When it has none, the
232
+ command says: `the User Container's image has no sh: give it a shell, or name a command after --`
233
+ - `jr2 workspace shell --user -- <command>` says this when the User Container cannot run the command (exit `126` or
234
+ `127`): `the User Container could not run <command> (exit <code>)`
169
235
 
170
236
  ## Read next
171
237
 
@@ -174,4 +240,8 @@ A [Machine](../reference/glossary.md#machine) can also push the branch with an
174
240
  - [ADR-0004](../reference/decisions/0004-worktree-provisioning-model.md): the clone and the Worktree.
175
241
  - [ADR-0005](../reference/decisions/0005-sandbox-pod-composition.md): the containers of a Sandbox.
176
242
  - [ADR-0012](../reference/decisions/0012-workspace-wrapper-machine.md): when a Workspace deletes its Sandbox.
243
+ - [ADR-0021](../reference/decisions/0021-workspace-continuity-is-a-lease-that-answers-back.md): the Lease, and when a
244
+ run holds its Sandbox.
245
+ - [ADR-0076](../reference/decisions/0076-an-agents-control-credential-lives-only-where-no-workspace-code-runs.md): why
246
+ your shell runs in the domain of the Agents.
177
247
  - [Watch a run](watch-a-run.md)
@@ -1,12 +1,13 @@
1
1
  ---
2
2
  title: Open the Console
3
- description: Forward the port of the Orchestrator, open the Console, and unlock it with the Instance token.
3
+ description: Forward the port of the Orchestrator, open the Console, and unlock it with a token or a login.
4
4
  ---
5
5
 
6
6
  # Open the Console
7
7
 
8
- Open the [Console](../reference/glossary.md#console) in a browser, and paste the Instance token to start runs and answer
9
- [Gates](../reference/glossary.md#gate).
8
+ Open the [Console](../reference/glossary.md#console) in a browser. Paste a token, or log in, to start runs and answer
9
+ [Gates](../reference/glossary.md#gate). The Console shows only what the [Caller](../reference/glossary.md#caller) of the
10
+ token may do.
10
11
 
11
12
  The [Orchestrator](../reference/glossary.md#orchestrator) serves the Console on port 4000, in the cluster. To reach it
12
13
  from your computer, forward the port with `kubectl`. In the commands on this page, replace `<namespace>` with the
@@ -39,6 +40,8 @@ Without the token, the Console shows the runs, and you cannot change them:
39
40
  Click the caret of a Workflow to list its runs.
40
41
  - The center shows the [Machine](../reference/glossary.md#machine) of the Workflow that you select. When you select a
41
42
  run, the Console shows the states that the run is in.
43
+ - A run on an [Assembly](../reference/glossary.md#assembly) that is not the current one shows the mark
44
+ `older Assembly · <hash>`. The center then shows the Machine of that run, not the current Machine.
42
45
  - The Activity tab of the right drawer lists the type of each [Emit](../reference/glossary.md#emit) of the runs of the
43
46
  Workflow, the newest first.
44
47
 
@@ -62,29 +65,75 @@ The command prints the token, with no line break after it.
62
65
 
63
66
  ## Paste the token
64
67
 
65
- Paste the token into the box `instance token` in the nav of the Console. Push Enter. The badge after the box shows `…`
66
- while the Console checks the token, then `live`. With a live token, the Console shows more:
68
+ Paste the token into the box `Caller token` in the nav of the Console. Push Enter. The badge after the box shows `…`
69
+ while the Console checks the token, then `live`. The nav then shows who the Console acts as, such as
70
+ `as token/instance`. Put the pointer on the name to see its scopes.
67
71
 
68
- - A `start` button for each Workflow in the Fleet rail. It opens a form for the run input of the Workflow. A Workflow
69
- that declares no run input gets a box for JSON.
70
- - The Attention tab of the right drawer. It shows a card for each open Gate of the selected Workflow, with a form to
71
- send each event that the Gate takes. Select `all workflows` to see the Gates of each Workflow.
72
+ The Console asks the Orchestrator what the token may do ([`GET /whoami`](../reference/http-api.md#get-whoami)). Then it
73
+ shows each control that a scope of the token opens:
72
74
 
73
- The Console keeps the token in the browser tab. A reload keeps it. When you close the tab, the token is gone.
75
+ | Scope | What the Console shows |
76
+ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
77
+ | `start` | A `start` button for the Workflow in the Fleet rail. It opens a form for the run input of the Workflow. |
78
+ | `answer` | The Attention tab of the right drawer, with a card for each open Gate and a form for each event it takes. |
79
+ | `read` | The full state of the selected run: why it waits, why it failed, and who started it. The ended runs of the Workflow in the Fleet rail. The conversations of the run in the bottom drawer. |
80
+ | `cancel` | A `cancel run` button on the selected run, while the run is live. |
81
+ | `steer` | A box in the bottom drawer, beside the [Agent](../reference/glossary.md#agent) slot, to send a [Steering message](../reference/glossary.md#steering-message) while the run is live. |
82
+
83
+ The Instance token has each scope for each Workflow, so it shows each control. A named Caller token shows the controls
84
+ of its scopes, for its Workflows ([Give a Caller a scope](give-a-caller-a-scope.md)). A Workflow that declares no run
85
+ input gets a box for JSON in its start form. In the Attention tab, select `all workflows` to see the Gates of each
86
+ Workflow.
87
+
88
+ The Console keeps the token in the browser tab. A reload keeps it. When you close the tab, the token is gone. Click
89
+ `sign out` to forget it before then.
90
+
91
+ ## Read a conversation
92
+
93
+ With `read`, the Fleet rail lists the ended runs of the selected Workflow under its live runs, each with its status. A
94
+ `drifted` run shows its reason. Click an ended run to see its Machine, the state where it ended, and its conversations,
95
+ for as long as jr2 keeps the run ([`runs.retain`](../reference/config.md#runs)).
96
+
97
+ The bottom drawer shows the [Conversations](../reference/glossary.md#conversation) of the selected run. Closed, it is a
98
+ bar with one tab for each Agent slot of the run. A dot shows a slot whose [Turn](../reference/glossary.md#turn) is open.
99
+ Click a tab to open the drawer on that slot. The drawer shows what the model wrote, each tool call with the answer of
100
+ its pick, the refusals, the Steering messages and the notices. While the Turn is open, the drawer adds each new entry.
101
+ Drag the top edge of the drawer to change its height. The browser keeps the height for you.
102
+
103
+ ## Log in
104
+
105
+ When the Instance declares an issuer with [`login: true`](../reference/config.md#callers), the nav shows a `log in`
106
+ button. Click it. The browser goes to the login page of the issuer, and then comes back to the Console. The Console then
107
+ acts as you, with the scopes that your groups give. The nav shows the name that jr2 shows for you, such as your email.
108
+
109
+ To make the login work, register a client at the issuer:
110
+
111
+ - A public client, with no secret. Its client id is the `audience` of the issuer entry.
112
+ - The redirect URI is the root of the Console, such as `http://localhost:4000/`.
113
+ - The issuer must let the origin of the Console call its discovery document and its token endpoint (CORS).
114
+
115
+ The login needs the Console on `https`, or on `localhost`, because the browser makes its code challenge only there.
74
116
 
75
117
  ## Rules
76
118
 
77
119
  - A token that the Orchestrator does not accept reads `invalid`. The Console then shows no `start` button and no
78
120
  Attention tab.
79
- - When the Orchestrator refuses the token later, with the status 401, the Console goes back to view only.
80
- - Only the Instance token unlocks the Console. A [Sandbox](../reference/glossary.md#sandbox) token reads `invalid`.
121
+ - When the Orchestrator refuses the token later, with the status 401, the Console goes back to view only. An expired
122
+ login and a rotated token do this.
123
+ - A login whose groups give no scope reads `live` and shows no control. The nav shows who you are, so that you can see
124
+ why.
125
+ - A [Sandbox](../reference/glossary.md#sandbox) token is not a Caller. It reads `invalid`.
126
+ - The Console hides a control that the scopes do not open, so that you do not get a 403. The Orchestrator still checks
127
+ each request.
81
128
  - The port forward stops when you stop its command, or when the Orchestrator pod restarts. Then run the command again.
82
129
 
83
130
  ## Read next
84
131
 
85
132
  - [Architecture](../concepts/architecture.md)
86
- - [ADR-0032](../reference/decisions/0032-the-console-unlocks-with-the-instance-token.md): why the token unlocks the
87
- Console.
133
+ - [ADR-0032](../reference/decisions/0032-the-console-unlocks-with-a-callers-credential.md): why a Caller's credential
134
+ unlocks the Console, and how the login works.
135
+ - [ADR-0078](../reference/decisions/0078-a-caller-comes-from-one-authenticator-seam-and-acts-within-its-scopes.md): the
136
+ Callers and their scopes.
88
137
  - [ADR-0014](../reference/decisions/0014-observation-is-open-run-state-is-not.md): what the Console shows with no token.
89
138
  - [`GET /`](../reference/http-api.md#get) and the [open band](../reference/http-api.md#band-open)
90
139
  - [Answer a Gate](answer-a-gate.md)
@@ -0,0 +1,225 @@
1
+ ---
2
+ title: Read a conversation
3
+ description: Read what an Agent said and did in a run, live or after the run ended, with jr2 logs or the Console.
4
+ ---
5
+
6
+ # Read a conversation
7
+
8
+ Read the [Conversation](../reference/glossary.md#conversation) of each [Agent](../reference/glossary.md#agent) of a run,
9
+ while the run continues or after it ended.
10
+
11
+ The [Harness](../reference/glossary.md#harness) of each Agent sends the entries of its conversation to the
12
+ [Orchestrator](../reference/glossary.md#orchestrator) during the [Turn](../reference/glossary.md#turn). The Orchestrator
13
+ keeps them for as long as it keeps the run. Thus you can read a conversation after its
14
+ [Sandbox](../reference/glossary.md#sandbox) is gone. A [Menu](../reference/glossary.md#menu)-only Agent sends its
15
+ conversation in the same way.
16
+
17
+ The examples on this page use a run of the `task` [Workflow](../reference/glossary.md#workflow) of
18
+ [An Agent in a Sandbox](../get-started/an-agent-in-a-sandbox.md), with the prompt
19
+ ``In docs/intro/repo, run `node bin/greet.js`. Then finish, with what it printed.``. In the commands, replace `<run id>`
20
+ with the run id, or its first 4 characters or more. `jr2 run` prints the run id in the line
21
+ `run <run id> (<workflow>) — attached`.
22
+
23
+ Give each `jr2` command in the [Instance](../reference/glossary.md#instance) folder.
24
+
25
+ ## Print the conversations of a run
26
+
27
+ Run [`jr2 logs`](../reference/cli.md#logs) with the run id. It prints the conversation of each Agent of the run, in the
28
+ order of the time of each entry:
29
+
30
+ ```sh
31
+ jr2 logs <run id>
32
+ ```
33
+
34
+ ```text
35
+ → context <context> / namespace <namespace>
36
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] [prompt] In docs/intro/repo, run `node bin/greet.js`. Then finish, with what it printed.
37
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder]
38
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] Work in /work/target/task, on branch jr2/task-48ebf9ad-1e5d-4997-a330-d91ec762f83c — your tools are rooted there, so a relative path lands inside it. Commit what you do there, then call finish.
39
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder]
40
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] <jr2-turn>
41
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] Working directory: /work/target/task
42
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] Allowed now: `mcp__jr2__finish`.
43
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] </jr2-turn>
44
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] [thinking] The user wants me to:
45
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] 1. Run `node bin/greet.js` in the directory `docs/intro/repo`
46
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] 2. Finish with what it printed
47
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder]
48
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] Let me first check if this file exists and what it contains, then run it.
49
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder]
50
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] [text]
51
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder]
52
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder]
53
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] [bash] node docs/intro/repo/bin/greet.js
54
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] [thinking] The command printed "hello, world". Now I need to finish with that.
55
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder]
56
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] [text]
57
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder]
58
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder]
59
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] [finish] {"summary":"Ran `node bin/greet.js` in docs/intro/repo. It printed: hello, world"}
60
+ [coder] [7a0e8b50-7b3e-4d83-837c-d07857d81868/body/coder] [finish answer] Delivered "finish" to the workflow (delivery a86c2340-377a-4c4d-a138-2872c38c1219). The workflow consumed it and moved on: your turn is over.
61
+ ```
62
+
63
+ The thinking, the calls and the text are the words of the model, so your conversation is different. Your ids are
64
+ different too.
65
+
66
+ `jr2 logs` prints the conversation lines of the pod log of the Harness. It does not print the lines of the story of the
67
+ run: `[run] …`, and `[<agent>] [admitted] …` and `[<agent>] [pick] …`, which have no Instance ID.
68
+ [Watch a run](watch-a-run.md#read-the-pod-log) tells how to read the pod log.
69
+
70
+ ## Print the conversation of one Agent
71
+
72
+ Give an Agent slot, or the name of an Agent, after the run id. An Agent slot is the path of the
73
+ [Machine](../reference/glossary.md#machine) of the Agent, then its name, such as `body/coder`.
74
+ [`jr2 steer`](../reference/cli.md#steer) `<run id>` lists the Agent slots of a live run. A name, such as `coder`, prints
75
+ each conversation of the Agents of that name:
76
+
77
+ ```sh
78
+ jr2 logs <run id> coder
79
+ ```
80
+
81
+ When the run keeps no conversation of that Agent, `jr2 logs` lists the Agents that it keeps. Without `-f`, it then exits
82
+ with `1`. With `-f`, it waits for the conversation of that Agent.
83
+
84
+ ## Follow a conversation
85
+
86
+ Add `-f` to print each new entry when the Orchestrator keeps it:
87
+
88
+ ```sh
89
+ jr2 logs <run id> -f
90
+ ```
91
+
92
+ `jr2 logs -f` first prints what the Orchestrator keeps. Then it follows each conversation that has an open Turn, and it
93
+ finds each new conversation of the run. It stops when the run ended and no Turn is open. The Harness sends its entries
94
+ when the model's answer ends, at the end of the Turn, and about one time each second. Thus a line comes a short time
95
+ after the model wrote it.
96
+
97
+ ## Read the lines
98
+
99
+ Each line starts with the name of the Agent in brackets, then the [Instance ID](../reference/glossary.md#instance-id) of
100
+ the conversation in brackets. The Instance ID starts with the run id. The first line of each entry then has a label in
101
+ brackets. The next lines of the same entry have no label:
102
+
103
+ | Line | What it shows |
104
+ | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
105
+ | `[<agent>] [<iid>] [prompt] <text>` | A message that the model reads: the prompt of the Turn, or a message that jr2 adds to the Turn, such as a [Steering message](../reference/glossary.md#steering-message) or a notice. |
106
+ | `[<agent>] [<iid>] [thinking] <text>` | The thinking of the model. |
107
+ | `[<agent>] [<iid>] [text] <text>` | The text of the model. |
108
+ | `[<agent>] [<iid>] [<call>] <input>` | A call of a [Working tool](../reference/glossary.md#working-tools), or a pick from the Menu. `<input>` is a path for read, write and edit, the command for `bash`, or else JSON. |
109
+ | `[<agent>] [<iid>] [<server>/<tool>] <input>` | A call of an [MCP tool](../reference/glossary.md#mcp-tools): the server's name in `jr2.config.ts`, then the tool. `<input>` is JSON. A pick never prints with a `/`. |
110
+ | `[<agent>] [<iid>] [<pick> answer] <text>` | The answer that the model got for a pick from its Menu. |
111
+ | `[<agent>] [<iid>] [<pick> error] <text>` | An answer to a pick that the model reads as an error, such as a refusal. |
112
+ | `[<agent>] [<iid>] [compacted] <text>` | The Harness made the context of the conversation smaller: `context <before> → ~<after> tokens (window <window>)`. |
113
+ | `[<agent>] [<iid>] [thinking level] <text>` | The model has no thinking level of the name that the Turn asked for, and the line names the level that the model ran at. The Harness prints it one time for each Turn. |
114
+ | `[<agent>] [<iid>] [cut] <text>` | The Orchestrator keeps no more entries of this conversation. See [Rules](#rules). |
115
+
116
+ The conversation does not hold the result of a Working tool or of an MCP tool. For example, it does not hold the text of
117
+ a file that the Agent read, or the output of a command that the Agent ran. The Harness cuts an input that is longer than
118
+ 2000 characters at its end, and marks the cut with `…`. It cuts a long answer to a pick in its middle, and marks the cut
119
+ with `… [<n> characters cut] …`. The model reads the full text.
120
+
121
+ ## Read a conversation in the Console
122
+
123
+ With a [Caller](../reference/glossary.md#caller) token that has the `read` scope for the Workflow, the
124
+ [Console](../reference/glossary.md#console) shows the conversations of the run that you select:
125
+
126
+ - The bottom drawer has one tab for each Agent slot of the run. A dot on a tab shows a slot whose Turn is open.
127
+ - Click a tab. The drawer opens on the conversation of that slot. While the Turn is open, the drawer adds each new
128
+ entry.
129
+ - The drawer folds each pick with its answer. A Working tool's call shows no result. It shows the Steering messages, the
130
+ notices and each [Compaction](../reference/glossary.md#compaction).
131
+ - The Fleet rail lists the ended runs of the Workflow under its live runs. Click an ended run to read its conversations.
132
+
133
+ [Open the Console](open-the-console.md#read-a-conversation) tells more.
134
+
135
+ ## Keep conversations for a different time
136
+
137
+ The Orchestrator keeps an ended run, with its conversations, for 30 days. To change the time, set
138
+ [`runs.retain`](../reference/config.md#runs) in `jr2.config.ts`. The conversations are on the state volume of the
139
+ Orchestrator. A new volume claim is `5Gi` by default. To make it larger, set `runs.volume`:
140
+
141
+ ```ts
142
+ import { defineConfig } from "@jr2/orchestrator";
143
+
144
+ export default defineConfig({
145
+ runs: {
146
+ // Keep each ended run, its conversations and the hook log for 90 days.
147
+ retain: "90d",
148
+ // The size of the Orchestrator's state volume. A larger size needs a StorageClass that allows expansion.
149
+ volume: "20Gi",
150
+ },
151
+ });
152
+ ```
153
+
154
+ Then run [`jr2 up`](../reference/cli.md#up). The Orchestrator uses the new `retain` at its next sweep, one time each
155
+ hour. When `runs.volume` is larger than the volume claim, `jr2 up` makes the claim larger, but only when its
156
+ StorageClass allows expansion. The `standard` class of kind does not. Thus on kind, with the claim of `5Gi` that the
157
+ first `jr2 up` made, `jr2 up` refuses, and applies nothing:
158
+
159
+ ```text
160
+ …
161
+ refusing: runs.volume is 20Gi, larger than the state volume claim jr2-state (5Gi), and its StorageClass "standard" does not allow expansion (allowVolumeExpansion is not true). Keep runs.volume at 5Gi, or use a StorageClass that allows expansion (ADR-0065). Nothing was applied.
162
+ ```
163
+
164
+ On kind, set `runs.volume` before the first `jr2 up` of the Instance. A new claim takes that size, and `jr2 up` prints
165
+ no line about it. A live run and its conversations stay, whatever their age.
166
+
167
+ ## Rules
168
+
169
+ - The Orchestrator keeps at most 8 MiB of one conversation. It keeps the start of the conversation. In place of the
170
+ entry that goes above the limit, it keeps one entry `[cut]`, and it keeps no entry after it:
171
+ `the Orchestrator keeps no more of this conversation: it is at its cap of 8 MiB (ADR-0023)`
172
+ - When the state volume is more than 80% full, the Orchestrator deletes the conversations of the runs that ended, the
173
+ oldest run first, until the volume is less than 80% full. It does not delete the row of the run. It never deletes a
174
+ conversation of a live run for space. `jr2 logs` prints `<agent slot> [<iid>]: no space` in place of a conversation
175
+ that it deleted, and `jr2 status` and `jr2 runs` give the run `swept: "conversation swept: no space"`.
176
+ - When the volume is more than 95% full and no ended run has a conversation to delete, the Orchestrator keeps no more
177
+ entries of each open conversation:
178
+ `the Orchestrator keeps no more of this conversation: its state volume is full (ADR-0065)`
179
+ - `jr2 logs` with an Agent that the run keeps no conversation of prints a line on stderr. Without `-f`, it then exits
180
+ with `1`; with `-f`, it waits: `run <run id> keeps no conversation of "<agent>" — its Agents: <slots>`
181
+ - When the run keeps no conversation at all, the line ends differently:
182
+ `run <run id> keeps no conversation of "<agent>" — it keeps no conversation yet`
183
+ - The routes of the conversations refuse a Caller without the `read` scope for the Workflow of the run, with the status
184
+ code `403`: `the Caller <via>/<name> needs the "read" scope for Workflow "<workflow>" (ADR-0078)`. A Caller with the
185
+ `read` scope for no Workflow gets this refusal first:
186
+ `the Caller <via>/<name> has no "read" scope for any Workflow (ADR-0078)`
187
+ - `GET /runs/:runId/conversations/:instanceId` refuses an Instance ID that the run does not keep, with the status code
188
+ `404`: `run "<run id>" keeps no conversation "<iid>"`
189
+ - `runs.retain` is a number and `m`, `h`, `d` or `w`. The config load refuses another value:
190
+ `<file> at runs.retain: "<value>" is not a duration — a number and m, h, d or w, such as "30d" (ADR-0065)`
191
+ - The config load refuses a `runs.retain` that is shorter than one hour:
192
+ `<file> at runs.retain: "<value>" is shorter than 1h — jr2 keeps an ended run for at least 1h (ADR-0065)`
193
+ - The config load refuses a `runs.volume` with no unit:
194
+ `<file> at runs.volume: "<value>" is not a storage quantity — a number and a unit, such as "5Gi" or "500Mi" (ADR-0065)`
195
+ - `jr2 up` grows the claim when `runs.volume` is larger and the StorageClass allows expansion:
196
+ `state volume: growing the claim jr2-state from <claim size> to <size>`
197
+ - `jr2 up` keeps the size of a claim that exists when `runs.volume` is not set, and the claim is not `5Gi`:
198
+ `state volume: keeping the claim jr2-state at <claim size> — runs.volume is not set, and the default 5Gi is for a new claim`
199
+ - `jr2 up` refuses, and applies nothing, when it cannot read the claim:
200
+ `refusing: cannot read the state volume claim jr2-state in namespace "<namespace>" (<error>). Nothing was applied.`
201
+ - `jr2 up` refuses, and applies nothing, when `runs.volume` is larger and it cannot read the StorageClass:
202
+ `refusing: runs.volume is <size>, larger than the state volume claim jr2-state (<claim size>), and jr2 cannot read StorageClass "<class>" to see if it allows expansion (<error>). Nothing was applied.`
203
+ - `jr2 up` refuses a `runs.volume` that is smaller than the claim, and applies nothing:
204
+ `refusing: runs.volume is <size>, smaller than the state volume claim jr2-state (<claim size>) — Kubernetes never makes a claim smaller. Set runs.volume to <claim size> or more (ADR-0065). Nothing was applied.`
205
+ - `jr2 up` refuses a larger `runs.volume` on a StorageClass that does not allow expansion, and applies nothing:
206
+ `refusing: runs.volume is <size>, larger than the state volume claim jr2-state (<claim size>), and its StorageClass "<class>" does not allow expansion (allowVolumeExpansion is not true). Keep runs.volume at <claim size>, or use a StorageClass that allows expansion (ADR-0065). Nothing was applied.`
207
+
208
+ > **Caution**
209
+ >
210
+ > A Caller with `read` can read each conversation of the Workflow, and the answers that jr2 gives to the picks. An answer
211
+ > can hold the output of a [`command`](../reference/authoring-surface/command.md)
212
+ > [Effect](../reference/glossary.md#effect). Give `read` only to the Callers that can see that output.
213
+ > [Secrets and trust](../concepts/secrets-and-trust.md) tells what a conversation can hold.
214
+
215
+ ## Read next
216
+
217
+ - [Agents and Turns](../concepts/agents-and-turns.md)
218
+ - [Durable runs](../concepts/durable-runs.md): how long jr2 keeps a run.
219
+ - [ADR-0023](../reference/decisions/0023-the-harness-prints-the-conversation.md): the Harness prints the conversation,
220
+ and the Orchestrator keeps it.
221
+ - [ADR-0065](../reference/decisions/0065-a-persist-survives-a-crash-and-history-is-kept-for-a-set-time.md):
222
+ `runs.retain`, `runs.volume` and the space guard.
223
+ - Reference: [`jr2 logs`](../reference/cli.md#logs), [`runs`](../reference/config.md#runs),
224
+ [`GET /runs/:runId/conversations`](../reference/http-api.md#get-runs-runid-conversations)
225
+ - [Watch a run](watch-a-run.md)
@@ -141,26 +141,24 @@ Put the Chart file in a folder that has the name of its wrapper: `workflows/<wra
141
141
  lower-case letters, digits and `-`. Then run [`jr2 up`](../reference/cli.md#up). It checks each Chart file at the door
142
142
  before it changes the cluster, and publishes it in the [Assembly](../reference/glossary.md#assembly).
143
143
 
144
- [`jr2 runs`](../reference/cli.md#runs) lists the Chart under its wrapper, on stderr:
144
+ [`jr2 workflows`](../reference/cli.md#workflows) lists the Chart under its wrapper:
145
145
 
146
146
  ```sh
147
- jr2 runs
147
+ jr2 workflows
148
148
  ```
149
149
 
150
150
  ```text
151
151
  …
152
152
  → context kind-jr2 / namespace my-instance
153
- workflows:
154
- notes (machine, Chart wrapper: body "body", one-shot)
155
- notes/summary (chart file)
156
- ping (machine)
157
- []
153
+ notes (machine, Chart wrapper: body "body", one-shot)
154
+ notes/summary (chart file)
155
+ ping (machine)
158
156
  ```
159
157
 
160
158
  The first line, `…`, is the line `→ .env:`, with the keys that the CLI took from `.env`.
161
159
 
162
- `one-shot` means that the wrapper also takes a Chart in its run input. `jr2 runs --workflows` prints the same list as
163
- JSON on stdout.
160
+ `one-shot` means that the wrapper also takes a Chart in its run input. `jr2 workflows --json` prints the same list as
161
+ JSON.
164
162
 
165
163
  ## Run the Chart
166
164
 
@@ -173,7 +171,7 @@ jr2 run notes/summary --input '{"topic":"the greet CLI"}'
173
171
  ```text
174
172
  …
175
173
  → context kind-jr2 / namespace my-instance
176
- run 08a1a07b-b5d8-4e8b-aec5-811eab9289ec (notes/summary) — attached
174
+ run ff5db853-9afc-4563-9db4-e5c2a49b15a2 (notes/summary) — attached
177
175
  → active "running"
178
176
  → active "running"
179
177
  → done "done"
@@ -203,12 +201,12 @@ curl -X PUT -H "Authorization: Bearer $TOKEN" -H "content-type: application/json
203
201
  ```
204
202
 
205
203
  ```text
206
- {"name":"notes/brief","origin":"runtime","hash":"4685124c248a"}
204
+ {"name":"notes/brief","origin":"runtime","hash":"4f2fb0e7474c"}
207
205
  ```
208
206
 
209
207
  `hash` is the hash of the Chart text. The status code is `201` for a new name, and `200` when the Chart replaced a
210
- runtime Chart with the same name. `jr2 runs` then lists `notes/brief (chart)`, and `jr2 run notes/brief` starts it. A
211
- run of the old text keeps its own text.
208
+ runtime Chart with the same name. `jr2 workflows` then lists `notes/brief (chart)`, and `jr2 run notes/brief` starts it.
209
+ A run of the old text keeps its own text.
212
210
 
213
211
  To remove the Chart:
214
212
 
@@ -217,7 +215,7 @@ curl -X DELETE -H "Authorization: Bearer $TOKEN" http://localhost:4000/workflows
217
215
  ```
218
216
 
219
217
  The Orchestrator keeps a runtime Chart on its volume, so it stays after a restart. When a publish removes a part that it
220
- uses, it stays, and `jr2 runs` marks it `unrunnable` with the reason.
218
+ uses, it stays, and `jr2 workflows` marks it `unrunnable` with the reason.
221
219
 
222
220
  ## Run a Chart one time
223
221
 
@@ -254,7 +252,9 @@ write.
254
252
  - The `PUT` refuses a Chart that the door refuses, with the status `422`: `{"error":"refused","report":[<problems>]}`
255
253
  - The `DELETE` refuses a Chart file, with the status `409`:
256
254
  ``a Chart file is the Instance's own: remove workflows/<wrapper>/<name>.chart.json and `jr2 up` (ADR-0070)``
257
- - `PUT` and `DELETE` need the Instance token. Without it, the status is `401`.
255
+ - `PUT` and `DELETE` need the Instance token. No scope opens them. Without a token, the status is `401`. With the token
256
+ of a named Caller or a JWT, the status is `403`:
257
+ `this route needs the Instance token: no scope opens it, so the Caller <via>/<name> cannot`
258
258
  - An unrunnable named Chart does not start. The status is `409`: `named Chart "<wrapper>/<name>" cannot run: <reason>`
259
259
  - `jr2 run` prints the report of a Chart that the door refuses in the run input, and exits with `1`:
260
260
  `error: the door refused the Chart for "<workflow>"`, then one line for each problem.
@@ -264,7 +264,8 @@ write.
264
264
  - [Charts](../concepts/charts.md)
265
265
  - [Start a run](start-a-run.md)
266
266
  - [Let an Agent write a Chart](let-an-agent-write-a-chart.md)
267
- - Reference: [`chartSchema`](../reference/authoring-surface/chartschema.md), [`jr2 runs`](../reference/cli.md#runs),
267
+ - Reference: [`chartSchema`](../reference/authoring-surface/chartschema.md),
268
+ [`jr2 workflows`](../reference/cli.md#workflows),
268
269
  [`PUT /workflows/:wrapper/charts/:name`](../reference/http-api.md#put-workflows-wrapper-charts-name),
269
270
  [`GET /workflows/:wrapper/chart-schema`](../reference/http-api.md#get-workflows-wrapper-chart-schema)
270
271
  - [ADR-0070](../reference/decisions/0070-a-machine-lends-its-parts-to-a-chart.md): a Machine lends its parts to a Chart.