# MOPAC harness configuration for @ACCOUNT@ (@HOST@, index @INDEX@) — # generated by deploy/install-account.sh from deploy/accounts.tsv # (Redmine 494). Hand-edits are ALLOWED and survive re-runs of the # installer (it refuses to overwrite an existing harness.toml). # # No secrets in this file, ever — only env: refs resolved at runtime from # ~/.mopac/env (0600, see deploy/runbook.md bootstrap step). # Vertical / stack identity for this harness instance. vertical = "@VERTICAL@" # Absolute paths (substituted at install): the bash tool executes in # work_root; REPORTs land in report_dir; daemons keep state under state/. work_root = "@HOME@/.mopac/work" report_dir = "@HOME@/.mopac/reports" [loop] # Bounded turn: max LLM round trips per task (tool calls included). max_rounds = 8 # `harness loop` daemon: Redmine scan interval and state location # (append-only loop.jsonl, dedup by issue id + updated_on). poll_interval_secs = 120 state_dir = "@HOME@/.mopac/state/loop" [redmine] url = "https://projects.knownelement.com" key_ref = "env:HARNESS_REDMINE_KEY" # Released scope for this account's vertical (project from accounts.tsv): scope_query = "project=@REDMINE_PROJECT@&status_id=released&limit=25" # class_field: Redmine custom field carrying the TASK class; issues # without it get default_class. class_field = "Class" default_class = "primary" # After a REPORT is noted back on an issue, an issue whose CURRENT status # matches a key here moves to the value (names resolved via # /issue_statuses.json). Set the pair that moves work OUT of the released # scope for this project's workflow, e.g. (uncomment + adjust names): # [redmine.status_map] # "Released" = "Done" # Empty/absent map = leave status alone (the loop still advances its own # dedup marker past its writebacks — no redispatch storm). [litellm] base_url = "http://192.168.3.78:4001" key_ref = "env:HARNESS_LITELLM_KEY" timeout_secs = 120 max_retries = 2 # GITEA (optional, off by default): `harness loop` commits each REPORT # file to this repo right after writing it. Per-account REPORT repos can # be wired later by uncommenting (key goes into ~/.mopac/env). # [gitea] # url = "https://git.knownelement.com" # key_ref = "env:HARNESS_GITEA_KEY" # owner = "ukrrs" # repo = "MOPAC-reports" # branch = "main" # commit_reports = false # MODEL ROUTING v0 (static, config-only): [models] is the tier map (tier # alias -> concrete proxy model); [models.classes] maps task classes to # tiers. Swapping models is a one-line edit here. [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. [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 *", ] # Smoke-test issue for this install: `harness once --dry-run --demo` runs # the plan path with NO secrets and NO LLM call — the runbook verify step. [demo] id = "demo-@VERTICAL@" subject = "@ACCOUNT@ install smoke" prompt = "introduce yourself and your vertical" class = "primary" # EVENTS: the `harness events` webhook receiver. Port @EVENTS_PORT@ = # 4100 + index from accounts.tsv — unique per account per host. [events] listen = ":@EVENTS_PORT@" state_dir = "@HOME@/.mopac/state/events" [events.redmine] secret_ref = "env:HARNESS_REDMINE_WEBHOOK_SECRET" [events.discourse] secret_ref = "env:HARNESS_DISCOURSE_WEBHOOK_SECRET" [events.gitea] secret_ref = "env:HARNESS_GITEA_WEBHOOK_SECRET" # SERVE: the OpenAI-compatible front door for OpenWebUI. Port # @SERVE_PORT@ = 8090 + index from accounts.tsv. Bearer vkey auth — the # same value goes into the OWUI connection config for this account. [serve] listen = ":@SERVE_PORT@" vkey_ref = "env:HARNESS_SERVE_VKEY" # QUOTA GATE (Redmine 490): values pre-filled for this account's plan # group (@QUOTA_ACCOUNT@); flip enabled = true once the shared redis # container is up (README runbook) and the grouping is confirmed. # [quota] # enabled = false # account = "@QUOTA_ACCOUNT@" # plan_5h_credits = 28000 # plan_weekly_credits = 140000 # usage_url = "" # key_ref = "env:HARNESS_ZAI_KEY" # poll_interval_secs = 300 # defer_at_pct = 85 # block_at_pct = 95 # peak_start = "01:00" # peak_end = "05:00" # timezone = "America/Chicago" # peak_weekdays_only = true # peak_classes = ["study", "read"] # redis_url = "redis://192.168.3.78:6390/0" # RESOURCE GATE (Redmine 491): read-only host monitor; the loop defers # dispatch while busy. Flip enabled = true per host capacity. # [resources] # enabled = false # max_load_avg = 6.0 # min_mem_available_mb = 2048 # min_disk_free_mb = 5120 # max_io_delay_pct = 90.0