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
Decide what the borrowing-positions contract should do with a position whose debt rounds to $0.00. The producer currently emits debt_usd: 0.0 even though it declares gt=0, and the app-core consumer then rejects the whole response. Any fix picks portfolio semantics (drop dust positions vs. accept zero debt), so this is not weak-agent work.
Evidence
Sentry ZAP-PILOT-WEB-2: ZodError at positions[6].debt_usd — "Too small: expected number to be >0" — in getBorrowingPositions, 3 events 2026-09-19T07:49:38Z–2026-09-20T10:05:49Z, release 3.0.1. ZAP-PILOT-WEB-4: same error, 1 event at 2026-09-20T10:09:58Z. 0 identified users.
Producer: apps/analytics-engine/src/models/borrowing.py declares debt_usd: USDRounded = Field(gt=0.0) (and total_debt_usd the same), where USDRounded = Annotated[float, AfterValidator(_round_usd)] (apps/analytics-engine/src/models/types.py). The bound passes on the raw value, then rounding produces zero. Reproduced locally on main 44736128: BorrowingPosition(debt_usd=0.004, …) validates and dumps debt_usd: 0.0.
Consumer: packages/app-core/src/schemas/api/analytics/portfolioSchemas.ts mirrors the declared contract with debt_usd: z.number().positive() and total_debt_usd: z.number().positive(), so one dust row fails the entire borrowing panel.
These events started within 15 seconds of [operator] Decide daily-suggestion handling of missing spot prices #643's ANALYTICS-ENGINE-1/2, in the same dashboard session. ops_investigate sentry:stale-unresolved/zap-pilot-web: blockers [], inspectionCoverage inspected, no AUM or customer exposure recorded.
Options
The producer drops positions whose rounded debt is ≤ 0 before building the response, and defines what total_debt_usd / worst_health_rate mean when only dust remains.
Enforce the bound after rounding so the producer never emits an invalid model (on its own this turns the symptom into a producer error; pair it with option 1).
Relax the consumer to nonnegative() and accept zero-debt rows. This changes the published contract, so contract snapshots must be regenerated.
Decision needed
Decide what the borrowing-positions contract should do with a position whose debt rounds to $0.00. The producer currently emits
debt_usd: 0.0even though it declaresgt=0, and the app-core consumer then rejects the whole response. Any fix picks portfolio semantics (drop dust positions vs. accept zero debt), so this is not weak-agent work.Evidence
ZodErroratpositions[6].debt_usd— "Too small: expected number to be >0" — ingetBorrowingPositions, 3 events 2026-09-19T07:49:38Z–2026-09-20T10:05:49Z, release 3.0.1. ZAP-PILOT-WEB-4: same error, 1 event at 2026-09-20T10:09:58Z. 0 identified users.apps/analytics-engine/src/models/borrowing.pydeclaresdebt_usd: USDRounded = Field(gt=0.0)(andtotal_debt_usdthe same), whereUSDRounded = Annotated[float, AfterValidator(_round_usd)](apps/analytics-engine/src/models/types.py). The bound passes on the raw value, then rounding produces zero. Reproduced locally on main44736128:BorrowingPosition(debt_usd=0.004, …)validates and dumpsdebt_usd: 0.0.packages/app-core/src/schemas/api/analytics/portfolioSchemas.tsmirrors the declared contract withdebt_usd: z.number().positive()andtotal_debt_usd: z.number().positive(), so one dust row fails the entire borrowing panel.ops_investigate sentry:stale-unresolved/zap-pilot-web: blockers[], inspectionCoverageinspected, no AUM or customer exposure recorded.Options
total_debt_usd/worst_health_ratemean when only dust remains.nonnegative()and accept zero-debt rows. This changes the published contract, so contract snapshots must be regenerated.Fingerprint
triage:sentry:ZAP-PILOT-WEB-2