Skip to content

fix(engine): close #731 and #732 — pin two ON CONFLICT windows, and deliver the finding nobody could receive - #745

Merged
eaitbrahim merged 1 commit into
mainfrom
fix-731-732-attestation-gaps
Sep 7, 2026
Merged

fix(engine): close #731 and #732 — pin two ON CONFLICT windows, and deliver the finding nobody could receive#745
eaitbrahim merged 1 commit into
mainfrom
fix-731-732-attestation-gaps

Conversation

@eaitbrahim

Copy link
Copy Markdown
Contributor

Closes #731. Closes #732.

Both were found while implementing #718 and left alone to keep that PR to its scope. Both sit under rail 22.

#731 — two upsert clauses, correct and untested

broker_subscriptions and venue_cash_postures both carry attest_due_ts in an INSERT … ON CONFLICT DO UPDATE SET, both set it, and deleting either line left the whole suite green — the same hole #718 closed for the asset and instrument tables and left open here.

venue_cash_postures.attest_due_ts is rail 22's input. A re-attestation carrying the old window forward would keep an expired posture reading as current, and the rail would stop vetoing when it should — the failure direction that costs money rather than opportunity.

Mutating every column of both clauses found two more the issue didn't name:

  • attested_posture is the column rail 22 actually reads. An operator who moves off margin and re-attests, whose re-attestation silently kept MARGIN_ENABLED, would go on being vetoed by a record saying the opposite of what they stated.
  • The refutation columns had the hole the method's own docstring already states for credential_fingerprint"a writer that could not clear it would let a stale fingerprint outlive the record it described" — so a posture the venue refuted and the operator then fixed would read as refuted forever.

Every column in both clauses is now pinned.

#732 — a registered finding nothing could deliver

attest.cash_posture was in _ATTESTATION_FINDINGS, and notify_after_cycle never called cash_posture_findings. The registration was real; the delivery path was not.

It fires when the account is attested margin-enabled, when the posture attestation has expired, or when it was attested with no due date at all — three states where rail 22 has stopped letting the agent enter positions. The symptom otherwise is silence: an agent that looks healthy and never trades again.

The break was the same bug one layer down. events_from_state emitted one attestation event per cycle, commented "the finding list carries one rail-17 verdict" — true when the registry held rail 17 alone. With rail 22 in it, that break makes a cash-posture problem invisible whenever a withdrawals problem also exists. One event per finding name now.

The pin closes the class. A test comparing the registry against a list of gatherer names would be a third list to drift. Instead it drives the real notify_after_cycle against a book where every registered finding is unhealthy at once and asserts each one arrives — so a registration with no gatherer fails there rather than in production quiet.

One behaviour change worth naming

A deployment that has never attested a cash posture now notifies. cash_posture_findings(None) is a FAIL — "cash posture never attested" — and rail 22 vetoes on it, so the agent cannot enter and until now had no way to say so. That's the standing case #732 is really about, and it's why an existing test's sent == 1 became sent == 2: the default double carries no posture, which was never a fixture detail.

Gates

  • 6,254 passed / 3 skipped; mypy clean on 444 files; ruff clean (the one E501 is pre-existing in docs/experiments/)
  • 9 mutants killed: both windows dropped · a neighbour dropped from each clause · refuted_ts, refuted_reason, credential_fingerprint, state and attested_posture dropped from the posture clause · the cash-posture gatherer removed · the break restored · a healthy posture notifying anyway

🤖 Generated with Claude Code

https://claude.ai/code/session_01KZZxmspQXe5qJ9FAsG13s6

…eliver the finding nobody could receive

Both were found while implementing #718 and left alone to keep that PR to its
scope. Both sit under rail 22.

#731: TWO UPSERT CLAUSES WERE CORRECT AND UNTESTED

`broker_subscriptions` and `venue_cash_postures` both carry `attest_due_ts` in an
`INSERT ... ON CONFLICT DO UPDATE SET`, both set it, and deleting either line left
the whole suite green -- the same hole #718 closed for the asset and instrument
tables and left open here.

`venue_cash_postures.attest_due_ts` is RAIL 22's INPUT. A re-attestation that
carried the old window forward would keep an expired posture reading as current,
and the rail would stop vetoing when it should: the failure direction that costs
money rather than opportunity. On `broker_subscriptions` the column is NOT NULL,
so the same slip is even less visible -- the window can never read as absent,
only as stale.

Mutating every column of both clauses found TWO MORE the issue did not name.
`attested_posture` is the column rail 22 actually reads: an operator who moves
off margin and re-attests, whose re-attestation silently kept `MARGIN_ENABLED`,
would go on being vetoed by a record saying the opposite of what they stated.
And the refutation columns had the same hole the method's own docstring already
states for `credential_fingerprint` -- "a writer that could not clear it would
let a stale fingerprint outlive the record it described" -- so a posture the
venue refuted and the operator then fixed would read as refuted forever.

Every column in both clauses is now pinned.

#732: A REGISTERED FINDING THAT NOTHING COULD DELIVER

`attest.cash_posture` was in `_ATTESTATION_FINDINGS`, the opt-in registry of
findings a webhook receives, and `notify_after_cycle` never called
`cash_posture_findings`. The registration was real; the delivery path was not.

That finding fires when the account is attested MARGIN-ENABLED, when the posture
attestation has expired, or when it was attested with no due date at all -- three
states in which rail 22 has stopped letting the agent enter positions. The
symptom otherwise is SILENCE: an agent that looks healthy and simply never trades
again. It is exactly what a webhook is for.

AND THE `break` WAS THE SAME BUG ONE LAYER DOWN

`events_from_state` emitted one attestation event per CYCLE, with a comment
saying "the finding list carries one rail-17 verdict" -- true when the registry
held rail 17 alone. With rail 22 in it, that break makes a cash-posture problem
invisible whenever a withdrawals problem also exists. One event per finding NAME
now.

THE PIN CLOSES THE CLASS, NOT THE INSTANCE

A test comparing the registry against a list of gatherer names would be a third
list to drift. Instead it drives the REAL `notify_after_cycle` against a book
where every registered finding is unhealthy at once, and asserts each one
ARRIVES -- so a registration with no gatherer fails here rather than in
production quiet.

One behaviour change worth naming: a deployment that has never attested a cash
posture now notifies. `cash_posture_findings(None)` is a FAIL -- "cash posture
never attested" -- and rail 22 vetoes on it, so the agent cannot enter and until
now had no way to say so. That is the standing case #732 is really about, and it
is why an existing test's `sent == 1` became `sent == 2`: the default double
carries no posture, which was never a fixture detail.

Nine mutants killed: both windows dropped, a neighbour dropped from each clause,
`refuted_ts`, `refuted_reason`, `credential_fingerprint`, `state` and
`attested_posture` dropped from the posture clause, the cash-posture gatherer
removed, the break restored, and a healthy posture notifying anyway.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KZZxmspQXe5qJ9FAsG13s6
@eaitbrahim
eaitbrahim merged commit 749619a into main Sep 7, 2026
4 checks passed
@eaitbrahim
eaitbrahim deleted the fix-731-732-attestation-gaps branch September 7, 2026 09:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant