I built a job-search pipeline for a family member — discovery, scoring, application generation, pursuit strategy and tracking, all operated by AI coding agents. The system ran 31 jobs through its workflow, scoring each against 13 weighted dimensions and routing them into pursuit tiers. Early in the build, I stood up a third-party orchestration platform with a running server, an embedded database, an org chart and issue-based task routing, and piloted one job through it successfully end to end.
Then I removed every trace of it.
The same capabilities wound up handled by two Python packages and plain JSON files on disk. The orchestration layer wasn't needed. The job-search pipeline itself kept running afterward — applications went out, though they weren't submitted directly through the system — but the infrastructure I'd built to manage the agents was gone.
Deleting working code is a decision, not a failure.
The mechanism: what an orchestration platform does and why I tried it
An orchestration platform handles agent routing, state persistence, task decomposition and approval gates across a multi-agent workflow. The promise is that you declare the org chart, the issue types and the escalation paths, and the platform enforces them — no hand-rolled state machines, no file-locking logic, no JSON parsing drift.
I tried it because I was about to run 15 named agent roles — onboarding, market research, collector, evaluator, strategist, resume architect, ATS reviewer and simulator, researcher, tracker and coach — through a workflow with approval gates, red-line violations, and five-tier pursuit routing. Each role documented against a fixed Mission/Inputs/Outputs/Constraints/Approval-Rules/Tool-Access/Escalation template. That's a lot of coordination surface to hand-roll in Python scripts.
So I brought in the platform. I wired one job through it end to end. It worked.
Then I looked at the stack: a server process, an embedded database, a platform-specific agent definition format, and — critically — the same state-tracking and approval-gate logic I was going to have to write myself anyway, because the platform's declarative routing didn't actually understand the 13-dimension scoring model or the red-line cap rules the evaluator needed.
I deleted it and replaced it with requests, pyyaml, and standard-library Python. No database, no server. Plain JSON, YAML and Markdown files on disk for state. The whole current system ships 25,605 lines of Python across 56 files with exactly two third-party dependencies.
The rule that came out of it
Infrastructure is justified only by the complexity it removes.
If the abstraction doesn't cut the number of decisions you have to make — if you're still writing the same approval logic, the same state-transition rules, the same error-recovery paths, just in a different syntax — then the platform is cost without leverage. Delete it and run the workflow in the simplest mechanism that enforces the invariants you actually care about.
For this pipeline, those invariants were:
- Status is derived from artifacts present, not from agent self-reporting. This prevents drift between reported and actual state.
- Approval gates block downstream steps. A job doesn't advance until its gate clears.
- Red-line violations and deal-breaker caps stop a job before materials are generated.
All three of those rules lived in my Python anyway. The orchestration platform didn't write them for me; it gave me a different place to express them.
How another builder can apply this
If you're evaluating an orchestration or workflow platform for an agent system, run this test:
- List every decision the platform makes for you — not the ones you configure, the ones it actually removes from your code.
- List every invariant your workflow needs to enforce (approval sequences, state constraints, escalation paths).
- Check whether the platform's decisions cover your invariants. If you're still writing the enforcement logic, the platform is a wrapper.
A wrapper isn't always bad — sometimes the monitoring, logging and retry surface alone justify it — but if you can get the same guarantees from a 40-line Python script and a JSON file, take the script.
I kept the rule simple: Can I see the state on disk? If the answer is yes, and the state file tells me everything I need to know about where a job is and what gate it's waiting on, I don't need a database or a server to track it.
The job-search pipeline enforces that rule literally. Status is derived from what exists on disk: if the output file is there and the approval artifact is there, the step is done. If the file exists but the approval artifact doesn't, the step is incomplete. No agent self-report, no status flags stored separately from the artifacts.
What broke and how I fixed it
That governance principle caught its own violation.
An initialization function was marking a pipeline step "done" purely because the output file existed on disk, without checking whether the step's own upstream approval gate had actually cleared. I found it because 26 of 31 tracked jobs had a step incorrectly marked complete before approval had happened.
I added an explicit dependency-enforcement pass and wrote 6 new tests. The current suite has 445 test functions; a dated snapshot recorded 147 passing.
A related gap showed up in the same session: the audit log held exactly 1 entry despite 31 jobs already tracked, because the state-initialization code never logged its own actions. I fixed it; the log grew from 1 to 208 entries.
Both of those fixes were easier to write in plain Python than they would have been in a platform's declarative routing language. I could see the state file, read the approval artifacts, and write a function that enforced the dependency directly. No schema migration, no platform-version compatibility check, no waiting for an upstream fix.
The status now
The job-search pipeline is parked. It works — 25,605 lines of Python, 445 tests, 2 dependencies, no server process — but it's not running new jobs. The orchestration platform is gone. The same workflow I piloted through that platform runs faster, simpler and with full audit visibility on plain files.
Deleting working infrastructure is a normal part of building. If the abstraction doesn't pay for itself in decisions removed, it's drag. I kept the parts that mattered — the scoring model, the approval gates, the state-from-disk principle — and dropped the layer that didn't.
You can see the receipts for everything I ship at /receipts/.