You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Context (verified 2026-09-04, on main at the #717 merge)
#701's Positions view shipped items 1–4. Its attestation chip did not, because two of the things it asks for are not recorded anywhere.
1. There is no expiry to read. The chip is specified as Attested: Q2-2026 · Purif: 0.38% turning into RE-ATTESTATION REQUIRED "when the quarterly filing window expires". Neither per-asset table records a due date:
Both carry attested_at and stop there. Two of the four attestation-bearing tables in the schema — broker_subscriptions and venue_cash_postures — do carry an explicit attest_due_ts alongside their attested_at, so the pattern exists here and these two were written without it. (venue_trade_scopes carries neither; it tracks attested_ts/confirmed_ts/refuted_ts instead.)
2. There is no denominator for the ratio.PurificationReport.owed_by_asset gives a per-asset USD figure that is real and recorded. A percentage needs something to be a percentage OF — owed against position value? against total income? against the asset's own realised proceeds? — and that choice is a judgement, not a lookup. Nothing on the report holds it.
Deriving either at read time is the failure mode this codebase names directly: a number invented for the UI. Same reasoning that split #715 out of #700.
Scope
Schema bump, following the standing pattern (v17/v18/v19/v20 — DDL in _SCHEMA_STATEMENTS, a numbered, documented no-op step, SCHEMA_VERSION bumped):
asset_attestations.attest_due_ts INTEGER
instrument_attestations.attest_due_ts INTEGER
NULL means "no expiry recorded", never "expired" and never "valid forever". Every row written before this bump was made without anyone stating a window, and stamping one now — in either direction — would manufacture the claim the column exists to hold. venue_cash_postures and broker_subscriptions are the shape to copy.
Write it at attestation time, wherever upsert_asset_attestation / upsert_instrument_attestation are called from, so the window is the attester's statement rather than a constant applied later. The quarterly cadence matches the pinned-quarterly-snapshot decision recorded on keel-broker-alpaca Phase B: equities paper profile, attestation semantics, runbook #370.
Decide the purification figure (a decision, not code): either define the denominator upstream so a ratio can be computed by a report and read by the page, or accept owed_by_asset's dollars as what the chip shows. Dollars are honest today and need no engine change.
Refusals
No backfill of attest_due_ts, for the reason above.
No derivation of the expiry from attested_at + one quarter at read time. That is a global policy constant standing in for a per-row fact, and it is precisely the posture the two tables that got this right deliberately avoided — a window belongs to the attestation that was made, not to whatever the current default happens to be when someone opens a page.
No purification percentage until its denominator is defined and held by a report.
Then
The chip becomes a read: attested_at + attest_due_ts → attested / due-soon / RE-ATTESTATION REQUIRED, styled the way _ENTRY_GATE_STATES styles the freshness chip beside it, plus owed_by_asset in dollars. That closes the last of #701's original scope.
Acceptance
Fresh DB stamps the new version; the prior version migrates cleanly; re-running is idempotent.
A newly written attestation records the window it was made under; rows written before the bump read NULL and render as "no expiry recorded" rather than as either expired or valid.
Tests: migration idempotence, NULL-means-unrecorded on pre-bump rows, and an expired window rendering the warn state.
Split out of #701, where both were found to be unbuildable as specified.
Context (verified 2026-09-04, on
mainat the #717 merge)#701's Positions view shipped items 1–4. Its attestation chip did not, because two of the things it asks for are not recorded anywhere.
1. There is no expiry to read. The chip is specified as
Attested: Q2-2026 · Purif: 0.38%turning intoRE-ATTESTATION REQUIRED"when the quarterly filing window expires". Neither per-asset table records a due date:asset_attestations(v6):asset, sector, backing, pays_yield, source, attested_by, attested_atinstrument_attestations(v10):venue, product_id, wrapper, source, attested_by, attested_atBoth carry
attested_atand stop there. Two of the four attestation-bearing tables in the schema —broker_subscriptionsandvenue_cash_postures— do carry an explicitattest_due_tsalongside theirattested_at, so the pattern exists here and these two were written without it. (venue_trade_scopescarries neither; it tracksattested_ts/confirmed_ts/refuted_tsinstead.)2. There is no denominator for the ratio.
PurificationReport.owed_by_assetgives a per-asset USD figure that is real and recorded. A percentage needs something to be a percentage OF — owed against position value? against total income? against the asset's own realised proceeds? — and that choice is a judgement, not a lookup. Nothing on the report holds it.Deriving either at read time is the failure mode this codebase names directly: a number invented for the UI. Same reasoning that split #715 out of #700.
Scope
_SCHEMA_STATEMENTS, a numbered, documented no-op step,SCHEMA_VERSIONbumped):asset_attestations.attest_due_ts INTEGERinstrument_attestations.attest_due_ts INTEGERvenue_cash_posturesandbroker_subscriptionsare the shape to copy.upsert_asset_attestation/upsert_instrument_attestationare called from, so the window is the attester's statement rather than a constant applied later. The quarterly cadence matches the pinned-quarterly-snapshot decision recorded on keel-broker-alpaca Phase B: equities paper profile, attestation semantics, runbook #370.owed_by_asset's dollars as what the chip shows. Dollars are honest today and need no engine change.Refusals
attest_due_ts, for the reason above.attested_at+ one quarter at read time. That is a global policy constant standing in for a per-row fact, and it is precisely the posture the two tables that got this right deliberately avoided — a window belongs to the attestation that was made, not to whatever the current default happens to be when someone opens a page.Then
The chip becomes a read:
attested_at+attest_due_ts→ attested / due-soon /RE-ATTESTATION REQUIRED, styled the way_ENTRY_GATE_STATESstyles the freshness chip beside it, plusowed_by_assetin dollars. That closes the last of #701's original scope.Acceptance
Split out of #701, where both were found to be unbuildable as specified.