Skip to content

Archive: plans ​

These are decision records, not documentation. Every page below is history unless its header says planned or executing. Each one is the contract some build was executed against, kept for the reasoning that produced the product, and its body is frozen at the day it was written. What is still true of the product is in each page's own header and in the What is still current list below; the normative pages are Portfolio, Metrics, Database, Data pipeline and Deployment.

44 plans: 28 built, 9 built-with-deviations, 5 superseded, 2 retired. This page is generated from the plan headers by docs/scripts/plans-index.mjs (cd docs && npm run plans:index), and a unit test fails if it is edited by hand or left stale.

PlanStatusLandedUpdated
Aave V3 / SparkLend account boundary — implementation plan (issue #717)builtPR #730 (v0.53.0); migration 0912026-09-14
Activity: semantic actions, four-column statement, and the same-direction double-count fixbuiltv0.32.0 (rounds 1 and 2); rebuilt on the current engine in v0.43.02026-09-14
Plan: AI assistant (stages 1 and 2)built-with-deviationsmigrations 038 and 039 (v0.3.0); the whole UI was removed again by PR #719 (v0.51.0)2026-09-14
Plan: reduce chat assistant input-token costbuiltv0.3.02026-09-14
Replaying positions that closed inside the backfill windowsupersededneither shape here was built; the deep-history signup build shipped instead (v0.36.0)2026-09-14
Cross-asset view — implementation plansupersededPR #524 (v0.27.0); the view was replaced by the All view, PR #843 (v0.59.0)2026-09-14
Cross-currency taxonomy plan (2026-09-18)built-with-deviationsPR #921 (feature PR against staging, 2026-09-18)2026-09-19
Deep-history signup buildbuiltthree stages on feat/deep-history (v0.36.0); migration 0762026-09-14
Dune price mirror: staging evidence (2026-07-20)builtcompanion acceptance record for the mirror cutover (migration 054, v0.14.0)2026-09-14
Dune price mirror + coherent-mark refactorbuiltmigration 054 (v0.14.0); hardened again by the valuation policy, migration 098 (v0.58.0)2026-09-22
The v0.32.x validation fix wavebuiltPR #560, released in v0.34.1 (2026-08-10)2026-09-14
The window start when the wallet already holds positions at its floorbuiltPR #931 (fix/held-at-floor-window)2026-09-22
Lido Earn USD as a multi-strategy fund, August 2026: planbuiltv0.43.02026-09-14
Mark-gap per-line bridge — implementation planbuiltPR #802 (v0.56.0)2026-09-14
Plan: Consistent market vs redemption basis for non-numeraire assets and non-traded wrapperssupersedednever built as drafted; the valuation policy settled it instead, PR #826 (v0.58.0)2026-09-22
Money Market Funds tab, August 2026: planbuilt-with-deviationsPR #635, migration 086 (v0.44.0)2026-09-14
Plan: Morpho Blue isolated markets in the Repo markets tablesupersededmigrations 035 and 041 (v0.1.0 to v0.3.0); membership governance moved to morpho-markets-expansion-plan.md on 2026-07-082026-09-14
Morpho markets expansion: carries + registry-driven Repo marketsbuiltmigration 041 and scripts/morpho-discovery.ts (v0.3.0)2026-09-14
Portfolio performance rebuild: one total-return line + one accrual linebuilt-with-deviationsfeat/nav-rebuild (v0.32.0); partly superseded by the valuation policy (v0.58.0)2026-09-14
Pinned-basis class: zero-basis-by-construction for arb-pinned wrappersretiredbuilt July 2026 on feat/pinned-basis-class (v0.14.x); retired by the valuation policy, migration 099 (v0.58.0)2026-09-17
Pinned-basis classification: evidence record (1 pinned / 38 market)retiredevidence for the registry seeded in feat/pinned-basis-class (v0.14.x); retired with it in v0.58.02026-09-14
Portfolio 100k-Wallet Scale Plan — Event Ledger Architecturebuiltmigration 064 (v0.25.0), 072 (v0.27.0), 082 and 083 (v0.42.0)2026-09-14
The /portfolio "All" view — implementation planbuiltPR #843 (v0.59.0)2026-09-14
Portfolio coverage-consistency hardening — implementation planbuiltmigration 061 (v0.21.0)2026-09-14
Portfolio coverage expansion planbuilt-with-deviationsTranche 1 in PR #376 (v0.7.0); Tranches 2 to 5 folded into portfolio-taxonomy-coverage-plan.md; the BTC book retired by migration 077 (v0.36.0)2026-09-14
Plan: entry basis + dislocation P&L on portfolio carry tradesbuiltv0.2x; rebuilt on the current engine as src/lib/portfolio/v2/entry-basis.ts2026-09-14
Portfolio (read-only) — execution logbuiltappend-only companion to portfolio-read-only-plan.md; last row P29 records the old engine's retirement (v0.55.0)2026-09-14
Portfolio multi-strategy fund balances and earnings in redemption unitsbuilt-with-deviationsPR #8852026-09-16
Redemption display evidencebuiltCompanion evidence for PR #8852026-09-16
Portfolio data model: ledger-first rows, one derivation worker, values computed at read, venue adapter contract (2026-09-24)built-with-deviationsv0.71.0 (release PR #964, 2026-09-26; integration PR #961, comparator fix #963, report #962; migrations 114, 115, 116, 117)2026-09-28
Portfolio multi-wallet tracking — implementation planbuiltmigration 048 (v0.9.0) and migration 050 (v0.10.0)2026-09-14
The /portfolio "Other" tab — decision recordsupersededv0.29.0; replaced by the All view, PR #843 (v0.59.0)2026-09-14
Portfolio phase 2 — full PT accounting + Fluid position trackingbuiltmigration 044 (v0.3.0)2026-09-14
Portfolio (read-only) — implementation planbuiltmigrations 042 and 043 (v0.3.0); deviations recorded in portfolio-execution-log.md2026-09-14
Portfolio taxonomy & full-coverage planbuiltmigration 049 (v0.10.0); the BTC-book addendum of 2026-08-10 by migration 077 (v0.36.0)2026-09-18
Pricing categories, price sources and loopability (2026-09-22)built-with-deviationsPR #938 (feature PR against staging, 2026-09-23); migrations 110, 111 and 1122026-09-23
Pendle PT coverage in portfolio accounting (#811 program)builtPR #850, migrations 101 and 102 (v0.59.0)2026-09-14
Pendle PT maturity marker and redemption-index impairment planbuiltthe maturity marker in v0.53.0; the impairment factor in migration 101 and src/lib/portfolio/v2/pt-factor.ts (v0.59.0)2026-09-14
The PT row a bond trader would want: return breakdown and an exact locked-in ratebuilt-with-deviationsPR #940 (feat/pt-row-attribution)2026-09-23
sGHO (Aave Savings GHO) — portfolio + asset-profile support planbuiltmigration 053 (v0.14.0)2026-09-14
Plan: staging + prod environments with a promote-to-prod flowbuiltJune to July 2026: staging.creddit.xyz and .github/workflows/deploy-staging.yml2026-09-14
USD yield-token support batch, August 2026: planbuiltmigration 074 (v0.31.0)2026-09-14
USD yield-token coverage survey, verification run (API-precise), 2026-08-03builtdecision taken 2026-08-03 (usd-yield-batch-2026-08-plan.md); shipped in migration 074 (v0.31.0)2026-09-14
Valuation policy (#810) and yield-bearing assets: implementation planbuiltPR #826 (pieces A to H) and migrations 098, 099 and 100 in v0.58.0; the legacy sweep, PR #849, in v0.59.02026-09-22

What is still current ​

One or two sentences per plan, from its own header, on what in it still describes the product. A plan that is still open has nothing shipped yet and reads none.

PlanWhat is still current
Aave V3 / SparkLend account boundary — implementation plan (issue #717)The uncollateralized-supply carve-out it defines (issue #717) is live: an Aave or SparkLend supply the venue does not count as collateral is classified at the account boundary, in src/components/portfolio/signed-in-model.ts. The engine wiring, the switches and the two-reader framing it describes are gone.
Activity: semantic actions, four-column statement, and the same-direction double-count fixThe four-column statement and the semantic action vocabulary are what the portfolio Activity feed renders today, in src/lib/portfolio/v2/activity.ts. The engine and the flow ledger this document computes them from were replaced.
Plan: AI assistant (stages 1 and 2)The tool layer, the chat API, the prompts and the usage accounting still run, gated behind CHAT_ENABLED. Every UI surface stage 1 and stage 2 describe (the chat page, the dock, the /agent route) was removed in v0.51.0 and the assistant ships with no UI.
Plan: reduce chat assistant input-token costAll of it is the live cost discipline: the rolling prompt cache, the shaped tool payloads and the weighted per-user budget. Three modules cite this page by name (src/app/api/chat/route.ts, src/lib/agent/session.ts, src/lib/agent/message-shaping.ts).
Replaying positions that closed inside the backfill windowNothing. Positions that close inside the backfill window are covered by the deep-history build; read deep-history-plan.md for the shape that shipped.
Cross-asset view — implementation planThe membership rule survives and is still the rule: groupIsCrossAsset, the whole-account move, and the venue's unit of exposure. The fourth tab, the per-denomination return curves and the CROSS wire key do not.
Cross-currency taxonomy plan (2026-09-18)Cross-currency borrowing now covers every borrow no single currency runs through, a holding with no borrow against it is Repo lending or Smart repo lending whatever it settles in, and 'Not in the USD or ETH views' is replaced by a Not covered band that sits outside the All view's total and value history. That band holds the positions this product cannot value: a bare debt, a borrowing whose collateral has no price, and that same unpriceable collateral posted at a venue with nothing borrowed against it. The third shape is the single deviation from section 2.3, which files every debt-free holding with no currency book under Repo lending: a principal token settling into an asset creddit does not track has no unit to be stated in at all, so it keeps the 'Payout asset not tracked' reason and stays out of a band whose subtotal is a figure. Read-time only, no migration.
Deep-history signup buildThe signup-time history contract is live: the tiered backfill window, its span floor and the depth a new account is promised, in src/lib/portfolio/backfill.ts. The flow ledger and reader it writes through were replaced.
Dune price mirror: staging evidence (2026-07-20)Nothing describes current behaviour: this is a frozen staging validation record. The mirror it accepts is live and documented in the data pipeline.
Dune price mirror + coherent-mark refactorThe mirror is the historical market-price source behind every persisted mark, and every bar in it is HOURLY: the exact-minutes channel this plan designed alongside the hourly one had no caller after v0.55.0 and was deleted by the pricing categories plan on 2026-09-22 (migration 110, which also purged the rows it had written), so the cost model, the burst batching and the clustering this document describes for it are history. The MIRROR_EXTRA and basisClass registries it introduces were hand-kept constants in code and were replaced by the token registry in migration 099. DeFiLlama came PART of the way back on 2026-09-17 (#907, migration 109) and the distinction matters: it is not a fallback and it never picks a bar. It is a declared FEED on two named rows whose Dune tape does not exist (BTC.b, USDai), writing the same mirror table under the same spike gate and dark-feed alert, and it is admissible only for an idle or no-base row precisely because of this plan's own finding that an aggregate is too noisy to carry a basis line.
The v0.32.x validation fix waveNothing describes current behaviour. It is the adjudication record of the v0.32.x validation campaign, including the renegotiated P3 acceptance figure; the engine those figures were measured against has since been replaced.
The window start when the wallet already holds positions at its floorThe window rule it settles is live: a wallet that held a curve-starting position at its own history floor charts from that floor, with the position as an opening balance, and only a wallet that held nothing there has its start raised to its first curve-starting activity (heldCurveStartingAt + computeBackfillWindow in src/lib/portfolio/backfill.ts). The nine-wallet table in section 1 is a snapshot of the defect on 2026-09-22, not a standing list; those wallets are rebuilt by the gated release step, which is where their before/after is recorded. One line of section 5 is superseded by the shipped build: no injectable reader seam was built, as it decided, but the floor read's wiring and the single production call site are NOT left to the staging run and review alone. They are pinned at the source in backfill.test.ts, after round-1 review showed that hard-coding heldAtFloor: false at that call site, a complete revert of this fix, left all 6403 tests green.
Lido Earn USD as a multi-strategy fund, August 2026: planearnUSD ships as described: a listed multi-strategy fund with its own share-rate series, backfilled history, strategy brief and statistics tower.
Mark-gap per-line bridge — implementation planThe per-line mark bridge is live in the engine and documented as M21 in Metrics: a line with no mark at a reading is bridged from its own last valued point, never from another line's. The incident figures are history.
Plan: Consistent market vs redemption basis for non-numeraire assets and non-traded wrappersNothing of its mechanism, and the aggregator-mid tier it leans on in section 3 is itself retired (pricing categories, 2026-09-22): the live tick reads the same stored bars a settled snapshot does. The composition it proposes is now one function driven by the token registry (src/lib/portfolio/unit-prices.ts), which walks iETHv2 to stETH to wstETH exactly as section 1 diagnoses. The diagnosis is the record of why that function exists.
Money Market Funds tab, August 2026: planThe Money Market Funds tab, its eligibility gates and the fund registry are live. Six sections no longer describe what ships and are annotated in place where they sit.
Plan: Morpho Blue isolated markets in the Repo markets tableThe repo-tab integration and the market Type column it introduced are still on the lending page. The hardcoded top-2 selection and the discovery query here are not canonical; the registry owns membership.
Morpho markets expansion: carries + registry-driven Repo marketsThe registry-driven admission rule is still what decides which Morpho markets appear (morpho_market_registry plus the discovery cron, documented in Processes A.7). The route it calls /money-market-rates has been /repo-lending since 2026-08-21.
Portfolio performance rebuild: one total-return line + one accrual lineOne total-return line and one accrual line is still how the portfolio charts performance. Everything about the PINNED class is retired: those symbols no longer exist and valuation-policy-810-plan.md carries the current rule.
Pinned-basis class: zero-basis-by-construction for arb-pinned wrappersNothing the product computes or renders: the pinned basisClass was retired, every idle asset is marked off its own price feed, and the one surviving case (an asset that IS its book's own unit) is identityUnitAsset in src/lib/portfolio/unit-prices.ts. The surface-6 display path it left behind (the pinned note, the Market Depth pinned card and the synthetic pinned basis block) was deleted in #909.
Pinned-basis classification: evidence record (1 pinned / 38 market)Nothing. The registry it certifies no longer exists: BASIS_TOKENS and MIRROR_EXTRA are deleted and every asset the survey measured is Dune-marked. Kept as the evidence behind a decision that was later reversed.
Portfolio 100k-Wallet Scale Plan — Event Ledger ArchitectureThe event-ledger spine is the architecture the portfolio runs on: raw events, the dirty set and a recompose whose cost does not scale with the number of registered wallets. The dual-write, shadow-build and reader-flip machinery it schedules is gone, the flip having completed.
The /portfolio "All" view — implementation planThe All view is the portfolio's third tab exactly as section 1 settles it: every position at its dollar value in one list, with a value history in place of return curves. D2's "at its MARKET value in USD" is now literal in the Value column: every row on the view states dollars, whatever book the position settles in, from the server's own per-reading conversion — it read the row's own book for the first days after this landed. The engineering anchors in section 2 are as of v0.58.0, and the holdings sections since share one column grid across every band.
Portfolio coverage-consistency hardening — implementation planThe discovery certificate it defines is still the gate that decides whether a wallet may be served: an uncertified wallet withholds rather than reporting a partial book (src/lib/portfolio/ledger-v2-api.ts). The reader and ledger it hardens were replaced.
Portfolio coverage expansion planThe base-asset rule is the live coverage policy and src/lib/portfolio/buckets.ts cites this page for it. The BTC book it grants was retired in August 2026; bitcoin assets are shown outside the yield book.
Plan: entry basis + dislocation P&L on portfolio carry tradesEntry basis and dislocation P&L are still published per carry position, derived at read time from the dual-marked flows exactly as this plan argues. The v1 module and the column wiring it names are gone.
Portfolio (read-only) — execution logNothing on its own: it is the deviation record for the portfolio build, and the Portfolio page links it as such. Several rows name modules that have since been replaced.
Portfolio multi-strategy fund balances and earnings in redemption unitsMulti-strategy holdings state Balance in the fund's declared payout token; Yield earned stays in the fund's ETH or USD book like every other holdings band, a deviation from contract points 2 and 3 taken because a yield-bearing payout token made the earned figure read as performance above holding that token. Portfolio totals and return accounting remain in their established ETH or USD book.
Redemption display evidenceThis is the verification record for the payout assets and block-pinned conversions used for the portfolio's multi-strategy fund BALANCES. The earned-yield equivalent its body weighs no longer exists: Yield earned is stated in the fund's own ETH or USD book.
Portfolio data model: ledger-first rows, one derivation worker, values computed at read, venue adapter contract (2026-09-24)Rows follow the ledger, one worker derives, values are computed at read, adapters declare; the audit books explained-or-paged corrections. Deviations: the worker starts after the two backfills (§9 said before); R2's never-read leg (a leg the chain holds that no reading has read is served nowhere, §11); accepted corrections fold on the statement (R5c amended); openings are written for dust legs (R7 clarified); the stamp trails the chain by the ingester's 64-block finality margin (issue #965). Native ether has receipts since issue #966 (a block feed, WETH9's wrap and unwrap, the audit's transfer listing), which closes §11's incoming-ether-in-the-fold decision and the WETH wrap decision (#956 F1); its accepted cause now covers only a stretch whose sources could not answer. The contract release (old paths off, value columns dropped) is owed after a clean week.
Portfolio multi-wallet tracking — implementation planMultiple wallets per account, the wallet index, the add-wallet lock and the aggregate view are live (src/lib/portfolio/wallets.ts). The modules it calls the engine were replaced.
The /portfolio "Other" tab — decision recordDecision 2 survives intact and is still the rule: a holding outside coverage is shown at market value and nothing else. The label, the section split and the CROSS wire key do not.
Portfolio phase 2 — full PT accounting + Fluid position trackingFull PT accounting and Fluid position tracking are live, through the Pendle and Fluid readers and the pendle_markets registry. How a PT is valued was re-settled by the PT coverage program; where the two disagree, pt-coverage-811-plan.md wins.
Portfolio (read-only) — implementation planIts M1 to M9 methodology is still normative and Metrics cites it by number. Everything else (the routes, the modules, the engine wiring, the two-reader framing) was rebuilt and is history.
Portfolio taxonomy & full-coverage planSuperseded in part by the cross-currency taxonomy plan (2026-09-18), which added an eighth category (Smart repo lending), broadened Cross-currency borrowing to every borrow no single currency runs through, and replaced the catch-all band with Not covered. portfolio_tokens remains the source of truth for the taxonomy (src/lib/portfolio/types.ts). The BTC category was retired, which is what the addendum at the foot of the page records.
Pricing categories, price sources and loopability (2026-09-22)Every tracked asset is valued either at what it trades for or at the rate it redeems into, and which one it is is now a measured question rather than an asserted one: the declared mint and redeem terms, the six-hourly capacity series and the weekly market measurement all sit on the registry row, the verdict module reads them, and a candidate that disagrees with the declared category for fourteen straight days is PROPOSED on the alert line and never applied. The market limb's three bars are measured where each can be answered honestly: the trading-day count and the pool depth on chain, and the median daily volume on CoinGecko's reported figure across exchanges and DEXes, falling back to the on-chain median for a token it does not list and saying which it read. A pool side that is the pool's own share token is never counted as depth. loopable is a plain boolean for every row the test measures. The five asset moves of R11 shipped as written (sDAI, sUSDS, sUSDD and srUSDe redemption-priced, USD3 market-priced, USDD 2.0 added). The signed-in page and Synchronize price every market-priced asset from a live CoinGecko quote with DefiLlama behind it, corroborated before it is shown; the hourly tape is still what values every point of history, and the two are never mixed inside one series. The 5-minute bar channel, the pool-quote feed and the Kyber live tip are gone from the pricing path. Three things shipped differently from the body and are listed in section 9: R6 withholds only on a vendor CONTRADICTION rather than on any two off-band readings, section 8 declared USD3 instant where the measurement read a bound of zero (shipped capped), and the retired pool-quote vocabulary leaves the code entirely while the two cells migration 099 wrote in it are frozen in the registry's drift test, so that applied file is still matched to the byte.
Pendle PT coverage in portfolio accounting (#811 program)Decisions D1 to D7 are the live PT accounting rule: a PT is a composed asset over its payout asset, priced by ptRate before maturity and by the redemption-index factor at or after it, never at par.
Pendle PT maturity marker and redemption-index impairment planBoth rules are live: the matured-PT marker on the activity feed, and the redemption-index impairment factor that a matured PT is valued through. The hold-from-merge sequencing and the ledger it waits on are history.
The PT row a bond trader would want: return breakdown and an exact locked-in rateBuilt with D1 revised after review and three deviations. D1 (revised 2026-09-23, Fred chose the locked-rate convention): the expanded row states the OPEN POSITION since purchase at amortized cost, a point-in-time statement of the lots against the latest reading in the payout coin at par: carry = book value at the locked-in rates less cost, mark to market = market value less book value (split into the rate change since purchase and the price paid against the market then where every lot states its market yield), total = carry + mark to market exactly; the window-span breakdown, the trading-costs line and the unattributed line are gone. (1) The pre-window step runs at the end of EVERY wallet build (full replay or gap patch), unconditionally like the ledger merge, because backfillWallet's body is pinned by a test not to branch on the run's verdict; it is a no-op for a wallet with no bare PT held before its window. (2) D6 was revised during the build (Fred, 2026-09-23): a live 'Cost to sell now' (one Pendle hosted-SDK sell quote for the account's whole holding against its value at the moment of the quote, signed, fetched on open) through the new authenticated route /api/portfolio/pt-exit-cost, with pool liquidity and the position's share kept beneath it as context; pendlePrice moved to src/lib/data/pendle-swap.ts with the swap-cost route's behaviour unchanged. (3) The stamps land only on rows the resolver returned an entry for (a row nothing could be priced for keeps its mark-unresolved anomaly and no facts). Everything else is as written: stamps in meta (ptFactor/ptRate/ptMarkValue), one striking rule for every stamped acquisition (what was paid converted at the payout coin's own bar at the fill: the coin count for a payout-coin fill, the PT's own rate for a mint or a receipt valued at the mark; review S3), pre-window fills in migration 113 (renumbered from 112, which the pricing-categories branch also uses) admitted only on an exact explanation of the opening reading, PositionRow.ptDetail, and the expandable fixed-rate row.
sGHO (Aave Savings GHO) — portfolio + asset-profile support plansGHO is a wallet-tracked variable-rate USD asset with a full profile, as specified. The route it calls /asset-coverage is now /asset-profiles.
Plan: staging + prod environments with a promote-to-prod flowThe design is how staging runs: same box as prod, reseeded from a prod dump, no refresher crons of its own. The runbook is Deployment, not this page, and the current-state section describes the pre-staging world (there are backups and a migration ledger now).
USD yield-token support batch, August 2026: planThe batch shipped as approved: the USD3 asset profile, the registry rows, the srUSDe promotion and the five rate series. Migration 074 cites this page as its approved scope.
USD yield-token coverage survey, verification run (API-precise), 2026-08-03Nothing describes behaviour: this is a frozen measurement record, and src/lib/portfolio/valuation-sources.test.ts pins the anchors it published. Venue sizes are as of 2026-08-03 and have moved since.
Valuation policy (#810) and yield-bearing assets: implementation planR1 to R6 and Y1 to Y7 are the live valuation policy — one composition function, the token registry as the single source of truth for how an asset is valued, and the mirror as the only market feed — with ONE exception: Y5, the pool-quote feed, RETIRED by the pricing categories plan on 2026-09-22 (migration 110). Its two rows take the standard history chain, so the feed vocabulary is three kinds and feed_config carries only a routed token's saved query. The PT hooks section 8 leaves were taken up by the PT coverage program.

Private documentation. creddit.xyz