retrieval
A memory is only as useful as what reaches the conversation. innernet never hands an AI the whole map and hopes. Every ask goes through one door, innernet_context, and comes back as a small, ranked package with a receipt.
the one call#
{ "name": "innernet_context", "arguments": { "slug": "my-product", "intent": "what did we decide about pricing?" } }intent is the question in the person's own words. Not a keyword list, not "pricing": the whole ask. The selector reads it the way a person would, and a precise question gets a precise slice. Over REST it is the same handler:
curl "https://innernet.live/api/v1/context?slug=my-product&intent=what+did+we+decide+about+pricing" \
-H "Authorization: Bearer innernet_..."what comes back#
| field | what it is |
|---|---|
read_first | One line: answer from focus, or the memory holds nothing on this. It ends by saying what time it is for the person, in their own timezone. Read it before anything else. |
now | The moment on the person's own clock: { date, local, tz, known_tz }. When they keep no timezone it is UTC, and known_tz says it is a guess. |
focus | The sections that answer the ask, best first: { dimension, section, text }. A section too long to fit is excerpted and marked partial. A section that writes a date of its own carries dated: the date it speaks from and how long ago that is. When it holds numbers and that date is a month or more gone, it is marked snapshot: that day's reading, not today's. Every section also carries standing: what kind of memory it is, how age has touched it, and, when it is stale or superseded, one line on what to do before using it as the present (see how memory ages). |
periphery | A handful of near-misses, { ref, summary }: close enough to mention, not close enough to send whole. |
retrieval_advice | What to open next if the conversation turns (usually an innernet_get_dimension call). |
spine | What this project is: name, tagline, type, its core, open tasks, what moved lately, and as_of. |
map | Every dimension by name, so nothing in the memory is out of reach. |
personal_context | Only when facts about the person bear on this ask, and only shareable ones. Each fact says when it was last confirmed (as_of), and standing when its kind has aged it. |
sent | The receipt: which selector chose the slice, how many tokens went, how many personal facts were shared, how many private ones were withheld. |
meta | holds_answer, asks_about_past, to_confirm (the sections in focus that are stale or superseded), and the counts behind the receipt. |
the budget#
Focus has a hard ceiling of about 1,600 tokens. The package is bounded by the ask, never by the size of the memory: a map with nine hundred sections answers in the same one to two thousand tokens as a small one. That is what keeps innernet cheap to call on every turn, and it is why a good intent matters more than a big context window.
when the memory holds nothing#
meta.holds_answer: false and a read_first that says so. That is an answer, not a failure: the AI should say the memory has nothing on it rather than guess from the project name. The periphery still lists what was close, so the conversation can go there instead.
history stays out of the way#
Every dimension keeps its superseded decisions under a ## history heading. Retrieval leaves those lines out of focus, because an AI that reads "was X, now Y" next to "Y" tends to repeat the X. When the ask is about the past ("what did we use before?", "why did we change…"), meta.asks_about_past flips and the history of every admitted dimension rides along. See branches & history.
how memory ages#
Not every memory gets old the same way. A law written in june is as true in october. A number read on 24 july is a reading of 24 july. So innernet gives every section a kind, and every kind its own curve:
| kind | half-life | floor | what age does |
|---|---|---|---|
| law | never | 1.00 | nothing: a law stands until it is replaced |
| decision | 365 days | 0.75 | fades slowly, holds until a newer decision |
| reference | 180 days | 0.70 | how a thing works drifts as it is rebuilt |
| note | 90 days | 0.80 | everything else |
| plan | 60 days | 0.50 | a bet on a future that arrives |
| status | 14 days | 0.35 | where things stand is true for days |
| count | 10 days | 0.30 | a number is true on the day it was read |
A section's age is the newest date it writes itself (never a ## history line); else the date its page's opening declares (rewritten 2026-07-24, as of …); else, most weakly, when its page was last saved. Its state follows: standing (a law), current (inside one half-life), aging (one to three), stale (past three: confirm it before saying it is still so), superseded (a newer reading on the same subject exists: read that first), or undated.
Age orders, it never hides. Relevance alone decides what reaches focus. The weight only orders what was admitted, so under the fixed budget the present is packed before the past. When the ask is about the past, every weight is 1.
A newer reading supersedes an older one. A page that says the present reading is [[x]] hands its numbers and statuses over to x, and superseded by [[x]] hands over its plans too. A section that says it replaces a page supersedes that page's older readings, and two dated readings on the same subject, two weeks or more apart, softly do the same. When an older reading reaches focus, the one that replaced it takes its place in the order, and the older one follows at its aged weight. Laws and decisions are never superseded by a reading: they are replaced by rewriting them, and ## history keeps the old one.
Readings are dated at birth. When a page is saved, by you or by netti, a section that ages fast (a count, a status, a plan), writes no date, and changed in this save gets one quiet line at its end: _as of 2026-10-08_, on your own calendar. An unchanged section keeps what it had.
You can say what a section is. Put <!-- ages: law --> anywhere in a section (it does not render), or ages: decision in a page's frontmatter. Otherwise innernet reads the kind from the section's heading (a plan full of percentage targets is still a plan), then from numbers in its text, then from the page's name.
Facts about you age the same way, by what they are about: who you are stands, how you work holds for a long time, what you use drifts, and what you are in the middle of goes stale in weeks.
captures that haven't folded yet#
A capture lands in the commit log in milliseconds; netti folds it into dimensions afterwards. Until it does, retrieval splices recent captures in as a pending_captures section on projects you own, so something you said a minute ago is already answerable.
lean loads, full opens#
innernet_load_project is lean by default: one line per dimension, the capture protocol and a slice of personal context. It orients a session. innernet_get_dimension opens one page whole when the conversation turns that way, and full: true on a load returns every body (the REST GET /projects/{slug} always does). For answering questions, innernet_context is almost always the right call.