Files
nisse/nisse-dev.example.yaml
T
dongarandClaude Opus 5.5 6ae2375194
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 2m16s
CI / e2e (pull_request) Successful in 10m51s
M2.8: switch over to the new loop
nisse-dev now runs only the conversational loop. The gated state machine
it was built alongside is gone:

- Removed control.py, planner.py, executor.py, approvals.py, gates.py
  (command_form moves to loop/reader.py), publish.py and poller.py, the
  old assembly in agent.py (its shared helpers move to loop/build.py),
  the store's state-machine view (get_state, transition), their tests,
  the old end-to-end and live planning/milestone/gate tests, and
  specs/orchestrator.qnt with its scenarios.
- Roles are driver, helper, expert and classifier; driver is required.
  loop:, roles.planner, roles.executor and tuning.executor are refused
  with what to use instead; tuning.driver takes the turn cap and failure
  limit.
- The benchmark and the capability matrix measure the driver: the
  loop's own system prompt and tools, the task's plan as the agreed
  restatement. Task plans end with finish_milestone, so earlier runs
  show as (old); stored runs' executor tuning reads as the driver's.
- A delegation on the loop records what its helper's alias resolved to
  (L9), as the old path's did.
- The dump shows a work item's revision and what it waits for.
- Behaviour the old tests covered and the loop shares stays covered:
  driver runs that fail on a model call, stop mid-turn, reset the
  failure count; go-aheads ignoring case and punctuation; a request too
  big to fit is never sent; the assembly tests, now on build_loop_agent.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
2026-10-08 03:12:58 +00:00

101 lines
4.7 KiB
YAML

# Example configuration for nisse-dev. Copy to nisse-dev.yaml (or point
# NISSE_CONFIG at your copy) and edit.
#
# - Structure lives here. Secrets do not: write them as ${VARIABLE} references,
# resolved from the environment (or .env, see .env.example) at startup.
# - Keep this file outside the workspace clone. Startup refuses otherwise,
# because the agent commits and pushes everything in the clone.
# - Unknown keys are errors, so a misspelt knob fails at startup instead of
# silently doing nothing.
state_db: ~/nisse-demo-workspace/state.db
# loop: new # the new conversational loop (M2.1); default old (control.py)
# D8: one entry per project. A second project is a second entry (the old loop
# runs exactly one). Changed by PR like the rest of this file.
projects:
demo:
repo: owner/demo-repo
base_branch: main
workspace: /root/work/demo # the clone, on the build host
build_host: # L13: every command runs here, over SSH
address: build-demo.example
key: ~/.ssh/nisse-dev # the agent's key for the build host
# user: root
# port: 22
push_key: ~/.ssh/push-demo-repo # a deploy key with write access (D4)
# labels: [discuss] # added to every issue's own (D1)
# secrets: # by name; values only by reference (D7)
# DATABASE_URL: {value: "${DEMO_DATABASE_URL}", visible: commands}
# DEPLOY_TOKEN: {value: "${DEMO_DEPLOY_TOKEN}", visible: harness}
# egress: [pypi.org] # beyond the default; recorded, not yet enforced
llm: # L9: LiteLLM is the only LLM destination
base_url: http://litellm.example:4000
token: ${NISSE_LLM_TOKEN}
# Ceiling on each response. The model's own max_output_tokens in LiteLLM
# caps it further, which is where to hold a local model to less.
max_output_tokens: 16384
# How long one request may take before it is abandoned. A safety net for a
# hung connection; slow local models can take minutes over a long answer.
request_timeout_s: 600
roles: # L9: role -> LiteLLM model alias
# Each work item pins the mapping when it opens.
driver: claude-opus-5-5 # drives the loop: talks, restates, works
helper: claude-opus-5-5 # takes over what the driver got stuck on
expert: claude-haiku-4-5 # one question at a time, no tools: cheap is enough
# classifier: claude-haiku-4-5 # reads go-aheads (later: actions, L4); unset, expert's
# Capability profiles (L9), from benchmarks: what one role is told about
# another (never a model's name). Optional; a model without one is briefed as
# "no profile recorded".
profiles:
qwen3.8-27b:
tools: reliable (37/40 on the executor benchmark, PR #55)
strengths: careful multi-step edits that follow a clear brief
weaknesses: speed (minutes per hard task) and open-ended design
claude-haiku-4-5:
tools: reliable
strengths: quick, well-scoped changes and short answers
weaknesses: long multi-file work (15/20 on the harder benchmark tasks)
claude-opus-5-5:
tools: reliable
strengths: design, debugging, and work other models got stuck on
weaknesses: cost; use it for what needs it
matrix: # L5
homeserver: https://matrix.example
user_id: "@nisse-dev:example"
token: ${NISSE_MATRIX_TOKEN}
room_id: "!roomid:example"
operators: ["@you:example"]
gitea: # D4, D5
url: https://gitea.example
token: ${NISSE_GITEA_TOKEN}
operators: [your-gitea-login]
# What each knob does, and how to choose a value: docs/Tuning-Guide.md.
# These are the defaults; the section can be left out entirely. The file is
# read at startup, so a change takes effect on the next restart.
tuning:
driver:
max_turns: 40 # model calls per driver run before it stops as capped
failure_limit: 2 # consecutive failed commands before escalating (L9)
expert:
consult_budget: 3 # ask_expert calls per milestone (L9)
delegation: # hard caps on one delegation (L9)
max_turns: 30
max_tokens: 200000
wall_clock_s: 900
tools:
command_timeout_s: 120 # one run_command before it is killed
max_output_chars: 4000 # tool output kept for the model, head and tail
context: # fitting each request into the model's window
keep_recent_turns: 6 # turns never cut or dropped
safety_margin: 0.1 # fraction of the window held back
loop: # the new loop (loop: new)
bug_grace_s: 600 # a `bug` restatement proceeds after this long unanswered
general_idle_s: 86400 # a conversation closes after this long without a message