> ## Documentation Index
> Fetch the complete documentation index at: https://docs.defiloops.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Skills

> What the model is told, how it retrieves it, and the rule that keeps it honest

Skills are what the chat agent reads before it answers. They are the only
description of this system it has.

So a skill that is wrong is not a stale document: **it is an agent confidently
telling somebody to do something that cannot work.**

There are twenty-one, each a directory under `skills/` holding a `SKILL.md` and,
beside it, a `FACTS.md`.

## The twenty-one

| skill                     | what it covers                                                                                                                       |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `what-0xequity-is`        | The company, the product, and the words for it: what a share is, where rent comes from, what the fees are, and what may not be said. |
| `account-and-balances`    | The operating address, what it holds, and which chain to plan on.                                                                    |
| `writing-amounts`         | Every amount is a raw integer in the asset's base units. How to get the denomination right.                                          |
| `pipeline-authoring`      | How to write a pipeline document the compiler will accept.                                                                           |
| `connectors-and-batching` | How steps connect, and which ones share a transaction.                                                                               |
| `approval-gates`          | What it means when a run stops and asks, and which gates a person must answer on chain.                                              |
| `chaining-and-schedules`  | Arranging several pipelines in order, making one recur, answering a scheduled run that could not start.                              |
| `moving-value`            | Sending tokens to the owner, and drawing on a budget the owner granted.                                                              |
| `bridging`                | Moving USDC between Ethereum, Base and Arbitrum.                                                                                     |
| `swapping`                | Exchanging one asset for another, and sizing the trade before writing it.                                                            |
| `limit-orders`            | Waiting for a price: a resting order, partial fills, and why it re-arms.                                                             |
| `lending`                 | Supply collateral, borrow against it, repay, withdraw.                                                                               |
| `liquidity-positions`     | Uniswap V3: mint, add, collect, move a range, split, close.                                                                          |
| `choosing-a-range`        | Where to provide liquidity, from what pools actually paid rather than an advertised APY.                                             |
| `levered-liquidity`       | The levered half of position management, Arbitrum only.                                                                              |
| `moving-a-position`       | Migrating a leveraged position between lenders or markets, or closing it out.                                                        |
| `property-trading`        | Buying and selling 0xequity property tokens.                                                                                         |
| `rent-income`             | Turning property rent into another asset and sending it to the owner.                                                                |
| `tokenized-stocks`        | Coinbase tokenized stocks: Base only, and not ordinary ERC-20s.                                                                      |
| `one-asset-two-names`     | USDT and USD₮0 are one asset; XAUt and XAUt0 are one asset, and the two cases do not follow the same rule.                           |

## The two rules for changing one

**1. One skill, one editor, one commit.** Do not edit a skill somebody else is
editing. If you are adding a capability that touches three skills, commit them
together: a reader who gets one skill from your commit and another from
somebody else's gets a contradiction.

**2. A skill describes what the code DOES, today.** Not what it will do, not what
it used to do. Every claim should be checkable against a catalogue entry, a test,
or a run, and when you change the code, the skill changes in the same commit or
it starts lying.

That second rule has already been broken once, expensively. `limit-orders` said
*"there is no adapter that waits for a price, and you must not look for one"* for
as long as that was true, and **kept saying it after the feature shipped**. An
agent reading it talked somebody out of the exact thing they were asking for.

A negative claim is the dangerous kind, because nothing fails when it goes stale.

## What to change when

| you changed                | update                                                       |
| -------------------------- | ------------------------------------------------------------ |
| a catalogue parameter      | the skill that documents that step                           |
| an adapter's behaviour     | the same skill, and say what it does *now*, not what changed |
| an MCP tool                | every skill that names the tool                              |
| what an operation is *for* | probably several; grep for the step id                       |

Grep first. `grep -rl "loan.close" skills/` costs nothing and finds the ones you
forgot.

## Facts, beside the prose

Each skill has a `FACTS.md`: the same knowledge, in the shortest form that is
still true.

A section is prose, and prose earns its length; it carries the *why*, and the
sentences that tell a model how to *say* a thing are not compressible into claims
at all. But a question like "is gold borrowable on Aave v3" is answered by one
line, and answering it from prose alone costs the 542-word section that line sits
in.

So facts are indexed **beside** the prose rather than instead of it.
`find_skill` leads with facts and follows with the two best sections, which is
cheaper than five sections *and* finds more, because a fact is a small document
dense in the terms somebody actually searches for.

Two properties worth knowing:

* **One fact, one fragment.** Grouping a section's facts into one row would
  return them the way prose is returned: all of a section, to answer one
  question, which is exactly the cost this removes.
* **The heading is the join, and it is checked rather than trusted.** A fact
  names the section it came from and the section supplies the line range, so a
  fact cites the prose that backs it. A heading that no longer exists is a
  **build failure**, not a fact that quietly outlives its source.

Facts are the one thing here that is authored rather than derived. Everything
else in the index is reconciled from a file by content hash; extracting facts is
a model's job, and doing it at boot would make the corpus nondeterministic, slow,
and different in every process. So they are extracted once, reviewed by a person,
and committed.

## Writing for retrieval

The index searches **sections**, not whole files. Three arms rank them: an
English-stemmed one, a literal one that keeps identifiers intact, and BM25:
fused by reciprocal rank.

**Name the subject in the heading and in the first line of the body.** The
ranking cannot find a section that never says what it is about. Measured on this
corpus: the best answer to "what is an approval gate" is a section headed *"When
a run stops and asks"* which does not contain the string `approv` anywhere in it.

**Keep sections short.** BM25 divides by length, so a two-line answer beats an
essay that mentions the subject in passing, but only if those two lines exist as
their own section.

**Write identifiers exactly**: `arm_schedule`, `limit_price`, `loan.close`. The
literal arm exists so somebody typing a name finds it; an English stemmer mangles
those into something a search for the exact name no longer matches.

## A skill may only name a tool that exists

And more sharply: **a tool that spends is withheld from discussion.** A skill
telling the agent to call one while it is still working out what somebody wants
is a skill describing something that will be refused. See [the tool server](/tools) for which
five those are.

## The index rebuilds itself

The index is a **derived cache** in Postgres, and the repository wins on every
boot: unchanged sections are not rewritten, and sections absent from disk are
pruned, in one transaction.

* **Restart the tool server** after editing a skill and the change is live.
  There is nothing to migrate and nothing to remember.
* If Postgres will not answer, the process falls back to reading the files. The
  table is never a source of truth.
* On staging, skills are **baked into the image**, so an edit there needs a
  rebuild rather than a restart. The boot line naming how many sections were
  indexed is the proof it took.

Edit the markdown, restart the server, ask the question. Drift lives one deploy.

## Before you commit

* `grep -rn "<the thing you changed>" skills/`: did you get all of them?
* Restart the server and ask the question a person would ask, **in their words**.
* If a section you expected did not come back, the heading is the problem, not
  the ranking.


## Related topics

- [Every tool](/tools/reference.md)
- [The tool server](/tools.md)
- [DeFiLoops](/index.md)
- [Bounded execution](/routing.md)
- [Adapters](/adapters.md)
