| Feature | MIS v1 (the email engine) | MIS v2 (the dashboard) |
|---|---|---|
| Sheet ID | 1HEmRev… MIS_v7.1_gsheet_forclaudeedit | 1HEmRev… SAME sheet (v2 is also bound to it) |
| Script ID | 1yBMztL4… MIS-v1-script | Separate v2 deployment AKfycbw…UeHzfU… |
| Code location | MIS/MIS-v1-script/ (Code.js · emailDailySnapshot.js · fse_foundation.js · mobile_command_center.js · runSACSUpgrade.js · 9,640 lines) | MIS/v2/ (Code.gs from _gen.py · 241 KB) |
| Output channel | Gmail emails: Morning Brief 9:46 AM · Trade Action 2:05 PM · Power Hour 3:00 PM · Sun 6:05 PM Week-Ahead | Web App URL + Scope page + Telegram bot bridge |
| Trigger | Apps Script time-triggers (4 per weekday) | Cloudflare cron (nightly snapshot) + on-demand |
| Data source | Sheet tabs + GoogleFinance + Finnhub + Schwab API | Sheet tabs + Yahoo v8 chart + Finnhub + Worker overlay |
| FSE | Yes (10-gate resolver, lives in fse_foundation.js) | Yes (11-gate, lives in _gen.py Code.gs) |
| Reads holdings | Yes (HOLDINGS_CLEAN tab) | Yes (same tab) |
| Cost basis truth | Old (transaction-derived) | NEW broker-snapshot (lifetime +$22,447, 14 equities) |
| Per-account split | Partial | Yes — Sam/Joint/Son/Daughter/Schwab 6-way |
| Active code maintenance | Last touched May 20 | Active (15+ deploys in last 7 days) |
Both, for different jobs. v1 is your push-cadence (3 emails/day fire whether you check or not — discipline mechanism). v2 is your pull-cadence (you open the dashboard or Scope when you want to dig).
The v1 emails should keep firing. The v2 dashboard is what you USE when you want to make a decision. Don't kill v1; don't try to dual-fire what v1 already does well.
Conflict risk: the v1 brief computes verdicts from its own FSE; v2 computes from its own FSE. If the doctrine drifts between them, they'll disagree. Mitigation: v2 FSE was modeled on v1 FSE doctrine — same gates, same weights. Audit below.
You moved SCHWAB_CLIENT_ID, SCHWAB_CLIENT_SECRET, SCHWAB_REFRESH_TOKEN from the sheet's CONTROL tab to Script Properties. v1 stopped finding them.
Root cause: v1's misReadControl_(key) only reads CONTROL tab. When the tab cell is blank, returns empty string. Doesn't fall back to anything.
Fix (just applied in MIS-v1-script/emailDailySnapshot.js): the function now reads CONTROL tab first (legacy storage), and if empty, falls back to PropertiesService.getScriptProperties().getProperty(key). Non-destructive — CONTROL values still win if set. New values like Schwab credentials in Script Properties now found.
To deploy: needs your clasp login in MIS/MIS-v1-script/, then I push. YOUR ACTION
You need the bot to TELL you which price is regular session vs after-hours, with the differentiation explicit. Apple Stocks shows "At Close $X / After Hours $Y" — same pattern needs to land in MIS notifications.
Prior memory feedback_mis_advisory_not_autonomous said IBKR was ruled out because it needs an "always-on gateway machine." That was true for the legacy IB Gateway / TWS API. IBKR now ships the Client Portal API (Web) — OAuth-based, no gateway, works from a Cloudflare Worker.
| Path | Real-time quotes | Execution | Bracket orders | Cost | Friction |
|---|---|---|---|---|---|
| IBKR Web API | Yes (need data subscription) | Yes — stocks/options/futures | Yes (bracket + OCO) | $10/mo data (waived if you commission $30+/mo) + you already have the account | OAuth · session re-auth every ~24h (less pain than Schwab's 7d) |
| Schwab Trader API | Yes | Yes | Yes | $0 | 7-day refresh-token rotation (more pain) |
| Yahoo (current) | Yes | No | No | $0 | None |
New recommendation: IBKR Web API for execution + quotes is now the strongest single choice IF you want trade execution from MIS. Schwab still works for your existing positions but the 7-day rotation is annoying. You'd ideally want to consolidate trading into ONE broker — pick the one you'd actually trade from (or use IBKR for active trades + Schwab as the savings/custody account).
If you want me to wire IBKR: I need (a) your IBKR username (NOT password), (b) you generate an OAuth consumer key on IBKR developer portal, (c) I add it as Worker secret, (d) I build the bridge. ~3-4 hours of work. YOUR DECISION
| File | Lines | Purpose | Status |
|---|---|---|---|
| Code.js | 1,417 | Tab builders, Earnings_Master refresh, Tickers tab management, menu bar items | Active, healthy |
| emailDailySnapshot.js | 7,037 | The monster. Email engine + FSE renderer + Schwab API + Finnhub + GoogleFinance + HTML brief assembly | Active, has the Schwab bug I just fixed; otherwise healthy |
| fse_foundation.js | 511 | FSE doctrine + gate resolver (the 10-gate engine that emits verdicts) | Active, mirrors v2 logic |
| mobile_command_center.js | 218 | Mobile-friendly command surface (early prototype, predates Scope page) | PHANTOM — predates v2 Scope, likely unused |
| runSACSUpgrade.js | 457 | One-shot SACS migration helpers (renames, formula updates) | PHANTOM — migration runs are one-time, code stays as artifact |
Static analysis: 154 functions defined in emailDailySnapshot.js, all referenced somewhere. Doesn't mean all USED — some may live in dead branches or inside runOnce-style helpers. I can't reliably auto-detect "phantom" without runtime tracing. Honest answer: leave them all in place. Don't risk breaking the email engine to chase 10 KB of dead code.
| v2 lesson | Port to v1? | Effort |
|---|---|---|
| Broker-snapshot cost basis truth (UNG -36% fake → +7.4% real) | Yes — v1 reads HOLDINGS_CLEAN same as v2; once v2 has the correct Position_Costs, v1 will pick it up | FREE — already there |
| Account labels (Son/Daughter/Joint/Sam) | Yes — v1 brief's "Your Holdings" lists accounts; rename to match v2 labels | 30 min, low risk |
| FIFO realized P&L | Yes — v1 email currently shows only unrealized; adding realized = honest +$22K visible in the brief | 1 hr — read v2's Realized_PnL tab in v1 brief |
| Apple-style dual price labels | Yes — v1 brief should split "AT CLOSE / AFTER HOURS" in the Holdings section | 30 min |
| Weekend display fix (no after-hours labels Sat/Sun) | Yes — v1 brief skips Sat/Sun already; minor cleanup needed | 10 min |
| No-MQB warning (Extended + 10D > 5%) | Already in v1 via "EXTENDED" flag in High Conviction Setups section | FREE |
| Sector ETF context | v1 already shows SECTOR_CLUSTER warnings; sector ETF comparison line could add | 30 min |
| # | Action | Time | Unblocks |
|---|---|---|---|
| 1 | clasp login from terminal in workspace root | 30 sec | MIS v2 cache deploy (4-5 min → 5-10 sec) + sheet hygiene endpoints + bot upgrades |
| 2 | cd MIS/MIS-v1-script && clasp login (separate auth for v1 script) | 30 sec | v1 Schwab fix deploys; v1 brief picks up your Script Properties Schwab credentials |
| 3 | Decide on IBKR: yes/no/later | 1 min | If yes, I scope the wire |
| 4 | Pick a Scope mockup (A-F from yesterday) | 5 min | Real Scope refactor |
| 5 | Confirm: should I port realized P&L + dual-label prices to v1 brief? | 1 min | v1 brief upgrade |