Attribution: why delta has no owner yet
Measured 2026-09-03 Status blocking — every per-trader number depends on this
The seam
The whole design rests on three lines:
MECHANICAL the issued plan, resolved against the tape -> a property of the SETUP
REALISED what the account actually did -> a property of the ACCOUNT
TRADER DELTA realised - mechanical -> a property of a PERSON
Delta is a property of a person. No row in the ledger names the person.
What is actually there
ride_context.decided_by is free text:
rule:lab-fast 1,742 hand:evancooney@gmail.com 41
rule:runner 182 hand:api 31
rule:lab-ticks 51 hand:evan 26
rule:tick-scalper 46 unknown (reconstructed) 22
rule:junk-gate 24 ...
Roughly 2,050 machine to 67 human — and hand:evan and
hand:evancooney@gmail.com are the same person under two users rows:
id 1 evan owner (no email)
id 2 evancooney@gmail.com owner evancooney@gmail.com
id 3 143804e8-… member evancooney+55@gmail.com
id 6 74689488-… member mark@slowdesk.io
All four share the account agentic-907533723. No ride table carries a
user_id at all.
Why it is fatal rather than untidy
With one trader the ambiguity is invisible, because every delta is the same person's. With a desk it becomes an average over people, which describes nobody: one trader who over-manages and one who under-manages cancel to a clean zero, and the report says the desk is fine.
parseDecidedBy() in src/ledger.ts currently returns
{ kind, userId: null } — it can tell human from rule, but not which human.
Every ride scored today produces a delta with no owner.
The other half: no way to record a No
position_recommendations, 5,087 rows:
~50 accepted
0 rejected <- the state does not exist
3,375 hold, still "proposed" forever
1,199 expired as "superseded by a newer verdict"
There is no seen_at either. So when a trader holds through an exit-early
that would have saved a point, the ledger cannot say whether they overruled
the desk or never opened the page. Those are opposite diagnoses — a
judgment to examine versus a workflow bug — and coaching someone on the wrong
one costs their trust in the tool permanently.
Findings have no owner either
learning_findings is well shaped and working — category, headline,
metric_json, status, and live rows already carry low_power to hold back
thin claims. But its subjects are grade:B- and source:catalyst-scan:
properties of the system. With no user_id and no scope it cannot hold
"you cut winners early" at all.
What has to change, desk-side
- Merge the two Evan
usersrows, then adduser_idtopositions,manual_ordersand everyride_contextwriter. Backfill from thedecided_byprefix, which already encodeshand:vsrule:. - Add
seen_atand a terminalrejected(with a reason) toposition_recommendations, and stampseen_atwhen one renders. This is the cheapest of the changes and the most urgent — every day without it is a day of data that cannot be recovered afterwards. - Add
user_idand a scope tolearning_findings, so a finding can belong to a person as well as to the desk.
Recommendation on account structure: keep one account and separate by
user_id. Splitting accounts also splits caps, rails and reconciliation — a
much larger job, undertaken to solve what is really a reporting problem.