plans/ held 58 documents and exactly one said whether it was open. The rest
mixed finished work, reviews of shipped work, parked specs and genuinely
pending ones, with nothing distinguishing them, so "how many plans are in
the queue" had no answer short of reading all 58.
Now `grep -H '^Status:' plans/*.md` is the answer:
50 done 3 in progress 2 planned 2 reference 1 parked
Statuses were derived rather than guessed: CLAUDE.md's own built list and
"What's NOT built yet" section, plus checking the subject exists in the
code. A review of work that shipped counts as done -- it records what was
found, it is not a request for anything. `reference` separates the two docs
that are conventions rather than work items (admin-design-standards,
admin-work-framework), which otherwise read as permanently-open plans.
The vocabulary is deliberately five words. A larger one invites "mostly
done" and "blocked-ish", which is how the directory became unreadable.
test_plans_declare_status.py keeps it from rotting: a new plan without a
marker fails, as does an unknown status, one buried below the eighth line,
or an open status with no reason -- "planned" alone is the state that rots,
since nobody can tell later whether it waits on a decision, a dependency,
or just nobody's turn.
Also updates the sweep plan with what landed and what did not, including
that #9 was not a defect.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VRQXz5SYZYVWscxS1QqF6U
12 KiB
Spec: restructure README.md around a pitch → features → install → per-command usage shape
Status: done -- current README
Origin. Modeled on the structure of
dsplce-co/supabase-plus's README
— its section shape and pacing, not its content or voice. supabase-plus is
a Rust CLI tool with crates.io badges, install-method sub-sections, and
punchy, jokey per-command usage blurbs; none of that is this project. What's
being borrowed is purely structural: a short pitch up front, a scannable
features list, a Table of Contents for a doc long enough to need one,
installation broken into named sub-methods, and — the part worth the most —
usage organized per command, each with its own short "why you'd want
this" motivation before the command itself, rather than one long undifferentiated
block of curl examples.
This project's own voice stays: dry, evidence-first, "measured live on
[date]" citations, numbers with dates on them. Nothing here asks for new
jokes, new claims, or new numbers — only reorganizing what's already true in
the current 1039-line README.md into a shape a first-time reader can
actually navigate.
No README changes accompany this document — this is the spec opencode builds from.
What's being borrowed, what's being skipped, and why
| Reference element | Verdict | Reasoning |
|---|---|---|
| Org attribution banner (top link) | Skip | No org; this is a personal project. |
| Badges row (crates.io, license, version) | Skip, or minimal | Nothing here is published to a package registry. A license badge only makes sense once a license exists (see Open Decisions below) — don't badge something that isn't true yet. |
| One-line pitch + short elaboration paragraph | Adopt | The current README already has this content (see §1 below) — it's just buried under a heading instead of leading the file. |
| Italic disclaimer right after the pitch | Adopt, re-aimed | The reference's is a trademark disclaimer. This project's real analog already exists and is more load-bearing: "Numbers in this README are measurements, not specifications" (current README, "What This Is"). Same structural slot — a caveat before anyone trusts a number — different content. |
| Demo GIF | Optional, not this pass | tui.py's live dashboard is the natural candidate, but capturing one is a manual terminal recording step, not something a text plan can produce. Leave a placeholder comment (<!-- TODO: tui.py demo gif -->) rather than skip the idea entirely. |
## Features — punchy bulleted list |
Adopt, own voice | See §2. The existing "At a Glance" table already IS a features summary, just in dry-table form instead of scannable bullets. |
--- / Table of Contents |
Adopt, straightforwardly | The current README has no TOC at all across ~25 major sections and 1039 lines. This is the single highest-value, lowest-risk item in this whole plan — pure navigation, no content decisions required. |
## Installation with named sub-methods |
Adopt, honestly scoped | The reference has 6 real install methods (nix/cargo/homebrew/deb/apt/aur). This project has exactly one (venv + pip) plus a systemd deployment path. Structure as two sub-sections — "Local" and "As a systemd service" — not six fake ones. Do not invent install methods that don't exist to mimic the reference's breadth. |
## Usage — one sub-heading per command, motivation → command → bullets |
Adopt — the main point of this plan | See §3. This is the biggest actual improvement available: the current "Quick Usage" section is 9 curl commands in one code block with almost no narrative, while the reasons for each one are already written elsewhere in the doc, disconnected from the command they justify. |
## Requirements |
Adopt | Already exists as a sentence in "Setup" ("You need: a Neuralwatt API key, Python 3.10+...") — promote it to its own short section, matching the reference's terse bulleted form. |
## Repo & Contributions |
Needs a decision, see below | The reference is a public GitHub project soliciting PRs. This repo's remote is a private, self-hosted Gitea instance (git.adlee.work) — "PRs welcome" isn't true here. |
## License |
Needs a decision, see below | No LICENSE file exists in this repo (checked directly). The reference names MIT/Apache-2.0 because those are real, chosen licenses. Do not write a license section that names something that isn't actually true. |
Open decisions (yours, not opencode's to invent)
Two sections in the reference structure map to facts that don't exist yet in this repo. Both should be explicit decisions, not filled in by guessing during implementation:
- License. Pick one (or explicitly decide "unlicensed / private, not
for redistribution") before a
## Licensesection gets written. Whatever is decided, add the matchingLICENSEfile at the same time — a README section naming a license with noLICENSEfile in the repo would be the exact "documented but not actually true" failure mode this project's ownconfig.yamlstrictness rules exist to prevent elsewhere. - Repo & Contributions. Given the remote is a private Gitea instance rather than a public GitHub project, decide whether this section exists at all, and if so what it actually says — a link to the internal remote for your own reference, not an open invitation for outside contributions that can't reasonably arrive here.
If no decision is made, the plan's default is: omit both sections rather than have opencode fabricate a license or a contribution policy that isn't real.
Section-by-section mechanism
§1. Pitch + elaboration (replaces the top of "What This Is")
Move the existing lead paragraph up to immediately follow the # Local LLM Model Router title, ahead of any subheading — this is exactly what the
reference does (pitch line, then one elaborating paragraph, before any ##).
Source material already exists verbatim in the current README's opening
paragraph and the "Numbers in this README are measurements, not
specifications" caveat — this section is a move-and-reflow, not a rewrite.
§2. ## Features
Reference pattern: one bullet per capability, phrased as a real situation the reader has been in, followed by the command that fixes it. This project's own voice should replace "clever/jokey" with "concrete/measured" — the through-line of the whole existing document. Candidate bullets, pulled directly from existing content rather than invented:
POST /route— "Want to know what a task would cost before you spend anything on it?" (current README: "no provider call, no cost")- Per-request energy/cost pricing — "List price ranks models backwards for this workload; billing is per-kWh, and this router prices per request from what's actually shaped like your traffic." (current: "Weighted Scoring" section)
- Local vision fallback — "Your cheapest coding model doesn't support images. This one falls back to a local model instead of 422ing." (current: "Local Vision Fallback")
- Live TUI — "
python tui.py, a live routing feed with no polling delay." (current: "Monitoring") - Structural + local-LLM verification — "Every response gets checked for free before routing ever learns from it." (current: "Verification Pipeline")
Five bullets, matching the reference's scope (3 headline + "and others
like"), not an exhaustive re-listing of every feature — the full detail
still lives in its own section further down, same as the reference's
## Usage expands on its ## Features teasers.
§3. ## Usage — the main restructuring work
Current "Quick Usage" is one code block, 9 curl commands, minimal
narrative. Reference pattern is one ### sub-heading per command: a short
paragraph on why (often phrased as the problem the reader already has),
then the command, then a bullet list of what it actually does.
This project already has the "why" prose for nearly every command — it's just located in a different section than the command itself. Concrete mapping (existing source section → new usage sub-heading):
New ### sub-heading |
Command | Source prose already written |
|---|---|---|
| Route without spending anything | POST /route |
API Endpoints table: "no provider call, no cost" |
| Skip the classifier when you already know the shape | /route with overrides |
"Input to /route and /dispatch can include... overrides — these skip the classifier" |
| Actually dispatch and log energy | POST /dispatch |
API Endpoints table |
| Point any OpenAI-compatible client at it | /v1/chat/completions, /v1/models |
"Pointing a Coding Agent at It" |
| Route overnight/batch work through flex rows | latency_tolerance: batch |
"auto:batch admits flex rows for async work" |
| Ask an image question | image_url request | "Local Vision Fallback" |
| Force JSON output | response_format |
Weighted Scoring, hard filter #6 |
| Watch it live | python tui.py, /metrics, /events/decisions |
"Monitoring" section, mostly verbatim |
| Probe routing without spending | router_cli.py |
"Monitoring" section |
This is reorganization, not new writing: every cell in the right column already exists in the current README. The work is moving each explanation next to the command it explains, and adding a one-line "why" lead-in where the existing text is purely descriptive rather than motivating.
§4. ## Installation
Two named sub-sections, matching what's actually true:
- Local (
venv) — the existing "Setup" code block, unchanged. - As a systemd service — the existing "Scheduled Jobs (systemd)" table
and its install pointer to
deploy/README.md.
Do not add a third method. The reference's breadth (6 install paths) exists because that project targets a general audience installing a CLI tool from multiple ecosystems; this one has an owner, a GPU, and a fixed deployment shape.
§5. ## Requirements
Pull the existing "Setup" opening sentence — "a Neuralwatt API key, Python
3.10+ (suite verified on 3.10 and 3.14), and an Ollama reachable from
wherever this runs with a classifier model pulled" — into its own short
bulleted section, ahead of Installation, matching the reference's
requirements-before-installation ordering.
§6. Table of Contents
Auto-derivable from the final heading structure once the above moves are
made. Every existing ##/### heading gets an entry; nest sub-headings
(Usage's per-command sections, Installation's two methods) the way the
reference nests its own.
What must NOT change
This is a restructuring of entry points and navigation, not a rewrite of substance. Everything below stays exactly as it is, moved but not rewritten:
- The architecture diagram, the module table, the full schema documentation
(
models/proficiency/energy_observations/verifications/route_decisions), the weighted-scoring mechanism, the classifier reliability notes, and Known Limitations & Open Items — none of this has a reference-README equivalent becausesupabase-plusdoesn't carry this much operational depth. It stays as reference material past the new Usage/Installation front matter, in its current form. - No new measurements, dates, or claims. Every fact placed into a new
section must already exist verbatim (or near-verbatim, for reflow)
somewhere in the current
README.md. - No jokes or voice imported from the reference. "Had buckets locally once, never found them in prod" works for a Supabase CLI's audience; this project's own established register — measured numbers, dated observations, named caveats — is what every other document in this repo already uses, and the README should not be the one place that departs from it.
Recommendation
Build it. The highest-value pieces (a Table of Contents for a 1039-line document that currently has none, and moving existing "why" prose next to the commands it explains) require no new facts and no voice risk — they're pure reorganization. The two sections that need a real answer (License, Repo & Contributions) should get one from you before opencode touches them; absent that, the plan's default is to leave them out rather than invent them.