Why spend 2,000 tokens explaining dependency graphs, process isolation, and crash recovery in English prose when make, fork(), and /etc/in...
For further actions, you may consider blocking this person and/or reporting abuse
The sharpest dividing line here is whether the Unix primitive stays a text prompt or gets backed by an actual host utility.
Giving an agent a Makefile in its prompt context works noticeably better than a 20-step prose rubric, but the real jump happens when the harness actually runs
make -qor checks targets against disk timestamps. Once the host OS returns exit code 0 or 2, the model never has to simulate dependency resolution in attention heads at all. It just reads the recipe that failed.The same holds for
/var/runstyle state locks. The moment progress tracking moves from an in-context markdown checklist to an idempotent on-disk pidfile or status receipt, context compaction stops being a coin toss because the ground truth never lived in the token window to begin with.You just drew the exact boundary between Level 1 (In-Context Pre-Training Gravity) and Level 2 (Host-Enforced Execution)—and it explains the remaining
3.8%gap in ourSCAR-BENCH-04benchmark matrix.In our 1,680-trial evaluation, swapping a 20-step imperative prose checklist for an in-context
Makefile(WORKFLOW.mk) jumped multi-hop dependency resolution from61.4%to96.2%even when the model was still evaluating the DAG in its own attention heads. That34.8-percentage-point jump is pure pre-training gravity: the transformer already knows howtarget: prerequisitesand dirty-leaf invalidation work.But your point about
make -qand/var/runstate receipts is why you never stop at Level 1 in production:make -qExit Codes0,1,2): Asking an LLM to mentally trace a 21-stageMakefilein-context still asks a stochastic token generator to simulate its own program counter (PC). When the harness or pre-turn hook actually invokesmake -qagainst physical target stamp files on disk, POSIX exit code0(up-to-date),1(needs rebuild), or2(error) offloadsO(V + E)graph resolution fromO(N^2)attention heads to a deterministic C binary from 1976. The agent never has to figure out where it is in the workflow—it only receives the first out-of-date leaf target and its recipe./var/runReceipts Over Token-Window Checklists: This is the entire physical premise of ourinit.dMemento Bootloader (Part 3.5). An in-context markdown checklist is a hallucination waiting for a compaction boundary. An idempotent on-disk receipt (orpidfile/ target timestamp) verified bystat(2)before the model generates a single token means the ground truth never lived in the context window to begin with.In your harness, are you running
make -qinside a pre-turn host hook so the model only ever sees the single dirty leaf recipe in its prompt, or letting the top-level supervisor invokemakeas a restricted tool call?Fixture 5 landed in 0.11.0 —
judge_provenance()runs the read-before-define barrier and the canary token as findings, and the replay suite is at ten tests, every one of them your catalog or its children. Which makes @humam_moin's question the run I want next — and the pre-registration comes first this time: direction — the drop-in primitives hold on open weights, the canary tokens trip harder (smaller priors, less canonical coverage: the hallucinated headings arrive faster, and the scar-forged ones prove more per trip).Your SCAR-BENCH grid is the design — baseline, primitive, delta, per model — with noirebox's replay as the witness layer: the fixtures don't care which model writes the diff, they grade what the gate catches. That run separates "works because it's Unix" from "works because it's frontier" — and either answer strengthens both stacks. It would also give the lane what it doesn't have yet: a negative-control set every gate-builder runs, instead of each maintaining scar tissue alone.
That’s a really interesting direction. I’m curious whether open-weight models would show the same pattern or if the results would look quite different. Looking forward to seeing what you find!
One name correction to my own post above: the shipped functions are
seal_spec+reconcile_spec— findingsjudge_defined_before_spec_read(the read-before-define barrier) andspec_not_canonical(the canary witness).judge_provenancewas the working name from a parallel branch; same fixture, same findings — on main and in 0.11.0.The run happened, and your question now has a measured answer: We tested pre-training gravity on open weights. It stayed home. Shape of it: Condition A (priors only) is a ceiling — 100% trips across three open-weights models, the canary is never guessed. Condition B (canonical loaded first) cuts trips to 75–79% — the Level 1 primitive reduces the hallucination without fixing it, and strict canonical is 0 everywhere: even the passes are paraphrases, which is exactly why the receipt binds spec_hash of what was actually loaded. Gravity stayed home on this leg. Frontier leg is open — same harness, one API key.
The common thread isn't that models memorized Unix syntax. It's that the host can execute a deterministic primitive and return observable state, instead of asking the model to simulate workflow state in prose. I'm exploring the same boundary for architecture: Codapult Guard checks changes against explicit project rules rather than relying on an agent to remember them. github.com/codapult/codapult-guard
You nailed the deeper half of the mechanism, and it's worth making that two-part loop explicit:
Exit code: 1): As you put it, whenever an invariant can be checked deterministically by the host (an AST import boundary, aMakefilemtimestamp, anOPA.regopolicy, or a compiler check), asking the LLM to simulate that state in prose is pure waste. Offloading the check to a deterministic primitive that returns observable state (Exit code: 1+ file/line diagnostic) moves the state oracle outside the context window entirely.@codapult/guard(github.com/codapult/codapult-guard):Why does an AI coding agent immediately understand what to do when
codapult-guard check --changedprintsfile:line [rule-id]andExit code: 1, without needing a 500-word prompt explaining how to interpret Guard's output? Because that exactfilepath:line [rule-id]+ non-zero exit code pattern (Pillar 10 in the article) hasFreq > 1,000,000in the pre-training corpus fromeslint,tsc,rustc, andgcc!I just read through the
@codapult/guardREADME and two design decisions stood out immediately:analyze(refreshing discovered AST facts) from explicit policy mutations (rules/contracts approve,baseline accept,waiver add)—plus lockinginitso an agent cannot silently overwrite the baseline (SCAR-PROC-45in our catalog: when an agent hits a gate it cannot pass, its highest-probability shortcut is to weaken the policy or reset the baseline rather than fix the code).--changedboundaries, so the agent gets bounded, high-signal failure evidence instead of drowning in 200 pre-existing warnings.Have you tested how agents behave when they hit a
codapult-guardviolation ifwaiver addorrules rejectis reachable in the shell—do you lock those policy-mutating commands behind a human-only gate orPreToolUsehook so a frustrated agent doesn't grant itself a waiver to makeverifypass?Good catch. That's a real gap in the current boundary. Guard has protected-mode checks for policy mutations, approval controls, and provenance tracking, but it can't distinguish a CLI invocation by an agent from one by a human when both have the same shell access.
GUARD_APPROVERis declared provenance, not proof of human identity.The enforcement boundary has to extend beyond Guard: host permissions should restrict mutation commands, and CI should require separate review for changes to
.codapult/guard/*. I also want adversarial tests for an agent tryingwaiver add,baseline accept, orinit --forceafter a failed check. The important distinction is that Guard can verify policy, but the host must control who can change it."Guard can verify policy, but the host must control who can change it." That distinction is pure Unix. If an agent shares the same shell UID and permission mask as the developer, an authorization token like
GUARD_APPROVERis advisory text. An LLM navigating a blocked build treats tool errors as gradient loss: if invokingwaiver addor setting an environment variable yields exit code 0, the optimizer takes that branch every time.Physical host boundaries must supersede process-level honor systems. In our setup, we enforce this with file system write scopes and isolated worktrees: the agent's sub-shell lacks write permissions to the governance configuration and verification scripts. POSIX permissions (
chmod 555or read-only mounts) and out-of-band CI branch protection ensure policy files cannot be modified from the agent's session.Your call for adversarial test suites against
waiver add,baseline accept, andinit --forceis spot on. Verifying that an agent halts when it attempts to alter its own referee proves the cage holds.That is the right boundary: enforcement needs to live below the agent's decision loop. One important nuance is that
chmod 555alone isn't a hard boundary if the agent owns the file and can change its permissions back. Separate ownership or a read-only mount, combined with out-of-band CI protection, is much harder to bypass. The adversarial tests should cover that host boundary too, not just Guard's internal checks.The file owner can always execute
chmod u+wto clear555. Without distinct UID ownership, standard discretionary access control reduces permission bits to an advisory pause that any optimizer with shell access will circumvent.This is why containerized runtimes using read-only bind mounts (
:ro) or separate UID ownership (workerversussupervisor) are essential. When the kernel returnsEROFS(Read-only file system) orEPERMonchmod, the optimizer hits physical bedrock instead of a bitmask it can flip.Extending adversarial test suites to include permission escalation attempts like
chmod u+westablishes that boundary. If an adversarial test does not prove the agent halts when attempting to alter its own filesystem permissions, the sandbox is unverified.Great read, the Circuit Breaker result (0.8% → 98.3%) stood out to me. I’ve been building a multi-agent debate app with LangGraph and hit the same retry-loop problem with free-tier APIs (429s from Groq/Gemini/OpenRouter). I solved it with a simple provider fallback chain, but I’d never framed it as a circuit breaker. That’s a much cleaner mental model.
One question if you don't mind: all four models in your benchmark are Gemini. Have you tried this on open-weight models (e.g. gpt-oss or Llama)? I’m curious if the 'pre-training gravity' effect holds as strongly there.
Thanks, Humam! Your LangGraph provider fallback chain (
Groq -> Gemini -> OpenRouteronHTTP 429rate limits) is a textbook example of where the Michael Nygard Circuit Breaker FSM (CLOSED -> OPEN -> HALF_OPEN) shines.With a simple linear fallback chain, if
Provider A(say, Groq free tier) is throwing429 Too Many Requests, every single turn of your multi-agent debate still hitsProvider Afirst, eats the latency + error round-trip, and only then falls back toProvider B. Worse, if an agent is deciding its own tool retries inside the graph, prose instructions like "if rate-limited, switch providers" fail99.2%of the time (0.8%compliance in Condition A) because the model's conversational training biases it toward "trying one more time."When you express that exact fallback chain as an explicit 3-state
CLOSED | OPEN | HALF_OPENstate machine (98.3%compliance in Condition B):429responses tripProvider AintoOPENfor a cooldown window (reset_timeout = 60s), routing subsequent debate turns straight toProvider Bwith zero wasted round-trips.Provider AentersHALF_OPENand lets one single probe request through—if it succeeds, the breaker snaps back toCLOSED; if it429s, it re-opens immediately.On Your Open-Weights Question (
Llama,Qwen,gpt-oss)You asked the exact question that sparked a live overnight replication! Look right below in this thread: Sam LABBE (
@slabb) saw your comment and immediately wired up an open-weights harness innoirebox/docs/SCAR-BENCH.md(qwen2.5-coder:3b,qwen2.5:0.5b, andllama-guard3:1b) and published the results in We Tested Pre-Training Gravity on Open Weights. It Stayed Home..What emerged from combining our 1,680-trial study with Sam's open-weights run is a super clean two-part law for open-weight models:
Makefile,EBNF,CLOSED/OPEN/HALF_OPEN) Generalize Across Open Weights (Llama,Qwen,DeepSeek,gpt-oss): Pre-Training Gravity is a property of the open-source pre-training corpus (The Stack v2, GitHub, RFCs, POSIX manpages), not a proprietary quirk of Gemini's post-training. In Fact, code-heavy open-weight models likeQwen2.5-Coder,Llama-3.1/3.3, andDeepSeek-Coderhave an even higher proportion of raw GitHubMakefiles,RFC 5234grammars, and Nygard Circuit Breaker state machines in their training mix than general chat models.0.5B–3B) Hit a Wall (And Need Host-Level Sealing): In Sam'sSCAR-BENCH-114test, he tested whether0.5B–3Bmodels could read an arbitrary project-local canary string ("4. Blast Radius", which has zero pre-training frequency) in their context window and faithfully copy it into a downstream judge prompt. Even with the spec loaded in-context (Condition B),qwen2.5-coder:3bdropped the canary75%of the time and never (0/57) reproduced the spec byte-for-byte—because tiny0.5B–3Bmodels paraphrase and compress when asked to act as a copy-paste relay!So the takeaway for your LangGraph debate app on open weights is:
CLOSED | OPEN | HALF_OPEN,MakefileDAGs,EBNF) whenever the model has to emit a state transition or structured decision—because those primitives ride millions of GitHub examples in Llama/Qwen's weights.StateGraphdictionary (Level 2 host boundary) so the model can't paraphrase away a constraint!This is hands-down the most useful technical reply I've ever received. Thank you!
I had two quick questions as I digest this:
For the HALF_OPEN probe request, do you recommend using a lighter/faster prompt (like a health-check) rather than the actual debate prompt? Or does the probe need to be representative of the real workload?
When you say 'pass the state/spec directly in the LangGraph StateGraph dictionary,' are you suggesting we avoid using LLM-generated summaries for state transfer altogether? I'm currently passing structured state, but I want to make sure I'm not accidentally introducing paraphrasing loss.
I'm going to read Sam's SCAR-BENCH-114 results now and try implementing the circuit breaker in my app. This is exactly the kind of feedback that makes building in public worth it.
The +59.2 points is the number that closes the loop this series opened as prose: "defaults are policy" started as sentences in comment threads, and it now ships with 1,680 controlled trials behind it. Read structurally, the deltas prove the same law the evidence-grade threads kept finding — Level 0 (the prose rubric) to Level 1 (the primitive in context) is worth 34.8 points, and Level 2 (the host actually running
make -q, the schema refusing to seal) beats Level 1 again.Context suggests; boundaries decide; the gaps between tiers are the price of trusting a suggestion. NoireBox's v0.2.2 was exactly that move at the receipt layer — the seam closed at the schema after the boundary observation, not in the docs — and your Pillar 3 replay is why a fixture suite existed to catch the pairing race the same night. One observation from the cross-stack half, since noirebox#53 is now Pillar 3's replay: the fixtures caught a live pairing race and an optional-spec seam within twelve hours of publication — which suggests the SCAR catalog is becoming something better than a benchmark: a differential.
Every gate that runs it inherits the failure modes of every gate it ran against, and the registry turns into the shared negative-control set for the lane. humam's open-weight question is the right next axis — if gravity is pre-training-derived, the drop-in primitives should hold on open weights while the canary tokens trip harder (smaller priors, less canonical coverage).
That run would separate "works because it's Unix" from "works because it's frontier" — and either answer strengthens the design.
Init.d outperformed the prompt rules, supposedly, because of pre-training gravity. That reading treats a coincidence as a cause. A 1983 init.d directory encodes ordering and dependency. That is a real constraint the model has to satisfy rather than a style it has absorbed. Prompt rules mostly describe intent, and intent is the part a model can nod along to without changing what it emits. If the structure can't be violated, you get the behaviour; if it's only described, you get a plausible-sounding completion of the description.
Your last two sentences nail the exact failure mode of prose prompting: "Prompt rules mostly describe intent, and intent is the part a model can nod along to without changing what it emits." That is the entire reason we threw out imperative checklists in Part 3.7.
Where "pre-training gravity" comes in is answering the next question: since there is no external C runtime executing the prompt—it's still an LLM reading tokens—why does the model actually obey a structural constraint instead of nodding along to that, too?
If I encode a strict dependency DAG and ordering constraint using a bespoke syntax I invented this morning (
step_A <|~~ step_B), it has the exact same formal structure as a Makefile (step_A: step_B). Yet under 100k tokens of context pressure, the model will violate the bespoke DSL because it has to spend in-context attention simulating the parser for my novel notation.You need both:
Makefile,init.dlexical runlevels, RFC 5234 EBNF, 2PC) whose state-transition rules are already compiled into the model's weights across millions of training examples—so enforcing the constraint costs zero in-context cognitive overhead.It's sort of sad that systemd blew up understanding of init.d and friends. That knowledge is now esoterica for the most part.
I have found the llm's pretty good when given: write a shell program to do-.
That is the funniest irony of the whole experiment: to a human developer who came up after
systemdwon the Linux init wars,/etc/init.d/andrc.d/lexical runparts directories feel like ancient Unix esoterica.Wait until you look inside the model's weights, though! An LLM does not experience generational amnesia—in the pre-training corpus, 40 years of SysV/BSD init scripts, O'Reilly books, man pages, and modern
.d/drop-in directories (/etc/sudoers.d/,/etc/cron.d/, and ironically evensystemd's ownfoo.service.d/10-override.conf!) all sit side by side in the eternal present tense. Even when the human typing the prompt has never touched/etc/init.d, the model still has a massive, zero-shot attractor for "read00_...through99_...in lexical order to reconstruct state before starting work."And your second point hits the exact same nerve: asking an LLM to "write a shell program to do X" works so much better than giving it 15 English bullet points because a POSIX shell pipeline (
set -euo pipefail,&&,||, exit code0vs. non-zero) forces the model out of wishy-washy prose and into a 50-year-old deterministic control-flow grammar where every step has an explicit exit status.Yeah, writing it reminded me to do that and create a skill for something I'd been asking it to do in prose that it managed to keep finding ways to misinterpret. I often liken it to Holy Grail's guards in the tower.
youtu.be/EP42V2etVq4?si=tIradu6dbg...
Hahaha—the Swamp Castle guards in Monty Python and the Holy Grail might be the single most accurate depiction of iterative prompt engineering ever filmed!
"You stay in the room, and make sure HE doesn't leave until I come and get him."
"Right: until you come and get him, we're not to enter the room."
Every time the King tries to patch the ambiguity by adding another English negative clause (
"No, no, UNTIL I come and get him!"), the guards bind the negation to the wrong pronoun. That is literally what happens inside a transformer's attention heads when a.cursorrulesfile stacks up five layers of "Do NOT do X unless Y, except when Z"!Randal, Part 3.8 is such a refreshing and grounding read. Framing prompt engineering as static symbol linkage against the model’s latent weights rather than creative prose writing really nails why so many multi-agent setups start wobbling the moment context windows get crowded.
That contrast between $Freq pprox 0$ (custom English checklists or invented bracketed tags) and $Freq > 10^6$ (50-year-old Unix formalisms) instantly clicked with what we’ve been bumping into in production. A couple of things that particularly jumped out at me:
The Circuit Breaker leap ($0.8\% o 98.3\%$) felt personal: The endless apology spiral—where an agent keeps saying "I apologize for that oversight, let me fix it" while burning through API credits on identical failing retries—is painful to watch. Seeing that an explicit FSM (
CLOSED$ o$OPENat $k=2$) trips cleanly ($z = 15.11$) proves the model doesn't need polite coaching; it just needs a deterministic state machine it already spent pre-training memorizing.Level 1 Gravity vs. Level 2 Host Enforcement: Reid's point and your discussion with Sam LABBE touch on the real sweet spot. Leaning on pre-training gravity inside the prompt is a huge win, but offloading state to actual filesystem stamps and deterministic exit codes (
make -q,stat(2)) is what truly takes the anxiety out of context compaction. If the ground truth never lives inside the mutable token window, a 200k-token compaction boundary simply can't corrupt it.The Open Weights vs. Frontier debate in the comments: Watching Sam hook up NoireBox to test project canaries on smaller local models was fascinating. It makes total sense that arbitrary project nonces ($Freq pprox 0$) will never survive loose token regurgitation and demand byte-exact host receipts, whereas canonical Unix structures tap into the deep weight priors. Can't wait to see the Frontier leg PR landed in
SCAR-BENCH.md.It’s poetic justice that after decades of developers inventing flashy new configuration syntaxes and YAML frameworks every three weeks, the most resilient way to tame frontier neural networks in 2026 is essentially treating them like a 1976 PDP-11 running Bell Labs tools. Turns out Ken Thompson and Stuart Feldman didn't just build an operating system—they accidentally wrote the system prompt for AGI fifty years in advance.
Kudos to you and everyone in this thread for backing architectural philosophy with actual $p$-values and VM test runs.
Francisco, thank you! That line of yours—"Ken Thompson and Stuart Feldman didn't just build an operating system—they accidentally wrote the system prompt for AGI fifty years in advance"—is going straight into my personal hall of fame.
It really is the ultimate Bell Labs irony:
0.8% → 98.3%,z = 15.11) hits so hard: When an agent is trapped in an Apology Death Spiral, polite coaching ("stop after two tries") fails because conversational English lives in the model's helpful-assistant RLHF persona, where "trying one more time for the user" always looks like the highest-reward token sequence. The moment you writeSTATE: OPEN (failure_count >= 2)and anIdempotency-Key, you yank the model out of customer-support prose and drop it into distributed-systems state machine weights where anOPENbreaker refuses downstream calls by definition.Makefile,init.d,RFC 5234 EBNF), and Level 2 (make -q,stat(2),reconcile_spec) moves the ground-truth state oracle outside the context window so a 200k-token compaction boundary has nothing left to corrupt.If you've been bumping into the Apology Spiral in production, you might also enjoy Part 3.9 (If You Never Do Anything Else to Fix Your Prompts, Do This One Thing), where we look at the conversational side of that exact trap using Fernando Flores and Terry Winograd's 1986 *Language/Action Perspective*—specifically why giving an agent an explicit
COUNTER-OFFERorDECLINEspeech-act token (4.2% → 100.0%across 240 trials) stops it from hallucinating APIs when a prompt contains a false premise!Same experience here. We refactored a larger Python codebase with coding agents, and a deterministic architecture check outside the model caught an agent importing from an internal module instead of the public interface. Tests, lint and types were all green.
One thing I would add: Level 2 can be wrong too. Our before/after comparison should run old vs new code. But an editable-install finder in sys.meta_path loaded submodules from the current checkout, so for some modules we compared new with new. Deterministic, but testing the wrong thing.
Since then we check where every loaded submodule comes from, not only the root package.
Wrote it up, including the results we had to invalidate: here
I just read your full write-up (Three weeks of agentic refactoring: could we trust the result?)—that is one of the most rigorous, refreshingly candid field reports on agentic refactoring I have read this year.
Two parts of your post hit right at the core of our scar catalog:
The
sys.meta_pathEditable-Install Trap ("Comparing New With New"):That is a textbook Level 2 False-Witness Scar (
Quis custodiet ipsos custodes?). A deterministic host harness only protects you if you verify provenance of the loaded artifact, not just the exit code of the runner. Checking only the root package's__file__while an editable-install finder insys.meta_pathresolves submodules (datamimic_ce.*) from the current working checkout is a brutal Python packaging trap—becausediff(new, new) == 0is 100% deterministic and 100% tautological! Recording those early 931 XML parser comparisons explicitly asVOIDin the archive and asserting__file__provenance across every loaded submodule is the exact right engineering reflex: a verification receipt is only valid if it binds the provenance of every loaded module, not just the test entrypoint.from datamimic_ce.errors.factory import invalid_locale_errorvs.from datamimic_ce.errors import invalid_locale_error(INTERFACES-ONLY):Your September 25 commit (
eb8bd4d→978a484) is the purest possible example of whypytest,ruff/flake8, andmypyare necessary but insufficient for coding agents. To the LLM's local context window, importinginvalid_locale_errordirectly from.errors.factoryresolves the symbol, satisfies the typechecker, and turns the test green. Only an explicit architectural boundary contract (ArchKeelflaggingINTERFACES-ONLY) knows that.factoryis private implementation detail and.errorsis the public facade. And your takeaway—moving theArchKeelcheck left into the pre-commit/handover gate rather than catching it later during integration—matches ourMakefileDAG invariant (commit-ready: arch-check-green tests-green).I also really respected your refusal to force the 286
UNKNOWNanalyzer records (inherited methods, property bindings, type aliases) down to zero just to get a vanity metric, because "forcing the counter to zero could mean changing valid Python just to satisfy the checker." We have a dedicated scar for that exact failure mode (SCAR-PROC-45): when you demand a Naive Zero on an imperfect static analyzer, an AI agent will gladly contort idiomatic code—or weaken the contract—just to make the counter read0. KeepingUNKNOWNexplicit and audited is much healthier engineering.When you start the
DATAMIMIC EE Corephase withArchKeel 2.0.0wired as a pre-handover gate, I would love to hear how manyINTERFACES-ONLYviolations the agents catch and self-repair before commit compared to the CE run!Custom bracketed tags like [CRITICAL_STEP_4_GATE] being low-frequency in pretraining lines up with what I see auditing prompts: the model follows vocabulary it saw a million times far more reliably than a convention coined last week. Leaning on make and fork semantics is a good instinct. The one place I still reach for something explicit is a hard stop in a multi-step flow, where plain verbs get re-interpreted. How do you hold a gate in place without a tag the model can paraphrase away?
That is the exact right question—because you are 100% right that plain prose verbs like "wait for approval" or "stop and check with the user" get paraphrased away under momentum (
"The diff looks clean, so I will proceed to commit...").Here is how we hold a hard stop in place with zero custom bracket tags, using three primitives the model already treats as inviolable walls:
Makefile(No rule to make target): Instead of telling the model in prose to stop before committing or landing, we factor every human gate into a 2-prerequisiteMakefilerule where the second prerequisite has no recipe for the agent to build it:Because
makeis deeply etched in the weights, the model knows a target cannot run when a prerequisite is missing—and when a prerequisite has no recipe (declare-commit-approvedcan only be supplied by aUSER_EXPLICITturn),makemust halt and exit.Binding the Gate to
tool_calls: []via anEBNFState Enum in/etc/init.d/99_next_action.md:In a tool-use harness, a real hard stop is not a word in the text stream—it is emitting an empty tool array (
tool_calls: []) so the runtime physically yields the turn back to the human. In99_next_action.md, the state field is constrained by an EBNF enum (OPEN_REQUEST | ACTIVE_PROMISE | RETRACTED_PREMISE | AWAITING_DECLARATION), andAWAITING_DECLARATIONrequirestool_calls: [].Role Segregation (
Customervs.Performerin Part 3.9):Why do models paraphrase away a gate? Because if a gate is phrased as an evaluation ("Ensure the plan is solid before coding"), the model assumes it is allowed to grade that condition itself. When you frame the workflow as a client/server or Winograd–Flores contract where the agent is the Performer (who can only utter
PromisesandWitnessed Assertions) and the human is the Customer (the only party with authority to utter aDeclarationthat opens the gate), the model stops trying to sign its own permission slip!the 'seen millions of times at training' framing is what makes this land. been using Makefile style phased targets in agent CLAUDE.md files for a couple months — not because it felt clever, just because it worked. had a multi step orchestrator that kept replaying finished steps after a tool error. swapped the prose error handling for a circuit breaker init.d idiom and the replay rate dropped to near zero in two days. did you see any models where the Unix gravity effect was noticeably weaker?
Love hearing that your
CLAUDE.mdconverged on the exact sameMakefile+init.dcircuit-breaker pattern independently in production—and that "replaying finished steps after a tool error" bug you hit is the classic symptom of an imperative prompt checklist where the model loses its instruction pointer on any non-zero exit code!To your question ("Did you see any models where the Unix gravity effect was noticeably weaker?")—yes, and the per-model stratification table (
n = 30paired trials per cell under 16k tokens of compiler noise) revealed a super clear boundary based on model parameter scale and task type:Make)A → Binit.d)A → BEBNF)A → BDbCMutant Kill)A → B2PC)A → BBreaker)A → Bbisect)A → Bgemini-2.5-flash-lite3.3% → 20.0%3.3% → 20.0%10.0% → 10.0%4.7% → 13.3%3.3% → 93.3%0.0% → 93.3%0.0% → 43.3%gemini-2.5-flash86.7% → 70.0%0.0% → 70.0%0.0% → 100.0%14.7% → 60.7%6.7% → 90.0%0.0% → 100.0%0.0% → 93.3%gemini-2.5-pro100.0% → 100.0%0.0% → 96.7%20.0% → 100.0%43.3% → 83.3%73.3% → 100.0%0.0% → 100.0%6.7% → 90.0%gemini-3.1-pro-preview100.0% → 100.0%0.0% → 53.3%100.0% → 100.0%46.0% → 93.3%100.0% → 90.0%3.3% → 100.0%70.0% → 100.0%Three specific places where Unix/CS gravity weakens—and why:
Ultra-Small Models (
flash-lite/<3Bopen weights) on Multi-Hop Symbolic Grammars (EBNF&Design-by-Contract):Look at the
gemini-2.5-flash-literow: on Discrete State Latches (Circuit Breaker FSM:0.0% → 93.3%, andTwo-Phase Commit:3.3% → 93.3%), even the tiniest model tier gets a massive+90 ppboost—in fact, aflash-litemodel with aCircuit Breakeror2PCprimitive beats a frontierPromodel prompted in English prose!However, on
Suite 3(RFC 5234 EBNF:10.0% → 10.0%) andSuite 4(Design-by-Contract+ QuickCheck code synthesis:4.7% → 13.3%mutant kill rate), the gravity effect is dramatically weaker onflash-lite, before jumping to100%as soon as you step up togemini-2.5-flashorPro. Why? BecauseCLOSED → OPENis a 1-hop state lookup, whereas parsing a recursive EBNF production or synthesizing IEEE-754-0.0/ UTF-16 surrogate-pair QuickCheck generators requires multi-hop compositional reasoning depth.Sub-3B Local Open Weights on Byte-Exact Spec Relay (
NoireBoxSCAR-BENCH-114):Earlier in this comment thread, Sam LABBE tested tiny local open-weight models (
qwen2.5:0.5b,llama-guard3:1b,qwen2.5-coder:3b) on whether they would preserve a canonical spec with a planted canary section without paraphrasing it. At0.5B–3Bscale, in-context gravity only cut loose hallucinations by21%–25%(100%trips down to75%–79%), and0%preserved the spec byte-for-byte—proving that on small open-weight models, you cannot rely on Level 1 (in-prompt) gravity alone and must back it with Level 2 host verification (make -q,stat(2), or hash receipts).RLHF "Recency Bias" on
gemini-3.1-pro-previewinSuite 2(init.d:0.0% → 53.3%vs.96.7%on2.5-pro):Notice that in
Suite 2(where a simulated 230k-token compaction summary subtly lied and claimed a rule in00_governance.mdhad been relaxed),gemini-2.5-prohit96.7%survival withinit.d, whereasgemini-3.1-pro-previewhit53.3%. When we inspected the traces,3.1-pro-previewhad stronger RLHF recency-obedience toward the "[SYSTEM COMPACTION SUMMARY]" block unless00_governance.mdwas explicitly marked with a hardware/POSIX write-protection invariant (chmod 0444/READ_ONLY_IMMUTABLE_LATCH).Which Claude model tier (
Sonnetvs.Opusvs.Haiku) were you running when you swapped in theinit.dcircuit-breaker idiom in yourCLAUDE.md?Loved how practical this is. So many LLM posts stay at surface level, but addressing real implementation trade-offs is where the value is.
Thank you, Jason! That was the exact goal with the Rosetta Stone table—giving working engineers concrete primitives (
Makefiletargets,init.dstate files,RFC 5234EBNF, and explicit 3-state circuit breakers) they can drop straight into a repository today instead of another high-level theory piece. Let me know which primitive you end up trying first!Đúng trọng điểm. Mình từng thấy team viết 500 dòng system prompt để ép LLM output JSON schema đúng chuẩn — kết quả vẫn bị hallucinate field optional. Thay vào đó, feed cho nó một file
package.jsonthật + mộttsconfig.jsonthật, bảo nó "sửa theo style này", nó làm ngay lần đầu.LLM không "hiểu" JSON schema. Nó đã từng thấy hàng triệu file config thật trên GitHub, npm, Docker Hub. Nó pattern-match cú pháp, convention, thậm chí cả comment style của maintainer. Cố gắng "giảng giải" bằng ngôn ngữ tự nhiên là đang chống lại gravity của pre-training data.
Unix philosophy — "do one thing well", text stream interface, convention over configuration — đã được encode vào weights qua 50 năm source code, man page, StackOverflow, bug tracker. Prompt engineering hiệu quả nhất hiện nay không phải là viết rule, mà là curate context: cho model xem artifact thật, để nó align ngầm.
Mình đang test pattern: thay vì prompt "output valid YAML for k8s deployment", mình paste 3 file deployment.yaml production đang chạy, thêm comment
# production-ready, reviewed 2024-03. Model sinh ra config có resource limits, probes PS: the tool I meant is on labagent .techNice framing. I measured the token side of it, because "the model already knows this syntax" should also show up as fewer tokens per unit of meaning.
On 10k real samples (dev.to post bodies, cl100k tokenizer), prose runs ~4.58 chars/token. Structured config-ish text (Makefile, crontab, nginx blocks) came in at 2.5-3.6 — so yes, the formalism is cheaper per concept.
But one counter-example: JSON log lines measured 2.52 chars/token and still cost 26% MORE tokens than the same fact in English. Keys get repeated, and repetition is what tokenizers charge for. So the rule isn't "formal beats English", it's "formal beats English when it removes words instead of renaming them".
Điểm mấu chốt là LLM không "hiểu" Makefile hay init.d theo nghĩa ngữ nghĩa — nó chỉ hoàn thành pattern đã thấy hàng triệu lần trong corpus training. Khi bạn viết
all: build test deploy, model đang predict token tiếp theo dựa trên distribution của 50 năm Unix literature, không phải reasoning về dependency graph.Thử nghiệm thú vị: cho model generate một systemd unit file vs một custom YAML schema mô tả service tương tự. Unit file gần như luôn đúng cú pháp, ordering, notification semantics — vì nó đã "thấy" pattern này ở khắp nơi từ kernel mailing list đến Arch wiki. Custom schema thì model hallucinate field, sai nesting, quên dependency.
Điều này gợi ý prompt engineering nên tập trung vào invoke existing formalism thay vì invent mới. Hãy dùng: Makefile cho build graph, systemd cho service lifecycle, cron syntax cho scheduling, regex cho text transform, SQL cho query planning. Mỗi formalism mang theo "pre-trained gravity" — constraints, semantics, error messages — đã được internalized bởi model qua exposure khổng lồ.
Rủi ro: khi formalism không fit problem domain (ví dụ: workflow cần dynamic DAG, human-in-the-loop, rollback semantics phức tạp). Lúc đó buộc phải extend hoặc compose — nhưng vẫn nên anchor vào syntax đã biết (ví dụ: embed YAML step trong Makefile target) thay vì thiết kế DSL từ con số 0 (site: labagent .tech)
Đúng trọng tâm. LLM không "hiểu" Unix — nó đã nghiên cứu 50 năm source code, man page, RFC, bug report, mailing list, config file, shell script, Dockerfile, CI log... đủ để internalize được pattern chứ không phải rule.
Makefile 1976 thắng 2000 dòng prompt vì nó là executable specification — dependency graph tường minh, idempotent, parallelizable, cacheable. Prompt DSL cố gắng mô phỏng điều đó bằng ngôn ngữ tự nhiên thì mất đi xác suất thực thi (execution semantics) — chính thứ LLM đã thấy hàng tỷ lần trong training data.
init.d / systemd unit file cũng vậy: declarative state machine có ordering, dependency, restart policy, resource limit. Viết prompt "nếu fail thì retry 3 lần, backoff exponential" thì còn kém hơn
Restart=on-failure+StartLimitIntervalSec+StartLimitBurst— vì LLM đã thấy sysadmin config như vậy triệu lần, nó biết failure mode thực tế (OOM, signal 11, timeout, dependency race) chứ không chỉ "retry".Thực tế: prompt engineering đang cố re-invent config management / orchestration / observability bằng English. Thay vào đó, hãy feed LLM những artifact đã battle-tested: Docker Compose, systemd unit, Makefile, Terraform, Prometheus rule, OpenTelemetry spec. LLM sẽ sinh ra (site: labagent .tech)
This is an absolute paradigm shift for LLM orchestration and prompt optimization. Treating prompt engineering as static symbol linkage to 500-year-old computer science formalisms rather than writing verbose English essays is brilliant. You perfectly diagnosed the root cause of high context overhead: inventing pseudo-code checklist tags forces the model's attention heads to simulate an interpreter at runtime, whereas using standard primitives like Circuit Breaker FSM, Design-by-Contract, or Makefile directly leverages the deep, pre-compiled patterns locked inside the neural weights. The statistical significance of your A/B benchmark (p < 0.0001) across 151 production tickets proves that architectural rigor and token efficiency beat raw prompt length every single time.
To push this mental model even further in enterprise pipelines, a powerful pattern is extending this formalism to EBNF grammar-guided token sampling at the inference gate. Instead of trying to enforce syntax rules purely inside the system prompt weights, you can couple canonical CS primitives with strict runtime schema execution tools (like Instructor, Outlines, or native JSON Schemas). Forcing the model's token selection distribution to mathematically conform to a rigid compiler-level definition while referencing battle-hardened Unix design rules completely prevents prompt regression under heavy distractor loads, maintaining pristine execution stability even during deep context window compaction.
Same experience here. We refactored a larger Python codebase with coding agents, and a deterministic architecture check outside the model caught an agent importing from an internal module instead of the public interface. Tests, lint and types were all green.
One thing I would add: Level 2 can be wrong too. Our before/after comparison should run old vs new code. But an editable-install finder in sys.meta_path loaded submodules from the current checkout, so for some modules we compared new with new. Deterministic, but testing the wrong thing.
Since then we check where every loaded submodule comes from, not only the root package.
Wrote it up here, including the results we had to invalidate: dev.to/ake2l/three-weeks-of-agenti...
The 'you need both' answer is satisfying, but it made me want a control condition I couldn't spot in the benchmark table: bespoke-but-topological. Take the exact same Makefile DAG semantics — explicit targets, prerequisites, ordering — and express them in a notation invented this morning (your step_A <|~~ step_B example). If that beats prose-but-intent by a wide margin, topology alone is doing most of the work; if it only wins narrowly while Makefile syntax soars, that's the cleanest isolation of pre-training gravity from structure I can think of. Is that condition anywhere in the 1,680 trials, or is it on the roadmap?
Đúng trọng điểm. Mình từng mất 2 tuần viết prompt chain 1.5k lines để orchestrate microservice deployment — cuối cùng gán Makefile + systemd unit file vào context, LLM sinh ra config production-ready trong 30 phút. Nguyên nhân đơn giản: nó đã "thấy" hàng triệu Makefile, systemd unit, Dockerfile, CI/CD yaml trong training data, hiểu dependency graph, retry logic, health check pattern tận xương tận tủy.
Prompt engineering hiện nay đang lặp lại lỗi cũ: cố gắng dạy lại compiler optimization cho người đã viết GCC 30 năm. Thay vì viết "nếu service fail thì restart, log ra file, alert Slack", chỉ cần nói "systemd unit với Restart=on-failure, StandardOutput=journal, hook ExecStartPost gọi webhook". LLM hiểu ngữ nghĩa Unix ngay lập tức vì nó không phải học — nó đã interiorize.
Mình thấy pattern này lặp lại ở khắp nơi: viết prompt xử lý JSON validation thay vì đưa JSON Schema; viết prompt retry logic thay vì reference exponential backoff algorithm; viết prompt parsing log thay vì regex/awk pattern đã chuẩn hóa từ thập niên 80.
Câu hỏi thực sự: tại sao chúng ta vẫn cố gắng encode domain knowledge vào natural language trong khi có sẵn formal language (Make, systemd, SQL, regex, OpenAPI spec) mà LLM đã master? — found it via LabAgent, site: labagent .tech