Skip to content

test(manifest): keep the rule-manifest test able to catch a keel init reseed - #173

Merged
eaitbrahim merged 1 commit into
mainfrom
fix/live-dca-budget-50
Aug 6, 2026
Merged

test(manifest): keep the rule-manifest test able to catch a keel init reseed#173
eaitbrahim merged 1 commit into
mainfrom
fix/live-dca-budget-50

Conversation

@eaitbrahim

@eaitbrahim eaitbrahim commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

What this is now

This PR started life as the deploy/live-rules.json DCA budget_usd 25 -> 50 change, split out of #172. #172 was merged and carried that change in, so the value edit, the executor.py comment and the prose are all on main already. Rebased onto origin/main, what remains is the one thing #172 did not land: repairing the test it silently weakened.

The problem

#172 replaced this assertion in test_committed_manifest_is_valid:

assert dca[0]["params"]["budget_usd"] == "25", "DCA budget must not revert to the default 50"

with a check that the manifest's budget equals config.dca.budget_usd. Checking agreement rather than a literal is the right instinct — a hardcoded number there just re-creates the drift it is meant to catch, one deploy later.

But it lost something. The original assertion guarded a specific, real failure: keel init on a fresh box seeds every rule at candidate from each rule kind's constructor defaults, silently discarding any parameter an operator tuned by hand, on a box that otherwise looks correctly provisioned. Nothing errors.

50 is also Dca.__init__'s constructor default. And deploy/live-rules.json's DCA params are now exactly the four constructor defaults:

param manifest Dca.__init__ default
cadence_days 7 7
budget_usd "50" Decimal("50")
dip_bonus_pct "0" Decimal("0")
lookback_days 90 90

So "manifest agrees with config" is satisfied both by a correctly-provisioned deployment and by one that keel init quietly reseeded. The values cannot tell those two states apart any more.

Why I did not do what was asked literally

The instruction was to assert "the value is not merely the constructor default". That is impossible to satisfy honestly — the operator's intended budget is the constructor default. Any assertion of that form would either be false or would require moving Dca's default away from 50 to suit a test, which changes library semantics for a test's convenience. So the guard is restored a different way.

What the test asserts now

  1. Agreement — manifest budget_usd == config.live-sandbox.yaml's dca.budget_usd, parsed from the file, not hardcoded. This is the value the executor actually spends.
  2. Not seed-shaped — the DCA rule's status is live, and no rule in the manifest is candidate. This is the only discriminator assertion (1) leaves standing: keel init always seeds at candidate regardless of what the params say.
  3. The coincidence is pinned, not assumed — the manifest's DCA params are asserted equal to Dca(product_id=...).describe()["params"]. If the operator ever moves the budget off the default, this is what fails, and its message explains that the failure is good news: assertion (1) has regained the ability to catch a reseed on its own, and (2) is no longer the last line of defence.

Verification

Each assertion was confirmed to fail for the right reason, by mutating the committed manifest and reverting:

  • DCA status -> candidate: AssertionError: the live DCA rule is not status=live -- if this is a candidate, keel init likely reseeded it from Dca's constructor defaults...
  • budget_usd -> "25": AssertionError: the live DCA rule's budget_usd must match config.dca.budget_usd... assert Decimal('25') == Decimal('50')
  • cadence_days -> 14: trips assertion (3) with the "reasoning behind assertion (2) no longer applies" message.

ruff, pytest and mypy clean.

🤖 Generated with Claude Code

… reseed

PR #172 landed the live DCA rule's `budget_usd` 25 -> 50, aligning the manifest with
`config.dca.budget_usd` -- the value the live executor actually spends, since
`executor._build_intent` ignores the rule row's own `budget_usd` entirely.

That alignment silently WEAKENED the test that came with it. `test_committed_manifest_is_valid`
now asserts manifest == config, but 50 is also `Dca.__init__`'s constructor default, and
`deploy/live-rules.json`'s DCA params are now EXACTLY the constructor defaults. So the scenario
the test originally existed to catch -- `keel init` on a fresh box silently reseeding every rule
from constructor defaults, discarding an operator's tuned value, with nothing erroring -- now
passes green. The values can no longer tell a correctly-provisioned box from a reseeded one.

Asserting "the value is not merely the constructor default" is impossible here: the operator's
intended value IS the default. So this restores the guard using the one thing that still
discriminates -- `keel init` always seeds at `candidate`, and every rule in the committed
manifest is `live` -- and pins the coincidence itself, so that if the budget ever moves off the
default the value check regains its power and the pin is what says so.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@eaitbrahim
eaitbrahim force-pushed the fix/live-dca-budget-50 branch from c4fdc61 to 7366d03 Compare August 6, 2026 22:54
@eaitbrahim eaitbrahim changed the title fix(deploy): align the live DCA rule's budget_usd with config (25 -> 50) test(manifest): keep the rule-manifest test able to catch a keel init reseed Aug 6, 2026
@eaitbrahim
eaitbrahim merged commit 6306263 into main Aug 6, 2026
@eaitbrahim
eaitbrahim deleted the fix/live-dca-budget-50 branch August 6, 2026 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant