{"slug": "stuart-feldman-was-right-in-1976-why-your-ai-agent-needs-a-makefile-not-a-20", "title": "Stuart Feldman Was Right in 1976: Why Your AI Agent Needs a Makefile, Not a 20-Step Prompt", "summary": "A developer argues that autonomous coding agents should be structured as dependency graphs rather than linear numbered prompt checklists, invoking Stuart Feldman's 1976 make utility as the model. The writeup contends that 20-step imperative prompts cause attentional degradation and GOTO-style routing failures across long tool-call sessions, and proposes a DAG of verified artifacts — ticket, approved plan, TDD diff, adversarial review, push, CI quiescence, landing — with human airlocks at key gates.", "body_md": "*\"Most of the problems in writing software come from not knowing what depends on what.\"*\n\n— **Stuart Feldman**, creator of `make` (1976)\n\nAlmost everyone starts engineering autonomous coding agents the exact same way: a numbered checklist inside a system prompt or `SKILL.md` file.\n\n```\nStep 1: Pick an open issue from the tracker.\nStep 2: Read the codebase and write an architectural plan.\nStep 3: Pause and ask the human for approval.\nStep 4: Write failing tests first (TDD).\nStep 5: Implement the code.\nStep 6: Run tests and static analysis.\nStep 7: Perform an adversarial self-review.\nStep 8: Rebase on main and commit.\nStep 9: Push and create a pull request.\n...\nStep 17: Triage bot reviews, update documentation, and clean up.\n```\n\nOn paper, it looks wonderfully organized. It reads like a Standard Operating Procedure you would hand to a new human intern on their first day.\n\nAnd yet, in production, it reliably collapses into chaos.\n\nLarge Language Models are probabilistic next-token predictors. A 20-step linear checklist creates a combinatorial explosion of procedural state transitions.\n\nAs the conversation history fills up with compiler logs, test outputs, and git diffs, the model experiences **attentional degradation**. The top of the checklist drifts tens of thousands of tokens into the past.\n\nEven worse is the **Imperative GOTO Trap**. What happens when a test fails at Step 6, or an automated code review bot leaves three comments after Step 9?\n\nThe prompt author starts writing tortured, imperative routing rules:\n\n*\"If a review bot leaves comments after Step 9, jump to Step 12.2. If code edits are needed, go back to Step 5, but do not re-create the branch from Step 1, then proceed to Step 8, but do not create a new PR, just push with lease, and return to Step 12.4...\"*\n\nLLMs cannot reliably simulate an imperative virtual machine with nested loop counters and conditional `GOTO` jumps across 150 tool turns. They lose their place, skip intermediate gates, or hallucinate an exit condition out of sheer contextual fatigue.\n\n``` php\nflowchart TD\n    S1[\"Step 1: Pick Issue\"] --> S2[\"Step 2: Write Plan\"]\n    S2 --> S5[\"Step 5: Code & Test\"]\n    S5 --> S9[\"Step 9: Open PR\"]\n    S9 -->|\"Bot comment?\\nJump to Step 12.2\"| S12[\"Step 12.2: Triage Bot\"]\n    S12 -->|\"Needs code edit?\\nGo back to Step 5\"| S5\n    S5 -.->|\"Positional blur!\\nSkips Step 7 review\"| S17[\"Step 17: Merge Unreviewed Code 💥\"]\n```\n\nWhat happens when an agent opens a pull request, pauses while CI runs, and you wake it up two hours later with: *\"CI failed on the widget test and the review bot suggested a refactor\"*?\n\n`Step 1: Pick an open issue` at the top of its skill file and starts hallucinating, asks which ticket to work on, or restarts archaeology from scratch.`make` Was Never Just for C Files\nIn 1976 at Bell Laboratories, Stuart Feldman solved this exact systems problem: **dependency tracking and state reconciliation**.\n\nFeldman didn't write an imperative shell script that said:\n\n*\"First compile `foo.c`, then compile `bar.c`, then link them into binary `baz`.\"*\n\nHe realized that imperative build scripts are brittle because they fail to model the underlying structure of reality:\n\n`make` does not care about step numbers. It cares about the **Directed Acyclic Graph (DAG)** of dependencies.\n\nAn autonomous AI coding agent's workflow is not a procedural script. **It is a Directed Acyclic Graph of physical software artifacts and verified invariants.**\n\n``` php\nflowchart TD\n    T1[\"1. ticket-assigned\"] --> T2[\"2. approved-plan\\n(Human Plan Airlock)\"]\n    T2 --> T3[\"3. implementation-diff\\n(Red-Green TDD)\"]\n    T3 --> T4[\"4. approved-adversarial-report\\n(6-Pillar Critic = 0 Blockers)\"]\n    T4 --> T5[\"5. commit & push\\n(Human Git Airlocks)\"]\n    T5 --> T6[\"6. ci-quiescent & all-bots-triaged\"]\n    T6 -.->|\"Bot finding or edit dirties tree:\\nPrerequisite automatically invalidated\"| T3\n    T6 --> T7[\"7. land\\n(Human Landing Airlock)\"]\n```\n\nInstead of 20 fragile numbered steps, the entire lifecycle of software engineering can be expressed as a declarative Makefile DAG inside the agent's skill definition, where every human checkpoint and quality bar is a distinct target with bounded prerequisites:\n\n```\n.PHONY: finish land ready-to-land ci-quiescent push commit pre-commit-clean \\\n       approved-adversarial-report adversarial-review implementation-diff \\\n       approved-plan researched-ticket ticket-assigned review-ready ship fast-track\n\nfinish: land codified-scars-consolidated pristine-workbench\nland: ready-to-land human-landing-approval\nready-to-land: ci-quiescent changelog-updated\nci-quiescent: push ci-remote-green all-bots-triaged\npush: commit human-push-approval\ncommit: pre-commit-clean human-commit-approval\npre-commit-clean: approved-adversarial-report clean-static-analysis doc-audit-complete\napproved-adversarial-report: adversarial-review triaged-blockers human-review-approval\nadversarial-review: implementation-diff\nimplementation-diff: approved-plan tdd-failing-repro human-diff-approval\napproved-plan: researched-ticket human-plan-approval\nresearched-ticket: ticket-assigned candidate-scars git-archaeology\nticket-assigned:\n```\n\nWhen you dispatch an agent on a fresh ticket, the top-level goal is always the same:\n\n```\nmake finish\n```\n\nEvaluating the graph backward from `finish` to the deepest unsatisfied leaf immediately induces the exact execution trajectory:\n\n```\nticket-assigned → researched-ticket → approved-plan → implementation-diff → ... → finish\n```\n\nWhy can't we simply attach all prerequisites onto a single target line like this?\n\n```\n# ❌ THE PREREQUISITE DILUTION TRAP (5 prerequisites on one line)\nland: push ci-remote-green all-bots-triaged changelog-updated human-landing-approval\n    gh pr merge --squash\n```\n\nIn classical GNU Make, a target with ten prerequisites executes deterministically from left to right because a C program uses a hard CPU loop counter.\n\nAn LLM is not a C program. It is an autoregressive transformer governed by self-attention weights and predictive momentum.\n\nEmpirical field testing across 143 production tickets revealed a universal cognitive hazard we codified as **The Prerequisite Dilution Trap** (`SCAR-PROC-91`):\n\n`push` → `ci-remote-green` → `all-bots-triaged` → `changelog-updated`), the conditional probability of continuing without stopping approaches `1.0`. The fifth item (` human-landing-approval`) gets swept along as a rhetorical checkbox rather than an immovable barrier, tempting the model to merge the PR unilaterally without asking the human.`7 ± 2` chunks, which compresses to `3 ± 1` in dense tool-calling contexts), an agent cannot simultaneously verify four repository states while keeping sentinel attention on a hard stop condition.`int index = 3;`), a transformer has no internal integer register. It resolves pairwise binary dependencies (`A` before `B`) with near-100% reliability, but tracking its ordinal spot inside a 5-item list degrades into positional blur once terminal logs fill the context window.\nTo eliminate prerequisite dilution, every Makefile target in an agent workflow must obey the **Bounded Fan-In Invariant**:\n\n```\n1 <= |Prerequisites(Target)| <= 3\n```\n\nEvery privileged human checkpoint (`approved-plan`, `commit`, `push`, `land`) is factored into an irreducible **Atomic Barrier Tuple** with strictly **two** prerequisites—a composite readiness target and the explicit human approval gate:\n\n```\naction-target: ready-state human-approval\nphp\nflowchart TD\n    P1[\"ci-quiescent\\n(Checks Green + Bots Triaged)\"] --> R[\"ready-to-land\\n(1. Mechanical Readiness Target)\"]\n    P2[\"changelog-updated\\n(CHANGELOG.md Verified)\"] --> R\n    R --> L[\"land: gh pr merge --squash\\n(2. Atomic Human Barrier Tuple)\"]\n    H[\"human-landing-approval\\n(STOP & Wait for User)\"] --> L\n```\n\nUnder this two-prerequisite topology, the agent's decision at the airlock is strictly binary:\n\n`ready-to-land` physically satisfied? `tool_calls: []`). Present the status and wait for the human.\nBy factoring wide prerequisite lists into shallow 2-to-3 item sub-targets, human approval gates become impenetrable Dijkstra barriers.\n\nWatch how a Makefile DAG eliminates every `while` loop, retry counter, and conditional `GOTO` from your prompt:\n\n```\nSatisfied(target) ⇔ (∀ p ∈ Prerequisites: Satisfied(p)) ∧ Invariant(target) == true\n```\n\n`ci-quiescent`, and an automated review bot posts a legitimate bug finding on GitHub. You do not need a prompt rule saying `commit`, `approved-adversarial-report`! The DAG automatically routes the agent back through the local Adversarial Critic (`adversarial-review`) before it can re-commit and re-push.` git status`, `gh pr checks`, test exit codes). So long as a prerequisite is dirty or missing, its recipe runs. Once all prerequisites hold, the target settles into its fixed point.`O(1)`\nHow does a Makefile-driven agent know where to pick up when you drop into a branch mid-flight—or after a break?\n\nInstead of relying on conversational memory, the agent runs the **Session Frontier Resolution Oracle**: it inspects the physical state of the repository and GitHub forge to locate the deepest unsatisfied prerequisite of `make finish`:\n\n| Physical Git / Forge State | Resolved Active Target | Natural Operator Prompt | \n|---|---|---|\n| PR open with unaddressed bot comments or red CI | `ci-quiescent` | *\"Triage the bot review\"* | \n| PR open, all checks green, bots quiescent | `land` | *\"Land it!\"* | \n| Committed locally on feature branch, not yet pushed | `push` | *\"Push and open the PR\"* | \n| Clean static analysis + approved critic report | `commit` | *\"Commit this\"* | \n| Implementation diff passing tests, unreviewed | `adversarial-review` | *\"Run the critic\"* | \n| Approved `plan.md` on disk, no code changes yet | `implementation-diff` | *\"Proceed with the plan\"* | \n| Clean working tree on `main` | `ticket-assigned` | *\"Let's run with #321!\"* | \n\nYou never have to tell the agent which step number it is on. The filesystem and git graph *are* the state machine.\n\nNot every task needs a full zero-to-merged autonomous run. Just like a real `Makefile`, our workflow exposes ergonomic meta-targets:\n\n`make finish`` ticket-assigned`) all the way through PR merge (` land`) and post-mortem scar extraction (` codified-scars-consolidated`).` make review-ready``make ship`` pre-commit-clean`, runs the critic and static analysis, commits, pushes, triages CI, and lands.`make fast-track`\nWhy does this work so dramatically better than natural-language checklists?\n\n`Makefile` s, `BUILD` files, and dependency graphs during pre-training. The syntax `target: prerequisite-a prerequisite-b` activates deep, structural dependency-resolution circuits in the model's weights that prose bullet lists never touch.`SCAR-PROC-84`)`|ActiveTargets(t)| == 1`). Even if an eager human types `human-push-approval` after showing the commit hash.`self_critical_review.md` does not exist on disk with `VERDICT: APPROVED (0 BLOCKERS)`, the prerequisite for We have now battle-tested this Declarative Makefile DAG across **143 production tickets** (`101` open-source framework tickets in `BlocSignal` and `42` commercial enterprise monorepo tickets) backed by **450 codified Synthetic Scars**:\n\n`N_nudge = 0`)\nStop writing 20-step natural language essays to herd your coding agents. Stuart Feldman solved dependency orchestration at Bell Labs in 1976. Give your agent a `Makefile`.\n\nWait—what happens when a massive, 5-round architectural ticket runs for **579 steps**, crosses **230,000 tokens**, and the host IDE fires **automatic context compaction** twice in the middle of your Makefile DAG?\n\nIn **Part 3.7**, we will look at how another classic Unix invention—** 1983 SysV `init.d` lexical runlevel files** combined with Christopher Nolan's *Memento* tattoo protocol and `fork()`/` wait()` subagents—lets an AI agent survive mid-flight context compaction with **zero lost invariants and zero repeated steps**.\n\n*(Want to inspect the live Declarative Makefile DAG and modular reference files right now? Check out [Randal's Public Workflow Gist](https://gist.github.com/RandalSchwartz/598a1f2b5760a23c1d70b57e9e85393f).)*\n\n`init.d` and \"Memento\" Made My AI Coding Agent Immune to Context Compaction\nDrop your thoughts in the comments below: have you watched an AI agent lose its place inside a long numbered prompt checklist? What happens when you switch from procedural step lists to declarative dependency graphs?", "url": "https://wpnews.pro/news/stuart-feldman-was-right-in-1976-why-your-ai-agent-needs-a-makefile-not-a-20", "canonical_source": "https://dev.to/gde/stuart-feldman-was-right-in-1976-why-your-ai-agent-needs-a-makefile-not-a-20-step-prompt-5bn2", "published_at": "2026-10-09 00:40:57+00:00", "updated_at": "2026-10-09 00:48:30.304809+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "large-language-models", "mlops"], "entities": ["Stuart Feldman", "make", "Bell Laboratories"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/stuart-feldman-was-right-in-1976-why-your-ai-agent-needs-a-makefile-not-a-20", "markdown": "https://wpnews.pro/news/stuart-feldman-was-right-in-1976-why-your-ai-agent-needs-a-makefile-not-a-20.md", "text": "https://wpnews.pro/news/stuart-feldman-was-right-in-1976-why-your-ai-agent-needs-a-makefile-not-a-20.txt", "jsonld": "https://wpnews.pro/news/stuart-feldman-was-right-in-1976-why-your-ai-agent-needs-a-makefile-not-a-20.jsonld"}}