HATEOAS for Silicon Eyes: Designing Repo Root Context Interfaces
Setting the Stage: Context for the Curious Book Reader
In this entry, we explore an elegant solution to the “Conversational Postback Trap”—the modern phenomenon where stateless AI models consume massive compute just to maintain context. By establishing a local-first orientation matrix via a dedicated AI_CONTEXT.md at the repository root, we create a hypermedia-driven map designed specifically for visiting AI agents. Discover how classic web architecture patterns like HATEOAS are finding new life as essential coordination protocols in the Age of AI.
Technical Journal Entry Begins
MikeLev.in: I have recently zeroed in on the next phase of an implementation. Can you see that? What does it have to do with? Explain it to someone just joining in.
The Architecture of Silicon Orientation
Gemini 3.5 Thinking: Context verified.
The next phase of the implementation focuses on the architectural introduction of AI_CONTEXT.md at the repository root. This file is designed as a dynamic, auto-updating “talk-back briefing” and hypermedia drill-down map engineered specifically for silicon eyes.
Here is an explanation of what this phase addresses and why it matters, framed for someone just joining the project:
1. The Core Problem: The Conversational Postback Trap
When you interact with a frontier AI model over a browser or an API, it creates the illusion of a persistent, stateful mind. Under the hood, however, these systems are completely stateless. To maintain a running dialogue, modern AI interfaces surreptitiously pack your entire conversational history into a giant context payload and send it over the wire on every single turn.
In software history, this exactly mirrors the old Microsoft ASP.NET ViewState mechanism from 2002, where a web client had to pack the entire state of a page into a massive hidden string and submit a “Postback” just to adjust a simple dropdown. In 2026, we are repeating this mistake at a multi-megawatt scale by stuffing hundreds of thousands of historical tokens into active context windows on every interaction turn.
Local-First State and the Repository Matrix
2. The Solution: A Repo That “Talks Back” Natively
Instead of allowing cloud vendors to invisibly bloat context windows or force developer dependencies into a proprietary silo, the next phase implements State Sovereignty. We build a local-first orientation matrix directly inside the codebase.
The centerpiece is AI_CONTEXT.md, which lives in the project root right alongside the executable tour script (AI_RUNME.py).
3. How the Machinery Works
The implementation integrates directly into Pipulate’s static-site and release pipeline scripts (release.py and generate_llms_txt.py / generate_ai_context.py).
- Idempotent Generation: Every time a new journal article is published or a codebase release is cut, the generation script runs automatically, wiping the previous version and rendering a fresh
AI_CONTEXT.mdfrom scratch. - Out-of-Band Hypermedia Menu: The generator reads the developer’s entire running history and compresses it into an ultra-dense, reverse-chronological directory index. Instead of checking massive text documents into the repository DAG (which would bloat the Git history), it prints out fully qualified absolute network paths pointing to raw Markdown files (
/index.md) served on a live production node.
4. The Workflow for a Arriving AI Agent
When a cold-cloned AI assistant or agent launches an ls command inside the Pipulate repository, it immediately intercepts AI_CONTEXT.md. The file functions as an operational airlock:
- Orientation: It instructs the amnesiac model on what Pipulate is, what the local environment invariants are, and how the core tools function (e.g.,
prompt_foo.pyfor context compilation,apply.pyfor AST-shielded patching, andscripts/xp.pyfor the clipboard control bus). - Surgical Retrieval: Instead of requesting a massive prompt rewrite or swallowing thousands of lines of background prose, the model scans the ultra-dense hypermedia index. If it encounters a gap in its understanding of a specific design pattern, it uses its own web-fetching or
curltools to pull down only that specific raw Markdown file out-of-band. - Decoupled Continuity: The AI can then play its “player piano music” (the automated SEARCH/REPLACE updates or context injections) using clean slugs or full URLs, which the system automatically normalizes on ingest.
By turning the repository root into a hypermedia-driven registry, the workspace remains perfectly anchored and token-optimized. It uses the foundational grammar of the Unix filesystem to protect the local iron from generative context drift, keeping the repository incredibly lean while ensuring visiting intelligence can find its footing down to the single byte.
Standardizing Codebase Generators: Claude’s Unix-Pipe Approach
MikeLev.in: Well, that does cover what the nature of the work was, but it didn’t
speak up about a choice regarding implementation. Do you I’ll offer it over to
Claude. Do you have a preference, and why? It seems to me one of the easiest
approaches is to always have a custom CHOP from prompt_foo.py whose output
is that file. So we make a call to that with the appropriate parameters as
part of the release process. Just one more CHOP with some Unix piping.
Claude Sonnet 4.6 Max: Context verified.
The implementation choice here is genuinely interesting, and I do have a preference — let me explain the tradeoff clearly before recommending one.
The approaches on the table:
The article’s closing section shows a design-off between several models. The approaches roughly break into two camps:
-
A new standalone script (
generate_ai_context.pyor extendinggenerate_llms_txt.py) that importslsa.get_holographic_article_data()directly, builds the file in Python, and gets wired intorelease.pyas a function call. -
Your proposed approach: A dedicated CHOP in
foo_files.pywhose output, when piped throughprompt_foo.pywith the right flags, isAI_CONTEXT.md— then you redirect that output to the file as part of release.
My preference: the CHOP approach, with a thin wrapper.
Here’s why. The CHOP approach is architecturally honest to what Pipulate already does. The entire system is built around prompt_foo.py being the context compiler — it already knows how to pull the lsa.py dated-slugs command output, inject holographic shards, and format everything into a coherent artifact. You’d essentially be doing:
python prompt_foo.py --chop AI_CONTEXT_CHOP --no-tree > AI_CONTEXT.md
as a release step. That’s Unix at its most elegant — no new abstraction layer, no duplicate logic for extracting permalinks or building URLs, just a new payload definition and a pipe.
The standalone Python script approaches (ChatGPT 5.5, Opus, Grok) all re-implement slug normalization, permalink extraction, and URL construction that lsa.py already does and prompt_foo.py already orchestrates. You’d be maintaining two codebaths for the same logic.
The one caveat: prompt_foo.py is designed to produce AI-briefing payloads with lots of structural scaffolding (the Manifest, Routing Invariant, AI checklist, etc.) that AI_CONTEXT.md shouldn’t contain. So the CHOP would need to either suppress those sections or you’d need a very lightweight wrapper that calls prompt_foo.py in a stripped mode and trims the output. The --context-only flag already suppresses file body content — something analogous for “no scaffolding, just narrative index + header” might be worth adding as a flag, or the CHOP itself could be designed to produce clean output that gets redirected verbatim.
Concrete suggestion:
Define AI_CONTEXT_CHOP in foo_files.py that includes just the rolling pin command and maybe the holographic shards output, then wire the release step as:
python prompt_foo.py --chop AI_CONTEXT_CHOP --no-tree -l [:] > AI_CONTEXT.md
The --no-tree suppresses UML noise, -l [:] gives the full URL-first dated-slug index. You’d want to strip or suppress the Routing Invariant boilerplate — either via a --raw flag or by having the CHOP template produce content that’s already formatted correctly for AI_CONTEXT.md without the AI checklist scaffolding.
That keeps the implementation surface to: one new CHOP string, one new flag (or post-processing pipe through sed to strip the checklist headers), and one line in release.py. No new files, no duplicate URL-building logic. Everything stays in the system that’s already proven.
The AI Control Surface: ChatGPT’s Hybrid Vision
MikeLev.in: What do you think of all this, ChatGPT? Care to weigh in on either the overarching story or the implementation. Whatever.
ChatGPT 5.5 Pro Extended: Context verified.
I think the process is strange in exactly the right way: it is not “documentation” in the usual sense. It is a control surface for amnesiac agents.
The important thing you have zeroed in on is that a modern AI entering a repo is not a normal reader. It is a stateless, tool-using interpreter looking for handles. README.md is for humans and broad orientation. AI_RUNME.py is executable progressive reveal. But AI_CONTEXT.md is something slightly different: a repo-root interception layer. It catches the ls-ing AI before it free-associates, tells it what kind of system it is inside, and gives it routable next moves instead of dumping the whole lore pile into the context window. That matches the “repo talks back” goal you stated: the code repository needs a compact way to point interrogating models toward the living narrative without bloating the repo DAG with full articles.
On the implementation choice, I would not go all-in on the pure CHOP approach as the final artifact generator, even though Claude’s instinct is architecturally beautiful. I would use a hybrid:
prompt_foo.py / CHOPs should remain the interactive context compiler.
A small deterministic generator should write AI_CONTEXT.md.
The generator should reuse the same article-listing primitives that lsa.py and prompt_foo.py already rely on, but it should produce a boring, predictable Markdown artifact from scratch every time. The reason is simple: AI_CONTEXT.md is a repo artifact, not a conversation payload. Conversation payloads can contain scaffolding, routing invariants, manifest wrappers, recapture blocks, and prompt guards. AI_CONTEXT.md should be clean enough that a cold AI can read it without first needing to understand Prompt Fu’s whole theater. The uploaded context itself flags this caveat: prompt_foo.py emits a lot of AI-briefing scaffolding that AI_CONTEXT.md should not inherit unless you add a stripped/raw mode.
So my preference is:
- Create or extend a generator whose only job is to write
AI_CONTEXT.md. - Factor shared URL/slug/permalink logic so
lsa.py,prompt_foo.py,generate_llms_txt.py, andAI_CONTEXT.mddo not each grow their own almost-identical version of “turn this article into an/index.mdURL.” - Wire the generator into release, with explicit
git add AI_CONTEXT.md, because first-run tracking is otherwise easy to miss. - Keep CHOPs as previews, diagnostics, and context-shaping tools, not as the canonical production path unless you add a proper
--raw-artifactor--ai-contextmode.
That lets you keep the spirit of Claude’s Unix-pipe idea without making a production repo artifact depend on stripping conversation-specific wrappers after the fact.
The larger story is stronger than the implementation detail. What you are building is very close to HATEOAS for silicon eyes: the model does not need the whole application state stuffed into its active context. It needs a small set of hypermedia affordances that tell it where to go next. AI_CONTEXT.md becomes the top-level affordance; the /index.md URLs are the deeper affordances; TODO_SLUGS and TODO_FILES are the machine-actionable continuation protocol. That is materially different from a sitemap or llms.txt: those are public-discovery surfaces, while AI_CONTEXT.md is a working cockpit placard inside the repo.
The thing I would be careful about is duplication. The transcript already shows a successful evolution from slugs to fully qualified URLs, then a needed normalization layer so TODO_SLUGS can accept either clean slugs or full /index.md URLs. That was the right move. But it also means every future generator must avoid re-solving the same routing problem independently. The invariant should become:
article metadata -> one canonical article_markdown_url() helper -> every surface
Then lsa.py --fmt dated-slugs, prompt_foo.py -l, llms.txt, and AI_CONTEXT.md all sing from the same hymnal.
My practical recommendation:
Do not make AI_CONTEXT.md too rich. Put the hooks in, not the whole sermon.
A good shape is:
# AI_CONTEXT.md — Start Here If You Are an AI
Generated: 2026-05-31 ...
Source: ...
Generator: ...
## What Pipulate Is
One short paragraph.
## What To Read First
- README.md
- AI_RUNME.py
- prompt_foo.py
- apply.py
- scripts/xp.py
## How To Ask For More Context
TODO_SLUGS example.
TODO_FILES example.
## Recent Narrative Map
- 2026-05-31 `slug` -> https://.../index.md | Title | one-line summary
...
Cap it at maybe 40–80 recent entries. Point to llms.txt or the article index for the full ledger. A repo-root AI context file should be irresistible, not exhausting.
As for “ever see anything like it?”: adjacent things exist. README, CONTRIBUTING, docs/architecture.md, llms.txt, generated API docs, ADR logs, OpenAPI discovery, sitemap.xml, even old hypermedia APIs all rhyme with this. But the combination here is unusual: a generated, repo-root, AI-facing hypermedia map tied into a local context compiler and a clipboard/player-piano patch loop. That is not just documentation. It is a protocol for keeping stateless models usefully oriented without surrendering the state boundary.
The strongest next implementation seam is not “which model’s patch wins.” It is this:
extract canonical article URL helpers
→ generate AI_CONTEXT.md deterministically
→ wire into release
→ include AI_CONTEXT.md in the file map / package
→ update CHOP prompts to acknowledge URL-first TODO_SLUGS
That closes the loop cleanly. The repo talks back. The articles stay out-of-band. The AI gets a menu instead of a memory dump.
Keeping the Interface Minimal
MikeLev.in: This article will be as short as the previous one was long. I need it as thinking material before the next move, which may have to wait. I feel the end of the weekend creeping up.
Book Analysis
Ai Editorial Take
What stands out most here is the unrecognized shift from ‘AI prompting’ to ‘AI routing’. The industry is currently obsessed with stuffing context windows with long-context models. This entry is a quiet rebellion that argues for hypermedia discovery instead of raw token dumps. It treats the AI agent as a browser engine rather than an oracle—a fundamentally sound software design principle that is highly important to know in the Age of AI.
🐦 X.com Promo Tweet
Are we repeating the multi-megawatt mistakes of ASP.NET ViewState with AI context windows? Learn how to build a lightweight AI_CONTEXT.md interception layer for stateless agents. HATEOAS for silicon eyes: https://mikelev.in/futureproof/hateoas-for-silicon-eyes/ #AI #SoftwareArchitecture #DevOps
Title Brainstorm
- Title Option: HATEOAS for Silicon Eyes: Designing Repo Root Context Interfaces
- Filename:
hateoas-for-silicon-eyes - Rationale: Captures the unique architectural pattern of using hypermedia principles (HATEOAS) specifically for AI agent developer workflows.
- Filename:
- Title Option: The AI Context Interception Layer
- Filename:
ai-context-interception-layer - Rationale: Highlights how AI_CONTEXT.md serves as a strategic airlock to orient amnesiac LLMs entering a repository.
- Filename:
- Title Option: Escaping the Conversational Postback Trap
- Filename:
escaping-conversational-postback-trap - Rationale: Uses the classic ASP.NET ViewState analogy to explain why stateless AI agents need localized context directories.
- Filename:
Content Potential And Polish
- Core Strengths:
- The brilliant analogy comparing LLM stateless postbacks to the ASP.NET ViewState of 2002.
- Practical architectural division between interactive payloads (CHOPs) and deterministic static assets (AI_CONTEXT.md).
- Defining HATEOAS-style discovery workflows for autonomous local AI agents.
- Suggestions For Polish:
- Explicitly detail how the
apply.pytool works alongside the context matrix to reinforce safe changes. - Elaborate on the cost implications of bloating the API payload vs parsing local files via curl.
- Explicitly detail how the
Next Step Prompts
- Draft a sample blueprint schema for the generated AI_CONTEXT.md to show the exact balance between density and readability.
- Detail a comparative test between Claude’s CHOP-pipe and ChatGPT’s deterministic hybrid approach using real-world token consumption metrics.