I did not start with a grand automation plan.
I wanted to play with Hermes and see whether it could help organize my life. The one experience I really hoped might work was a private morning podcast: something that could read my calendar, look at the work happening across my projects, catch important email, give me useful context for the day, and turn it into something I would actually listen to.
That part now works.
Every morning, a three-voice podcast arrives in Telegram. Cyrus acts as chief of staff. Isaac covers iBuildMVPs and revenue from my book (The Big O Book!). Tarah covers Teemzo (I used to try and sell software to help small engineering teams organize reviews – my plan is to use it to blog about engineering leadership related things). The show gives me an inbox overview, tells me what changed, and tries to reduce the day to the few things that genuinely need me. It is close to the experience I imagined when I started, and it is one of my favorite outputs from the whole experiment.
Getting there took twelve days of failures that rarely looked related from the outside:
- I spent $26.30 in a few hours and projected a roughly $1,000 monthly bill for a system that had not produced remotely that much value.
- A single morning-brief loop made 51 model calls and processed about 4.09 million prompt tokens.
- One scheduled job was blocked before making a model call because the primary subscription quota was exhausted and the fallback configuration was not real.
- Another job started successfully, chose the wrong calendar tool, wandered through tool discovery, stalled, and never produced the podcast.
- A local model ran but could not reliably use the tools the workflow depended on.
- One growth day used 3.9 million prompt tokens against only 53,000 completion tokens.
- A prospect spreadsheet reached 45 rows while containing only one named-person email address.
- Outreach drafts were technically complete and obviously AI-generated.
- An agent ran on schedule but I saw nothing because Telegram delivery was not actually working.
- Another output told me to write something that the agent was supposed to write for me.
None of those problems were solved by finding one magical model. The useful system emerged from model routing, deterministic tools, narrow roles, explicit handoffs, hard external-action boundaries, and a lot more operational visibility than I expected to need.
This is the comprehensive version of what I learned.
The hobbyist constraint changed every decision
This is a hobbyist system. I am not building a venture-backed agent platform with a cloud reliability budget and a team on call. I am trying to find out how useful a personal agent can become without creating another expensive monthly liability.
That constraint is important because it changes the architecture:
- Use the AI subscriptions I already pay for when the harness can consume their included allowance.
- Run the system on the MacBook I already own instead of buying an always-on server before the workflow has proven its value.
- Use cron, scripts, compact tools, and non-frontier or local models for work that does not need frontier reasoning.
- Save the most capable model for the few decisions where judgment, reputation, or commercial value justify it.
The MacBook approach creates sleep and clamshell problems. Subscriptions create quota windows. Local models are slower and less dependable with tools. Those are real tradeoffs, but they are visible tradeoffs. I would rather engineer around them than pay production-grade costs for an experiment that is still proving its usefulness.
The objective is not the cheapest possible token. It is the lowest predictable cost for a useful result.
A personal agent is not a chat
A chat usually looks like one request and one answer. An agent job can load instructions, read memory, inspect files, search the web, call tools, retry a failed provider, delegate part of the work, update state, create an artifact, and deliver the result somewhere else.
Every one of those steps can fail independently. Every model turn can resend the conversation accumulated so far. Every automatic fallback can change the bill. Every output can be present and still be useless.
I initially evaluated the system like a chat product: Was the answer good? I now evaluate it more like an engineering system:
- Did the scheduled event fire?
- Did the agent actually start?
- Which provider and model handled the work?
- Which tools did it use?
- Did it finish?
- Did the result reach me?
- Did it create the right artifact in the right place?
- Was the artifact accurate and useful?
- What external action, if any, still needs my approval?
“The cron job succeeded” answers only one part of that chain.
The first cost mistake was confusing access with billing
I started with OpenRouter because it offered one API and a broad model catalog. It felt like the easiest way to stop thinking about providers.
Within a few hours I had spent $26.30.
The OpenRouter dashboard makes the scale less abstract: 500 requests, 80.4 million tokens, a 94.5 percent cache hit rate, and a blended cost of $0.33 per million tokens in the displayed one-month window. Most of the spending landed in one large spike.
OpenRouter did what it was supposed to do. The mistake was mine: I had not made an explicit decision that unattended agent loops were allowed to buy metered inference. I treated a convenient model router like a fixed-price subscription. It is not. OpenRouter deducts the cost of each request from purchased credits, and different models charge different amounts.
I also assumed the consumer AI subscriptions I already paid for would naturally become included-use fallbacks. In my Hermes setup, several did not. A consumer chat subscription sitting in a browser is not useful to an agent unless the harness has a supported authentication path that consumes the included allowance. An API key is normally a separate metered product. An OAuth button is not proof that requests use the subscription allowance rather than extra usage credits.
I currently have a Claude subscription at $20 per month. That $20 Claude I have does not support the Hermes automation use case I wanted. Higher-tier and extra-usage rules can change, so the durable lesson is to test the actual authentication and billing path before counting any consumer subscription as agent capacity.
The practical rule is simple:
If the harness cannot authenticate against a plan as included usage, that plan is not part of the agent’s automatic budget.
Do not count subscriptions. Test routes.
The Agent-Subscription Pattern
I have started calling my resulting policy the Agent-Subscription Pattern:
Run automatic personal-agent work on a subscription-backed route with a cost you already chose. When its usage window is exhausted, rotate only to another explicitly approved subscription-backed route if one is supported. I happen to have multiple LLM subscriptions and this works very well with my workflow and budget. I much prefer a $20 ChatGPT subscription and a $50 Grok subscription compared to the $26 I spent using OpenRouter for a single day. Otherwise, use a tested local model or stop. Keep metered APIs out of automatic fallback unless you have deliberately approved that spend and capped the key.
The point is not that subscriptions are unlimited. They are not. They have caps, windows, policies, and sometimes inconsistent availability. The point is that the failure mode is visible and bounded. A quota error is preferable to a quiet invoice if I never authorized the overflow purchase.
A simple cross-provider version is ChatGPT subscription first, Grok subscription second, then a tested local route or stop. The brand names are replaceable. The important part is proving that the harness can consume each subscription’s included allowance before treating it as automatic fallback.
My live cost routes currently look like this:
- Automatic cloud work uses the subscription-backed
openai-codex/gpt-5.4route. - The local
gpt-oss:20b-hermesOllama model is the last automatic fallback, but only for work it has actually proven it can complete. - No metered API sits in the automatic fallback chain.
Sol consultant escalation shares the approved ChatGPT subscription lane, but it is selected by the separate Secretary, Employee, Consultant pattern (I define this pattern further down in the post). It is not a provider-failure fallback.
Metered services are still useful. They may be the right answer for a production service, a revenue-producing workflow, a short benchmark, or an explicitly approved high-value task. I just do not want an unattended retry policy silently turning them into my default.
If a setup guide tells a hobbyist to begin with OpenRouter, the missing question is not “which model should I pick?” It is “do I want this agent to stop at a known cap, or keep buying inference when the first route fails?” The price difference between those policies is material.
If I did use OpenRouter automatically again, I would create a separate key for the agent, set a hard dollar limit with a daily, weekly, or monthly reset, and monitor usage by that key. A general account balance is not a safety control.
The Secretary, Employee, Consultant pattern
The clearer model for the whole system is what I now call the Secretary, Employee, Consultant pattern.
This is separate from the Agent-Subscription Pattern. Agent-Subscription answers how automatic work is funded and what happens when a quota ends. Secretary, Employee, Consultant answers how much capability, judgment, and review a task receives. Either pattern can exist without the other. They work especially well together in a cost-constrained personal system.
These are not necessarily three bots. They are three levels of responsibility and reasoning inside one workflow.
| Layer | What it should do | Cheapest sensible implementation | Boundary |
|---|---|---|---|
| Secretary | Watch the clock, detect state changes, gather known inputs, maintain queues, and wake the right worker | The harness/router, deterministic preflight, and a lightweight OpenAI model for bounded triage | Does not make consequential judgments or represent me externally |
| Employee | Research, qualify, draft, update state, and move bounded work forward | A capable subscription-backed workhorse model | Treated like a junior employee whose work is reviewed |
| Consultant | Review or rethink high-value copy, positioning, strategy, architecture, security, or other consequential decisions | A frontier model such as Sol or the best current model for that task | Invoked deliberately for one bounded pass, not left running in every loop |
The secretary
The secretary is primarily the harness itself, not another elaborate agent personality. Hermes, its gateway, cron scheduler, and deterministic preflight logic know that something needs to happen. They check the clock, see that a queue changed, notice that a follow-up is due, gather the known source files, and wake the employee with a compact packet. In my live setup, this secretary-style routing and triage uses a lightweight OpenAI model that is separate from the models doing the agent work.
This layer should be as deterministic and inexpensive as possible. Sometimes it does not need a model at all. Hermes cron can run a preflight script and skip the agent when nothing changed. A small local or non-frontier model may be enough to classify a bounded state change or format a status update.
The secretary should not browse the open web for 20 turns, invent positioning, or write customer-facing copy. Its job is orchestration and triage.
In my live system today, the secretary layer is already running: the harness, router, scheduler, preflight logic, and lightweight routing model decide what needs attention. When real agent work is required, that layer wakes GPT-5.4 as the employee. The two model choices are not contradictory; they sit at different levels of the same workflow.
The employee
The employee is the normal agent. Cyrus, Isaac, and Tarah are employee-layer agents with different jobs. I treat this layer like a junior employee: capable of doing a lot of useful work, but limited, sometimes overconfident, and not authorized to represent me to customers without review.
The employee can research a company, qualify a prospect, prepare a draft, update a status file, compare options, and recommend the next move. It owns internal progress inside a defined lane. My live workhorse is the subscription-backed GPT-5.4 route.
The employee’s output is usually a draft, a recommendation, or an approval-ready artifact. It is not an autonomous send. Customer communication, publication, spending, deletion, and production changes still stop at a human gate.
The consultant
The consultant is for the work where getting a merely plausible answer is not good enough. Final outreach, important follow-ups, public content, copywriting, positioning, offer design, product strategy, architecture, and security decisions can affect revenue or reputation. Those deserve an extra set of eyes.
The consultant receives verified facts, constraints, the employee’s proposed answer, and one bounded question. It should challenge the reasoning, improve the work, and identify what would make the recommendation wrong. Then it exits.
Hermes delegation makes that escalation materially different from switching the employee’s entire session to a frontier model. The consultant child starts with a fresh conversation. It receives the focused goal and context Isaac supplies, but not automatically Isaac’s accumulated conversation, prior tool calls, profile memory, context files, or full skill packet. It inherits permitted tool access, and only its final summary comes back to Isaac. The consultant still has token cost, but it does not need to drag the employee’s entire working history through the expensive pass.
Isaac’s live consultant route uses GPT-5.6 Sol at xhigh effort. The strongest future model could serve the same role if tested and deliberately routed. The pattern matters more than the model name: do not spend frontier-model capacity checking an empty queue, and do not let the cheapest routine model make the decision that defines the company.
The workflow becomes:
Secretary notices and prepares context -> employee does the work -> consultant reviews when the stakes require it -> employee incorporates the review -> I approve any consequential external action.
Not every task reaches the consultant. That is the cost control. Every task starts at the cheapest layer capable of doing it and escalates when the value or risk of the decision justifies more reasoning.
The two patterns solve different problems and meet at the routing decision:
- The Secretary, Employee, Consultant pattern decides what level of work and review the task deserves.
- The Agent-Subscription Pattern decides which already-approved subscription, local route, stop condition, or explicitly capped metered route may pay for it.
Together, they let the existing MacBook, deterministic scripts, tested local models, and subscription allowances handle most work while reserving frontier reasoning for the moments where it creates enough value to justify the cost.
The loop costs more than the answer
One morning-brief run made 51 model calls and processed about 4.09 million prompt tokens. About 3.95 million of those were cached input, and Hermes recorded roughly $1.45 for the model run.
I am not upset about paying less than $2 for a genuinely useful daily podcast. I would make that trade. I was upset about spending $26.30 in an afternoon without knowing which work created the value or why the spend was accelerating.
The lesson was that the answer is not the expensive object. The loop is.
A more dramatic example came from Tarah’s early prospecting schedule. Ten growth jobs in one day consumed 3,908,315 prompt tokens and 53,452 completion tokens, a ratio of about 73 to 1. The prospecting job averaged about 895,000 prompt tokens per run and peaked above 1.1 million while adding one prospect.
My first guess was that the repo, skills, and standing instructions were too large. I measured them. All the files a run could load, plus the skill snapshot, were about 51,000 tokens. That was under six percent of an expensive prospecting run. Removing 32 unused bundled skills reduced the fixed prompt footprint by 8.5 percent, which was worth doing for clarity, but it was not the source of the bill.
The real cost was raw web content accumulating inside a multi-turn conversation. The agent would fetch a large page, reason about it, fetch another page, and then resend the growing context on every later turn.
Measured run duration and prompt usage looked like this:
| Runtime | Prompt tokens |
|---|---|
| 30 seconds | 74,000 |
| 122 seconds | 278,000 |
| 191 seconds | 677,000 |
| 232 seconds | 1,112,000 |
Runtime grew by 7.7 times while token use grew by about 15 times.
That reversed one of my early intuitions. Fewer, longer jobs were not cheaper. They amortized a relatively small startup cost while multiplying a much larger context-accumulation cost.
The easiest way to see the difference is to run the agent when there is no work to do. That gives you a no-op baseline. The difference between a working run and the no-op run is the accumulation cost. Optimize that before obsessing over a slightly cheaper model.
Deterministic tools beat model browsing for mechanical work
The prospecting output made the token problem concrete.
At one audit point, Tarah had gathered 45 prospect rows. Forty-two were LinkedIn URLs with no practical contact route. The file contained one named-person email. Every person and company could be real while the dataset remained nearly useless. A row was being counted as a lead when it was actually research inventory.
The fix was not another prompt. It was a small deterministic pipeline:
- Recover a likely company domain from the company name.
- Validate that the site identifies the company and that the domain can receive mail.
- Ask an email-resolution provider about the named person and domain.
- Return a compact structured record to the model.
- Let the model apply judgment to the result.
The first production backfill processed 31 rows without an email. It recovered 23 domains, skipped zero rows for lack of a resolvable domain, and produced 14 verified sendable addresses. Named-person emails in the dataset went from one to 16.
Hunter supplied the verified results in that run. Apollo was configured too, but its people-search and person-match endpoints returned 403 on my current free plan. The API key existed and organization enrichment worked, but the capability the workflow needed did not. “Credential present” is not the same as “usable plan.”
It also exposed a useful technical distinction: an MX record proves that a domain can receive mail. It does not prove that a particular mailbox exists. A guessed address on a valid Google Workspace domain is still a guess. I now separate published addresses, provider-verified addresses, risky inferred patterns, catch-all domains, and no-result records. Only the first two categories can advance to a draft.
The model remains valuable for qualification, relevance, and judgment. It is the wrong component for repeatedly pulling raw pages into context to do a mechanical lookup. The more of those steps I moved into bounded tools that returned compact JSON, the cheaper and more reliable the agent became.
This applies beyond prospecting. If a step can be expressed as parse, query, deduplicate, validate, compare, or transform, I now try to put it in code. The model should decide what matters, not spend a million tokens impersonating a scraper.
A local model is not automatically a useful fallback
I installed a 20-billion-parameter open-weight model through Ollama on a 32 GB M1 Pro. It can call functions. It passed a real Hermes terminal-tool smoke test. It also taught me that “the model runs” is an almost meaningless acceptance test.
First, Hermes rejected the model’s default 2,048-token context window. I needed a 65,536-context alias before it could serve as the configured fallback.
Second, a 20B model with a large context window creates real memory and swap pressure on a 32 GB machine. One local run exceeded the cron system’s 600-second idle budget. A fallback that pushes the machine into swap and times out is not a fallback. It is a slower failure.
Third, inference is not tools. During one failed briefing, the local model asked me for Google OAuth and a text-to-speech provider that were already configured in the harness. The model was available. The workflow was not.
The right test is task-specific:
- Can the model follow this skill?
- Can it select and call the exact tool?
- Can it stay inside the context and time budget?
- Can it produce the required artifact?
- Can the delivery layer send that artifact?
Until a local model passes the whole workflow, I treat it as a canary for narrow auxiliary tasks, not as a free replacement for the cloud agent.
Scheduled agents need less freedom than interactive agents
The morning podcast failed in several different ways, and they looked identical when I woke up: no audio file.
One basic failure was host availability. A cron job on a MacBook cannot run while the machine is asleep. I now keep the Mac awake through a LaunchAgent running caffeinate -i -m -s. The details matter: the -s assertion applies only while the Mac is on AC power, and a closed laptop still needs normal clamshell conditions.
Another 6:00 a.m. run did start. The logs showed 13 model calls and 19 tool calls. It invoked macOS’s /usr/bin/calendar command instead of the Google Workspace wrapper built for the workflow. Then it started discovering tools and files, stalled for about 649 seconds, and eventually died after more than 1,000 seconds without a response.
The fix was to pin the exact tool path in both the skill and the cron prompt and forbid runtime tool rediscovery for that job.
Exploration can be useful in an interactive session. It is dangerous inside a scheduled path with a fixed delivery deadline. A cron prompt should have fewer degrees of freedom than a conversation:
- Name the exact inputs.
- Name the exact tool.
- Define the required artifact.
- Put a hard ceiling on turns and tool calls.
- Define the delivery target.
- Define what to report when nothing changes.
If the work is mechanical, skip the agent entirely and schedule a script.
A missing output can fail before or during inference
Quota exhaustion produced another failure that looked identical from my side. On August 15, the morning job was recorded as blocked with usage_limit_reached. It made zero model calls. The cron preflight treated the exhausted primary credential like a missing credential because the fallback chain was empty, so the agent never existed for that run.
A valid fallback chain changed the behavior. Cron could start the agent and let the provider-routing layer handle the exhausted subscription. That did not guarantee success. The next missed podcast started on the cloud model and then sat inside web_search until the 600-second inactivity limit killed it.
One missing MP3 was a preflight and routing failure. Another was a live tool stall. The earlier calendar incident was tool-selection drift. Re-running the same prompt would not have fixed all three.
Before changing a model or prompt, determine which stage failed: schedule, preflight, inference, tool execution, artifact creation, or delivery.
Multiple agents are multiple systems
I currently run three named agents:
- Cyrus is the chief of staff. He owns the morning brief, cross-business priorities, and routing.
- Isaac owns iBuildMVPs prospecting, qualification, outreach preparation, and commercial recommendations.
- Tarah owns Teemzo maintenance marketing, prospecting, and drafts.
The names help me reason about ownership, but the names are not the architecture. The profiles are.
Each Hermes profile can have its own configuration, environment, credentials, memory, skills, sessions, cron jobs, logs, gateway, and Telegram bot. I learned that after adding a new model credential to the default profile and assuming Tarah would see it. She did not. Her profile retained the exhausted credential and quietly fell through to the local model.
I also saw Tarah behave differently in Telegram than in the terminal. That was not a personality mystery. The Telegram gateway started from a different working directory, did not load the repo’s project instructions, and inherited a platform hint that encouraged a style I disliked. Cron and chat sessions also could not see each other’s history.
The solution was explicit separation plus shared truth:
- Each agent gets a profile-local role and operating contract.
- Role-specific memory stays with that profile.
- Shared facts and current status live in versioned files.
- Scheduled jobs update compact status files that interactive sessions read.
- Cross-agent decisions go into a decision journal instead of disappearing in a chat transcript.
The rule I use now is: shared truth in files, role-specific learning in profile memory.
The org chart has to reflect the real strategy
Another mistake was allowing the automation schedule to preserve an old priority. Teemzo had many active growth jobs because that was what I had built first. That did not mean Teemzo deserved most of my future attention.
I eventually made the business decision explicit:
- iBuildMVPs and The Big O Book are the primary revenue lanes.
- Hermes, local AI, and hardware experiments are first-class R&D.
- Teemzo and DeltaRival are maintenance-tier unless real traction earns more investment.
That required changing the agents, not just writing the decision in a strategy document. Tarah stayed, but her broad hourly operator became a once-daily general job while her focused Teemzo tasks remained. Isaac became a dedicated iBuildMVPs revenue agent. He now runs hourly from 7:00 a.m. through 4:00 p.m. on weekdays and from noon through 4:00 p.m. on weekends. Cyrus reads both agents’ status and puts the iBuildMVPs revenue gate first by default.
The lesson is that cron frequency is resource allocation. If an old project has more automated attention than the business you say is the priority, the system will keep manufacturing evidence that the old project is important.
An agent should have some room to choose the highest-value action inside its lane. It should not have authority to redefine the lane, rewrite its own safety policy, or create more recurring work because it is bored.
Agency became preparation plus a real handoff
I wanted the agents to have agency. I still do. I am less convinced that broad, unsupervised agency is practical or cost-effective for a personal system today.
The useful middle ground is stronger than a chatbot and narrower than an autonomous employee.
An agent can notice an opportunity, gather evidence, qualify it, draft the work, put the artifact in the correct queue, and reduce my involvement to a quick decision. It can decide which prospect deserves the next bounded research pass. It can recommend a positioning change and explain what would prove it wrong. It can prepare a Gmail draft.
I still send the email.
That boundary is not a failure of autonomy. It is the design. Anything involving outreach, publishing, money, deletion, deployment, or a material production change still requires fresh human approval.
The system began to feel real when work appeared where I could act on it: a draft in Gmail, an artifact attached in Telegram, or a specific approval item in the morning brief.
That changed my definition of done:
- “I found a person” is not a contactable lead.
- “I wrote email copy” is not a draft in the correct mailbox.
- “I created a file” is not delivery.
- “I delivered a path” is not an attachment.
- “I made a recommendation” is not a high-value decision if the required consultant pass never happened.
- “The job completed” is not proof that the output was true or useful.
The value lives in the handoff.
AI slop needs deterministic rejection, not a stronger prompt
The first outreach drafts were grammatically acceptable and obviously written by AI. Two supposed segment variants were 95 percent identical. Nearly every line could have been sent to every prospect. Formatting cleanup would only have produced a neater mail merge.
I built three quality layers.
First, I measured my actual writing instead of asking a model to “sound like me.” A voice profile based on 256 of my messages separated real habits from sloppiness. For example, I often use a spaced hyphen and rarely use an em dash. But my typos are not a brand trait that should be copied into a cold email.
Second, I turned mechanical preferences into a linter. It checks length, formatting, banned phrases, unfilled placeholders, paragraph shape, links, punctuation, whether a claimed personalization hook appears in the draft, and whether two messages are suspiciously similar.
Third, I required every personalization hook to be an observed, sourced fact. Blank is better than invented.
That last rule came from a particularly useful failure. While writing the anti-fabrication standard, one worked example claimed that a company’s team page listed 21 people with named delivery leads. The source did not say that. The number 21 came from an employee-band field, and the model dressed it up as a plausible observation.
The sentence sounded reasonable. That was the danger.
The data model now stores the hook, its source URL, and when it was observed. A row without a real hook does not advance to outreach. A stronger model can still invent a fact, so evidence gates matter more than eloquence.
Use expensive reasoning at the decision boundary
I do not need the strongest model to deduplicate rows, inspect a queue, or report that nothing changed. I do want better-than-commoditized reasoning when the system is deciding what iBuildMVPs should sell, how it should position itself, or what I should say to a real potential client.
Isaac therefore handles routine work on the normal subscription-backed model but must delegate one pass to gpt-5.6-sol at xhigh reasoning effort for consequential copy, positioning, offers, packaging, ideal-customer decisions, and product strategy. The final response includes a model and effort receipt. If the delegation fails, the answer remains preliminary rather than being quietly presented as consultant-cleared.
This rule exists because “use the better model when needed” is too vague to audit. At one point Isaac said the delegation tool was not exposed. The live configuration and logs told a different story. After fixing the surface that loaded the skill, I verified real delegated child sessions using the expected model and effort.
Model routing is most useful when it follows the value of the decision, not the personality of the agent.
Observability is not the goal, but it is mandatory
Observability became super important because every failure looked the same from my side: nothing useful arrived.
Consider a few examples:
- The 6:00 a.m. podcast made Isaac sound inactive because his first weekday job did not run until 7:00. The podcast was reading the prior close and presenting it without a freshness label.
- Isaac’s hourly jobs ran, but the results were initially delivered locally rather than to Telegram.
- After switching delivery, Telegram returned
Chat not foundbecause the bot existed but I had never pressed Start. - Tarah rewrote her status file with an old claim that Gmail was not configured even after the OAuth setup and live mailbox check had succeeded.
- One Telegram response gave me a local file path rather than the file.
- A job could finish and still create no usable Gmail draft because a stale expected-address typo and an overbroad deny rule blocked the allowed draft command.
Those are schedule, freshness, delivery, state-propagation, artifact, and policy failures. None is primarily a model-quality problem.
The system now uses several layers of evidence:
- Cron execution history says whether a job was claimed, started, completed, or failed.
- Model and tool logs show what happened inside the run.
- Compact status files show current business state across isolated sessions.
- Activity logs preserve material work without turning the status file into a novel.
- Telegram heartbeats say what the agent did, the result, what I need to do, and what the agent owns next.
- Approval queues identify the actual human gate.
- Output files and Gmail drafts prove that the artifact exists.
- The morning podcast gives me a daily human-readable review of the whole system.
Run success, delivery success, and quality success are different metrics. I need all three.
The podcast became both the interface and the test suite
The podcast matters because I consume it. A Markdown report can exist forever without changing my day. I actually listen to the morning show.
It also exposes defects that dashboards miss. One episode told me to write an outreach draft that Tarah owned. The audio rendered correctly. The underlying operating model was wrong. Listening caught it immediately.
The production path now has a few explicit controls:
- Cyrus uses the George voice, Isaac uses Mark, and Tarah uses Jessica in ElevenLabs.
- The synthesizer rejects a missing host or duplicate voice before calling the paid synthesis API.
- A free dry run validates the script before audio generation.
- Long synthesis calls retry rather than discarding the whole episode on one transient timeout.
- Isaac’s segment reads his actual state and labels it as prior-close data because the podcast runs before his first scheduled job.
- The show assigns work to the agent that owns it and asks me only for the real human gate.
That is a general design lesson: choose an output you will genuinely consume. Consumption creates a natural quality review. A system that only produces files for other agents to read can be wrong for a long time without bothering anyone.
Safety controls can also break the allowed path
The agents prepare work, but they cannot send email, publish, spend money, delete data, or materially change production behavior without me.
For Gmail, I went beyond a prompt instruction. The helper is draft-only and blocks send and reply paths. The profiles also have deny policies around external actions. The business mailbox was granted a narrow compose scope, and the helper checks the expected identity before creating a draft.
That is defense in depth, not a perfect security boundary. Google’s compose scope still permits sending, and a process running with my unrestricted local-user permissions can reach the same files. A true non-bypassable boundary would need a separate broker, identity, or operating-system boundary.
The safety system also produced a useful counterexample. Isaac’s draft path was blocked first by a typo in the expected mailbox address and then by a broad command-deny pattern that accidentally matched the permitted draft workflow. No email was sent, which is the correct failure direction, but the agent could not complete its approved internal work either.
Fail closed, but test the allowed path. A safety policy that has never proven one legitimate draft can be security theater with a broken product behind it.
Memory only helps when it reaches the next decision
One reason I chose Hermes was the promise of memory, skills, and cross-session learning. I learned quickly that recorded information is not the same as applied information.
A fact may exist in a terminal transcript, one profile’s memory, an old status snapshot, or a draft document and still be invisible to the next scheduled job. The most embarrassing version is when the system “knows” something somewhere but behaves as if it does not.
I now treat memory as a propagation problem:
- Stable facts go into canonical knowledge files.
- Explicit operating rules go into the relevant role or skill.
- Current state goes into compact status files.
- Non-obvious choices go into a dated decision journal with evidence.
- Cron and Telegram sessions read the same canonical files.
- A decision does not count as durable merely because one AI chat agreed with me.
This also lets me use different coding and reasoning harnesses without trusting their private memory stores to stay synchronized. The filesystem is the handoff.
What is working now
This is an as-of snapshot, not a final architecture. The system changes almost daily. As of this draft:
- The morning podcast runs daily at 6:00 a.m. and has delivered successfully on recent mornings.
- Cyrus, Isaac, and Tarah all appear with separate voices.
- Isaac has two active schedules totaling 60 revenue runs per week.
- Tarah’s broad operator has been reduced to once per weekday, while her focused maintenance tasks remain active.
- All three profiles use a subscription-backed daily model with the tested local Ollama model as the configured last fallback.
- Isaac’s high-value commercial work has a verified consultant-model path.
- Telegram summaries report what Isaac did and what, if anything, I need to do.
- Teemzo has real unsent Gmail drafts. Nothing has been sent automatically.
- The cost drivers are measurable rather than mysterious.
It is still R&D. The system has not earned its keep in new revenue yet. Isaac’s first iBuildMVPs outreach draft is still blocked from becoming a real Gmail draft by the draft-path issues described above. Local inference is not a dependable replacement for every workflow. Some state still has to be reconciled manually. More agency would be possible, but not all of it would be wise or cost-effective.
I am still happy with where this is going. The morning experience is close to what I hoped for, and the agents increasingly remove blank-page work instead of creating more of it.
What I would tell someone starting this weekend
- Start with one experience you want. Mine was the morning podcast. “Organize my life” is not testable.
- Design the Secretary, Employee, Consultant ladder. Decide what can be a script or cheap triage model, what belongs to the everyday agent, and which decisions require a frontier consultant pass.
- Choose the billing failure mode before the model. Decide whether quota exhaustion should stop, switch to another fixed-cost route, use local, or buy metered inference.
- Use the Agent-Subscription Pattern deliberately. Subscription-backed automatic work, tested local or stop, metered APIs only when explicitly approved and capped.
- Reuse hardware until the workflow proves otherwise. An existing MacBook is enough to learn a lot if you handle sleep, power, memory, and scheduling.
- Set a hard limit on every metered key. Use a separate key for the agent and monitor it independently.
- Measure a no-op run. That is your fixed boot cost. Everything above it is workflow accumulation.
- Do not feed raw pages into a long loop. Build compact deterministic tools for scraping, parsing, lookup, validation, and deduplication.
- Keep scheduled jobs narrow. Exact inputs, exact tool, exact artifact, bounded turns, explicit delivery.
- Verify runtime behavior. List the live fallback chain, inspect the live cron schedule, and check fresh logs. Do not trust plausible YAML.
- Test every profile separately. Credentials, memory, skills, gateways, environment, and cron state are profile-scoped.
- Define done as a handoff. A lead needs a route. Email copy needs a real draft. A document needs to arrive as an attachment. A recommendation needs evidence.
- Reject AI slop mechanically where possible. Lint the copy, source the personalization, compare drafts, and let blank fields stay blank.
- Spend stronger reasoning at the decision boundary. Do not pay for it on every queue check, and do not let routine reasoning impersonate a consultant pass.
- Separate running, delivery, and quality. A green cron status is not a useful outcome.
- Keep human approval for consequential actions. Drafting can be autonomous. Sending should not be, at least not until the workflow has earned far more trust.
- Make the automation reflect the real strategy. Cron frequency is resource allocation. Do not let yesterday’s experiment dominate tomorrow’s business.
- Listen to or inspect the output. If you do not consume it, you do not have a quality loop.
The conclusion after twelve days
I still want agents with agency. I want them to notice problems, choose useful work, and make action easier without waiting for a prompt.
What changed is my understanding of what has to surround that agency.
The secretary needs to notice and route work cheaply. The employee needs a bounded role, deterministic tools, and a clear definition of done. The consultant needs to appear only at the high-value decision boundary. Profiles need isolated credentials and shared truth. External actions need hard human gates. Outputs need real destinations. The whole thing needs enough observability to distinguish “did not run” from “ran and produced junk.”
Observability is not the product I wanted, but it is infrastructure I cannot run agents without.
The product I wanted is the thing that now waits for me in Telegram every morning: a useful summary of my day, my inbox, and the work moving around me. The rest of the last two weeks was learning what it takes to make that experience reliable, affordable, and worth listening to.