{"$k":["id","title","columns","rows"],"$r":[["memory-by-condition","Every condition, Claude Sonnet 5.5",{"$k":["key","label","unit"],"$r":[["condition","Memory","text"],["full","Full pass","text"],["functional","Hidden tests pass","text"],["code","Code-visible rules","text"],["structure","Folder-visible rules","text"],["tribal","Team knowledge","text"],["broken","Ran the stale test command","text"],["input","Median input tokens","tokens"],["wall","Median time (s)","seconds"],["hook","Hook blocks","count"]]},{"$k":["condition","full","functional","code","structure","tribal","broken","input","wall","hook"],"$r":[["No memory","9/15","12/15","57/60","21/21","6/15","12/15",78455,18,0],["/init CLAUDE.md","9/15","12/15","57/60","21/21","10/15","13/15",82262,19,0],["Curated, 11 lines","15/15","15/15","60/60","21/21","15/15","0/15",65045,21.9,0],["Raw notes, 60 lines","14/15","14/15","60/60","21/21","15/15","0/15",76963,26.8,0],["Dreamed notes","15/15","15/15","60/60","21/21","15/15","0/15",68218,27.2,0],["Handbook, 210 lines","15/15","15/15","60/60","21/21","15/15","0/15",85223,23.6,0],["Stop hook only","12/15","12/15","60/60","21/21","10/15","9/15",125674,27.3,5],["Curated + hook","15/15","15/15","60/60","21/21","15/15","0/15",69224,22,0]]}],["memory-by-condition-haiku","Every condition, Claude Haiku 4.5",{"$k":["key","label","unit"],"$r":[["condition","Memory","text"],["full","Full pass","text"],["functional","Hidden tests pass","text"],["code","Code-visible rules","text"],["structure","Folder-visible rules","text"],["tribal","Team knowledge","text"],["broken","Ran the stale test command","text"],["input","Median input tokens","tokens"],["wall","Median time (s)","seconds"],["hook","Hook blocks","count"]]},{"$k":["condition","full","functional","code","structure","tribal","broken","input","wall","hook"],"$r":[["No memory","2/10","6/10","40/40","12/14","0/10","10/10",301233,54.2,0],["/init CLAUDE.md","2/10","7/10","38/40","14/14","1/10","10/10",323519,52.9,0],["Curated, 11 lines","7/10","9/10","40/40","14/14","8/10","0/10",284212,51.7,0],["Raw notes, 60 lines","6/10","10/10","40/40","14/14","6/10","10/10",285263,51,0],["Dreamed notes","7/10","9/10","40/40","14/14","8/10","1/10",267405,51.8,0],["Handbook, 210 lines","3/10","10/10","40/40","14/14","3/10","0/10",313796,49.9,0],["Stop hook only","8/10","8/10","40/40","14/14","8/10","10/10",530935,68.5,10],["Curated + hook","9/10","9/10","40/40","14/14","10/10","0/10",340491,52.8,3]]}],["memory-raw-notes","The 56 raw notes, labelled by what a consolidation pass should do with each (paths in the test repository shown under tally/)",{"$k":["key","label","unit"],"$r":[["date","Saved","text"],["note","Note","text"],["fate","Should be","text"]]},{"$k":["date","note","fate"],"$r":[["2026-06-12","Project is `tally`, a small invoicing ledger for the billing service. Plain ESM, no dependencies.","kept"],["2026-06-12","Shah prefers small PRs with one change each.","kept"],["2026-06-14","Dev server for the billing service ran on port 3001 this afternoon.","removed: transient"],["2026-06-18","Run tests with `npm test`.","removed: stale"],["2026-06-20","Amounts are dollars as floats. Format them with `toFixed(2)`.","removed: stale"],["2026-06-20","Use 2-space indentation and single quotes.","kept"],["2026-06-22","Branch `feat/customers-v1` pushed; waiting for review.","removed: transient"],["2026-06-25","The time helper is `now()` in `tally/src/clock.js`.","removed: stale"],["2026-06-27","Shah is out on Friday; do not merge anything then.","removed: transient"],["2026-07-01","Customers live in `tally/src/customers.js`.","kept"],["2026-07-03","Throw `TallyError` with a code from `CODES` in `tally/src/errors.js`; the billing service maps codes to HTTP statuses.","kept"],["2026-07-03","Error codes are public API. Do not rename an existing code.","kept"],["2026-07-05","Prefer named exports.","kept"],["2026-07-08","Used jq to inspect the payment fixtures; worked fine.","removed: transient"],["2026-07-10","Do not use `console.log` in `tally/src/`; use `log()` from `tally/src/log.js`.","kept"],["2026-07-12","Staging database was reset today.","removed: transient"],["2026-07-14","Late fee is 2% of the unpaid balance.","removed: stale"],["2026-07-15","PR #212 (partial payments) merged.","removed: transient"],["2026-07-18","The report module is new; Shah wants it in the next release.","kept"],["2026-07-22","Shah wants a line under `## Unreleased` in CHANGELOG.md for every user-visible change.","kept"],["2026-07-22","Keep CHANGELOG entries to one line.","kept"],["2026-07-25","`slugify()` is used for export file names.","kept"],["2026-07-29","Remember: no `console.log` in src, use the log helper.","merged: repeat"],["2026-08-01","Released 1.3.0 (monthly report, partial payments).","removed: transient"],["2026-08-03","CI was slow today because of a runner outage.","removed: transient"],["2026-08-05","Incident: someone edited migration 0002 and production schemas drifted. Migrations are append-only now: add a new `tally/migrations/NNNN_<name>.json`, never edit an old one.","kept"],["2026-08-07","Store loads the schema from `tally/migrations/*.json` in file-name order.","kept"],["2026-08-09","Shah prefers early returns over nested ifs.","kept"],["2026-08-12","Migrated all money to integer cents (`amountCents`). Parse input with `parseAmount()`, print with `formatCents()`. No floats for money.","kept"],["2026-08-12","`toFixed` caused rounding bugs in the old float code.","kept"],["2026-08-14","Reminder: throw TallyError, not Error.","merged: repeat"],["2026-08-16","Coffee machine on floor 3 is broken (Shah mentioned it).","removed: transient"],["2026-08-19","CI flaky again; reran twice.","removed: transient"],["2026-08-22","Payment amounts must not exceed the open balance (`E_OVERPAYMENT`).","kept"],["2026-08-24","Branch `fix/report-totals` pushed.","removed: transient"],["2026-08-27","Integer cents everywhere. Do not divide by 100 except when formatting.","merged: repeat"],["2026-08-30","Renamed the time helper: use `nowIso()` from `tally/src/time.js`. Tests inject a clock with `setClock()`. Do not call `new Date()` or `Date.now()` in src.","kept"],["2026-09-02","Throw TallyError with a CODES entry; add a new code when none fits.","kept"],["2026-09-04","Shah likes tests next to each feature change.","kept"],["2026-09-06","Looked at Stripe's refund API for ideas; not needed yet.","removed: transient"],["2026-09-08","Port 3001 is taken by another service now; billing dev server moved to 3002.","removed: transient"],["2026-09-10","Lost a fix because I edited `tally/src/report.gen.js` directly; it is generated. Edit `tally/templates/report.tmpl.js` and run `node tally/scripts/gen-report.mjs`.","kept"],["2026-09-11","The report template uses a `__CURRENCY__` placeholder.","kept"],["2026-09-13","Shah asked for clearer error messages in validation.","kept"],["2026-09-15","Finance changed the late fee to 1.25% of the unpaid balance, effective now. Round half up to the cent.","kept"],["2026-09-16","Email validation added to customers.","kept"],["2026-09-18","Reminder: changelog line for every user-visible change.","merged: repeat"],["2026-09-20","Released 1.4.0 (integer cents, email validation).","removed: transient"],["2026-09-21","`node --test test/` fails on Node 25 (it treats the folder as a file). Run `node --test` with no path. `npm test` uses the broken form.","kept"],["2026-09-23","Prefer `Object.freeze` for constant maps.","kept"],["2026-09-24","Do not edit migration files that already exist.","merged: repeat"],["2026-09-26","Shah reviews PRs in the morning.","kept"],["2026-09-28","Use the log helper for audit events (payments, refunds).","kept"],["2026-09-30","The billing service reads `CODES` at start-up; new codes need no other change.","kept"],["2026-10-01","Staging is on the new cluster.","removed: transient"],["2026-10-02","Generated file again: never hand-edit `tally/src/report.gen.js`.","merged: repeat"]]}],["memory-by-task","Full passes per task (Claude Sonnet 5.5, of 3)",{"$k":["key","label","unit"],"$r":[["task","Task","text"],["none","No memory","count"],["init","/init CLAUDE.md","count"],["curated","Curated, 11 lines","count"],["raw","Raw notes, 60 lines","count"],["dreamed","Dreamed notes","count"],["bloated","Handbook, 210 lines","count"],["hook","Stop hook only","count"],["curated-hook","Curated + hook","count"]]},{"$k":["task","none","init","curated","raw","dreamed","bloated","hook","curated-hook"],"$r":[["Refunds",3,3,3,2,3,3,3,3],["Report decimals",0,0,3,3,3,3,3,3],["Customer phone",3,3,3,3,3,3,3,3],["Late fee",0,0,3,3,3,3,0,3],["Slugify (control)",3,3,3,3,3,3,3,3]]}]]}