Every change to the model, the scanners, and the live execution stack — published as it lands. No marketing edits. The dev log is the changelog.
◆ 2026-05-12SHIPPED
Best live day in weeks + deep system audit
### Live trade
BA 247.5C 5/22 entry $1.75 → exit $2.27 = +$52 (~30% on contract).
Edge=42, AGG_SWING bucket, strategies UOA+SPREAD, cf=2 — exactly the
SPREAD+UOA cf=2 cohort that's running 77% WR this week. Account: $419.80 → $471.67 (+12.4%).
Three Kalshi MLB picks ALSO fired today via the edge≥55 bypass shipped
last night: Rockies HOME (75¢), SF HOME (74¢), DET HOME (57¢). First
confirmation that the structural fix is firing the high-conviction picks
we'd been missing for weeks.
### Two real bugs found + fixed
1. SAMEDAY_EXITS=off was orphaning winners (commit 637f2da).
VPS journalctl showed BA's T05_TRAIL was correctly suppressed, but
tracker.ts had already written scannerResult=T05_TRAIL + exitPrice=target05
to the DB. loadPendingPlays excludes plays with non-null exitPrice → BA
dropped from in-memory tracking → EOD sweep saw it as orphan and force-closed
at 12:45 PT. The entire SAMEDAY=off intent was being defeated. Fixed by
adding sameDayTrailSuppress param to processQuote() that blocks both
the trail state and the synthetic exitPrice write. Tests +2 (158 passing).
2. Kalshi fills not syncing to DB (commit d6b563e).
3 MLB picks fired on the exchange today with orderIds in Discord, but DB
showed played=false for all of them. Root cause: interpretOrderFill()
returns hasRealFill=false for marketable-limits-that-fill-asynchronously,
and the mlb-scanner else-branch only writes orderId, leaving played=false.
Shipped POST /api/cron/kalshi-fill-reconcile — pulls fills every 15 min
during market hours, matches by orderId, writes played=true + stake/
contracts/filledPrice. cron-job.org jobId 7594384 registered.
### Manual backfills
- BA 5/12 → status=WON, pnl=+$52, exit=$2.27, exitReason=EOD_ORPHAN_FORCE_CLOSE
- 3 MLB picks → played=true with real orderIds + stakes
- 1 weather pick (NYC NO ×20) → played=true, stake=$9.04
### Deep audit findings (data/audits/2026-05-12-deep.md)
Working: AGG_SWING + SPREAD+UOA + cf=2 is the winning recipe (77% WR n=13).
PR #1247 edge gate is filtering correctly. Kalshi bypass fires the 3+ picks/day
we'd been missing.
Ambiguous: signalContributions show base and strategyBonus LOSS-biased
on n=27 — components score losers ~10-15% higher than winners. Could be
real anti-signal, selection bias, or sample noise. Need 60-90d data
before acting.
Brittle: edge-band 30-39 played WR has degraded from historical 74% to
30% (n=20). Likely the cf=1 subset is dragging it down — cf=2 in that band
might still be strong. Don't change ALPACA_MIN_EDGE_SCORE=30 yet; layer
in a cf-aware rule when data justifies.
Dead components confirmed: vix, macro, cicero, coolOff fire <5% of plays
(#1167 still open).
### Tomorrow's first-scan validation
- VPS confirmed: MIN_CONFLUENCE=2, MIN_EDGE_SCORE=30, SAMEDAY_EXITS=off
- Watch for any same-day T0.5 winner → end-to-end test of 637f2da
- 9 AM PT MLB scan → confirm Kalshi bypass still firing
- First kalshi-fill-reconcile tick at 13:00 UTC → should sync any orphans
User's Sunday-night check before Monday market open. Triaged GitHub state, cleared a stranded PR, and hunted down two more instances of the \n-pollution bug pattern that bit us earlier today on the charm/ivRank kill flags.
### GitHub triage
- Open PRs: #1189 (PC strategy-arena grounded rewire) had unresolvable merge conflicts on pc/autonomy-week-may-2 — the branch was the basis of the already-merged #1169 but kept living and accumulated auto-context commits in parallel with Mac's auto-context, blowing up the merge. Cherry-picked the 2 real commits (f470fcd strategy-arena rewire + 4cbcb9e macro-extractor diagnostic / P0 alarm path) onto a fresh branch from main → opened PR #1190 clean → merged as cb71a51. Closed #1189 as superseded.
- 5 issues closed as stale/superseded:
- #1098 + #1099 — 2026-04-26 authority-chain comms incident, no recurrence in 7+ days, no code action needed (rule lives in MEMORY.md / CLAUDE.md).
- #1120 — subsumed by #1167 verification work (both shipped today via #1174 + #1176).
- #1150 — May 1 sports research; sportsbook-side paused til Fall 2026, Kalshi items absorbed into live nba-scanner / mlb-scanner crons.
- #1152 — Durant injury check, game played 2026-05-01.
- Status comments on 3 issues (kept open for verification window): #1167 (4 dead components — fixes shipped, kill flags only genuinely active starting Mon since "true\n" corruption was just fixed tonight), #1156 (edgeScore compression — same), #1148 (PC missing keys — Mac side confirmed clean, PC owns the sync).
User came back mid-Sunday with a crashed plan-mode session. Picked up the UI/data-transparency audit in flight. While verifying the pending edits, discovered both uncommitted in-flight edits were on dead files (no callers); the actual rendered files are different. Reverted, redid the work on the real targets, then surfaced — and fixed — a silent prod env bug that had been silently neutering the charm/ivRank kill flags shipped Saturday.
### Merged
- PR #1183 — paper-vs-live transparency sweep + realized P&L hero tile. Public landing now shows Realized P&L · Alpaca Live · since Apr 13 alongside Model P&L · Lifetime · paper so visitors can compare paper-basis to real-fill at a glance. Realized number sums settled optionPlay rows where alpacaOrderId is set since ALPACA_LIVE_START, mirroring the canonical query the bankroll-review cron already uses. Empty state renders — instead of fabricating $0. OPTIONS + MARKETS sector cards no longer claim "Alpaca auto-trade on the paper model" / "auto-trade sampling on $45 test bankroll" — both implied behavior that didn't match reality (execution is live; weather auto-trade is paused). markets/help TL;DR (line 125) and Important box (252–253) no longer self-contradict the existing Auto-Trade — Paused step at line 84.
- PR #1185 — owner portfolio one-click DCA helper. New runs read-modify-write in a single Prisma transaction (server is the source of truth for the weighted-avg math, no client-side floating-point drift, no race window). Frontend: chip on each (with so card-click → edit still works), tiny modal with + inputs, updates as you type — shows new total shares, new weighted , dollar amount being added, and whether the basis got *lowered* or *raised*. Does NOT auto-create an (recurring paychecks split across multiple positions; deposits stay logged separately).
◆ 2026-05-03SHIPPED
Mac act-on-PC-findings sweep: 1 merge + 6 PRs
User came back to a session-fresh Mac and asked to address everything PC autonomy filed overnight. Plan mode → 7-tier coherent push. PR #1169 (PC autonomy week-of-may-2) merged first because Tier 1A depends on data/macro-events-latest.json it produces; then 6 Mac PRs ship the consumer side, the WR-impact kill flags, dead-component diagnostics, the rate-limit batch, FRED expansion, and state-truth observability.
### Merged
- PR #1169 (PC) — pc/autonomy-week-may-2. +1943/−228, no src/*. Macro-extractor (Python) + 8 new timeslots + scoring-calibration script + context-prune. Local-only auto-stub commit dropped via rebase --skip (regenerable by design); backed up as backup/auto-stub-2026-05-02.
### Opened (Mac, in plan order)
- PR #1174 (Tier 1A) — macro JSON consumer (#1168). New src/lib/options/macro-events-file.ts reads data/macro-events-latest.json and emits both NostradamusSignal[] (CPI/FED/GDP/JOBS/GEOPOLITICAL → signalContributions.macro) and MacroNewsEventForScoring[] (all directional events with sectors → .news). added; honors explicit sectors and matches direct ticker ETFs. gains in COMPONENTS. issue's prescription (replace array at scanner.ts:59) wouldn't fix the scoring component — that array is the FOMC calendar. This PR fixes the actual gap.
- (#1173). short-circuits ; short-circuits the IV-cheapness bonus in AND the event-regime gate that amplifies vanna/charm. Default-OFF (current behavior preserved). Once both PR + Vercel env flip ship, the calibration's −5.7 charm and −7.1 ivRank drag disappear from new plays; 7d / 14d re-runs decide whether to keep off, redesign, or unflip.
- (#1167). Three unconditional / / logs so vix/cicero/coolOff = 0 is diagnosable as regime-correct vs upstream failure. Hypothesis: vix is dormant (VIX ≤22 → MODERATE level, vixAdj only fires HIGH/EXTREME); cicero may be posting tickers we don't scan; coolOff is no-stops-in-2d-window. Logs will confirm; per-component sub-issues file as needed.
- (#1170). New (rateLimitResponse + RATE_LIMITS tier constants) applied to 9 routes. added to + per #1149 (both leaked live trading state to public reads). 3 vitest tests covering bucket exhaustion + slug isolation + IP isolation, all pass. Closes #1170 #1158 #1149 #1134 #1114 #1092.
- (#1171). 4 new series (T10Y3M, DFII10, NFCI, UNRATE) + 3 new derivations (, , preferring T10Y3M). 3 new scoring rules within existing ±10 cap. FRED section reclassified scoring-active. Likely also broken in Vercel prod (consistent with calibration showing fred=17/20 zero). Owner action flagged in PR description. Backfill of historical deferred (needs FRED historical-date queries).
- (#1172). Pure additive: , with per scanner, . PC autonomy parses arbitrary JSON so it'll start citing automatically. gh-counts (open issues / PRs) deferred — needs token + REST fetch from serverless, separate clean PR.
Continued the Saturday push past sunset. Standup priority 1+2 batch shipped (PR #1166), Kalshi bankroll raised to $100, live tracker on home dashboard, baseline verification query for Monday's #1163 effect.
### PR #1166 — standup priority 1+2 batch (6 features)
1. Effective-spread logging in execution — services/price-stream/src/execution.ts logs entry/exit slippage % vs simulator 5% baseline (#1068)
2. Realistic PnL helper — src/lib/options/realistic-pnl.ts extracted from realistic-paper-simulator. Used by track-record API + scorecard cron.
3. Drag % on weekly scorecard — 📈 Realistic P&L (sim) · ⚠️ drag X% line on options-scorecard Discord post.
4. Realistic 90d on /api/track-record — adds realisticOptions90d block (paper, realistic, drag, dragPct, played count, tradeable-paper count, dropped count).
5. NBA + MLB loss analyzers — daily Discord patterns + ScanRun audit. Sports loss analyzer cron registered (jobId 7554563, 02:30 PT).
6. Weather gates tuner — src/lib/kalshi/weather-gates-tuner.ts reads loss tags + proposes 6 classes of gate adjustments. Wired into weather-loss-analysis cron (Discord output, no auto-apply).
### Direct ships
- Kalshi bankroll $45→$100 (Vercel env: KALSHI_BANKROLL=100, MAX_BET_USD=18, DAILY_LIMIT_USD=40, KELLY_FRACTION=0.25). Goal upgraded from "test bankroll" to "grow it same as options."
- Live Kalshi tracker on home (a83daca) — MARKETS card now shows LIVE block with position count + total exposure + top 2 positions + last fill summary. Conditional on — invisible until first trade.
- : removed duplicate () — existing predated it.
User invoked plan mode for a comprehensive sweep — "no winning trades 2 weeks, equity $515 vs $1000 deposits, why are we stuck." 3 explore agents ran in parallel (options/scoring, Kalshi/agentic-learning, autonomy/agents/GH). Diagnosis identified 5 compounding causes; this Tier 1 PR ships the highest-ROI lowest-risk fixes in one coherent overhaul.
### Verified diagnosis (read-only DB query)
- 14d edge distribution: max=53, avg=37.5, ZERO plays scored 55+ — confirms #1156
- 70 of 141 plays (50%) failed per-contract caps even when scoring qualified
- Weather scanner produced 0 picks 16 days; gates cascade to 100% rejection
- Realistic-paper simulator: paper +$5,090 → realistic −$318 (106% drag)
- Kalshi weather loss analyzer existed but never called from any cron
### PR #1163 — 7 changes
1. Per-contract caps raised (route.ts:1405-1411) — CORE $300→$500, AGG $400→$600, LOTTO $250→$350. ~22% more tradeable plays.
2. TECHNICAL regime weight 0.85→1.15 in RISK_ON (scanner.ts:220) — 87% WR n=15 was being penalized in regime where it performs best.
3. Penalty soft-cap −35 raw (scanner.ts:1392) — cool-off + vix + directional + BULL-PUT could stack to −47, depressing edgeScore distribution.
4. Weather cf-floor 45→30 (weather.ts:1124) — Apr 22-29 logs showed 60% bracket-kill at 45.
5. Weather stdDev range widened [2.0,3.0]→[1.5,4.0] — tight band killed entire cities every day stdDev was outside.
6. Weather under-quarantine → overconfidence cap (0.55) — Mescudi RCA found under failures are NWS-blended overconfidence, not bracket type. Replace blanket block with modelProb cap.
7. Weather loss analyzer cron (NEW /api/cron/weather-loss-analysis) — closes the agentic-learning-loop-is-theatre gap on Kalshi side.
### Cleanup
- `ce7fc42` Purged 30 subagent-stop-auto JSON dumps from data/agents/minasara/context.md (89 lines → 6, header only). PR #1146 fixed the hook but never cleaned existing pollution.
- : #1091, #1104, #1132 (already closed prior), #1045 #1040 (superseded by PR #1146), #1101 (already closed), plus #1140/#1142/#1147/#1153/#1154 closed Friday night.
Evening session after Tuesday's red day. Two phases:
### Phase 1 — bug fixes (8:30-9:45 PM PT)
`4789848` VPS execution writer atomic exitPrice (closes #1108 / #1110 / #1119). The recurring leak — exit signal writes pnl + scannerResult but not exitPrice, settle cron skips, plays stay PENDING. Same class that produced 11 hand-reconciles last week + today's XLF case. Now tracker.ts computes exitPrice when scannerResult flips terminal; db.ts writes it via COALESCE so real Alpaca fill takes precedence over scanner estimate.
`97f07cb` Quarantine edgeScore [45, 50) band (closes #1122). PC autonomy data: 22% WR, n=27, −$2,579 over 30 days. Drops from both bucketMap and strictBucketMap after RISK_OFF gating.
`5eb71b2` Odds API quota fix (partial #1121). Markets reduced from h2h,spreads,totals to h2h only. Sportsbook M/L sector paused 2026-04-22 left spreads/totals unused; we only trade Kalshi game-winner = h2h equivalent. 3× credit-cost reduction (~720/mo → ~150/mo on free 500 tier).
◆ 2026-04-28SHIPPED
Big day: D1 audit, reconcile, triage, Kalshi observability
Long Monday session covering the live-trade morning, D1 audit shipped, full issue triage (63→45), 5 PC-autonomy bug fixes, and Kalshi observability infrastructure.
### Live trading
- Morning: woke up late; investigated why no live trades had fired. Found 3-loss-streak gate carrying stale state from last week. Reset DB counter. SPY $685P then hit slippage gate (cheap LOTTO + 7% pct threshold = blocked at +10% drift on a $0.03 absolute move). Shipped bucket-aware slippage gate (commit bf69ac3) — LOTTO 15% / CORE+AGG 7%. SPY filled at $0.30 shortly after at +5.3% drift.
- Day 2 fills: SPY $685P (LOTTO, 4 DTE) entry $0.30 → close $0.18 (~−40% unrealized, near stop). XLF $53C (LOTTO) entry $0.06 → close $0.08 (+$2). XLE Friday-position closed clean at stop $0.13 (only $0.01 slip, limit-first exit working as designed).
- Net day: −$15 realized, ~−$10 unrealized. Daily-loss budget: 5%.
### D1 heavy edgeScore audit (post-close)
Run by Mac in lieu of PC's #dashboard post which Mac cache doesn't have. Saved as data/agents/mescudi/2026-04-27-d1-audit-and-cap-analysis.md. Five findings:
1. Expensive plays win — mid ≥ $2.50 → 64.4% WR / +$8,153 paper / 0 filled live in 30d. Per-contract cap is the real gate, blocking the model's strongest signals. Don't raise caps yet — paper PnL is over-stated by selection bias + perfect-fill assumptions; ~80% paper-to-live haircut from prior week's data.
2. edgeScore is INVERTED at higher bands — edge 30-39 = 60% WR vs edge 50-54 = 50% WR. The metric is anti-predictive at the top end.
3. 5 components dead (vix/fred/macro/vanna/cicero): split into 3 categories — regime-conditional (vix/fred = working as designed), upstream-data-missing (macro/cicero = #1120 filed), and real bug (vanna requires trendDirection populated by TECHNICAL strategy only, 75% of plays had null).
4. is data distribution (universe is low-IV stocks), not a code bug. Closed #1117.
5. (n=32) — directly contradicts PC's #1091 −15 penalty proposal based on n=5 last-week sample. Commented #1091: do NOT ship that piece.
Want the full historical log? It lives in DEVLOG.md on the repo. Older entries roll off this page after the most recent 8.
### \n-pollution sweep (Vercel env)
While verifying Mon readiness, found two more env vars with the same trailing-\n corruption pattern that bit OPTIONS_CHARM_OFF + OPTIONS_IVRANK_OFF earlier today:
- `ODDS_API_KEY` stored as 9afecde…10ef\n — caused MLB scanner to fail today 16:00 PT with Odds API error: 401 Unauthorized (NBA scanner uses a different odds source so unaffected).
- `CRONJOB_API_KEY` stored with trailing \n — cron-job.org status calls from Vercel-deployed code were 401'ing silently (health-check observability blind from Vercel side; local key is clean which is why my Mac-side checks worked).
Both fixed via the same vercel env rm + printf '<value>' | vercel env add pattern (no trailing newline). Verified post-fix: ODDS_API_KEY 32 chars (was 33 with \n), CRONJOB_API_KEY 44 chars. Effect picks up on next deploy. This is the third instance today of this same corruption pattern — there's likely a recurring how-they-got-set issue worth a follow-up audit (probably heredoc / clipboard paste preserving newline).
### Tomorrow's open posture (verified)
- Alpaca options: ✅ live, equity $515.47, buying power $504.47, dbCap $900, VPS heartbeat fresh.
- Kalshi NBA/MLB: ✅ flags + balance ($40.35 → ~$100 when deposit clears tomorrow). Last 5d: 4 SportsPicks total, 1 executed (NYK@ATL +$0.41 on 4/30). Sat/Sun produced 0 picks — scanners ran on schedule, all gated out by edge-gap / confluence filters. Not a system bug — scanner being conservative.
- Weather: 0 picks (penny floor 25¢ + DC/OKC blacklist + Brier filters rejecting). WEATHER_AUTO_PICKS=true is set but functionally inert — flag/CLAUDE.md alignment is a follow-up but harmless tonight.
- MLB scanner: should clear tomorrow once next deploy picks up the fixed ODDS_API_KEY.
### Files touched
- DEVLOG.md — this entry
- ROADMAP.md — added Vercel-env-pollution audit to Known Issues; updated PR/issue refs
- (No src/* changes this session — pure ops/triage)
### Carry-overs
- Vercel-env-pollution audit — three corrupted env vars in 24h is a pattern. Worth scripting a one-shot sweep: vercel env pull → grep for \\n / trailing whitespace → flag any value whose stripped length differs. Filed verbally; not a GH issue yet.
- `WEATHER_AUTO_PICKS=true` vs CLAUDE.md "paused" — minor doc drift, no operational impact (gates reject everything anyway). Reconcile when next touching /markets/help.
- Vercel Coding Agents plugin (released 2026-03-17) — user evaluated, deferred install to fresh session tomorrow morning to avoid mid-session restart.
### Money truth
No movement (weekend). Equity $515.47 unchanged. Kalshi $40.35 → ~$100 at deposit clear Mon. The model improvements that landed earlier today only become measurable starting Mon's first scan (kill flags went genuinely active when the "true\n" got fixed).
POST /api/owner/positions/[id]/dca
+ DCA
HoldingCard
e.stopPropagation()
sharesAdded
pricePerShare
live-preview tile
avgCost
OwnerDeposit
### Filed
- Issue #1184 — Kalshi + Polymarket consensus sentiment overlay. Phase 1: analytics-only — daily snapshot of 6 macro markets (Fed FOMC, S&P-week-up, recession-by-EOY, CPI YoY, BTC month-end, Trump approval) on both platforms; logs consensus label (strong-bull / strong-bear / uncertain / noise) but does NOT feed into edgeScore. Phase 2: regime layer — wires into signalContributions.predmarket once 30-60d of Phase 1 data shows the consensus label is actually predictive. Per-ticker matching deferred (single-stock catalysts almost never have matching contracts). Owners: Steelo (Phase 1 cross-listing audit + market shortlist refinement), Malcom (Phase 2 scoring hook).
### Silent kill-flag bug fix (production)
PR #1175 (Saturday) shipped OPTIONS_CHARM_OFF + OPTIONS_IVRANK_OFF env-flag short-circuits intended to remove the −5.7 charm + −7.1 ivRank drag the calibration measured. Today's vercel env pull revealed both vars stored as literal "true\n" (backslash-n suffix, 6 chars instead of 4) — same pollution pattern as the 2026-04-22 Discord webhook 401 incident. Code reads them as process.env.X === "true", which fails on "true\n", so the kill flags had been silently dead in prod since Saturday's deploy. Re-set both via vercel env rm + printf 'true' | vercel env add (no trailing newline). Fix takes effect on next deploy — both PR merges today triggered deploys, so the flags are now genuinely active.
### Verifications closed
- FRED_API_KEY in Vercel prod — pulled and tested against https://api.stlouisfed.org/fred/series/observations?series_id=DGS10 → 200 with valid data. PR #1178's local smoke-test failure was a stale local key, not a prod issue. No rotation needed.
- CRONJOB_API_KEY — confirmed present in both Vercel prod (46 chars) and local .env. Rotation still on the carry-over list but not blocking anything.
- `/owner/portfolio` infrastructure verified fully live: 4 API routes (positions CRUD + dca + deposits + auth), 4 schemas (OwnerPosition, OwnerDeposit, OwnerPortfolioReview, OwnerPortfolioSnapshot), 2 crons registered on cron-job.org (daily 4:30pm PT snapshot + Sunday 6pm PT Perplexity review), OWNER_EMAILS env set. User starts filling positions Mon AM with recurring DCA paychecks; today's review cron at 6pm PT will generate Perplexity briefs on whatever's in by then.
### Files touched
- src/app/brand-preview/_lib/data.ts — PreviewRecord gains realizedPnl / realizedTradeCount / realizedSinceISO; ALPACA_LIVE_START constant mirrors bankroll-review cron
- src/app/brand-preview/landing/landing-client.tsx — hero stat-tile swap (plays settled public → realized P&L · alpaca live), OPTIONS + MARKETS card body fixes, polymorphic stat array (animated vs static empty-state)
- src/app/markets/help/page.tsx — TL;DR + Important box align with paused-execution status
- src/app/api/owner/positions/[id]/dca/route.ts — new POST route, transaction-wrapped weighted-avg compute
- src/app/owner/portfolio/portfolio-client.tsx — DcaModal + + DCA button on HoldingCard + dcaForId state
### Reverted (in-flight edits on dead files)
- src/app/landing-client.tsx (928 lines, no callers — src/app/page.tsx:5 imports from brand-preview/landing/landing-client.tsx instead)
- src/app/sports/sports-client.tsx (1,736 lines, no callers — src/app/sports/page.tsx:1 already re-exports the paused brand-preview/sports/page.tsx)
### Deferred (carry-over follow-ups)
- Dead code cleanup PR — delete src/app/landing-client.tsx (928 lines) + src/app/sports/sports-client.tsx (1,736 lines). Filed-when-asked; not auto-filed yet.
- CRONJOB_API_KEY rotation — present and working, but the rotation carry-over from earlier in the week is still untouched.
- Re-run `scripts/calibration/scoring-calibration.ts` 7d post-flip — expect charm + ivRank rows to show as dead in the next run, macro/news to show non-zero firing thanks to PR #1174.
- Backfill historical `signalContributions.fred` — Tier 2C deferred portion of PR #1178; needs FRED historical-date queries.
- gh-counts in state-truth-check — Tier 3 deferred portion of PR #1179; needs token + REST fetch from serverless.
### Money truth (no movement, weekend)
Equity $515.47 unchanged; Kalshi $100 deposit clears Mon. Today's work moves the *next week's* WR — not this week's. Real measurement is the 7-14d post-flip calibration re-run.
### Headline finding from this batch
PR #1175 is the highest-WR-impact ship of the session. Once the Vercel env flips on prod, paper plays should immediately stop carrying the 5-7pt drag the calibration measured. Tier 1A is the highest-coverage ship — closes the macro-Nostra-scoring gap that's been silent since Nostra started posting bracket-prefix text instead of fenced JSON.
### Verification gates passed
- All 6 PRs: npx tsc --noEmit clean
- Tier 2B: npx vitest run src/lib/__tests__/api-protect.test.ts 3/3 pass
- Tiers 2B + 2C: npm run build clean
### Open follow-ups (post-merge)
- Verify FRED_API_KEY in Vercel prod, rotate if needed (PR #1178 ⚠️)
- Flip OPTIONS_CHARM_OFF=true + OPTIONS_IVRANK_OFF=true in Vercel after PR #1175 merges
- Re-run `scoring-calibration.ts` 7d post-flip — expect charm + ivRank rows to show as dead, macro/news to show non-zero firing
- Carry-over from prior DEVLOG: CRONJOB_API_KEY rotation; silent agent (Steelo, Onion, Lana) pivot assignments; Archy stuck-issue audit (auto-fires post-#1169); PR #1145 Wave 4 conflicts (now closed since #1165 superseded)
- gh-counts in state-truth-check (Tier 3 deferred portion) — separate small PR
- Backfill `signalContributions.fred` for historical plays (Tier 2C deferred)
### Money truth (no movement, weekend pre-market)
Equity $515.47 unchanged from Saturday. Kalshi $100 funds clear ~Mon. The model bug fixes ship; impact won't show until Monday's first scans + 7-14d settled-play sample.
### Verification baseline (read-only, set Monday's bar)
- 14d edge distribution post-#1163-pre-market-test: max=53 (1 play 5/01), avg=37.3-39.0, 0 plays cleared 55, 0 cleared 60
- Tradeable counts 0-8/day, mostly 1-3 of ~14 candidates
- 0 scans today (Saturday — markets closed)
- Monday's bar: max edgeScore ≥55 (ideally ≥60), avg ≥45. If max stays ≤53 → soft-cap didn't take, re-investigate.
### Open follow-ups
- #1163 effect verify — pull fresh edge data Tue evening after 1-2 trading days
- Silent agent restart (Steelo, Onion, Lana) — punted to PC, needs user direction on pivoted assignments
- Archy rate-limit batch PR (#1158, #1149, #1134, #1114, #1092 → 1 PR) — punted to PC
### Money (no movement today, weekend)
- Equity $515.47, no scans/fills, Kalshi $100 funds in transit (clears ~Mon)
Closed 8 stale issues
### Open follow-ups
- CRONJOB_API_KEY needs rotation — both local and Vercel return 401. Required to register the new weather-loss-analysis cron on cron-job.org.
- #1156 verification — re-pull edge distribution Mon/Tue after 3-5 days of post-PR-1163 data. Expect max ≥60, avg ≥45.
- PC silent agents (Steelo, Onion, Lana) — need explicit pivot assignments since sports paused 2026-04-22.
- Wire loss tags → gate auto-tuning (Tier 2 plan item, not shipped today).
- PR #1145 Wave 4 Track A — still DIRTY conflicts.
### Money truth (unchanged from this morning)
- Equity $515.47 / trading PnL −$484.53 / break-even gap $684 below
- 14d real: −$473 / 38% WR. Realistic-sim: −$318 (consistent).
### What changes Monday pre-market
- Per-contract caps unlock ~22% of currently-rejected plays
- TECHNICAL plays surface more in RISK_ON
- Stacked-penalty plays no longer compress below baseScore−35
- Weather scanner can produce picks (cf-floor + stdDev + under cap all softened)
- Weather losses get tagged within 24h (when cron registers; key rotation pending)
`fa5f138` Weather kill-switch cohort-aware. Brier check now uses LATER(30d-ago, 2026-04-26) so pre-#1081 model data (Brier 0.4855) doesn't immediately re-trip. Then flipped WEATHER_AUTO_PICKS=true on Vercel — weather scanner activates from next tick. $40 bankroll, intentionally consumable.
`b161b06` Removed dead ivRank +5 stamp (closes #1117) + UOA-solo confluence gate (closes #1118). The ivRank "stuck at +5" finding turned out to be duplicative scoring — computeIvRank measures percentile within chain, not historical IV; ATM strikes have lower IV than OTM via vol smile, so 27/30 recent plays scored +5 just for being ATM. Strategy-level scorers (scoreIvTerm, scoreEarnings) still use ivRank where it differentiates. UOA-solo gate filters single-strategy UOA plays with confluenceCount<2 (effectively all UOA-solo) — Mescudi data: 52% WR n=88 vs 63% UOA+SPREAD.
`83a4318` Loss-streak stateVersion auto-reset (closes #1115). On VPS startup, if persisted stateVersion < EXECUTION_LAYER_VERSION constant, consecutiveLosses resets to 0 and version bumps. Initial v1 → v2 covers the atomic exitPrice writer. Deployed live to VPS — readiness checks all green, auto-reset cleared a stale streak=1 from v1, persisted as v2.
`d626a46` vixRegime at play creation (closes #1102). LOW/MODERATE/HIGH/EXTREME from regimeFlags.vixLevel. Unblocks Arena Round 3 priors→posteriors transition.
`95d93a1` scanWindowHour Int field (closes #1107). ET hour at scan time, captured via Intl.DateTimeFormat in America/New_York. Backfilled 238 historical rows from ScanRun.createdAt. Distribution: hour=9 n=79, hour=10 n=27, hour=14 n=24, hour=15 n=25, hour=16 n=83 (legacy).
### Triage
#1116 closed with corrected diagnosis. The "5 dead components" framing was overstated:
- vanna → already fixed (commit 5d4b792, 27% fire rate post-fix)
- vix → by design (regime-conditional, fires HIGH/EXTREME only)
- fred → by design (fires INVERTED/FLAT curve or ELEVATED+ stress)
- macro (Nostradamus) + cicero → split out to #1127 for pipeline verification
- news → already working (73% fire rate)
#1127 filed for macro/cicero pipeline verification follow-up.
### Memory updates
Rewrote feedback_time_estimates_optimistic.md: my time estimates run unreliable in BOTH directions; user rule = "don't let time be a limiting factor, I can always defer manually."
Added feedback_no_problem_deferral.md: ship identified-problem-with-concrete-fix in-session, don't defer to tomorrow as comfort move.
### What changes for the 6:50 AM PT scan tomorrow
edgeScore baseline drops ~1.6 points across all plays (removed +5 ivRank stamp / 320 divisor)
npx vitest run — 1169 main + 141 VPS tests pass (added 2 new tests for #1115 auto-reset behavior)
VPS readiness — all checks green at restart, 1 position (XLK $161C) tracking, market closed pre-restart
### Open follow-ups for owner
Rotate Odds API key after May 1 reset (#1121) — unblocks MLB scanner
Watch first 2-3 days of new scoring distribution before tuning bucket floors
ivRank "stuck on +5"
TECHNICAL+MAX_PAIN combo at 65.6% WR
Trend-backfill fix shipped (5d4b792) — scoreAndRankPlays now propagates trendDirection across all hits per ticker via a tech-cache pass. Vanna scoring should activate on ~75% more plays starting tomorrow's 6:50 AM scan.
### Stale PENDING reconcile (#1108)
Archy live-trade-sanity flagged 11 PENDING+played plays >48h old. Diagnosed: VPS execution writes pnl + scannerResult on exit but never writes exitPrice; settle cron has a guard at line 171 that skips plays without exitPrice. Manually reconciled all 11: 5W / 6L / −$308 net realized (incl. TSLA −$260 which was previously hidden from analysis). D1 audit findings shift slightly with these 11 added. #1108 closed; root cause logged for #1095/#1110 atomic-trade-log work.
### Issue triage (63 → 45 open)
Per user direction "review what we can close, what aligns with goal." Closed:
- Bucket 1 (critical, dupes): #1108, #1119
- Bucket 2 (resolved/stale): #1109, #1117, #1046, #970, #977, #1024, #1042
- Bucket 4a (PC autonomy fixes Mac shipped): #1075 (publish-status awk), #1086 (AUTO-DRAFT dedup with 4h window), #1039 (git-sync.sh empty-commits-as-1), #1093 (subagent-stop noise), #1034 (lana null-case routing in agent prompt), #1100 + #1097 + #1096 (closed as not-in-repo)
- Strategic: #1106 CODEOWNERS shipped — .github/CODEOWNERS now gates Mac review on live-trading paths (scanner, kalshi, price-stream, cron, schema, auth). Branch protection toggle still manual.
### Kalshi observability shipped
User: "I want it as much of a focus as options... whats the call?" Shipped infrastructure to make the call data-driven:
- Enhanced `kalshi-scorecard` cron — adds pipeline volume per surface (scanned vs traded), dark-scanner alarms (14d window), and weather unpause-gate signal (Brier ≤ 0.30 over ≥ 20 settled post-#1081 picks).
- CLAUDE.md formal unpause gate documented under "Live Beta — Prediction Markets":
- Cohort start: 2026-04-26 (#1081 ship date)
- Pre-cohort 26-pick legacy data (Brier 0.4855) excluded from gate math but kept on /track-record
- Required: Brier ≤ 0.30 AND ≥ 20 settled in cohort
- Decision is manual env flip, not auto-unpause
- MLB dark diagnosis — manual scanner trigger surfaced "Odds API 401 Unauthorized." Key 58d old. Filed #1121 for user to rotate.
### Honest take on Kalshi
Surface-level differences with options that argue against equal capital allocation today (vs equal observability):
- No Cicero/Wumbo equivalent on Kalshi side (Nostradamus only on macro)
- 2¢ entry fee = ~2% drag on $1 contracts → tight edge math
- Smaller addressable universe (~10 NBA games/day, 32 weather contracts)
- Weather Brier 0.4855 was directional miss not calibration drift — the rebuilt model needs 3-4w of post-fix data to prove out
Reasonable posture: equal observability now, capital allocation pending data.
### Issues filed
- #1121 Odds API 401 — user action: rotate key
- #1120 Macro/Cicero/News upstream verification (Type B from #1116 split)
### Tomorrow watch
1. Rotate Odds API key (5 min) — unblocks MLB
2. SPY $685P likely stops out at open (~−$14 expected)
3. First scan with trend backfill live — watch edgeScore distribution
4. D1 audit re-run post-close with reconciled 11 plays