DEV Community

Cover image for Separating the Idea, State, and Artifact Planes in Agent Pipelines
shakti mishra
shakti mishra

Posted on

Separating the Idea, State, and Artifact Planes in Agent Pipelines

The agent worked. The architecture didn't.

This failure mode won't show up in your eval suite.

An AI architect builds a personal automation pipeline: an agent scouts trending content, pipes ideas into a chat thread, he reacts, things get logged. The agent did its job. It found the trends, wrote them down, and responded when he asked it to.

He killed it anyway, and not over hallucination or token cost. He killed it because everything lived in "a flat scroll of messages. No structure, no views, no way to see what is in scripting versus what is scheduled." He was spending his entire one-hour creation window scrolling backwards through a Telegram thread, looking for something he'd written the day before.

The model wasn't the problem. The substrate was, and almost everyone shipping agents today has the same problem, because the default agent UI is a chat window and the default system of record is the transcript.

If your agent's output lands in a conversation, you've built an append-only log with no schema and no query interface. Retrieval is O(n), and a human eye does the scanning. That works fine in a demo and falls apart somewhere around week three.


Why the transcript fails as a system of record

Break a chat log down to its data properties and the problem is obvious:

CHAT TRANSCRIPT AS DATABASE
---------------------------
Schema            none (freeform text)
Primary key       timestamp (not semantic)
Indexes           none
Query interface   Ctrl+F, human eyes
Mutation          impossible (append-only, no UPDATE)
Aggregation       none
Views/filters     none
State transitions untracked
Enter fullscreen mode Exit fullscreen mode

The row that matters is Mutation: impossible. Real work has state that changes: an idea becomes a draft, the draft gets scheduled, the scheduled item ships. In a chat log none of those transitions exist as data. They exist as later messages contradicting earlier ones, and the reader has to reconstruct the current truth by replaying the whole thread.

That's event sourcing without a projection. You get the event stream and no materialized view.

It also compounds. Every session starts with context reconstruction: what did I decide? where did I leave off? which of these forty messages is still live? The human pays that cost every time, and it grows with the length of the thread while the thread's value stays flat.

You'll know you have the problem when you catch yourself using the agent to search the agent's own output.


The fix: three planes, not one thread

The working version of the pipeline separates concerns into three data planes, each with a different write pattern and a different owner.

        ┌──────────────────────────────────────────┐
        │  PLANE 1: IDEA / INTAKE                  │
        │  Google Sheet · append-only              │
        │  Writer: agent (scheduled, unattended)   │
        │  Volume: high · Precision: low           │
        │  Never edited in place                   │
        └───────────────────┬──────────────────────┘
                            │  human selects (the gate)
                            ▼
        ┌──────────────────────────────────────────┐
        │  PLANE 2: STATE / PIPELINE               │
        │  Notion DB · typed records               │
        │  Writer: agent on human instruction      │
        │  Volume: low · Precision: high           │
        │  status ∈ {Idea, Scripting, Filming,     │
        │            Scheduled, Published}         │
        └───────────────────┬──────────────────────┘
                            │  references by ID
                            ▼
        ┌──────────────────────────────────────────┐
        │  PLANE 3: ARTIFACT                       │
        │  Google Docs · Drive · rendered media    │
        │  Writer: human (scripts) + agent (renders)│
        │  Addressed by link from Plane 2          │
        └──────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Each plane has a job the other two are bad at.

Plane 1 optimizes for recall rather than precision. The scheduled scan writes 20+ ideas a day across TikTok, Reels, X and YouTube, each row carrying the trend, a hook, an angle, a caption, hashtags, format notes, and a suggested post time. Most of those rows are garbage, which is fine. It's an intake buffer, and the rule is never curate in place.

That rule earns its keep. Agent writes are non-deterministic, so if your agent mutates rows in the same table it writes to, you lose the ability to tell "the agent changed its mind" from "I changed my mind" from "the agent silently dropped something." Append-only intake gives you an audit trail for free, and it makes human selection the only path from noise to signal.

Plane 2 optimizes for queryable state: one typed record per unit of work, with a status enum. A single glance answers what's in scripting, what's waiting to film, and what ships next, which is the question the chat thread could never answer.

Plane 3 holds the payload. Documents and media are referenced by ID from Plane 2, never inlined into it. That's ordinary normalization, and agent systems break it all the time by pasting entire drafts into chat messages.

The state machine itself is simple enough to copy:

  Idea ──► Scripting ──► Filming ──► Scheduled ──► Published
   │           │             │
   └───────────┴─────────────┴──► Dropped
Enter fullscreen mode Exit fullscreen mode

Five states and one escape hatch. That's the whole orchestration model, and both the human and the agent can read it, which matters: an agent that sees status = "Scripting" can act on it directly. An agent reading a chat thread has to infer status from prose, and inference is where reliability starts slipping.


Splitting the agent into workflow, runner, and schedule

The second architectural idea in the piece is a clean three-way split of what most people mash into a single "agent":

Component Answers Analogue
Workflow How the job is done DAG definition / playbook
Runner Who owns and executes it Worker identity + permissions + memory
Schedule When it fires Cron / event trigger

If you've ever built data infrastructure, this is Airflow's DAG-vs-worker-vs-scheduler split arriving in the agent world, and the fact that it keeps getting rediscovered independently is a decent signal that it's correct.

The practical consequence is that each axis varies independently. Same workflow, different runner (dev vs prod credentials). Same runner, different schedule (daily scan vs on-demand). Same schedule, swapped workflow (v1 to v2 of your edit pipeline) without touching the trigger or the identity.

The monolithic alternative is a chat agent where the how, the who, and the when are tangled together in a prompt you retype every session. You can't version that, and you certainly can't hand it to anyone else.

ENTANGLED (chat agent)
  "hey can you scan trends and put them in my sheet like
   you did last time, you know the format" ──► ???

DECOMPOSED
  Workflow:  trend_scan.v3   (deterministic playbook)
  Runner:    content_bot     (Drive+Notion scopes, memory: voice/topics)
  Schedule:  0 6 * * *       (daily 06:00)
Enter fullscreen mode Exit fullscreen mode

The decomposed version is a config artifact. You can diff it, review it, and roll it back.


Skills are portable; runtimes are not

This is the detail with the longest shelf life. The video editing logic (cut to vertical 1080×1920, word-synced captions, motion graphics, brand logos, phone-legible thumbnail) was a Claude Skill wrapping Remotion. When the pipeline moved to a different orchestrator, that logic wasn't rebuilt from scratch. It was ported into a saved Workflow and invoked by a Runner.

The value was never in the runtime.

It was in the encoded decision rules: caption style, safe zones, font sizes, brand colors, render steps. Those took work to get right and would be expensive to rediscover. The execution environment around them is commodity infrastructure that churns every eighteen months or so.

       ┌─────────────────────────────────────┐
       │  DURABLE  (you author this once)    │
       │  • decision rules & checklists       │
       │  • constraints, safe zones, brand    │
       │  • step ordering & failure handling  │
       └──────────────┬──────────────────────┘
                      │ portable
       ┌──────────────▼──────────────────────┐
       │  COMMODITY (swap every ~18 months)  │
       │  • agent runtime / orchestrator      │
       │  • model provider · tool bindings    │
       └─────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

So write skills as instruction artifacts rather than runtime code. A skill expressed as a markdown playbook with explicit steps, constraints, and decision rules is a text file you can carry anywhere. Bind it hard to one vendor's SDK and you've scheduled a rewrite.

If you already have Claude Skills, you already have portable assets. They're the durable layer, not vendor lock-in, and every orchestrator (including the one you're using today) is replaceable.


Where to put the human: automate the overhead, not the critical path

The pipeline has five stages. Two of them are deliberately not automated:

1. Trend scan   AGENT   (scheduled, unattended)
2. Curation     HUMAN   → agent files the selection
3. Scripting    HUMAN   ← agent assists on request
4. Filming      HUMAN   (fully manual, by design)
5. Editing      AGENT   (workflow-invoked)
Enter fullscreen mode Exit fullscreen mode

Automation sits at the ends, intake and post-production, while the human occupies the middle where judgment lives. The stated reason for keeping scripting human is sharp: "the point of the system is not to remove me from the work that is mine."

The engineering framing is Amdahl's law. Total time is critical path plus serial overhead. In a creative or knowledge pipeline the critical path is judgment, and it's irreducible because you are the value being produced. The serial overhead is everything around it: noticing, logging, filing, linking, formatting, rendering.

Speed up the overhead and the whole system gets faster. Try to speed up the critical path by automating judgment and you don't get faster output, you get more output that nobody wanted.

There's a second constraint the piece names explicitly, and it deserves a term: the friction budget. As he puts it: "anything that is not seamless does not get done. If an idea requires me to open six tabs, copy something from one place to another, and remember where I put the draft, it dies."

Treat friction as a hard budget. For a part-time operator with one hour, the budget is near zero: six tabs exceeds it, and the workflow gets abandoned no matter how good the agent is. It's the same reason an accurate internal tool that takes six clicks to reach loses to a rougher one sitting behind a single button. Adoption follows friction more than capability. Most agent projects that "failed" cleared the capability bar and blew the friction budget.


What to build on Monday

If you're standing up an agent pipeline, personal or production, the port is mechanical:

  1. Pick a real system of record: anything with a schema, a status field, and views. A database, a project tracker, even a spreadsheet. Not the chat transcript.
  2. Split intake from state. Agents write to a high-volume, append-only intake table. Nothing moves to the state table without passing a gate, either human approval or a deterministic filter. Never let an unattended agent mutate your source of truth in place.
  3. Model the states explicitly, as a short enum both the human and the agent can read. If your agent has to infer status from prose, add the field.
  4. Decompose how, who, and when into workflow, runner, and schedule, versioned separately. A retyped prompt is not an architecture.
  5. Write skills as portable instruction artifacts. Playbooks in text, loosely bound to whatever runtime is current. Assume the runtime churns.

6. Audit your friction budget. Count the tabs and copy-paste steps between "I have an idea" and "I'm doing the work." If it's more than two, the workflow will be abandoned, and the model won't be the reason.

Key Takeaways

  • A chat transcript is an append-only log with no schema, no index, and no UPDATE, so it can't serve as a system of record for stateful work, however good the agent writing to it is.
  • Separate the idea plane, the state plane, and the artifact plane. Intake optimizes for recall and stays append-only, state optimizes for queryability and stays typed, and artifacts are referenced by ID.
  • Split the agent into workflow (how), runner (who), and schedule (when) so each axis versions and rolls back independently. Airflow settled on the same split a decade ago.
  • Skills are the durable layer and runtimes are commodity. Encode decision rules as portable instruction artifacts so an orchestrator swap is a port rather than a rewrite.
  • Automate the serial overhead, not the critical path. Judgment is where the human is the product. Noticing, filing, and rendering are where the hours leak.

- Adoption follows friction more than capability. A workflow that exceeds the user's friction budget dies regardless of model quality.

The question worth arguing about

Every major agent product is converging on the same interface: a chat box. But the moment an agent's work has state that outlives a session, the chat box stops being a UI and starts being a bad database.

So which is it? Is chat a transitional interface we'll look back on the way we look back on command-line-only databases, with agents eventually shipping real structured front ends? Or is the transcript fine, and the fix is just better memory and retrieval bolted onto the thread?

If you've killed an agent that technically worked, what made you stop using it? I'd bet more of those stories are about state and friction than about the model.


Top comments (0)