@juzser/blacksmith 0.4.0 → 0.5.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.
- package/.claude/agents/{auditor.md → bs-auditor.md} +5 -5
- package/.claude/agents/{coder.md → bs-coder.md} +8 -7
- package/.claude/agents/{grader.md → bs-grader.md} +4 -4
- package/.claude/agents/{merger.md → bs-merger.md} +4 -4
- package/.claude/agents/{planner.md → bs-planner.md} +20 -6
- package/.claude/agents/{researcher.md → bs-researcher.md} +6 -5
- package/.claude/agents/{reviewer.md → bs-reviewer.md} +13 -5
- package/.claude/agents/{scribe.md → bs-scribe.md} +11 -2
- package/.claude/agents/{security-reviewer.md → bs-security-reviewer.md} +6 -6
- package/.claude/agents/{spec-reviewer.md → bs-spec-reviewer.md} +15 -10
- package/.claude/agents/{tester.md → bs-tester.md} +40 -12
- package/.claude/agents/bs-uiux.md +257 -0
- package/.claude/agents/{verifier.md → bs-verifier.md} +4 -4
- package/.claude/agents/{wave-runner.md → bs-wave-runner.md} +14 -5
- package/.claude/skills/bs/SKILL.md +99 -21
- package/.claude/skills/bs/audit.md +34 -27
- package/.claude/skills/bs/dispatch.md +100 -50
- package/.claude/skills/bs/lessons.md +28 -14
- package/.claude/skills/bs/mcp.md +4 -4
- package/.claude/skills/bs/new.md +3 -3
- package/.claude/skills/bs/plan.md +27 -18
- package/.claude/skills/bs/report.md +11 -11
- package/.claude/skills/bs/run.md +181 -49
- package/.claude/skills/bs/status.md +14 -7
- package/.claude/skills/bs/ui.md +21 -5
- package/.claude/skills/bs/waivers.md +78 -2
- package/.claude/skills/bs/wave.md +109 -53
- package/README.md +53 -32
- package/factory/orchestrator/dist/agentNames.js +43 -0
- package/factory/orchestrator/dist/agents-registry.js +11 -4
- package/factory/orchestrator/dist/agentsSync.js +48 -14
- package/factory/orchestrator/dist/artifacts.js +31 -0
- package/factory/orchestrator/dist/attribution.js +4 -0
- package/factory/orchestrator/dist/audit.js +125 -17
- package/factory/orchestrator/dist/budgetAlarm.js +132 -37
- package/factory/orchestrator/dist/budgets.js +302 -84
- package/factory/orchestrator/dist/claims.js +9 -19
- package/factory/orchestrator/dist/cli.js +790 -100
- package/factory/orchestrator/dist/cliName.js +27 -0
- package/factory/orchestrator/dist/crosscheck.js +136 -8
- package/factory/orchestrator/dist/daemon.js +154 -36
- package/factory/orchestrator/dist/db/projector.js +278 -29
- package/factory/orchestrator/dist/db/queries.js +1831 -94
- package/factory/orchestrator/dist/db/schema.js +57 -4
- package/factory/orchestrator/dist/declaredArtifactLine.js +18 -0
- package/factory/orchestrator/dist/delegation.js +86 -19
- package/factory/orchestrator/dist/diffstat.js +15 -8
- package/factory/orchestrator/dist/dispatchLint.js +13 -37
- package/factory/orchestrator/dist/effort.js +14 -2
- package/factory/orchestrator/dist/effortTiers.js +13 -0
- package/factory/orchestrator/dist/env.js +26 -0
- package/factory/orchestrator/dist/epic.js +323 -38
- package/factory/orchestrator/dist/epicBudget.js +93 -0
- package/factory/orchestrator/dist/epicWidth.js +22 -5
- package/factory/orchestrator/dist/errorIssues.js +10 -4
- package/factory/orchestrator/dist/escalation.js +2 -2
- package/factory/orchestrator/dist/events.js +105 -3
- package/factory/orchestrator/dist/feedback.js +169 -0
- package/factory/orchestrator/dist/findingContext.js +26 -0
- package/factory/orchestrator/dist/findings.js +83 -12
- package/factory/orchestrator/dist/gate.js +120 -10
- package/factory/orchestrator/dist/goalCheck.js +2 -2
- package/factory/orchestrator/dist/harness.js +25 -17
- package/factory/orchestrator/dist/hookDecision.js +92 -3
- package/factory/orchestrator/dist/integration.js +9 -7
- package/factory/orchestrator/dist/judgePreflight.js +25 -4
- package/factory/orchestrator/dist/judgeRoles.js +47 -0
- package/factory/orchestrator/dist/judgeStopHook.js +90 -32
- package/factory/orchestrator/dist/judges.js +419 -21
- package/factory/orchestrator/dist/lessons.js +190 -11
- package/factory/orchestrator/dist/mcp.js +6 -6
- package/factory/orchestrator/dist/paths.js +10 -7
- package/factory/orchestrator/dist/plan.js +269 -33
- package/factory/orchestrator/dist/planQuorum.js +5 -2
- package/factory/orchestrator/dist/policy.js +1275 -30
- package/factory/orchestrator/dist/projectName.js +25 -0
- package/factory/orchestrator/dist/promptCapture.js +306 -0
- package/factory/orchestrator/dist/promptHook.js +33 -0
- package/factory/orchestrator/dist/promptImport.js +281 -0
- package/factory/orchestrator/dist/prompts.js +13 -0
- package/factory/orchestrator/dist/providers/schema-validate.js +2 -2
- package/factory/orchestrator/dist/providers/types.js +1 -1
- package/factory/orchestrator/dist/queue.js +4 -4
- package/factory/orchestrator/dist/quorum.js +18 -5
- package/factory/orchestrator/dist/results.js +25 -7
- package/factory/orchestrator/dist/roadmap.js +10 -5
- package/factory/orchestrator/dist/run-cli.js +15 -10
- package/factory/orchestrator/dist/runner.js +2 -2
- package/factory/orchestrator/dist/schemas.js +56 -8
- package/factory/orchestrator/dist/severity.js +8 -4
- package/factory/orchestrator/dist/spec.js +177 -13
- package/factory/orchestrator/dist/specChange.js +13 -9
- package/factory/orchestrator/dist/stack.js +6 -6
- package/factory/orchestrator/dist/storeRoot.js +90 -0
- package/factory/orchestrator/dist/symbols.js +261 -6
- package/factory/orchestrator/dist/taskEvents.js +179 -27
- package/factory/orchestrator/dist/taskStatus.js +14 -0
- package/factory/orchestrator/dist/testerAudit.js +31 -12
- package/factory/orchestrator/dist/testgate.js +16 -13
- package/factory/orchestrator/dist/uiuxGate.js +83 -0
- package/factory/orchestrator/dist/usage.js +97 -40
- package/factory/orchestrator/dist/waivers.js +39 -5
- package/factory/orchestrator/dist/waveBudget.js +2 -0
- package/factory/orchestrator/dist/waveConcurrency.js +143 -7
- package/factory/orchestrator/dist/workroot.js +1 -1
- package/factory/orchestrator/dist/worktree.js +61 -19
- package/factory/orchestrator/drizzle/0013_operator_feedback.sql +19 -0
- package/factory/orchestrator/drizzle/0014_misty_madripoor.sql +2 -0
- package/factory/orchestrator/drizzle/0015_gifted_omega_flight.sql +1 -0
- package/factory/orchestrator/drizzle/0016_milestones_project_default.sql +30 -0
- package/factory/orchestrator/drizzle/0017_events_raw_cli_session_id.sql +2 -0
- package/factory/orchestrator/drizzle/meta/_journal.json +35 -0
- package/factory/policies/budgets.yml +123 -33
- package/factory/policies/crosscheck.yml +51 -13
- package/factory/policies/delegation.yml +3 -3
- package/factory/policies/effort.yml +18 -10
- package/factory/policies/guardrails.yml +8 -6
- package/factory/policies/harness.yml +5 -5
- package/factory/policies/lessons.md +53 -2
- package/factory/policies/scheduler.yml +4 -4
- package/factory/policies/sensitive-paths.yml +1 -1
- package/factory/policies/severity.yml +13 -1
- package/factory/policies/stack.yml +6 -6
- package/factory/policies/taxonomy.yml +9 -3
- package/factory/policies/worktree.yml +15 -9
- package/factory/specs/roadmap.md +7 -7
- package/factory/specs/schema/event.schema.json +8 -1
- package/factory/specs/schema/result.schema.json +21 -8
- package/factory/specs/schema/task-spec.schema.json +12 -0
- package/package.json +16 -12
- package/.claude/agents/uiux.md +0 -133
|
@@ -6,23 +6,24 @@
|
|
|
6
6
|
# What is mechanical, and what is a request (P9-18, 2026-08-08; `failed_rounds`
|
|
7
7
|
# added P9-32 and `alarm_ratio` P9-33, both 2026-08-10; `max_in_flight_tasks`
|
|
8
8
|
# added 2026-08-26, the same day `epic.cap_tokens` grew a reader that actually
|
|
9
|
-
# blocks). Exactly six
|
|
9
|
+
# blocks). Exactly six kinds of number here reach a runtime host — each one
|
|
10
|
+
# sized per effort tier, see "Effort tiers" below:
|
|
10
11
|
#
|
|
11
12
|
# * `epic.cap_tokens` — three readers now, and only the newest of them
|
|
12
13
|
# blocks. planQuorum's budget trigger sums *declared* task budgets against
|
|
13
14
|
# it before any dispatch and only ever surfaces the finding for a human to
|
|
14
|
-
# act on; `
|
|
15
|
-
# event log, after wave merge, and also stops nothing itself. `
|
|
15
|
+
# act on; `bs budget alarm` compares it against spend counted from the
|
|
16
|
+
# event log, after wave merge, and also stops nothing itself. `bs wave
|
|
16
17
|
# check` (src/waveBudget.ts) is the reader that blocks: at wave admission —
|
|
17
18
|
# before any task in the wave has been dispatched — it sums the wave's
|
|
18
19
|
# declared task budgets against headroom under the cap (measured spend plus
|
|
19
20
|
# a declared price for every dispatch nothing has measured yet, the same
|
|
20
|
-
# projection `
|
|
21
|
+
# projection `bs budget alarm` computes) and refuses to admit a wave
|
|
21
22
|
# that would cross it. It is not a stricter version of the other two
|
|
22
23
|
# readers' advice; it is the only one of the three standing upstream of the
|
|
23
24
|
# spend it is judging, so it is the only one that can refuse the spend
|
|
24
25
|
# instead of merely describing it afterward.
|
|
25
|
-
# * `epic.alarm_ratio` — `
|
|
26
|
+
# * `epic.alarm_ratio` — `bs budget alarm` (src/budgetAlarm.ts), which
|
|
26
27
|
# reports each epic's measured and projected spend against
|
|
27
28
|
# `alarm_ratio * cap_tokens` and exits 1 on a crossing. Measured spend is a
|
|
28
29
|
# floor, not a total: a judge returns findings rather than a Result, so its
|
|
@@ -32,14 +33,17 @@
|
|
|
32
33
|
# `task:` block's coverage of the roles the factory actually dispatches is
|
|
33
34
|
# load-bearing and not merely documentary.
|
|
34
35
|
# * a task's `tokens` — compared at the gate against the result's
|
|
35
|
-
# `token_usage.total_tokens`.
|
|
36
|
+
# `token_usage.total_tokens`. The per-role caps under `task:` are what
|
|
37
|
+
# `bs budget alarm` and `bs wave check` charge a dispatch nothing has
|
|
38
|
+
# measured yet, and what the dispatch harness hands a CLI turn as its
|
|
39
|
+
# `cap_tokens`.
|
|
36
40
|
# * a task's `diff_lines` — compared at the gate against a real
|
|
37
41
|
# `git diff --numstat` (src/diffstat.ts), lockfiles and generated output
|
|
38
42
|
# excluded.
|
|
39
43
|
# * `escalation_ladder.rungs[].failed_rounds` — counted from `gate-outcome`
|
|
40
|
-
# events by `
|
|
44
|
+
# events by `bs escalation check` (src/escalation.ts), which asserts the
|
|
41
45
|
# rung's `enforce` obligation against what the log shows happened next.
|
|
42
|
-
# * `epic.max_in_flight_tasks` — `
|
|
46
|
+
# * `epic.max_in_flight_tasks` — `bs wave check`, which refuses to admit a
|
|
43
47
|
# wave that would put more of the epic's tasks in flight at once (admitted,
|
|
44
48
|
# not yet merged) than this. Null by default; see the field's own comment
|
|
45
49
|
# below for why it is not the mechanism that bounds cost.
|
|
@@ -51,7 +55,7 @@
|
|
|
51
55
|
# measuring (D-29: a coder spent its tail shaving lines to land exactly on
|
|
52
56
|
# `diff_lines`, stopping mid-procedure to do it).
|
|
53
57
|
#
|
|
54
|
-
# The epic cap no longer works that way: `
|
|
58
|
+
# The epic cap no longer works that way: `bs wave check` blocks on one.
|
|
55
59
|
# The difference is not that an epic overrun matters more than a task overrun
|
|
56
60
|
# — it is *when* each is checked. The task gate polices work already
|
|
57
61
|
# underway, so refusing there distorts the work it is judging. Wave admission
|
|
@@ -68,13 +72,48 @@
|
|
|
68
72
|
# agent-interviews.md M-4 had called it inert), and a plan cannot raise or
|
|
69
73
|
# lower a role's ceiling. So plan validation rejects it as a task budget
|
|
70
74
|
# field, and the dispatch prompt restates the template's number verbatim.
|
|
75
|
+
# It is one number per template, not per tier: a template cannot know the
|
|
76
|
+
# epic it will be dispatched into, so each `maxTurns` is sized as the ceiling
|
|
77
|
+
# for the huge tier (raised 2026-09-29, measured on eight medium-tier dogfood
|
|
78
|
+
# epics, 2026-09-14..29). The token caps below are what scale down for a
|
|
79
|
+
# smaller epic; the turn ceiling does not.
|
|
80
|
+
#
|
|
81
|
+
# Effort tiers (2026-09-29). Every token and diff number in this file is sized
|
|
82
|
+
# per effort tier — effort.yml's small / medium / huge: the tier the epic
|
|
83
|
+
# runs at, i.e. its plan's `effort` raised by effort.yml's `security_floor`
|
|
84
|
+
# when a live task trips a security trigger, and effort.yml's `default_tier`
|
|
85
|
+
# (medium) when there is no plan in hand or it names none. One source of
|
|
86
|
+
# truth, one scale:
|
|
87
|
+
#
|
|
88
|
+
# * `epic.cap_tokens` is an explicit triplet, because an epic's size is not
|
|
89
|
+
# a straight multiple of its tasks'.
|
|
90
|
+
# * every `task:` number is declared once, at medium, and multiplied by
|
|
91
|
+
# `task_tier_scale` for the tier: small 0.5x, huge 2x.
|
|
92
|
+
# * `epic.alarm_ratio` is a ratio and is the same at every tier.
|
|
93
|
+
#
|
|
94
|
+
# Per-box env overrides (`.env`, or an exported value, which beats it). Each
|
|
95
|
+
# number that a box may want to move has an env name — BS_EPIC_CAP_TOKENS,
|
|
96
|
+
# BS_TASK_<ROLE>_CAP_TOKENS, … listed in .env.example (the deprecated
|
|
97
|
+
# SMITH_* spellings still work as a fallback) — and each name has a
|
|
98
|
+
# `_SMALL`, `_MEDIUM` and `_HUGE` variant. For an epic of a given tier the
|
|
99
|
+
# precedence is, highest first:
|
|
100
|
+
#
|
|
101
|
+
# 1. the variant for that tier, e.g. BS_EPIC_CAP_TOKENS_HUGE;
|
|
102
|
+
# 2. the bare name, e.g. BS_EPIC_CAP_TOKENS, which applies to every tier
|
|
103
|
+
# that has no variant of its own set;
|
|
104
|
+
# 3. the number in this file for that tier.
|
|
105
|
+
#
|
|
106
|
+
# An env value beats the tier: a bare name pins one number for every tier. A
|
|
107
|
+
# malformed value in any variant — even one for a tier not in play — is
|
|
108
|
+
# refused with `budgets.invalid-env`. `bs wave check` and `bs budget
|
|
109
|
+
# alarm` name the variables that moved a number, never their values.
|
|
71
110
|
#
|
|
72
111
|
# No concurrency cap on cost grounds, by design (removed 2026-08-05). Workers
|
|
73
112
|
# run in isolated worktrees on disjoint path claims, so parallelism is bounded
|
|
74
113
|
# by the claim graph, not by a worker count — and fan-out buys wall-clock
|
|
75
114
|
# without buying extra tokens (architecture §15.3). Hundreds of concurrent
|
|
76
115
|
# subagents is a supported shape. That reasoning holds only as long as the
|
|
77
|
-
# token cap it leans on actually binds, which — before `
|
|
116
|
+
# token cap it leans on actually binds, which — before `bs wave check` —
|
|
78
117
|
# `epic.cap_tokens` did not. `epic.max_in_flight_tasks` below is not that
|
|
79
118
|
# removed cap come back: it defaults to null, and cost stays bounded by
|
|
80
119
|
# `cap_tokens`, not by a worker count. It exists for an operator who wants a
|
|
@@ -83,7 +122,22 @@
|
|
|
83
122
|
# nothing about what bounds spend.
|
|
84
123
|
|
|
85
124
|
epic:
|
|
86
|
-
cap_tokens:
|
|
125
|
+
cap_tokens: # planner + all workers + judges, one epic.
|
|
126
|
+
small: 4000000
|
|
127
|
+
medium: 16000000
|
|
128
|
+
huge: 32000000
|
|
129
|
+
# 2026-09-29: per tier. Medium is 16M, the cap
|
|
130
|
+
# the operator's own box had already been
|
|
131
|
+
# running by env override; the largest measured
|
|
132
|
+
# medium epic (eight medium-tier dogfood epics,
|
|
133
|
+
# 2026-09-14..29) spent about 7.3M, so 16M
|
|
134
|
+
# carries it with the alarm at 11.2M. Small
|
|
135
|
+
# keeps the old single number, 4M; huge is 32M.
|
|
136
|
+
# This is also the per-epic override follow-up
|
|
137
|
+
# (1) below asked for, in the only form a
|
|
138
|
+
# policy file can give it: an epic's `effort`
|
|
139
|
+
# picks its cap.
|
|
140
|
+
# Earlier history:
|
|
87
141
|
# Raised from 2,000,000 by operator decision on
|
|
88
142
|
# 2026-08-11 (dogfood-mcp-1), which is the
|
|
89
143
|
# operator answer the `alarm_ratio` note below
|
|
@@ -99,31 +153,32 @@ epic:
|
|
|
99
153
|
# so a number raised for one epic is raised for
|
|
100
154
|
# every epic black-smith will ever run. What
|
|
101
155
|
# exists is a per-BOX override, a different
|
|
102
|
-
# thing:
|
|
156
|
+
# thing: BS_EPIC_CAP_TOKENS in the env (or
|
|
103
157
|
# `.env`) replaces this number for every epic
|
|
104
158
|
# run on that box while it is set — the
|
|
105
|
-
#
|
|
159
|
+
# BS_EPIC_* / BS_TASK_* names in
|
|
106
160
|
# .env.example cover each number in this file
|
|
107
161
|
# that a box may want to move; (2) a
|
|
108
162
|
# large share of that 1.5M was rework — stopped
|
|
109
|
-
# dispatches and re-dispatches that `
|
|
163
|
+
# dispatches and re-dispatches that `bs
|
|
110
164
|
# escalation check` recorded as ladder
|
|
111
165
|
# violations — so this cap now accommodates
|
|
112
166
|
# waste as well as work. A cap sized from a
|
|
113
167
|
# badly-run epic is a ceiling measured at the
|
|
114
168
|
# wrong place.
|
|
115
|
-
alarm_ratio: 0.7 # at 2.8M
|
|
169
|
+
alarm_ratio: 0.7 # same at every tier (small: 2.8M, medium:
|
|
170
|
+
# 11.2M, huge: 22.4M). At that point: planner must re-plan remaining
|
|
116
171
|
# work to fit, or ask the operator. Epics that
|
|
117
172
|
# cannot fit are split at spec time, never
|
|
118
173
|
# silently extended (extension is always an
|
|
119
|
-
# operator question). Checked by `
|
|
174
|
+
# operator question). Checked by `bs budget
|
|
120
175
|
# alarm <session>`, which the /bs run loop runs at
|
|
121
176
|
# each wave merge — before P9-33 this number's
|
|
122
177
|
# only reader was a human remembering to look.
|
|
123
178
|
max_in_flight_tasks: null # Off by default. "Fan-out buys wall-clock
|
|
124
179
|
# without buying extra tokens" above is the
|
|
125
180
|
# standing decision, and it only holds while the
|
|
126
|
-
# token cap actually binds — which `
|
|
181
|
+
# token cap actually binds — which `bs wave
|
|
127
182
|
# check` now makes true. So this is NOT the
|
|
128
183
|
# mechanism that bounds cost; `cap_tokens` is,
|
|
129
184
|
# and it is checked regardless of how this field
|
|
@@ -131,17 +186,32 @@ epic:
|
|
|
131
186
|
# wants a wall-clock or rate-limit bound for a
|
|
132
187
|
# reason of their own — a provider's
|
|
133
188
|
# concurrent-request limit, a laptop's CPU count
|
|
134
|
-
# — and setting it makes `
|
|
189
|
+
# — and setting it makes `bs wave check`
|
|
135
190
|
# refuse to admit a wave that would put more of
|
|
136
191
|
# the epic's tasks in flight (admitted, not yet
|
|
137
192
|
# merged) than this number at once.
|
|
138
193
|
|
|
194
|
+
task_tier_scale:
|
|
195
|
+
# Multiplies every `task:` number below for an epic of that tier. Not the
|
|
196
|
+
# epic cap, which is declared per tier above.
|
|
197
|
+
small: 0.5
|
|
198
|
+
medium: 1
|
|
199
|
+
huge: 2
|
|
200
|
+
|
|
139
201
|
task:
|
|
202
|
+
# Medium-tier numbers; `task_tier_scale` gives the small and huge ones.
|
|
140
203
|
# Defaults a planner sizes a task's own `budget` block against. The task's
|
|
141
204
|
# declared numbers are what the gate checks; these are the shape of a
|
|
142
205
|
# reasonable declaration, not a second cap applied on top.
|
|
206
|
+
#
|
|
207
|
+
# Sized 2026-09-29 from the p90 tokens per dispatch measured on eight
|
|
208
|
+
# medium-tier dogfood epics, 2026-09-14..29, rounded up. Before that the
|
|
209
|
+
# coder cap was 150k (10 of 36 measured coder dispatches over it), the four
|
|
210
|
+
# judges shared one 40k bucket (31 of 32 spec-reviewer dispatches over it),
|
|
211
|
+
# researcher was 60k, and planner, tester, security-reviewer and auditor had
|
|
212
|
+
# no cap at all, which left every epic that used one unverifiable.
|
|
143
213
|
coder:
|
|
144
|
-
cap_tokens:
|
|
214
|
+
cap_tokens: 220000 # Second reader, added 2026-08-26: `bs wave
|
|
145
215
|
# check` prices a task that exists only in the
|
|
146
216
|
# event log at this number. A follow-up minted by
|
|
147
217
|
# `findings raise` has claims but no declared
|
|
@@ -158,18 +228,38 @@ task:
|
|
|
158
228
|
# `budget.tokens` is a different silence and is
|
|
159
229
|
# still refused — the schema requires that field,
|
|
160
230
|
# so its absence is a plan that never passed
|
|
161
|
-
# `
|
|
162
|
-
cap_diff_lines:
|
|
231
|
+
# `bs plan validate`.
|
|
232
|
+
cap_diff_lines: 700 # excludes lockfiles/generated files. Measured
|
|
233
|
+
# p50 316 / p90 727 lines (was 400); small 350,
|
|
234
|
+
# huge 1400.
|
|
235
|
+
tester:
|
|
236
|
+
cap_tokens: 60000 # p90 55k
|
|
237
|
+
planner:
|
|
238
|
+
cap_tokens: 110000 # p90 103k
|
|
163
239
|
researcher:
|
|
164
|
-
cap_tokens:
|
|
165
|
-
|
|
166
|
-
cap_tokens:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
240
|
+
cap_tokens: 80000 # p90 74k (was 60k)
|
|
241
|
+
spec-reviewer:
|
|
242
|
+
cap_tokens: 170000 # p90 168k (was the shared 40k judges bucket)
|
|
243
|
+
grader:
|
|
244
|
+
cap_tokens: 110000 # p90 105k (was 40k)
|
|
245
|
+
reviewer:
|
|
246
|
+
cap_tokens: 60000 # p90 56k (was 40k)
|
|
247
|
+
verifier:
|
|
248
|
+
cap_tokens: 40000 # p90 25k (unchanged)
|
|
249
|
+
security-reviewer:
|
|
250
|
+
cap_tokens: 80000 # p90 77k
|
|
251
|
+
auditor:
|
|
252
|
+
cap_tokens: 90000 # p90 89k
|
|
253
|
+
# The old shared `judges:` bucket is gone. A policy file that still carries
|
|
254
|
+
# `judges: {cap_tokens: N}` has N read for spec-reviewer, reviewer, verifier
|
|
255
|
+
# and grader wherever it does not name that role itself.
|
|
256
|
+
#
|
|
257
|
+
# Not priced here, and dispatched anyway: merger, uiux, scribe, wave-runner.
|
|
258
|
+
# `bs budget alarm` cannot put a number on those dispatches, so an epic
|
|
259
|
+
# that used one is reported unverifiable rather than under — the omission is
|
|
260
|
+
# visible instead of free. Left unpriced on purpose until there is real spend
|
|
261
|
+
# data to size them from; inventing a cap would make the projection look
|
|
262
|
+
# complete without making it true.
|
|
173
263
|
|
|
174
264
|
pre_code_budget:
|
|
175
265
|
# researcher + uiux together, before any code is written for the epic
|
|
@@ -193,7 +283,7 @@ context_window:
|
|
|
193
283
|
# quietly loses the contract it was given.
|
|
194
284
|
counts_against_budget: true # tokens spent before a compaction still count
|
|
195
285
|
# against the caps above — compacting is not a
|
|
196
|
-
# way around the
|
|
286
|
+
# way around the coder cap.
|
|
197
287
|
compacting_roles: [planner, coder, tester, researcher, uiux, scribe]
|
|
198
288
|
narrowing_roles: [reviewer, verifier, grader, spec-reviewer, security-reviewer, merger, auditor]
|
|
199
289
|
# narrowing_roles hold evidence rather than build on it: a judge that compacts
|
|
@@ -219,7 +309,7 @@ escalation_ladder:
|
|
|
219
309
|
# architecture §12, agent-constraints.md "budgets (factory-wide)"
|
|
220
310
|
#
|
|
221
311
|
# `failed_rounds` and `enforce` are the machine-readable half, added P9-32.
|
|
222
|
-
# src/escalation.ts reads them and `
|
|
312
|
+
# src/escalation.ts reads them and `bs escalation check` asserts them
|
|
223
313
|
# against the log; `trigger`/`action` stay as the human contract and must say
|
|
224
314
|
# the same thing. A failed round is one `gate-outcome` with outcome
|
|
225
315
|
# `blocked` for the task.
|
|
@@ -260,7 +350,7 @@ effort_scaling:
|
|
|
260
350
|
# and it lives in `factory/policies/effort.yml`: a per-epic tier
|
|
261
351
|
# (small/medium/huge) that scales the deliberation steps — pre-code briefs,
|
|
262
352
|
# spec-review rounds, the plan quorum, grader rounds, verifier severities,
|
|
263
|
-
# the closing spec review — and nothing else. Ask `
|
|
353
|
+
# the closing spec review — and nothing else. Ask `bs effort show`; the
|
|
264
354
|
# two files do not overlap, and neither may touch a mechanical gate.
|
|
265
355
|
- rule: small fixes get a single coder, not a fan-out.
|
|
266
356
|
- rule: >
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
# provider does not fail loudly; it spends a doomed call on every quorum
|
|
15
15
|
# trigger, has it caught, and leaves a failure row that reads like an outage.
|
|
16
16
|
# So turn on the one you actually have — a one-line edit, runbook §2, and
|
|
17
|
-
# `
|
|
17
|
+
# `bs judge preflight` says beforehand whether it will work.
|
|
18
18
|
# Full setup/calibration/promotion procedure: docs/runbooks/providers.md.
|
|
19
19
|
#
|
|
20
20
|
# Shadow mode (Phase 8 design decision): `mode: shadow` means a provider's
|
|
21
|
-
# verdicts are RECORDED (judge-verdict events, `
|
|
21
|
+
# verdicts are RECORDED (judge-verdict events, `bs stats providers`) but
|
|
22
22
|
# have ZERO gating power — quorum.ts falls back to the native verdict alone
|
|
23
23
|
# whenever no provider in a case is `mode: active`. Flipping a provider to
|
|
24
24
|
# `mode: active` in this file (an operator edit, never a runtime write) is
|
|
@@ -48,13 +48,21 @@ providers:
|
|
|
48
48
|
# extractor generations diverge exactly as D-118 claimed: first-parseable
|
|
49
49
|
# returns `[]`, first-validating returns the verdict. If you change these
|
|
50
50
|
# args, re-run that comparison rather than reasoning about it.
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
#
|
|
52
|
+
# Model and effort are pinned here, not inherited. Without `-m` the judge
|
|
53
|
+
# runs whatever `~/.codex/config.toml` defaults to — an interactive-use
|
|
54
|
+
# choice, often the frontier model at high effort — so a confirm/refute
|
|
55
|
+
# call billed at `model_tier: mid` spent frontier quota. `model` below must
|
|
56
|
+
# name the same id as `-m`: it is what the event log records (without it a
|
|
57
|
+
# cli judge is logged as `codex:default`), and nothing checks the two agree.
|
|
58
|
+
args: ["exec", "--color", "never", "-m", "gpt-6-sol", "-c", "model_reasoning_effort=\"medium\""]
|
|
59
|
+
model: gpt-6-sol
|
|
60
|
+
model_tier: mid # taxonomy.yml model_tier — judge tier, architecture §4
|
|
53
61
|
# PRECONDITION: `codex` on PATH, and `codex login` run on every machine
|
|
54
62
|
# that dispatches a quorum trigger. Without either the CLI transport still
|
|
55
63
|
# spawns, fails, and quorum.ts records a provider error per trigger —
|
|
56
64
|
# caught, so nothing gates on it, but it is latency and noise.
|
|
57
|
-
# `
|
|
65
|
+
# `bs judge preflight` checks the first half locally; only a real call
|
|
58
66
|
# can check the second.
|
|
59
67
|
# `auto`, not `true`. This is the one field in the file that describes a
|
|
60
68
|
# MACHINE, and the file is checked in, so `true` here would be a claim
|
|
@@ -69,7 +77,7 @@ providers:
|
|
|
69
77
|
# session still spends a call per trigger and records the failure.
|
|
70
78
|
#
|
|
71
79
|
# Turned on for THIS box, 2026-09-02, by the operator who owns it: `codex`
|
|
72
|
-
# resolves on PATH and `codex login` is done, both checked by `
|
|
80
|
+
# resolves on PATH and `codex login` is done, both checked by `bs judge
|
|
73
81
|
# preflight` and by a real `codex exec` call. Rollback for one box is
|
|
74
82
|
# `enabled: false` here, which `auto` never overrides.
|
|
75
83
|
enabled: auto
|
|
@@ -89,11 +97,30 @@ providers:
|
|
|
89
97
|
# is make this box gate the moment one is enabled, with no second edit
|
|
90
98
|
# and no second decision to remember. Rollback is `mode: shadow` here.
|
|
91
99
|
mode: active
|
|
100
|
+
# OpenRouter substitution (operator decision 1a, docs/runbooks/providers.md
|
|
101
|
+
# §9): when `codex` is missing from PATH or not logged in, and
|
|
102
|
+
# OPENROUTER_API_KEY is set, this provider runs through OpenRouter
|
|
103
|
+
# instead — same name, same mode, same gating power, only the transport
|
|
104
|
+
# and model underneath change. `openai/gpt-6-sol` is an EXACT catalog
|
|
105
|
+
# match (`curl -s https://openrouter.ai/api/v1/models`, checked
|
|
106
|
+
# 2026-09-30) for the id `-m gpt-6-sol` pins above: codex substitutes as
|
|
107
|
+
# literally the same model, not an approximation. No
|
|
108
|
+
# response_format_json_object override: the catalog entry lists
|
|
109
|
+
# `response_format` among its supported parameters, so the default
|
|
110
|
+
# (true) applies.
|
|
111
|
+
openrouter_fallback:
|
|
112
|
+
model: openai/gpt-6-sol
|
|
92
113
|
deepseek:
|
|
93
114
|
kind: api
|
|
94
115
|
transport: api
|
|
95
116
|
base_url: https://api.deepseek.com
|
|
96
|
-
|
|
117
|
+
# `deepseek-reasoner` retired from DeepSeek's own `/models` listing
|
|
118
|
+
# (live check of `/models`, 2026-09-30): a call naming it is now silently
|
|
119
|
+
# answered by `deepseek-flash` instead of erroring, so the pin below
|
|
120
|
+
# matters -- a stale model id here fails open, not closed.
|
|
121
|
+
# `deepseek-v4-pro` is DeepSeek's current reasoning-tier model, the
|
|
122
|
+
# direct-API successor to the retired `deepseek-reasoner`.
|
|
123
|
+
model: deepseek-v4-pro
|
|
97
124
|
response_format_json_object: true
|
|
98
125
|
api_key_env: DEEPSEEK_API_KEY
|
|
99
126
|
model_tier: mid
|
|
@@ -103,7 +130,7 @@ providers:
|
|
|
103
130
|
# Without it api-transport.ts throws `Environment variable "DEEPSEEK_API_KEY"
|
|
104
131
|
# is not set` on every quorum trigger; quorum.ts catches it, so the gate
|
|
105
132
|
# holds on the native verdict alone, but each trigger records a provider
|
|
106
|
-
# error. `
|
|
133
|
+
# error. `bs judge preflight` reports the name it looked for and never
|
|
107
134
|
# the value it found, so it is safe to run anywhere.
|
|
108
135
|
#
|
|
109
136
|
# `auto`, not `true`, for the same reason codex is: this file is checked in
|
|
@@ -123,6 +150,17 @@ providers:
|
|
|
123
150
|
# two dogfooded product epics (docs/runbooks/providers.md §3).
|
|
124
151
|
# Rollback is `mode: shadow` here; nothing else remembers the promotion.
|
|
125
152
|
mode: active
|
|
153
|
+
# OpenRouter substitution (operator decision 1a): when DEEPSEEK_API_KEY
|
|
154
|
+
# is missing and OPENROUTER_API_KEY is set, this provider runs through
|
|
155
|
+
# OpenRouter instead. `deepseek/deepseek-v4-pro` is an EXACT catalog
|
|
156
|
+
# match (`curl -s https://openrouter.ai/api/v1/models`, checked
|
|
157
|
+
# 2026-09-30) for the id pinned above: the fallback substitutes as
|
|
158
|
+
# literally the same model, not an approximation, same as the codex
|
|
159
|
+
# substitution above. No response_format_json_object override: the
|
|
160
|
+
# catalog entry lists `response_format` among its supported parameters,
|
|
161
|
+
# same as the direct-API entry above, so the default (true) applies.
|
|
162
|
+
openrouter_fallback:
|
|
163
|
+
model: deepseek/deepseek-v4-pro
|
|
126
164
|
|
|
127
165
|
quorum_triggers:
|
|
128
166
|
# architecture §6, agent-constraints.md "cross-check (phase 8)" — all four,
|
|
@@ -195,7 +233,7 @@ quorum_rule:
|
|
|
195
233
|
# deciding with two opinions in front of them rather than one — which is the
|
|
196
234
|
# whole point of the file — not an automatic override.
|
|
197
235
|
#
|
|
198
|
-
# It silences one advisory in `
|
|
236
|
+
# It silences one advisory in `bs judge preflight` and nothing else. A
|
|
199
237
|
# provider enabled where it cannot be called is still a problem, and
|
|
200
238
|
# `gating.canDecide` still reports false, because it is false.
|
|
201
239
|
accept_non_gating_actives: true
|
|
@@ -204,7 +242,7 @@ asymmetric_roles:
|
|
|
204
242
|
finder_ne_critic: true
|
|
205
243
|
critic_mandate: refute, not confirm
|
|
206
244
|
# The machine-readable form of finder_ne_critic (P9-23). Each pair says
|
|
207
|
-
# "this critic must not run on that finder's own model"; `
|
|
245
|
+
# "this critic must not run on that finder's own model"; `bs dispatch
|
|
208
246
|
# check <session>` asserts it against the event log after the fact, using
|
|
209
247
|
# the `model` field every dispatch_decision now carries. Without this list
|
|
210
248
|
# the rule was unenforceable prose: it named no roles.
|
|
@@ -229,13 +267,13 @@ role_isolation:
|
|
|
229
267
|
#
|
|
230
268
|
# The only evidence of a separate turn the event log can hold is a separate
|
|
231
269
|
# `dispatch_decision`, written by the node that dispatched, never by an agent
|
|
232
|
-
# about itself. `
|
|
270
|
+
# about itself. `bs tester check <session>` asserts that against the log
|
|
233
271
|
# after the fact, per `testgate-result`.
|
|
234
272
|
#
|
|
235
273
|
# That reading survives delegation.yml granting `Agent` because of what the
|
|
236
274
|
# grant costs: a grantee must open its own session first, so its dispatches
|
|
237
275
|
# are its own log's, and no grant may hand a role its own auditor from the
|
|
238
|
-
# `pairs` below. `
|
|
276
|
+
# `pairs` below. `bs delegation check` enforces both, which is what keeps
|
|
239
277
|
# a widened grant from quietly disarming this file.
|
|
240
278
|
#
|
|
241
279
|
# One entry, and it is meant to stay one until a second role starts grading
|
|
@@ -289,7 +327,7 @@ independent_finder:
|
|
|
289
327
|
# summary and the failure scenario and never the source. A finder cannot: it
|
|
290
328
|
# has nothing to read but the diff. Shipping worktree source to a third-party
|
|
291
329
|
# API is a decision no code in this repo has standing to make quietly, so it
|
|
292
|
-
# is a switch, it ships false, and `
|
|
330
|
+
# is a switch, it ships false, and `bs crossfind run` REFUSES rather than
|
|
293
331
|
# falling back to a diffless "find bugs" prompt that would invent findings.
|
|
294
332
|
send_diff: false
|
|
295
333
|
max_diff_bytes: 120000 # refuse rather than truncate: half a diff produces confident findings about code that is not there
|
|
@@ -9,15 +9,15 @@
|
|
|
9
9
|
# event log for what it dispatches" (docs/standards/agent-constraints.md).
|
|
10
10
|
# Until D13 step 3 that was enforced by granting `Agent` to nobody, which also
|
|
11
11
|
# capped an epic at one operator session. A grantee that opens its own session
|
|
12
|
-
# with `
|
|
12
|
+
# with `bs session start <id> --continues <dispatch-event-id>` is a real
|
|
13
13
|
# dispatching node with a real log, so the cap can lift without the rule
|
|
14
14
|
# bending.
|
|
15
15
|
#
|
|
16
|
-
# What a grant may not do — asserted by `
|
|
16
|
+
# What a grant may not do — asserted by `bs delegation check` and by
|
|
17
17
|
# delegation.test.ts against the shipped files, so a widened grant fails CI:
|
|
18
18
|
#
|
|
19
19
|
# - dispatch itself (a role that dispatches itself writes dispatches about
|
|
20
|
-
# itself, and `
|
|
20
|
+
# itself, and `bs tester check` reads a second dispatch as proof of a
|
|
21
21
|
# second turn),
|
|
22
22
|
# - dispatch its own auditor from crosscheck.yml `role_isolation.pairs`
|
|
23
23
|
# (a coder that picks and prompts its own tester grades itself), or
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# written for: a decision made fresh every time is a decision made differently
|
|
8
8
|
# every time. So the tiers are declared here and asked for, never recalled.
|
|
9
9
|
#
|
|
10
|
-
# HOST: `
|
|
10
|
+
# HOST: `bs effort show --plan <plan.json>` reads this file plus the plan's
|
|
11
11
|
# own `effort` field and returns the profile for that epic
|
|
12
12
|
# (factory/orchestrator/src/effort.ts). `.claude/skills/bs/plan.md` and
|
|
13
13
|
# `run.md` run that verb at the top of `/bs plan` and `/bs run` and obey the
|
|
@@ -19,6 +19,14 @@
|
|
|
19
19
|
# `effort_scaling:` block is the prose sibling of this file — it says fan-out
|
|
20
20
|
# is a wall-clock optimisation; this says how much judgment each epic buys.
|
|
21
21
|
#
|
|
22
|
+
# Budgets follow the same tier (2026-09-29): `budgets.yml` sizes the epic cap
|
|
23
|
+
# and every per-task cap for small / medium / huge, and each budget reader
|
|
24
|
+
# takes the tier the epic runs at — the plan's `effort`, else `default_tier`
|
|
25
|
+
# below, raised to `security_floor` when the floor applies. That is
|
|
26
|
+
# a size, not a skipped step — the budgets still report and alarm at every
|
|
27
|
+
# tier. Agent `maxTurns` is not tiered: one ceiling per template, sized for
|
|
28
|
+
# `huge`.
|
|
29
|
+
#
|
|
22
30
|
# THE INVARIANT THAT MAKES THIS SAFE: a tier scales judgment steps only. It
|
|
23
31
|
# never touches a mechanical oracle or a guardrail — see `invariants:` at the
|
|
24
32
|
# bottom, which the host returns alongside every profile so the list cannot be
|
|
@@ -61,7 +69,7 @@ tiers:
|
|
|
61
69
|
pre_code_uiux: when-ui-criterion
|
|
62
70
|
# /bs plan steps 3-4 — planner <-> spec-reviewer until nothing S1/S2 is left.
|
|
63
71
|
spec_review_rounds: until-clean
|
|
64
|
-
# /bs plan step 4 — `
|
|
72
|
+
# /bs plan step 4 — `bs plan quorum` before operator sign-off.
|
|
65
73
|
plan_quorum: always
|
|
66
74
|
# /bs run step 6 — the grader's bounded rubric loop (agent-constraints.md
|
|
67
75
|
# caps it at 2; a tier may lower that number, never raise it).
|
|
@@ -120,22 +128,22 @@ tiers:
|
|
|
120
128
|
|
|
121
129
|
# ── What no tier may touch ──────────────────────────────────────────
|
|
122
130
|
#
|
|
123
|
-
# Returned verbatim by `
|
|
131
|
+
# Returned verbatim by `bs effort show` next to every profile. These are
|
|
124
132
|
# mechanical oracles and guardrails, not judgments: their cost is a command
|
|
125
133
|
# exiting, not an agent thinking, so scaling them saves nothing and buys
|
|
126
134
|
# nothing but a weaker claim about the result.
|
|
127
135
|
invariants:
|
|
128
136
|
- the gate pipeline — schema check, grader verdict, tests, coverage
|
|
129
|
-
evidence, findings intake, severity decision (`
|
|
137
|
+
evidence, findings intake, severity decision (`bs gate run`)
|
|
130
138
|
- the root-level integration check on the assembled branch
|
|
131
|
-
(`
|
|
132
|
-
- claim disjointness and worktree isolation (`
|
|
133
|
-
`
|
|
139
|
+
(`bs integration check`)
|
|
140
|
+
- claim disjointness and worktree isolation (`bs wave check`,
|
|
141
|
+
`bs worktree create/fingerprint/verify`)
|
|
134
142
|
- the security-reviewer's conditional dispatch
|
|
135
|
-
(`
|
|
143
|
+
(`bs security triggers`) — sensitive-paths.yml decides it, not a tier
|
|
136
144
|
- the operator's plan sign-off, which no tier may skip or infer
|
|
137
|
-
- the epic-final verdict and its mechanical holds (`
|
|
138
|
-
`
|
|
145
|
+
- the epic-final verdict and its mechanical holds (`bs epic verdict`,
|
|
146
|
+
`bs epic close`)
|
|
139
147
|
- the event log — every dispatch is still a `dispatch_decision` with a
|
|
140
148
|
causal parent, at every tier
|
|
141
149
|
- the escalation ladder after a blocked round (budgets.yml
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Blacksmith — guardrail enforcement policy
|
|
2
2
|
#
|
|
3
3
|
# docs/standards/guardrails.md is the contract; this file is the data half of
|
|
4
|
-
# what enforces it. HOST: `
|
|
4
|
+
# what enforces it. HOST: `bs policy check`/`bs policy hook`
|
|
5
5
|
# (factory/orchestrator/src/policy.ts), and — via `dist/policyHook.js` —
|
|
6
6
|
# `.claude/hooks/guard.sh`, the PreToolUse gate on every guarded tool call
|
|
7
7
|
# an agent session makes.
|
|
@@ -36,9 +36,11 @@ protected_branches:
|
|
|
36
36
|
# history-rewrite rule only (rule 5) — worktree.yml's
|
|
37
37
|
# `integration_branch.pattern`: a leaf ref "smith/<epic>" cannot coexist
|
|
38
38
|
# with "smith/<epic>/<task-id>" refs in real git (D/F ref conflict), so the
|
|
39
|
-
# shape is "smith/<epic>/integration", never a bare "smith/<epic>".
|
|
39
|
+
# shape is "smith/<epic>/integration", never a bare "smith/<epic>". Both
|
|
40
|
+
# prefixes are listed (bs-rename, operator decision 2/3): new epics
|
|
41
|
+
# integrate on bs/, but one already under way on smith/ stays there.
|
|
40
42
|
names: [main, master]
|
|
41
|
-
patterns: ["smith/*/integration"]
|
|
43
|
+
patterns: ["bs/*/integration", "smith/*/integration"]
|
|
42
44
|
|
|
43
45
|
catch_up_remotes:
|
|
44
46
|
# rule 3's one exception: the remotes a protected branch is allowed to
|
|
@@ -123,7 +125,7 @@ rules:
|
|
|
123
125
|
# ---------------------------------------------------------------------------
|
|
124
126
|
#
|
|
125
127
|
# Everything above applies to every agent session. This block applies to one
|
|
126
|
-
# additional condition: a `
|
|
128
|
+
# additional condition: a `bs sandbox open` lease is active over the
|
|
127
129
|
# directory the command will run in (factory/orchestrator/src/sandbox.ts).
|
|
128
130
|
# The orchestrator opens a lease before handing a worktree to one of the six
|
|
129
131
|
# read-only judge roles and closes it after.
|
|
@@ -141,7 +143,7 @@ rules:
|
|
|
141
143
|
#
|
|
142
144
|
# What it is not: a container, a seccomp profile, or a read-only mount. A
|
|
143
145
|
# command that writes through an interpreter (`python3 -c "open(...,'w')"`)
|
|
144
|
-
# is invisible to a matcher, and always will be. `
|
|
146
|
+
# is invisible to a matcher, and always will be. `bs worktree verify`
|
|
145
147
|
# stays in the pipeline behind this for exactly that reason. Both halves are
|
|
146
148
|
# stated in docs/standards/guardrails.md; neither is sold as the other.
|
|
147
149
|
#
|
|
@@ -157,7 +159,7 @@ judge_sandbox:
|
|
|
157
159
|
# `Edit`/`Write` (.claude/agents/*.md). `researcher` is deliberately absent
|
|
158
160
|
# — fetching is its job, and it is never leased. A lease is matched to a
|
|
159
161
|
# rule set by role, and a role named in neither list falls back to *this*
|
|
160
|
-
# one, so the list is the vocabulary `
|
|
162
|
+
# one, so the list is the vocabulary `bs sandbox open --role` validates
|
|
161
163
|
# against rather than a gate of its own.
|
|
162
164
|
roles: [reviewer, verifier, spec-reviewer, security-reviewer, grader, uiux]
|
|
163
165
|
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
# architecture §19 "Worker harness port". A *provider* is the model vendor a
|
|
4
4
|
# judge's verdict comes from (crosscheck.yml); a *harness* is the program
|
|
5
5
|
# that holds a worker turn — gives the agent its tools, its working directory,
|
|
6
|
-
# its turn limit. HOST: `
|
|
6
|
+
# its turn limit. HOST: `bs harness list` / `bs harness plan`
|
|
7
7
|
# (factory/orchestrator/src/harness.ts), which read this file when `--policy`
|
|
8
|
-
# names no other. `
|
|
9
|
-
# (§18 rule 3); `
|
|
8
|
+
# names no other. `bs` renders an invocation from it and never starts one
|
|
9
|
+
# (§18 rule 3); `bs-run` (src/run-cli.ts) is the separate binary that does.
|
|
10
10
|
#
|
|
11
11
|
# Shape, per harness:
|
|
12
12
|
# kind `in-process` — the Claude Code Agent tool, no program started
|
|
13
|
-
# (`command`/`args` unused); `cli` — a program `
|
|
13
|
+
# (`command`/`args` unused); `cli` — a program `bs-run` spawns
|
|
14
14
|
# with the rendered prompt on stdin.
|
|
15
15
|
# roles taxonomy roles this harness serves; empty = every role that
|
|
16
16
|
# ships a `.claude/agents/<role>.md`.
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
# when this is empty). Rule 6's fingerprint runs regardless.
|
|
26
26
|
# schema_args appended only when the turn names a schema (`--schema`), so a
|
|
27
27
|
# turn that validates nothing renders without one.
|
|
28
|
-
# output how
|
|
28
|
+
# output how bs-run reads the program's output: `text` (default),
|
|
29
29
|
# `codex-json` (the `codex exec --json` JSONL stream),
|
|
30
30
|
# `claude-json` (the `claude -p --output-format json` object).
|
|
31
31
|
# models tier → model id for `{model}`; tiers are taxonomy.yml
|