harness: single-shot conductor + CLI with MVP demo path
`harness once` runs one bounded iteration (intake -> routing -> bounded turn
-> REPORT) then exits, so callers chain it without a daemon. The bounded
turn loops request -> tool calls -> results up to max_rounds; gate denials
feed back to the model and are counted instead of failing the turn.
--dry-run prints the plan (task, resolved model, tool bounds) and makes zero
LLM calls; --demo runs the [demo] issue ("tell me about yourself" through
LiteLLM -> GLM self-description as the REPORT), the MVP acceptance bar.
Distinct exit codes for config/usage, intake, and llm failures. Ships
harness.toml.example (scope query, tier map, allow-lists); real configs are
gitignored. Loop tests run end-to-end against a scripted fake OpenAI server:
demo turn, dry-run zero-call, tool round-trip, denial counting, round limit,
and error-class mapping.
💘 Generated with Crush
Assisted-by: Crush:glm-5.2
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
# MOPAC harness configuration, v0 (2026-08-28).
|
||||
#
|
||||
# Copy to harness.toml and adjust. harness.toml is gitignored: secrets never
|
||||
# live in this file, only refs (env:NAME | file:PATH | literal:VALUE; the
|
||||
# bw: bitwarden ref lands with the key wrapper in build phase 3).
|
||||
|
||||
# Vertical / stack identity for this harness instance.
|
||||
vertical = "demo"
|
||||
|
||||
# Where the bash tool executes and REPORTs land (relative to the CWD the
|
||||
# harness is started from).
|
||||
work_root = "."
|
||||
report_dir = "reports"
|
||||
|
||||
[loop]
|
||||
# Bounded turn: max LLM round trips per task (tool calls included).
|
||||
max_rounds = 8
|
||||
|
||||
[redmine]
|
||||
url = "https://rm.example.org"
|
||||
key_ref = "env:HARNESS_REDMINE_KEY"
|
||||
# Released scope: raw /issues.json filter params...
|
||||
scope_query = "project=mopac&status_id=released&limit=25"
|
||||
# ...or a saved custom query id (scope_query wins when both are set).
|
||||
# scope_query_id = 42
|
||||
# Custom field carrying the TASK class; issues without it get default_class.
|
||||
class_field = "Class"
|
||||
default_class = "primary"
|
||||
|
||||
[litellm]
|
||||
base_url = "http://192.168.3.78:4001"
|
||||
key_ref = "env:HARNESS_LITELLM_KEY"
|
||||
timeout_secs = 120
|
||||
max_retries = 2
|
||||
|
||||
# MODEL ROUTING v0 (static, config-only, no heuristics): [models] is the
|
||||
# tier map (tier alias -> concrete proxy model); [models.classes] maps task
|
||||
# classes to tiers. Requests go out with the CONCRETE model name resolved
|
||||
# here. Swapping models (e.g. glm-4.7-flash -> glm-5.3-flash once it is
|
||||
# configured on the proxy) is a one-line edit in this file.
|
||||
[models]
|
||||
mopac-study = "glm-4.7-flash" # flash tier
|
||||
mopac-code = "glm-5.2" # flagship
|
||||
mopac-review = "glm-5-turbo" # mid
|
||||
mopac-primary = "glm-5.3" # default / flagship+
|
||||
mopac-vision = "glm-4.6v" # vision when needed
|
||||
default_tier = "mopac-primary"
|
||||
|
||||
[models.classes]
|
||||
study = "mopac-study"
|
||||
read = "mopac-study"
|
||||
code = "mopac-code"
|
||||
architecture = "mopac-code"
|
||||
review = "mopac-review"
|
||||
summarize = "mopac-review"
|
||||
writeback = "mopac-review"
|
||||
vision = "mopac-vision"
|
||||
primary = "mopac-primary"
|
||||
|
||||
# Exec tool: allow-listed bash. Org preset: deny-first, read-leaning allow
|
||||
# list, no sudo/ssh/network exfil. Compound commands are checked segment by
|
||||
# segment; command substitution and subshells are always denied.
|
||||
[tools.bash]
|
||||
enabled = true
|
||||
timeout_secs = 60
|
||||
max_output_bytes = 100000
|
||||
default = "deny"
|
||||
deny = [
|
||||
"sudo *",
|
||||
"ssh *",
|
||||
"scp *",
|
||||
"nc *",
|
||||
"curl *",
|
||||
"wget *",
|
||||
"rm -rf *",
|
||||
]
|
||||
allow = [
|
||||
"pwd",
|
||||
"ls *",
|
||||
"cat *",
|
||||
"head *",
|
||||
"tail *",
|
||||
"grep *",
|
||||
"find *",
|
||||
"wc *",
|
||||
"echo *",
|
||||
"env",
|
||||
"git status",
|
||||
"git diff *",
|
||||
"git log *",
|
||||
"git show *",
|
||||
"go version",
|
||||
"go build *",
|
||||
"go vet *",
|
||||
"go test *",
|
||||
]
|
||||
|
||||
# MVP demo (Charles, 2026-08-28 ~19:00): `harness once --demo` runs this
|
||||
# issue through LiteLLM; the GLM self-description lands as the REPORT.
|
||||
[demo]
|
||||
id = "demo-1"
|
||||
subject = "MVP demo: GLM self-description"
|
||||
prompt = "tell me about yourself"
|
||||
class = "primary"
|
||||
Reference in New Issue
Block a user