Development record
A development session's token cost is measured, and set against the size class its spec predicted
Typed links: related_issues iss-2608301744251874 (token metering), iss-2608301856299268 (size classes) and iss-2608220150157508 (token accounting in the history store), the three records this draft plans as one.
Press Release
Every development session records what it actually cost in tokens, and every spec says in advance which size class it expects to fall in, so a prediction can be checked against what the work became. When a transcript is captured into the history store, abcd keeps the per-message token counts and the model id the transcript itself carries, locally and as metadata only; a report sums them per session, per spec and per repository; and a spec declares a size class before it is built that the report sets beside the measured cost. "We used to guess a flat cost per task and never learned whether the guess was right," said Maya, an autonomous-development practitioner. "Now the size we predicted sits next to what the work actually took, and a wrong class shows up in the next report."
Why This Matters
Nothing in the record measures what a development act cost. The superseded
itd-29 estimated token cost forward from a flat per-task constant, and the
draft itd-98 names token cost only inside one experiment's report, so an
estimate can be wrong indefinitely without anything noticing. The one tally the
2026-08-30 cost calibration made had to be assembled by hand from one session's
notifications, and it was lost with that session. The parked notes
(.abcd/development/research/notes/2026-08-30-development-token-metering-gap.md
and 2026-08-30-spec-size-classification-gap.md) name the pair: a size class
predicts, metering measures, and neither is worth much alone. The product
thinker ruled on 2026-09-29 to plan metering and size classes as one intent
(ruling J3) and that session token accounting in the history store joins it
(ruling J4).
What's In Scope
- Measurement at capture: when the history store captures a transcript, it keeps the per-message usage the transcript carries (input, output, cache read, cache write) and the model id, aggregated with a timestamp in the stored transcript's metadata. Metadata only, never bodies (brief invariant 15's existing carve-out for metadata).
- A report that sums the counts per session, per spec and per repository, local-only: never committed, never rendered on any site.
- Size classes a spec declares before it is built, checked against the measured cost in the same report. The notes' finding binds the scheme: depth does not track volume, and the roadmap forbids time estimates, so a class is not denominated in days.
- Prices on explicit ask only: a user-level price table; a report meeting a model with no recorded price offers an explicit refresh and never fetches on its own (adr-38). Money figures are labelled as API-equivalent estimates.
What's Out of Scope
- Budget enforcement: refusing to start a run on a budget is itd-29's superseded ground and is not revived here.
- Anything that leaves the machine.
Mechanism
Prompted (the claim-recording gradient): why the authors expect this to work, as a falsifiable "we expect X because Y" — not the outcome restated. Replace this line with the claim, or with the exact token
None stated.alone on its line to record the claim as considered and declined.
Scope Conditions
Required (the claim-recording gradient): the population, platform, scale, or assumptions this claim holds under, one per top-level bullet —
abcd intent planstamps each with a persistent identity. Replace this line with those bullets, or with the exact tokenNone stated.alone on its line.
Acceptance Criteria
Seeded by the run from the three records and the ruling, unconfirmed: the planning interview walks each one.
- Given a transcript whose messages carry usage fields, when the history store captures it, then the stored metadata carries the summed input, output, cache-read and cache-write counts and the model id, and no message body is added to the metadata.
- Given a transcript that carries no usage fields, when it is captured, then its metadata records the counts as unmeasured rather than zero.
- Given captured sessions for one repository, when the report runs, then it sums the counts per session, per spec and per repository, and writes nothing.
- Given a spec that declares a size class, when the report covers the sessions that built it, then it shows the declared class beside the measured cost.
- Given a report meeting a model with no recorded price, when it runs, then it shows token counts without a money figure, names the refresh verb, and performs no network fetch.
SOTA
Surveyed on 2026-10-23; sources, evidence tiers and the local fit risks are in the models, prompts and measurement SOTA note; the gap itself is in the token-metering and size-class notes.
- The transcript already carries the counts. This repository's stream
fixture (
internal/core/runner/testdata/claude-stream-2.1.302.jsonl) shows per-messageinput_tokens, cache creation split by lifetime, cache read, output, thinking tokens andmodel, with a result record carrying per-modelcostUSDatcostBasis: "list"and sub-agent statistics. - The host's own dollar figure is local, at list price, and an estimate:
/usagecomputes it "from token counts at list price", says it is "an estimate", and that for subscribers "the session cost figure isn't relevant for billing" (Claude Code cost docs). "API-equivalent estimate" is the host's own framing. - Two conventions disagree on what "input" is. OpenTelemetry's
gen_ai.usage.input_tokens"SHOULD include ... cached tokens"; the host's exportedtype="input""excludes tokens read from or written to the prompt cache" (GenAI attribute registry; Claude Code monitoring docs). Keep the four raw counts and derive totals in the report, naming the convention. - Community meters price from one community table. ccusage reads the
host's local data, tracks cache tokens separately, prices from LiteLLM's
model_prices_and_context_window.json(a "community maintained list" at a stable raw URL) and runs offline on cached prices, at the cost that "you will need to upgrade to get updated pricing" (ccusage; LiteLLM docs). - A price is four rates and modifiers: base input, 5-minute cache write
(1.25×), 1-hour write (2×), cache read (0.1×, 0.025× or 0.05× on the newest
models), output; batch 50 % off; data residency 1.1× (vendor pricing page).
The user-level table needs that shape per model, and two cases a flat
four-rate row cannot hold: the long-context tier (one model pays higher
prices on a prompt over 100,000 tokens) and the fast-mode premium (the
stream records
speed); the table either carries them or the report marks such a session as priced at base rates. - Relative size estimates are weak and overconfident. Story points correlated strongly with development time in 7 % of 37 projects and estimators misestimated in 78 % of 37,440 stories (Tawosi, Moussa and Sarro, ESEM 2022); relative estimates were less accurate, slower to produce and not developer-independent than hour estimates (Jørgensen and Escott, 2022). A class is a distribution checked by hit rate, not a point.
- Task difficulty is predictable from task features, cost is not (agent psychometrics: IRT plus issue, repository, solution and test features predicts task-level success; no tokens or dollars; Ge et al., 2026). The corpus's own variable, review rounds, is the candidate denomination.
Path 2: native metering at capture (four raw counts, model id, sub-agent
split, aggregated into metadata), a report that derives totals and names its
convention, and a user-level price table in LiteLLM's per-model field shape
so a refresh can import that community file on explicit ask and a row can be
hand-edited; size classes denominated in expected review rounds, declared
before the build and reported as a hit rate per class beside measured tokens
and rounds; attribution by capture stamp (the stream's session id; an agent
name exists only as agent.name in the host's telemetry export, which the
history store does not read) with the branch as fallback; itd-98 consumes this rather than counting
its own. No dependency; the LiteLLM file is a format, not a library. The
independent fit-challenge runs at plan time.
Open Questions
- (SOTA 2026-10-23) Whether the report shows cached tokens inside the input total (the OpenTelemetry convention) or beside it (the host's), given that the two disagree and both readers exist.
- (SOTA 2026-10-23) Whether the price table's refresh imports LiteLLM's community file wholesale, on explicit ask, or only the rows for models the store has seen.
- What a size class measures: the notes say depth does not track volume; is the class about the number of ways the work can be quietly wrong, the review rounds it takes, or tokens alone?
- How a session is attributed to a spec: the branch, the run log's lane record, or a stamp at capture.
- Where the price table lives in the user-level home, and its refresh verb.
- Whether itd-98's comparison report consumes this measurement rather than measuring on its own.
Audit Notes
Empty. Populated by intent-auditor when intent moves to shipped/.
Frontmatter
| id | itd-2609292107351737 |
|---|---|
| type | intent |
| lifecycle | drafts |
| severity | minor |
.abcd/development/intents/drafts/itd-2609292107351737-every-development-session-records-what.md
open on GitHub ↗ · commit history ↗
Referenced by8
- iss-2608220150157508Local-only token-usage accounting in the history store: at history capture time, extract per-message usage (input, output, cache-read, cache-write) and the model id from the transcript's own usage fields, store the aggregate with a timestamp in the stored transcript's metadata, and offer a report summing per session and per repo. Pricing is a user-level table (~/.abcd), recorded on explicit ask only: when a report meets a model with no recorded pricing it offers an explicit refresh verb in the docs-cite-refresh mould — never an implicit fetch (adr-38). Estimates are labelled API-equivalent (subscription seats do not bill per token; cache tiers price differently). Local-only by construction: never committed, never rendered on any siterelated
- iss-2608301744251874development token metering is parked as a note and owes a file or reject decision at the next phase planningrelated
- iss-2608301856299268a size classification for specs and tasks is parked as a note and owes a design and filing decision in a future sessionrelated
- iss-2610262032595554itd-2609292107351737 has transcripts captured into the history store; ahoy says history/ is the registry only and holds no transcriptsrelated
- iss-2610262036076395The token-cost draft adds per-session token accounting at capture; 11-history already reports per-session token usage in reconstruct telemetry, with its own counting rule.related
- iss-2610262037171531itd-2609292107351737 treats refusing to start a run on a budget as abandoned ground from a superseded intent; the build ships a budget check that refuses a run whose estimate is over quota.related
- iss-2610262043179497itd-2609292107351737 cites 'the roadmap' as an authority after itd-2609211913453478 retired the wordrelated
- iss-2610262043347672itd-2609292107351737 measures per-session token cost at capture; itd-2609091718595846 already ships per-session token telemetryrelated
mentions8
- adr-38Implicit checks are disk-only — the network answers only an explicit ask
- dcn-26092900000000112026-09-29 — The product thinker answered the twenty-six Group J rulings (plan or close), J1 to J26 (recorded by lane recGroupJ of autonomous run A, for orchestrator abcd-fc). The answers are kept verbatim in the local-tier file `.abcd/.work.local/scratch/reports/rulings-answered-2609-29.md`, section "Group J", dated 2026-09-29, and are restated here because that file is not committed. PLAN: the installer script becomes a minimal starter with an ownership-checked hand-over, planned as a new intent with its planning interview owed (J2, iss-377, draft itd-2609292106557115); token metering and size classes are planned as one intent (J3, iss-2608301744251874 and iss-2608301856299268), and session token accounting in the history store joins that metering intent (J4, iss-2608220150157508; all three in draft itd-2609292107351737); the sources tooling moves into abcd's core with ingest and consult as abcd verbs (J5, iss-27, whose corpus half itd-76 already delivered), and the backfill of the placeholder source entries is part of that intent (J6, iss-55; both in draft itd-2609292108089653); the grill hands off to an installed external interview skill and falls back to its own (J11, iss-165, draft itd-2609292108373494); an opt-in local-model prompt sanitiser is planned (J14, iss-2608261543489261, draft itd-2609292109005937); decision-to-transcript links are planned, with the anchor kind and the link's home settled in the planning interview owed for draft itd-171 (J16, iss-2608290819228175); the dredge synthesis, its write-ups as their own memory source class, is planned together with draft itd-25, whose planning interview is owed (J19, iss-2609211905340006); one provenance register across ingest and vendoring is planned together with draft itd-26, whose planning interview is owed (J20, iss-2609211905346507); release retention, keeping the newest release per version line, is automated by planning draft itd-70 (J21, iss-282); a rules-backend seam with an opt-in CARL adapter is planned, the native loader staying the default (J22, iss-64, draft itd-2609292109214516); core-owned managed pre-commit gates are planned with draft itd-62 (J23, iss-84); a behavioural end-to-end scenario suite per verb family is planned (J24, iss-48, draft itd-2609292109475690). Every draft stays in drafts/ until a person plans it, and each source issue links its draft and names that planning interview in its deferral. BUILD: the teaching plane, the rules-loader safety domain generated from the hazard registry, is built as a lane, the registry being the single source (J10, iss-151 and itd-103; a code lane owns it). RULED DETAILS: `source_kind` carries both, as two separate labels, one for the tool and one for the route (J13, iss-2608230752354928); the prompt router's removal signal is the full list of active domains every time, a domain's absence meaning it has stopped (J15, iss-2608261550580260); setup offers an outside AI service (for example OpenRouter) at install, skippable, once the API adapter ships (J18, iss-2609081951416843, which waits on the API adapter); the salvage-hook timeout is 120 seconds, the wait must show a counter or a message while it runs and never stall silently, and every per-event timeout is pinned in a test (J25, iss-323). J13, J15 and J25 are carried by code lanes. CLOSE: the quick-tunnel preview protocol is closed unless the need recurs (J26, iss-2608230617385431, wontfix with that reason). PARKED ON A TRIGGER: agent payment protocols are kept under watch, not now, revisited as the protocols mature (J8, iss-138); the findings-only skill waits for the skill format to be versioned and stewarded (J9, iss-139); the disposition worksheet as an intent and a site page waits until after the first study (J17, iss-2609021815529020). DECIDE LATER: the Homebrew tap stays parked (J1, iss-380); pluggable search back ends (J7, iss-26); forge-backed record numbering (J12, iss-2608210737264758).
- dcn-26092900000000202026-09-29 — The product thinker answered the twenty-six Group J rulings (plan or close), J1 to J26 (recorded by lane recGroupJ of autonomous run A, for orchestrator abcd-fc). The answers are kept verbatim in the local-tier file `.abcd/.work.local/scratch/reports/rulings-answered-2609-29.md`, section "Group J", dated 2026-09-29, and are restated here because that file is not committed. PLAN: the installer script becomes a minimal starter with an ownership-checked hand-over, planned as a new intent with its planning interview owed (J2, iss-377, draft itd-2609292106557115); token metering and size classes are planned as one intent (J3, iss-2608301744251874 and iss-2608301856299268), and session token accounting in the history store joins that metering intent (J4, iss-2608220150157508; all three in draft itd-2609292107351737); the sources tooling moves into abcd's core with ingest and consult as abcd verbs (J5, iss-27, whose corpus half itd-76 already delivered), and the backfill of the placeholder source entries is part of that intent (J6, iss-55; both in draft itd-2609292108089653); the grill hands off to an installed external interview skill and falls back to its own (J11, iss-165, draft itd-2609292108373494); an opt-in local-model prompt sanitiser is planned (J14, iss-2608261543489261, draft itd-2609292109005937); decision-to-transcript links are planned, with the anchor kind and the link's home settled in the planning interview owed for draft itd-171 (J16, iss-2608290819228175); the dredge synthesis, its write-ups as their own memory source class, is planned together with draft itd-25, whose planning interview is owed (J19, iss-2609211905340006); one provenance register across ingest and vendoring is planned together with draft itd-26, whose planning interview is owed (J20, iss-2609211905346507); release retention, keeping the newest release per version line, is automated by planning draft itd-70 (J21, iss-282); a rules-backend seam with an opt-in CARL adapter is planned, the native loader staying the default (J22, iss-64, draft itd-2609292109214516); core-owned managed pre-commit gates are planned with draft itd-62 (J23, iss-84); a behavioural end-to-end scenario suite per verb family is planned (J24, iss-48, draft itd-2609292109475690). Every draft stays in drafts/ until a person plans it, and each source issue links its draft and names that planning interview in its deferral. BUILD: the teaching plane, the rules-loader safety domain generated from the hazard registry, is built as a lane, the registry being the single source (J10, iss-151 and itd-103; a code lane owns it). RULED DETAILS: `source_kind` carries both, as two separate labels, one for the tool and one for the route (J13, iss-2608230752354928); the prompt router's removal signal is the full list of active domains every time, a domain's absence meaning it has stopped (J15, iss-2608261550580260); setup offers an outside AI service (for example OpenRouter) at install, skippable, once the API adapter ships (J18, iss-2609081951416843, which waits on the API adapter); the salvage-hook timeout is 120 seconds, the wait must show a counter or a message while it runs and never stall silently, and every per-event timeout is pinned in a test (J25, iss-323). J13, J15 and J25 are carried by code lanes. CLOSE: the quick-tunnel preview protocol is closed unless the need recurs (J26, iss-2608230617385431, wontfix with that reason). PARKED ON A TRIGGER: agent payment protocols are kept under watch, not now, revisited as the protocols mature (J8, iss-138); the findings-only skill waits for the skill format to be versioned and stewarded (J9, iss-139); the disposition worksheet as an intent and a site page waits until after the first study (J17, iss-2609021815529020). DECIDE LATER: the Homebrew tap stays parked (J1, iss-380); pluggable search back ends (J7, iss-26); forge-backed record numbering (J12, iss-2608210737264758).
- iss-2610301943552138abcd records nothing about what each question it puts to a person costs in tokens. A question passes through the question-writing agent, which may draft and check it several times before it passes (up to five checks to a part under itd-2610230756259215), so one question can cost far more than the text the person sees, and no record says how much: a single drafter run in an interview on 2026-10-30 used between 58 and 73 thousand tokens, and one on 2026-10-23 used about 174 thousand while counting rows by hand. Without the count, nobody can tell whether the writer's loop is worth its cost, compare drafting strategies, or see what an interview costs as a whole. The product thinker asked for the tokens of each question to be recorded, as part of a wider account of what abcd's work costs in tokens (a tokenomics intent), whose nearest home is the draft itd-2609292107351737, which measures a development session's token cost against its spec's predicted size class.
- itd-29Domain Experts Run A Spec Autonomously And Recover From Anything Without Touching Git
- itd-98Solo vs. Duo Is Measured, Not Debated
- itd-2610161733316518One task done across a model matrix, re-runnably
- itd-2611011325403127Every landing shows what it cost and the next run's estimate