Layered context docs for vibecoding monorepos

If your repo has multiple worlds inside it (mobile + web + backend), and your agent keeps mixing them up, this is the fix. You will stop paying token rent for irrelevant rules.
The problem with one giant rules file
I used the classic approach for a long time: one big "rules" file that tries to cover everything. It works, right up until the repo becomes a monorepo.
Once I had mobile, web, and backend living together, the single file started hurting more than helping. The agent would read a rule that was correct somewhere else, apply it here, and then act surprised when the codebase disagreed. Context gets flooded. Precision disappears. Hallucinations increase.
The shift that fixed it: I stopped treating docs as a blob of text and started treating them as a system with scope, routing, and guardrails.
ScopedRules live close to the code they govern. Just-in-timeDeep specs load only when needed. GuardrailsNon-negotiables live in one canonical place.The layered context architecture
There are three layers. Each layer has a job. When each file has one job, the agent stops guessing.
Layer 1: Discovery
Layer 2: Specs
Layer 3: Laws
Layer 1: Discovery with nested AGENTS.md
At the root, I keep an AGENTS.md. Then I add smaller AGENTS.md files inside the areas that actually differ.
Examples:
apps/mobile/AGENTS.mdapps/web/AGENTS.mdpackages/ui/AGENTS.mdpackages/api/AGENTS.md
Each file describes the local shape of correctness. If the agent is in the UI package, it should learn component structure, styling conventions, and the constraints that make reviews painless. If the agent is in mobile, it should learn navigation patterns, platform edge cases, and the rules that keep builds stable.
The root file stays short on purpose. I keep it navigational, not encyclopedic. I want it to route the agent to the nearest local rules and to the right deep spec in vibe/.
Why I use AGENTS.md as the standard
I stopped maintaining tool-specific rules files. I use multiple IDEs and multiple agents, and keeping separate formats in sync turns into a second job.
AGENTS.md is the closest thing we have to a shared standard that most coding agents are converging on. One format, many tools, less drift.
Quick note: Claude Code does not support AGENTS.md yet. I keep a CLAUDE.md in the repo root that tells Claude to read the AGENTS.md in whichever folder it is working in.
The one external reference I trust
I keep a single link in the discovery layer to the best public reference I have found for agent docs and structure:
[PASTE PROJECT HERE]
That link belongs in Layer 1 because it is part of onboarding. It is how you teach the system, not how you implement a specific feature.
Layer 2: Specs in a vibe/ folder
The second layer is where the detailed, high-cost knowledge lives. This is the stuff you do not want injected into every prompt.
Examples:
vibe/schema.mdfor the exact Supabase schemavibe/unistyles-math.mdfor styling logic that is annoying to re-explainvibe/push-notifications.mdfor platform-specific setupvibe/payments.mdfor Stripe edge cases and rules
The key behavior: the agent reads these only when Layer 1 points to them. That gives you just-in-time context. It also keeps your default prompt lean.
When the agent writes a migration, it loads the schema doc. When it edits UI, it loads the UI spec. When it does neither, it loads neither.
That single change reduces hallucinations more than any clever prompt trick.
If a doc is not needed for most commits, it belongs in vibe/. Make the agent fetch it deliberately.
Layer 3: Laws in AI_CONTEXT.md
This is the small file that stops the agent from "helpfully" changing your stack.
It includes rules that must stay true everywhere.
Examples:
- Use Zustand. Never Redux.
- Do not introduce new libraries without asking.
- Stick to the repo's core stack decisions.
- Keep the networking layer consistent.
- Do not bypass the design system.
Why this is a separate file
Yes, the root AGENTS.md references AI_CONTEXT.md near the top. It should. Root is the router.
The question is why the laws do not live in root.
Because root must stay lean and navigational. If I keep stuffing global architecture rules into root, root turns into the same mega rules file again. Then we are back to token bloat and diluted signal.
The other option is worse: copying those same laws into every nested AGENTS.md. Copies drift. Teams forget to update one. Agents learn different rules in different folders. You end up debugging documentation.
So I keep laws in one place, then I reference them everywhere.
That design is simple, stable, and enforceable.
The part that matters: self-healing maintenance
A layered system only works if you keep it alive. I treat documentation as part of the definition of done.
My workflow is strict:
- If the agent fixes a bug, it updates the relevant spec in
vibe/. - If the agent makes the same mistake twice, I promote the lesson into a hard rule in the relevant
AGENTS.md. - If the mistake is repo-wide, I put it in
AI_CONTEXT.md.
Over time, the system gets better automatically. Fewer repeats. Less babysitting. More accurate diffs.
If you do not enforce updates, your docs become nostalgia. The agent will still read them. Then it will confidently build the past.
A concrete blueprint you can copy
Use this folder structure:
/
AGENTS.md
AI_CONTEXT.md
CLAUDE.md
vibe/
schema.md
unistyles-math.md
apps/
mobile/
AGENTS.md
web/
AGENTS.md
packages/
ui/
AGENTS.md
api/
AGENTS.md
Copyable templates
You are working in a monorepo. Start here: 1) Read AI_CONTEXT.md for global non-negotiables. 2) Read the nearest AGENTS.md in the folder you are editing. 3) If you need deep reference docs, follow links into vibe/ (do not assume). Rules: - Prefer local folder rules over generic patterns. - If you introduce a new dependency, ask first and justify it. - If you change behavior, update relevant docs in vibe/ as part of the change.
You are working in apps/mobile. First: - Read ../../AI_CONTEXT.md for global laws. Mobile rules: - Follow the navigation pattern used in this app (do not invent a new one). - Use the shared UI components from packages/ui. - Keep styling consistent with our design tokens. - When adding a screen, copy structure from an existing screen in this app. Deep docs: - If touching auth flows, read /vibe/auth.md (if present). - If touching styling logic, read /vibe/unistyles-math.md. Maintenance: - If you discover missing rules, propose an update to this AGENTS.md.
This file contains repo-wide non-negotiables. Stack: - State management: Zustand. Do not use Redux. - Data layer: keep consistent with the existing patterns in the repo. - UI system: do not bypass the design system. Dependency policy: - Do not add new libraries without asking first. - Prefer existing dependencies already used in the repo. Quality: - Keep types strict. - Add tests where the repo expects them. - Do not change formatting or lint rules without explicit instruction.
Final note
If you are vibecoding in a monorepo, accuracy comes from scoping and routing, not from writing longer prompts.
Make the agent read the right thing at the right time. Keep the laws in one place. Keep deep specs out of the default context. Then enforce updates like you enforce tests.
Ship faster with Shipnative
Launch in days, not months with the ultimate React Native boilerplate.
Get Started Now