בס״ד
ואהבת לרעך כמוך
← Home

System architecture

every app · every engine · every data store · who can touch what · the unify map
Five layers, top to bottom. Surfaces (what you tap) → Engines (what runs) → Data stores (where state lives) → External (3rd party we depend on) → Cadences (when things fire automatically). Security pills on every node so blind spots are visible. Tap any node name to go to the live thing.
1Surfaces · what you actually tap 17 pages
Home base
LiveGated
Bento dashboard. Cash + Loops + Markets + Today + Groceries + launcher to everything.
From
ops-api · /plaid/balances · /inbox?cmd=QUEUE+GLIST
To
browser only; no writes from this page
Do this next
LiveGated
The ONE move. Filters out blocked items, picks highest-leverage doable.
From
ops-api · /inbox?cmd=QUEUE
To
ops-api · DONE/DEFER/NEED_INFO writes
Peek
Needs FinnhubGated
Type a ticker → sanity card. Not the FSE.
From
ops-api · /mis/peek → Finnhub /quote /profile2 /metric /calendar /candle
To
read-only
Connect a bank
SandboxGated
Plaid Link UI. Sandbox now; Production swap = 1 secret edit.
From
ops-api · /plaid/link-token /plaid/items
To
ops-api · /plaid/exchange → KV (encrypted tokens)
Obligations PWA
LivePublic link
Chanie-personal default. Live obligations from BOS sheet.
From
Apps Script Web App (pwa-api) → Monthly Obligations sheet
To
read-only (write loop captured but not wired)
Chanie · G
MockupGated
Awaiting Sam's vibe vote. Plum/brass/cream, Hebrew chars, plain copy.
From
sample data (not wired)
To
SMS prefill to Zee
Cockpit Offer
LiveGated
Buyer-facing one-pager. Walk-into-Weiser asset.
From
static
To
read-only
App Library
LiveGated
Catalog of every PWA + tool + proposed build + skill.
From
static (hand-curated)
To
links to each app
Icon Studio
LiveGated
Design icons live, send spec to Claude.
From
browser-local
To
clipboard → chat/Telegram → make-icons.mjs
Photographs you send → extracted + filed. School tax #1 lives here.
From
Telegram images → Claude reads → docs/captures/
To
portal pages + memory references
Auto-regen list of every output. Pre-commit hook keeps it current.
From
git pre-commit hook scans outputs/
To
read-only
75 → 8 projects merge view (snapshot 5/27).
From
snapshot at build time
To
read-only · regenerable via tools/build_projects_board.py
System audit
LiveGated
Diagnose-before-solution surface. Inventory + diagnosis + product hypothesis.
From
snapshot
To
read-only
2Engines · what runs 5 services
ops-api Worker
LiveHolds secrets
Cloudflare Worker at ops-api.sam-0f0.workers.dev. Routes: /health, /plaid/*, /inbox (whitelisted commands), /mis/peek.
Holds
PLAID_CLIENT_ID, PLAID_SECRET, INBOX_SECRET, APPS_SCRIPT_URL, FINNHUB_API_KEY
Reads
CF KV (PLAID_ITEMS), 3rd-party APIs
Writes
CF KV (tokens), Apps Script Web App
HSInboxBot (Pulse Bot)
LiveHolds secrets
Google Apps Script bound to Personal Command Inbox sheet. Runs the Telegram webhook, pulse cadence, brain feed, search-eyes, remember-op.
Holds
INBOX_SECRET, TELEGRAM_TOKEN, ANTHROPIC_API_KEY in Script Properties
Reads
Sheet (Action_Queue, Transcript, Grocery, Brain_Feed, Context), Gmail, Calendar
Writes
Same sheet; Telegram replies
MIS v2 engine
LiveHolds Finnhub
Apps Script MIS/v2/Code.gs as a Web App. FSE 11 gates, SACS, holdings ingestion, entry-pad renderer.
Holds
FINNHUB_API_KEY, MIS_V2_TOKEN
Reads
Snapshot/Tickers/Market sheets, Finnhub, Gmail (broker emails)
Writes
Snapshot, FINAL_STATE_ENGINE, EARNINGS_DEPTH, FINAL_STATE_HISTORY
LevSMS router
PilotHolds Twilio
Apps Script bound to LevSMS sheet. Twilio webhook → SMS UX (TIMES, NEXT, ZIP, SHUL, REFRESH).
Holds
TWILIO_SID, TWILIO_TOKEN in Script Properties
Reads
LevSMS sheet, Hebcal API, NW schedule
Writes
Twilio outbound SMS
Telegram webhook proxy
Live
Cloudflare Worker at telegram-webhook. Fixes the 302 issue between Telegram and Apps Script.
Reads
Telegram updates
Writes
forwards to bot's doPost
3Data stores · where state lives 7 stores
Personal Command Inbox sheet
LiveOwner-only
The single source of truth for tasks. Tabs: Action_Queue · Transcript · Grocery · Brain_Feed · Context · Profile.
Holds
75 open cards · grocery list · full bot transcript · session brain-feed entries
Monthly Obligations v1
LiveOwner-only
CANONICAL per Sam 2026-05-06. The household money sheet. v2 is stale.
ID
1L_rxCSOnc...
Reads
obligations PWA · BOS scripts · briefings
Cloudflare KV (PLAID_ITEMS)
LiveEncrypted
Encrypted Plaid access tokens + 5-min balances cache.
ID
1801c5faf766...
Reads
ops-api Worker only
.claude/memory
LiveLocal-only
My personal memory. ~150 files. Never leaves this machine — gitignored, never commits anywhere.
Path
%USERPROFILE%\.claude\projects\...\memory
Workspace repo (GitHub)
LivePrivate repo
zee78900/hookstreet-workspace. Code + outputs + docs + captures. Private — only Sam's GitHub.
Holds
everything except secrets (which live in Apps Script + CF Worker)
Google Drive
LiveOwner-only
Folders for STR, Eden, Mom, archived sessions, OneDrive Mirror. Read-only from Claude.ai connector.
Gmail (2 accounts)
LiveOwner-only
sam@hookstreetcapital.com (business) + ztreitel@gmail.com (personal). Mildred has access to business only.
4External · 3rd party we depend on 8 services
Cloudflare
Live
Pages (portal hosting) + Access (Gmail-login gate) + Workers (ops-api, telegram-webhook) + KV. Same login.
Anthropic API
Live
Powers the bot's conversational layer (when MENTION + non-command lands).
Plaid
SandboxProd in review
Bank balances + transactions. Sandbox works (Tartan Bank); Production pending Plaid review.
Finnhub
Key needed
Market data. Key is in MIS Script Properties; copy to ops-api Worker for Peek to go live.
Twilio
Live
LevSMS pilot + Mom 2-way relay. Auto-recharge $20 on card 9405 (acct 1260).
Telegram
Live
HSInboxBot. Voice + text capture. Outbound from notify.ps1 and the bot itself.
Google Workspace
Live
Gmail (×2), Calendar, Drive, Sheets, Apps Script. 2FA isolated per account.
GitHub
Live
7 repos. hookstreet-workspace private. 3 public (services site, abnbcalc, lawn-coop).
5Cadences · when things fire automatically
every 30 minPulse — bot scans queue + mail + calendars. Observe mode. Asks before acting on money/legal/family. 7 AM dailyMorning brief — Telegram message with date, weather, top loops, today's agenda. on pushPortal redeploy — Cloudflare rebuilds ops.hookstreetservices.com ~60 sec after any commit to outputs/. on commitBriefings index refresh — pre-commit hook regenerates outputs/index.html from all output files. manualBOS reports — Operations Summary, Daily Snapshot, Weekly Review run from triggers Sam can review in MIS/BOS script editors. every sessionI read STATE — Claude Code pulls inbox.ps1 STATE (queue + grocery + transcript) at every session-open so I'm not blind to what you texted the bot.
?FAQ + blind spots
The "12 rows" cap you saw — what is it?
The Telegram QUEUE command shows all open cards (75 right now), but on the home page the Open Loops tile shows the top 12 grouped by P0/P1/P2. The "Today" tile (just added by parallel session) shows the top 4. To see all 75 → tap "see all 75 in the projects board" link inside the loops tile, or open next.html (the highest-leverage one) or the Projects board.
Where are my secrets — exactly?
None in this repo. Secret locations:
· ops-api Worker (CF Worker Variables/Secrets): PLAID_CLIENT_ID · PLAID_SECRET · INBOX_SECRET · APPS_SCRIPT_URL · FINNHUB_API_KEY (still pending)
· HSInboxBot Script Properties: TELEGRAM_TOKEN · ANTHROPIC_API_KEY · INBOX_SECRET (matched pair with the Worker)
· MIS v2 Script Properties: FINNHUB_API_KEY · MIS_V2_TOKEN
· LevSMS Script Properties: TWILIO_SID · TWILIO_TOKEN · LEVSMS_NUMBER
· Local laptop: command-inbox/.claude-notify.json (gitignored) holds webhookUrl + inboxSecret + notifySecret for the laptop to text you.
Browser pages never hold a secret. The ops-api Worker is the broker: it holds the secret, accepts only whitelisted commands from the browser, forwards the privileged call.
Who can read the portal?
Only Sam. Cloudflare Access on ops.hookstreetservices.com requires Google login for sam@hookstreetcapital.com. Anyone else gets the login wall (you saw it when Playwright tried). If you add Chanie to the Access policy later (Cloudflare Zero Trust → Access → Applications → Add Email), she gets the same Gmail-login wall with her own account.
Blind spots I'm watching for you
1. outputs/pwa-deploy/ Netlify mirror is a public URL with read API key in source. Stop sharing that link; the same PWA on ops.hookstreetservices.com/pwa-deploy/ is the gated copy.
2. Apps Script Web App URLs are public but require INBOX_SECRET in the POST body for writes. Anyone who knew the URL could send GETs — that's why every command goes via POST with secret.
3. The Telegram bot's webhook URL is public — its only auth is "does the message come from Telegram's IP." Telegram does send-time validation; a leaked URL means spam at worst, not data theft.
4. The OneDrive Mirror sync means your laptop's local working copies show up across devices. If a device is lost, the workspace is exposed at the OS level. Recommend Windows BitLocker / FileVault on any device that syncs.
5. Gmail = the master key. 2FA + recovery contacts already locked. If anyone hijacks Gmail they can reset Cloudflare/GitHub/Plaid → that's why no MFA bypass anywhere.
I (Claude Code) didn't see Chanie found a gardener until you told me — why?
You texted that to the bot, not to me. The bot kept it in its Transcript tab; I wasn't reading the transcript at session-open. Fixed — locked the rule in feedback_read_bot_transcript_at_session_open. Every session-open now pulls inbox.ps1 STATE which includes the transcript tail. New asks you drop to the bot get caught.
architecture · ops.hookstreetservices.com/architecture.html · regenerable as system grows · בס״ד