I have become suspicious of the phrase “one AI workspace”.

It sounds clean: one chat box, one context surface, one task list, one file surface, one system that knows everything. The failure mode is also clean. State starts to live in too many places. A model carries one version, a local config says another, a scheduler keeps running an old job, and my notes contain the plan I actually meant.

So I now treat my personal AI setup less like a product and more like a small distributed system. The main question is not “which model is smartest?” It is “which component owns this state, and what is allowed to write it?”

The current answer is simple enough to audit:

  • Codex owns interactive engineering transactions.
  • Hermes owns recurring background execution.
  • Obsidian owns the human-readable plan.
  • CC Switch owns shared tooling and provider plumbing.

The ownership contract

I keep the system sane by treating each layer as having a narrow interface.

LayerReadsWritesMust not own
Codexlive repositories, local config, PDFs, current workspace statepatches, verified reports, draft contentunattended recurring jobs
Hermescron registry, job prompts, Hermes workspace, bounded toolsetsscheduled reports, maintenance output, job statusrisky repository edits while I am asleep
ObsidianAGENTS.md, route map, Home, Now, Board, daily notes, project noteshuman-readable plans, source records, logs, reviewshidden agent state
CC Switchskill registry, provider settings, client runtime stateshared tool visibility and provider routingproject meaning or personal planning

This table is more important than the tools themselves. If a job is failing, I want to know whether the failure is in the interactive surface, the scheduler, the vault, or the plumbing. Without that split, every bug becomes “the AI system is confused”, which is not a useful diagnosis.

Codex is a transaction boundary

Codex is where I run high-trust interactive work. A Codex task should usually follow one loop: read the current state, make a bounded edit, verify it, then report the exact changes.

That makes it a good fit for repository edits, config checks, document review, build failures, and anything that might damage real files if handled casually. I am present, so Codex can ask for judgment when the system boundary is unclear.

I deliberately do not treat Codex as the default scheduler. It can automate things, but a coding surface is not where I want long-running ownership to live. If a task should wake up every morning without me, it needs a different contract: fixed scope, fixed delivery behavior, observable last-run state, and conservative writes.

That is Hermes territory.

Hermes cron owns recurring state maintenance

Hermes has a cron registry with enabled jobs, schedules, prompts, skills, toolsets, last-run timestamps, next-run timestamps, and last status. That last part matters. A scheduled AI job without status is just a hope with a timer.

I group the current cron jobs by the kind of state they maintain:

State classExample jobsWhat they maintain
Agent operationsdaily-evolution, weekly-review, daily-git-commitHermes workspace hygiene, learned operating rules, versioned local state
Vault stateobsidian-morning, obsidian-nightly, obsidian-weekly, obsidian-healthdaily note, Board, route-map health, project/course/research surfaces
Information feedsdaily-ai-news, arxiv-daily-digestdeduped briefings and research intake
Desktop/runtime hygienedesktop-screenshot-cleanup, hermes-auto-update-and-health-checkscreenshot archiving, update checks, runtime health

The daily schedule is deliberately spread out: daily-evolution runs at 00

, daily-git-commit at 01
, the Hermes health check at 03
, AI news at 08
, the Obsidian morning pass at 08
, the ArXiv digest at 09
, the Obsidian nightly pass at 22
, and screenshot cleanup at 22
.

The slower jobs stay weekly: weekly-review runs Monday 00

, obsidian-weekly runs Friday 18
, and obsidian-health runs Sunday 21
.

The point is not that every time slot is sacred. The point is that ownership is explicit. If AI news repeats, I look at the news job and its dedupe context. If the vault gets stale, I look at the Obsidian jobs and their route-map reads. If runtime behavior drifts, I look at the client and provider plumbing rather than blaming the chat surface.

The state flow

Most recurring work follows the same path.

flowchart TD
  A["Cron tick"] --> B["Hermes job registry"]
  B --> C["Prompt + skill + toolset"]
  C --> D{"State class"}
  D --> E["Vault: route map -> daily note / Board / logs"]
  D --> G["Feeds: sources -> dedupe -> briefing"]
  D --> H["Runtime: update check -> health report"]
  E --> I["Bounded write surface"]
  G --> I
  H --> I
  I --> J["Short report or quiet no-op"]

The important detail is the bounded write surface. A vault job should start from the route map and approved top-level files, not wander through random folders. A screenshot cleanup job should archive obvious screenshots, not delete arbitrary desktop files. A briefing job should dedupe against recent outputs, not rediscover the same release note every day.

This is where cron becomes more than “run a prompt later”. It is a state reconciliation loop.

Obsidian is the visible second brain

Obsidian is the human-readable layer. The vault is where plans become inspectable: Now, Board, daily notes, reading queues, research maps, course notes, and project syntheses.

The design is not something I invented from scratch. It comes from Andrej Karpathy’s LLM Wiki pattern, which many people now describe as an AI-maintained Obsidian second brain: keep knowledge as plain Markdown, use Obsidian as the readable frontend, and let an LLM maintain the wiki structure instead of hiding everything inside a chat transcript. The useful part is not that AI can write notes. The useful part is that raw material, synthesized pages, indexes, and logs are all files I can inspect.

I did not keep the starter layout exactly. The common LLM Wiki shape is something like raw/, wiki/, index.md, log.md, and an agent instruction file. My vault has to support daily planning, coursework, research, paper reading, and automation logs, so it uses a human-first numbered layout:

AreaRole
Root filesHome.md, Now.md, Inbox.md, AGENTS.md, index.md, and a root log.md pointer
00 System/templates, route map, raw/source material, operation logs, assets, runtime residue
01 Daily/flat daily notes named by date
02 Work/active projects, coursework, Board, dev logs, reviews, presentations, people
03 Research/research maps, paper notes, reading queue, methodology notes, synthesis
04 Knowledge/reusable concept notes and study explainers
99 Archive/superseded plans, historical material, and legacy shells

The technical bridge is the route map. Agents do not get to hardcode paths like wiki/, raw/, Projects/, or root Logs/. They resolve logical routes such as daily, work, research, knowledge, raw, logs, board, and reading_queue through 00 System/obsidian-second-brain/routes.json.

That small file is what keeps the vault usable by both humans and agents. I can rename or reorganize a visible section without retraining every prompt. The cron jobs still know where to write the daily note, where to append an operation log, and where raw source material belongs.

The write path also has a control-plane read. Before a vault job changes anything, it should read AGENTS.md, index.md, Home.md, Now.md, and the route map. AGENTS.md is the operating manual, index.md is the catalog, Home.md and Now.md are the human state surfaces, and the route map turns logical destinations into paths.

There is also an exclusion contract. Hidden/runtime folders such as .codex/, .opencode/, .gemini/, .obsidian/, .venv/, .smart-env/, .omc/, and copilot/ are not part of ordinary vault health. They may exist inside the vault directory, but vault maintenance jobs should not treat them as knowledge.

The vault jobs also write operation logs. That matters because I do not want a silent agent to “organize” my work and leave no trace. If a nightly job updates a daily note or surfaces a project item, I should be able to see what happened later.

CC Switch keeps the clients aligned

CC Switch is plumbing: shared skills, provider routing, and runtime visibility across clients. It should not become a planning system or a source of project meaning. Its job is to reduce environment drift.

This layer becomes important when a failure looks like an agent problem but is actually a runtime mismatch. One client may see a skill while another does not. A provider may be configured differently across tools. A local PATH issue may look like a missing binary even though the usable command is still resolvable through another path. I want that kind of problem diagnosed as plumbing, not treated as a philosophical AI failure.

The routing rule I actually use

The routing rule is simple. File edits with verification go to Codex. Scheduled tasks with bounded writes go to Hermes cron. Plans and durable conventions I need to read tomorrow go to Obsidian and project-level instructions. Problems with skills, providers, or client visibility start with CC Switch.

The manual-first habit is important. I do not want every useful action to become a cron job immediately. I would rather run something through Codex once, see the exact inputs and failure modes, then promote it to Hermes only when the write boundary is boring enough.

Failure modes I design around

The system is still messy. The difference is that the mess is easier to localize.

Duplicate ownership is the first failure mode. If an old Codex automation and a Hermes cron job both believe they own the same briefing, I get repeated messages or conflicting summaries. So I treat Hermes cron as the active owner for recurring work, while old Codex automation records are audit history unless explicitly reactivated.

Stale instructions are the second. A project instruction, route map, or note can be wrong or outdated. For config, schedules, enabled tools, and current files, agents should inspect live state first.

Unbounded writes are the third. A prompt that says “clean up my vault” is too broad. A prompt that says “read the route map, update today’s daily note, append an operation log, and do not touch hidden/runtime folders” is much safer.

Cleanup jobs are another easy place to be reckless. My screenshot job moves old screenshots to an archive folder instead of deleting them. That is less elegant, but reversible.

The final failure mode is false confidence. A successful run is not the same as a correct run, so scheduled jobs need last status, visible outputs, and enough logging for a later audit.

Where this leaves me

This setup is not an attempt to build an all-knowing assistant. It is closer to an operating model for a few imperfect agents.

Codex gives me verified interactive changes. Hermes keeps recurring state from rotting. Obsidian remains the place where I can read the plan without asking an agent to reconstruct it. CC Switch keeps the shared runtime from drifting too far.

That split is less elegant than a single workspace. It is also the reason I can debug the system when it lies, repeats itself, or loses track of what matters.