PRODUCT.md described recurring costs as repeating "monthly, every N days,
or every N weeks", understating everyNMonths, which supports an interval
like the other two kinds.
demo-data.ts gave "Rent" both an ordinary monthly purchase and a
never-confirmed recurring cost from 2026-06 onward, so the demo's Rent
Projected read as double-charged for June through September. The ordinary
purchase now stops once the recurring cost exists.
Two rules that only review catches, so they go in AGENTS.md §1: occurrences are
computed and never stored, and a confirmation's date and its slot are different
facts. Collapsing the second pair into one field would silently delete the
phone-bill behaviour, which is why it is written down rather than left to the
types.
§2 gets the termination guard. n >= 1 is rejected at both write boundaries
rather than clamped, and the walk throws rather than breaking, because a bill
silently dropped from a budget is worse than a visible error.
Demo data seeds a monthly rent and a 28-day subscription — the second is what
puts two occurrences in one month, which is the case worth looking at. It also
seeds a biweekly cost and a lastCharge-anchored one, so every recurrence kind
and both anchorings show up in Settings and the month view.
DECISIONS.md, PRODUCT.md, ARCHITECTURE.md and TODO.md are updated to match:
schema is at 7, the month view carries a second Projected balance beside
Remaining, and TODO.md records what a week of real use — not a test — will
have to answer.
ARCHITECTURE, PRODUCT and TODO move out of the repository root, and
docs/superpowers/{specs,plans} flattens to docs/{specs,plans}:
"superpowers" names the tool that wrote those documents, not a kind of
document.
No content changes. This commit is the move, plus the roughly thirty
cross-references the move invalidated.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Two things this session depended on lived only in a scratchpad, so the next
agent would have had to reinvent them from a prose hint:
- scripts/screenshot-fonts.conf, now applied by screenshot.ts itself. Without
it this container renders every generic font family as Fira Code and the UI
looks monospaced in a way no user sees — a trap that nearly produced a "fix"
for a font bug that does not exist.
- scripts/demo-data.ts, which seeds a visibly synthetic dataset. Without it
every screenshot shows an app full of zeros, because Chrome starts from a
fresh profile each run.
CLAUDE.md now carries the two-command recipe verbatim instead of "point
FONTCONFIG_FILE at an override", and says why --reload is mandatory. Verified
from a clean shell with no environment set.
Also flags docs/superpowers/plans/2026-09-01-budget-app.md as a historical
record: its snippets still show CURRENCIES and CURRENCY_DIGITS, which no
longer exist, and an agent reading it as current would be misled.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>