Skip to content

OliviaKeiter/groundwork

Repository files navigation

Groundwork

Route the idea to the smallest model that can carry it. Then check the receipts.

Every time you start a build with Claude, you place a bet: which model is this job worth? Bet too big — Opus or Fable for work Haiku could carry — and you pay 5 to 10x for reasoning the task never uses. Bet too small on genuinely hard work and you pay in failed loops and retries; a stronger model that finishes in two attempts is cheaper than a weaker one that takes seven. Either way, the tokens are burned before you learn whether the bet was right. Because nobody checks.

Groundwork is the check. Score a build idea on six axes and get a verdict: the smallest Claude model that can carry the job, what a run and a month will cost, and the exact failure signal that means move up a tier. Every verdict lands in a log. If you use Claude Code, a hook fills in what each session actually ran and actually cost, straight from the transcript, zero typing. After a few weeks, the calibration panel tells you — in real dollars — whether your instincts bet too big or too small.

Built for the moment right after a first scope conversation, when it is very tempting to reach for the biggest model in the drawer.

Try the console live — no clone, no install, no login. Hit "Load sample data" to see a populated verdict, log, and calibration panel in one click. When the weights are wrong for how you work or the tiers don't match your stack, everything below shows you how to get the source and make it yours.

What it does

  • Scores ideas on a weighted six-axis rubric with verdict bands and escalation triggers
  • Estimates cost per run and per month against an editable, verified-dated rate table
  • Auto-scores from your scope notes via the Anthropic API (bring your own key, or keyless inside a Claude artifact)
  • Hands off from any Claude chat: one copyable prompt turns the conversation that scoped the idea into a structured scope block — per-axis evidence plus which model did the scoping. Paste it back and the sliders, idea, and runs set themselves instantly, no API call needed
  • Tracks every Claude Code session automatically via a SessionEnd hook: real tokens, real cache behavior, real cost
  • Pairs verdicts with reality: run /groundwork at the start of a session and the hook fills in what actually happened at the end
  • Calibrates you: match rate, tier drift, escalation clusters, and evidence-based threshold suggestions
  • Shares a receipt, not just a number: one-click PNG export of a verdict ticket or a calibration readout, styled with your accent theme — built for pasting into a post, not just a doc
  • Looks the part: black console UI with five selectable neon accents (volt, ultraviolet, ice, hot pink, gold)

This is not an auto-switcher. Groundwork recommends and measures. You always choose the model. The escalation trigger is the safety net, not a bigger default.

Quick start

No accounts, no login, no build step. Ready to make it yours instead of just using the hosted copy? Clone it and you have everything, including every weight, tier, and price, as one file to edit.

Just the web console — score ideas by hand, no Claude Code required:

git clone https://github.com/OliviaKeiter/groundwork.git
open groundwork/index.html      # or deploy to Netlify / GitHub Pages

The full loop — Claude Code sessions flow into the console automatically:

cd groundwork
./install.sh                    # macOS/Linux/Git Bash · or ./install.sh --global, see below
npx serve                       # serve the console from the repo
claude                          # open Claude Code in this folder

On Windows PowerShell use .\install.ps1 (or .\install.ps1 -Global) — same installer, native shell. Careful with bare bash install.sh in PowerShell: that often resolves to WSL's bash, not Git Bash, and fails if WSL isn't set up. After install, double-click groundwork.cmd to reopen the console any time — it starts the server if needed and opens the browser.

Then the rhythm is:

  1. In Claude Code, start every task with /groundwork <what you're about to build>. You get a verdict card — recommended model, why, the escalation trigger — and the verdict is logged.
  2. Work the session normally. Switch models or don't; your call.
  3. Exit. The SessionEnd hook reads the transcript and fills in what the session actually used and cost, no typing.
  4. Open (or refresh) the console at the served URL. It auto-syncs data/dispatch-log.json on load — your verdicts and real costs are just there. (Opened as a plain file instead of served? The Import button does the same thing manually.)

Where /groundwork works: plain ./install.sh makes it available only when you open claude inside this folder. ./install.sh --global registers the hook for every project on the machine and installs /groundwork as both a global command and a global skill — so any session anywhere feeds the same console, whether you type /groundwork or just ask "what model does this need?"

Full guides: docs/HOW-TO-USE.md for the daily workflow, docs/SETUP.md for install.

How it works

scope conversation ends
        │
        ▼
┌────────────────────┐     you adjust,      ┌──────────────────────┐
│  Intake            │     you decide       │  Verdict ticket      │
│  6-axis rubric     │ ───────────────────► │  model · why ·       │
│  presets ·         │                      │  escalate-if ·       │
│  auto-score (API)  │                      │  $/run · $/month     │
└────────────────────┘                      └──────────┬───────────┘
                                                       │ log it
                                                       ▼
┌────────────────────┐   SessionEnd hook   ┌──────────────────────┐
│  Claude Code       │ ──────────────────► │  dispatch-log.json    │
│ /groundwork verdict│   real tokens,      │  verdicts + reality   │
│  then work happens │   real cost, pair   └──────────┬───────────┘
└────────────────────┘                                │ merge-import
                                                      ▼
                                            ┌──────────────────────┐
                                            │  Calibration panel   │
                                            │  match % · drift ·   │
                                            │  threshold evidence  │
                                            └──────────────────────┘

The rubric

Six axes, each 0 to 100, fixed weights. Reasoning and ambiguity weigh most because they drive capability need hardest; autonomy and failure cost push toward stronger models because weak models fail more loops, and loops are where cost hides.

Axis Weight Left end Right end
Reasoning depth 0.26 Template fill, reformatting Novel multi-step problem solving
Ambiguity 0.20 Fully specified spec Open-ended judgment calls
Context volume 0.12 A prompt and a paragraph Whole codebases, document sets
Autonomy 0.18 One shot, one answer Long agentic loops with tools
Cost of failure 0.16 A retry is free Mistakes burn trust or money
Output volume 0.08 A short reply Long documents, large files
Score Verdict The short version
0-30 Claude Haiku 4.5 Anything bigger is paying for unused reasoning
31-62 Claude Sonnet 5 The production default at a third of Opus pricing
63-85 Claude Opus 4.8 Fewer attempts beats cheaper attempts
86-100 Claude Fable 5 Failed loops cost more than the 2x premium

Every verdict ships with an escalation trigger: the concrete failure signal that means bump one tier. Start cheap, escalate on evidence, not vibes.

Claude Code integration

Three pieces, all in this repo:

Piece File What it does
SessionEnd hook hooks/dispatch-watch.mjs Parses the session transcript, totals tokens per model (input, output, cache reads at 0.1x, cache writes at 1.25x), computes real cost, logs the session. Always exits 0; can never break a session.
/groundwork command .claude/commands/groundwork.md Scores the task you are about to start, prints the verdict card, suggests the /model switch, logs a pairable verdict.
Skill .claude/skills/groundwork/SKILL.md The same rubric conversationally: paste a scope conversation anywhere Claude runs skills, get the same verdict format.

The pairing is the payoff: /groundwork logs a verdict, the session runs, the hook fills that verdict's "actually used" with the dominant model by spend and the real dollar cost. Your calibration data collects itself. Sessions without a verdict still land as standalone CC session records, so nothing burns untracked.

Honest limits: the hook sees Claude Code sessions on machines where it is installed. It cannot see claude.ai chats (no local transcript to read). Verdicts for chat-side work go through the web console or the skill.

Cost estimates and pricing

Defaults as of July 2026, USD per million tokens, editable in the UI and in data/pricing.json:

Model Input Output
Claude Haiku 4.5 $1.00 $5.00
Claude Sonnet 5 $3.00 $15.00
Claude Opus 4.8 $5.00 $25.00
Claude Fable 5 $10.00 $50.00

Rates drift, so the pricing table carries a last-verified date and a one-click "mark verified today". Verify against claude.com/pricing. Every verdict also surfaces the cheaper plays: prototype one tier down, Batch API for 50% off async work, prompt caching for repeated context. The monthly line shows one tier down and one tier up, because $0.40 vs $0.08 per run is shrug money and $120 vs $24 a month is a decision.

All of the above is pay-as-you-go API pricing, which has nothing to say to someone on a flat-rate subscription (Pro, Max, Team) — there's no per-token bill to compute, and no local way to read Anthropic's actual account-side usage limit either; a session transcript has tokens, not quota consumed. So open Plan & usage in the header and pick your plan, then use the Plan usage panel for the real numbers: type in the two percentages the Claude app's own usage indicator already shows you (5-hour limit, weekly all-models) whenever you check it. That's the only accurate source there is. Underneath, a rough dollar-equivalent throughput figure runs alongside it — explicitly labeled as not your real quota, since metered list-price is priced well above what a subscription actually charges you for the same usage, and no ceiling number fixes that mismatch.

Calibration

Once two or more entries have both a recommendation and an actual, the panel wakes up: entries compared, match rate, escalations, downshifts, average tier drift, and a plain-language read. If three or more verdicts from the same tier escalated, it suggests an evidence-based threshold tune with the actual score numbers. Hook-tracked entries bring real dollars into this, so the drift readout is not estimate-vs-estimate, it is promise-vs-receipt.

Project structure

groundwork/
├── index.html                     # The whole web console. One file, no build step.
├── install.sh                     # Project or --global hook install
├── hooks/
│   └── dispatch-watch.mjs         # SessionEnd hook: transcript → real cost → log
├── .claude/
│   ├── settings.json              # Project-level hook registration
│   ├── commands/
│   │   └── groundwork.md          # /groundwork slash command
│   └── skills/
│       └── groundwork/
│           └── SKILL.md           # Conversational Groundwork skill
├── data/
│   ├── pricing.json               # Rates the hook uses (edit when prices move)
│   └── dispatch-log.json          # Your log (gitignored)
├── docs/
│   ├── HOW-TO-USE.md              # Day one, daily loops, reading calibration
│   ├── SETUP.md                   # Install, the loop, testing, uninstall
│   ├── ARCHITECTURE.md            # Log format, pairing logic, cost math
│   └── FAQ.md
├── examples/
│   └── dispatch-log.example.json  # What a paired log looks like
├── CONTRIBUTING.md · CHANGELOG.md · LICENSE (MIT)

Customizing

Everything meant to be edited sits at the top of the script in index.html: WEIGHTS (rubric), TIERS (bands and verdict copy), MODELS (lineup and default rates), PRESETS (your recurring build shapes), AUTOSCORE_MODEL. The hook's rates live in data/pricing.json. Theme choice is a click, saved per browser.

Privacy

No accounts, no tracking, no analytics, no server. The log lives in your browser's local storage and in a gitignored JSON file. The only network call in the system is the optional auto-score request, which goes browser-direct to Anthropic with your own key. API keys are held in memory unless you explicitly opt into local storage on that device.

Tech stack

Vanilla HTML/CSS/JS (one file, Google Fonts only) · Node 18+ for the hook (ships with Claude Code) · Claude Code hooks, slash commands, and skills · Space Grotesk + JetBrains Mono on black, five neon accents


Built by Olivia Keiter · part of building out loud · MIT licensed

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors