| 1 | # Context Engine v2: Instructions, Memory, and Retrieval |
| 2 | |
| 3 | Context Engine v2 gives Reasonix two durable context layers with different |
| 4 | authority: |
| 5 | |
| 6 | - **Standing instructions** define how the agent must work. |
| 7 | - **Background memory** stores facts that may help later but can become stale. |
| 8 | |
| 9 | Keeping those layers separate is the central design rule. A fact should not |
| 10 | silently become a command, and a long-lived rule should not depend on retrieval |
| 11 | finding it at the right moment. |
| 12 | |
| 13 | ## Choose the right layer |
| 14 | |
| 15 | | Put this in | Use it for | Examples | |
| 16 | | --- | --- | --- | |
| 17 | | `AGENTS.md`, `REASONIX.md`, or `CLAUDE.md` | Rules that must be present on every relevant turn | required test commands, repository boundaries, review conventions | |
| 18 | | Project memory | Durable facts that apply only to this workspace | release branch, non-obvious service constraint, project ticket URL | |
| 19 | | Global memory | A fact that should be available in every workspace | a user preference explicitly chosen as global | |
| 20 | | Session history | Original wording, tool output, or a decision that is not yet a stable fact | an error from yesterday, an abandoned approach | |
| 21 | |
| 22 | Keep instruction files short. They are part of the cache-stable prompt prefix, |
| 23 | so every extra paragraph is carried by every turn. Store discoverable facts as |
| 24 | memory instead. |
| 25 | |
| 26 | A minimal project file is usually enough: |
| 27 | |
| 28 | ```markdown |
| 29 | # Build and verify |
| 30 | |
| 31 | - Run `go test ./...` before reporting completion. |
| 32 | - Do not edit generated files under `desktop/frontend/src/generated/`. |
| 33 | - Keep public API changes backward compatible. |
| 34 | ``` |
| 35 | |
| 36 | In the CLI, `/remember <note>` and `# <note>` directly append a note to the |
| 37 | project instruction document. They are shortcuts for standing guidance, not the |
| 38 | agent's background-fact `remember` tool. |
| 39 | |
| 40 | ## Instruction resolution |
| 41 | |
| 42 | Reasonix recognizes `REASONIX.md`, `AGENTS.md`, and `CLAUDE.md`, plus matching |
| 43 | `.local.md` variants. It first loads user-global instruction files from the |
| 44 | Reasonix home directory. It then walks from the workspace root to the target |
| 45 | path; at each directory it loads the normal files followed by that directory's |
| 46 | `.local.md` files. |
| 47 | |
| 48 | Deeper directories beat broader directories, and a local variant beats normal |
| 49 | files in the same directory. Later entries therefore win when rules conflict. |
| 50 | The current user request remains the highest-authority user instruction. Files |
| 51 | with identical expanded content are deduplicated, preferring the more specific |
| 52 | source. |
| 53 | |
| 54 | An instruction file can import another file with a standalone relative line: |
| 55 | |
| 56 | ```markdown |
| 57 | @docs/agent-testing.md |
| 58 | ``` |
| 59 | |
| 60 | Imports are expanded deterministically, deduplicated, limited to five levels, |
| 61 | and confined to the directory owned by the source instruction file. Absolute |
| 62 | paths, parent escapes, symlink escapes, unreadable imports, and cycles are |
| 63 | rejected and surfaced as diagnostics rather than silently trusted. |
| 64 | |
| 65 | Use the following command to see the actual result: |
| 66 | |
| 67 | ```text |
| 68 | /memory instructions |
| 69 | ``` |
| 70 | |
| 71 | It reports load precedence, scope, target directory, imports, and diagnostics. |
| 72 | The desktop Context Center exposes the same provenance. |
| 73 | |
| 74 | ## Background fact model |
| 75 | |
| 76 | Each fact is a Markdown file with: |
| 77 | |
| 78 | - an immutable `id`; |
| 79 | - a monotonic `revision`; |
| 80 | - `created_at` and `updated_at` timestamps; |
| 81 | - a human-readable name, title, and description; |
| 82 | - an independent `type` and `scope`; |
| 83 | - optional search `keywords` — aliases and translations of key terms that let |
| 84 | a paraphrased or cross-language query reach the fact; |
| 85 | - an optional `subject_key` — a dotted key naming the question the fact |
| 86 | answers (`project.package_manager`, `user.response_style`); |
| 87 | - the Markdown body. |
| 88 | |
| 89 | `type` classifies the content: |
| 90 | |
| 91 | - `user`: user identity or preferences; |
| 92 | - `feedback`: guidance about how to work and why; |
| 93 | - `project`: project goals or constraints not already evident in the repository; |
| 94 | - `reference`: external resources such as URLs or ticket IDs. |
| 95 | |
| 96 | `scope` controls reach: |
| 97 | |
| 98 | - `project` is the safe default; |
| 99 | - `global` must be chosen explicitly. |
| 100 | |
| 101 | Type does not imply scope. Project feedback remains project-local, and a global |
| 102 | reference remains a reference. |
| 103 | |
| 104 | A subject key is the knowledge-conflict model: one scope holds at most one |
| 105 | active value per subject. Saving a second fact for a held subject is rejected |
| 106 | with the holder's id, so "npm → pnpm" becomes a revision of one fact instead |
| 107 | of two contradicting facts both staying active. `/memory subjects` lists the |
| 108 | keys in use; facts answering the same subject count as equivalent for |
| 109 | overrides and recall suppression regardless of their names and titles. |
| 110 | |
| 111 | When equivalent project and global facts exist, automatic recall uses the |
| 112 | project fact. Both remain visible in Context Center and `/memory`, with the |
| 113 | override explained instead of deleting or hiding either source. |
| 114 | |
| 115 | A third dimension, `activation`, is orthogonal to both: `relevant` (the |
| 116 | default) keeps a fact retrieval-only, while `pinned` snapshots its body into a |
| 117 | lower-priority `session-context` section before the next real user turn. Pinning |
| 118 | is an |
| 119 | explicit user choice (`/memory pin <id-or-name>`, or asking the assistant), |
| 120 | and total pinned bodies are capped at 1,500 characters — enforced when |
| 121 | pinning, with overflow directed to REASONIX.md/AGENTS.md instructions, where |
| 122 | always-binding rules belong. A fact is either pinned (in `session-context`) or |
| 123 | relevant (recallable): never both, never neither. |
| 124 | |
| 125 | For compatibility, legacy globally scoped `user` and `feedback` facts that |
| 126 | predate the field stay pinned until explicitly unpinned. When an equivalent |
| 127 | project fact exists, it suppresses pinned global guidance before the background |
| 128 | snapshot is built, so project-over-global precedence does not depend on a later |
| 129 | recall match. |
| 130 | |
| 131 | ## Automatic recall |
| 132 | |
| 133 | Before each real user turn, Reasonix searches active facts using the raw user |
| 134 | message. Host-added provider context is not fed back into the query. The selected |
| 135 | facts are appended to that user turn as a bounded, low-authority suffix; they do |
| 136 | not mutate the system prompt or tool schema. |
| 137 | |
| 138 | Recall is conservative: |
| 139 | |
| 140 | - generic turns such as "continue" do not trigger recall; |
| 141 | - distinctive lexical matches are ranked with BM25 (CJK text is matched by |
| 142 | character bigrams, so a hit needs a real word overlap, not scattered common |
| 143 | characters); |
| 144 | - project facts receive a small relevance preference; |
| 145 | - stale facts are down-ranked, not silently deleted; |
| 146 | - equivalent project facts suppress global fallbacks for that recall; |
| 147 | - global `user` / `feedback` facts already present as stable guidance are not |
| 148 | duplicated by automatic recall; |
| 149 | - at most four facts and 2,400 characters are included by default; |
| 150 | - fact storage paths are omitted, and home-directory prefixes in snippets are |
| 151 | replaced with `<local-home>`. |
| 152 | |
| 153 | Freshness defaults depend on fact type: |
| 154 | |
| 155 | | Type | Fresh | Current | Stale after | |
| 156 | | --- | ---: | ---: | ---: | |
| 157 | | `reference` | 14 days | 45 days | 45 days | |
| 158 | | `project` | 30 days | 180 days | 180 days | |
| 159 | | `user`, `feedback` | 90 days | 365 days | 365 days | |
| 160 | |
| 161 | Type is a default, not a truth about volatility — a README location can hold |
| 162 | for years while a release branch dies in days. An explicit `volatility` |
| 163 | overrides the type windows: `volatile` (7 / 30 days), `stable` (90 / 365 |
| 164 | days), or `evergreen` (never ages). Two optional timestamps refine it further: |
| 165 | `expires_at` is a hard boundary — past it the fact is `expired` and excluded |
| 166 | from automatic recall entirely (explicit search still finds it) — and |
| 167 | `last_verified_at`, stamped by `/memory verify <id-or-name>` or by the |
| 168 | assistant re-confirming a fact, renews the freshness clock without changing |
| 169 | what `updated_at` means. |
| 170 | |
| 171 | Freshness is a warning and ranking signal, not a truth claim. Recalled text |
| 172 | explicitly tells the model that it may be wrong and cannot override the current |
| 173 | request or standing instructions. |
| 174 | |
| 175 | Inspect the last decision with: |
| 176 | |
| 177 | ```text |
| 178 | /memory recall |
| 179 | ``` |
| 180 | |
| 181 | The trace includes the query, selected IDs and revisions, scores, match reasons, |
| 182 | freshness, budget use, omitted count, and suppression reason. |
| 183 | |
| 184 | The explicit read-only `memory` tool remains available for deeper `search`, |
| 185 | `read`, and `list` operations. Use `history` instead when exact wording or tool |
| 186 | output matters. |
| 187 | |
| 188 | ## Safe writes and confirmation |
| 189 | |
| 190 | The ordinary path is zero-configuration. Reasonix may automatically create a |
| 191 | new memory only when all of these conditions hold: |
| 192 | |
| 193 | - the owning controller has the current project store (interactive or top-level |
| 194 | headless, never a sub-agent); |
| 195 | - the type is explicitly `project` or `reference`; |
| 196 | - the scope is project or omitted; |
| 197 | - the operation is create-only, not an update; |
| 198 | - the body is within the automatic-write budget; |
| 199 | - no credential, secret, private key, or email address is detected; |
| 200 | - no fact with the same name, title, or description already exists. |
| 201 | |
| 202 | The grant is one-shot and the storage layer enforces create-only semantics, so a |
| 203 | concurrent fact cannot be overwritten after assessment. |
| 204 | |
| 205 | Under Read only, everything else still requires explicit confirmation: |
| 206 | |
| 207 | - global facts; |
| 208 | - `user` preferences and `feedback`; |
| 209 | - updates to an existing ID or revision; |
| 210 | - possible duplicates; |
| 211 | - sensitive or oversized content; |
| 212 | - every `forget` operation. |
| 213 | |
| 214 | Read only keeps those confirmations. Workspace write treats `remember` and |
| 215 | `forget` as normal policy fallback inside its permitted scope, while explicit |
| 216 | `ask` and `deny` rules remain effective. Full access skips ordinary memory |
| 217 | prompts unless an explicit deny rule matches. Guardian and permission hooks |
| 218 | cannot approve them for the user. A top-level headless controller may use only |
| 219 | the same one-shot low-risk create path above. Sub-agents and |
| 220 | headless surfaces without the owning scoped controller fail closed; all other |
| 221 | headless memory mutations still require an interactive confirmation surface. |
| 222 | |
| 223 | Direct edits made by the user in Context Center, `/remember`, restore, and |
| 224 | recovery commands are already explicit user actions and do not add another |
| 225 | approval prompt. |
| 226 | |
| 227 | ## Revisions, archive, and recovery |
| 228 | |
| 229 | Updating a fact creates an immutable snapshot of the previous revision. A stale |
| 230 | `expected_revision` is rejected instead of overwriting a newer edit. |
| 231 | |
| 232 | Restoring an old revision does not rewind storage in place. Reasonix copies the |
| 233 | chosen content into a new, higher revision, preserving a monotonic audit trail: |
| 234 | |
| 235 | ```text |
| 236 | /memory revisions <id-or-name> |
| 237 | /memory restore <id-or-name> <revision> |
| 238 | ``` |
| 239 | |
| 240 | `forget` removes a fact from active recall and moves it to `.archive/`. Recovery |
| 241 | accepts only an archive entry owned by the current store, rejects symlink and |
| 242 | path escapes, refuses ID/name collisions, and never overwrites an active file: |
| 243 | |
| 244 | ```text |
| 245 | /memory archived |
| 246 | /memory recover <archive-path> |
| 247 | ``` |
| 248 | |
| 249 | Recovered content also becomes a new monotonic revision. Restore and recovery |
| 250 | mark the background snapshot dirty; one complete replacement `session-context` |
| 251 | is appended before the next real user turn. |
| 252 | |
| 253 | ## Zero-configuration suggestions |
| 254 | |
| 255 | Opening the desktop Suggestions tab automatically scans recent local user turns. |
| 256 | There is no setup toggle. It proposes: |
| 257 | |
| 258 | - durable memory candidates from explicit preferences, constraints, and project |
| 259 | conventions; |
| 260 | - Skill candidates from repeated workflow patterns. |
| 261 | |
| 262 | Scanning uses original user content, deduplicates against facts from both scopes |
| 263 | and loaded instruction bodies, and never writes by itself. Every candidate shows |
| 264 | evidence and must be explicitly accepted. Remote workspaces fail closed: |
| 265 | Reasonix does not fall back to local sessions or local memory when the remote |
| 266 | surface cannot provide the feature. |
| 267 | |
| 268 | ## Management surfaces |
| 269 | |
| 270 | Bare `/memory` shows every active fact from both scopes, including ID, revision, |
| 271 | type, scope, freshness, and storage provenance. Structured completion is |
| 272 | available in CLI, desktop, and remote workspaces. |
| 273 | |
| 274 | | Command | Result | |
| 275 | | --- | --- | |
| 276 | | `/memory` | Combined instruction, fact, and archive summary | |
| 277 | | `/memory instructions` | Precedence, directories, imports, diagnostics | |
| 278 | | `/memory recall` | Last automatic-recall trace | |
| 279 | | `/memory revisions <ref>` | Active fact and immutable history | |
| 280 | | `/memory restore <ref> <revision>` | Restore as a new revision | |
| 281 | | `/memory archived` | Archived facts and paths | |
| 282 | | `/memory recover <path>` | Recover an owned archive as a new revision | |
| 283 | |
| 284 | Context Center provides the same model visually, including conflicts and |
| 285 | project-over-global explanations. |
| 286 | |
| 287 | ## Upgrade compatibility |
| 288 | |
| 289 | Context Engine v2 upgrades existing stores without requiring setup: |
| 290 | |
| 291 | - legacy facts without IDs receive deterministic `legacy-*` identities; |
| 292 | - missing revisions start at revision 1; |
| 293 | - missing scope is inferred from the containing project/global directory; |
| 294 | - migration is idempotent and writes the new metadata only once; |
| 295 | - compatibility routing fields keep older clients from moving facts to the |
| 296 | wrong directory when versions share a state root; |
| 297 | - old `MEMORY.md` indexes are treated as derived data and rebuilt from fact |
| 298 | files; |
| 299 | - legacy Memory v5 `<memory-compiler-execution>` transcript blocks remain |
| 300 | readable, while the retired `[agent].memory_compiler` setting is removed. |
| 301 | |
| 302 | No vector database, embedding service, setup wizard, or re-index command is |
| 303 | required. |
| 304 | |
| 305 | ## Cache and privacy contract |
| 306 | |
| 307 | - Standing instructions join the stable system prefix at session start. The |
| 308 | derived index and pinned guidance live in the versioned `session-context` |
| 309 | snapshot and refresh before the next real user turn when their digest changes. |
| 310 | - Provider-visible instruction provenance uses stable `workspace/...` and |
| 311 | `user/...` labels; absolute source and store paths stay in local diagnostics. |
| 312 | - Provider-visible memory tool results use stable `project/<name>.md` and |
| 313 | `global/<name>.md` references. Those references round-trip directly through |
| 314 | read, update, revision, and archive operations, including when both scopes |
| 315 | contain the same name; Context Center and local recovery diagnostics retain |
| 316 | the real storage paths. |
| 317 | - Dynamic recall is appended only to the current user turn. |
| 318 | - Diagnostics never enter provider requests. |
| 319 | - Automatic recall omits fact storage paths and redacts home-directory prefixes |
| 320 | in snippets. |
| 321 | - External approval notifications receive the tool name, not memory contents. |
| 322 | - Remote management uses the remote controller's memory catalog and never reads |
| 323 | the desktop machine's local store as a fallback. |
| 324 | |
| 325 | This keeps the provider-visible prefix stable while making dynamic context |
| 326 | observable and recoverable. |
| 327 |