Skip to content

trail note: count a learning's cost from where its work began - #620

Merged
anirudhkumar-nanonets merged 1 commit into
mainfrom
feat/learning-cost-from-work
Oct 15, 2026
Merged

anirudhkumar-nanonets merged 1 commit into
mainfrom
feat/learning-cost-from-work

Conversation

@anirudhkumar-nanonets

Copy link
Copy Markdown
Collaborator

Moves: none of the project's metrics directly. It fixes the number every credit line shows ("saved ~958k tokens and ~129 min"), which the 80k rule uses to choose between tokens and "3x faster to a PR". learnings_committed is the closest metric (PostHog query in daily/project.md). I didn't check its value, because this session has no Metabase access.

Why

trail note charges a learning for the whole session since the last note. In a long session that did several things, the learning gets the cost of all of them. One learning saved today, about committing the hook wiring, claimed "129 min and ~958k tokens". That stretch also covered a Slack search, two PR merges and a demo setup, none of which it records.

What changes

A learning's cost now counts from the turn where its work first came up:

  • What it's about: the files it names, plus anything it puts in backticks that's specific enough to date the work, such as a path, a file, or an identifier like dropHtmlComments or repo_id. Phrases and plain words like trail init or publish are skipped, because they come up in any session about the product.
  • Where that work began: the prompt of the first turn whose prompt or tool calls mention one of those. The trail note call being saved never counts, since it names them all.
  • When nothing matches: only the last 30 active minutes count, never the whole session.
  • What stays the same: --minutes and --tokens still win. The files a note goes to are still taken from everything edited since the last note.

Before and after

I re-ran the cost of every trail note / graft note in my last 21 days of local Claude Code transcripts, old way and new way, with a script that isn't in the PR. These are 55 notes from one person's machine, so treat them as an example, not a measurement:

minutes tokens
old 1,787 17.5M
new 872 8.75M

Notes from short, focused sessions don't change. The big drops are in long mixed sessions:

  • Overlap false alarms: 121 min / 948k became 30 min / 134k.
  • A retry-default check: 101 min / 862k became 30 min / 109k.
  • Committing the hook wiring: 129 min / 958k became 117 min / 806k. Its files came up early in that session.

The number is still labelled as an estimate wherever it's shown.

Tests

  • New in trail-notes:
    • which terms a note is about
    • the cost starting at the turn that first names its file, with the earlier hour of other work and the in-flight note call both excluded
    • the 30-minute cap when nothing matches
  • Existing cost tests are unchanged and pass: without terms, the whole stretch counts as before.
  • Full suite on my Mac: 1,425 pass, 3 fail, 1 skipped. The 3 are the graft-to-trail tests that fail on main here too, because a global trail is installed for a demo.

🤖 Generated with Claude Code

@trailhq-graft

trailhq-graft Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

🌱 graft blast radius

Nothing outside this diff depends on it. 2 areas changed; no indexed dependents at depth 2.
Tests: no test reaches Note Command; 1 area updated its tests.
Tag: @shhdwi — Note Command

Who knows this code — 1 person across 2 areas
Area Who knows it
Note Command · changed @shhdwi — 25 commits, last yesterday
Session Cost Tracking · changed only you — nobody else has touched these files

Ownership is git history over each area's own files, weighted towards recent work (120-day half-life). Merge commits and bots are dropped, and you are dropped from your own PR. A name with no @ has no GitHub handle in its commit email — tag them by hand, or add a .mailmap entry. A suggestion from history, not a CODEOWNERS rule.

Test signal per changed area — 1 ✓ · 1 ✗

Reached = a node under a test path has a resolved edge into the changed symbol. It undercounts anything called indirectly — through a CLI, a spawned process or a dynamic import — so read a low ratio as “look here”, never as a coverage gate.

  • ✓ Session Cost Tracking — 2 of 7 reached · 1 test file changed here: test/trail-notes.test.ts
    • not reached: firstMention, promptText, specific, lastActive, currentSessionCost
  • ✗ Note Command — 0 of 1 reached · no test file reaches it
    • not reached: runNoteCommand

graft blast · origin/main...HEAD · depth 2 · 3 changed files

Open the interactive graph → — click an area to see its dependent symbols at file:line.

github-actions Bot added a commit that referenced this pull request Oct 15, 2026
@anirudhkumar-nanonets
anirudhkumar-nanonets merged commit 8b23184 into main Oct 15, 2026
8 checks passed
github-actions Bot added a commit that referenced this pull request Oct 15, 2026
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