Command Center

✅ 2 fixes shipped live · 4 decisions staged for you

Triggered by your Hermes-video learning: hard character caps on the files that load every session, as a forcing function for clean markdown. I benchmarked every agent against Hermes, found the real gap, fixed the two safe high-value items, and staged the structural calls below.

The one-line finding: your identity/doctrine layer is actually leaner than Hermes. The bloat — and the missing enforcement — was concentrated in Aria’s memory-index layer, the one agent that had only a weekly (ignorable) audit.

🚀 Shipped this session

Consolidated memory/MEMORY.md under cap

fd42743

29,652 → 18,108 chars (39% smaller). Enforced the file’s own one-line/~150-char rule, dropped resolved + stale entries, fixed "Linq owns day-to-day" framing (Linq absorbed 2026-05-15), added 4 missing pointers. Clears the 6-day-carried "prune MEMORY.md" item.

aria-secondbrain

Extended pre-flight check.mjs to cover Aria

982e3a50

The session-start hygiene check audited the 5 Aspire specialists but NEVER Aria — her files live in a different repo. Added checkAriaMemoryHygiene() so every session now caps-checks CLAUDE.md, IDENTITY/SOUL/LANES, NEXT.md, MEMORY.md. Additive, non-blocking, tested (40→41 checks, exit 0).

aspire-clients

🧭 Three enforcement models, one platform

Hermes (M3)

Strongest

Hard caps in runtime code. memory_tool.py: USER.md ≤1375 chars, MEMORY.md ≤2200. Hitting the cap forces consolidation before you can add. Cannot be ignored.

Aspire specialists

Middle

Role caps + session-start warning. agents/_shared/memory-hygiene.md defines role-based caps; check.mjs warns at every session start. Advisory (non-blocking) but consistently surfaced.

Aria (personal)

Weakest → now patched

Soft prose caps + WEEKLY audit. Caps lived only as prose in CLAUDE.md; the shell audit runs Sundays and only flags. A weekly flag is trivially ignorable — MEMORY.md sat over cap for 6 days. (Fixed today: now covered at session-start too.)

A flag can be ignored forever; a hard cap cannot. That’s the entire lesson from the Hermes video — and why Aria’s weekly flag let MEMORY.md sit over cap for six days.

📊 Every-session file heatmap

AgentFileCharsCapStatusNote
Aria CLAUDE.md 18,519 24 KB ok doctrine + Greeter — leaner than Hermes AGENTS.md
Aria IDENTITY+SOUL+LANES 8,331 ok identity layer, fine
Aria memory/NEXT.md 15,790 20 KB watch under cap, but "Last run" block is a 3.5 KB wall (rule = one line)
Aria memory/MEMORY.md 18,108 25 KB fixed was 29,652 (over cap) — consolidated today
Hermes USER.md ≤1,375 HARD enforced enforced in runtime code (memory_tool.py)
Hermes MEMORY.md ≤2,200 HARD enforced enforced in runtime code — cannot be ignored
Hermes SOUL.md 1,533 ok tiny identity + constraints
Circa MEMORY.md 19,464 20 KB (override) ok state-heavy override — GHL token/sub-account tables
Paris AGENTS.md 22,099 24 KB (override) ok workflow-manual override — inline per-prospect commands
Vegas mistakes.md 11,375 watch mistakes that are now mechanically prevented should be pruned

🗺 Where enforcement runs (and didn’t)

  SESSION START (every Claude Code session)
        │
        ▼
  ~/.claude/settings.json  SessionStart hook
        │   runs: aspire-clients/skills/pre-flight/check.mjs --all --session-start
        ▼
  checkMemoryHygiene() ──── walks aspire-digital/agents/<persona>
        │                   vegas · sahara · circa · strat · paris   ✅ covered
        │                   linq (retired)                            ⚠ stale
        │                   aria                                      ❌ WAS MISSING
        │
        └── checkAriaMemoryHygiene()  ◀── ADDED TODAY
                    walks aria-secondbrain: CLAUDE.md, IDENTITY/SOUL/
                    LANES, NEXT.md, MEMORY.md                         ✅ now covered

  WEEKLY (Sundays only)
        │
        ▼
  ops/aria-weekly-self-audit.sh ── flags Aria caps + drift + journal gaps
        (flag-only; was Aria’s ONLY coverage — easy to ignore)

🧹 Data-integrity findings

HIGH

memory/MEMORY.md over its own 25 KB cap · FIXED today

Flagged weekly, carried 6 days. Root cause: flag without forcing function.

HIGH

Aria’s files invisible to the session-start check · FIXED today

check.mjs walked only aspire-digital/agents/<persona>; Aria is a separate repo.

MED

check.mjs persona list still includes retired "linq", omits "aria" · STAGED

Audits a dead persona; daily-report writes to a linq/ path. Surgical rename needed.

MED

aspire-digital doctrine points at "skills/pre-flight/check.mjs" — wrong repo · STAGED

Script actually lives in aspire-clients. Relative path misleads any reader.

LOW

~/projects/shared-skills/ is empty but CLAUDE.md advertises it · STAGED

CLAUDE.md claims it holds "web crawling, document generation, screenshots." Points at nothing.

LOW

NEXT.md "Last run" block is a 3.5 KB narrative wall · STAGED

Discipline says one-line Last-run; detail belongs in memory/daily/. Trim queued for end of session.

🎙 Wispr Flow — what it changes

Cleaner input at the source

Wispr improves dictation quality → cleaner capture → fewer garbled action items → less downstream cleanup. Compounds with tighter back-end caps.

Proper nouns still drift

In this very session Wispr rendered "Vegas"→"Begus" and "Jaime"→"Jamie". The voice-artifact parsing rule stays load-bearing.

Highest-value action: custom dictionary

Add Aspire jargon to Wispr’s vocabulary: Vegas, Sahara, Circa, Strat, Paris, Aria, Hermes, Jaime, Aspire, Otten, Willowbrook, Synchrony, Tirzepatide.

Per-person asymmetry

Topher on Wispr, Jaime on Apple dictation. Capture-quality assumptions should not bake in one engine until both are aligned.

⚙️ M4 operating model — web → terminal

Web → M4 launch

Claude Code on the web picks the com.aria.remote.plist daemon on M4. Anthropic clamps these sessions to "Ask permissions" — bypass is impossible upstream.

The allow-list workaround

Pre-approving every tool in ~/.claude/settings.json makes "Ask" never actually ask. But it’s maintained reactively ("if Topher gets prompted, add it") against a huge MCP surface — it lags.

Known fragility

env-id rotates on every daemon restart (triggers must be repointed); cron-leaked sessions need a 10-min reaper; logs need daily truncation; Opus prompts where Sonnet does not.

Idea: drift-check the allow-list

A pre-flight check that compares installed MCP servers against the settings.json allow-list would catch coverage gaps before they prompt. The /fewer-permission-prompts skill already does a version of this.

⚡ Round 2 — forcing-functions shipped

The thesis in action: convert prose rules into enforced checks so integrity survives any session forgetting.

Link-integrity check (weekly audit)

Converts the "every /info page must be linked" rule into an enforced check. Caught 1 true orphan (the redesign tracker) — now linked. Hardened to true reachability after it false-flagged 14 reachable sub-pages.

MCP allow-list drift check

ops/allowlist-drift-check.mjs — found 11 configured MCP servers (10 GHL + Linear) NOT in the allow-list, so each prompts mid-session. Detect-only by design: blanket-allowing send-capable GHL servers would disarm the confirmation prompt on client-facing writes.

Auto-journal backfill (OPS-91)

ops/journal-gap-detect.mjs + morning-cron STEP 6b. The cron now writes a journal for any committed human-session day that lacks one — the auto-generation CLAUDE.md named as the goal.

🧱 Round 3 — Tier 2 & 3 (autonomous)

Model-routing doctrine

memory/tools/model-routing.md — Haiku=cron triage, Sonnet=build/Astro, Opus 4.8+effort=deep reasoning/autonomous. Codifies your per-job switching.

⚠ MCP-context bug found (OPS-92)

While building cost instrumentation: the 10 GHL MCP servers are registered GLOBALLY (~400 tool defs) and overflow Haiku's 200K context — Haiku+MCP = "Prompt is too long," the same root cause as the subagent failures. This corrected my own Haiku-for-crons advice. Fix: scope GHL MCP per-project. Staged.

Usage meter + reader (Tier 2b)

ops/usage-meter.sh + usage-report.mjs — opt-in token/duration metering (cost is ~$0 on subscription). Built + tested; NOT wired into crons (production change left for you).

Productization (Tier 3)

Forcing-function lesson added to the personal-ai-starter build-doc (committed, public deploy held); new "Context Governance" sellable module in the Aspire RAG methodology with this audit as the dogfood case study.

🫵 Decisions staged for you

1. Adopt the session-start cap-check as the forcing function (DONE — confirm you want it kept)

I already wired Aria into check.mjs so it warns every session. Keep it. If you want it to be a true hard gate (block until acknowledged), that’s a one-line settings.json change I left for you.

5. MCP allow-list policy — reads vs writes

11 servers prompt mid-session. I did NOT auto-fix: blanket-allowing GHL would auto-approve sending messages to client customers. Decide: allow read-only GHL/Linear tools, keep write/send gated. Then I add the safe ones to settings.json.

2. Unify enforcement — the "third agent" trigger has fired

memory-hygiene.md §6 says: when a 3rd agent independently hits the same hygiene problem, build one shared layer. You now have 7 agents across 3 enforcement models. Recommend one canonical hygiene-check serving Aria + specialists + Hermes.

3. Fix the doctrine drift

Rename check.mjs persona linq→aria; correct the aspire-digital doctrine’s path to the real aspire-clients location; either populate shared-skills/ or remove the claim from CLAUDE.md.

4. Wispr custom dictionary

You add the wordlist in the Wispr app (I can’t reach it). 5-minute task, kills the proper-noun artifact class.

Tracked in Linear OPS. Reply with a yes/no on each and I’ll execute the approved ones.