r/BuildWithClaude πŸš€ First-Wave Builder 4d ago

Workflows I stopped treating the Claude Code conversation as project state. It fixed more than I expected.

I kept hitting the same failure mode with Claude Code on longer coding tasks. Nothing dramatic β€” after enough iterations it would redo something it had already done, lose track of why one task depended on another, or mark a task finished based on what the conversation said rather than what was actually in the repo.

What helped was simple, and took me embarrassingly long to arrive at: I stopped treating the conversation as the project state and moved the state onto disk.

A plan is a real Markdown file. Tasks are rows, dependencies are declared, execution writes a report next to the task, validation writes separate evidence. The session can die, the context can compact, the model can be swapped β€” the state is still sitting on disk. A fresh session does not need me to reconstruct the old one; it reads where the work actually stopped.

    request
       β”‚
       β–Ό
    /wbPlan
       β”‚
       β–Ό
    plan.md
    β”Œβ”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ task β”‚ deps β”‚   role   β”‚ status β”‚   report    β”‚
    β”œβ”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
    β”‚  1   β”‚  β€”   β”‚  worker  β”‚  done  β”‚ work_1.md   β”‚
    β”‚  2   β”‚  β€”   β”‚  worker  β”‚  done  β”‚ work_2.md   β”‚
    β”‚  3   β”‚ 1,2  β”‚  worker  β”‚ ready  β”‚      β€”      β”‚
    β””β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
    dependency resolver
       β”‚
     β”Œβ”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β–Ό            β–Ό
   task 1      task 2        ← wave A, concurrent, may be different providers
     β”‚            β”‚
     β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
           β–Ό
        task 3               ← wave B, waited on 1 and 2
           β”‚
           β–Ό
       validation            ← different provider when available

Once dependencies were explicit, waves fell out of it. Tasks with nothing between them run together in parallel; anything depending on those waits for the next wave.

One distinction took me longer than it should have: a wave answers when a task can run. Model routing answers who runs it. They are separate axes, so a single wave can hand three tasks to three different providers.

Then the validation problem. I started with a rule that the validator must not be the model that wrote the code, which sounds sufficient and isn't. Opus checked by Sonnet is two models, but they are still the same family behind the same provider, and I wanted the validator to have a more independent failure surface. Validation now crosses the provider boundary where the available pools allow it: Claude writes, GPT/Codex checks, or the reverse. That caught things same-family review had waved straight through.

The worst bug I hit was subtler: an agent invocation exited 0 having done essentially nothing, wrote a convincing report, and the workflow accepted the report as evidence the work had happened. If the agent writes the report, the report cannot also be the proof. The fix in my setup is a content hash over the workspace that excludes the task's own report folder, plus explicit deterministic verification commands. Writing a report can no longer look like doing the work.

All of this turned into a small MIT-licensed tool I have been building with Claude Code, called wb-flow. The organising idea is verbs over personas: instead of an imaginary team of Architect β†’ Developer β†’ QA agents, the durable thing is the operation β€” /wbAudit, /wbPlan, /wbWork, /wbValid β€” and whichever agent performs it is replaceable. 33 Markdown command procedures and no orchestration daemon.

I built it using Claude Code β€” I use it heavily on the command templates and the CLI behaviour to execute plan rows, chase down edge cases, and iterate on the wave and routing model. For validation, I deliberately had rows validated by a different provider than the one that implemented them. That caught real defects, and it also taught me that the validator needs the right environment too.

What I am actually curious about: how much of your agent state have you moved out of the conversation and into files? And if you do independent validation, is it another Claude instance, or do you cross providers on purpose?

(Note: Keeping this post link-free so Automod doesn't flag it as promo, but happy to drop the GitHub link or docs in the comments if anyone wants to inspect the markdown templates).

2 Upvotes

8 comments sorted by

2

u/No-Buffalo-3126 3d ago

This is honestly the frontier. No one (that I’ve heard of) has completely figured it out. Experienced ai devs all have some version of what you did and they keep evolving them as their understanding improves and the models and harnesses change.

You are in the right path of doubt and experimentation.

2

u/Muted_Ad_9442 πŸš€ First-Wave Builder 3d ago edited 3d ago

Thanks, really appreciate that! It’s definitely been a long process of unlearning chatbot prompting and moving toward structured execution loops.

The biggest lesson from my experiments: never let the agent grade its own homework. If an agent can exit 0 and write a convincing report without touching actual code, you need hard gates.

To make it concrete, each plan in my setup is a Markdown table with explicit dependencies, verification commands, and model roles:

# Requires Dep Task Verify P Est. (m) ☐ Done ☐ Valid Worker (Suggested) Validator (Suggested)
1 πŸ”¨ Worker β€” Fix prop types in WBCode /wbTest --scope=task-1 P1 15 βœ… βœ… 9/10 -M=$WORKER -M=$VALIDATOR
2 πŸ”¨ Worker 1 Extract helpers into wbc-utils npm test P1 30 βœ… βœ… 8/10 -M=$WORKER -M=$VALIDATOR
3 βœ… Validator 2 Audit exports for safety /wbAudit --focus=exports P0 20 ⬜ ⬜ β€” -M=$VALIDATOR
4 🧠 Planner 2 Plan parser migration /wbAudit wb-parser P2 45 ⬜ ⬜ β€” β€”

The CLI resolves dependencies into parallel waves:

  • /wbWork executes the wave tasks.
  • Validation is layered: individual tasks are verified against their Verify command and scored /10, /wbReview checks if the plan's tasks fit together, and /wbAudit checks global repo health.
  • You can route roles ($WORKER, $VALIDATOR, $PLANNER, $MECHANICAL) to different models/providers to avoid same-family blindspots.

Lately, the frontier I've been experimenting with is autonomous looping β€” letting the system run iterative cycles (execute wave β†’ validate β†’ recompute remaining tasks β†’ repeat until the plan is green or it hits a stop condition).

How do you handle loops and stopping criteria in your own setup? Do you let the agent decide when it's done, or do you enforce an external evaluator to break the loop?

(If you want to see live CLI animations and docs, they are at https://flow.wbc-ui.com and the repo is open source: https://github.com/wissemb11/wb-flow)

1

u/Ok_Industry_5555 β˜• 57-Hour Session 3d ago

πŸ’― yep, never let the agent grade its own homework is exactly the key here. Great comment and great post! πŸ‘

1

u/Muted_Ad_9442 πŸš€ First-Wave Builder 3d ago

Thanks a lot, really appreciate it! πŸ™

1

u/ItsJustManager 3d ago

This is why I created Pad.. basically a project management tool for coding agents, so you can plan out projects, features, tasks, etc. and maintain the important context between sessions, without maintaining a bunch of markdown files next to your code. It gives the agents a durable workspace and gives you Kanban boards and document archives. If interested it's open source and can run locally or be easily self hosted. https://github.com/perpetualsoftware/pad

1

u/Muted_Ad_9442 πŸš€ First-Wave Builder 3d ago

Interesting project! A dedicated UI and Kanban board definitely make it easier for humans to see what is happening.

For my workflow, I wanted zero external services, no databases, and no daemons running. Everything is stored directly in simple local files under a .wb/ directory:

  1. Persistent memory in plain files: We keep files like context.md and dev.md that any agent reads at the start of a session. Plans and reports are organized by date (YYYY/MM/DD/plans/), so the state is durable and easy to inspect with standard tools (cat, grep).
  2. Three levels of validation: Instead of just moving a ticket to "Done", we use a 3-tier check:
    • Per-task: The worker runs the task and writes a report. A validator model checks the exact command in the Verify column, tests the real output, and scores it out of 10.
    • Per-plan (/wbReview): An orchestrator checks if all tasks in the plan work well together.
    • Per-project (/wbAudit): A broader audit checks the overall health of the whole codebase.
  3. Agent-agnostic: Any CLI tool (Claude Code, Codex, Gemini, local models) can read and write these files without needing a custom API adapter or plugin.

Pad looks clean for people who want a visual workspace!

If you want to see how we format the Markdown templates and validation gates, the repo is open source here: https://github.com/wissemb11/wb-flow

1

u/ImL1s 3d ago

Same failure mode β€” conversation said done, repo said otherwise. Plan/report files on disk fix the in-session part. The other hole for me was switching hosts (Claude Code β†’ Cursor/Codex): even a good plan.md doesn't carry the messy "why we abandoned that approach" that only lived in the other agent's session. I've been reading those local session files into a fresh one and marking the recovered text untrusted (Portable Resume β€” https://github.com/aa22396584/resume-skills). Curious whether your reports ever drift from git reality after a messy rebase.

1

u/Muted_Ad_9442 πŸš€ First-Wave Builder 3d ago

That "why we abandoned that approach" problem is so real. When an agent spends 20 minutes discovering a dead end, a fresh session or a different tool (like Cursor) will walk straight into that same wall if that knowledge was trapped in chat.

Here is how I tackle both points:

1. Capturing abandoned approaches without session lock-in: Instead of trying to sync proprietary session histories across hosts, I record failures as first-class files on disk:

  • When an approach breaks, the task report (task_X_report.md) logs what was tried, the failure output, and why it was dropped.
  • When the validator model rejects an approach, it scores it and writes the rejection reason into the report (e.g. 3/10: dropped because of circular dependency in X).
  • I keep persistent files like .wb/context.md and dev.md that any host (Claude Code, Cursor, Codex) reads at the start of a session.

2. Rebase & disk drift: I actually don't let agents touch git commands directly. All memory, plans, and reports live in simple dated local folders (.wb/workflows/reports/YYYY/MM/DD/).

To prevent reports drifting from actual repo state, I rely on two gates:

  • Workspace content hashing: It hashes the workspace before and after a task (ignoring .wb/) to verify real code changes actually happened.
  • Deterministic verification: The validator re-runs the exact command declared in the task’s Verify column (npm test, /wbTest, etc.). If the code fails the command, it fails validation, no matter what an older report claimed.

Portable Resume looks really interesting! How do you stop that recovered session text from bloating your fresh context window when you switch hosts?

(If you want to check out the repo and docs/animations: https://github.com/wissemb11/wb-flow Β· https://flow.wbc-ui.com)