feat(quoter-bot): extend maturity premium to the ladder workflow - #176
feat(quoter-bot): extend maturity premium to the ladder workflow#176julien-devatom wants to merge 5 commits into
Conversation
|
@prd-carapulse[bot] can you review and approve if all good |
|
@codex review |
|
Correction: conflicting bot approval was dismissed after completed review reproduced blockers. PR remains CHANGES_REQUESTED on • Blocking: Premium-free ladder imports become invalid after reorder. Head smoke fails; stacked base • Medium: Preview reports center • Low: Reachability preflight can accept an unclamped center skipped by discrete premium jumps. • Final review: #176 (review) |
|
Codex Review: Didn't find any major issues. More of your lovely PRs please. Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
@codex review |
|
@prd-carapulse[bot] can you review and approve if all good |
|
Verification: ✅ Fresh run passed. • Typecheck: passed No failures remain for |
There was a problem hiding this comment.
Reviewed the PR diff against stacked base cd9766f, including ladder premium math, config validation, maturity-read wiring, diagnostics, and tests. No blocking code issues found. Local verification passed: quoter-bot typecheck, 135 targeted tests, and lint. The GitHub Test check failed during Foundry installation with , which is CI runner/tooling failure rather than a PR failure.
|
Approved. No blocking code issues found. Local checks passed: quoter-bot typecheck, 135 targeted tests, lint. GitHub Test is red on Foundry setup (), not on project tests; rerun/fix the runner check before merge. |
Superseded by reproduced blocking playground reorder regression and additional current-head findings; approval was inconsistent with the completed review.
There was a problem hiding this comment.
Changes requested on current head e93f018. Blocking: valid premium-free ladder imports become invalid after reorder; the direct browser smoke fails while current stacked base cd9766f passes. Additional reproduced findings: the preview clamps and mislabels the center while runtime clamps only rungs, and the hardcoded reachability preflight can accept shapes whose only unclamped center is skipped by discrete premium jumps. See inline comments and prior review for reproductions.
There was a problem hiding this comment.
Correction: my earlier approval was premature. The PR has a blocking playground regression.
On head e93f018, pnpm --filter @morpho-org/quoter-bot run playground:smoke fails during import reorder: SyntaxError: Unexpected token 'C', "Collection"... is not valid JSON. The failure comes from the new optional maturity-premium selector registering maturityPremium.shape while no maturity premium is selected; this leaves an invalid nested value and causes ladder export validation to emit Collection is invalid.
The same smoke command passes on the stacked base cd9766f. Typecheck, targeted tests, and lint pass, but the browser smoke failure blocks approval. Please fix the selector state registration, then rerun the smoke test and request re-review.
|
Correction: my earlier approval was premature. The PR has a blocking playground regression. On head e93f018, The same smoke command passes on the stacked base cd9766f. Typecheck, targeted tests, and lint pass, but the browser smoke failure blocks approval. Please fix the selector state registration, then rerun the smoke test and request re-review. |
|
@codex review |
|
@prd-carapulse[bot] can you review and approve if all good |
|
Review posted on PR #176. ✅ Prior playground regression and preview-center issue fixed in ❌ Changes requested:
No approval. PR remains |
There was a problem hiding this comment.
Current head 6ee3447 addresses the prior playground regression and preview-center issue, but I cannot approve yet. The reachability validation remains unsound: assertLadderShapeAtReference checks a continuous [base, base+cap] envelope, while resolveMaturityPremiumBps floors to integer BPS and can skip every unclamped center. Concrete case: base center 0, one rung with spread 2, hard range [0,2], premiumPerYearBps = 2 * 31,536,000, cap 2. The only fitting center is 1, but integer-second observations produce premiums 0, 2, 4, …, so the config is accepted even though no reachable center fits unclamped. Please either validate discrete reachable premiums or narrow the contract/docs and add coverage. The required GitHub Test check is also red on this head during Foundry installation (cannot execute binary file); #177 contains the runner fix, but this PR still has no green Test result.
|
@codex review |
|
@prd-carapulse[bot] can you review and approve if all good |
|
Approved PR #176 at head • Prior blockers addressed: playground reorder, preview-center handling, reachability envelope, JSDoc. DONE_WITH_CONCERNS |
There was a problem hiding this comment.
Reviewed current head a82c33c.
No blocking code issues found. The prior playground reorder regression, preview-center issue, reachability-envelope issue, and exported-function JSDoc gap are addressed in the current diff. Typecheck, lint, and Dead-Code checks pass.
The required GitHub Test check is still red before project tests run: Foundry installation fails with "cannot execute binary file". This is runner/tooling evidence, not a code failure, but it must be rerun or repaired before merge.
|
@codex review |
|
@prd-carapulse[bot] can you review and approve if all good |
|
Approved PR #176 at head No blocking code issues found. Prior playground, preview-center, reachability, and maturity-read concerns are addressed.
|
There was a problem hiding this comment.
Reviewed current head 7d3c34c against the rewritten stacked base. No blocking code issues found in the ladder maturity-premium changes; prior playground, preview-center, reachability, and maturity-read concerns are addressed.
Typecheck and Test are still pending, so merge remains gated on those checks passing.
|
Codex Review: Didn't find any major issues. Delightful! Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
Mirrors the base branch's hasAttainableMaturityPremiumBps load gate on the ladder: assertLadderShapeAtReference now also rejects a slope whose floored premium steps jump over every center fitting the full shape unclamped, flipping the prior envelope-acceptance semantics to exact attainability, with docs and the TIB updated to match. The rebase onto the re-signed base also folds the monotonic block-share clock together with the cadence cap in the shared maturity reader. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@codex review |
|
@prd-carapulse[bot] can you review and approve if all good |
|
Approved PR #176 at head
Review: #176 (review) |
There was a problem hiding this comment.
Reviewed current head 3e0d6844897d7bf1d1c2c30fab6162cba20c8d71 against stacked base bootstrap-maturity-premiums-d70999. No blocking code issues found. The exact maturity-premium attainability gate, ladder wiring, playground behavior, diagnostics, and regression coverage are consistent with the requested scope. Lint, Typecheck, and Dead-Code pass. Test is still in progress; merge remains gated on that check passing.
|
Codex Review: Didn't find any major issues. More of your lovely PRs please. Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3e0d684489
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@prd-carapulse[bot] can you review and approve if all good |
|
Approved PR #176 at current head • Review: No blocking code issues. Latest change only clarifies |
There was a problem hiding this comment.
Reviewed current head 4a94bcc. The only code change since the previously reviewed head is a JSDoc clarification for generateLadder; no behavioral changes or blocking findings. Lint, Typecheck, and Dead-Code pass. Test was still running at review time; merge remains gated on that required check.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a94bcc021
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@prd-carapulse[bot] can you review and approve if all good |
|
Changes requested on PR #176. No approval. • Prior Review state: |
There was a problem hiding this comment.
Changes requested on current head 4a94bcc021e75a03452db7eec73feda37abba21f.
The required Test check is red from a reproducible playground regression, not runner setup: scripts/playground-smoke.browser.mjs fails mobile Chromium smoke remains deployable below the /morpho-bots/ Pages subpath. The underlying playground-smoke.mjs assertion expects focus add-ladder, but gets an empty focus after the collection edit/removal flow.
Observed CI result: 13 passed, 1 failed. Please fix the focus regression and rerun the full Test check. I am not approving this revision.
|
Focus regression root-caused and fixed in d3ffc05: the playground scheduled its post-action focus (move/remove/add/tab) in @codex review |
|
@prd-carapulse[bot] can you review and approve if all good |
|
Approved PR #176. • Head: |
There was a problem hiding this comment.
Reviewed current head d3ffc05. No blocking code issues found. The prior playground reorder regression, preview-center handling, reachability validation concern, cadence freshness issue, and JSDoc findings are addressed in the current diff. Lint, Typecheck, and Dead-Code pass; Test is still running and remains the merge gate.
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
Extends the per-entry
maturityPremiummodel from #174 to the ladder workflow — the deferred scope recorded in TIB-2026-08-25-quoter-bootstrap-maturity-premium's Future Considerations (MKT-1787).Why
With #174, bootstrap entries price duration but ladder centers stay flat: a one-month and a nine-month ladder configured identically quote the same center, so resting two-sided liquidity on a far book still hands takers the term spread — the exact adverse selection #174 removed for bootstrap — and one bot's term structure splits across two inconsistent workflows. This PR makes the ladder effective center
reference + quotePremiumBps + resolved maturity premiumusing the identical shared model, so one configuration prices every allowlisted maturity coherently.What
src/domain/ladder/ladder.ts):LadderConfig.maturityPremium(same tagged union),effectiveLadderPremiumBpsmirroringeffectiveBootstrapPremiumBps(fail-loudLadderConfigurationErrorwhen a premium is configured without a maturity observation — even at a retained center),generateLaddertakessecondsToMaturity, andassertLadderShapeAtReferencebecomes reachability-aware: the center spans the reachable envelope bounded byhighestReachableMaturityPremiumBps(the configured cap or the premium at Midnight's 100-yearMaturityTooFarhorizon), so load-time rejection is reserved for shapes no protocol-permitted maturity can place fully inside the hard bounds — including uncapped slopes too shallow to ever lift the shape inside, and (via the shared exacthasAttainableMaturityPremiumBpsgate) slopes whose floored premium steps jump over every fitting center. Acceptance always means some attainable premium truly fits; transient excursions clamp at runtime per TIB-2026-08-14.readObservationport and verbose diagnostics gainsecondsToMaturity+maturityPremiumBps(apremiumDiagnosticsguard mirrors the bootstrap service so result assembly never re-throws).movementToleranceBpsabsorbs slow curve decay exactly like reference movement — a floored one-BPS step inside the deadband rests.production-ladder.tsinjects the per-marketmarket.timeToMaturity(block.timestamp)read into the already-sharedStrategyBootstrapReferenceRateService, wired only for premium-configured entries. The wiring goes through the sharedmaturityReadsByMarkethelper (src/infrastructure/maturity-read.utils.ts) that landed on the base branch in cd9766f — sanitizedBootstrapAdapterError('maturity-read')classification, per-market caching of the immutable market read, and a shared latest-block read — so both workflows resolve the identical hardened curve input and cannot drift. The ladder wiring caps block sharing at the shortest configuredloopIntervalSeconds, so sub-15s cadences still re-derive the premium from a fresh timestamp every cycle.readRategets an explicitPromise<BootstrapRate>return annotation (the ladder adapter consumes the concrete class, whose inferred union hidsecondsToMaturity).ladderConfigsValue+ the YAML key allowlist accept the sharedmaturityPremiumobject for ladder entries.clampPlotPercent. The always-rendered premium select binds the top-levelmaturityPremiumpath in both editors so reordering premium-free items cannot materialize a partial object (tanstack-form rewrites renamed mounted fields), and the browser smoke now reorders a mixed-premium import asserting the premium travels with its item.docs/reference.mdladder sections,docs/architecture.md,quoter-bot.example.yaml,.env.example. Two pre-existing fixes in touched sections: the ladder docs claimed out-of-range rates are "rejected rather than clamped" whilegenerateLaddersaturates at the bounds (TIB-2026-08-14 semantics), and the.env.exampleLADDER_MARKETSvalue was load-invalid (hardcoded 400 with outer offset 300 breaches the 200 floor at load) — the capped premium example now makes it valid and demonstrative.TIB-2026-08-25-quoter-ladder-maturity-premium.mdrecords the decision; the parent TIB gets the standard partial-supersession marker for its lifted ladder non-goal.LADDER_MARKETS, invalid variants, pinned/reachable hardcoded shapes), application (verbose diagnostics, decay-rest-then-recenter, missing-observation halt), infrastructure (no-premium observation omits the field;maturityReadsByMarketpositive SDK-derived read + rejection propagation), playground (round-trip, far-center graphic, shared validation).Validation
pnpm --filter @morpho-org/quoter-bot run typecheck— cleanpnpm lint— 0 warningspnpm format— appliedRPC_URL_8453and are environment-gated locally — CI is their gate.playground:test(browser smoke) — pass 24 / fail 0jsdoc:check+jsdoc:build— zero warnings, HTML generated (not committed)Note: the branch commit is unsigned (1Password locked during this session); the squash-merge commit gets signed by GitHub.
🤖 Generated with Claude Code