BACK
OPERATING SYSTEM · AGENT LOOPS

How I actually work.

Most of my day runs on loops I built, not on a todo list. I specify the job, an agent runs it on a schedule, the output lands in one ledger, and I act only on decisions. When a loop is wrong, the correction becomes a standing rule it must check before acting again.

The engineer’s job is shifting from producing systems to specifying them and verifying machine output. Judgment is the scarce input. Everything below is how I practice that on myself.

01 / Architecture

The system in one picture

SCHEDULERS 3AM · 9PM · DAILY CONNECTORS MAIL · CAL · LINEAR · DRIVE read AGENT RUN DRAFT · RANK · FLAG STANDING RULES CHECKED BEFORE ACTING constrain write LEDGER 1 ISSUE PER LOOP ME DECIDE · SEND a correction becomes a rule
  1. 1
    Schedulers

    Cron style triggers at fixed times. No agent runs without a trigger.

  2. 2
    Connectors

    Email, calendar, Linear, Notion, Drive, and a scraper. Read mostly. Writes go to exactly one place.

  3. 3
    Ledger

    One running Linear issue per recurring loop, one comment per run, archived when the loop retires. Nothing gets its own file or folder.

  4. 4
    Standing rules

    A memory layer of constraints written in plain language. Every rule came from a mistake.

  5. 5
    Me

    The approval step. Agents draft, rank, and flag. I decide and send.

02 / The loops

Four loops, running

01Daily operating brief

RUNNING
Trigger
3 AM Pacific, and a second pass at 9 PM.
Inputs
Inbox, calendar, Linear, the pipeline CRM, and yesterday’s ledger entry.
Decision
Pick one item for the day with a hard deadline or the highest expected value, rank the rest, draft any replies that are ready to send, and triage the inbox into act, wait, ignore.
Output
One comment on the ledger issue. The 9 PM pass checks whether the one item got done and rolls anything open into tomorrow.
Guardrails
Cannot resurface an item I marked closed. Cannot pick from a list of disqualified sources. Cannot surface security advisories or account sign in alerts as work.
What broke

Four separate scheduled tasks were duplicating context and storage. Merged into one task that fires twice. Old schedules deleted, not paused. Separately, the loop once picked a thread from a source I had already ruled out. That became the first standing rule: check the disqualified list before choosing.

02Application tailoring

RUNNING
Trigger
A new role enters the pipeline, either from the daily scraper or from me.
Inputs
The posting, my base narrative, and three or four resume variants (agent infrastructure, protocol engineering, engineering lead, smart contract operations).
Decision
Select the variant, rewrite only the sections the posting actually tests, and produce a short outreach message.
Output
A tailored document and a draft message, queued for my review.
Guardrails
Anti sycophancy rules in the config: no claim that is not in the source material, no title inflation, no restating the recipient’s own background back at them. Drafts are the length a person would type.
What broke

Early drafts ran long and read as credential stacking. The fix was a length ceiling and a rule that the message must open with what I built, not who I am.

03Signal scraper

RUNNING
Trigger
Daily.
Inputs
A watch list of company career pages and a few communities.
Decision
Diff against yesterday, score against my target profile, drop anything from disqualified sources.
Output
New matches appended to the pipeline with a score and a one line reason.
Guardrails
Direct competitors of my current employer are excluded by rule.

04Chat capture

IN PROGRESS
Problem
I run six parallel workstreams across many LLM chats and none of it was being saved. Ideas died in scrollback.
Design
Local first, command based. A CLI captures a chat, writes a memory, links it to the relevant workstream, and creates a task only if the chat contained one. The LLM is invoked for classification and summarization, not kept in the loop.
Status
The capture ritual runs manually through a Notion command center today. The CLI is being built to replace it.
03 / Method

How I build the loops

The same discipline applies when the agent is writing code for me.

  • CLAUDE.md as a constitution: what the agent may touch, what it may never do, what proof it must produce before claiming a milestone.

  • PROMPT.md as the spec: milestones with acceptance criteria, not vibes.

  • run.sh as the harness: restarts the session on failure, parses the provider’s rate limit reset time out of the error text, sleeps until then, and resumes. Limit hits do not count as failures.

  • A clean room check before any push: grep for anything proprietary from my day job.

run.sh — the part that matters
if grep -q "session limit" "$LOG"; then
  RESET=$(python3 parse_reset.py "$LOG")   # epoch seconds, stated timezone
  sleep $(( RESET + 120 - $(date +%s) ))   # two minute buffer
  WAITS=$((WAITS+1)); continue             # does not consume a retry
fi
04 / Why guardrails

Agents that need controls

The reason I care about guardrails on my own loops is the same reason I built Aegis: an agent that can act on assets needs a human approval step enforced below the application layer, not above it.

  • Policy engine driven by YAML rules.
  • Human approval enforced as an EIP 712 guardian cosignature at the contract level, so a prompt injected agent still cannot execute a gated action.
  • Hash chained audit log with Ed25519 signatures and Merkle anchoring.
  • Adversarial eval suite at 0% bypass. Exposed through an MCP server.
VIEW THE REPO ↗
05 / Memory layer

Standing rules (excerpt)

Every rule below exists because a loop got it wrong once.

  • Check the disqualified list before surfacing any lead.
  • Closed means closed. Do not resurface.
  • One ledger per loop. No new files or folders for recurring work.
  • Drafts are short. No formal closing paragraph.
  • No security advisories or sign in alerts in the morning brief.
  • No AI attribution on commits.

If you want to see any of this running, ask. The ledger is the demo.

Let’s talk