For the complete documentation index, see llms.txt. This page is also available as Markdown.

Budgeting the agent's context

How to budget the agent's context — deciding @ injection vs a link, splitting a growing ENTITY.md, placing content at root vs domain, and when a rule earns a policy.

Decide where a sentence lives — and therefore who pays to load it — before you write it.

When you need this

  • You're deciding whether to @-inject a supporting file or just link it.

  • An ENTITY.md keeps growing and every analysis of that entity is paying for it.

  • You're unsure whether a convention belongs in the root LYNK.md, a domain LYNK.md, or on one entity.

  • An entity or skill isn't getting loaded for the questions it should answer — or is loaded for ones it shouldn't.

  • You're about to add a policy for a rule that only applies sometimes.

The principle

Every sentence in the layer has a load class:

  • Always — root and domain LYNK.md, GLOSSARY.yml, policies. Taxes every question in scope.

  • On activation — an entity's ENTITY.md body plus everything it @-injects; a skill's body. Taxes every question touching that primitive.

  • On index — entity and skill frontmatter descriptions. Read for every routing decision.

  • On demand — linked supporting files. Free until summoned.

Know the class before you write. The cost of a sentence is set by its class, not its length.

Patterns

The three-tier entity split

An entity accumulates knowledge — quirks, procedures, worked examples. Split it into three tiers:

  • Index tier — the description: one line, grain plus use-for. Read on every routing decision.

  • Activation tier — the ENTITY.md body: only what every analysis of this entity needs.

  • JIT tier — supporting files (instructions/, examples/): linked, not injected. Loaded only when a question summons them.

Grove's customer ENTITY.md had grown to ~600 words: fiscal-year mechanics, the closing-period procedure, two past-analysis walkthroughs. Every ARR or churn question paid all 600 before a line of SQL was written. After the split:

Cost: activation drops from ~600 words to ~80. The fiscal-year detail now costs nothing except on the questions that need it. Deviate only when a supporting file is genuinely needed by most loads — then @-inject it and accept the cost as part of the activation tier.

Inject with @ when the content is short and needed by most loads of the host. Link when it's situational or long. And prefer a conceptual path over a whole file: @glossary.logo_churn.description injects one sentence that stays in sync with its source; @/.lynk/... injects an entire file. Grammar in Markdown format.

Grove's customer injects @glossary.logo_churn.description — one sentence, relevant to nearly every customer analysis — and links the closing-period procedure, which only month-end questions touch.

Descriptions that route

The description is the index tier: it's all the agent sees when deciding whether to load an entity or skill. Write it as what-it-is + grain + "use for X, Y" — and make it discriminate against its siblings, not just describe its subject. Arcadia has both player and player_cohort; the description is what routes retention questions to the right one:

A description can be accurate and still fail — see the vague description below for the wrong form.

The placement ladder

Root LYNK.md → domain LYNK.md → entity → supporting file. Each step down means fewer questions pay for the sentence; promoting a sentence up multiplies who pays. Place at the lowest rung whose audience still covers everyone who needs it.

Grove: the fiscal year (starts February 1) is root LYNK.md — every domain reports on it. The test-account exclusion is customer's ENTITY.md — it's a rule about one entity's rows (LYNK.md is explicit that orientation carries only what no single entity owns). The closing-period procedure is a supporting file — even most customer analyses never need it.

Anti-patterns

The encyclopedia ENTITY.md

Wrong: a 600-word ENTITY.md body — history, edge cases, worked examples, all inline.

Why it fails: the body loads as a unit on every activation, so every analysis of the entity pays the full 600 words, including the vast majority that need none of it. The waste is invisible — nothing errors, context just fills.

Fix: the three-tier split. Body keeps only what every analysis needs; the rest moves to linked supporting files.

Whole-file @ of another entity

Wrong: @/.lynk/domains/core/entities/subscription/ENTITY.md inside customer's ENTITY.md.

Why it fails: @ is eager — every load of customer now drags in all of subscription's prose, plus anything it injects, whether or not the question involves subscriptions.

Fix: link the file, or inject just the fact you need via a conceptual path — @subscription.is_pending_cancellation.description.

The vague description

Wrong: description: Customer data.

Why it fails: the agent routes on descriptions. This one loads the entity for wrong questions and skips it for right ones — and no build check catches it, because the field is present and non-empty. The failure only shows up as bad answers.

Fix: grain + use-for: Grove accounts. One row per company. Use for ARR, churn, and plan-tier analysis.

Policy creep

Wrong: a situational rule — "when analyzing refunds, break out by channel" — written as a policy.

Why it fails: policies are eager, always-apply commitments (Policy); every question in the domain now carries a rule that applies to one kind of analysis. Each addition seems small; the always-loaded tier only ever grows.

Fix: put it where it's lazy — a skill body if it's how to reason through refund analyses, entity prose if it's a fact about order.

Injection chains

Wrong: ENTITY.md injects instructions/a.md, which injects instructions/b.md, which injects a third file.

Why it fails: injection cycles fail the build (Markdown format), but chains pass silently — and every activation of the host loads the whole transitive closure. The author of each link sees one small @; the agent pays for all of them.

Fix: flatten. The host injects at most one level; anything deeper becomes a link the agent follows on demand.

The bar

  • Every entity and skill description states grain and use-for, and discriminates against its siblings.

  • ENTITY.md bodies stay under ~150 words unless you can say why every analysis needs more.

  • Nothing is @-injected that isn't needed by most loads of its host file.

  • For any sentence in the layer, you can name its load class — and it's the cheapest class that still reaches everyone who needs it.

Last updated