Versions and rulings
This chapter records the early rewrite and program rulings through specification v1.6, dated 3 September 2026. It is a historical record, not the current release manifest. Later model and audit work is documented in the relevant methods chapters and repository; the running engine reports its specification, build and data identity at /api/forwardflow/health. Read it when a number in an older document does not match what the engine prints today, or when a term in an older document is not in the glossary.
Two rules govern what follows. The source defines the implemented calculation; a disagreement with the documented intent is a review finding. Each formula below names its implementing function. The spec is the intent: the version table is drawn from the change blocks at the top of the specification, which record what changed and why, in the order it happened.
How to read the dates
A spec version is a number the specification carries (the table here covers v1.0 through v1.6). It changes when the engine’s definition changes. A ruling is a decision by Marc on a program term or a modelling choice, cited here by date and decider, for example “Marc, 2026-08-22”. A ruling is applied by a spec version, sometimes weeks later. The gap matters: from 22 August to 3 September the engine still priced the July product while the program had moved on. The v1.5 change block is where the September rulings caught up with the code.
A Model Card is a third kind of document. It stamps one configuration and one set of figures for a data room. It cites the spec version it was run on, and records whether the engine owner has accepted it; a draft is not a stamp. The lineage is at the end of this chapter.
Current release card
The v3.3 model card, updated 14 September 2026, documents engine/API 0.7.0 guided MCP, authorized by Marc for research release that day. It retains the 0.6.1 USD/BTC measurement boundaries and model mathematics. Deployment verification is recorded separately; actual Claude conversation acceptance remains pending manual testing, and independent model approval has not been recorded. The preceding authorized 0.6.1 release has its own deployment record. The historical card sections and numerical stances below describe prior configurations, not new workspace defaults. The repository archives v2.1 under docs/model-cards/.
Spec versions
| Version | Date | What changed | Why |
|---|---|---|---|
| v1.0 | 2026-07-10 | The rewrite itself. One job: the economics of a Holder buying BPA paper of any term. Hybrid verdict: keep the double-entry ledger, the exact rust_decimal money math, the Brownian-bridge path generator and the API; scratch-build the domain (Agreement, exits, fees). M0 closed-form fixtures done the same day. | The legacy simulation modelled a different program (1.92×, 120 months, warehouse, bonds). Its semantics would have fought every line. |
| v1.1 | 2026-07-10 | Term length a true parameter: payment, fee rate, hazard shape and outputs all derive from it. “Payment 1 to BTC Now” generalised to the first N payments (origination_payments, default 1). The Python actuarial engine demoted from oracle to directional reference; acceptance rests on invariants. | Marc: “5yr” is a default, not an assumption. Reproduction of a differently specified model is not a test. |
| v1.2 | 2026-07-11 | Haircut and market-sale cost promoted to inputs #15 and #16. The stop sale (then liquidation) corrected: sized to the remaining schedule, never the whole coin; residual coin back to the Buyer; no sale excess to BTC Now. Per-Agreement shortfall in dollars in the drill-down. | Marc, 2026-07-11: the paper’s owner is entitled only to the cash component, capped at the Agreement. Superseded for the residual on 2026-09-03 (see below); “BTC Now takes fees only” survives. |
| v1.3 | 2026-07-11 | Inputs #17 shock designer, #18 origination window and runoff, #19 inverse price solver. The Assumption Tornado with a golden reference. The Scenario Shelf (S1 to S12, plus S13). | Merged from a parallel spec session. Cleaner crash instruments than moving bridge endpoints; the tornado is the one-picture sensitivity a reader asks for first. |
| v1.4 | 2026-07-12 to 07-13 | No static haircut (default 0); the forced sale priced at the following month’s mark. Par as the default purchase price (purchase_pct_of_strike 1.00, $60,000; was 1.05, $63,000). Input #20 intramonth strike dispersion. Input #22 early-completion take-profit gate. Custom per-year stop timing. The tie-out audit (an independent TypeScript re-derivation of every figure). Input #23 drawdown-scaled hazard, which ties the deterministic crash grid to the Python oracle within ±0.3 pp. Break-even heatmaps, stamped exports, the tornado golden check. The pooled-vehicle seat (input #21) built, then removed on 2026-07-12. Cockpit defaults 1%/yr fee and dispersion ON. Hosting hardening with byte-identical outputs. | Marc, 2026-07-12: par is the neutral anchor for the negotiation; a one-coin sale has no market impact, so the clock is priced by time on the path, not by a haircut. Marc, 2026-07-12, on input #21: recycling multiplies wealth, never the rate, so the paper’s IRR is the analysis and a second engine mode carries no information. |
| v1.5 | 2026-09-03 | The September program. The stop replaces the old sale: day 16 is the Stop Date, the coin is sold for dollars 18 days after the missed payment (input #24 stop_sale_lag_days), the R-1033 waterfall pays the Holder first, refunds the Buyer up to what he paid, and leaves the surplus with the Holder. The fee is a flat 5% of every delivered dollar (servicing_fee_rate replaces base_fee_pa). Early completion is cash-only. Horizon + 1. Vocabulary locked. The Behavior Engine parked. | Marc’s rulings of 2026-08-22, 08-31, 09-02 and 09-03, applied as Phase 0 of the build plan. The engine had been seven weeks behind the program. |
| v1.6 | 2026-09-03 | The exposure layer: the two lines, coverage, the exposure ladder, PD·LGD·EAD per vintage, Greeks by bump-and-revalue, the rational walk-away frontier as the fifth behavior mode (input #25). One seeded draw stream per Agreement (engine.rs::agreement_rng). POST /api/forwardflow/risk and the Risk desk page. | Marc’s “start” on Phase 1. The bumps are sensitivities only if a bump changes decisions and never the random numbers behind them, hence the per-Agreement streams. |
Two versions deserve a sentence each beyond the table.
v1.4 is the longest change block because it contains a reversal. The pooled-vehicle seat (change 3), the evergreen view (change 8) and the evergreen framing of that vehicle (change 9) were built and then removed in the second change 11, committed 2026-07-12, after the IRR-versus-wealth discussion: recycling compounds wealth, but it cannot raise the rate above the paper’s own. The removed implementation lives in git history. Nothing in the current engine models a pooled vehicle. The paper’s own IRR is the Holder’s rate, and a wrapper returns that rate less idle-cash drag.
v1.5 is the version that changed the product rather than the method. The Model Card v2.0 draft says so in its first heading. Every figure in a document dated before 3 September 2026 was produced under v1.4’s economics and should be read with the translation table below in hand.
Rulings the engine implements
Each row names the ruling, the decider and date, and the spec version that applied it. Where a ruling was later superseded, the row says so.
| Date | Ruling | Decider | Applied by |
|---|---|---|---|
| 2026-07-10 | Term is a model parameter; the first N payments go to BTC Now, N = 1 by default. | Marc | v1.1 |
| 2026-07-11 | The residual-coin correction: on a stop the sale is sized to the remaining schedule; coin beyond that returns to the Buyer; there is no sale excess to BTC Now. | Marc | v1.2. Residual rule superseded 2026-09-03; “fees only” kept. |
| 2026-07-12 | No static haircut. The delay between the missed payment and the sale is priced by selling at the next month’s mark. | Marc | v1.4. Refined by v1.5 (sale at day 18, interpolated). |
| 2026-07-12 | Par is the default purchase price: $60,000 on the base coin, not $63,000. The premium remains a free input. | Marc | v1.4 |
| 2026-07-12 | Buyers may stop on a custom per-year timing; Buyers complete early only above a take-profit threshold when the gate is on. | Marc | v1.4 |
| 2026-07-12 | The pooled-vehicle seat (input #21) is removed: a vehicle holding the paper needs no model of its own, because the paper’s rate is the vehicle’s rate less idle-cash drag. | Marc | v1.4 change 11 (the second), committed 2026-07-12 |
| 2026-07-13 | Cockpit base case: fee 1%/yr (was 0.75%), strike dispersion ON. | Marc | v1.4 change 12. Fee form superseded 2026-08-31. |
| 2026-08-05 | The pricing stance is a zero-drift bootstrap at trailing-24-month volatility; the 2016-regime construction is superseded. Model Card v1.0 stamped. | Marc | Model Card v1.0 and v1.1 (no engine change) |
| 2026-08-05 | The late window is 15 days, not 25: the Agreement already said so, and the engine’s 25-day wording was conformed to it. The engine notes the window as descriptive at monthly resolution. | Marc, confirming the Agreement’s text; restated as R-1035 on 2026-08-22 | Model Card v1.1. Made exact by v1.5 (input #24). |
| 2026-08-06 | Model Card v1.1 stamped after the price series refresh through July 2026. | Marc | Model Card v1.1 |
| 2026-08-22 | The stop: a recorded sale for dollars; refund = min(paid, max(0, proceeds + paid − Purchase Price)); the Buyer never receives more than he paid. Day 16 after a missed payment is the Stop Date (R-1035). No eligibility check and no sizing. The sale within two business days (R-1037). | Marc | v1.5 |
| 2026-08-31 | The servicing fee is 5% of every dollar sent to the Holder; the send is the fee event, termination sends included. | Marc | v1.5 |
| 2026-09-02 | Vocabulary: Buyer and Holder, numbered from 0; Transfer and Sale; Partner. | Marc | v1.5 |
| 2026-09-03 | The surplus above the Purchase Price on a stop sale stays with the Holder; BTC Now takes its 5% of every delivered dollar and nothing else. | Marc | v1.5 |
| 2026-09-03 | The Holder’s stop-sale delivery is in dollars; there is no in-kind residual term. A Holder who wants coin buys it with the proceeds. | Marc | v1.5 change 8. A reinvest-into-coin view is planned as the Holder’s own act. |
| 2026-09-03 | The Behavior Engine v0 is parked on its own branch; its rational boundary is lifted into the main engine; its four-channel decomposition goes to the memorandum as prose. | Marc | v1.5 change 7, v1.6 change 6 |
| 2026-09-03 | Lockouts reinstated: seven days after two lapsed windows, six months after a stop. | Marc | Noted in v1.5 change 8. Not modelled. |
| 2026-09-03 | Phase 1 of the build plan: the exposure layer. | Marc | v1.6 |
Two items are flagged in the spec as term-sheet questions rather than rulings, and the engine has taken a position on each pending the answer. Whether payment 1 sits in the Buyer’s refund base is modelled as yes, on Marc’s phrase “the maximum he paid”. The sale standard (venue, deadline, price against the index) is not yet written into the Agreement; the engine assumes a market sale at the path price less 25 bp. Both are listed in limits.
Three rulings in numbers
The base terms throughout: a $60,000 coin, multiple 1.475×, Purchase Price $88,500 (contract.rs::ContractTerms::terminal), 60 monthly payments of $1,475.00 (contract.rs::ContractTerms::schedule), payment 1 to BTC Now, 5% servicing on every dollar delivered to the Holder, the Holder buys at par, the stop sale 18 days after the missed payment, 25 bp sale cost.
The par default of v1.4
Before v1.4 the default purchase price was 105% of the strike, $63,000. From v1.4 it is par, $60,000 (engine.rs::SimConfig::purchase_pct_of_strike, default 1.00). The M0 fixtures were generated at 105% and their tests pin that value, so a fixture figure and a cockpit figure at the same inputs differ by the $3,000 premium and nothing else. A reader of the July file set’s “Buyer Pack 105” document is reading the pre-v1.4 anchor.
The fee at send
From v1.0 through v1.4 the fee was a rate per year multiplied by the term:
\[ \text{fee rate} = \text{base_fee_pa} \times \frac{\text{term months}}{12} . \]
At 1%/yr and 60 months that is 5%, and at 0.75%/yr it is 3.75% ($55.31 per payment). At 36 months the same 1%/yr gave 3%. Since v1.5 the rate is the input itself, servicing_fee_rate, flat at 5% whatever the term (contract.rs::ContractTerms::fee_rate). At the base terms nothing moved: 5% of $1,475.00 is $73.75 to BTC Now and $1,401.25 to the Holder on every delivered payment (fees.rs::FeeState::split, with cumulative rounding so the lifetime total is exact to the cent). At any other term the fee did move, which is why the acceptance item that once read “total fee rises linearly in term” (spec §6.5) now asserts the opposite; the test that carries it is term_parametricity_sweep_is_smooth_and_monotone. The M0 fixtures keep their historical basis by pinning the flat rate per term: 2.25%, 3%, 3.75%, 5.25% and 7.5% for 36, 48, 60, 84 and 120 months.
What the 2026-08-31 ruling added, beyond the flat form, is scope. The fee is on every send, the stop-sale delivery included. The engine had charged the fee on sale deliveries since v1.0 (spec §3.2: “in the plus we also get our fee”); the September rule makes that the program’s own term rather than a modelling convention.
The residual-coin correction and the waterfall that replaced it
Take a Buyer who makes twelve payments and misses the thirteenth. He has paid in \(A = 12 \times 1{,}475 = 17{,}700\), payment 1 included. The remaining schedule is \(R = P - A = 70{,}800\). The missed date is month 13; the sale is 18 days later; the cash posts at month 14, which is \(\mathrm{round}(13 + 18/30.4375)\). The proceeds are the interpolated path price less the sale cost, \(V = S \times (1 - 0.0025)\) (engine.rs::stop_sale). The waterfall is
\[ \text{refund} = \min\big(A,\ \max(0,\ V + A - P)\big), \qquad \text{delivered} = V - \text{refund}, \]
with the Holder receiving the delivery less 5%, the shortfall \(\max(0, R - V)\) and the surplus \(\max(0, V - P)\) recorded per Agreement.
| Coin at $30,000 | Coin at $120,000 | |
|---|---|---|
| Proceeds \(V\) | $29,925.00 | $119,700.00 |
| Refund to the Buyer | $0 | $17,700.00 (capped at \(A\)) |
| Delivered to the Holder, gross | $29,925.00 | $102,000.00 |
| Fee to BTC Now on the delivery | $1,496.25 | $5,100.00 |
| Holder receives | $28,428.75 | $96,900.00 |
| Shortfall against the schedule | $40,875.00 | $0 |
| Surplus above the Purchase Price | $0 | $31,200.00 |
Both columns were produced by the live engine on a one-Agreement custom path that steps at month 12 and stays flat: the left by a conviction walk at month 13, the right by a hazard draw at age 12 under custom per-year timing, since the conviction rule cannot fire while the coin is in the money. Every cell reproduces from the four formulas above. The test stop_sale_regime_one_exact_cents pins a sibling case (a walk at month 7 on a path that drops to 60%) cent by cent, timing included; stop_sale_waterfall_identities_across_regimes checks the identities across all three regimes on one path.
Under v1.2 through v1.4 the right-hand column read differently. The sale was sized to the remaining schedule: only enough coin to raise $70,800 was sold (at the next month’s mark from v1.4; on the missed date, less the haircut, in v1.2 and v1.3), and the coin beyond that (worth about $49,200 at that price, before the sale cost) went back to the Buyer as coin. The Holder received $70,800 less the fee. The v1.2 rule was itself a correction: before it, the whole coin was sold and the excess above the schedule went to the paper’s owner. The September ruling returns the surplus to the Holder, but in a different shape. The Buyer is now refunded in dollars up to what he paid, so the Buyer’s position in the up case is $17,700 of refund rather than $49,200 of coin, and the Holder’s is $102,000 gross rather than $70,800.
The left-hand column barely changed between the two rules. When the coin is worth less than the schedule, both rules sell it all and both leave the same shortfall. That is why the Model Card’s zero-drift medians moved by a tenth of a point between v1.1 and v2.0 while the paced replay median moved from 12.9% to 21.5% and the single-vintage replay median from 19.7% to 47.9%. The difference between the rules is the up case, and on Bitcoin’s own history the up case is large.
One founder invariant needs restating because the v1.2 wording no longer holds. “We can never keep more than we are owed” described the v1.2 sale and is superseded for the Holder. What stays true and stays tested is narrower: BTC Now takes fees only, the first N payments and the flat 5%, never a share of a stop sale. No input may give it one.
What a reader of an older document must translate
The July memorandum, the diligence Q&A, the drawdown exhibit and every engine document dated before 3 September 2026 describe the earlier product. Six terms recur. Each has a current equivalent.
| Older document says | Today it means | Where it changed |
|---|---|---|
| The 25-day clock | Day 16 after a missed payment is the Stop Date; the sale is 18 days after the missed date, input #24, priced on the path by interpolation. | 15 days confirmed against the Agreement 2026-08-05 and restated as R-1035 on 2026-08-22; made exact by v1.5. |
| $63,000 | The Holder buys at par, $60,000. The 105% premium is a free input, not the anchor. | v1.4, Marc 2026-07-12. |
| The made-whole lockout | Early completion is the Buyer paying the remaining schedule in cash and taking the coin. A stop is refunded by formula. Lockouts exist in the program (seven days, six months) and are outside the engine. | v1.5; lockouts reinstated 2026-09-03, not modelled. |
| The advance structure, “45% advance” | There is no advance. The Holder buys the whole receivable at par and carries the full coin basis from day one. The two lines in exposure.rs::two_lines are the replacement exhibit. | Never an engine input: the July exhibit priced an alternative structure the program did not offer. Redrafted for the par Holder on 2026-09-03; the two lines are v1.6. |
| “Purchaser”, “Purchaser Analytics” | The Holder; the report page is now Scenario report. | Vocabulary, Marc 2026-09-02. |
| “the fund”, “forward-flow buyer” | The Holder. There is no pooled vehicle in the engine. | Input #21 removed 2026-07-12; word retired 2026-09-02. |
Some detail on each.
The 25-day clock. From v1.0 the engine’s comments said 25 days, and from v1.4 the delay was priced by selling at the following month’s mark, one full month after the missed payment. On 5 August 2026 Marc pointed out that the Agreement’s window was 15 days, not 25 (a payment up to 15 days late carries no fee and no penalty); the engine’s documents were conformed, the 22 August ruling restated the window as R-1035, and Model Card v1.1 recorded the engine’s clock as descriptive at monthly resolution, since a 15-day and a 25-day clock both sat below the model’s step. v1.5 made the timing exact: the sale lands at stop_sale_lag_days after the missed date, default 18 (day 16 plus two business days), and the price is interpolated log-linearly between the path’s monthly marks, so \(\text{lag} = 0\) sells at the missed date’s mark and \(\text{lag} \approx 30.4\) at the next. At monthly resolution the difference between 18 and 30 days is a fraction of one month’s price move, and the test above pins the ordering of the three prices.
The $63,000 price. The July diligence script deflects a request to lend against the receivables with “the offer is whole-receivable flow at $63,000”. The number is the 105% default of v1.0 through v1.3. The structure (“whole receivables, one structure”) still holds; the price does not. Every current figure is at par, and the inverse price solver (input #19) is the tool for any other price.
The made-whole lockout. The July diligence answer to “why won’t Buyers churn” was that a profitable re-entry mathematically implies an exit that was not made whole, which triggered a six-month lockout. In the September program the exit is a stop with a refund by formula, so the arithmetic of that answer has to be re-run against the waterfall. The engine’s lockouts are out of scope; what it offers instead is the rational walk-away frontier of v1.6 (boundary.rs::rational_frontier), which prices the walk against continuing or completing early, with a walk cost as an input. The current view of churn is a question for the behavior chapter, not a closed answer.
The advance structure. The July drawdown exhibit’s first finding, that a 30% drop in Bitcoin costs nothing, was true of a senior advance at 45% of the coin’s day-one value, an alternative structure the program never offered. It is not true of a Holder who pays par. The v2.0 draft of that exhibit says so and retires the sentence: at par a permanent −30% costs yield, not capital; capital loss begins near −60% inside a year; the 2021–22 shape is the worst cell. The engine’s own statement of the same fact is the capital line, which starts at 1.05 of entry at month 1 (payment 1 went to BTC Now and every delivered dollar carries 5%) and reaches zero at month 44. Those two values are pinned by test in v1.6.
Purchaser and the fund. Two vocabularies had grown, one in the legal drafts and one in the developer spec, and “trade” alone named three different things. The 2026-09-02 ruling ended it: the paying side is the Buyer, the receiving side the Holder, Holder 0 is always BTC Now, the paying side changes hands by Transfer and the receiving side by Sale, and a Partner is anyone paid a cut of BTC Now’s fees. The words Purchaser, customer, obligor, forward-flow buyer, fund, liquidation and non-performance left every user-visible string in v1.5. Engine identifiers did not change: Owner is the Holder’s ledger entity, Obligor the Buyer’s, non_performance an exit tag, MakeWholeDelivery the ledger kind of an early-completion payoff, and base_fee_pa survives only in the M0 fixture file and in the spec’s history. A reader of the code should map them and not be alarmed.
Model Card lineage
Three cards exist. Each states a full configuration, a hazard model, a path process and a results table at seed 42, sufficient for reproduction. The results are Holder IRRs.
| Card | Date | Stamp | Spec | The pricing construction | Paced zero-drift median | Single vintage zero-drift median | Single vintage replay median |
|---|---|---|---|---|---|---|---|
| v1.0 | 5 August 2026 | Stamped by Marc, 2026-08-05 | v1.4 | Zero-drift bootstrap from the 2016-onward regime, about 68% realized; the 25-day clock, next month’s mark, capped at the schedule, excess to the Buyer. | 9.8% | 13.7% | 19.8% (100 starts) |
| v1.1 | 6 August 2026 | Stamped by Marc, 2026-08-06 | v1.4 | Zero-drift bootstrap at trailing-24-month volatility (July 2024 to July 2026, 41.4% realized) after the series refresh to 174 bars; the 15-day window, descriptive at monthly resolution. | 13.1% | 15.0% | 19.7% (113 starts) |
| v2.0 DRAFT | 3 September 2026 | Pending Marc’s stamp | v1.6 | Same construction; the September program: the R-1033 waterfall with the surplus to the Holder, 5% flat, cash-only early completion, 84-month paced horizon. | 13.1% | 14.9% | 47.9% (113 starts) |
What moved between v1.0 and v1.1 was the volatility regime, not the product. Marc ruled on 5 August that the modern-regime window included market microstructure that no longer exists, so the pricing stance became current volatility with the full-history construction kept as the printed stress. The v1.0 stamp did not carry across the construction swap, which is why v1.1 needed its own.
What moved between v1.1 and v2.0 was the product. The card’s own reading is the right one: on a driftless path the September waterfall and the July sale deliver almost the same cash, so the zero-drift medians moved by a tenth of a point (the v1.5 morning run printed 13.0% and 14.8%). Every right tail and every replay row moved a lot, because a Buyer who stops while the coin is worth more than the Purchase Price now hands the surplus to the Holder, and the engine produces such stops at half the baseline hazard through the ×0.5 in-the-money multiplier. How often a Buyer with a winning coin stops is the least-evidenced behavior in the model, and it now drives the upside. The card attaches that sentence to every replay figure.
The v2.0 draft carries one more note a reader should not mistake for a product change. Its figures were re-run on v1.6, which gave every Agreement its own seeded draw stream so that bump-and-revalue Greeks are sensitivities rather than draw noise. The same seed therefore draws differently from the v1.5 run of the same morning: the zero-drift medians moved by a tenth of a point and the single-vintage replay median from 38.2% to 47.9%. That is the in-the-money-stop sensitivity restated. On Bitcoin’s own history a handful of such stops per vintage moves a median by ten points.
The stamp is the act. Until Marc stamps v2.0, the figures a Holder may be shown are v1.1’s, and v1.1 describes a product that no longer exists. The verification chapter gives the one command that reproduces each card’s table.