Finance dashboard rebuild: bills by paycheck, graphics, and drill-downs
Date: 2026-10-03. Scope: review of the stalled jknash/personal-dashboard project, a
feature-by-feature mapping onto the live workbench finance page
(jknash/dashboard, site/finance/), a bills-by-paycheck design with a worked
example from Justin's real numbers, graphics and drill-down proposals sized for a
static snapshot architecture, external best practices, and a phased build plan.
This is a review-and-recommend document; nothing here has been built yet.
Data provenance: paycheck dates, balances, Plaid recurring streams, and
transactions come from the live snapshot site/finance/data/finance.json
(generated 2026-10-03 from the Chase via Plaid pull). Bill details Plaid does not
carry (the Flex split, the individual Apple subscriptions, the Upgrade loan, the
Affirm plan total) come from Justin's records and the Outlook Apple receipts
identified on 2026-10-03. Where the two sources disagree or Plaid is silent, the
item is flagged with a warning marker in the tables below.
1. What the personal-dashboard project contains
Repository: jknash/personal-dashboard (private), TypeScript, last pushed
2026-09-14. It is a backend only: a Cloudflare Worker plus a local stdio MCP
server in front of Supabase/PostgreSQL. There is no web UI anywhere in the repo;
the only UI-adjacent artifact is a spec (docs/specs/phase-1/workspace-web-host.md).
Over time it also grew into a general "personal workspace platform" (module SDK,
capability registry, identity, encryption, outbox/jobs machinery, ten ADRs), and
that platform work is most of the code mass. The finance core is small and good.
1.1 Feature inventory
Finished and tested:
- Bill registry —
supabase/migrations/20260722213000_initial_finance_schema.sqldefinesbill_templates(name, estimated amount in cents, due-day windowdue_day_starttodue_day_end, autopay flag, default payment account) andbill_occurrences(one row per month: due window, expected amount, actual amount, status expected / scheduled / paid / skipped, link to the bank transaction that paid it). Exposed throughsrc/application/finance-service.tsand MCP toolslist_bills/create_bill. - Payment routing —
supabase/migrations/20260727165649_payment_routing.sqladdspayment_accounts,payment_methods, andbill_payments. The model deliberately separates the source of funds from the mechanism ("Chase Checking via Venmo"). Services insrc/application/payment-service.ts; MCP toolslist_payment_accounts,create_payment_account,list_payment_methods,create_payment_method,set_bill_payment_defaults,record_bill_payment,list_bill_payments. - Bill-to-paycheck allocator —
src/domain/allocate-bills.ts, a pure function with a thorough test suite (tests/allocate-bills.test.ts, 15 cases). Detailed in section 1.2. - Income and paycheck data model —
income_streams(schedule weekly / biweekly / semimonthly / monthly, next expected date, semimonthly day pair, deposit account) andpaycheck_occurrences(expected deposit date and amount, actual date and amount, status forecast / deposited / missed, matched transaction). Schema only: no service or tool generates or reads occurrences. - Two-step destructive approval — archiving a bill requires
request_bill_archival(mints a five-minute, single-use token) thenconfirm_destructive_action. Heavily tested, including concurrency. - Audit trail —
audit_eventstable; every MCP mutation writes an event. - Bank provider interface —
src/banking/bank-provider.tsdefines the contract (connection session, token exchange, account list, cursor-based transaction sync, disconnect). Interface only. - Platform machinery — GitHub OAuth 2.1 with an immutable user-ID allowlist,
capability policy and grants, envelope encryption, transactional outbox,
rate limiting, recovery contracts (
src/auth,src/capability-policy,src/encryption,src/events-jobs,src/module-sdk,src/rate-limit). Well engineered, and almost entirely in service of multi-client MCP access rather than of the dashboard itself.
Stubbed or planned but never built (the README's own "Next implementation slices" list, all still open):
- Generating monthly bill occurrences from due-day ranges.
- Generating paycheck occurrences for the four schedules.
- Persisting and editing suggested allocations (the allocator runs nowhere in the running system; no MCP tool or service calls it).
- Encrypted bank-token storage and Plaid Sandbox Link.
- Idempotent transaction synchronization (cursor and webhooks).
- Matching deposits to paycheck forecasts and debits to bill occurrences.
The bank feed (slice 4 and 5) is the blocker that stalled the project: it needed Justin's own Plaid account and production pricing decision, so no real data ever flowed. The workbench route removes that blocker entirely, because Muse's existing Plaid connection already reads the accounts.
1.2 The allocation model
allocateBillsToPaychecks(paychecks, bills) in src/domain/allocate-bills.ts:
- All money is integer cents; non-integer, negative, or unsafe amounts throw.
- Paychecks sort by deposit date; bills sort by due date (stable, so equal due dates keep input order).
- Each bill, in due-date order, is assigned whole to the latest paycheck
deposited on or before the bill's due date that still has at least the full
bill amount unallocated. If the latest paycheck lacks room, it falls back to
earlier paychecks. Bills are never split across paychecks, and the database
agrees:
bill_allocationshas a unique constraint on the bill occurrence. - A bill no eligible paycheck can fully cover lands in
unallocatedBillOccurrenceIds— a visible failure, not a silent overdraft. Projected remaining per paycheck is therefore never negative. - Output per paycheck: expected amount, allocated amount, projected remaining.
Edge cases it handles: bill due before the first paycheck (unallocated); exact-fit bills draining a paycheck to zero; aggregate capacity shortfalls; fallback to an earlier paycheck with room; invalid amounts.
Edge cases it misses, which the workbench design must patch:
- Due-date windows. The registry models a window (due day 5th to 9th, say), but the allocator consumes a single due date. Nothing decides which day in the window to use. Conservative choice: the window's first day for assignment (money is ready early), displayed as a range.
- Due date versus cash date. Assignment is by due date, but cash leaves on the posting date. Justin's Chase minimum is due on the 1st while the paycheck lands on the 2nd; the model charges the prior paycheck, the bank debits the new one. The page should show both dates so the seam is visible.
- Actuals. The allocator plans from expected amounts only. Occurrence status and actual amounts exist in the schema but the function ignores them, so a bill already paid still consumes capacity until it is removed from the input. The generator must feed it unpaid occurrences only, and re-run as actuals land.
- No priority among bills. Order is purely chronological. If capacity runs short, a small subscription due early can crowd out a larger essential bill due later in the same window. A priority class (housing, debt, essential, subscription) as a secondary sort key is cheap insurance.
- No reserve. Projected remaining is treated as fully spendable; there is no buffer, no discretionary allowance, and no sinking-fund set-aside. The "safe to spend" figure has to be layered on top (section 3.4).
- Monthly occurrence assumption. Occurrences are one per month per bill. Semimonthly items (the Zelle to Michele) and split bills (Flex) need either two templates or an occurrence generator that allows multiple per month.
2. Feature mapping to the workbench
The workbench finance page is static: scripts/build_finance_snapshot.py turns
Plaid CLI dumps into site/finance/data/finance.json, and site/finance/index.html
renders it. No backend, no database, no build step; deploys are file uploads.
Every feature below is judged against that shape. The generator script is the
"server": anything computable at snapshot time belongs there, so the page stays
a dumb renderer and the JSON carries finished answers.
| Project feature | Verdict | Static equivalent |
|---|---|---|
| Bill registry (templates, due windows, autopay) | Keep, adapt | A curated registry file in the dashboard repo (for example scripts/bill_registry.json) that the generator merges with Plaid recurring streams. Plaid is authoritative for actuals; the registry is authoritative for due days, expected amounts, and bills Plaid misses entirely. |
| Bill occurrences with paid status | Adapt | The generator emits occurrence objects for the current and next cycles into the snapshot, matching actual transactions by payee, amount tolerance, and date window — the same matching the morning bill watch already does by hand. |
| Income streams and paycheck occurrences | Adapt | The generator derives the anchor and cadence from Plaid inflow streams and emits forecast paychecks (next 4 to 6) with expected amounts; a forecast flips to "deposited" when a matching deposit appears in transactions. |
| Allocator | Keep nearly as-is | Port the pure function to Python inside the generator (about 60 lines), with the section 1.2 patches: priority secondary sort, unpaid occurrences only, due-window start for assignment. The snapshot ships the finished allocation; the page never computes. |
| Payment accounts and paid-via routing | Drop for now | Nearly everything Justin pays comes out of one checking account, so source-versus-mechanism routing answers a question he is not asking. The registry can carry an optional "paid via" label per bill shown as a small pill; that captures the visible value at no structural cost. |
| Manual payment recording | Drop | Plaid actuals replace hand recording. The bill watch already verifies postings every morning. |
| Two-step destructive approval | Drop | The page has no destructive operations. Registry edits happen as repo commits, which are reviewable and reversible in git. |
| Audit events | Drop, replaced free | Every snapshot is committed to the repo with a timestamp; git history is the audit trail. |
| MCP server, OAuth, capability platform | Drop | Muse is the interface. Asking Muse replaces tool calls; the page replaces the client app. This was most of the project's mass and none of it serves the dashboard goal. |
| Supabase, Postgres, row-level security | Drop | One reader (Justin), one static JSON, Cloudflare Access in front. |
| Own Plaid integration (Link, tokens, sync, webhooks) | Drop, already solved | Muse's Plaid connection feeds the generator. This was the project's fatal blocker; it no longer exists. |
What genuinely needs a backend, and the static substitute:
- Editing bills in the page (add a bill, change an amount, drag a bill to a different paycheck). Substitute: edits go through Muse in chat — Muse updates the registry, regenerates, commits, deploys. That loop already exists and is the standing rule for finance pulls. A middle step worth having later: the registry supports per-bill overrides (pin this bill to the first paycheck of the month) that the allocator honors, so "move this bill" is a one-line registry change rather than a code change.
- Real-time balances. Substitute: snapshot cadence. The data is only ever as fresh as the last pull; the page already timestamps it. Daily refresh rides the existing bill watch.
- Push alerts (bill due tomorrow, paycheck short). Substitute: the morning bill watch already reports paid versus due in chat; extend it to flag unallocated bills and low projected balances from the same snapshot.
3. Bills by paycheck design
3.1 Pay periods
Anchor on actual deposits, not on a calendar assumption. Plaid shows the Insperi payroll stream as biweekly, average $5,133.62, with deposits on Friday 2026-09-18 and Friday 2026-10-02 (the October 2 deposit was still marked pending in the October 3 snapshot). Stepping 14 days forward:
- Paycheck A: Friday 2026-10-02, $5,133.62 (deposited)
- Paycheck B: Friday 2026-10-16, $5,133.62 (forecast)
- Paycheck C: Friday 2026-10-30, $5,133.62 (forecast)
- Paycheck D: Friday 2026-11-13, $5,133.62 (forecast)
October 2026 is a three-paycheck month, which a monthly budget view hides completely. A pay period runs from a deposit date up to the day before the next deposit. A bill belongs to the latest paycheck deposited on or before its due date (the project's rule), so a bill due on payday itself belongs to that day's paycheck, and a bill due the day before payday belongs to the previous one.
Two wrinkles in Justin's real cash flow:
- Flex rent is split across two paychecks by design. Flex pays the property in full up front; installment 1 ($1,089.60) charges around the 30th or 1st and installment 2 ($1,287.50) on the 15th. Installment 2 due October 15 belongs to paycheck A (October 2). Installment 1 due around October 30 belongs to paycheck C. The registry models Flex as two bills, not one.
- The Zelle to Michele is semimonthly and variable (average $1,066, last actual $2,000 on 2026-08-28, no posting since in the data pulled). It behaves like a bill for cash-flow purposes. The worked example carries it at the $1,066 average as its own line so Justin can see both totals; whether it is formally a "bill" in the allocation is one of the open questions (section 7).
The $100 monthly Zelle from X-Centric IT Solutions LLC (last received 2026-09-15, next predicted 2026-10-15) is assigned to the paycheck whose period contains it, as supplemental income to that cycle.
3.2 Worked example: the current cycle
Paycheck A, deposited Friday 2026-10-02, $5,133.62. Period: October 2 to 15.
| Bill | Due | Amount | Status and source |
|---|---|---|---|
| Apple — Craft Plus and FOX One | Oct 2 | $28.57 | Posted (Apple receipt, order MMQH7W26NN) |
| Oct 2 | $1.99 | Posted (Plaid stream) | |
| Apple — iCloud+ 2 TB | about Oct 6 | $9.99 | Receipt; renews Oct 6 |
| Netflix | Oct 8 | $28.58 | Plaid predicted Oct 8 |
| Backblaze (subscription 1) | Oct 8 | $27.00 | Plaid average; a second stream below is subscription 2 |
| Homeowners insurance | Oct 11 | $13.84 | Plaid shows two insurance streams ($16.40 average and $13.84); the confirmed amount is $13.84 — see data notes |
| Backblaze (subscription 2) | Oct 14 | $33.21 | Plaid last amount (average $32.85) |
| Flex rent, installment 2 | Oct 15 | $1,287.50 | Flex schedule; not a Plaid stream |
| Subtotal, bills | $1,430.68 | ||
| Zelle to Michele (at average) | about Oct 13 | $1,066.00 | Timing and amount vary — see open questions |
| Total assigned | $2,496.68 | ||
| Other income in period (X-Centric Zelle, Oct 15) | +$100.00 | ||
| Projected leftover from this paycheck | $2,736.94 | Before groceries, dining, and all other discretionary spending |
Already out the door when the October 3 snapshot was taken: $30.56 of the assigned bills above (the two October 2 postings), plus two items that belong to the previous paycheck by the due-date rule but were paid from this one — the Chase card minimum of $40.00 (due October 1, paid October 2) and, from the prior cycle, Flex installment 1 of $1,089.60 and Affirm's $92.86 posting on October 1. That seam is exactly why the page must show due date and paid date side by side.
3.3 The next two cycles (forecast)
Paycheck B, Friday 2026-10-16, period October 16 to 29 — the light cycle:
| Bill | Due | Amount |
|---|---|---|
| Microsoft | about Oct 19 | $6.00 |
| YouTube Premium | Oct 21 | $16.93 |
| Apple — Craft Plus and FOX One | Oct 22 | $28.57 |
| AT&T | Oct 22 | $423.65 |
| Apple — Fortnite Crew (Linus's account) | about Oct 26 | $12.70 |
| Homeowners insurance | Oct 28 | $13.84 |
| Marcus Theatres | Oct 28 | $10.58 |
| Total assigned | $512.27 | |
| Projected leftover | $4,621.35 |
Paycheck C, Friday 2026-10-30, period October 30 to November 12 — the heavy cycle, where the first-of-month cluster lands:
| Bill | Due | Amount |
|---|---|---|
| Apple One Premier | about Oct 30 | $41.99 |
| Flex rent, installment 1 | about Oct 30 | $1,089.60 |
| Affirm, all plans | about Nov 1 | $386.00 |
| Upgrade loan | about Nov 1 | $748.81 |
| Chase card minimum | Nov 1 | $40.00 |
| Netflix | Nov 8 | $28.58 |
| Backblaze (subscription 1) | Nov 8 | $27.00 |
| Total assigned | $2,361.98 | |
| Projected leftover | $2,771.64 |
The pattern across A, B, and C is the entire argument for this view: assigned bills swing from $512 to $2,497 per paycheck while income is flat. A monthly total (about $5,371 of assigned bills across the three cycles, against $15,500.86 of income including the $100 Zelle) says "comfortable"; the per-paycheck view says which specific Fridays are tight, and it is the only view that can answer "can I spend this today" honestly.
3.4 "Where am I right now"
The top of the page should answer, for the current cycle, in one glance:
- Paycheck in: $5,133.62 on October 2 (plus $100 expected October 15).
- Bills paid so far this cycle: $30.56 posted, of $2,496.68 assigned.
- Still spoken for: $2,466.12 (including the Zelle at its average).
- Safe to spend: checking available balance minus still-spoken-for minus an optional buffer. On the October 3 snapshot: $5,514.91 available, minus $2,466.12, equals $3,048.79 (no buffer). This is a computed field in the snapshot, not a page calculation, so it is identical everywhere it appears.
- Projected end-of-cycle position: the cycle's projected leftover ($2,736.94), which becomes the starting cushion for the next cycle in the forecast chain (section 5.3).
3.5 Data-quality notes the design has to absorb
These are why the curated registry (section 2) is not optional:
- The Upgrade loan ($748.81) does not appear in Plaid's recurring streams at all, though it posted September 25. Plaid-only bills would silently drop the second-largest obligation.
- Affirm shows as a single $92.86 stream; the known total across six plans is about $386. The registry carries the total until Plaid's detection improves.
- Homeowners insurance appears as two Plaid streams ($16.40 average with a $13.31 last amount, and $13.84). The confirmed premium is $13.84; the other stream looks like a duplicate detection and must be suppressed in the registry.
- Apple is one blended Plaid stream ($9.61 average). The real subscriptions are four separate items ($9.99, $41.99, $12.70, $28.57) known from receipts, on four different days. The registry carries the four; Plaid matches actuals.
- A GEICO charge of $115.71 posted September 28 and matches no known bill. It is either a new recurring obligation or a one-off; it is carried as an open question, not silently registered.
- The Microsoft stream looks stale in Plaid (last date August 19 against a monthly cadence). The $6 charge is real and monthly per Justin's records.
4. Graphics and drill-downs
Constraints honored throughout: no chart library, no CDN, no build step. Every visual below is HTML, CSS, and inline SVG generated by the page's existing vanilla-JS renderer from snapshot fields, in the page's current dark theme. Effort key: S is an evening's small change (an hour or two), M is a solid half-day, L is a day or more including generator work.
| Visual | Question it answers | Data the snapshot must carry | Effort |
|---|---|---|---|
| Safe-to-spend hero | "What can I spend right now without breaking this cycle?" | Current cycle block: available balance, remaining assigned total, buffer setting | S |
| Paycheck cards with stacked allocation bar | "What does each paycheck have to cover, and what is left?" | Per-cycle: income, allocations as named segments, leftover segment | S |
| Cash-flow river (projected balance line) | "Where does my balance dip, and how low does it get before the next paycheck?" | Ordered forecast events (date, delta, label) for 60 to 90 days, plus today's balance | M |
| Bill calendar strip | "What hits in the next 30 days, and how big is each hit?" | Occurrences with due dates and amounts for 30 to 60 days | S |
| Paid-versus-due checklist per cycle | "What has actually posted, what is still coming, what is late?" | Occurrence status (paid, pending, upcoming, overdue) with actual amounts and paid dates | S |
| Category bars with click-to-expand transactions | "Where did the money go, exactly?" | All transactions in the window with categories (raise the current 40-item cap) | S |
| Credit card utilization ring | "How full is the card?" | Already in the snapshot (balance, limit, available) | S |
| Balance and net-position sparkline | "Am I trending up or down over time?" | A small history series the generator appends on each run from its own prior snapshots | M |
| Bill detail history (per bill, last 6 occurrences) | "Is this bill creeping up?" | Per-bill occurrence history with expected versus actual | M |
Notes on the two that carry the "wow":
- The cash-flow river is one inline SVG path. The generator emits the running projected balance day by day (starting at today's available balance, stepping down at each expected bill, up at each forecast paycheck). The page draws it as a stepped area chart with a zero line, a marked lowest point with its date and amount, and dots for paychecks. It is the single most informative object on the page: the sawtooth shape is Justin's financial life, and the marked trough answers "how bad does it get" before he asks.
- Stacked allocation bars should use one muted color family with a single accent reserved for warnings (an unallocated bill, an overdue item), direct labels on segments wide enough to hold them, and a legend list that doubles as the drill-down index. Part-to-whole by bar, never by pie (section 5.5).
Drill-down pattern, four levels, all client-side from the one JSON:
- Level 0, summary: hero number, river, paycheck cards.
- Level 1, paycheck: clicking a paycheck card expands its bill list — each bill with due date, expected amount, status pill.
- Level 2, bill: clicking a bill expands its detail — expected versus actual for the last several occurrences, paid-via label, the matched transaction when paid.
- Level 3, transactions: category rows and bill rows expand to the underlying transactions (date, payee, amount, account, pending flag), the same fields the recent-transactions table already renders.
Expansion uses the same card-and-table styling the page already has, so the upgrade reads as one coherent page getting deeper, not a new app.
5. External best practices
Only practices that survive translation to a single-user, static, snapshot-fed page are included.
5.1 Budget by paycheck, not by month
The paycheck budgeting method builds a separate zero-based plan for each paycheck: fill a bill calendar first, then give every dollar of that paycheck a job before discretionary spending is considered. It exists precisely for people whose bills cluster unevenly across the month — Justin's $512-versus-$2,497 cycle swing is the textbook case. Sources: The Penny Hoarder's walkthrough of the Budget by Paycheck method (Kumiko Love's approach), https://www.thepennyhoarder.com/budgeting/budget-by-paycheck/ ; Ramsey Solutions on zero-based budgeting (income minus assignments equals zero), https://www.ramseysolutions.com/budgeting/how-to-make-a-zero-based-budget?campaign_id=&utm_campaign=no_campaign&utm_content=dr_fb_everydollar_blog_what_is_zero_based_budgeting_92419&utm_medium=social_organic&utm_source=facebook_dave_ramsey&utm_term=everydollar_bu
5.2 Assign each bill to the paycheck that lands before its due date
Paycheck-aligned (pay-period) budgeting states the assignment rule plainly: each bill belongs to whichever paycheck arrives before its due date, rather than to a calendar month — if rent is due on the 1st and a paycheck lands on the 28th, that paycheck owns the rent. This independently validates the stalled project's allocator rule (latest paycheck on or before the due date). The same source recommends moving due dates closer to a reliable paycheck where lenders allow it, and funding irregular costs with a small transfer every payday. Source: ExpressPlanner's household budget calendar guide, https://expressplanner.io/blog/household-budget-calendar
5.3 Forecast cash flow by rolling the balance forward
Practical cash-flow forecasting for a personal account: start from the real balance today (not from income), list expected inflows with conservative timing, list expected outflows fixed-first and irregulars included, then roll each period's closing balance into the next period's opening. Chaining periods is what exposes which cycles are always tight. This is the method behind the cash-flow river in section 4 and the projected-leftover chain in section 3. Source: PocketGuard's cash flow forecasting guide, https://pocketguard.com/blog/cash-flow-forecasting/
5.4 Level the irregulars with sinking funds
Known but non-monthly costs (annual premiums, semiannual insurance, annual subscriptions) should be converted to a level per-paycheck set-aside — annual total divided by the number of pay periods — and treated as a fixed assignment in every cycle, so a lump never lands on one paycheck unannounced. Keep the funds few and combined rather than one per category; a single "irregulars" line with a registry of what it covers is enough at this scale. Sources: Symple Lending on sinking funds for irregular expenses, https://symplelending.com/insights/build-sinking-funds-for-irregular-expenses ; Simple Finance Bytes on keeping sinking funds to one combined fund, https://simplefinancebytes.com/2026/09/07/sinking-funds-without-20-budget-categories/
For Justin today this is a small number (the $35 annual "Dmb" stream Plaid found, plus anything GEICO turns out to be), but the mechanism belongs in the design now because the divorce timeline will change his obligation set, and leveled set-asides are how new annual costs should enter the plan.
5.5 One hero number, honest graphics
Dashboard design practice converges on a priority stack: available money and the safe-to-spend figure first and largest, then days to payday and cycle progress, then category detail, then transactions. The safe-to-spend formula used by practitioners: available balance plus expected income before the horizon, minus upcoming bills, minus debt payments, minus savings commitments, minus a reserve. One number gets the visual emphasis; everything else supports or explains it. A worked priority-stack specification: https://github.com/benthompsondev/ledger-local-finance/blob/HEAD/docs/product/ADOPTION_AUDIT.md
For the graphics themselves, Tufte's principles, distilled in practitioner references: bars over pies for part-to-whole (angle judgment is the least accurate), small multiples on a shared scale for comparing like series, sparklines inline with text for trends, direct labels instead of legends where space allows, color spent on one job (the warning) with everything else muted, and no ornament that does not encode data. Sources: https://github.com/aradotso/claude-code-skills/blob/HEAD/skills/tufte-data-visualization/SKILL.md ; https://github.com/berto-play/claude-skills/blob/HEAD/craft--tufte-data-visualization/SKILL.md
Practices deliberately not imported: envelope cash management (Justin's spending is card and transfer based; per-paycheck category allowances are offered as an open question instead), multi-account envelope systems such as YNAB's full workflow (the subscription and the manual reconciliation habit are the cost; the allocator already provides the discipline), and 50/30/20 ratio targets (a diagnostic at most; his fixed obligations are what they are, and the per-paycheck view is strictly more informative).
6. Phased build plan
Phase 0 — Decisions (needs Justin, no code). Answer the section 7 questions; confirm the registry seed list (the bills in section 3 with their due days and amounts, including the flagged items). Deliverable: a signed-off registry draft. Effort: one conversation.
Phase 1 — Bills by paycheck (the centerpiece). Build bill_registry.json;
port the allocator into build_finance_snapshot.py with the section 1.2
patches; emit a pay_cycles block (current cycle plus three forecast cycles,
each with income, allocations, totals, leftover, unallocated list); render
paycheck cards with stacked allocation bars and per-cycle bill tables on the
finance page. The page's existing sections stay untouched below. Effort: M.
Delivers exactly what Justin asked for first.
Phase 2 — Right-now position and forecast. Match actuals to occurrences (paid status, actual amounts, paid dates) using the same transaction window the generator already loads; compute safe-to-spend; emit the 90-day forecast event series and render the cash-flow river with its marked trough. Extend the morning bill watch to flag unallocated bills and a negative projected trough from the same snapshot. Effort: M.
Phase 3 — Depth. Raise the transaction cap so categories carry their full window; add the drill-down levels (paycheck to bill to transactions, category to transactions); bill calendar strip; card utilization ring; per-bill expected-versus-actual history in the bill detail. Effort: M.
Phase 4 — Polish and history. Generator appends each run's headline numbers to a history series (net position, checking balance, cycle leftover) for the sparkline; sinking-fund leveling line for annual items; due-date smoothing suggestions when a cycle's assigned total exceeds a threshold share of the paycheck. Effort: S to M. Optional throughout: nothing in Phases 1 to 3 depends on it.
Dependencies are strictly in order: the registry (Phase 1) feeds everything; actuals matching (Phase 2) feeds drill-down status (Phase 3); history (Phase 4) needs only time to accumulate.
7. Open questions for Justin
- Paycheck anchor. Plaid shows Insperi deposits on Friday September 18 and Friday October 2, 2026, $5,133.62 each. Is every-other-Friday from October 2 the right anchor and $5,133.62 the right planning amount for forecast paychecks (overtime or deductions could make actuals vary)?
- The Zelle to Michele. Count it as a bill in the allocation? And if so, at what planning figure — the $1,066 average, the $2,000 last payment, or a fixed amount you name? Its timing (which days of the month) matters as much as the amount.
- Affirm. Plan on the roughly $386 total across six plans, or only on the $92.86 Plaid can see? If $386, the registry needs the six plans' due days, or one combined line on one day of the month.
- GEICO, $115.71 on September 28. New recurring bill (auto insurance?) to register, or a one-off? If recurring: how often, and what amount?
- Forecast horizon. How far ahead should the page look: two cycles (about a month), six cycles (about a quarter), or a full year of paychecks?
- Safe-to-spend buffer. Subtract a safety cushion before calling money spendable? If yes, how much (a flat figure, or a percentage of the paycheck)?
- Discretionary allowances. Should groceries, dining, and similar variable spending get per-paycheck allowance lines inside the allocation (true zero-based, so leftover means something precise), or stay outside the plan as pace tracking against the 30-day category totals?
- Due-date changes. The October 30 cycle carries about $2,362 against the October 16 cycle's $512. If any billers allow due-date moves, shifting one mid-size bill from the heavy cycle to the light one would flatten the sawtooth. Worth pursuing, or leave dates as they are?
Published by Muse · 2026-10-03.