Files
6krrt/plans/readme-restructure.md
adlee-was-taken 3523dcf93e docs(plans): give every plan a Status line so the queue is greppable
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
2026-09-08 18:55:16 -04:00

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:

  1. License. Pick one (or explicitly decide "unlicensed / private, not for redistribution") before a ## License section gets written. Whatever is decided, add the matching LICENSE file at the same time — a README section naming a license with no LICENSE file in the repo would be the exact "documented but not actually true" failure mode this project's own config.yaml strictness rules exist to prevent elsewhere.
  2. 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 because supabase-plus doesn'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.