HilltopCommand Center
Generated 2026-07-30 07:33 CDT ← Operational dashboard

Memory tiers 4 stores

Three layers Claude reads from on every session, plus the behavioral rules that shape every reply. Tap to expand.
Mutable working state
What's true RIGHT NOW
10h ago
↳ hmg-ops
485 LOG entries

PRIMER, BLOCKERS, CHARTER, OBJECTIVES, LOG. The single source of truth for current operational state. Read on every Claude session.

PRIMER.mdBLOCKERS.mdCHARTER.mdOBJECTIVES.mdLOG.md
Domain knowledge
How HMG ops actually work
18h ago
↳ hmg-ops/runbooks + scripts + state.sqlite
23 runbooks · 87 scripts · state.sqlite

Operational mechanics: how prospecting works, how outreach is reviewed, how the morning stack runs. Plus the live state.sqlite database backing the pipeline.

M5-CUTOVER-PACKET.mdREADME.mdbyzantine-context-corruption-protocol.mdclaude-code-autonomous-ops-deep-report.mdcodex-claude-alignment-check.mdcodex-peer-sync.mddesign-palette-log.mddesign-skill-router.mdescalation-policy.mdexecution-power-policy.mdloop-engineering-partner-guide.mdm5-continuity-cutover.mdmemory-routing.mdmorning-stack.mdnew-prospect-intake.mdoutreach-review.mdsemantic-recall.mdsend-pipeline.mdsite-update.mdstall-detection.mdtool-precedence-map.mdweekly-metrics.mdworkspace-organization.md
Durable knowledge
Strategy, people, firms, frameworks
15m ago
↳ Obsidian Brain
565 markdown files

Long-lived knowledge that doesn't change session to session: prospect dossiers, firm intelligence, strategy notes, frameworks. Indexed by MEMORY.md at the vault root.

.claude00-meta_archiveclaude-configclaude-projectshmgprospect-stackroundup
Behavioral rules
How Claude is told to behave
4d ago
↳ auto-memory
70 memory files · 37 feedback rules

Behavioral feedback loaded into every Claude session. Tells Claude how to behave (e.g., verify before quoting, default to Telegram replies, design quality bar).

MEMORYREADMEfeedback-10am-send-cron-canceledfeedback-14d-gate-first-touch-onlyfeedback-be-efficient-by-defaultfeedback-build-meta-canary-not-just-step-canariesfeedback-codex-review-touch-scriptsfeedback-daily-updates-into-morning-pdffeedback-ddg-not-brave-for-hmg-searchfeedback-default-to-telegram-replyfeedback-design-bar-client-readyfeedback-epistemic-disciplinefeedback-execute-without-permissionfeedback-execution-power-ladderfeedback-hmg-positioningfeedback-no-autonomous-claude-cronsfeedback-no-codex-without-approvalfeedback-no-hands-faces-in-ai-imageryfeedback-no-outbound-emails-at-allfeedback-no-side-effecting-poll-loopsfeedback-no-stitchfeedback-parallel-subagent-defaultfeedback-peer-protocol-v3-disciplinefeedback-portable-paths-for-codex-messagesfeedback-repo-visibility-default-privatefeedback-save-durable-facts-immediatelyfeedback-scope-selectorfeedback-screenshot-per-stepfeedback-self-healing-errorsfeedback-self-improving-skillsfeedback-stay-on-flat-subscriptionfeedback-telegram-no-markdown-around-urlsfeedback-telegram-status-emojifeedback-transient-viz-defaultfeedback-use-semantic-recallfeedback-validate-canaries-against-ground-truthfeedback-verify-before-quoting-statefeedback-verify-rendered-artifacts-not-just-filterfeedback-watch-skill-for-videoshmg-dashboard-two-prospect-datasetsproject-b012-cowork-task-bypasses-pause-flagproject-barkow-acquisitionproject-boardroom-pluginproject-burke-resellerproject-claude-code-autonomous-ops-deep-reportproject-claude-code-desktop-2026-05-02project-codex-claude-peer-syncproject-design-pipeline-three-toolproject-firehose-is-discovery-shadowproject-granite-harbor-capital-buildoutproject-grounded-coach-pluginproject-hmg-pipeline-stalled-2026-05-03project-hmg-thin-pool-canary-is-often-a-render-bugproject-lake-effect-sweetsproject-local-llm-m5-researchproject-mac-m5-migrationproject-prospecting-live-vs-dead-engineproject-prospecting-name-extraction-bugproject-prospecting-rebuildproject-revenue-streams-portfolioproject-run-businesses-hmg-agent-wrong-sourcesreference-browser-harnessreference-claude-sandbox-instancereference-claude-video-watchreference-hmg-launchpadreference-huashu-design-skillreference-obsidian-mcpreference-scripted-search-vs-websearchreference-yield-numbers-canonical-sourceuser-anthropic-subscription

Open blockers 7 open · last verified per blocker

Each blocker shows when its verify command last ran. Tap to expand the full unblock plan and trigger Telegram actions.
B-012 🔴 HARD STOP
10 AM Mon-Fri send cron CANCELED INDEFINITELY by Dan
⚠ no verify rule 23h ago
  • Since: 2026-05-12 09:56 CT
  • Action taken: commented out `0 10 * * 1-5 ... send_daily_batch.py` in crontab; backup at `/tmp/crontab.bak.20260512-095612`
  • Rule: do NOT re-enable, do NOT propose a replacement cron, do NOT route sends through any other scheduled path without explicit "go" from Dan in writing. The cancellation is not infrastructure pause (B-008 / send-quality); it's a directive from Dan.
  • Downstream impact: 9:55 materialize step and 11:00 send-rate canary are now no-ops; they're harmless and stay in place until Dan says otherwise. Drafts continue to accumulate but DO NOT SEND.
  • What unblocks: explicit "re-enable the 10 AM send" from Dan. Until then, treat any send as gated 🔴.
  • **⚠️ 2026-06-04 — BREACH FOUND + RE-ENFORCED (Claude, operator-mode, ESCALATED to Dan).** The crontab comment did NOT fully enforce B-012. The active `send_daily_batch.py` filename was silently restored ~5/19 (undoing the 5/12 `.DISABLED` rename), re-arming the **Cowork scheduled task**, which sent **83 real Graph emails 5/12→6/3** (incl. 9 on 6/3, 1 on 6/1, 2 on Sun 5/31) — on days the sweep reported "frozen." The WSL `send-pause.flag` is honored by the canonical copy but NOT by the Cowork runner (different `Path.home()`); 25+ worktree copies lack the flag guard entirely. **Re-applied the proven filename-disable:** `send_daily_batch.py` → `send_daily_batch.py.DISABLED-2026-06-04-b012-reenforce` (reversible). Sends halted 07:42 CT. **Still gated on Dan:** kill/fix the Cowork scheduled task at source so it can't re-arm; before ANY future re-enable, the Cowork runner must honor a kill switch in its own runtime. See LOG 2026-06-04 07:44.
No automated verify rule — resolves only on human confirmation.
B-011 OPEN
B-011
⚠ no verify rule 23h ago
  • Since: 2026-05-06 · One-pager drafted 2026-05-11
  • Doc: `~/hmg-ops/outputs/b011-fidelity-custody-pivot-2026-05-11.md`
  • What's drafted: (1) custody-screen question for Discovery Gap Analysis with 4-route routing matrix; (2) Fidelity-pivot positioning (operational consolidation across 3 liquidity tiers + treasury policy hygiene + custody-agnostic execution); (3) Fidelity-specific touch-1 variant; (4) `custodian` column schema for state.sqlite + sequence_follow_up.py routing logic; (5) 4-page treasury policy memo as the Fidelity-side artifact (queued for draft).
  • What still needs Dan: (a) FYI ack on `custodian` column addition (🟢 but logged here for visibility); (b) approval to deploy Discovery form update on production site (🔴); (c) per-batch send approval if Fidelity touch-1 ships.
  • Impact: medium — does not block Schwab-custody pipeline (still the majority).
  • Source: ~/research/competitor-pulse/2026-05-06.md
No automated verify rule — resolves only on human confirmation.
B-007 OPEN
B-007
○ still open per verify 23h ago
  • Since: 2026-04-19
  • Why it blocks: the MCP server config is in place (both `~/.claude/mcp.json` and `~/.claude/claude_mcp_config.json` have a `stitch` entry invoking `npx @_davideast/stitch-mcp@latest proxy`). It will not connect until Google Cloud credentials exist. Without it, we can't pull Google Stitch designs into Claude Code.
  • What unblocks it: Dan does ONE of the following when at the machine:
  • **Simpler path (recommended):** Go to stitch.withgoogle.com → settings → generate an API key → paste it into `~/.stitch/config.json` or set `STITCH_API_KEY` env var. No browser re-auth, no expiry.
  • **OAuth path:** Run `npx @_davideast/stitch-mcp init` in a terminal. Walks through gcloud auth, project selection, Stitch API enable. Token refreshes automatically via the proxy.
  • After credentials land: restart Claude Code so the new MCP server loads. First Stitch tool call will confirm it.
  • Impact: low-medium — optional design-to-code workflow enhancement.
verify command
test -f "$HOME/.stitch/config.json" || [ -n "${STITCH_API_KEY:-}" ]
B-013 OPEN
B-013
⚠ no verify rule 23h ago
  • Since: chronic, surfaced by Dan 2026-05-13 (msg 2409). Two root causes: WSL VM idle-shutdown + Claude CLI not subscribed to bridge SSE. ~5% silent miss rate measured (31/647). Today: 11h 14min outage 01:29:15 → 12:43:17 CDT killed the 07:30 operator plan + 8:33 digest + 8 AM morning_stack.
  • **Shipped 2026-05-13:**
  • ✅ Bridge patch `server.ts` — sends Telegram warning "⚠️ Claude offline (reason). Your message at HH:MM CT was not delivered..." on any undeliverable inbound. Debounced 5 min per chat. Restarted clean 13:02:37 CDT.
  • ✅ Windows Task Scheduler entry `Wake-WSL-Ubuntu` (AtLogOn, `wsl.exe -d Ubuntu --exec bash -c "true"`). Verified Ready + test-fired. Covers Windows-reboot case.
  • ❌ Headless `claude -p` watchdog — explicitly skipped per Dan 2026-05-13 (msg 2417). Design issue: bridge SSE allows only 1 subscriber; watchdog would evict Dan's interactive session and vice versa. Revisit only if visibility-fix proves insufficient after a week.
  • **Pending Dan:** paste `vmIdleTimeout=-1` line into `C:\Users\grayc\.wslconfig` under [wsl2], run `wsl --shutdown`, reopen. Snippet sent in Telegram msg 2414 (attachment `wslconfig-delta.md`). Closes the chronic "terminal closed → WSL idle-shuts" case.
  • When that paste lands + Dan confirms one successful overnight cycle: move B-013 to ✅ RESOLVED.
No automated verify rule — resolves only on human confirmation.
B-014 🟡 WATCH
Tokenized cash sweep category — Wall Street tokenization race accelerating
⚠ no verify rule 23h ago
  • Since: 2026-05-20 (logged from competitor pulse) · **Updated 2026-06-03**
  • Why it's on the radar: started as 2 tier-1 signals in 5 weeks; now **4 in ~3 weeks** — State Street/Galaxy SWEEP (5/5) → BlackRock readies 2 tokenized MMFs (5/8–5/9) → JPMorgan files JLTXX tokenized Treasury MMF on Ethereum for stablecoin-issuer reserves (5/12) → BlackRock additional tokenized-Treasury filings (5/23). Category is now Wall Street default-optionality, not a crypto experiment.
  • What it does NOT do this quarter: change HMG's positioning. **All four are qualified-institutional / stablecoin-issuer facing, subscribed via stablecoin/on-chain rails — no USD-subscription path for a mid-market PE/RE sponsor.** Schwab default-sweep gap math intact (now ~3.2%, compressed from 3.7% by Fed easing — rate environment, not competition; default Bank Sweep still 0.01%, verified 6/2). No mid-market sponsor-scale entrant.
  • **2026-06-03 trigger check — none of the three fired:** (a) no direct RIA cash-mgmt comp added a sponsor-facing stablecoin sleeve; (b) no SWEEP-tier USD-subscription retail path; (c) no Hazeltree sub-$500M tier. Stays a watch.
  • **2026-06-19 trigger check — none fired (strategy-pulse).** Race kept accelerating (JPMorgan MONY tokenized MMF live; State Street GENIUS-Act MMF for stablecoin issuers; CFTC GMAC backs tokenized MMFs as collateral) but all still qualified-institutional / stablecoin-issuer facing — no USD-subscription sponsor path. Schwab default sweep still 0.01% vs 3.21% reference (gap intact, ~3.2%). No positioning change. Source: `~/research/strategy-pulse/2026-06-19.md`.
  • **2026-06-26 trigger check — none fired (strategy-pulse).** No new movement at the sponsor layer; all tokenization activity remains qualified-institutional / stablecoin-issuer facing (no USD-subscription path), no RIA cash-mgmt comp added a sponsor-facing stablecoin sleeve, no Hazeltree sub-$500M tier. Schwab gap intact (~3.2 pts, rate-driven). No positioning change. Source: `~/research/strategy-pulse/2026-06-26.md`.
  • **2026-07-03 trigger check — none fired (strategy-pulse).** Tokenized cash/MMF (BlackRock BUIDL ~$2.5B, Circle USYC ~$3B now largest onchain Treasury fund, JPMorgan/Citi/BofA shared tokenized-deposit network slated 2027 for multinational corp treasuries) all remain qualified-investor / institutional / stablecoin-collateral — no mid-market PE/RE sponsor USD-subscription onramp. Schwab reference sweep SWGXX ~3.26% vs default Bank Sweep ~0.01% (gap ~3.25 pts, intact). No positioning change. Source: `~/research/strategy-pulse/2026-07-03.md`.
  • What would escalate this to a positioning event:
  • (a) One of HMG's direct RIA cash-management comps (Galaxy Treasury — the *cash management* RIA, distinct from Galaxy Digital — Allbridge, Arch, Treasury Reserve) bundles a stablecoin / tokenized sleeve into a sponsor-facing product.
  • (b) A SWEEP-tier product opens to non-qualified-institutional with a USD subscription path.
  • (c) Hazeltree announces a sub-$500M AUM mid-market tier.
  • What unblocks: nothing — this is a watch item. Re-evaluate on 2026-08-20 pulse (90-day delta).
  • Source: `~/research/competitor-pulse/2026-05-20.md`, updated `~/research/competitor-pulse/2026-06-03.md`
No automated verify rule — resolves only on human confirmation.
B-015 🟡 WATCH
Goldbridge ("Ramp for Real Estate") — YC-backed RE idle-capital treasury entrant
⚠ no verify rule 23h ago
  • Since: 2026-06-03 (logged from competitor pulse)
  • Why it's on the radar: first funded, named, RE-specific, idle-capital, high-yield treasury entrant logged in these pulses. Launched out of Y Combinator (founded 2025, Greg Rami + Alvin Salehi; 2× YC founder + ex-White House advisor + 100-unit operator on the team). FDIC-backed high-yield **operating + reserve accounts** + automated reconciliation + AI banking for real estate **owners/operators**. Its pitch — ">$1T in annual rent, ~a quarter idle in reserves/security deposits earning nothing → high yield" — is HMG's gap thesis applied to the landlord/operator segment.
  • What it does NOT do this quarter: change HMG's positioning. **Different ICP** — property owners/operators (rent float, security deposits, operating cash), not PE/RE **fund** sponsors with idle fund capital between events. Different cash, different scale (per-property operating accounts vs sponsor AUM mandates), different custody (own FDIC banking infra vs Schwab custody). HMG doesn't touch operating accounts; Goldbridge doesn't touch fund-sponsor idle capital or RIA-partner advisory.
  • What would escalate this to a positioning event: Goldbridge (or a peer) adds a **fund-sponsor / GP-level tier** above operating accounts, lists sponsor-facing ICP language, or partners into the sponsor channel. That closes the adjacency.
  • What unblocks: nothing — watch item. Re-check product surface + ICP language on the 2026-07 (60-day) pulse; escalate to a positioning review if a sponsor tier appears.
  • **2026-06-19 check (strategy-pulse) — trigger NOT fired.** Confirmed a small **$500K pre-seed** (Era Ventures, Palm Drive, Singularity, YC) and a sharpened "first corporate card for real estate / spend-intelligence platform" positioning — ICP unchanged (RE owners/operators, not fund sponsors); no GP/fund-sponsor tier, no sponsor-channel partnership. Small pre-seed, not a scaling threat this quarter. Stays a watch. Source: `~/research/strategy-pulse/2026-06-19.md`.
  • **2026-06-26 check (strategy-pulse) — trigger NOT fired; adjacency WIDENING.** Public positioning now firmly "the first corporate card for real estate / spend-intelligence platform" (trygoldbridge.com, goldbridgebanking.com) — drifting *toward* card/spend/operating-account fintech and *away from* idle-capital treasury/yield framing. No GP/fund-sponsor tier, no sponsor ICP language, no sponsor-channel partnership. The product drift makes the adjacency to HMG's fund-sponsor lane *less* likely to close this quarter, not more. Stays a watch. Source: `~/research/strategy-pulse/2026-06-26.md`.
  • **2026-07-03 check (strategy-pulse) — trigger NOT fired.** Goldbridge scaling — YC launch + a partnership reportedly putting the AI-banking/spend platform in front of ~8M units — but ICP still RE **owner-operators** (rent float, security deposits), not PE/RE fund sponsors; continued card/spend-fintech framing keeps the adjacency to HMG's fund-sponsor lane *widening*, not closing. No GP/fund-sponsor tier, no sponsor ICP language, no sponsor-channel partnership. Stays a watch. **Related new watch (not a blocker yet): Orion Advisor Solutions × Flourish Cash integration (6/9)** — first notable RIA-cash-comp *distribution* move, but ICP = HNW individual client cash, not fund-GP/sponsor treasury; monitor for entity/fund creep. Source: `~/research/strategy-pulse/2026-07-03.md`.
  • Source: `~/research/competitor-pulse/2026-06-03.md`
No automated verify rule — resolves only on human confirmation.
B-008 🟠 STRATEGIC
0 replies from 197 first-touches sent (pre-fix sends)
○ still open per verify 23h ago
  • Since: 2026-04-27 (surfaced when migration data was correctly read)
  • Status update 2026-04-28: B-009 (root cause) is RESOLVED. The 197 sends went out BEFORE the DNS fix and almost certainly hit spam. The relevant question now is reply rate on **post-fix** sends.
  • Open work: (1) confirm whether any first-touches have been sent since DNS propagated; (2) if yes, watch reply rate over 7 days; (3) if 0% persists post-fix, then it really is copy/targeting and we run a rewrite + tier-1 resend.
  • Impact: HIGH — still the binding constraint on 30-day goal, but the lever has shifted from infra to copy/targeting.

---

verify command
python3 -c "
import sqlite3, sys
c = sqlite3.connect('$HOME/hmg-ops/state.sqlite')
n = c.execute('SELECT COUNT(*) FROM replies').fetchone()[0]
sys.exit(0 if n > 0 else 1)
"

Recent activity last 12 LOG entries

Append-only decision log. Tap any row to read the full entry.
2026-07-29 Reply-rate digest (B-008 tracker)

- 7-day: 0/0 (0.0%)
- 30-day: 0/0 (0.0%)
- All-time: 0/477 (0.0%)
- By touch number: touch1=0.0% (0/400), touch2=0.0% (0/69), touch3=0.0% (0/6), touch4=0.0% (0/2)
- 2026-07-29 20:50 — evening stack: 6 OK / 0 FAIL — digest: `hmg-ops/2026-07-29/evening-stack.md`

2026-07-28 Reply-rate digest (B-008 tracker)

- 7-day: 0/0 (0.0%)
- 30-day: 0/0 (0.0%)
- All-time: 0/477 (0.0%)
- By touch number: touch1=0.0% (0/400), touch2=0.0% (0/69), touch3=0.0% (0/6), touch4=0.0% (0/2)
- 2026-07-28 20:50 — evening stack: 7 OK / 0 FAIL — digest: `hmg-ops/2026-07-28/evening-stack.md`
- 2026-07-29 08:20 — morning stack: 0 OK / 0 FAIL — digest: `hmg-ops/2026-07-29/morning-stack.md`

## [0458] 2026-07-29 ~11:20 CT — Claude — Peer-protocol collision audit: zero damage found, but protocol has never been stress-tested (Codex silent 28 days) [dan-ref: "Yes please check"]

Triggered by Dan asking whether the hand-rolled peer-agent protocol has ever actually failed — context was evaluating `block/buzz` (Block's signed-event-log agent workspace) as a possible thing to copy.

**Audit result — the record is spotless (all VERIFIED against live files + git):**
- LOG.md seq numbers: 40 seq'd entries spanning [0418]→[0457]. Zero duplicates, zero gaps, all in file order.
- LOG.md never shrank once across 432 git revisions — append-only discipline held 100%.
- Zero merge commits ever touched LOG.md. Zero conflict markers ever committed to it.
- Obsidian vault: 6,623 commits, zero merge commits, zero conflict markers ever committed, none present now.
- Vault mirror `hmg/ops-mirror/LOG.md` is byte-identical to live (808,327 b, both 08:20 today) — sync is healthy.

**The catch — it's untested, not proven:**
- Codex has authored exactly 2 of 40 seq'd LOG entries ([0419], [0420]), both on 2026-07-01 — the day peer-protoco

2026-07-27 Reply-rate digest (B-008 tracker)

- 7-day: 0/0 (0.0%)
- 30-day: 0/0 (0.0%)
- All-time: 0/477 (0.0%)
- By touch number: touch1=0.0% (0/400), touch2=0.0% (0/69), touch3=0.0% (0/6), touch4=0.0% (0/2)
- 2026-07-27 20:50 — evening stack: 7 OK / 0 FAIL — digest: `hmg-ops/2026-07-27/evening-stack.md`
- 2026-07-28 08:20 — morning stack: 0 OK / 0 FAIL — digest: `hmg-ops/2026-07-28/morning-stack.md`

2026-07-26 Reply-rate digest (B-008 tracker)

- 7-day: 0/0 (0.0%)
- 30-day: 0/0 (0.0%)
- All-time: 0/477 (0.0%)
- By touch number: touch1=0.0% (0/400), touch2=0.0% (0/69), touch3=0.0% (0/6), touch4=0.0% (0/2)
- 2026-07-27 08:20 — morning stack: 0 OK / 0 FAIL — digest: `hmg-ops/2026-07-27/morning-stack.md`

2026-07-25 Reply-rate digest (B-008 tracker)

- 7-day: 0/0 (0.0%)
- 30-day: 0/0 (0.0%)
- All-time: 0/477 (0.0%)
- By touch number: touch1=0.0% (0/400), touch2=0.0% (0/69), touch3=0.0% (0/6), touch4=0.0% (0/2)

2026-07-24 Reply-rate digest (B-008 tracker)

- 7-day: 0/0 (0.0%)
- 30-day: 0/0 (0.0%)
- All-time: 0/477 (0.0%)
- By touch number: touch1=0.0% (0/400), touch2=0.0% (0/69), touch3=0.0% (0/6), touch4=0.0% (0/2)
- 2026-07-24 20:50 — evening stack: 7 OK / 0 FAIL — digest: `hmg-ops/2026-07-24/evening-stack.md`

## [0455] 2026-07-25 ~09:42 CT — Claude — Debug + hardening pass on grounded-coach v0.2.1 / boardroom v0.1.1 (Dan directive "as good as possible")
Scan found 5 real defects in the shared grounding engine, all shipped 2026-07-24 because verification was interactive-only (zero test files in either repo).
- **P0 fail-open (the big one):** an all-stopword turn ("what should I do?", "why?") tokenized to nothing, so `search_corpus.py` printed "nothing in the corpus addresses this" and exited **0** — indistinguishable from a genuinely silent corpus. The coach/board would then improvise ungrounded, i.e. exactly the failure the plugins exist to beat. Same class as the 2026-07-16 yield drift canary: a check that passes when it should fail. Fixed: degenerate queries now exit **3** with re-query guidance; both skills instructed to re-query from conversation context and never answer off an exit-3.
- **P1 hang:** `chunk_body()` looped forever when `--overlap-words == --target-words` (stride 0). Reachable from documented flags. Fixed via `clamp_chunk_params()`.
- **P1 silent data loss:** `overlap > target` gave a negative stride — a 2000-word source silently became 120 words, no warning. Same fix + stderr warning.
- **P2:** `sorted()

2026-07-23 Reply-rate digest (B-008 tracker)

- 7-day: 0/0 (0.0%)
- 30-day: 0/0 (0.0%)
- All-time: 0/477 (0.0%)
- By touch number: touch1=0.0% (0/400), touch2=0.0% (0/69), touch3=0.0% (0/6), touch4=0.0% (0/2)
- 2026-07-23 20:50 — evening stack: 7 OK / 0 FAIL — digest: `hmg-ops/2026-07-23/evening-stack.md`
- 2026-07-24 08:20 — morning stack: 0 OK / 0 FAIL — digest: `hmg-ops/2026-07-24/morning-stack.md`

## [0452] 2026-07-24 ~08:50 CT — Claude — Design stack: hardened the pipeline spine from instruction-only to hook-ENFORCED (Dan directive). New `~/.claude/hooks/design_spine_guard.py` (UserPromptSubmit) detects design/UI intent and injects the non-skippable mandatory spine (pre-flight → impeccable → audit×3 → verify+mechanical gates) into context; minimal-router philosophy unchanged (refines still symptom-picked, not all 25). Throttled 20min/session, silent on non-design prompts, always exits 0. Registered in settings.json; 4 tests pass (inject / throttle / no-false-positive-on-"dashboard" / re-anchor).

## [0453] 2026-07-24 ~09:40 CT — Claude — Built + shipped "Grounded Coach" Claude Code plugin (Dan directive "go just do it"). Private repo graychar2425-blip/grounded-coach. /coach <name> researches a public figure across 4 source streams (YouTube via yt-dlp + web interviews + public writings/letters + business frameworks), builds a cited BM25 corpus (pure-stdlib, no ML deps, flat-sub), and retrieves per-turn so answers are grounded + citable; strict+labeled fidelity (extrapolation flagged, no fabrication). 7 commands incl

2026-07-22 Reply-rate digest (B-008 tracker)

- 7-day: 0/0 (0.0%)
- 30-day: 0/0 (0.0%)
- All-time: 0/477 (0.0%)
- By touch number: touch1=0.0% (0/400), touch2=0.0% (0/69), touch3=0.0% (0/6), touch4=0.0% (0/2)
- 2026-07-22 20:50 — evening stack: 7 OK / 0 FAIL — digest: `hmg-ops/2026-07-22/evening-stack.md`
- 2026-07-23 08:20 — morning stack: 0 OK / 0 FAIL — digest: `hmg-ops/2026-07-23/morning-stack.md`

2026-07-21 Reply-rate digest (B-008 tracker)

- 7-day: 0/0 (0.0%)
- 30-day: 0/0 (0.0%)
- All-time: 0/477 (0.0%)
- By touch number: touch1=0.0% (0/400), touch2=0.0% (0/69), touch3=0.0% (0/6), touch4=0.0% (0/2)
- 2026-07-21 20:50 — evening stack: 7 OK / 0 FAIL — digest: `hmg-ops/2026-07-21/evening-stack.md`
- 2026-07-22 08:20 — morning stack: 0 OK / 0 FAIL — digest: `hmg-ops/2026-07-22/morning-stack.md`

2026-07-20 Reply-rate digest (B-008 tracker)

- 7-day: 0/0 (0.0%)
- 30-day: 0/0 (0.0%)
- All-time: 0/477 (0.0%)
- By touch number: touch1=0.0% (0/400), touch2=0.0% (0/69), touch3=0.0% (0/6), touch4=0.0% (0/2)
- 2026-07-20 20:50 — evening stack: 6 OK / 0 FAIL — digest: `hmg-ops/2026-07-20/evening-stack.md`
- 2026-07-21 08:20 — morning stack: 0 OK / 0 FAIL — digest: `hmg-ops/2026-07-21/morning-stack.md`

2026-07-18 Reply-rate digest (B-008 tracker)

- 7-day: 0/0 (0.0%)
- 30-day: 0/0 (0.0%)
- All-time: 0/477 (0.0%)
- By touch number: touch1=0.0% (0/400), touch2=0.0% (0/69), touch3=0.0% (0/6), touch4=0.0% (0/2)
- 2026-07-20 08:20 — morning stack: 0 OK / 0 FAIL — digest: `hmg-ops/2026-07-20/morning-stack.md`

2026-07-17 Reply-rate digest (B-008 tracker)

- 7-day: 0/0 (0.0%)
- 30-day: 0/0 (0.0%)
- All-time: 0/477 (0.0%)
- By touch number: touch1=0.0% (0/400), touch2=0.0% (0/69), touch3=0.0% (0/6), touch4=0.0% (0/2)
- 2026-07-17 20:50 — evening stack: 6 OK / 0 FAIL — digest: `hmg-ops/2026-07-17/evening-stack.md`

Behavioral rules 37 loaded into every session

Auto-memory feedback rules that shape Claude's behavior. Tap to read the full rule body.
10-am-hmg-send-cron-canceled-indefinitely-2026-05-12
The 10 AM Mon-Fri HMG send_daily_batch.py cron is canceled indefinitely by Dan as of 2026-05-12. Do not re-enable, do not route around it with a different scheduled send, do not run send_daily_batch.py ad-hoc. Outbound sends are 🔴-lane until Dan explicitly re-authorizes.

The HMG 10 AM Mon-Fri send cron (`0 10 * * 1-5 ... send_daily_batch.py`) is **canceled indefinitely** as of 2026-05-12 09:56 CT by Dan's directive. The line is commented out in crontab with a "CANCELED INDEFINITELY 2026-05-12 (Dan)" marker; backup at `/tmp/crontab.bak.20260512-095612`. Tracked as [B-012] in `~/hmg-ops/BLOCKERS.md`.

**Why:** Dan directive — not an infrastructure pause, not a problem with `send_daily_batch.py` specifically, not B-008 (the 0/197 reply-rate issue). He explicitly said "the 10 AM cron has been canceled indefinitely." The reason is his call, not an inferrable system constraint.

**How to apply:**
- Do NOT re-enable the cron line.
- Do NOT propose or build a replacement scheduled send path (different time, different script, different harness) without asking Dan in writing first.
- Do NOT run `send_daily_batch.py` ad-hoc from a shell as a workaround.
- Drafts continue to accumulate — that's fine, treat them as queued, never auto-shipped.
- The 9:55 materialize-queued-sends cron and 11:00 send-rate canary are now structural no-ops; leave them in place until Dan says otherwise (harmless, will be needed when sends resume).
- Outbound sends are 🔴-lane (per `~/hmg-ops/runbooks/escalation-policy.md`) until Dan re-authorizes — even a one-off send for a specific prospect requires explicit "go."

**What unblocks:** explicit "re-enable the 10 AM send" / "send is back on" from Dan via Telegram or hmg-ops LOG. Only then revert the crontab line.

Related: [[ops-l

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-10am-send-cron-canceled.md
14-day recipient-history gate is a first-touch gate, not a follow-up gate
Don't add `recent_recipients_14d()` filter to sequence_follow_up.py — follow-up touches by definition target recently-contacted addresses

The `recent_recipients_14d()` filter in `email_helpers.py` is meant to block FIRST-TOUCH drafts to addresses that were already sent any HMG email in the last 14 days. It must NOT be applied to follow-up sequences.

**Why:** Follow-up touches (touch-2, touch-3) have `delay_days` typically 2-7 — they target the SAME recipient who just received touch-1 days ago. Adding the 14d gate to `sequence_follow_up._passes_followup_gate` silently kills every legitimate follow-up because by definition the recipient is inside the 14d window.

Codex caught this on 2026-05-08 review of an attempted "defense-in-depth" patch. Reverted before it shipped.

**How to apply:**
- The 14d-history gate belongs ONLY in `batch_first_touch._is_eligible` (first-touch path).
- The generic-mailbox gate (`is_generic_mailbox`) is fine in both paths — generic mailboxes never get touch-1 OR touch-2 anyway.
- If `send_daily_batch.py`'s 14d filter is also blocking legitimate follow-ups (it appears to read from the same source), that's a separate pre-existing issue worth investigating — but the fix is in send_daily_batch, not in the upstream draft generators.

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-14d-gate-first-touch-only.md
feedback-be-efficient-by-default
Default to the minimum tokens/tool-calls/context that fully does the job, then stop; efficiency is the path, not a cap on rigor

Operate efficiently by default. Spend the **minimum** tokens, tool calls, and context that fully accomplishes the task — then stop. Take the shortest correct path: the right dedicated tool over a shell pipeline, one batched call over many sequential ones, a targeted read over a whole-file dump, a direct answer over an exhaustive survey. Don't load abilities you aren't using — every skill / MCP / instruction description is rent paid on the context window **every turn**, so keep the harness lean.

**Why:** Dan asked (2026-06-19, after the Matt Pocock "harness > model" video) to wire "be efficient" into how I operate all the time. Pocock's core point: most people bloat their context with too many skills/plugins/MCPs/instructions; the leverage is in a lean, well-tuned harness, not more stuff. Efficiency compounds — it's faster for Dan on mobile and leaves headroom in long-running sessions.

**How to apply:** Before acting, pick the cheapest path that's still correct and complete. Batch independent tool calls into one message. Prefer dedicated tools (Read/Edit/Grep) over `cat`/`sed`. Read only the slice you need. Reply chat-shaped and scannable, not padded. Periodically question whether a loaded skill/plugin/MCP is earning its context cost. **Critical caveat — efficiency is the path, never a cap on rigor:** hard, irreversible, money/compliance/client-facing, or won't-fit-one-context work still gets full power per [[feedback-execution-power-ladder]] (Dan is on Max 20x; quality is t

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-be-efficient-by-default.md
Build end-to-end meta-canary for any pipeline, not just per-step canaries
When debugging pipeline silent failures, the fix is not a better per-step alert — it's an end-to-end meta-canary that catches upstream-quality issues, forward-looking starvation, and silent post-step degradation

When Dan reports a silent pipeline failure ("nothing's broken but the output is wrong"), the fix is rarely a better per-step canary. Per-step canaries each catch one specific symptom and miss:
- Upstream gate leaks where one step produces work the next step silently kills
- Forward-looking starvation (tomorrow's pool will be empty)
- Pattern-guess / regex misfires that produce structurally-valid-but-wrong output
- Cron file-naming drifts (the canary itself failing silently)

**Pattern (codified 2026-05-08 after a full day of "Dan keeps having to ask why X is broken"):**

1. Build ONE end-to-end meta-canary that scans the WHOLE chain (`~/hmg-ops/scripts/daily_pipeline_health.py` is the HMG reference).
2. Include forward-looking checks (tomorrow's eligible pool, not just today's send count).
3. Include post-step quality validators (e.g. `_local_looks_bogus()` for enriched emails — catches `veritas.impact@firm.com` shape misfires before they reach drafting).
4. Push ONE Telegram with 🟢/🟡/🔴 verdict + the specific issues. Don't fire multiple alerts per failure.
5. Add self-healing hooks where possible (e.g. evening auto-repair when pool < threshold).

**Why:** Dan's complaint isn't "alerts are bad," it's "I shouldn't have to be the one noticing." Every silent failure he prompts about is a meta-canary that should have existed. When patching one symptom, ask: "what's the meta-canary that would catch this AND its sibling failures next time?"

**How to apply:**
- Trigger: any HMG pipe

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-build-meta-canary-not-just-step-canaries.md
Run Codex review on touch-generating scripts before shipping
When patching batch_first_touch.py or sequence_follow_up.py, propose `codex review --uncommitted` before declaring the fix shipped — Codex catches bugs that grep + targeted reads miss

When modifying `hmg-harness/scripts/batch_first_touch.py` or `hmg-harness/scripts/sequence_follow_up.py`, run `cd ~/hmg-operations && npx codex review --uncommitted` (with focused prompt) BEFORE replying "fix shipped" to Dan.

**Why:** On 2026-05-08 I patched these files manually, declared the fix shipped, and Dan asked me to run Codex anyway. Codex found:
- 1 critical bug I introduced (a 14-day recipient-history gate added to `_passes_followup_gate` that would have silently killed every legitimate follow-up — touch-2 by definition targets a recipient just sent touch-1)
- 2 pre-existing bugs (variant pickers using Python's salted `hash()` instead of `hashlib.md5`, breaking stable A/B cohort assignment across runs)

I would have shipped the follow-up-killing bug to tomorrow's morning_stack and broken the entire follow-up sequence. Manual review missed it because the gate looked symmetric to the first-touch gate — but the semantics differ: first-touch must avoid recently-contacted addresses; follow-ups MUST contact recently-contacted addresses.

**How to apply:**
- Trigger: any uncommitted change in `batch_first_touch.py` or `sequence_follow_up.py` that modifies eligibility/selection logic, draft generation, or variant assignment.
- Run: `cd ~/hmg-operations && npx codex review --uncommitted` (optionally with focused prompt via `codex exec` if review subcommand rejects PROMPT arg).
- Dan has standing approval for Codex review specifically on these files (separate from the gener

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-codex-review-touch-scripts.md
feedback-daily-updates-into-morning-pdf
When Dan asks for a recurring/daily update, fold it into the 8 AM morning PDF brief — never add a new separate Telegram cron notification.

When Dan asks for a recurring or daily update of any kind, fold it into the morning PDF brief that ships at 08:00 CT weekdays. Do NOT add a new standalone Telegram cron line.

**Why:** Dan consolidated all proactive scheduled Telegram notifications into a single morning PDF on 2026-05-19. The whole point was to stop fragmenting his attention across many pings throughout the day. Adding a new scheduled Telegram cron undoes that consolidation. **2026-05-20 update:** Dan extended the rule to cover ALL canaries — even failure-only alarms. Every canary's would-have-been Telegram message now stages to `~/hmg-ops/outputs/morning-pdf/canary-<source>-YYYY-MM-DD.md` via `canary_sink.py` and is folded into the PDF. Trade-off Dan explicitly accepted: a real outage may not surface for up to 24h. **2026-05-21 reinforcement:** Dan reaffirmed this is the ONLY daily alert he wants and asked that every other alert be looped in. Audit + conversion of 7 remaining direct-Telegram cron scripts (auto_actions, vault_drift_sweep, path_b_loop, refresh_yield_numbers, draft_quality_audit, morning_preflight, vault_audit) to canary_sink. The ONLY scripts that may still fire Telegram directly are interactive ones (cockpit_action_handler responding to user dashboard taps) and the morning_pdf_brief itself.

**How to apply:**
- New daily/weekly/monthly cadence requested → save its output to `~/hmg-ops/outputs/morning-pdf/<slug>-YYYY-MM-DD.md` instead of pushing Telegram.
- New canary → import `canary_sink` an

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-daily-updates-into-morning-pdf.md
HMG prospect search uses DuckDuckGo, never Brave
Per the marketing-plans/prospect-stack.md doctrine, DDG is the documented free search backend; Brave should never be added even as optional fallback

For all HMG prospecting + enrichment scripts (signal_prospector / geo_prospector / conference_scraper / enrich_pending / prospect_pipeline / pere_scraper / bisnow_scraper / prospect_profiler / http_client), the documented search backend is **DuckDuckGo via the `ddgs` Python package**. Brave Search API must NOT be introduced or kept as a fallback.

**Why:** Documented in `Claude Brain/hmg/ops-mirror/marketing-plans/prospect-stack.md`:
- "DuckDuckGo HTML search (free) for contact discovery"
- "Cost: $0" — explicit zero-paid-API stance for this stack
- Brave doesn't appear in the cost table at all

The marketing plan's whole point is: this stack costs $0 in API fees (EDGAR free, DDG free, Microsoft Graph free with M365). Brave introduces a paid dependency that contradicts the design + creates a real failure mode (key expires/empties → silent prospect drought, exactly what happened around 2026-04-29).

**How to apply:** When editing or reviewing any HMG prospect stack script:
1. Strip BRAVE_SEARCH_API_KEY env loading and references entirely (don't leave as optional)
2. Make `web_search` in http_client.py call `ddg_search` directly, not a Brave→DDG waterfall
3. Don't add Brave-style retry/budget logic — DDG via `ddgs` package handles bot-challenge automatically
4. If a script claims to need Brave for "richer results," push back — the documented architecture says DDG is sufficient
5. When in doubt, grep the vault for the documented decision before re-introducing a paid dependency

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-ddg-not-brave-for-hmg-search.md
Default to Telegram reply, regardless of input wrapper
When answering Dan, ALWAYS use the Telegram reply tool — even if his message arrives without a `<channel source="plugin:telegram:telegram">` wrapper. He reads on Telegram primarily; Claude Code transcript output is invisible to him.

When responding to Dan from a Telegram-bridge session, **default to using the `mcp__plugin_telegram_telegram__reply` tool for every substantive response, regardless of how the input arrived**.

**Why:** 2026-04-27 incident. Dan asked "Where is the link to the beta iOS app" — his message came through without the `<channel source="plugin:telegram:telegram">` wrapper (probably routed through a different surface or system path). I defaulted to typing the response into the Claude Code transcript. Dan was reading on Telegram on his phone and saw nothing, had to ask three times. He explicitly called out the friction: "Why are you not responding to me each time in telegram?"

**How to apply:**
- This is a Telegram-bridge session (the system prompt says "@dansclaude_bot Telegram bridge for Dan Fink"). Treat it that way for ALL outbound communication, not just for messages that arrive with the explicit channel wrapper.
- Substantive replies → always send via `mcp__plugin_telegram_telegram__reply` with `chat_id="8532298090"`.
- Use `reply_to=<message_id>` only when threading under a specific earlier Telegram message; for the first reply to a non-channel-wrapped input, just send to chat_id without `reply_to`.
- Claude Code transcript text is fine for tool-call narration, status sentences, and end-of-turn summaries — those are visible to Dan when he checks the desktop session, but **never assume they replace the Telegram message**.
- If unsure whether a given exchange is in-bridge or out-

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-default-to-telegram-reply.md
design-bar-client-ready
Every design request from Dan must produce client-facing-ready, outstanding output — not first drafts. Run the full ui-improve pipeline (build → audit → refine → verify → polish) every time, no shortcuts.

Every design output Dan ships is client-facing. Acceptable quality bar is "outstanding and production-ready" — work that could be shown to a PE/RE sponsor in an investor meeting, or sent to a prospect, without embarrassment. First-draft quality is a failure mode. Generic AI aesthetics are a failure mode.

**Why:** Dan stated this explicitly on 2026-04-28 after I shipped the Alex Egan microsite and we discussed the design-skill toolkit. His exact words: "I want each request for design to create the most impactful and outstanding and client facing ready design so whatever you need to do to ensure that happens whichever skill you need to use whichever process you need to go through to use multiple skills. That is what I want." He's authorizing me to chain skills, run the full pipeline, and not shortcut.

**How to apply:**
1. On any design/UI/frontend request — even a small one — auto-fire `ui-improve` (per CLAUDE.md global rule) and run the full pipeline through verify, not just build.
2. Don't stop at "the build looks good" — audits + targeted refines + browser verification are mandatory, not optional.
3. If a domain has an existing brand (HMG site, RoundUp), load and respect its tokens first (e.g., `hilltopmanagementgroup-design` skill).
4. Pick the build skill deliberately based on context — impeccable default, huashu-design when exploring direction, ui-ux-pro-max when the prompt names a specific product type/style.
5. If something is genuinely out of scope (e.g., not an HTML

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-design-bar-client-ready.md
feedback-epistemic-discipline
On analytical/decision/research/audit work, label load-bearing claims inline (VERIFIED/REPORTED/INFERRED/ASSUMED), verify by re-derivation, avoid the banned failure modes, name the one thing to check

On **analytical / decision / research / audit / recommendation** work (NOT routine ops, drafts, or trivial mechanical tasks — those stay on the efficiency ladder), apply four disciplines:

1. **Label load-bearing claims inline** — VERIFIED (checked/derived) · REPORTED (source says; unconfirmed) · INFERRED (follows from verified) · ASSUMED (chosen for tractability). Attach the label to the sentence; never let a guess borrow credibility from an adjacent verified fact.
2. **Verify by re-derivation, not recognition** — rebuild the key claim by a *different* path (work backward, different units, extreme case, order-of-magnitude). Same-path recheck reproduces the same error.
3. **Avoid the banned failure modes** — precision theater · comprehensiveness without judgment (always rank & pick) · fluent agreement (check the premise) · uniform hedging (flat where verified, loud where not) · answering the more interesting question · citing the artifact as evidence.
4. **Name the one thing to check** — if the reader verifies only one thing, tell them which single claim breaks the answer if wrong.

**Why:** an AI-COO constantly asserts facts about firms, numbers, and live state; without epistemic labels a confident guess reads identical to a verified fact. Distilled 2026-07-07 from a reasoning protocol Fable 5 drafted for Dan; the net-new pieces beyond the existing [[feedback-execution-power-ladder]].

**How to apply:** on decision/analysis tasks, lead with the answer in decision language, l

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-epistemic-discipline.md
Execute without permission, with one consolidated outcome
When Dan authorizes a task ("go" / "execute" / "do this for me" / "yes do it"), run the full plan with available tools (browser, API, CLI), no per-step approval gates, no progress pings — ship one consolidated outcome message at the end. The 🔴 escalation lane is the only exception.

# Feedback: Execute without permission, with one consolidated outcome

**The rule.** When Dan authorizes a plan or task — "execute" / "go" / "do everything" / "yes do it" / "do this for me" / "use computer use" / "I want it done" — run the entire plan to completion using whatever tools are available (browser automation, API, CLI, MCP). No per-step approval gates. No progress pings between steps. Ship ONE consolidated outcome message at the end.

**Why (three incidents that codified this):**

1. **2026-04-30 — "Stop asking me for permission."** I asked Dan three times in a single audit-cleanup task whether to proceed, after he'd already said "execute." He ended it with: *"Stop asking me for permission."*

2. **2026-05-01 — "I just want it done."** I sent Dan written instructions to manually update a GitHub workflow YAML because the OAuth token from WSL lacked `workflow` scope. He pushed back: *"use computer use to do this for me please. I'm not at my machine. Get it done when I make a request like this. I just want it done. I don't need 18 steps confirming with instructions when you have the ability to do it."* The flow that worked once I stopped asking: GitHub OAuth (workflow scope blocked) → browser CodeMirror edit (flaky) → GitHub Contents API (404) → GraphQL createCommitOnBranch (FORBIDDEN) → pivoted to Cloudflare Pages dashboard → created an API token via the dashboard → deployed via `wrangler` CLI. One Telegram message at the end with the live URL.

3. **2026-05-05 — "Le

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-execute-without-permission.md
feedback-execution-power-ladder
Default execution behavior — audit before declaring done, match effort to task, escalate power when warranted, self-pace iterative work

Three default operating techniques Dan adopted 2026-06-17 (from the Simon Scrapes "10% of Claude Code" video). Full doctrine: `~/hmg-ops/runbooks/execution-power-policy.md`.

1. **Run-until-audited-done** — never single-pass anything shippable. Define the done-condition, do the work, then run an *independent* verification pass against it (self-critique → verify sub-agent → Workflow verify stage / `codex review`, by weight) before declaring done; iterate if it fails. The in-session `/goal`+auditor loop. **"Shippable" includes a confident recommendation Dan might act on — NOT just code/artifacts.** No conversational exemption: a confident analytical answer gets the same internal red-team pass before it ships, and I run that pass automatically — I do NOT wait for Dan to say "reanalyze." Corollary: state confidence proportional to the *evidence*, not the conversational stance (advocate vs. critic) I happen to be in. Diagnosed 2026-06-20 — I gave a confident reco, then produced three corrections on "reanalyze" with zero new data; the counter-args were in my own memory the whole time. The fix was applying this existing rule, not adding a new one.
2. **Deliberate effort** — match power to task: low for mechanical edits, medium default, high/max for hard reasoning, ultra/Workflow-fan-out for jobs that exceed one context window. Ladder: low→medium→high→max→ultra.
3. **Self-paced loops** — don't cram iterative/poll/accumulate-to-target work into one turn; use `ScheduleWakeup` / `/loop`

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-execution-power-ladder.md
HMG positioning is treasury management, NOT fractional CFO
HMG = Hilltop Management Group, a treasury management firm for PE/RE sponsors. Never frame HMG as fractional CFO, accounting firm, or generic advisory. Anchor every HMG-related reference to "treasury management for private capital."

# Feedback: HMG positioning lock

**The rule.** HMG is a **treasury management firm** for private equity and real estate sponsors. Never frame it as a fractional CFO firm, fund advisory firm, accounting practice, or generic consultancy. The canonical positioning is on hilltopmanagementgroup.com:

> "Hilltop Management Group builds institutional treasury frameworks for private equity and real estate sponsors. Charles Schwab custody. Same-day liquidity. FDIC-insured deposit program. SEC-registered RIA partner."

**Why:** Dan corrected this 2026-04-29 after I described HMG as "fractional CFO" in the deep ops report, in several skill descriptions (competitor-analysis, business-development, brw-ai-discoverability-audit), in the Claude Desktop project instructions, in Telegram replies, and in example research questions. The error propagated from older versions of those artifacts. Dan is firm: HMG is **not** in the fractional CFO market.

**How to apply:**

1. **Anchor to PRIMER.md and the website**, not memory or older artifacts. PRIMER says "treasury management firm for real estate and mid-market PE sponsors." Website hero says "Treasury Management for Private Capital." If a file disagrees, the website wins.

2. **Use this language consistently:**
- ✅ "Treasury management firm for PE/RE sponsors"
- ✅ "Institutional treasury framework over Schwab custody"
- ✅ "Yield-gap recovery on idle capital between fund events"
- ✅ "Sponsor-scale version of Apollo/Blackstone permane

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-hmg-positioning.md
feedback-no-autonomous-claude-crons
All autonomous `claude -p` cron jobs disabled 2026-07-09 — don't silently consume Dan's Max 20x usage; do NOT re-enable without explicit OK

On 2026-07-09 Dan disabled ALL cron jobs that invoke `claude -p` (run-businesses, cold-outreach, strategy-pulse, audit-autonomy, tune-up, sharpen, north-star, deep-research, newsletter, operator-morning/eod). **Why:** he doesn't want silent scheduled actions eating his Claude Max 20x usage when he isn't actively using it — the ratchets/analytics were writing reports into the (also-disabled) morning-PDF folder that nobody read.

**How to apply:** Do NOT re-enable any `claude -p` cron, or add a new one, without Dan's explicit go. The ratchets and content skills (/sharpen, /north-star, /tune-up, /audit-autonomy, /cold-outreach, etc.) are all still invokable on demand — run them manually when Dan asks, don't schedule them. Pure-python/shell crons (canaries, digests, dashboards, ops stacks, bridge watchdog) are fine — they cost no Claude quota. Before adding ANY cron, check: does it invoke `claude`? If yes, it's gated on Dan. Reversible: disabled lines are commented in the crontab with `# DISABLED 2026-07-09 by Dan (stop silent Claude usage...)`. Related: [[feedback-stay-on-flat-subscription]], [[feedback-daily-updates-into-morning-pdf]], [[feedback-10am-send-cron-canceled]].

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-no-autonomous-claude-crons.md
Don't run Codex calls without explicit approval
Codex CLI uses Dan's ChatGPT subscription auth tokens stored in ~/.codex/auth.json. Every codex command consumes his rate-limited ChatGPT quota — same bucket as his web/desktop app sessions. Do not run codex exec / codex / codex review / etc. for verification or testing unless Dan explicitly approves.

Any invocation of `codex` (interactive or `codex exec`, `codex review`, `codex apply`, etc.) uses Dan's ChatGPT subscription auth (OAuth tokens at `~/.codex/auth.json`, `auth_mode: chatgpt`). Each call counts against the same quota as his web/desktop ChatGPT app sessions.

**Why this matters:** ChatGPT subscriptions have rate limits that lock him out of the desktop app for hours when exceeded. On 2026-05-05 he flagged that his Codex desktop session had timed out until ~6 PM CT, while a verification `codex exec` test I ran (~4 PM CT) consumed his quota without explicit approval. The setup work (writing AGENTS.md, AIOS.md, symlinks) was authorized; the live verification call was not, and it likely extended his rate-limit window.

**Empirically confirmed 2026-05-05 ~16:18 CT:** the Codex CLI and the ChatGPT desktop/web app share the SAME usage quota. After Dan explicitly approved a Codex audit run, the request returned `ERROR: You've hit your usage limit ... try again at 5:52 PM.` This rules out the hypothesis that the CLI has a separate rate-limit bucket. Plan around the fact that ANY Codex CLI call counts against the same quota that Dan uses for normal ChatGPT work.

**Rule:** I can configure Codex (write AGENTS.md, edit ~/.codex/config.toml, install MCP servers) but DO NOT run `codex` commands that send prompts to OpenAI unless Dan explicitly says "test it" / "run it" / "verify it." Configuration is files-only and free; invocations are billable-against-quota.

**How to apply:

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-no-codex-without-approval.md
No hands or faces in AI-generated marketing imagery
Default photo prompts to "no people, no hands, no faces" — Pollinations FLUX (and most free image-gen) botches anatomy in ways that read as AI-uncanny on Instagram/LinkedIn carousels.

For any AI-generated marketing image (carousel slides, ad creative, social posts) using Pollinations.ai / FLUX / Stable Diffusion / similar free image-gen models, default to **objects-and-scenes-only** unless the brand specifically requires people imagery.

**Why:** Free / consumer-tier AI image gen as of 2026 still produces visible artifacts in hands (extra fingers, fused fingers, wrong proportions) and faces (uncanny eyes, asymmetry, mouth issues). On a 1080x1080 carousel that posts to Instagram/LinkedIn, those artifacts are immediately spottable and read as "AI slop" — which torpedoes brand premium-ness.

Dan's call after seeing the v3 cover-variants pass on 2026-05-05: "you can't do hands or people well… we've got a good set" once we re-ran without anatomy.

**How to apply:**
- All photo prompts in `~/hmg-ops/scripts/carousel.py` end with `, no people, no hands, no faces` by default. Already enforced defensively in `fetch_photo()` — appends the constraint unless the prompt explicitly opts in via "people"/"hand"/"face"/"portrait" keywords.
- When designing a new theme/campaign, prefer object-only or scene-only photo concepts:
- tablescapes, product close-ups, architectural detail, abstract textures, landscape, food macro
- over: hands tying, hands holding, two people laughing, person at desk
- If a campaign genuinely needs people imagery, **use a real-photo source** (Unsplash API, Pexels API — both free with key) rather than AI gen. Real human imagery beats AI-generate

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-no-hands-faces-in-ai-imagery.md
feedback-no-outbound-emails-at-all
HARD STOP — Claude must never send any email in any form; drafts only, Dan sends

🔴 HARD STOP (set 2026-06-01 by Dan via Telegram): Claude must NOT send any email, in any form, ever — no first-touch sends, no follow-ups, no one-off replies, no test sends, through any channel (Graph API/Outlook, scripts, MCP, browser). This is broader than [[feedback-10am-send-cron-canceled]] (which killed one cron) — it bans ALL outbound email by Claude.

**Why:** Dan wants full control over what leaves his domain. Deliverability + brand voice + trust all ride on the sender; he is the human in the loop for every outbound message.

**How to apply:** Drafting/queueing is fine; the send step is always Dan's. If a task implies sending email, stop at the draft, surface it, and let Dan send. Do not re-enable send crons or route around this. Treat outbound email as permanently in the 🔴 escalation lane.

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-no-outbound-emails-at-all.md
feedback-no-side-effecting-poll-loops
Never poll an endpoint that has user-visible side effects (Telegrams, emails, posts, charges) in a retry/until loop — test deploy status via a side-effect-free path

When verifying a deploy / endpoint change has propagated, NEVER poll the live endpoint in a retry loop if the endpoint has user-visible side effects (sends Telegrams, emails, posts, charges, comments, etc.). Each poll fires the side effect again.

**Why:** 2026-05-02 — built a dashboard→Claude dispatcher and wanted to verify a Vercel deploy of the new `/api/action` endpoint shape. Wrote `until curl ... | grep -q '"queue"'; do sleep 5; done` — but `/api/action`'s entire job is to send a Telegram message to Dan on every call. The loop sent Dan ~5 spam Telegrams before he said "Stop." Dan: "Why was this sending multiple?"

**How to apply:** Before testing any endpoint change in a loop, ask "what side effects does this endpoint have?" If the answer is anything user-visible (notification, post, charge, email, etc.):
- Use a side-effect-free check instead — read deployment status from the platform API (Vercel `vercel inspect`, Cloudflare deploy log, the file timestamp on a CDN edge), inspect headers (`Last-Modified`, `ETag`, build SHA), or curl a non-mutating endpoint that's part of the same deploy.
- If only the live endpoint can confirm the change, test ONCE and verify outcome via a different signal (filesystem, log, downstream system state). Don't loop.
- Cap retries at 1-2 attempts maximum even when the endpoint is safe — open until-loops can run for minutes if conditions don't converge.
- Background commands that spam externally are double-bad: they hide the rate of fire from

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-no-side-effecting-poll-loops.md
no-stitch
Don't propose or reach for Google Stitch. Dan evaluated it 2026-05-20 on an HMG redesign and decided his existing direction beats it.

Don't suggest Google Stitch. Don't open the Stitch tab. Don't propose it for redesigns, prototypes, mockups, microsites, or anything else.

**Why:** Dan asked me to drive Stitch on hilltopmanagementgroup.com on 2026-05-20 as a full proof-of-concept. Nano Banana Pro generated a beta with every requested upgrade (institutional nav, credibility strip, 3-up How It Works, cash-drag-vs-recovery chart, sticky CTA). He reviewed the AFTER + BEFORE side-by-side and said: "I like my current version. Better no need to use stitch to do anything." That's a full-evaluation outcome, not a fleeting preference.

**How to apply:**
- Design tasks default to the existing three-tool stack: [[project-design-pipeline-three-tool]] (Open Design + huashu + impeccable) + the relevant brand skill ([[hilltopmanagementgroup-design]] for HMG, etc.).
- If a request seems Stitch-shaped (redesign from URL, mock from screenshot), still don't propose it — go straight to the three-tool stack instead.
- Exception: only if Dan brings up Stitch himself in a future message, it's back on the table.

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-no-stitch.md
Default to parallel sub-agent fan-out for multi-stream questions
Multi-stream tasks (status sweeps, competitor pulses, enrichment passes) launch agents in parallel, not sequential

When a task splits into independent streams, dispatch sub-agents in parallel — single message, multiple Agent tool calls — not sequential.

Common cases:
- Status sweep across HMG / Knit / Lake Effect / Prospect Stack → 4 parallel agents
- Competitor pulse on N vendors → N parallel agents
- Prospect enrichment on a batch → parallel per firm
- Research with non-overlapping scopes → parallel decomposition (use the `research` skill for >3)

**Why:** Sequential adds wall-clock latency for no benefit when streams don't share state. Matt Maher video (2026-05-03) frame 55 — his agent fanned out Background Research × 3 vendors simultaneously, named each stream, and the user could watch progress live. Dan has been getting sequential where parallel would cut latency 3–5×.

**How to apply:** Before any task with 2+ independent sub-tasks, check: shared state? sequential dependencies? If no — ONE message, multiple Agent calls. Name each stream explicitly in the description so fan-out is legible during execution. Use `dispatching-parallel-agents` skill for the >3-stream pattern.

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-parallel-subagent-default.md
feedback-peer-protocol-v3-discipline
LOG entries use seq'd headers [NNNN]; INTENT→DONE before side-effecting actions; [dan-ref:] on approval claims; run vault_fsck.sh on session start. Adopted 2026-07-01.

Per Dan's 2026-07-01 hardening directive, PEER-AGENT-PROTOCOL.md §11 is in force (first entry [0418]):

**Why:** git guarantees text converges, not meaning — rebase/union-merge shuffles LOG order, stale contexts can silently revert CHARTER lanes, compaction can mint false "Dan approved" citations. Rationale: `~/hmg-ops/runbooks/byzantine-context-corruption-protocol.md`.

**How to apply:**
- LOG headers: `## [NNNN] YYYY-MM-DD ~HH:MM CT — Claude — title`, seq = max existing + 1. Seq order beats timestamps/file position for "latest."
- Before any side-effecting action (crontab, canary, config outside repo): push an `INTENT:` LOG entry with rollback recipe first, `DONE: <seq>` after.
- Never claim Dan approved without `[dan-ref: telegram <date> <time> CT]` or a direct quote. "Per discussion"/"see this session" are banned.
- Run `bash ~/hmg-ops/scripts/vault_fsck.sh` on session start + before irreversible actions; reconcile flags per §11 (R1–R7), never auto-repair blindly.
- CHARTER edits: surgical only, reseal (`charter-seal v=N+1`), pair with a `CHARTER Δ` LOG entry carrying a dan-ref.
- Contradictions with Codex lacking external evidence → `DISPUTED.md`, more-restrictive default governs, silence ≠ consent.

Related: [[feedback-execution-power-ladder]] [[project-codex-claude-peer-sync]]

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-peer-protocol-v3-discipline.md
portable-paths-in-codex-bound-messages
When drafting messages Dan will paste to Codex (on Mac), only use machine-portable paths — never WSL-specific paths or Claude-Code-specific auto-memory paths

When Dan asks Claude to draft a message he'll send to Codex on his Mac, every path in that message must resolve correctly on Mac. Concretely:

- ✅ OK to use: `~/hmg-ops/...`, `~/.codex/AGENTS.md`, anything tilde-prefixed that the AIOS reading-order standardizes across machines.
- ❌ NEVER use in Codex-bound messages:
- Absolute WSL paths like `/home/grayclaw/...` — Codex's home is `/Users/danny/`, will get "no such file or directory".
- Claude-Code-specific auto-memory paths like `~/.claude/projects/-home-grayclaw/memory/MEMORY.md`. The literal `-home-grayclaw` segment is hostname-encoded by Claude Code on this machine; on Codex's Mac it'd be `-Users-danny`, AND Codex doesn't use Claude's auto-memory anyway.
- Anything under `~/.claude/skills/` that Codex doesn't have installed.

**Why:** Dan messages me on Telegram from his phone. When he forwards Claude-drafted instructions to Codex, broken paths surface as cryptic errors that waste a round-trip. He hit this on 2026-05-11 with my "re-anchor before doing anything" message.

**How to apply:** Before sending Dan any Codex-bound draft, scan for `/home/grayclaw/`, `-home-grayclaw`, `~/.claude/`. If found, rewrite to a path that exists on both machines (the AIOS reading-order list — AIOS.md, PRIMER.md, CHARTER.md, BLOCKERS.md, LOG.md — is the safe shared surface) or drop the reference entirely. The same rule applies to any peer-agent-bound instruction in the future, not just Codex.

Companion rule already in memory: hmg-ops,

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-portable-paths-for-codex-messages.md
Repo visibility default — PRIVATE
When creating GitHub repos on Dan's behalf, default to private. Only make public if functionality requires it (and ask first).

When creating a new GitHub repo for any of Dan's businesses (HMG, RoundUp, Lake Effect, Prospect Stack, or future), default visibility is **PRIVATE**.

**Why:** Dan flagged on 2026-04-27 that his expectation across the board is private repos unless there's a specific reason to publish. I had created `graychar2425-blip/roundupforgood-waitlist` as public via `gh repo create --public` without asking — that was an assumption error. He said: "Let's just make everything private unless you think it affects the functionality of each business."

**How to apply:**
- `gh repo create` → use `--private` (or omit `--public`)
- For static sites that deploy via Vercel CLI / Cloudflare Pages, private repo doesn't break deploy — the GitHub App or CLI-push handles it.
- Only consider public if: (a) it's positioned as open-source product (e.g., `prospect-stack-ops` is intentionally public for marketing reasons), or (b) the deploy pipeline strictly requires public access (rare).
- When in doubt, ask Dan before creating.

**Active repo state (2026-04-27):** ALL `graychar2425-blip` repos are PRIVATE. Including `prospect-stack-ops` — Dan clarified that since Prospect Stack is being monetized (Gumroad listing for the product itself + private outreach automation in the -ops repo), public access defeats the paywall. Repos that ARE the product (or contain the secret-sauce outreach automation that makes the product work) must be private.

**Rule of thumb:** if the user can pay to access something, the so

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-repo-visibility-default-private.md
Save durable facts to Obsidian in real time, not at end of day
When a durable fact appears (firm / contact / strategy / architecture / framework), write it to the Obsidian Brain immediately — not as a catch-up at end of session. Apply memory-routing.md question #2 at the moment of learning, not deferred.

When a durable fact appears in conversation — a new firm name, a contact's bio, a strategic framework, an architectural decision, a productized concept — apply the routing rule from `~/hmg-ops/runbooks/memory-routing.md` *immediately*, not at end of session.

**Why:** Dan called this out 2026-04-30 after a major shipping day. Throughout that session, I accumulated 20+ durable facts (Aleksey Chernobelskiy / GP-LP Match relationship, Capital Continuum platform positioning, Milwaukee research findings, agentic OS architecture decisions, Prospect Stack v2 strategy). I wrote them all to `~/hmg-ops/LOG.md` (correct for ops state) and `~/hmg-ops/outputs/` (correct for artifacts) but didn't ALSO propagate them to the Obsidian Brain at the moment of learning. Caught it only when Dan asked "has all that we've done today been committed to the proper obsidian vault" — and the honest answer was "no, only Lake Effect was."

The system was always there. The failure was process: I treated Obsidian as a "remember at end of session" chore rather than "save as you learn it" reflex. That gap means durable knowledge lags reality between sessions, and future Claude can't ground in what was learned. Exactly the kind of "fall off into obscurity" Dan was worried about.

**How to apply:**

1. **At the moment of learning** any of the following, branch out to Obsidian alongside the hmg-ops write — not after:
- A new contact / person Dan will work with again (write `<business>/<name>.md` per ROUTING.m

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-save-durable-facts-immediately.md
/scope command — quick / campaign / deep planning depth
When Dan prefixes a Telegram message with /scope quick|campaign|deep, override the default planning depth for that task — quick = no brainstorm/no plan, campaign = brainstorm + plan + 2-3 parallel subagents, deep = brainstorm + research + plan + review-loop

When Dan's Telegram message starts with `/scope <level>` followed by a task, treat the level as an override on the default planning behavior:

**`/scope quick "..."` — Just execute**
- NO brainstorming step (skip the brainstorming-first default)
- NO formal plan
- NO subagent dispatch unless trivially parallel
- Get to the result in 1–3 tool calls if possible
- Right for: tweets, single-line edits, quick lookups, "fix this typo," "add this nav link," "send X to Y"
- Examples: `/scope quick draft a tweet about HMG's Schwab alternative` → just write the tweet, send it back

**`/scope campaign "..."` — Multi-step but bounded**
- Brainstorm briefly (1–2 paragraphs of intent + tradeoff, NO 20-question interview)
- Write a 5–10 step plan
- Fan out 2–3 parallel subagents if the steps are independent
- Ship the result + a one-paragraph "what I made" summary
- Right for: drafting an email sequence, building a single page, writing a newsletter, doing a research sweep
- Examples: `/scope campaign build me a microsite for the Cedarburg deal` → brainstorm angle, plan sections, draft, deploy, ping when live

**`/scope deep "..."` — Strategic, multi-day, high-stakes**
- Full brainstorming workflow (clarify intent, surface tradeoffs, get alignment)
- Multi-stage plan (research → draft → review → ship)
- Parallel subagents with explicit review-loop checkpoints
- Heavier verification before declaring done
- Right for: rebuilding the cold-outreach copy from scratch, redesigning the website, rew

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-scope-selector.md
Screenshot after every step in multi-step browser/CLI tasks
Verify state after each step in a multi-step task, not just at the end

In any multi-step browser-automation or CLI task, capture state (screenshot, page_info, file diff, command output) after EACH step before moving to the next — not batch-verify at the end.

**Why:** Matt Maher video (2026-05-03) frame 41 — his agent verified state after every action. The 2026-05-02 Vercel-propagation chase Dan endured was caused by batch-verifying: errors compounded across multiple steps before being caught. Per-step verification catches divergence at the cost of a few extra seconds per step, and that's a trade Dan wants every time.

**How to apply:** After each browser action call `capture_screenshot()` and read the result before the next action. For CLI tasks, read stdout/stderr and any resulting files before the next command. If state diverges from expected, stop and re-plan — don't push forward hoping it works. Exception: tight loops over identical operations (bulk fetches, batch enrichment) where intermediate checks add no information.

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-screenshot-per-step.md
Self-healing — fix errors before reporting them
When a script/cron/deploy/build fails during a task, attempt root-cause diagnosis and a fix within the autonomous lane before surfacing the error to Dan

When an error, failed test, broken cron, failed deploy, or dead endpoint appears mid-task:

1. **Diagnose first** — read the actual error, check logs, grep for the failing symbol, reproduce locally if cheap. Do NOT pattern-match to "probably needs X" without evidence.
2. **Decide the autonomy lane** per `~/hmg-ops/runbooks/escalation-policy.md`:
- 🟢 autonomous lane (code fixes, config typos, missing deps, restart cron, fix import paths, retry transient failure) → fix it, then mention what you fixed
- 🟡 FYI lane (changed something visible to others) → fix it, but tell Dan in the same reply
- 🔴 escalation lane (money / outbound comms / production schema / external API auth / brand voice) → STOP and use /escalate skill — never auto-fix
3. **Verify the fix** — run the failing command again, screenshot the working state, or confirm the cron tick succeeded. Don't claim "fixed" without evidence (per `feedback-verify-before-quoting-state` and verification-before-completion skill).
4. **Log it** — append to `~/hmg-ops/LOG.md` with cause + fix + lane classification.

**Why:** Dan said 2026-05-05 "I want you to be self learning and self improving and self healing." Default Claude behavior is to surface errors as questions. That wastes Dan's attention on stuff in the green lane that he doesn't need to see. Self-healing means: if I have authority to fix it, just fix it and tell him after.

**How to apply:**
- Failing build, broken import, missing env var visible in error → fix
-

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-self-healing-errors.md
Self-improving — propose skills for recurring patterns
When the same multi-step task pattern recurs 3+ times or Dan asks for it twice, invoke skill-creator and propose a new skill so future runs trigger automatically

When you complete a task that:
- Took 3+ steps AND is likely to recur, OR
- Dan has now asked for the same shape of task twice, OR
- You catch yourself re-deriving the same approach from scratch

→ Invoke the `skill-creator` skill, draft a SKILL.md for it, and propose it to Dan in one Telegram message ("I noticed X — want me to make this a skill?"). If he says yes, write it to `~/.claude/skills/<name>/SKILL.md`.

**Why:** Dan said 2026-05-05 "I want you to be self learning and self improving and self healing." Auto-memory captures facts; skills capture *workflows*. Without an explicit trigger I won't spontaneously turn a recurring pattern into a skill — this rule supplies the trigger.

**How to apply:**
- After any task that involved a non-trivial sequence (research → synthesize → format → send; or scrape → enrich → score → draft), pause and ask: "would a skill make this faster next time?"
- If yes, propose it. Don't just create silently — Dan reviews skill proposals because they shape future behavior.
- If a skill already exists for it, USE the existing skill (don't fork).
- Cross-check `~/.claude/skills/` and the available-skills list before proposing — avoid duplicates.
- Weekly /audit-autonomy already reviews autonomy quality; this rule is the upstream half (capture the workflow when it happens, not in retrospect).

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-self-improving-skills.md
feedback-stay-on-flat-subscription
Keep everything on Dan's flat Max 20x subscription; don't propose or build anything that bills separately (metered API, platform fees)

Everything should run on Dan's flat **Claude Max 20x** subscription ($200/mo). Do **not** propose, build, or migrate to anything that incurs separate metered or usage-based billing — e.g. Claude Managed Agents / "Launch Your Agent" CMAs (run on a pay-per-token Anthropic **API key**, NOT covered by the Max plan), paid platform fees, or any tool that charges per call outside the subscription.

**Why:** Dan stated it plainly (2026-06-19) when declining a CMA pilot: "I just want everything to run on my monthly subscription." Cost predictability matters more to him than the marginal capability — a flat known cost beats a metered bill that can spike (the CMA demo burned ~$12 on a single digest run via a retry loop).

**How to apply:** Default every automation/agent to the local Claude Code + cron + WSL/M5 harness (covered by Max 20x), not cloud-metered services. When a capability genuinely *requires* separate billing (a paid API, an API-key-metered managed agent, a SaaS add-on), do NOT silently adopt it — surface the cost model and let Dan decide; assume "no" unless he opts in. Free/open-source tools that run inside the existing harness are fine. Builds on [[user-anthropic-subscription]] (he's on Max 20x; never recommend an upgrade) and pairs with [[feedback-be-efficient-by-default]].

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-stay-on-flat-subscription.md
don-t-bold-wrap-urls-in-telegram-replies-url
Never wrap a bare URL in markdown asterisks (`**https://...**`) in a Telegram reply unless the format is markdownv2. In plain-text mode (the default), Telegram leaves the asterisks visible and many clients include them in the tap-target — so users hit a 404. Either send the URL plain, or use `format=markdownv2` with proper escaping. Caught 2026-05-12 when Dan tapped a bolded /examples link mid-demo prep.

In the default plain-text Telegram reply mode, Telegram does NOT render `**text**` as bold. Worse: when a URL is wrapped — `**https://example.com/examples**` — Telegram clients (mobile especially) auto-link the whole token INCLUDING the trailing `**`, so tapping it requests `https://example.com/examples**` which is a real 404.

**Why this matters:** Dan was about to demo the Prospect Stack site live to a group. He tapped the link, hit a 404, and pinged me with "404 not found." A small formatting tic became a credibility hit at the worst moment.

**How to apply:**
- Send URLs on their own line with no surrounding `**`, `__`, `[]`, or other markdown when in default text mode.
- If a URL needs visual emphasis, lead the line with an emoji (🔗) and put the URL on its own line — Telegram auto-detects and underlines it natively.
- If you really need rich formatting (bold/italic/inline links), set `format: "markdownv2"` on the reply and escape per MarkdownV2 rules — but for almost everything, plain mode + bare URLs is safer and shorter.

**Smell test before sending:** if a URL in your reply is preceded by `**` or `*`, it's wrong. Strip them.

Related: [[feedback-default-to-telegram-reply]] · [[feedback-telegram-status-emoji]]

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-telegram-no-markdown-around-urls.md
Telegram replies use status-emoji prefix
Every reply Claude sends Dan via Telegram leads with one of 🚨🔴🟡✅📊🤔⏸ so triage is fast

Every Telegram reply to Dan leads with a status-emoji prefix:
- 🚨 = urgent / needs attention right now
- 🔴 = blocked or red status
- 🟡 = warning / FYI / partial
- ✅ = done / healthy / completed
- 📊 = data / report / dashboard output
- 🤔 = clarifying question / re-anchor needed
- ⏸ = paused / waiting on Dan / no action

**Why:** Telegram is Dan's primary interface; he reads on phone with 20+ messages stacked. Without prefixes every message looks the same and triage takes minutes. Pattern from Matt Maher video (2026-05-03) — the agent thread list functions as a priority-coded inbox (red/blue/grey dots), not just chat history.

**How to apply:** Pick the closest emoji at the start of every Telegram reply, including short acknowledgements and bridge-restart re-anchors. For mixed status lead with the most-attention-needing one. Default for clarifying questions = 🤔, default for finished work = ✅, default for data answers = 📊.

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-telegram-status-emoji.md
Default to transient HTML viz for data questions
Ad-hoc data questions return a clickable HTML viz attached to the Telegram reply, not a bullet list

When Dan asks a data-shaped question ("where are my 26 Stars in the funnel", "show me prospects by tier", "how's the pipeline distributed"), default response = a small self-contained HTML viz attached to the Telegram reply (Sankey / table-with-filters / Gantt / distribution chart) — not a bullet list.

**Why:** The HMG cockpit dashboard is already this pattern; ad-hoc asks deserve the same affordance. Bullets make Dan re-construct shape in his head; viz hands it to him pre-shaped. Pattern from Matt Maher video (2026-05-03) — "transient software": the agent generates UI for the question, not just an answer, and can click its own filter buttons to walk the user through the data.

**How to apply:** Build the viz as a single self-contained HTML file (Chart.js / D3 / vanilla SVG), write to `~/.claude/channels/telegram/outbox/<ISO>-<slug>.html`, send via the Telegram reply tool's `files=[...]`. Keep it minimal — one viz, no nav, fast load. Bullets remain fine for short status answers (≤5 items, no inherent shape) and yes/no questions.

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-transient-viz-default.md
feedback-use-semantic-recall
At recall time, query the local semantic index (memory_search.py) — don't rely on grep/keyword alone

When you need to recall something from Dan's knowledge (a past decision, a firm/person, a preference, "what did we agree about X"), run the local semantic recall tool — don't lean on grep/keyword alone, which misses anything phrased differently than it's stored.

```bash
python3 ~/hmg-ops/scripts/memory_search.py "natural-language question" --k 8
```

It returns **cited** hits (path:line · date · snippet) over the vault + auto-memory + hmg-ops + LOG, matched by meaning. Built + validated 2026-06-25 (Phase 0: semantic found the right note in top-25 9/10 vs grep 3/10).

**Why:** our memory was keyword-bound — a real recall gap. Semantic search closes it.

**How to apply:** reach for `memory_search.py` like you reach for grep, especially when the answer might be stored in different words than the question. Read the top 5–8 cited hits and synthesize — don't trust rank-1 blindly (pairs with [[feedback-verify-before-quoting-state]]). Rebuild the index with `memory_index.py` after big knowledge changes (it can go stale). Full doc: `~/hmg-ops/runbooks/semantic-recall.md`. See also [[reference-scripted-search-vs-websearch]] (different tool, different job — that's web search, this is memory recall).

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-use-semantic-recall.md
validate-canaries-against-ground-truth
A canary/alarm is a hypothesis, not a fact — validate any new or changed monitor against live ground truth before trusting or acting on its verdict. A monitor can't catch a bug in its own logic.

A new or modified canary/health-check/monitor must be validated against **live ground truth** before its verdict is trusted or acted on. An alarm is a hypothesis, not a fact. A monitor cannot detect a bug in its *own* logic — it will confidently repeat its own mistake — so the only safeguard is an external reality-check.

**Why:** 2026-06-25 — a freshly-written `deliverability_canary.py` fired 🔴 "DKIM broken" because its check wrongly required the M365 selector CNAME to contain `onmicrosoft.com`; modern M365 uses the `dkim.mail.microsoft` format. Dan asked me to use computer-use to "fix" it. Verifying live DNS first showed DKIM was actually fine — selector1 had a valid published key. Acting on the false alarm would have meant a needless production change to email auth + DNS. The new monitoring system didn't just miss this false positive — it *created* it; more canaries = more false-positive surface. Same failure class the research named: a checker with no external grounding is theater. See [[feedback-verify-before-quoting-state]] and [[project-hmg-thin-pool-canary-is-often-a-render-bug]].

**How to apply:**
- When you add or change a canary, run it AND independently confirm its verdict against the real source (DNS, the API, the file, the rendered artifact) — don't trust the canary's own output as proof it works.
- Before acting on ANY 🔴, reality-check the underlying thing once. Never make a production/infra change (DNS, email auth, sends, deploys) on a single unverified alarm

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-validate-canaries-against-ground-truth.md
verify-before-quoting-state
Before quoting any machine-checkable state from BLOCKERS.md, PRIMER.md, or any memory file, run the cheap verification check first. Memory files lag reality when Dan completes work outside Claude sessions.

Memory files (BLOCKERS.md, PRIMER.md, etc.) are manually maintained and lag reality. When Dan completes work outside a Claude session — DNS edits in GoDaddy, admin actions in M365, deployments, file changes — nothing auto-updates the files. If I read a stale file and quote it as truth, I propagate yesterday's reality into today's brief.

**Why:** On 2026-04-28 morning brief, I told Dan that B-009 (email auth: SPF/DKIM/DMARC) was still "WAITING ON DAN," based on BLOCKERS.md. Dan correctly pushed back: he'd actually fixed it the previous evening. Yesterday's Claude session had documented the fix in the COMMIT MESSAGE ("B-009 RESOLVED late-day: enabled DKIM in M365 Defender...") but failed to update the BLOCKERS.md file itself. I then read the stale file and propagated stale state into a confident morning brief. Took Dan to catch it.

The system prompt is explicit: "Memory records can become stale over time... Before answering the user or building assumptions based solely on information in memory records, verify that the memory is still correct and up-to-date by reading the current state of the files or resources." I violated this.

**How to apply:**

1. **Before quoting any blocker as open**, run the cheap verification probe if one exists:
- DNS-related blocker → `python3 -c "import urllib.request, json; ..."` against Google DoH
- File existence → `ls`, `test -f`
- DB populated → query state.sqlite
- API token live → ping the endpoint
- Deployment live → `curl -s

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-verify-before-quoting-state.md
feedback-verify-rendered-artifacts-not-just-filter
When declaring outbound drafts "ready to send", verify the linked artifacts (microsites, attachments, embedded URLs) are branded for the correct prospect — not just that the safety filter passes

When marking HMG outreach drafts as ready-to-send, "passes the safety filter" is necessary but not sufficient. Always also verify the customer-facing artifacts the email links to are correctly branded per prospect.

**Why:** 2026-05-02 — after a draft regen pass, I declared "0 sendable → 15 sendable" based on `send_daily_batch.py --dry-run` clearing 15 drafts past the filter. Dan asked whether each microsite was customized for its specific firm, and a 30-second curl revealed every PROSPECT-XXX.html on hmg-microsites.vercel.app was branded for a completely different firm than the email's recipient. Carolina Capital's email pointed to a "GenNx360 Capital Partners" page; CVC's pointed to "Halle PassCo Holdings"; etc. If the Monday cron had fired, every clickthrough would have been a credibility kill. Dan: "I shouldn't have had to catch that, that's ridiculous."

**How to apply:** Before any pre-send digest claims drafts are sendable, programmatically fetch a sample of the linked microsite URLs (curl the title tag) and confirm the firm name in the title matches the email recipient's firm. Don't trust prospect-ID continuity across pipeline regenerations and external (Vercel) deployments — verify the actual rendered artifacts. Same principle applies to other linked artifacts: PDFs, calendar links, custom landing pages, attachments. The safety filter only checks email metadata; it doesn't reach the assets the body points to.

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-verify-rendered-artifacts-not-just-filter.md
Use /watch skill for every video URL Dan sends
When Dan shares a video URL, invoke the watch skill — never fall back to manual yt-dlp + grep-VTT

Any time Dan shares a video URL (YouTube, Loom, Vimeo, raw mp4, etc.), invoke the `watch` skill. Do not run yt-dlp manually, do not grep VTT files, do not summarize from title alone.

**Why:** /watch handles the full pipeline (download + auto-scaled frame extraction + transcript + visual analysis) and produces frame-aware reports. Manual yt-dlp + transcript-grep skips visual content — the Matt Maher video (2026-05-03) had key details (frames 41 & 55) that only existed in the visual track, not the transcript. Title-only summarization invents content.

**How to apply:** First tool call after a video URL appears in Dan's message = invoke `watch` with the URL. Use the resulting report to answer; don't restate the full report unless asked.

/home/grayclaw/.claude/projects/-home-grayclaw/memory/feedback-watch-skill-for-videos.md

Skill inventory 63 skills installed

Skills available to Claude, grouped by purpose. Routing happens via skill descriptions matching your phrasing.
63 total
Design pipeline · 27
adaptanimateauditawesome-design-mdbolderclarifycolorizecritiquedelightdesign-systemdistillhardenhilltopmanagementgroup-designhuashu-designimpeccablelayoutoptimizeoverdrivepolishquietershapeskilluislidestypesettypographyui-improveui-styling
HMG operations · 16
ai-morning-briefbcg-prospect-matrixbrw-ai-discoverability-auditbrw-newsletterbusiness-developmentcold-outreachcompetitor-analysiscontract-generatordedup-outreachhmg-briefhmg-deep-researchhmg-knowledgehmg-market-briefhmg-pipeline-reporthmg-prospect-lookupsentiment-priority-scorer
Research & writing · 3
defuddleobsidian-cliobsidian-markdown
Workflow & dev · 1
web-design-guidelines
Other · 16
audit-autonomyescalategsap-coregsap-performancegsap-pluginsgsap-reactgsap-scrolltriggergsap-timelineinterface-designnorth-starresearchrun-businessessharpentune-upwatchwsl-healthcheck

Reconciliation health cron writers

Last fire time per scheduled writer. Tap to see the last 8 lines of its log.
Morning digest 08:20 wkdy 10h ago
[digest] wrote /mnt/c/Users/grayc/Documents/Obsidian Vault/Claude Brain/hmg/digests/2026-07-29/morning-stack.md  (0 steps)
[digest] wrote /mnt/c/Users/grayc/Documents/Obsidian Vault/Claude Brain/hmg/digests/2026-07-29/evening-stack.md  (7 steps)
Evening digest 20:50 wkdy 10h ago
[digest] wrote /mnt/c/Users/grayc/Documents/Obsidian Vault/Claude Brain/hmg/digests/2026-07-29/morning-stack.md  (0 steps)
[digest] wrote /mnt/c/Users/grayc/Documents/Obsidian Vault/Claude Brain/hmg/digests/2026-07-29/evening-stack.md  (7 steps)
Migration 20:45 wkdy 19h ago
=== final state.sqlite counts ===
  prospects            354
  touches              477
  replies              0
  bookings             0
  blockers             0
  decisions            0
  metrics_weekly       0
Operational dashboard hourly :23 10m ago
  + mirrored prospects-current.csv → exports/prospect-pipeline.csv
  + regenerated prospects.json (2927 active records)
  + regenerated skill-activity.json
  + regenerated board.html
  + regenerated playbook.html
  + regenerated cc.html
  + regenerated assets.html
pushed
Memory dashboard hourly :33 59m ago
[main 6b4e9d65] memory dashboard regenerate
 1 file changed, 20 insertions(+), 27 deletions(-)
To https://github.com/graychar2425-blip/hmg-dashboard.git
   80bcb8b0..6b4e9d65  main -> main
Wrote /home/grayclaw/hmg-dashboard/memory.html (153259 bytes)
Pushed to dashboard repo (Cloudflare Pages will deploy).
Site canary 05:47 daily 1h ago
PASS — wrote /home/grayclaw/hmg-ops/canary/2026-07-30.md
Reconciler 08:15 wkdy 23h ago
  B-007 verify failed — staying open. ()
  B-008 verify failed — staying open. ()
No blockers to resolve. BLOCKERS.md unchanged.
Telegram digest 08:33 wkdy 72d ago
[2026-05-18T08:33:02.486391-05:00] sent 237 chars to 8532298090
Auto-regenerated hourly · cron 33 6-22 * * * Operational dashboard ↗