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.
| Layer | Reads | Writes | Must not own |
|---|---|---|---|
| Codex | live repositories, local config, PDFs, current workspace state | patches, verified reports, draft content | unattended recurring jobs |
| Hermes | cron registry, job prompts, Hermes workspace, bounded toolsets | scheduled reports, maintenance output, job status | risky repository edits while I am asleep |
| Obsidian | AGENTS.md, route map, Home, Now, Board, daily notes, project notes | human-readable plans, source records, logs, reviews | hidden agent state |
| CC Switch | skill registry, provider settings, client runtime state | shared tool visibility and provider routing | project 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 class | Example jobs | What they maintain |
|---|---|---|
| Agent operations | daily-evolution, weekly-review, daily-git-commit | Hermes workspace hygiene, learned operating rules, versioned local state |
| Vault state | obsidian-morning, obsidian-nightly, obsidian-weekly, obsidian-health | daily note, Board, route-map health, project/course/research surfaces |
| Information feeds | daily-ai-news, arxiv-daily-digest | deduped briefings and research intake |
| Desktop/runtime hygiene | desktop-screenshot-cleanup, hermes-auto-update-and-health-check | screenshot 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:
| Area | Role |
|---|---|
| Root files | Home.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.
Discussion