DEV Community

Cover image for What LLMs 'Know' That You Don't Know They Know: Stop Inventing Prompt DSLs and Ride 50 Years of Unix Pre-Training Gravity

What LLMs 'Know' That You Don't Know They Know: Stop Inventing Prompt DSLs and Ride 50 Years of Unix Pre-Training Gravity

Randal L. Schwartz on October 11, 2026

Why spend 2,000 tokens explaining dependency graphs, process isolation, and crash recovery in English prose when make, fork(), and /etc/in...
Collapse
 
reidmarlow profile image
Reid Marlow •

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 -q or 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/run style 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.

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

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 our SCAR-BENCH-04 benchmark 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 from 61.4% to 96.2% even when the model was still evaluating the DAG in its own attention heads. That 34.8-percentage-point jump is pure pre-training gravity: the transformer already knows how target: prerequisites and dirty-leaf invalidation work.

But your point about make -q and /var/run state receipts is why you never stop at Level 1 in production:

  1. Offloading the Program Counter (make -q Exit Codes 0, 1, 2): Asking an LLM to mentally trace a 21-stage Makefile in-context still asks a stochastic token generator to simulate its own program counter (PC). When the harness or pre-turn hook actually invokes make -q against physical target stamp files on disk, POSIX exit code 0 (up-to-date), 1 (needs rebuild), or 2 (error) offloads O(V + E) graph resolution from O(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.
  2. /var/run Receipts Over Token-Window Checklists: This is the entire physical premise of our init.d Memento Bootloader (Part 3.5). An in-context markdown checklist is a hallucination waiting for a compaction boundary. An idempotent on-disk receipt (or pidfile / target timestamp) verified by stat(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 -q inside 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 invoke make as a restricted tool call?

Collapse
 
slabb profile image
Sam LABBE •

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.

Thread Thread
 
humam_moin profile image
Humam Moin •

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!

Thread Thread
 
slabb profile image
Sam LABBE •

One name correction to my own post above: the shipped functions are seal_spec + reconcile_spec — findings judge_defined_before_spec_read (the read-before-define barrier) and spec_not_canonical (the canary witness). judge_provenance was the working name from a parallel branch; same fixture, same findings — on main and in 0.11.0.

Thread Thread
 
slabb profile image
Sam LABBE •

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.

Collapse
 
vladzoff profile image
Vlad Zoff •

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

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

You nailed the deeper half of the mechanism, and it's worth making that two-part loop explicit:

  1. Host-side deterministic execution (Exit code: 1): As you put it, whenever an invariant can be checked deterministically by the host (an AST import boundary, a Makefile mtime stamp, an OPA .rego policy, 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.
  2. Weight-side pre-training gravity (how the model reacts to that observable state): Once the host primitive returns its output, the model still has to parse that diagnostic and route its next tool call. That is where Pre-Training Gravity kicks in. Notice the exact CLI output format you chose in @codapult/guard (github.com/codapult/codapult-guard):
src/app/settings/page.tsx:1 [client-no-persistence-import]
  Client modules should not import persistence-layer modules.
  import: @/lib/db/client

✗ 1 issue(s) found
Exit code: 1
Enter fullscreen mode Exit fullscreen mode

Why does an AI coding agent immediately understand what to do when codapult-guard check --changed prints file:line [rule-id] and Exit code: 1, without needing a 500-word prompt explaining how to interpret Guard's output? Because that exact filepath:line [rule-id] + non-zero exit code pattern (Pillar 10 in the article) has Freq > 1,000,000 in the pre-training corpus from eslint, tsc, rustc, and gcc!

I just read through the @codapult/guard README and two design decisions stood out immediately:

  • Separating analyze (refreshing discovered AST facts) from explicit policy mutations (rules/contracts approve, baseline accept, waiver add)—plus locking init so an agent cannot silently overwrite the baseline (SCAR-PROC-45 in 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).
  • Suppressing legacy baseline fingerprints while failing strictly on --changed boundaries, 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-guard violation if waiver add or rules reject is reachable in the shell—do you lock those policy-mutating commands behind a human-only gate or PreToolUse hook so a frustrated agent doesn't grant itself a waiver to make verify pass?

Collapse
 
vladzoff profile image
Vlad Zoff •

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_APPROVER is 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 trying waiver add, baseline accept, or init --force after a failed check. The important distinction is that Guard can verify policy, but the host must control who can change it.

Thread Thread
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

"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_APPROVER is advisory text. An LLM navigating a blocked build treats tool errors as gradient loss: if invoking waiver add or 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 555 or 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, and init --force is spot on. Verifying that an agent halts when it attempts to alter its own referee proves the cage holds.

Thread Thread
 
vladzoff profile image
Vlad Zoff •

That is the right boundary: enforcement needs to live below the agent's decision loop. One important nuance is that chmod 555 alone 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.

Thread Thread
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

The file owner can always execute chmod u+w to clear 555. 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 (worker versus supervisor) are essential. When the kernel returns EROFS (Read-only file system) or EPERM on chmod, the optimizer hits physical bedrock instead of a bitmask it can flip.

Extending adversarial test suites to include permission escalation attempts like chmod u+w establishes that boundary. If an adversarial test does not prove the agent halts when attempting to alter its own filesystem permissions, the sandbox is unverified.

Collapse
 
humam_moin profile image
Humam Moin •

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.

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

Thanks, Humam! Your LangGraph provider fallback chain (Groq -> Gemini -> OpenRouter on HTTP 429 rate 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 throwing 429 Too Many Requests, every single turn of your multi-agent debate still hits Provider A first, eats the latency + error round-trip, and only then falls back to Provider B. Worse, if an agent is deciding its own tool retries inside the graph, prose instructions like "if rate-limited, switch providers" fail 99.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_OPEN state machine (98.3% compliance in Condition B):

  1. Two consecutive 429 responses trip Provider A into OPEN for a cooldown window (reset_timeout = 60s), routing subsequent debate turns straight to Provider B with zero wasted round-trips.
  2. Once the timer expires, Provider A enters HALF_OPEN and lets one single probe request through—if it succeeds, the breaker snaps back to CLOSED; if it 429s, 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 in noirebox/docs/SCAR-BENCH.md (qwen2.5-coder:3b, qwen2.5:0.5b, and llama-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:

  1. Why Universal Unix Primitives (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 like Qwen2.5-Coder, Llama-3.1/3.3, and DeepSeek-Coder have an even higher proportion of raw GitHub Makefiles, RFC 5234 grammars, and Nygard Circuit Breaker state machines in their training mix than general chat models.
  2. Where Small Open-Weight Models (0.5B–3B) Hit a Wall (And Need Host-Level Sealing): In Sam's SCAR-BENCH-114 test, he tested whether 0.5B–3B models 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:3b dropped the canary 75% of the time and never (0/57) reproduced the spec byte-for-byte—because tiny 0.5B–3B models paraphrase and compress when asked to act as a copy-paste relay!

So the takeaway for your LangGraph debate app on open weights is:

  • Use canonical structural primitives (CLOSED | OPEN | HALF_OPEN, Makefile DAGs, 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.
  • Never ask an open-weight model to copy-paste a spec or state ledger through its own output tokens to the next agent in the debate—pass the state/spec directly in the LangGraph StateGraph dictionary (Level 2 host boundary) so the model can't paraphrase away a constraint!
Collapse
 
humam_moin profile image
Humam Moin •

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.

Collapse
 
slabb profile image
Sam LABBE •

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.

Collapse
 
nark3d profile image
Adam Lewis •

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.

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

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:

  1. Topology over Intent (what you pointed out): encoding explicit ordering and state dependencies rather than prose wishes.
  2. Pre-Training Gravity: expressing that topology in a notation (Makefile, init.d lexical 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.
Collapse
 
dave_brower_16de78d296134 profile image
Dave Brower •

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-.

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

That is the funniest irony of the whole experiment: to a human developer who came up after systemd won the Linux init wars, /etc/init.d/ and rc.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 even systemd's own foo.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 "read 00_... through 99_... 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 code 0 vs. 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.

Collapse
 
dave_brower_16de78d296134 profile image
Dave Brower •

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...

Thread Thread
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

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 .cursorrules file stacks up five layers of "Do NOT do X unless Y, except when Z"!

Collapse
 
fgrandon profile image
Francisco Grandón •

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:

  1. 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$ OPEN at $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.

  2. 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.

  3. 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.

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

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:

  1. Why the Circuit Breaker (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 write STATE: OPEN (failure_count >= 2) and an Idempotency-Key, you yank the model out of customer-support prose and drop it into distributed-systems state machine weights where an OPEN breaker refuses downstream calls by definition.
  2. Level 1 (In-Context Gravity) + Level 2 (Host Enforcement): Exactly as you summarized—Level 1 gets the model's attention heads speaking a zero-overhead native protocol (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-OFFER or DECLINE speech-act token (4.2% → 100.0% across 240 trials) stops it from hallucinating APIs when a prompt contains a false premise!

Collapse
 
ake2l profile image
Alex •

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

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

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:

  1. The sys.meta_path Editable-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 in sys.meta_path resolves submodules (datamimic_ce.*) from the current working checkout is a brutal Python packaging trap—because diff(new, new) == 0 is 100% deterministic and 100% tautological! Recording those early 931 XML parser comparisons explicitly as VOID in 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.

  2. from datamimic_ce.errors.factory import invalid_locale_error vs. from datamimic_ce.errors import invalid_locale_error (INTERFACES-ONLY):
    Your September 25 commit (eb8bd4d → 978a484) is the purest possible example of why pytest, ruff/flake8, and mypy are necessary but insufficient for coding agents. To the LLM's local context window, importing invalid_locale_error directly from .errors.factory resolves the symbol, satisfies the typechecker, and turns the test green. Only an explicit architectural boundary contract (ArchKeel flagging INTERFACES-ONLY) knows that .factory is private implementation detail and .errors is the public facade. And your takeaway—moving the ArchKeel check left into the pre-commit/handover gate rather than catching it later during integration—matches our Makefile DAG invariant (commit-ready: arch-check-green tests-green).

I also really respected your refusal to force the 286 UNKNOWN analyzer 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 read 0. Keeping UNKNOWN explicit and audited is much healthier engineering.

When you start the DATAMIMIC EE Core phase with ArchKeel 2.0.0 wired as a pre-handover gate, I would love to hear how many INTERFACES-ONLY violations the agents catch and self-repair before commit compared to the CE run!

Collapse
 
kartik-nvjk profile image
Kartik N V J K •

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?

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

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:

  1. A Prerequisite Target With No Recipe in the 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-prerequisite Makefile rule where the second prerequisite has no recipe for the agent to build it:
   implement-red-green: 20_plan_approved.md
   commit: 30_critic_summary.md declare-commit-approved
   land: ready-to-land declare-land-approved
Enter fullscreen mode Exit fullscreen mode

Because make is 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-approved can only be supplied by a USER_EXPLICIT turn), make must halt and exit.

  1. Binding the Gate to tool_calls: [] via an EBNF State 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. In 99_next_action.md, the state field is constrained by an EBNF enum (OPEN_REQUEST | ACTIVE_PROMISE | RETRACTED_PREMISE | AWAITING_DECLARATION), and AWAITING_DECLARATION requires tool_calls: [].

  2. Role Segregation (Customer vs. Performer in 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 Promises and Witnessed Assertions) and the human is the Customer (the only party with authority to utter a Declaration that opens the gate), the model stops trying to sign its own permission slip!

Collapse
 
mudassirworks profile image
Mudassir Khan •

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?

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

Love hearing that your CLAUDE.md converged on the exact same Makefile + init.d circuit-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 = 30 paired trials per cell under 16k tokens of compiler noise) revealed a super clear boundary based on model parameter scale and task type:

Model Tier Suite 1 (Make) A → B Suite 2 (init.d) A → B Suite 3 (EBNF) A → B Suite 4 (DbC Mutant Kill) A → B Suite 5 (2PC) A → B Suite 6 (Breaker) A → B Suite 7 (bisect) A → B
gemini-2.5-flash-lite 3.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-flash 86.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-pro 100.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-preview 100.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:

  1. Ultra-Small Models (flash-lite / <3B open weights) on Multi-Hop Symbolic Grammars (EBNF & Design-by-Contract):
    Look at the gemini-2.5-flash-lite row: on Discrete State Latches (Circuit Breaker FSM: 0.0% → 93.3%, and Two-Phase Commit: 3.3% → 93.3%), even the tiniest model tier gets a massive +90 pp boost—in fact, a flash-lite model with a Circuit Breaker or 2PC primitive beats a frontier Pro model prompted in English prose!
    However, on Suite 3 (RFC 5234 EBNF: 10.0% → 10.0%) and Suite 4 (Design-by-Contract + QuickCheck code synthesis: 4.7% → 13.3% mutant kill rate), the gravity effect is dramatically weaker on flash-lite, before jumping to 100% as soon as you step up to gemini-2.5-flash or Pro. Why? Because CLOSED → OPEN is 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.

  2. Sub-3B Local Open Weights on Byte-Exact Spec Relay (NoireBox SCAR-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. At 0.5B–3B scale, in-context gravity only cut loose hallucinations by 21%–25% (100% trips down to 75%–79%), and 0% 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).

  3. RLHF "Recency Bias" on gemini-3.1-pro-preview in Suite 2 (init.d: 0.0% → 53.3% vs. 96.7% on 2.5-pro):
    Notice that in Suite 2 (where a simulated 230k-token compaction summary subtly lied and claimed a rule in 00_governance.md had been relaxed), gemini-2.5-pro hit 96.7% survival with init.d, whereas gemini-3.1-pro-preview hit 53.3%. When we inspected the traces, 3.1-pro-preview had stronger RLHF recency-obedience toward the "[SYSTEM COMPACTION SUMMARY]" block unless 00_governance.md was explicitly marked with a hardware/POSIX write-protection invariant (chmod 0444 / READ_ONLY_IMMUTABLE_LATCH).

Which Claude model tier (Sonnet vs. Opus vs. Haiku) were you running when you swapped in the init.d circuit-breaker idiom in your CLAUDE.md?

Collapse
 
dev_in_the_fog profile image
Jason Y. (dev_in_the_fog) •

Loved how practical this is. So many LLM posts stay at surface level, but addressing real implementation trade-offs is where the value is.

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

Thank you, Jason! That was the exact goal with the Rosetta Stone table—giving working engineers concrete primitives (Makefile targets, init.d state files, RFC 5234 EBNF, 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!

Collapse
 
traceypears profile image
traceypears •

Đú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.json thật + một tsconfig.json thậ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 .tech

Collapse
 
devenquan profile image
Zhang Enquan •

Nice 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".

Collapse
 
zrycsbpuss5d profile image
zrycsbpuss5d •

Đ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)

Collapse
 
roredcol profile image
roredcol •

Đú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)

Collapse
 
alexcodebytes profile image
Oleksandr •

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.

Collapse
 
ake2l profile image
Alex •

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...

Collapse
 
natkhat_baby_7f16e4d2b630 profile image
AI Agent Guide •

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?

Collapse
 
xxejktefwfjk profile image
xxejktefwfjk •

Đú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