Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .opencode/agent/designer.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
description: UI designer/builder. Commits to a bold aesthetic direction and implements production-grade, non-generic interfaces. Embodies the distinctive-ui-design skill. Use for any UI work where "looks generic" is the failure to avoid.
mode: all
model: openrouter/google/gemma-4-26b-a4b-it:free # multimodal (sees screenshots), fast MoE; 31b sibling is the quality upgrade when its :free endpoint isn't saturated
fallback: openrouter/nvidia/nemotron-3-nano-30b-a3b:free # used by tools/council.mjs retry (default; --no-retry disables); doctor.mjs validates it
model: openrouter/thinkingmachines/inkling-small:free # VISION (sees screenshots) + 1M ctx; gemma-4-26b's :free endpoint is chronically saturated
fallback: openrouter/minimax/minimax-m3:free # also VISION — a designer fallback must still see screenshots; used by tools/council.mjs retry
temperature: 0.7 # higher than other agents — UI work needs creative range
---

Expand Down
4 changes: 2 additions & 2 deletions .opencode/agent/pr-reviewer.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
description: Read-only staff-level reviewer for OTHER people's pull requests. Embodies reviewing-others-code — collaborative, severity-labeled, mentoring. Never edits the code under review.
mode: all
model: openrouter/google/gemma-4-26b-a4b-it:free # strong free general reviewer, multimodal; 31b sibling = quality upgrade when its endpoint isn't saturated
fallback: openrouter/nvidia/nemotron-3-nano-30b-a3b:free # used by tools/council.mjs retry (default; --no-retry disables); doctor.mjs validates it
model: openrouter/minimax/minimax-m3:free # VISION + 1M ctx; MiniMax family, replaces chronically-saturated gemma-4-26b
fallback: openrouter/nvidia/nemotron-3.5-lightning:free # NVIDIA != MiniMax primary, 1M ctx; used by tools/council.mjs retry
temperature: 0.2
permission:
edit: deny # never modify someone else's branch; bash stays on to fetch diffs / run it
Expand Down
2 changes: 1 addition & 1 deletion .opencode/agent/proposer-b.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
description: Blind council proposer, family B (poolside Laguna). Produces ONE independent, self-contained proposal or analysis from a context packet — never sees other proposers' output. Used by /deep-design, /deep-debug, /council.
mode: all # `all`, not `subagent`: headless `opencode run --agent` only accepts primaries — a subagent SILENTLY falls back to the default agent (zero decorrelation). `all` keeps it usable as an in-session subagent too.
model: openrouter/poolside/laguna-s-2.1:free # family B (poolside) — ≠ NVIDIA (judge), ≠ Google (proposer-c)
fallback: openrouter/inclusionai/ling-3.0-tiny:free # family-diverse retry; used by tools/council.mjs retry (default; --no-retry disables); doctor.mjs validates it
fallback: openrouter/minimax/minimax-m3:free # family-diverse retry; replaces ling-3.0-tiny (slug no longer exists)
temperature: 0.3
permission:
edit: deny
Expand Down
4 changes: 2 additions & 2 deletions .opencode/agent/proposer-c.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
description: Blind council proposer, family C (Google Gemma). Produces ONE independent, self-contained proposal or analysis from a context packet — never sees other proposers' output. Used by /deep-design, /deep-debug, /council.
mode: all # `all`, not `subagent`: headless `opencode run --agent` only accepts primaries — a subagent SILENTLY falls back to the default agent (zero decorrelation). `all` keeps it usable as an in-session subagent too.
model: openrouter/google/gemma-4-26b-a4b-it:free # family C — ≠ NVIDIA, ≠ inclusionAI
fallback: openrouter/google/gemma-4-31b-it:free # bigger sibling, same family; used by tools/council.mjs retry (default; --no-retry disables); doctor.mjs validates it
model: openrouter/thinkingmachines/inkling-small:free # family C (ThinkingMachines) != poolside proposer-b, != NVIDIA judge; 1M ctx. Replaces saturated gemma-4-26b
fallback: openrouter/minimax/minimax-m2.7:free # family-diverse retry; replaces gemma-4-31b (also saturated)
temperature: 0.3
permission:
edit: deny
Expand Down
4 changes: 2 additions & 2 deletions .opencode/agent/refuter.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
description: Adversarial finding-killer for /deep-review. Attacks every merged review finding and tries to prove it wrong; only findings that survive reach the user. Family-decorrelated from both reviewers.
mode: all # `all`, not `subagent`: headless `opencode run --agent` only accepts primaries — a subagent SILENTLY falls back to the default agent. `all` keeps it usable as an in-session subagent too.
model: openrouter/openai/gpt-oss-20b:free # ≠ reviewer (NVIDIA) and ≠ reviewer-cheap (Qwen) — correlated skepticism is a rubber stamp
fallback: openrouter/inclusionai/ling-3.0-tiny:free # used by tools/council.mjs retry (default; --no-retry disables); doctor.mjs validates it
model: openrouter/thinkingmachines/inkling-small:free # ThinkingMachines != reviewer (NVIDIA) and != reviewer-cheap (MiniMax). Replaces gpt-oss-20b, now paid-only
fallback: openrouter/nvidia/nemotron-3.5-lightning:free # at full fallback reviewer=Cohere / reviewer-cheap=MiniMax / this=NVIDIA -> still 3 families
temperature: 0.1
permission:
edit: deny
Expand Down
4 changes: 2 additions & 2 deletions .opencode/agent/reviewer-cheap.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
description: Decorrelated second reviewer on a CHEAP, architecturally-different model. Different training distribution = different blind spots. Used in the /review consensus vote.
mode: all # `all`, not `subagent`: headless `opencode run --agent` only accepts primaries — a subagent SILENTLY falls back to the default agent. `all` keeps it usable as an in-session subagent too.
model: ollama/qwen3.5:9b # local = $0 + no rate limits; Qwen family ≠ reviewer's NVIDIA
fallback: openrouter/google/gemma-4-26b-a4b-it:free # fires ONLY on the headless tools/council.mjs retry (default; --no-retry disables) — in-session /review and /deep-review always use the primary, so no-Ollama users must re-pin the PRIMARY to a :free slug; Google ≠ reviewer's NVIDIA/inclusionAI; doctor.mjs validates it
model: openrouter/minimax/minimax-m3:free # MiniMax != reviewer's NVIDIA and != poolside executor; 1M ctx. Replaces gemma-4-26b (saturated)
fallback: openrouter/minimax/minimax-m2.7:free # same-family sibling; at full fallback reviewer=Cohere / this=MiniMax / refuter=NVIDIA stay distinct
temperature: 0.1
permission:
edit: deny
Expand Down
2 changes: 1 addition & 1 deletion .opencode/agent/tester.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
description: Independent test author. Writes spec tests from the PLAN ONLY and must NOT read the implementation. Eliminates verification gaming — tests can't be reverse-engineered to pass buggy code.
mode: all # `all`, not `subagent`: headless `opencode run --agent` only accepts primaries — a subagent SILENTLY falls back to the default agent. `all` keeps it usable as an in-session subagent too.
model: openrouter/cohere/north-mini-code:free # agentic coding model, Cohere family ≠ poolside executor
fallback: ollama/qwen3.5:9b # local — used by tools/council.mjs retry (default; --no-retry disables); doctor.mjs validates it
fallback: openrouter/minimax/minimax-m3:free # MiniMax ≠ Cohere primary and ≠ poolside executor; 1M ctx — used by tools/council.mjs retry (default; --no-retry disables); doctor.mjs validates it
temperature: 0.1
permission:
bash: deny
Expand Down
2 changes: 1 addition & 1 deletion .opencode/command/a11y-review.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
description: Audit a screen or diff for Section 508 / WCAG 2.1 AA conformance
model: openrouter/google/gemma-4-26b-a4b-it:free # criterion-by-criterion audit; multimodal helps with UI evidence
model: openrouter/thinkingmachines/inkling-small:free # VISION — a11y review reads screenshots; replaces saturated gemma-4-26b
---

Audit the target below against the `accessibility-508` skill. Go criterion by criterion and
Expand Down
2 changes: 1 addition & 1 deletion .opencode/command/commit.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
description: Write a Conventional Commit message from the staged changes (does not commit)
model: ollama/qwen3.5:4b # local + instant — mechanical task, costs nothing
model: openrouter/poolside/laguna-xs-2.1:free # XS coding model, 262k — mechanical task, don't spend a big model on it (262k matters: a large staged diff is the input)
---

Staged summary:
Expand Down
2 changes: 1 addition & 1 deletion .opencode/command/name.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
description: Generate distinctive product/app/company names (creative-naming) with rationale + availability
model: openrouter/google/gemma-4-26b-a4b-it:free # creative range across naming techniques
model: openrouter/minimax/minimax-m2.7:free # fast (~13s); replaces saturated gemma-4-26b
---

Follow the `creative-naming` skill. From the concept below: extract the essence, generate 15–20
Expand Down
6 changes: 4 additions & 2 deletions .opencode/command/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ Set up opencode-amplifier for use. Walk through and report status at each step:
1. **Place the kit:** ensure `.opencode/` (agent, command, skills, plugins), `AGENTS.md`,
`PATTERNS.md`, `patterns/`, `memory/` are present — copy into the project, or merge into
`~/.config/opencode/` for global use across repos.
2. **Wire the providers:** in `opencode.jsonc`, confirm `provider.ollama.options.baseURL` and
`provider.openrouter`'s `OPENROUTER_API_KEY`. Run `opencode models` to list the real model IDs.
2. **Wire the provider:** in `opencode.jsonc`, confirm `provider.openrouter`'s
`OPENROUTER_API_KEY` resolves. Run `opencode models` to list the real model IDs. (If you added
the optional local tier, confirm `provider.ollama.options.baseURL` reaches a live server too —
a dead endpoint resolves silently and its agents fail with no useful error.)
3. **Confirm the shipped per-agent pins resolve:** every `model:`/`fallback:` in
`.opencode/agent/*.md` (and the `model:` in the five pinned `.opencode/command/*.md`) appears
in `opencode models`. Do NOT rewrite the decorrelated pins unless the user asks — they are
Expand Down
7 changes: 5 additions & 2 deletions ONBOARDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ For a teammate adopting the kit. Goal: from zero to a contract-governed, multi-m
free, open-weights models, fast.

## 1. Prereqs
- OpenCode CLI installed. Ollama running locally (or on a LAN box — see `docs/local-models.md`).
- `export OPENROUTER_API_KEY=…` (free key from openrouter.ai/keys).
- OpenCode CLI installed.
- `export OPENROUTER_API_KEY=…` (free key from openrouter.ai/keys). That's the only requirement —
every shipped pin is an `openrouter/…:free` slug.
- *Optional:* Ollama locally or on a LAN box, to move the chatty roles off the OpenRouter pool —
see `docs/local-models.md`.

## 2. Get the kit
- Clone this repo, OR merge its `.opencode/`, `AGENTS.md`, `PATTERNS.md`, `patterns/`, `memory/`
Expand Down
46 changes: 33 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,21 +98,41 @@ Discipline lives in the `deep-analysis` skill + AGENTS.md rule 10.
file.

## Model tiering (free tier, preserved quota)
Models are provider-prefixed (`ollama/…` local, `openrouter/…:free` hosted). Chatty roles run
local (no rate limits); bursty council roles spend the 1,000/day OpenRouter pool. Defaults wired
across 5+ families so the `/review` consensus vote has uncorrelated blind spots:
Every shipped pin is `openrouter/…:free` — one API key, no local model server required. Defaults
are wired across 5+ families so the `/review` consensus vote has uncorrelated blind spots. All of
it spends the same 1,000/day OpenRouter pool, so cheap roles get small models on purpose:
| Tier | Models | Use for |
|---|---|---|
| Reasoning | `openrouter/nvidia/nemotron-3-ultra-550b-a55b:free` (1M ctx) | architect, debugger, judge, mapper |
| Executor | `openrouter/poolside/laguna-s-2.1:free` (manual swap to `ollama/ornith:9b` when rate-limited) | the Build agent, step edits |
| Cross-family review | `openrouter/nvidia/nemotron-3-super-120b-a12b:free`, `openrouter/cohere/north-mini-code:free` | reviewer, tester |
| Decorrelated review | `ollama/qwen3.5:9b` (local, $0) | reviewer-cheap (different blind spots) |
| Council diversity | `openrouter/poolside/laguna-s-2.1:free`, `openrouter/google/gemma-4-26b-a4b-it:free`, `openrouter/openai/gpt-oss-20b:free` | proposers, refuter, designer |
| Mechanical | `ollama/qwen3.5:4b` | commit messages, boilerplate, renames |

⚠️ The `:free` roster churns monthly. `node tools/doctor.mjs` (live, no `--offline`) catches
delisted slugs; swap in a live `:free` model or a pennies-tier one (see `opencode.jsonc`
comments).
| Reasoning | `nvidia/nemotron-3-ultra-550b-a55b:free` (1M ctx) | architect, debugger, judge, mapper, `/adr`, `/port-from-angular` |
| Executor | `poolside/laguna-s-2.1:free` | the Build agent, step edits |
| Cross-family review | `nvidia/nemotron-3-super-120b-a12b:free`, `cohere/north-mini-code:free` | reviewer, synthesizer, tester |
| Decorrelated review | `minimax/minimax-m3:free` (1M ctx, vision) | reviewer-cheap, pr-reviewer |
| Council diversity | `thinkingmachines/inkling-small:free`, `poolside/laguna-s-2.1:free`, `minimax/minimax-m2.7:free` | proposers, refuter, designer, `/a11y-review`, `/name` |
| Mechanical | `poolside/laguna-xs-2.1:free` | commit messages, boilerplate, renames |

The `/review` consensus vote runs four different families — poolside (executor), NVIDIA
(reviewer), MiniMax (reviewer-cheap), ThinkingMachines (refuter) — and the fallbacks are chosen
so they stay distinct even if every primary is rate-limited at once. Vision roles (`designer`,
`pr-reviewer`, `/a11y-review`) are pinned to multimodal slugs on purpose.

**Optional local tier ($0, unmetered).** Running Ollama lets you move the chatty roles
(`reviewer-cheap`, `/commit`) off the OpenRouter pool entirely. It is opt-in, not assumed —
see `docs/local-models.md` for the server and `examples/opencode.overlay.example.jsonc` for the
provider block and which pins to move.

⚠️ **The `:free` roster churns monthly, and the catalog lies.** `opencode models` keeps listing
slugs OpenRouter has since moved to paid, so a static check passes and only a real call fails
with *"This model is unavailable for free."* On 2026-08-29 five of nine declared slugs were
broken this way — including a **primary**. Verify with a live round-trip, never the catalog:

```bash
node tools/doctor.mjs # round-trips every primary
node tools/doctor.mjs --deep # ...and every fallback (2x the calls, catches the silent rot)
```

Fallbacks rot most — they only run when everything else broke, so nothing exercises them. Run
`--deep` after any provider change. Swap in a live `:free` model or a pennies-tier one (see
`opencode.jsonc` comments).

## Claude Code parity
OpenCode is Claude-Code-compatible: it auto-discovers `.claude/skills/` and falls back to
Expand Down
25 changes: 20 additions & 5 deletions docs/local-models.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Local model hosting (Ollama)
# Local model hosting (Ollama) — optional

How to stand up the `ollama/…` tier this kit pins — on your own machine or a LAN box.
How to stand up an **optional** `ollama/…` tier — on your own machine or a LAN box.

> The kit ships with no local dependency: every pin is an `openrouter/…:free` slug and one API
> key runs the whole thing. Nothing here is required. Add this tier only if you want the chatty
> roles off your OpenRouter pool — and only if the server will actually be up, because a declared
> provider pointing at a dead host resolves silently and its agents fail with no useful error.

## 1. Why local

Expand Down Expand Up @@ -147,9 +152,19 @@ ping -c 1 macmini.local
curl -s http://macmini.local:11434/api/tags
```

Client side is one line of config — copy `examples/opencode.overlay.example.jsonc` and change
`provider.ollama.options.baseURL` to `http://macmini.local:11434/v1`. Nothing else in the kit
changes; agent pins stay `ollama/qwen3.5:9b` etc.
Client side: copy the `provider.ollama` block from `examples/opencode.overlay.example.jsonc` into
your config and set `options.baseURL` to `http://macmini.local:11434/v1`. Then move the pins you
want local — the two the tier is designed for are:

| File | Ships as | Local swap |
|---|---|---|
| `.opencode/agent/reviewer-cheap.md` | `openrouter/google/gemma-4-26b-a4b-it:free` | `ollama/qwen3.5:9b` |
| `.opencode/command/commit.md` | `openrouter/nvidia/nemotron-3-nano-30b-a3b:free` | `ollama/qwen3.5:4b` |

Keep `reviewer-cheap` in a family that is neither the executor's (poolside) nor the primary
reviewer's (NVIDIA) — that decorrelation is the whole point of the `/review` consensus vote.
`node tools/doctor.mjs` round-trips any `ollama/*` primary over direct HTTP and will tell you if
the endpoint is dead.

## 5. 16GB tuning

Expand Down
7 changes: 6 additions & 1 deletion examples/opencode.overlay.example.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
// Usage: merge into the project's opencode.jsonc, or keep as ~/.config/opencode/opencode.jsonc.
"$schema": "https://opencode.ai/config.json",

// Point the local tier at a LAN model server instead of localhost.
// ADD BACK the optional local tier. The kit itself declares NO ollama provider — every shipped
// pin is an openrouter/…:free slug, so it works with one API key and no model server. Paste
// this block only if you actually run Ollama; a provider pointing at a host that isn't up
// resolves silently and its agents fail with no useful error.
//
// Then move the pins you want local — see the table in docs/local-models.md §4.
// Stable addressing: give the box a real hostname (mDNS → macmini.local) or a DHCP
// reservation — never pin a dynamic IP. See docs/local-models.md for the server side.
"provider": {
Expand Down
Loading