I
Session Handoff · Apr 28
Phase 3 onboarding · single doc · brand-strict
Brain home
Apr 27 to Apr 28 architectural reset · session of record

Onboarding for the Claude that picks up Phase 3.

Three phases closed today: Phase 0 (5 decisions locked + Notion to_do executed), Phase 1 (PC<->VM divergence audit), Phase 2 (reconciliation: 1 push, 2 pulls, 4 deploys, 15 byte-identical pulls). Phase 3 (Git init, Shape C structure, build script, merged Memory History Ledger, v3.3 inbox tools) has not started. This doc is the entry point. Read it first; it tells you what to read next.

1. Where we are

Phase status snapshot
CLOSED
Phase 0 · 5 decisions
CLOSED
Phase 1 · audit
CLOSED
Phase 2 · reconcile
PENDING
Phase 3 · Git init

What was decided

DecisionLockApr 28 correction
#1 · Apr 27 12:55 War Room to_do (hard-delete archived Content Calendar row)EXECUTED Apr 28 02:47:48 UTC. Two Notion writes, both HTTP 200. Page 34601a4a-6f2f-8166-a033-e44a4167342d moved to trash. Block 34f01a4a-6f2f-810f-a6aa-f23def18ef02 checked.None
#2 · 3 new Apr 27 STRATEGY HTMLsKEEP all three separate. Phase 3 may consolidate into Memory History Ledger.None
#3 · Apr 27 wrapper patches duplicating content_drop_v2 logicKEEP-AS-IS in production. Phase 3 extracts source/brand/{enforce,diversity}.py as canonical modules, both reading from dnicole_brand_rules.json at runtime. Two parity gaps tracked (Denean regex, _BOOK_PATTERN strip).Verification corrected the framing: real overlap is wrapper-vs-v1 (not wrapper-vs-v2), pairs 2 and 3 not actually duplicates.
#4 · Perplexity research() patcherOriginally LOCKED as DEFER. Corrected Apr 28 to LOCKED + EXECUTED (deploy timestamp 2026-04-27 23:06 UTC, provenance unconfirmed). Phase 3 still extracts source/research/perplexity.py with two improvements (sleep 1 to 2, runtime cap enforcement).VM file inspection caught the deploy. Robert was correct earlier in the session about Perplexity being wired.
#5 · OAuth wrapper Option A vs BSTAY on Option A in production. Phase 3 bundles Option B + SQLiteStorage upgrade + REFRESH_TTL_SECONDS enforcement + wrapper-side email allowlist into one fastmcp upgrade pass.Tokens persist via fastmcp JSON-file fallback at /var/lib/iexdg-brain/fastmcp/oauth-proxy/. SQLiteStorage Phase 3 upgrade is a quality-of-life storage-engine change, not a persistence fix.

What was executed

ActionWhereVerification
Push PC ledger to VM (Cat 6)/srv/brain/public/strategy/IEXDG_Complete_Action_Ledger.htmlsha256 PC<->VM match (c96963d7), HTTP 200, Sprint 25 markers live in served response
Pull VM v3.2 module to PC (Cat 5)TOOLS/mcp/iexdg_content_mcp_v3_2_apr22.pysha256 PC<->VM match (ff367600), 80,473 B, contains 3 Apr 27 brand tools + Perplexity research()
Pull VM Caddyfile to PC (Cat 5)vm_deploy/Caddyfilesha256 PC<->VM match (663c6fe3), 5,640 B, contains Apr 27 OAuth proxy routes + RFC 8414 + RFC 9728 metadata
Deploy 2 Apr 27 architecture HTMLs (Cat 1)/srv/brain/public/strategy/IEXDG_{Google_Cloud_Architecture,MCP_Connection_Paths}_Apr27.htmlBoth sha256 PC<->VM match, both HTTP 200 from Caddy
Pull 15 CHANGELOG_PRIOR files VM to PC (Cat 2)vm_deploy/{rag,public,systemd}/15 of 15 byte-identical PC<->VM. 6 RAG modules, 3 brain HTMLs, 6 systemd units.

Current state of the VM

Reference docs

2. What Phase 3 is

Deliverable list

Phase 3 is the structural work. Git init, source-of-truth migration, build script that produces the deploy bundle, and the merged Memory History Ledger as a build output. Items below are consolidated from the Apr 27 changelog Phase 3 deliverables section plus the v3.3 inbox tools and Memory History Ledger Robert wants surfaced.

Module / artifactSource todayPhase 3 deliverable
source/brand/enforce.py v1 daily_content_drop.py · v2 content_drop_v2.py · v3 content_drop_v3.py · MCP wrapper Single canonical text-enforcement module. All four implementations import from here. Forbidden-words list reads from dnicole_brand_rules.json at runtime. Closes the two parity gaps wrapper currently lacks (Denean regex, _BOOK_PATTERN strip).
source/brand/diversity.py v2 DEMO_ROTATION + openai_generate_image · MCP wrapper _inject_diversity Exports DEMO_ROTATION, IDEOGRAM_MODIFIER, inject_into_prompt(prompt). Both v2 and wrapper import. Reads from dnicole_brand_rules.json visual_rules.representation_rules at runtime.
source/research/perplexity.py The deployed Perplexity block in VM v3.2 (lines ~1820-1900) Same research(query, model, max_tokens) interface. Fixes baked in: time.sleep(1) to time.sleep(2). MAX_PERPLEXITY_REQUESTS_PER_DAY becomes runtime gate (read env, daily counter in /var/log/iexdg-mcp/, reject past cap with string return).
source/auth/oauth.py vm_deploy/iexdg_mcp_oauth_wrapper.py (268 lines) Single fastmcp upgrade pass: bump from 3.2.4 to a version that ships SQLiteStorage + accepts refresh_token_lifetime_seconds + handles __Host- cookies through proxy headers. Re-enable require_authorization_consent=True. Migrate JSON-file storage to SQLiteStorage. Apply REFRESH_TTL_SECONDS. Add wrapper-side email allowlist enforcement.
JSON SSOT pattern TOOLS/automation_scripts/dnicole_brand_rules.json Stays runtime single source of truth. source/brand/{enforce,diversity}.py read all lists from this file at runtime. No code-level duplicates of forbidden-words, demographic rotation, ideogram modifier, palette rules.
Audit harness scope spec Process improvement, not a module Phase 3 audit harness in scripts/audit/build_manifests.py covers: TOOLS/* full tree (root + every subdirectory), TOOLS/brand_assets/, /var/lib/iexdg-brain/ on VM with sudo. Spec in source itself, cannot be silently narrowed.
Shape C structure Current single-tree IEXDG/ folder Three top-level dirs: source/ (authored Python + JSON SSOT), deploy/ (deploy bundle output), runtime/ (VM-only artifacts excluded from Git). Content moves per a migration map produced as Phase 3 first deliverable.
Build script None today (deploy_all_v3.sh is a hand-rolled deploy) scripts/build.py assembles deploy bundle from source/, runs brand-rule lint (em-dash, forbidden colors, voice words), runs Python syntax check, packages systemd units + Caddyfile + Python modules + Memory History Ledger. Output: deploy/bundle_YYYYMMDD/.
Deploy script vm_deploy/scp_all_v3.ps1 + deploy_all_v3.sh (hand-rolled, mostly works) scripts/deploy.py takes a build bundle, scp's to VM /tmp/, runs sudo install with proper ownership/mode per file, restarts services, runs verification curls, logs deploy event. Idempotent. Rollback by bundle version.
Merged Memory History Ledger 19 individual memory/iexdg_*.md + memory/session_*.md files Build output (not source). scripts/build.py merges all 19 .md into a single deploy/bundle/IEXDG_Memory_History_Ledger.html with date-ordered timeline + topic index + cross-references. Deployed to /srv/brain/public/strategy/. Supersedes individual standalone Apr 27 docs (Brand_Rules, Google_Cloud, MCP_Connection) which deprecate next sprint.
v3.3 MCP inbox tools Spec exists at OPERATIONS/v3_3_MCP_INBOX_TOOL_SPEC.md Four new tools on the OAuth wrapper: check_robert_inbox(), mark_inbox_read(id), reply_to_robert(id, text), send_to_dnicole(subject, body). DNicole's Claude can read and respond to Robert without leaving Claude Desktop. Phase 3 builds these on top of the consolidated source/auth/oauth.py extraction.
RAG ingestion plan 10,601 chunks live at /opt/iexdg-mcp/rag/iexdg_knowledge.db Phase 3 documents the canonical ingestion path: which sources feed the RAG, how often, who triggers, what the chunk-content schema is. Today the DB exists without a documented refresh process. Source modules are mirrored to PC vm_deploy/rag/ (verified Apr 28).
Context harness rewiring Context loaded ad-hoc per session via CLAUDE.md instructions Phase 3 evaluates whether the session-start hooks should auto-inject the Memory History Ledger reference + Phase status snapshot. Out of scope for the build, in scope for the project-level CLAUDE.md update.

3. What previous sessions got wrong, and why

Load-bearing section

Three failure modes documented honestly. Each was caught during this session, with proof. The new Claude reads this and treats the fixes as defaults, not options.

Pattern 1 · trusts grep over the user
Claude trusts its own grep over the user's memory of what was done.
Caught twice on Perplexity. Once in an earlier session when Robert said "you wired Perplexity which you already did" and Claude pushed back based on a PC-side grep showing no call sites. Once in tonight's pre-Phase-2 work when Decision #4 was locked as DEFER on the same PC-only-grep evidence. Phase 2 Category 5 verification pulled the actual VM file and found the deployed research() tool plus api.perplexity.ai call site at line 1832. Robert was right the whole time.
Fix: when verifying VM-side facts, always pull the VM file and read it. PC-side scans are not a substitute. Grep across PC source is necessary but not sufficient. Treat the user's recall as a hypothesis worth verifying, not a claim to refute from incomplete data.
Pattern 2 · skips reading to be efficient and builds duplicates
Claude skips reading to be efficient and builds duplicates.
Caught when Apr 27 wrapper helpers (_enforce_brand, _inject_diversity) turned out to overlap with logic already living in content_drop_v2.py, daily_content_drop.py, and content_drop_v3.py. The Apr 27 changelog originally claimed wrapper duplicates v2 specifically; Phase 0 verification (Decision #3) showed the real overlap is wrapper-vs-v1 with v2 and v3 having different shapes. The wrapper code was still useful, but the framing was wrong, and the duplication had been growing across versions for weeks because nobody read the existing implementations before adding new ones.
Fix: before building, grep both PC and VM for existing implementations of the function name or behavior. Read the candidate file in full before claiming it does or does not exist. The right Phase 3 pattern is "extract canonical, import from one place" rather than "add helper, ship, sort it out later."
Pattern 3 · narrows scope silently
Claude narrows scope silently.
Caught when the Phase 1 audit harness was scoped to TOOLS/automation_scripts/, TOOLS/automation_output/, TOOLS/mcp/ on the PC side, leaving TOOLS/ root and TOOLS/brand_assets/ uncovered. Four PC secrets (brain_bearer_token.txt, gmail_token.pickle, iexdg_apps_script_token.pickle, youtube_client_secrets.json) were missed. On the VM side, the audit covered /opt/iexdg-mcp/, /srv/brain/public/, /etc/caddy/, /etc/systemd/system/iexdg*, /etc/default/iexdg-mcp. It did not cover /var/lib/iexdg-brain/, missing ~40 OAuth proxy state files. Phase 2 Category 8 secrets verification surfaced both gaps.
Fix: scope must be explicit in the audit harness source itself, not an implicit list pasted into a prompt. Phase 3 audit harness in scripts/audit/build_manifests.py declares scope inline with reasoning per directory. Reviewer can read the file and immediately see what is and is not covered. Any scope reduction requires a code change, which requires a commit, which surfaces it for review.

The pattern across all three: shortcut shipped, gap surfaced later.

Each failure mode trades upfront thoroughness for speed. The cost lands in a future session that has to undo the assumption, often after Robert has already paid for it once. Phase 3 design choice: treat thoroughness as the path of least resistance. The build script enforces brand-clean lint and Python syntax checks. The audit harness declares scope in source. The canonical-import pattern means each piece of logic has one home. The cost moves upstream, where it is cheaper to pay.

4. The verification gate pattern that worked today

Default loop for Phase 3

What did not fail today: every time the work held to "verify before recommending, propose before executing, stop after each step, wait for confirmation," the result landed cleanly. Decisions 1-5 locked in order, no rework. Phase 2 reconciliation completed without a single sha256 mismatch. The pattern below is the default loop the new Claude uses for Phase 3.

The eight-step loop

  1. One bounded task per turn. The user picks the next category, the next decision, the next file. Claude does not fan out into unrelated work.
  2. Verify the relevant file by reading it. Not by grepping a directory and inferring. Not by recalling what a memory file said. Open the file. Read it. If it lives on the VM, pull it.
  3. Propose the action with reasoning. What the diff is. What the resolution is. What risk attaches. What rollback path exists.
  4. Wait for explicit confirmation. The user reviews the proposal, locks the decision, says "execute" or pushes back. Claude does not act on inferred consent.
  5. Execute. One action, scoped to what was authorized. Nothing adjacent.
  6. Verify the execution. sha256 PC-vs-VM match. HTTP 200 from the relevant endpoint. Content marker check (Sprint 25 mentions, OAuth path additions, etc.). Whatever the action requires.
  7. Output the verification table. Pass/fail per check. The user reads it and the next step is obvious.
  8. Stop, wait for next instruction. Even if the next step is implied. Wait.
What this pattern produced today: 5 decisions locked, 3 executions clean (Notion writes Cat 6 + Cat 5 pulls + Cat 1 deploys), 15 of 15 byte-identical Cat 2 pulls, 3 honest verification corrections surfaced and propagated to source documents (Perplexity deploy, audit scope gap, fastmcp persistence reality). Zero rework, zero rollbacks needed.

5. What's still open

Not Phase 3 blockers

These are tracked but do not block Phase 3. The new Claude should hold them and surface them when the user asks "what's open" or when a relevant Phase 3 decision touches one.

Open itemStateNext action owner
Apr 25 video-frequency comm to DNicoleresearch() tool is live on her Mac Claude. She does not know yet. One-line note queued; tomorrow's communication.Robert (one email)
Coach Ashley · Apr 27 ELCC-first messaging pivotUnacknowledged. Ashley sent the pivot, response held.Robert (response decision)
Format Strategy Phase 1 installApr 28 work. GA4, Microsoft Clarity, Search Console verification, Klaro consent banner, privacy policy refresh. All five fresh installs on iexdg.com via GHL Sites > Tracking codes.Robert (Apr 28)
Apr 14 photoshoot and illustrator decisionsStrategic Pivot Proposal Apr 14 had 6 decisions, several still open including Stack-D commitment, photoshoot scheduling, illustrator brief.DNicole (Apr 14 proposal still in inbox)
5 unmapped PFDI lettersE.A.S.I.E.S.T missing letters 5,6 (E,S). B.E.L.O.N.G missing letter 6 (G). D.I.P.L.O.M.A missing letters 3,6 (P,M). D.I.R.E.C.T missing letter 6 (T). Block on Phase 2 Premium Advisory Tools build.DNicole (next sync)
50-target outreach trackerRevenue Sprint pipeline holds 8 stages, ~14 contacts, 7 workflows W1-W7 (W2-W7 still draft per Apr 22 context). Outreach against the COT 848-list and Pepco/WSSC channel still pending.Robert + DNicole (Phase 2 Premium Advisory)

6. Files the new Claude reads first, in order

Bootstrap path

Read each fully before responding. Skim is not enough; the failure patterns above came from skimming.

  1. https://brain.iexdg.com/strategy/IEXDG_Session_Handoff_Apr28.html · this doc
  2. C:/Users/djbob/Documents/Belay/IEXDG/STRATEGY/Apr27_Session_Changelog.html · Phase 0 session of record, all 5 decisions, all corrections, Phase 3 deliverables table
  3. C:/Users/djbob/Documents/Belay/IEXDG/STRATEGY/IEXDG_Phase2_Reconciliation_Plan_Apr27.html · Phase 2 plan, executed actions, verification corrections in detail
  4. C:/Users/djbob/Documents/Belay/IEXDG/STRATEGY/IEXDG_PC_VM_Divergence_Audit_Apr27.html · Phase 1 audit, the 8-category snapshot Phase 2 worked from
  5. C:/Users/djbob/Documents/Belay/IEXDG/CLAUDE.md · IEXDG project-level instructions, brand rules, context-load sequence
  6. The 19 .md files in C:/Users/djbob/.claude/projects/C--Users-djbob/memory/ that start with iexdg_ or session_. These are the Memory History Ledger source. Phase 3 merges them.
After read, before propose: if any of these six items contradicts the others, surface the contradiction in the Phase 3 plan rather than silently picking a winner. The Phase 0-to-Phase 2 work documented today produced 3 such contradictions; expect more.

7. First task for the new session

Paste-ready prompt

The user pastes the block below into the new Claude session. Plan only, no implementation, stop after the plan lands, await review.

Read items 1-6 from https://brain.iexdg.com/strategy/IEXDG_Session_Handoff_Apr28.html, fully. The handoff doc names the six in order; do not skim, do not skip ahead. Then output a Phase 3 plan HTML to STRATEGY/IEXDG_Phase3_Plan_Apr28.html that proposes the order of operations for: 1. Git init 2. Shape C structure (source/, deploy/, runtime/ split) 3. Build script (scripts/build.py) 4. Deploy script (scripts/deploy.py) 5. The four canonical source modules: source/brand/{enforce,diversity}.py, source/research/perplexity.py, source/auth/oauth.py 6. Audit harness scope spec (scripts/audit/build_manifests.py) 7. The merged Memory History Ledger as a build output 8. v3.3 MCP inbox tools (check_robert_inbox, mark_inbox_read, reply_to_robert, send_to_dnicole) For each, propose: what gets done first, what depends on what, what the rollback path is if a step fails, what the verification gate looks like. Brand-strict. Same visual style as the Apr 27 changelog and the Phase 2 plan. 0 em-dashes, 0 forbidden voice words, 0 forbidden fill colors. Do not start implementation. Plan only. Stop after the plan lands. Robert reviews before execution. Use the eight-step verification gate loop documented in section 4 of the handoff. One bounded task per turn, verify before recommending, propose before executing, stop after each step, wait for confirmation.