Repository navigation
Conversation
A net +83.50 USDT October with an empty book showed 2 of 4 slots and "1.0% of a 4.0% limit" on 2026-10-15. Production persists `hwm_v1` (ADR-0046), so the 17.92 give-back from the intra-trade equity peak is charged against the monthly limit; ADR-0051 (net-from-start, operator decision 2026-08-04) would show 4 slots and 0%, and the shadow metric `robsond_budget_model_shadow_slots_delta` reads 2 in production. The ADR's activation step was never run, partly because nothing on the dashboard would have followed the switch: `monthly_giveback_pct` was computed from the HWM consumption regardless of the active model. - `/status`: new `monthly_budget_utilization_pct` = consumed under the ACTIVE model as a share of the 4% budget. `month_peak_net` and `monthly_giveback_pct` become `Option` and are served only while `hwm_v1` is persisted (ADR-0051 §4). `month_equity_net` stays as the informational mark-to-market. Slots, remaining budget and halt were already model-aware. - Runbook `docs/runbooks/activate-net-from-start-budget.md`: §5.4 preconditions (flat account, no unmatched income, shadow check), the guarded `UPDATE monthly_state` for the current month, validation, rollback, and the accepted gaps (funding excluded from governed net, Entering cancel). No restart: the model is read on every snapshot and later months inherit it on every insert path. - ADR-0051 status note and CHANGELOG. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`deriveBudgetView` now prefers `monthly_budget_utilization_pct` and exposes the model (`net_from_start` | `hwm` | `legacy`) derived from `monthly_budget_model` with field-presence fallback. Under net-from-start the card reads "Net governed loss since month start · Profits do not raise the limit" with `net / reserved / left`; under HWM it keeps `peak / now`; older backends keep the gross-loss fallback. Without this the activation would have shown 4 slots next to a 1.0% gauge, and a backend that withholds the HWM fields would have fallen back to the gross-loss formula (49.6% on a month that is net +83.50). Tests: production payload of 2026-10-15 under both models, model kind detection, and the no-fallback guarantee once utilization is reported. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…te the runbook on ADR approval Review findings (Codex, P1/P2) on the activation runbook: - ADR-0051 §1 says the monthly budget basis MUST NOT increase during the month under net-from-start, but both recalibration paths (ledger- confirmed TRANSFER in income_ledger.rs, manual drift in reconciliation_worker.rs) could raise capital_base regardless of the model. `MonthlyBudgetModel::allows_capital_base_change` now withholds increases under net-from-start; decreases still apply; HWM unchanged. - The runbook accepted §5.4 blockers (funding outside governed net, Entering cancel, August ledger gap) on its own authority. It now stops at step 0 unless the operator has approved the "Activation exceptions" amendment added to ADR-0051, which lists each gap with its bound. - `unmatched_income_count == 0` is not settlement completeness: it skips acknowledged rows and the grace window and reads 0 on query failure. The runbook now queries the ledger directly (unmatched of any age must be zero), lists this month's out-of-band items and refuses activation when their sum exceeds 10% of the remaining budget, and cross-checks month_governed_realized_net against the closed-position projection. - Added the MonthlyHalt latch check (switching models does not clear a latched halt), corrected the shadow-delta expectation (the metric stays slots_nfs - slots_hwm after activation) and the first-entry validation (Armed reserves nothing; Entering/Active do). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
6 of 8 tasks
…asure funding by type in the runbook Second review round (Codex): - Withholding a capital_base increase under net-from-start left the wallet above `capital_base + month_net` forever, so the idle drift scan warned about the same explained deposit on every cycle. The manager now keeps the withheld amount (set by both recalibration paths, cleared when the delta is within tolerance or a recalibration is applied) and the drift scan adds it to the expected wallet balance. In-memory only: a restart re-derives it on the next ledger cycle. - The runbook's settlement-gap query filtered on `matched_at IS NULL`, but the matcher marks FUNDING_FEE rows matched, so it excluded the very funding it claimed to measure. Funding is now selected by type, plus acknowledged and still-unmatched rows, transfers excluded; and a fresh reconciliation scan (last completed within 10 minutes) is required. - First-entry validation: `monthly_budget_remaining` already subtracts the reservation, so slots are `min(4, floor(remaining / risk_unit))`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…loud deposit nuisance and require ledger freshness Third review round (Codex): the in-memory "withheld basis increase" scalar could mask a genuine withdrawal of the same size, survived basis resets, and could not be rebuilt after a restart for manual gains. It is removed; withholding stays and the recurring drift warning after an intra-month deposit is documented as expected, fail-loud behaviour with the persisted design tracked in #242 (runbook, ADR amendment row, CHANGELOG; operating constraint: no intra-month deposits under net-from-start until then). Runbook step 2 no longer treats a fresh position-reconciliation scan as ledger freshness: it checks the ledger's newest item and this month's row count against the exchange's income history and the last 30 minutes of ingestion logs before trusting the settlement-gap query. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…re-gauge # Conflicts: # CHANGELOG.md
…re-gauge # Conflicts: # CHANGELOG.md
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.
Summary
hwm_v1(ADR-0046), which charges the 17.92 give-back from the intra-trade equity peak; the operator decision ADR-0051 (net-from-start, 2026-08-04) says such a month shows 4 slots and 0%. The shadow metricrobsond_budget_model_shadow_slots_deltareads2in production right now./statusand the card model-aware (ADR-0051 rollout step 3) and adds the activation runbook (step 4). It does not switch the model; that is the operator's guardedUPDATE monthly_state, documented, no restart needed.Review round (Codex gpt-6.1 xhigh, on the branch)
First verdict: code checks passed (no consumer breaks on the
nullHWM fields, everymonthly_stateinsert path inherits the model, no cache, rollback resumes from the true peak); three P1 and three P2 on the runbook/policy. Third commit answers them:MonthlyBudgetModel::allows_capital_base_changewithholdscapital_baseincreases under net-from-start in both recalibration paths (ledger-confirmed TRANSFER, manual drift); decreases still apply; HWM unchanged. Unit-tested inrobson-domain.month_governed_realized_netis cross-checked against the closed-position projection.slots_nfs − slots_hwm); first-entry validation distinguishes Armed (no reservation) from Entering/Active.Rounds 2 and 3 (commits 4 and 5): the settlement-gap SQL selects funding by type (the matcher marks
FUNDING_FEErows matched), the slots formula usesmonthly_budget_remainingdirectly, and ledger freshness is checked against the exchange's income history instead of the position-reconciliation metric. An in-memory attribution of withheld deposits in the drift scan was tried and removed on review: it could mask a later genuine withdrawal and did not survive restarts. Accepted, documented consequence: after an intra-month deposit under net-from-start the idle drift scan warns every cycle until the month boundary (fail-loud); the persisted design is #242 and the operating constraint until then is no intra-month deposits under net-from-start.The PR leaves draft when the operator decides on the ADR-0051 "Activation exceptions" amendment.
Changes
robsond/src/api.rs: newmonthly_budget_utilization_pct(consumed under the active model, % of the 4% budget);month_peak_netandmonthly_giveback_pctbecomeOptionand are served only whilehwm_v1is persisted (nullunder net-from-start, ADR-0051 §4).month_equity_netstays as informational mark-to-market. Slots, remaining budget and halt were already model-aware.frontend/src/lib/presentation/budget.ts:budgetModelKind()(net_from_start|hwm|legacy) andderiveBudgetViewprefers the utilization field;BudgetView.modelexposed.frontend/.../dashboard/+page.svelte: MONTHLY LIMIT copy per model ("Net governed loss since month start · Profits do not raise the limit" withnet / reserved / left; HWM keepspeak / now; legacy unchanged).frontend/src/lib/api/robson.ts:monthly_budget_model,monthly_budget_utilization_pct,month_governed_realized_net,monthly_net_loss_consumed,monthly_open_risk_reserved,monthly_budget_amounttyped and normalized (null on older backends).docs/runbooks/activate-net-from-start-budget.md(+ README index): preconditions (flat account,unmatched_income_count == 0, shadow check), guardedUPDATEfor the current month, validation, rollback, accepted gaps (funding excluded from governed net; Entering cancel).robson-domain/src/policy.rs,robsond/src/income_ledger.rs,robsond/src/reconciliation_worker.rs: non-expanding basis under net-from-start.Tests
cargo test -p robson-domain -p robsond --features robsond/postgres(container, rust 1.92) — 170 + 362 passed; clippy-D correctness -D suspiciousclean;cargo +nightly-2026-08-22 fmt --checkcleancd frontend && npx vitest run— 133 passed (budget.test.ts 12);svelte-check0 errorsrobsond/src/api.rsstatus test asserts the HWM outputs areSomeunderhwm_v1and utilization mirrors active consumption.robson-domain/src/policy.rs:allows_capital_base_changeunder both models.frontend/tests/unit/budget.test.ts: production payload of 2026-10-15 under both models, model-kind detection, and the guarantee that the gross-loss fallback is never used once utilization is reported (it would read 49.6% on a month that is net +83.50).Migrations
monthly_budget_modelcolumn and CHECK exist since migration 25)Backward Compatibility
/statusJSON: two fields may now benull(month_peak_net,monthly_giveback_pct), only after the operator switches the model. The frontend onmainalready types them asnumber | nullandrobson-clidoes not read them. New field is additive.monthly_budget_utilization_pct).Security & Data
kubectl execon the prod Postgres pod with the operator's kubeconfig.Checklist
docs/DEVELOPER.md)🤖 Generated with Claude Code