feat(L5): cost-of-debt pricing engine + financing instruments (ADR-0013, #616)#641
Merged
Conversation
…13, #616) One data-driven pricing engine for all liabilities. FinanceEngine.price() computes terms from org type + counterparty + typed reputation + current leverage (ADR-0013's thesis); generate_offers() mints 2-3 concurrent STANDING offers with expiry (ADR-0012) so a raise is a campaign with optionality — better standing buys a richer, cheaper menu. Instruments (bank loan, revolving credit, VC equity, directed grant, philanthropy, desperation lever) live in data/balance/defaults.json "financing.*"; coefficients (org/counterparty/rep/ leverage factors) are file-swappable. Non-cash terms (equity dilution scalar, board-seat stub, agenda strings) mint ledger riders. Computed interest is snapped to the 0.001 save-safe grid so minted entries survive save/load. Additive by construction: the sweep's take_loan path routes Ledger.loan directly and is unchanged — the L1 medians are byte-identical (do_nothing 14, safety_lean 16.5, reserve_heavy 19, greedy 7, loan_desperation 7, random_walk 8; MORTALITY PASS max 45). Bots keep exercising instruments via the existing levers; the new seek_financing/accept_financing_offer/pay_bills actions expose the engine to the game/UI without touching the calibrated sweep policies. Fix #566 (loan billing zeroes money AND crashes reputation): the reputation crash (50->7.5) was uncapped rep damage — now capped per bill (max_rep_per_bill), and the "magnitudes don't reconcile" is fixed by reconciling the default note (principal_billed = paid_from_cash + shortfall; only the shortfall converts to capped doom/rep). Adds the "pay the bill" early-repayment interaction (Ledger.pay_entry / pay_soonest_payable). BOUNDARY: money-side only — no doom_system or ledger->doom conversion touched (owned by the doom-streams lane). Non-cash riders are inert standing terms. Tests: test_finance_engine.gd (22) — pricing determinism + input sensitivity, availability gating, standing-offer optionality/expiry, quoted-term minting, #566 regression (capped default + reconciled magnitudes), early repayment, save-safe rates. Gates green: quick 355, integration 14, simulation 93; L1 sweep unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
PipFoweraker
added a commit
that referenced
this pull request
Jul 15, 2026
…5 structural finding Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PipFoweraker
added a commit
that referenced
this pull request
Jul 15, 2026
…gen on calibrated base Correction round (PR #642): the earlier work branched a stale origin/main (58a5a17, pre-calibration). Rebased onto true main (4a0f4ae calibration + ef06ec1 #641 L5 finance). Harness unification (fixes the two-month-runners smell): - Extracted the calibrator's run loop (test_l1_month_sweep.gd _run/_answer_windows) VERBATIM into l1_month_driver.gd — one shared driver. Parity verified: the calibrator's regenerated docs/balance/L1_sweep_runs.csv is BYTE-IDENTICAL to the tracked calibration copy, so the extraction is outcome-neutral and the calibration table stands unchanged. - test_l1_month_sweep.gd now delegates to the driver (LegacyPolicyAdapter); its policies + reporting are untouched. Deleted the parallel month_runner.gd. - reactive_adapter.gd bridges reactive policies (ReactivePolicy) to the driver, with the opening-prefix override seam for EE-10. - Renamed the reactive policy loan_desperation -> loan_desperation_reactive to avoid colliding with the calibrator's loan_desperation. Regenerated ALL data on calibrated constants (runs now last months, so strategy expresses): - Policy headline (docs/balance/POLICY_SWEEP.md): safety_lean 18.5 mo best, passive 14.0 (== calibrator do_nothing, cross-harness anchor), fundraise_first 14.0 beats loan_desperation_reactive 13.0, capability_rush 6.0 worst. T9 floor HOLDS for all reactive standard lines (measured, not gated). - Desperation solver: the lever does NOT pay — firing earlier/more is monotonically worse (lever@always -2.5 mo) and converts doom deaths into ledger deaths (1 -> 12). fundraise_first now uses the L5 raise-as-campaign flow (seek/accept offer, pay_bills). - Opening book v0: winners over-index on money-in (fundraise_small +1.56, apply_grant); losers on hire_capability_researcher (-2.11), take_loan, desperation_lever — cross-validating the solver. Doc caveats rewritten to the true base. Full suite green (quick 365 / sim 93 / integration 14). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4 tasks
PipFoweraker
added a commit
that referenced
this pull request
Jul 15, 2026
Verified current main (post #636/#638/#639/#640/#641/#643 merge stack) launches clean headless, plays a full month through the End Turn -> MonthController path, and passes the fast unit gate CI runs (345 tests, 0 failures, 36/36 files). Nine-stream doom, finance offers, and flight recorder all pass their unit suites with no wiring gaps found. No code changes needed -- green light for tomorrow. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
PipFoweraker
added a commit
that referenced
this pull request
Jul 15, 2026
…r (unified harness) (#642) * feat(balance): EE-9 reactive-policy framework + solver + EE-10 opening-book miner Tooling-only balance instruments (tests/manual, excluded from CI). No gameplay code changed. EE-9 · Reactive rule-policy framework (reactive_policy.gd): a policy = ordered (condition -> action) rules evaluated at the plan phase (action priority) and per response window (verb), reading a features snapshot (cash, runway, doom, reserve, ledger load, offers). Declarative + parameterized so future sweeps vary the dials. Named policies (sweep_policies.gd): fundraise_first (the new standard finance line — fundraise by default, loan only when runway < N months), balanced_operator, scout_heavy (proxy pending DQ-18 scouting), loan_desperation (naive foil), plus the five exploit-sweep dispositions re-expressed as reactive policies (unit-tested to reproduce the old _choose_actions priority — the "keep existing policies working" regression link). MonthRunner: deterministic headless driver of the real L1 month loop (plan -> day-tick playback -> window auto-pause -> boundary), shared by all three instruments. test_l1_month_sweep.gd — month-grain sibling of the exploit sweep (kept untouched). test_desperation_solver.gd — EE-9 solver-bot isolating the desperation lever (DQ-25). test_opening_book_miner.gd — EE-10: random opening prefix + fixed continuation, feature -> outcome deciles, raw CSV. Framework unit tests + full suite + determinism verified green. Outputs carry a prominent pre-migration caveat and a one-line regenerate command (DQ-21 re-run). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * refactor(balance): unify EE-9/EE-10 onto the calibrator's harness; regen on calibrated base Correction round (PR #642): the earlier work branched a stale origin/main (58a5a17, pre-calibration). Rebased onto true main (4a0f4ae calibration + ef06ec1 #641 L5 finance). Harness unification (fixes the two-month-runners smell): - Extracted the calibrator's run loop (test_l1_month_sweep.gd _run/_answer_windows) VERBATIM into l1_month_driver.gd — one shared driver. Parity verified: the calibrator's regenerated docs/balance/L1_sweep_runs.csv is BYTE-IDENTICAL to the tracked calibration copy, so the extraction is outcome-neutral and the calibration table stands unchanged. - test_l1_month_sweep.gd now delegates to the driver (LegacyPolicyAdapter); its policies + reporting are untouched. Deleted the parallel month_runner.gd. - reactive_adapter.gd bridges reactive policies (ReactivePolicy) to the driver, with the opening-prefix override seam for EE-10. - Renamed the reactive policy loan_desperation -> loan_desperation_reactive to avoid colliding with the calibrator's loan_desperation. Regenerated ALL data on calibrated constants (runs now last months, so strategy expresses): - Policy headline (docs/balance/POLICY_SWEEP.md): safety_lean 18.5 mo best, passive 14.0 (== calibrator do_nothing, cross-harness anchor), fundraise_first 14.0 beats loan_desperation_reactive 13.0, capability_rush 6.0 worst. T9 floor HOLDS for all reactive standard lines (measured, not gated). - Desperation solver: the lever does NOT pay — firing earlier/more is monotonically worse (lever@always -2.5 mo) and converts doom deaths into ledger deaths (1 -> 12). fundraise_first now uses the L5 raise-as-campaign flow (seek/accept offer, pay_bills). - Opening book v0: winners over-index on money-in (fundraise_small +1.56, apply_grant); losers on hire_capability_researcher (-2.11), take_loan, desperation_lever — cross-validating the solver. Doc caveats rewritten to the true base. Full suite green (quick 365 / sim 93 / integration 14). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(balance): regenerate desperation-solver report with dose-response bullet Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * balance(EE-9/EE-10): regenerate on nine-stream doom (post-#643); caveats -> stream base Merged origin/main (74074c8, ADR-0015 nine-stream doom). Framework is orthogonal to the doom internals — clean merge, no conflicts, and all three instruments ran clean against stream-based doom (no breakage). Refreshed numbers + caveats now read "on nine-stream doom (post-#643)" instead of "pre-migration". Ordering is migration-robust: - Policy sweep: safety_lean 18.0 best, balanced_operator 16.0, fundraise_first 14.5 (still beats loan_desperation_reactive 13.0), passive 14.5 (~= calibrator do_nothing 14.0, cross-harness anchor holds), capability_rush 7.0 / loan_hoard 5.0 worst. T9 HOLDS for all reactive standard lines. - Desperation solver: the trap SURVIVED and got STEEPER on stream doom — lever@always now -5.0 median months (was -2.5), doom->ledger death conversion total (2 -> 12/12). Added two bullets to DESPERATION_SOLVER.md so the divergence isn't misread: the solver (isolates the mechanic) is the trap's instrument; the opening book's near-neutral lone-lever signal is a lever washed out among random picks, not a contradiction. - Opening book: winners over-index on money-in + doom-down (apply_grant +1.67, fundraise_big, publish_paper); losers on safety_research, take_loan, hire_capability_researcher. Determinism re-verified (policy sweep identical across runs). Full suite green (quick 355 / sim 93 / integration 14). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
PipFoweraker
added a commit
that referenced
this pull request
Jul 15, 2026
Developer-facing architecture map (audience: future junior dev). Maps each major system to its code and deciding ADR(s), with honest built/partial/designed status. Preserves the prior funder pitch at ARCHITECTURE_FUNDERS.md. Written against the L1 wave (month engine #636, nine-stream doom #643, finance #641, calibration #638, honest CI #640). Surfaces coherence-check findings in §7. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lane L5 · ADR-0013 · closes #616, fixes #566. Design-surface lane — Pip reviews, do not auto-merge.
What
One data-driven pricing engine for all liabilities plus the standing-offer raise flow, and the #566 fix — all money-side (the doom-streams lane owns doom conversion; this branch never touches
doom_systemor ledger→doom).1. Pricing engine (
FinanceEngine.price, ADR-0013 thesis)rate = base × org_factor × counterparty_factor + leverage·penalty − (rep/100)·relief, clamped and snapped to the 0.001 save-safe grid (probe-verified against the real full-precision JSON save path — calibration open-Q #2), so minted entries survive save/load. Coefficients live indata/balance/defaults.jsonfinancing.*(file-swappable per L9).2. Instruments (data-driven table)
3. Offer generation with optionality (ADR-0012)
generate_offers()mints 2–3 concurrent standing offers with anexpiry_turn; better standing → richer/cheaper menu. Seed-deterministic (WS-0). New actionsseek_financing/accept_financing_offer/pay_billsexpose the flow; accepted offers mint entries carrying the quoted terms (menu is honest). Non-cash terms mint inert ledger riders (equity/board seat = DQ-7 stub; agenda = the governance strings bill).4. Fix #566
max_rep_per_bill).ledger_defaultnote now recordsprincipal_billed = paid_from_cash + shortfall; only the shortfall converts to (capped) doom/rep.Ledger.pay_entry/pay_soonest_payable).No regression
The sweep's
take_loanpath routesLedger.loandirectly and is unchanged — L1 medians byte-identical: do_nothing 14, safety_lean 16.5, reserve_heavy 19, greedy 7, loan_desperation 7, random_walk 8;MORTALITY_CHECK max_months=45 → PASS.Tests
test_finance_engine.gd(22 tests, 69 asserts): pricing determinism + input-sensitivity, availability gating, standing-offer optionality/expiry, quoted-term minting, #566 regression (capped default + reconciled magnitudes), early repayment, save-safe rates. Gates green: quick 355 · integration 14 · simulation 93 · L1 sweep unchanged.Deferred / boundary
reputation/nonprofitdefault (their first-class GameState fields are owed by the ADR-0010 typed-attention and DQ-4 char/org-creation lanes).🤖 Generated with Claude Code