{
 "kind": "agent-memory-dreams",
 "recordedAt": "2026-10-06",
 "note": "Three independent dreaming passes over the raw notes (Claude Sonnet, no tools, one call each). dream-1 is the dreamed condition, declared before any agent session.",
 "scores": {
  "dream-1": {
   "lines": 41,
   "chars": 2403,
   "kept": {
    "cents": true,
    "parseFormat": true,
    "tallyError": true,
    "nowIso": true,
    "logHelper": true,
    "migrationsAppendOnly": true,
    "generated": true,
    "changelog": true,
    "lateFee125": true,
    "testCommand": true
   },
   "keptCount": 10,
   "keptOf": 10,
   "stale": {
    "lateFee2": false,
    "floatDollars": false,
    "clockJs": false,
    "npmTest": false,
    "port3001": false
   },
   "staleCount": 0,
   "staleOf": 5,
   "transient": {
    "coffee": false,
    "staging": false,
    "ci": false,
    "branches": false,
    "outFriday": false,
    "jq": false,
    "stripe": false,
    "pr212": false,
    "devPort": true
   },
   "transientCount": 1,
   "transientOf": 9
  },
  "dream-2": {
   "lines": 40,
   "chars": 2604,
   "kept": {
    "cents": true,
    "parseFormat": true,
    "tallyError": true,
    "nowIso": true,
    "logHelper": true,
    "migrationsAppendOnly": true,
    "generated": true,
    "changelog": true,
    "lateFee125": true,
    "testCommand": true
   },
   "keptCount": 10,
   "keptOf": 10,
   "stale": {
    "lateFee2": false,
    "floatDollars": false,
    "clockJs": false,
    "npmTest": false,
    "port3001": false
   },
   "staleCount": 0,
   "staleOf": 5,
   "transient": {
    "coffee": false,
    "staging": false,
    "ci": false,
    "branches": false,
    "outFriday": false,
    "jq": false,
    "stripe": false,
    "pr212": false,
    "devPort": true
   },
   "transientCount": 1,
   "transientOf": 9
  },
  "dream-3": {
   "lines": 41,
   "chars": 2423,
   "kept": {
    "cents": true,
    "parseFormat": true,
    "tallyError": true,
    "nowIso": true,
    "logHelper": true,
    "migrationsAppendOnly": true,
    "generated": true,
    "changelog": true,
    "lateFee125": true,
    "testCommand": true
   },
   "keptCount": 10,
   "keptOf": 10,
   "stale": {
    "lateFee2": false,
    "floatDollars": false,
    "clockJs": false,
    "npmTest": false,
    "port3001": false
   },
   "staleCount": 0,
   "staleOf": 5,
   "transient": {
    "coffee": false,
    "staging": false,
    "ci": false,
    "branches": false,
    "outFriday": false,
    "jq": false,
    "stripe": false,
    "pr212": false,
    "devPort": true
   },
   "transientCount": 1,
   "transientOf": 9
  },
  "memory:raw": {
   "lines": 58,
   "chars": 4332,
   "kept": {
    "cents": true,
    "parseFormat": true,
    "tallyError": true,
    "nowIso": true,
    "logHelper": true,
    "migrationsAppendOnly": true,
    "generated": true,
    "changelog": true,
    "lateFee125": true,
    "testCommand": true
   },
   "keptCount": 10,
   "keptOf": 10,
   "stale": {
    "lateFee2": true,
    "floatDollars": true,
    "clockJs": true,
    "npmTest": true,
    "port3001": true
   },
   "staleCount": 5,
   "staleOf": 5,
   "transient": {
    "coffee": true,
    "staging": true,
    "ci": true,
    "branches": true,
    "outFriday": true,
    "jq": true,
    "stripe": true,
    "pr212": true,
    "devPort": true
   },
   "transientCount": 9,
   "transientOf": 9
  },
  "memory:curated": {
   "lines": 10,
   "chars": 1049,
   "kept": {
    "cents": true,
    "parseFormat": true,
    "tallyError": true,
    "nowIso": true,
    "logHelper": true,
    "migrationsAppendOnly": true,
    "generated": true,
    "changelog": true,
    "lateFee125": true,
    "testCommand": true
   },
   "keptCount": 10,
   "keptOf": 10,
   "stale": {
    "lateFee2": false,
    "floatDollars": false,
    "clockJs": false,
    "npmTest": false,
    "port3001": false
   },
   "staleCount": 0,
   "staleOf": 5,
   "transient": {
    "coffee": false,
    "staging": false,
    "ci": false,
    "branches": false,
    "outFriday": false,
    "jq": false,
    "stripe": false,
    "pr212": false,
    "devPort": false
   },
   "transientCount": 0,
   "transientOf": 9
  },
  "memory:init": {
   "lines": 18,
   "chars": 1650,
   "kept": {
    "cents": true,
    "parseFormat": false,
    "tallyError": true,
    "nowIso": false,
    "logHelper": false,
    "migrationsAppendOnly": true,
    "generated": true,
    "changelog": true,
    "lateFee125": false,
    "testCommand": false
   },
   "keptCount": 5,
   "keptOf": 10,
   "stale": {
    "lateFee2": false,
    "floatDollars": false,
    "clockJs": false,
    "npmTest": true,
    "port3001": false
   },
   "staleCount": 1,
   "staleOf": 5,
   "transient": {
    "coffee": false,
    "staging": false,
    "ci": false,
    "branches": false,
    "outFriday": false,
    "jq": false,
    "stripe": false,
    "pr212": false,
    "devPort": false
   },
   "transientCount": 0,
   "transientOf": 9
  },
  "memory:bloated": {
   "lines": 172,
   "chars": 9592,
   "kept": {
    "cents": true,
    "parseFormat": true,
    "tallyError": true,
    "nowIso": true,
    "logHelper": true,
    "migrationsAppendOnly": true,
    "generated": true,
    "changelog": true,
    "lateFee125": true,
    "testCommand": true
   },
   "keptCount": 10,
   "keptOf": 10,
   "stale": {
    "lateFee2": false,
    "floatDollars": false,
    "clockJs": false,
    "npmTest": false,
    "port3001": false
   },
   "staleCount": 0,
   "staleOf": 5,
   "transient": {
    "coffee": false,
    "staging": false,
    "ci": true,
    "branches": false,
    "outFriday": true,
    "jq": false,
    "stripe": false,
    "pr212": false,
    "devPort": false
   },
   "transientCount": 2,
   "transientOf": 9
  }
 },
 "texts": {
  "dream-1": "# Memory\n\n## Project\n- `tally`: small invoicing ledger for the billing service. Plain ESM, no dependencies.\n- Customers live in `tally/src/customers.js`; email validation was added 2026-09-16.\n- Billing dev server runs on port 3002 (3001 is taken by another service as of 2026-09-08).\n\n## Workflow and preferences (Shah)\n- Small PRs, one change each.\n- Tests next to each feature change.\n- Early returns over nested ifs.\n- Prefer named exports.\n- Prefer `Object.freeze` for constant maps.\n- Add a one-line entry under `## Unreleased` in CHANGELOG.md for every user-visible change.\n- Clearer error messages in validation (asked 2026-09-13).\n- Shah reviews PRs in the morning.\n\n## Code style\n- 2-space indentation, single quotes.\n- No `console.log` in `tally/src/`; use `log()` from `tally/src/log.js`. Also use it for audit events (payments, refunds).\n\n## Testing\n- `npm test` is broken on Node 25 (it runs `node --test test/`, which treats the folder as a file). Run `node --test` with no path.\n- Tests inject a clock with `setClock()`.\n\n## Time\n- Use `nowIso()` from `tally/src/time.js`. Never call `new Date()` or `Date.now()` in `src` (the old `now()` in `tally/src/clock.js` is gone).\n\n## Money\n- All money is integer cents (`amountCents`) since 2026-08-12. Floats caused rounding bugs.\n- Parse input with `parseAmount()`, print with `formatCents()`. Divide by 100 only when formatting. Don't use `toFixed`.\n- Late fee: 1.25% of the unpaid balance (finance, 2026-09-15), rounded half up to the cent.\n- Payments must not exceed the open balance (`E_OVERPAYMENT`).\n\n## Errors\n- Throw `TallyError` (never plain `Error`) with a code from `CODES` in `tally/src/errors.js`. Add a new code if none fits.\n- The billing service maps codes to HTTP statuses and reads `CODES` at start-up, so new codes need no other change.\n- Error codes are public API; never rename an existing one.\n\n## Migrations\n- Append-only (decided 2026-08-05 after editing 0002 caused production schema drift). Add a new `tally/migrations/NNNN_<name>.json`; never edit an existing one.\n- The store loads the schema from `tally/migrations/*.json` in file-name order.\n\n## Generated code\n- `tally/src/report.gen.js` is generated; never hand-edit it (a fix was lost this way).\n- Edit `tally/templates/report.tmpl.js`, then run `node tally/scripts/gen-report.mjs`.\n- The template uses a `__CURRENCY__` placeholder.\n\n## Misc\n- `slugify()` is used for export file names.\n- Latest release: 1.4.0 (2026-09-20).\n",
  "dream-2": "# Memory\n\n## Project\n- `tally`: small invoicing ledger for the billing service. Plain ESM, no dependencies.\n- Customers live in `tally/src/customers.js`; email validation is in place (2026-09-16).\n- Billing dev server runs on port 3002 (moved from 3001 on 2026-09-08, which another service now uses).\n\n## Testing\n- Run `node --test` with no path. `node --test test/` fails on Node 25 (treats the folder as a file), and `npm test` uses the broken form (2026-09-21).\n- Tests inject a clock with `setClock()`.\n\n## Code style\n- 2-space indentation, single quotes.\n- Prefer named exports.\n- Prefer early returns over nested ifs (Shah).\n- Prefer `Object.freeze` for constant maps.\n- No `console.log` in `tally/src/`; use `log()` from `tally/src/log.js`. Also use it for audit events (payments, refunds).\n- Time: use `nowIso()` from `tally/src/time.js`. Never call `new Date()` or `Date.now()` in `tally/src/` (2026-08-30; replaces the old `now()` in `tally/src/clock.js`).\n- `slugify()` is used for export file names.\n\n## Money\n- Integer cents everywhere (`amountCents`), decided 2026-08-12 because `toFixed` on floats caused rounding bugs.\n- Parse input with `parseAmount()`, print with `formatCents()`. Never divide by 100 except when formatting.\n- Late fee is 1.25% of the unpaid balance, round half up to the cent (finance, 2026-09-15; replaces the old 2%).\n- Payment amounts must not exceed the open balance (`E_OVERPAYMENT`).\n\n## Errors\n- Throw `TallyError` (never plain `Error`) with a code from `CODES` in `tally/src/errors.js`; add a new code if none fits.\n- Error codes are public API: never rename an existing one. The billing service maps codes to HTTP statuses and reads `CODES` at start-up, so new codes need no other change.\n- Shah wants clearer error messages in validation (2026-09-13).\n\n## Migrations\n- Append-only (since the 2026-08-05 incident where editing 0002 caused production schema drift). Add a new `tally/migrations/NNNN_<name>.json`; never edit an existing one.\n- The store loads the schema from `tally/migrations/*.json` in file-name order.\n\n## Generated files\n- `tally/src/report.gen.js` is generated; never hand-edit it (lost a fix this way, 2026-09-10).\n- Edit `tally/templates/report.tmpl.js`, then run `node tally/scripts/gen-report.mjs`.\n- The template uses a `__CURRENCY__` placeholder.\n\n## Workflow (Shah's preferences)\n- Small PRs, one change each.\n- Add tests alongside each feature change.\n- Add a one-line entry under `## Unreleased` in CHANGELOG.md for every user-visible change.\n- Shah reviews PRs in the morning.\n\n## Releases\n- 1.3.0 (2026-08-01): monthly report, partial payments.\n- 1.4.0 (2026-09-20): integer cents, email validation.\n",
  "dream-3": "# Memory\n\n## Project\n- `tally`: small invoicing ledger for the billing service. Plain ESM, no dependencies.\n- Customers live in `tally/src/customers.js`; email validation is in place (1.4.0).\n- Billing dev server runs on port 3002 (3001 is taken by another service, as of 2026-09-08).\n\n## Workflow and preferences (Shah)\n- Small PRs with one change each.\n- Tests next to each feature change.\n- Early returns over nested ifs.\n- Clear, specific validation error messages (asked 2026-09-13).\n- Every user-visible change gets a one-line entry under `## Unreleased` in CHANGELOG.md.\n- Shah reviews PRs in the morning.\n\n## Code style\n- 2-space indentation, single quotes.\n- Named exports.\n- `Object.freeze` for constant maps.\n- No `console.log` in `tally/src/`; use `log()` from `tally/src/log.js`. Also use it for audit events (payments, refunds).\n\n## Testing\n- `npm test` is broken on Node 25 because it runs `node --test test/` (treats the folder as a file). Run `node --test` with no path.\n\n## Errors\n- Throw `TallyError` (never plain `Error`) with a code from `CODES` in `tally/src/errors.js`. Add a new code if none fits.\n- Error codes are public API: never rename an existing code.\n- The billing service reads `CODES` at start-up and maps codes to HTTP statuses; new codes need no other change.\n- Payments may not exceed the open balance (`E_OVERPAYMENT`).\n\n## Money\n- Integer cents everywhere (`amountCents`), decided 2026-08-12 after `toFixed` float rounding bugs.\n- Parse input with `parseAmount()`, print with `formatCents()`. Never divide by 100 except when formatting.\n- Late fee: 1.25% of the unpaid balance, round half up to the cent (Finance, 2026-09-15; replaced the earlier 2%).\n\n## Time\n- Use `nowIso()` from `tally/src/time.js` (replaced `now()` in `tally/src/clock.js`, 2026-08-30).\n- Tests inject a clock with `setClock()`. Never call `new Date()` or `Date.now()` in `tally/src/`.\n\n## Migrations\n- Append-only (decided 2026-08-05 after an edit to 0002 caused production schema drift). Add a new `tally/migrations/NNNN_<name>.json`; never edit an existing one.\n- Store loads the schema from `tally/migrations/*.json` in file-name order.\n\n## Generated code\n- `tally/src/report.gen.js` is generated; never hand-edit it (an edit was lost on 2026-09-10).\n- Edit `tally/templates/report.tmpl.js`, then run `node tally/scripts/gen-report.mjs`.\n- The template uses a `__CURRENCY__` placeholder.\n\n## Misc\n- `slugify()` is used for export file names.\n- Latest release: 1.4.0 (2026-09-20).\n"
 },
 "receipts": {
  "dream-1": {
   "model": [
    "claude-sonnet-5-5"
   ],
   "wallMs": 6805,
   "costUsdEstimate": 0.020119,
   "outputTokens": 975
  },
  "dream-2": {
   "model": [
    "claude-sonnet-5-5"
   ],
   "wallMs": 6660,
   "costUsdEstimate": 0.01132,
   "outputTokens": 1052
  },
  "dream-3": {
   "model": [
    "claude-sonnet-5-5"
   ],
   "wallMs": 6777,
   "costUsdEstimate": 0.01069,
   "outputTokens": 989
  }
 }
}
