Skip to content

fix(insights): the estimate's measured word cost (M19c) - #40

Open
jgrodziski wants to merge 4 commits into
feat/m19c-glossary-pagefrom
feat/m19c-estimate-measured
Open

jgrodziski wants to merge 4 commits into
feat/m19c-glossary-pagefrom
feat/m19c-estimate-measured

Conversation

@jgrodziski

Copy link
Copy Markdown
Contributor

Sixth step of milestone M19c in PLAN.md §20 (word cloud / glossary, #6). Stacked on #39 (itself on #38, #37, #36 and #35): this PR's diff is the four commits after #39.

--estimate now prices words with figures measured on a live run, not the guesses §20.3 started with. Spring PetClinic replaces Broadleaf as the test corpus (your decision): small enough to read every answer, and cheap to run live.

The run

codegraph explain on Spring PetClinic (spring-projects/spring-petclinic at 500158f, src/main/java: 30 files, 451 entities), prompt 2, openai/gpt-5.6-luna, --concurrency 2 --max-tokens 6000:

  • 139 units: 106 calls, 33 templated, 0 failures, 12 min 56 s;
  • 228 177 prompt + 96 356 completion tokens, $0.1343;
  • --estimate had said 66 570 completion tokens: 31% short.

The store and its side-car are kept beside the model in ~/spring-petclinic/, as paid records are.

The fit

Each call's prompt was rebuilt with the planner (contextPackFor + renderPrompts, over the run's own records), so the words and glossary entries it asked for are exactly the run's. The rebuilt estimates sum to the run's own estimate, token for token. Each call's measured completion tokens (reasoning included, since they are billed) were then fitted on one figure per block per level, one per word asked and one per glossary entry asked:

was fitted now
operation block 450 466 470
type block 650 534 530
module block 900 527 530
per word 30 121 120
per glossary entry 40 123 125
  • Per call, r² 0.81 with the new figures, 0.13 with the old.
  • Out of sample: fitted on one half of the calls, the figures predict the other half's total within −7% and +15% (±6% leaving the five module calls out). The old figures missed by −29% and −33%.
  • Why a word costs ~120 tokens: a word entry's own JSON is ~50 tokens; the rest is the reasoning that goes with it.
  • Cost per word, at this run's prices (fitted from the records' own costs: $0.067/M in, $1.256/M out): about $0.00015.
  • The Java fixture's --estimate now says 52 900 completion tokens (was 41 670).

Worth a look in review:

  • The glossary figure is weak. It rests on PetClinic's five module calls, and one half-sample fits 342 rather than 123. A corpus with more modules should refit it. The comment on the constant says so.
  • The figures are one model's, reasoning included. The estimate line now names the model: … plus 120 per word and 125 per glossary entry asked to define (gpt-5.6-luna, reasoning included).
  • The input side is unchanged, and measured 15% under: 7.9% because a cold estimate cannot quote explanations no run has written yet, 6.3% because this tokenizer packs 3.76 characters per token, not 4. It is recorded in §20.3, not fixed here.
  • The tests stop restating 450/650/900. run.test.ts and explain.test.ts multiplied the old figures by hand. They now use the exported constants, so they check the formula (the CLI test still recounts the words and entries from the prompts a run sends) and a future refit touches no test.
  • A test fix outside the estimate, in its own commit. explain usage errors … without an API key runs explain through the real seam, which reads the process environment. With OPENROUTER_API_KEY in the shell, it failed at the no-terminal confirmation instead of the missing-key error. It now clears the four provider variables for its duration (vi.stubEnv). No call could have gone out: without a terminal and without --yes the run stops before the first one.

Docs

  • docs/insights.md (IN-6) and the website's Explaining bottom-up: the figures and where they were measured.
  • The how-to Estimate the cost, the explain tutorial and Discover → meaning: the fixture's --estimate output reprinted as it now reads.
  • PLAN §20.3: a "Measured" paragraph after the Cost estimate it replaces. §20.4's estimate item: the measurement is in; the live run on the Java fixture is still owed.

Verification

  • Gate.
  • Tests: insights 158 (+1 skipped), cli 1,037, core 544, analyzer 614, vocabulary 345, viz 143, navigator-ui 114, city 94, extractor-typescript 66, scm 56, navigator 40, llm 34. All green, except analyzer's scale.test.ts, which timed out at 5 s under the full parallel run and passes alone (the known flake; the analyzer is untouched).
  • The no-key test passes both with the provider variables set in the shell and with them unset.

What the run also showed (not addressed here)

  • Words asked but not answered are silent. Coverage: operations 97%, types 92%, modules 40% (a module's own package word).
  • A module is asked to reconcile a word no type defined. Pet skipped birth, and the owner module paid for an "ambiguous: undefined term" entry.
  • Polysemy is flagged on near-synonyms, 16 of 52 entries, and twice with a single identical sense (owners, or).
  • Function words in the shared technical list are asked to be defined (or).
  • vocabulary --drift-insights names candidates for the technical list: form, page, redirect, paginated, cache, binder, pageable, views, formatter, interceptor, resolver.

Still owed for M19c:

  • docs/vocabulary.md and the README.
  • The live run on the Java fixture.
  • §20.4's definition of done restated on PetClinic.

Part of #6.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PKCVgyop39vhNa45r7zM8w

jgrodziski and others added 4 commits October 29, 2026 22:42
The test runs `explain` through the real seam, which reads the process
environment. With OPENROUTER_API_KEY exported in the developer's shell
the run found a key, stopped at the no-terminal confirmation instead of
the missing-key error, and the test failed. It now clears the four
provider variables for its own duration (vi.stubEnv), as childEnv
already strips NO_COLOR from a spawned CLI.

No call could have gone out: without a terminal and without --yes the
run stops before the first call.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01PKCVgyop39vhNa45r7zM8w
The per-word and per-entry figures were PLAN §20.3's guesses (30 and
40) and the block figures came from prompt 1. A live prompt-2 run of
gpt-5.6-luna over Spring PetClinic (106 calls, 96 356 completion
tokens, reasoning included) measured 31% more output than --estimate
said.

Each call's prompt was rebuilt with the planner (contextPackFor +
renderPrompts over the run's records; the rebuilt estimates sum to the
run's, token for token) and its completion tokens fitted on what it
asked: 466 / 534 / 527 per operation / type / module block, 121 per
word, 123 per glossary entry (r² 0.81 per call, against 0.13). Rounded:
470 / 530 / 530, 120 and 125. Fitted on half the calls, the figures
predict the other half's total within -7% and +15%; the old ones missed
by -29% and -33%. The glossary figure rests on five module calls.

The estimate line now says the figures were measured on a live run, for
which model, with reasoning counted. The tests that multiplied 450/650/
900 by hand use the exported constants, so they keep checking the
formula, not restating the measurement.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01PKCVgyop39vhNa45r7zM8w
docs/insights.md (IN-6) and the explanation page state the refitted
figures and where they were measured. The how-to, the tutorial and the
discover page reprint the Java fixture's --estimate as it now reads:
52 900 output tokens (was 41 670), $0.0432 at $0.10/$0.60 (was $0.0365).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01PKCVgyop39vhNa45r7zM8w
§20.3's Cost paragraph keeps its estimate and gains the measurement that
replaces it: the live PetClinic run (Broadleaf's place as the test
corpus, by the user's decision), the fit, its out-of-sample check, the
caveat on the glossary figure, and the input gap left as it is (7.9%
from explanations a cold estimate cannot quote, 6.3% from a tokenizer at
3.76 characters per token). §20.4's estimate item: the measurement is
in; the live run on the Java fixture is still owed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01PKCVgyop39vhNa45r7zM8w
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
codegraph 60b323f Commit Preview URL

Branch Preview URL
Oct 29 2026, 10:44 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant