brass-runtime 1.15.0 → 1.16.1

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 (209) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +673 -136
  3. package/dist/agent/cli/main.cjs +40 -35
  4. package/dist/agent/cli/main.js +9 -4
  5. package/dist/agent/cli/main.mjs +9 -4
  6. package/dist/agent/index.cjs +8 -4
  7. package/dist/agent/index.d.ts +1 -1
  8. package/dist/agent/index.js +7 -3
  9. package/dist/agent/index.mjs +7 -3
  10. package/dist/chunk-2HQTDLHF.mjs +683 -0
  11. package/dist/chunk-36I3M4UC.mjs +370 -0
  12. package/dist/chunk-3AYM6WPJ.js +1629 -0
  13. package/dist/chunk-3LOYJFRR.cjs +300 -0
  14. package/dist/chunk-3RG5ZIWI.js +10 -0
  15. package/dist/chunk-3Y2RIUMM.js +300 -0
  16. package/dist/{chunk-VEZNF5GZ.cjs → chunk-4ROBZFL6.cjs} +130 -126
  17. package/dist/{chunk-3QMOKAS5.js → chunk-52OB2ROS.js} +9 -5
  18. package/dist/chunk-52PPNNI4.cjs +416 -0
  19. package/dist/chunk-5EC274J5.cjs +2874 -0
  20. package/dist/chunk-5QC7LRZ3.js +229 -0
  21. package/dist/chunk-5VRJNBLZ.mjs +2874 -0
  22. package/dist/chunk-62AZW6UT.cjs +313 -0
  23. package/dist/chunk-6IXXWIUM.js +683 -0
  24. package/dist/chunk-74ZTY6CP.js +2871 -0
  25. package/dist/chunk-76YMRMH2.cjs +777 -0
  26. package/dist/chunk-7CMJS3QE.mjs +2871 -0
  27. package/dist/{chunk-4NHES7VK.mjs → chunk-7JIJOVCT.js} +27 -13
  28. package/dist/chunk-A2OM6NEH.mjs +194 -0
  29. package/dist/chunk-AGR5B2BC.cjs +683 -0
  30. package/dist/chunk-AVNQLJ5V.js +777 -0
  31. package/dist/chunk-B33ICAKP.js +313 -0
  32. package/dist/{chunk-ELOOF35R.mjs → chunk-B5JD23U7.mjs} +1 -1
  33. package/dist/chunk-BABBZK4Y.js +2024 -0
  34. package/dist/chunk-C3MDXTRZ.js +354 -0
  35. package/dist/chunk-CIZFIMK5.js +2193 -0
  36. package/dist/chunk-CZIVE6NT.cjs +354 -0
  37. package/dist/chunk-DNFJLJMW.mjs +354 -0
  38. package/dist/chunk-DNFO2EIZ.mjs +777 -0
  39. package/dist/chunk-EJ6BPYVR.mjs +416 -0
  40. package/dist/chunk-ENKODRU3.cjs +2193 -0
  41. package/dist/chunk-EOC4UHBS.mjs +229 -0
  42. package/dist/{chunk-BMH5AV44.js → chunk-FH2X7BVP.js} +756 -440
  43. package/dist/{chunk-PPUXIH5R.js → chunk-FHQGHPMO.mjs} +27 -13
  44. package/dist/{chunk-TGIFUAK4.cjs → chunk-GLE2WY7Z.cjs} +951 -635
  45. package/dist/{chunk-BDF4AMWX.mjs → chunk-GYM3LLGS.mjs} +756 -440
  46. package/dist/chunk-HLWLMW2F.mjs +2024 -0
  47. package/dist/chunk-JF5WGYJJ.cjs +194 -0
  48. package/dist/chunk-KH4SYAOS.mjs +1629 -0
  49. package/dist/chunk-KN32XNTH.mjs +313 -0
  50. package/dist/chunk-KQLYONSE.cjs +2871 -0
  51. package/dist/{chunk-STVLQ3XD.cjs → chunk-KZJQ723N.cjs} +92 -78
  52. package/dist/chunk-L2SYFEBS.js +194 -0
  53. package/dist/chunk-L6VB5N7Q.cjs +104 -0
  54. package/dist/{chunk-K6M7MDZ4.mjs → chunk-MBEJI5HF.mjs} +9 -5
  55. package/dist/chunk-MIIYDLGM.js +2874 -0
  56. package/dist/chunk-MOO4L7F4.mjs +104 -0
  57. package/dist/chunk-MT3OWDPC.mjs +2193 -0
  58. package/dist/chunk-MVGUEJ5Z.cjs +370 -0
  59. package/dist/chunk-OBGZSXTJ.cjs +10 -0
  60. package/dist/chunk-PD4EJTQC.cjs +229 -0
  61. package/dist/chunk-PWC3RBQE.mjs +300 -0
  62. package/dist/chunk-Q2I37RP3.cjs +1629 -0
  63. package/dist/chunk-RKGKFN2A.js +416 -0
  64. package/dist/{chunk-R3R2FVLG.cjs → chunk-SA6HUJVI.cjs} +5 -5
  65. package/dist/chunk-TRM4JUZQ.js +104 -0
  66. package/dist/chunk-UB4B6OFY.js +370 -0
  67. package/dist/{chunk-TO7IKXYT.js → chunk-UCUBNWM2.js} +1 -1
  68. package/dist/chunk-VN44DYYT.cjs +2024 -0
  69. package/dist/chunk-Y6FXYEAI.mjs +10 -0
  70. package/dist/client-CZHU674n.d.ts +820 -0
  71. package/dist/core/index.cjs +198 -4
  72. package/dist/core/index.d.ts +311 -212
  73. package/dist/core/index.js +237 -43
  74. package/dist/core/index.mjs +237 -43
  75. package/dist/{effect-CMOQKX8y.d.ts → effect-DIUHZ9IN.d.ts} +195 -1
  76. package/dist/effectRunner-CFLC32IK.cjs +8 -0
  77. package/dist/effectRunner-L4S7IPT3.js +8 -0
  78. package/dist/effectRunner-NNGG75QA.mjs +8 -0
  79. package/dist/http/index.cjs +1227 -2971
  80. package/dist/http/index.d.ts +826 -280
  81. package/dist/http/index.js +1089 -2833
  82. package/dist/http/index.mjs +1089 -2833
  83. package/dist/http/testing.cjs +161 -0
  84. package/dist/http/testing.d.ts +43 -0
  85. package/dist/http/testing.js +161 -0
  86. package/dist/http/testing.mjs +161 -0
  87. package/dist/index.cjs +486 -250
  88. package/dist/index.d.ts +87 -95
  89. package/dist/index.js +391 -155
  90. package/dist/index.mjs +391 -155
  91. package/dist/observability/index.cjs +162 -0
  92. package/dist/observability/index.d.ts +152 -0
  93. package/dist/observability/index.js +162 -0
  94. package/dist/observability/index.mjs +162 -0
  95. package/dist/perf/cli.cjs +401 -0
  96. package/dist/perf/cli.d.ts +1 -0
  97. package/dist/perf/cli.js +401 -0
  98. package/dist/perf/cli.mjs +401 -0
  99. package/dist/perf/index.cjs +141 -0
  100. package/dist/perf/index.d.ts +483 -0
  101. package/dist/perf/index.js +141 -0
  102. package/dist/perf/index.mjs +141 -0
  103. package/dist/schedule-CK3Ml_7p.d.ts +259 -0
  104. package/dist/schema/index.cjs +29 -0
  105. package/dist/schema/index.d.ts +179 -0
  106. package/dist/schema/index.js +29 -0
  107. package/dist/schema/index.mjs +29 -0
  108. package/dist/server-GJPg8ZSG.d.ts +675 -0
  109. package/dist/{stream-FQm9h4Mg.d.ts → stream-B4oK9JFP.d.ts} +1 -1
  110. package/dist/tracer-Hwt1cl7h.d.ts +189 -0
  111. package/dist/tracing-DqbTKGcf.d.ts +148 -0
  112. package/docs/ARCHITECTURE.md +292 -0
  113. package/docs/README.md +63 -0
  114. package/docs/adr/0001-ai-context-pack.md +32 -0
  115. package/docs/agent-apply-mode.md +104 -0
  116. package/docs/agent-approvals.md +110 -0
  117. package/docs/agent-batch.md +185 -0
  118. package/docs/agent-boundaries.md +112 -0
  119. package/docs/agent-chat-sessions.md +160 -0
  120. package/docs/agent-ci.md +17 -0
  121. package/docs/agent-cli.md +405 -0
  122. package/docs/agent-config.md +480 -0
  123. package/docs/agent-context-discovery.md +159 -0
  124. package/docs/agent-copilot-like-dx.md +126 -0
  125. package/docs/agent-declarative-optimized-planning.md +138 -0
  126. package/docs/agent-dx.md +224 -0
  127. package/docs/agent-env-files.md +126 -0
  128. package/docs/agent-follow-up-context.md +43 -0
  129. package/docs/agent-global-usage.md +180 -0
  130. package/docs/agent-init.md +109 -0
  131. package/docs/agent-install-and-configure.md +516 -0
  132. package/docs/agent-language-workspace-ux.md +99 -0
  133. package/docs/agent-llm-adapters.md +123 -0
  134. package/docs/agent-local-install.md +190 -0
  135. package/docs/agent-local-tests.md +51 -0
  136. package/docs/agent-observability.md +155 -0
  137. package/docs/agent-patch-quality-loop.md +162 -0
  138. package/docs/agent-presets.md +22 -0
  139. package/docs/agent-project-commands.md +237 -0
  140. package/docs/agent-project-intelligence.md +156 -0
  141. package/docs/agent-redaction.md +18 -0
  142. package/docs/agent-release-readiness.md +76 -0
  143. package/docs/agent-rollback-safety.md +162 -0
  144. package/docs/agent-rollback.md +23 -0
  145. package/docs/agent-run-artifacts.md +16 -0
  146. package/docs/agent-vscode-auto-discovery.md +137 -0
  147. package/docs/agent-vscode-batch-runner.md +100 -0
  148. package/docs/agent-vscode-chat-layout.md +90 -0
  149. package/docs/agent-vscode-clean-install.md +147 -0
  150. package/docs/agent-vscode-code-actions.md +70 -0
  151. package/docs/agent-vscode-diff-preview.md +45 -0
  152. package/docs/agent-vscode-inline-assist.md +56 -0
  153. package/docs/agent-vscode-install.md +186 -0
  154. package/docs/agent-vscode-model-setup.md +97 -0
  155. package/docs/agent-vscode-patch-preview.md +92 -0
  156. package/docs/agent-vscode-problems.md +79 -0
  157. package/docs/agent-vscode-project-dashboard.md +106 -0
  158. package/docs/agent-vscode-run-history.md +92 -0
  159. package/docs/agent-vscode-ux.md +73 -0
  160. package/docs/ai/INVARIANTS.md +84 -0
  161. package/docs/ai/PROJECT_MAP.md +338 -0
  162. package/docs/ai/PUBLIC_API.md +336 -0
  163. package/docs/ai/VALIDATION_MATRIX.md +67 -0
  164. package/docs/api-polish.md +37 -0
  165. package/docs/cancellation.md +162 -0
  166. package/docs/coverage.md +46 -0
  167. package/docs/getting-started.md +159 -0
  168. package/docs/guides/README.md +40 -0
  169. package/docs/guides/circuit-breaker.md +89 -0
  170. package/docs/guides/error-handling.md +91 -0
  171. package/docs/guides/getting-started.md +107 -0
  172. package/docs/guides/layers.md +189 -0
  173. package/docs/guides/metrics.md +101 -0
  174. package/docs/guides/resource-management.md +141 -0
  175. package/docs/guides/retry.md +215 -0
  176. package/docs/guides/semaphore.md +66 -0
  177. package/docs/guides/streams.md +117 -0
  178. package/docs/guides/supervisors.md +98 -0
  179. package/docs/guides/testing.md +162 -0
  180. package/docs/guides/tracing.md +71 -0
  181. package/docs/http-recipes.md +399 -0
  182. package/docs/http.md +749 -0
  183. package/docs/modules.md +285 -0
  184. package/docs/observability-collector-smoke.md +31 -0
  185. package/docs/observability-framework-examples.md +98 -0
  186. package/docs/observability.md +542 -0
  187. package/docs/otel-collector-smoke.yaml +27 -0
  188. package/docs/performance-profiler.md +199 -0
  189. package/docs/production-readiness.md +73 -0
  190. package/docs/recipes/README.md +12 -0
  191. package/docs/recipes/http-server.md +45 -0
  192. package/docs/recipes/layers.md +44 -0
  193. package/docs/recipes/performance.md +47 -0
  194. package/docs/recipes/runtime.md +41 -0
  195. package/docs/recipes/testing.md +41 -0
  196. package/docs/release.md +53 -0
  197. package/docs/wasm-bounded-queues.md +44 -0
  198. package/docs/wasm-engine-observability-benchmarks.md +85 -0
  199. package/docs/wasm-fiber-engine.md +117 -0
  200. package/docs/wasm-scheduler-state-machine.md +122 -0
  201. package/docs/wasm-stream-chunks.md +54 -0
  202. package/package.json +48 -2
  203. package/dist/chunk-AR22SXML.js +0 -1043
  204. package/dist/chunk-BDYEENHT.js +0 -224
  205. package/dist/chunk-JFPU5GQI.mjs +0 -1043
  206. package/dist/chunk-MS34J5LY.cjs +0 -224
  207. package/dist/chunk-UMAZLXAB.mjs +0 -224
  208. package/dist/chunk-XPZNXSVN.cjs +0 -1043
  209. package/dist/tracing-DNT9jEbr.d.ts +0 -106
@@ -0,0 +1,32 @@
1
+ # ADR 0001: Maintain an AI Context Pack
2
+
3
+ Status: accepted
4
+
5
+ ## Context
6
+
7
+ `brass-runtime` contains a core effect runtime, streams, HTTP modules, WASM
8
+ engine pieces, benchmarks, and Brass Agent surfaces. The codebase is still small
9
+ enough to navigate manually, but large enough that a contributor or coding agent
10
+ needs a compact map before making safe changes.
11
+
12
+ ## Decision
13
+
14
+ Maintain a small context pack:
15
+
16
+ - `AGENTS.md` for root-level contributor/agent guidance.
17
+ - `docs/ai/PROJECT_MAP.md` for module navigation.
18
+ - `docs/ai/INVARIANTS.md` for semantic rules.
19
+ - `docs/ai/VALIDATION_MATRIX.md` for test selection.
20
+ - `docs/ai/PUBLIC_API.md` for exports and compatibility.
21
+ - `scripts/context-pack.mjs` for generated workspace summaries.
22
+
23
+ The generated context command prints to stdout and does not create tracked
24
+ artifacts by default.
25
+
26
+ ## Consequences
27
+
28
+ - Future changes should update the context pack when they move module
29
+ boundaries, change public API, or add validation expectations.
30
+ - Agents can gather focused context without rereading the entire repository.
31
+ - The context pack is documentation, not a replacement for tests.
32
+
@@ -0,0 +1,104 @@
1
+ # Agent apply mode
2
+
3
+ P3 adds a conservative write path for the experimental agent.
4
+
5
+ ## Goal
6
+
7
+ Keep the default CLI behavior safe:
8
+
9
+ - default mode remains `propose`
10
+ - `write` mode must be explicit
11
+ - patch application remains policy-gated and approval-gated
12
+ - patch targets must stay inside the workspace
13
+ - discovered validation commands still go through `PermissionService`
14
+
15
+ ## New pieces
16
+
17
+ `src/agent` now includes:
18
+
19
+ - `PatchService`
20
+ - `patch.apply` / `patch.applied`
21
+ - unified-diff extraction helpers
22
+ - a Node patch adapter built on `git apply`
23
+ - CLI flags for `--mode`, `--apply`, and approval strategy
24
+
25
+ ## Modes
26
+
27
+ ```bash
28
+ brass-agent "fix the failing tests" # propose (default)
29
+ brass-agent --apply "fix the failing tests" # write, prompts when interactive
30
+ brass-agent --apply --yes "fix the failing tests" # write, auto-approve
31
+ brass-agent --mode write "fix the failing tests"
32
+ ```
33
+
34
+ ## Safety rules
35
+
36
+ 1. The agent only applies unified diffs.
37
+ 2. All patch target paths are validated as workspace-relative before apply.
38
+ 3. `propose` mode may emit `patch.proposed`, but never `patch.apply`.
39
+ 4. `write` mode may apply patches only after approval.
40
+ 5. Shell commands remain whitelisted.
41
+ 6. After `patch.applied`, the agent re-runs the same discovered validation commands.
42
+
43
+ ## Patch adapter
44
+
45
+ The Node adapter uses `git apply --check` before the actual apply step.
46
+
47
+ That gives us a conservative path with a dry-run check first, while keeping the runtime invariant intact:
48
+ all external work is still represented as cancellable `Async`.
49
+
50
+ ## Offline smoke tests
51
+
52
+ You can drive the fake LLM with a deterministic response:
53
+
54
+ ~~~bash
55
+ export BRASS_LLM_PROVIDER=fake
56
+ export BRASS_FAKE_LLM_RESPONSE='Here is a patch.
57
+
58
+ ```diff
59
+ --- a/hello.txt
60
+ +++ b/hello.txt
61
+ @@ -1 +1 @@
62
+ -old
63
+ +new
64
+ ```'
65
+
66
+ brass-agent --apply --yes --cwd ./tmp/repro "apply the inferred patch"
67
+ ~~~
68
+
69
+ ## Patch quality loop
70
+
71
+ P13 adds an optional repair loop for normal generated patches in `write` mode.
72
+ After a generated patch is applied, the agent re-runs discovered validation
73
+ commands. If validation fails and repair budget remains, it calls `llm.patch` to
74
+ request an incremental repair diff, applies that diff, and validates again.
75
+
76
+ The default repair budget is one attempt:
77
+
78
+ ```json
79
+ {
80
+ "patchQuality": {
81
+ "enabled": true,
82
+ "maxRepairAttempts": 1
83
+ }
84
+ }
85
+ ```
86
+
87
+ Exact patch-file flows remain exact. `--apply-patch-file` does not trigger
88
+ repair attempts, because clients such as the VS Code extension use that path
89
+ after the user approved a specific previewed diff.
90
+
91
+ See [Agent patch quality loop](./agent-patch-quality-loop.md).
92
+
93
+
94
+ ## Automatic rollback safety
95
+
96
+ P14 adds automatic rollback safety for generated patches. If generated patches
97
+ still fail validation after the configured repair attempts are exhausted, the
98
+ agent can schedule `patch.rollback` actions to reverse the generated patch stack.
99
+
100
+ Rollback is still policy-gated and approval-gated. Exact patch-file flows remain
101
+ protected by default so a VS Code-approved patch is not silently reversed unless
102
+ the project opts in with `rollback.allowForSuppliedPatches`.
103
+
104
+ See [Agent automatic rollback safety](./agent-rollback-safety.md).
@@ -0,0 +1,110 @@
1
+ # Agent approvals
2
+
3
+ P6 adds interactive approvals to `brass-agent` without moving prompt logic into
4
+ `src/core`.
5
+
6
+ The boundary remains:
7
+
8
+ ```txt
9
+ src/core
10
+
11
+ src/agent PermissionService / ApprovalService
12
+
13
+ src/agent/cli prompt UX
14
+ ```
15
+
16
+ ## Decision flow
17
+
18
+ Every action still goes through the same policy pipeline:
19
+
20
+ ```txt
21
+ AgentAction
22
+ -> PermissionService.check(...)
23
+ -> allow | deny | ask
24
+ -> ApprovalService.request(...) when ask
25
+ -> ToolPolicy timeout/retry
26
+ -> Async tool effect
27
+ -> Observation
28
+ ```
29
+
30
+ `PermissionService` decides whether an action needs approval. `ApprovalService`
31
+ decides how to obtain that approval: prompt the human, auto-approve, auto-deny,
32
+ or integrate with another UI.
33
+
34
+ ## Built-in approvals
35
+
36
+ The agent exports:
37
+
38
+ ```ts
39
+ autoApproveApprovals
40
+ makeAutoDenyApprovals(reason?)
41
+ ```
42
+
43
+ The CLI also provides an interactive implementation that prompts on stderr.
44
+
45
+ ## CLI behavior
46
+
47
+ ```bash
48
+ brass-agent --apply "fix tests" # prompts when interactive
49
+ brass-agent --apply --yes "fix tests" # auto-approve
50
+ brass-agent --apply --no-input "fix tests" # auto-deny
51
+ brass-agent --approval interactive --apply "fix tests"
52
+ ```
53
+
54
+ Environment variables:
55
+
56
+ ```bash
57
+ BRASS_AGENT_APPROVAL=approve|deny|interactive|auto
58
+ BRASS_AGENT_AUTO_APPROVE=true
59
+ ```
60
+
61
+ `auto` is conservative:
62
+
63
+ ```txt
64
+ human TTY session -> interactive prompts
65
+ json/events-json or non-TTY -> deny approval-required actions
66
+ ```
67
+
68
+ Use `--yes` explicitly for non-interactive smoke tests or CI flows that are
69
+ allowed to mutate the workspace.
70
+
71
+ ## Events
72
+
73
+ Approvals emit typed events:
74
+
75
+ ```txt
76
+ agent.approval.requested
77
+ agent.approval.resolved
78
+ ```
79
+
80
+ These events are available in human output and `--events-json`. They are emitted
81
+ before and after the approval service runs.
82
+
83
+ ## Safety invariants
84
+
85
+ - Approval prompts are a capability of `src/agent`, not `src/core`.
86
+ - An action that requires approval must not run unless approval is granted.
87
+ - Missing approval service means approval-required actions are rejected.
88
+ - Observability is best-effort and must not change approval semantics.
89
+ - Non-interactive runs deny by default unless explicitly configured to approve.
90
+
91
+ ## Config defaults
92
+
93
+ P7 allows a project config file to set the default CLI approval strategy:
94
+
95
+ ```json
96
+ {
97
+ "approval": "auto"
98
+ }
99
+ ```
100
+
101
+ CLI flags still win over config:
102
+
103
+ ```bash
104
+ brass-agent --approval deny "inspect"
105
+ brass-agent --yes --apply "fix tests"
106
+ ```
107
+
108
+ `permissions.patchApply` can also tune whether `patch.apply` is allowed, denied,
109
+ or routed through approval in `write` and `autonomous` modes. See
110
+ [Agent config and policy files](./agent-config.md).
@@ -0,0 +1,185 @@
1
+ # Agent batch runs
2
+
3
+ P21 adds sequential batch execution to `brass-agent`.
4
+
5
+ The goal is to make common DX/CI workflows composable without introducing a new
6
+ scheduler or breaking the existing boundary:
7
+
8
+ ```txt
9
+ src/core
10
+
11
+ src/agent runAgent(...)
12
+
13
+ brass-agent CLI batch runner
14
+ ```
15
+
16
+ A batch run is just multiple normal agent runs executed one after another. Each
17
+ run still goes through the same pipeline:
18
+
19
+ ```txt
20
+ AgentAction
21
+ -> PermissionService
22
+ -> ApprovalService when ask
23
+ -> ToolPolicy timeout/retry
24
+ -> Async tool effect
25
+ -> Observation
26
+ ```
27
+
28
+ Batch mode does not bypass policy, approvals, redaction, rollback safety, CI exit
29
+ codes, or artifact export.
30
+
31
+ ## CLI
32
+
33
+ Run a batch from a file:
34
+
35
+ ```bash
36
+ brass-agent --batch-file ./brass-agent.batch.json
37
+ ```
38
+
39
+ In CI:
40
+
41
+ ```bash
42
+ brass-agent --batch-file ./brass-agent.batch.json --ci --batch-stop-on-failure
43
+ ```
44
+
45
+ `--batch-stop-on-failure` stops after the first run whose CI status is non-zero.
46
+ `--batch-continue-on-failure` forces the opposite.
47
+
48
+ When neither flag is provided, the default is:
49
+
50
+ ```txt
51
+ --ci -> stop on failure
52
+ not --ci -> continue
53
+ ```
54
+
55
+ ## Batch file formats
56
+
57
+ ### JSON array
58
+
59
+ ```json
60
+ [
61
+ "inspect this workspace",
62
+ { "preset": "typecheck" },
63
+ { "preset": "lint" },
64
+ { "preset": "fix-tests", "mode": "propose" }
65
+ ]
66
+ ```
67
+
68
+ ### JSON object
69
+
70
+ ```json
71
+ {
72
+ "goals": [
73
+ { "preset": "inspect" },
74
+ { "goal": "explain the failing tests", "mode": "read-only" },
75
+ { "goal": "fix the failing tests", "mode": "propose" }
76
+ ]
77
+ }
78
+ ```
79
+
80
+ ### Plain text
81
+
82
+ If the file is not valid JSON, `brass-agent` treats it as a line-based goal file.
83
+ Blank lines and `#` comments are ignored.
84
+
85
+ ```txt
86
+ # brass-agent.batch.txt
87
+ inspect this workspace
88
+ run typecheck discovery and explain failures
89
+ fix the failing tests
90
+ ```
91
+
92
+ ## Per-goal fields
93
+
94
+ JSON batch items support:
95
+
96
+ ```ts
97
+ {
98
+ goal?: string;
99
+ preset?: "fix-tests" | "inspect" | "typecheck" | "lint";
100
+ mode?: "read-only" | "propose" | "write" | "autonomous";
101
+ cwd?: string;
102
+ patchFile?: string;
103
+ patchFileMode?: "apply" | "rollback";
104
+ saveRunDir?: string;
105
+ }
106
+ ```
107
+
108
+ `preset` fills in a standard goal. `goal` wins when both are present.
109
+
110
+ `cwd` lets one batch file target multiple workspaces, but the same loaded config
111
+ and CLI environment are reused for the full batch. Use separate invocations when
112
+ different workspaces need different config files.
113
+
114
+ ## Config default batch
115
+
116
+ A project can define a default batch:
117
+
118
+ ```json
119
+ {
120
+ "batch": {
121
+ "stopOnFailure": true,
122
+ "goals": [
123
+ { "preset": "inspect" },
124
+ { "preset": "typecheck" },
125
+ { "preset": "lint" }
126
+ ]
127
+ }
128
+ }
129
+ ```
130
+
131
+ Then run:
132
+
133
+ ```bash
134
+ brass-agent --ci
135
+ ```
136
+
137
+ The config batch is used only when the CLI does not receive an explicit goal,
138
+ `--preset`, `--patch-file`, or `--batch-file`.
139
+
140
+ ## Outputs
141
+
142
+ Human output prints each normal run and then a final batch summary:
143
+
144
+ ```txt
145
+ batch summary:
146
+ completed: 3/3
147
+ failed: 0
148
+ exit code: 0
149
+ ```
150
+
151
+ `--json` prints a batch object:
152
+
153
+ ```json
154
+ {
155
+ "type": "batch",
156
+ "summary": {
157
+ "total": 3,
158
+ "completed": 3,
159
+ "failed": 0,
160
+ "exitCode": 0,
161
+ "stoppedEarly": false
162
+ },
163
+ "results": []
164
+ }
165
+ ```
166
+
167
+ `--protocol-json` emits normal event messages and a `final-state` message per
168
+ run, followed by a `batch-summary` message.
169
+
170
+ ## Exit codes
171
+
172
+ In `--ci` mode, batch exit code is aggregated from individual runs:
173
+
174
+ ```txt
175
+ 1 if any run failed or latest validation failed
176
+ 2 if no run failed but at least one run proposed an unapplied patch with --fail-on-patch-proposed
177
+ 0 otherwise
178
+ ```
179
+
180
+ ## VS Code
181
+
182
+ P22 adds a VS Code command, `Brass Agent: Run Batch File`, which invokes the CLI
183
+ with `--protocol-json --batch-file`. The extension stores the batch as a parent
184
+ history entry and each CLI `final-state` message as a child run. See
185
+ [VS Code batch runner](./agent-vscode-batch-runner.md).
@@ -0,0 +1,112 @@
1
+ # Agent Module Boundaries
2
+
3
+ These rules keep the experimental agent layer useful without letting it leak into the runtime core.
4
+
5
+ ## Dependency direction
6
+
7
+ ```txt
8
+ core runtime
9
+
10
+ agent module
11
+
12
+ cli / UX
13
+ ```
14
+
15
+ Rules:
16
+
17
+ 1. `src/core` must not know that `src/agent` exists.
18
+ 2. `src/agent` may depend on `src/core` runtime primitives.
19
+ 3. Agent-specific shortcuts must not be added to `Runtime`, `Fiber`, `Scope`, or the scheduler.
20
+ 4. If the agent reveals a missing semantic in the core, fix the core as a runtime invariant first.
21
+ 5. Keep the agent as an experimental consumer of the runtime until the shape is stable.
22
+
23
+ ## Agent execution model
24
+
25
+ The agent does not perform side effects directly.
26
+
27
+ It must follow this pipeline:
28
+
29
+ ```txt
30
+ Goal
31
+ -> decideNextAction
32
+ -> PermissionService
33
+ -> ApprovalService when permission decision is ask
34
+ -> ToolPolicy
35
+ -> AgentAction interpreted as Async
36
+ -> Observation
37
+ -> reducer
38
+ -> next AgentState
39
+ ```
40
+
41
+ Rules:
42
+
43
+ 1. The planner produces `AgentAction` values.
44
+ 2. Every `AgentAction` is interpreted into `Async<AgentEnv, AgentError, Observation>`.
45
+ 3. All external work goes through capabilities in `AgentEnv`.
46
+ 4. All tool execution goes through permissions first.
47
+ 5. Approval-required actions must be approved before tool execution.
48
+ 6. All tool execution goes through timeout/retry policy.
49
+ 7. No detached background work by default.
50
+ 8. Every async tool that touches external work must be cancellable.
51
+ 9. Any patch-application path must validate that every target path stays inside the workspace.
52
+
53
+
54
+ ## Configuration boundary
55
+
56
+ Project policy may be loaded from `.brass-agent.json`, but config is still an
57
+ agent-layer concern:
58
+
59
+ ```txt
60
+ src/core
61
+
62
+ src/agent policy/config
63
+
64
+ src/agent/cli Node config loader
65
+ ```
66
+
67
+ Rules:
68
+
69
+ 1. Config loading must not move into `src/core`.
70
+ 2. Config is resolved before constructing `AgentEnv`.
71
+ 3. Config may tune permissions, approvals, LLM provider/model, and tool policies.
72
+ 4. Config must not store secrets; adapters should read API keys from environment variables.
73
+ 5. Config must not bypass the `AgentAction -> PermissionService -> ApprovalService -> ToolPolicy -> Async -> Observation` pipeline.
74
+
75
+ ## Runtime invariants the agent relies on
76
+
77
+ The agent assumes these runtime semantics:
78
+
79
+ 1. `Scope.close()` interrupts child fibers.
80
+ 2. `Scope.closeAsync(...)` can be awaited.
81
+ 3. Closing a parent scope propagates to subscopes.
82
+ 4. Interrupted fibers run their finalizers exactly once.
83
+ 5. `Async` work that registers external IO returns a canceler.
84
+ 6. Race-like operators close their internal scopes and cancel losing branches.
85
+ 7. If a tool cannot be cancelled, it is a bug in the tool adapter.
86
+
87
+ ## Safety defaults
88
+
89
+ Initial agent modes should be conservative:
90
+
91
+ 1. `read-only`: read/search/model only.
92
+ 2. `propose`: read/search/model plus whitelisted read-only commands and patch proposals.
93
+ 3. `write`: may apply patches only after approval.
94
+ 4. `autonomous`: reserved for later; sensitive actions still require approval.
95
+
96
+ The initial CLI should default to `propose`.
97
+
98
+ ## Extraction rule
99
+
100
+ Keep the agent in `src/agent` while validating the vertical slice.
101
+ Extract to packages only after the design stabilizes:
102
+
103
+ ```txt
104
+ packages/
105
+ brass-runtime/
106
+ brass-agent/
107
+ brass-node/
108
+ brass-llm/
109
+ brass-cli/
110
+ ```
111
+
112
+ Until then, `src/agent` is allowed to be experimental, but `src/core` is not.
@@ -0,0 +1,160 @@
1
+ # Brass Agent chat sessions
2
+
3
+ P30 turns the VS Code Chat view from a one-shot launcher into a lightweight
4
+ conversation surface.
5
+
6
+ The CLI remains the canonical execution boundary. The VS Code extension still
7
+ calls:
8
+
9
+ ```bash
10
+ brass-agent --protocol-json --protocol-full-patches --cwd <workspace> <goal>
11
+ ```
12
+
13
+ The new session behavior lives entirely in the extension.
14
+
15
+ ## What is stored
16
+
17
+ The VS Code extension stores a compact chat session in `workspaceState`:
18
+
19
+ ```txt
20
+ messages
21
+ last run summary
22
+ last validation output
23
+ last patch stats
24
+ last patch body, only when brassAgent.storePatchesInHistory is true
25
+ ```
26
+
27
+ This is editor-local state. It is not written to the repository and it is not
28
+ owned by `src/core` or `src/agent`.
29
+
30
+ The message history length is controlled by:
31
+
32
+ ```json
33
+ {
34
+ "brassAgent.chatHistoryLimit": 80
35
+ }
36
+ ```
37
+
38
+ Disable patch persistence with:
39
+
40
+ ```json
41
+ {
42
+ "brassAgent.storePatchesInHistory": false
43
+ }
44
+ ```
45
+
46
+ ## Follow-up context
47
+
48
+ After a run, follow-up messages can use the previous run as context.
49
+
50
+ For example:
51
+
52
+ ```txt
53
+ fix the failing tests
54
+ why did that fail?
55
+ try again but do not change the public API
56
+ explain the patch
57
+ ```
58
+
59
+ The extension composes the next agent goal with a compact context block that may
60
+ include:
61
+
62
+ ```txt
63
+ previous goal
64
+ previous status
65
+ previous summary/error
66
+ latest validation command output
67
+ last patch stats
68
+ last patch diff, only for explicit explain-last style requests
69
+ ```
70
+
71
+ The agent is instructed to ignore previous context if the new request is
72
+ unrelated.
73
+
74
+ ## Slash commands
75
+
76
+ The chat supports slash commands to avoid menus and flags:
77
+
78
+ ```txt
79
+ /inspect
80
+ /fix-tests
81
+ /typecheck
82
+ /lint
83
+ /ask <question>
84
+ /propose <task>
85
+ /apply <task>
86
+ /explain-last
87
+ /apply-last
88
+ /rollback-last
89
+ /doctor
90
+ /output
91
+ /clear
92
+ /help
93
+ ```
94
+
95
+ ### Safety behavior
96
+
97
+ `/apply <task>` still uses the safe apply-preview flow:
98
+
99
+ ```txt
100
+ chat request
101
+ -> propose run
102
+ -> patch preview
103
+ -> user approval
104
+ -> brass-agent --apply-patch-file <exact diff>
105
+ ```
106
+
107
+ `/apply-last` reopens the last patch preview. It does not silently write.
108
+
109
+ `/rollback-last` calls the CLI rollback path:
110
+
111
+ ```bash
112
+ brass-agent --rollback-patch-file <temp.diff> --yes ...
113
+ ```
114
+
115
+ It asks for VS Code confirmation first, and the CLI still goes through the normal
116
+ patch rollback service.
117
+
118
+ ## Quick actions
119
+
120
+ Assistant messages can include buttons such as:
121
+
122
+ ```txt
123
+ Open patch preview
124
+ Explain last
125
+ Rollback last
126
+ Show output
127
+ ```
128
+
129
+ These buttons send slash commands back through the same chat handler.
130
+
131
+ ## Boundary
132
+
133
+ The boundary remains unchanged:
134
+
135
+ ```txt
136
+ src/core
137
+
138
+ src/agent
139
+
140
+ brass-agent CLI protocol
141
+
142
+ VS Code chat session UI
143
+ ```
144
+
145
+ The extension owns conversation memory and UX. The agent owns execution,
146
+ permissions, validation, redaction, patch application, rollback, and protocol
147
+ semantics.
148
+
149
+ ## Explain last behavior
150
+
151
+ `/explain-last` is intentionally local and deterministic. It summarizes the last
152
+ stored run from VS Code workspace state instead of launching a new agent run.
153
+
154
+ That keeps the button useful even when the previous run stopped before the LLM
155
+ step, for example because a context file disappeared or a tool returned `FsError`.
156
+ For an AI follow-up using the same context, use:
157
+
158
+ ```txt
159
+ /ask why did that fail?
160
+ ```