The sink already holds every project on the machine, mixed together, and nothing can separate them. "What did this repository cost this month" cannot be asked.
What is missing, exactly
A stored record carries its tool, its model, its moment, its turn identifier and its step. It carries no project identity. The readers build it from what each tool wrote about a session, and none of them writes a repository.
The run journal knows: session_start carries project_id and project_remote, resolved from the repository the hook fired in. It stops there. Nothing carries it across into the record the sink stores.
That is the whole gap — a fact already established, one hop from where it is needed.
Why it bites
The sink is machine-level by design: it lives under the user's config directory, not per repository, because a session's figures belong to the person and their machine rather than to whichever checkout they happened to be in. The consequence is that a report over any period silently mixes every repository worked on in that period.
Nothing is wrong with the figures. They simply answer a question nobody asked, and there is no way to ask the one people do.
Done when
- A stored record names the project the session ran in.
- A report can be asked for one project, and a breakdown by project reconciles to the period's total exactly.
- A record stored before this change reads as belonging to no known project, rather than being attributed to a guess.
- Two checkouts of the same repository are one project, or they are deliberately two and that is written down.
Worth deciding, not assuming
What identifies a project. project_id is a directory name today and project_remote a git remote; the first collides across machines, the second is absent for a repository with no remote. Whichever is chosen, a record must say which one it used — the same reason vendor_field exists on the identifier.
Not this
Reporting per person or per team (#656, #661), which needs an identity nothing records yet. This is one field that already exists, carried one hop further.
The sink already holds every project on the machine, mixed together, and nothing can separate them. "What did this repository cost this month" cannot be asked.
What is missing, exactly
A stored record carries its tool, its model, its moment, its turn identifier and its step. It carries no project identity. The readers build it from what each tool wrote about a session, and none of them writes a repository.
The run journal knows:
session_startcarriesproject_idandproject_remote, resolved from the repository the hook fired in. It stops there. Nothing carries it across into the record the sink stores.That is the whole gap — a fact already established, one hop from where it is needed.
Why it bites
The sink is machine-level by design: it lives under the user's config directory, not per repository, because a session's figures belong to the person and their machine rather than to whichever checkout they happened to be in. The consequence is that a report over any period silently mixes every repository worked on in that period.
Nothing is wrong with the figures. They simply answer a question nobody asked, and there is no way to ask the one people do.
Done when
Worth deciding, not assuming
What identifies a project.
project_idis a directory name today andproject_remotea git remote; the first collides across machines, the second is absent for a repository with no remote. Whichever is chosen, a record must say which one it used — the same reasonvendor_fieldexists on the identifier.Not this
Reporting per person or per team (#656, #661), which needs an identity nothing records yet. This is one field that already exists, carried one hop further.