Skip to content

Commit 102997c

Browse files
anandgupta42claude
andcommitted
feat: rebrand to Altimate Memory, add comprehensive docs and side-effect analysis
- Rename tool IDs to altimate_memory_read/write/delete - Add comprehensive documentation at docs/data-engineering/tools/memory-tools.md - Document context window impact, stale memory risks, wrong memory detection, security considerations, and mitigation strategies - Add altimate_change markers consistent with codebase conventions - Update tools index to include Altimate Memory category Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 28e0d6e commit 102997c

7 files changed

Lines changed: 259 additions & 10 deletions

File tree

docs/docs/data-engineering/tools/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ altimate has 55+ specialized tools organized by function.
1010
| [Lineage Tools](lineage-tools.md) | 1 tool | Column-level lineage tracing with confidence scoring |
1111
| [dbt Tools](dbt-tools.md) | 2 tools + 6 skills | Run, manifest parsing, test generation, scaffolding |
1212
| [Warehouse Tools](warehouse-tools.md) | 6 tools | Environment scanning, connection management, discovery, testing |
13+
| [Altimate Memory](memory-tools.md) | 3 tools | Persistent cross-session memory for warehouse config, conventions, and preferences |
1314

1415
All tools are available in the interactive TUI. The agent automatically selects the right tools based on your request.
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
# Altimate Memory Tools
2+
3+
Altimate Memory gives your data engineering agent **persistent, cross-session memory**. Instead of re-explaining your warehouse setup, naming conventions, or team preferences every session, the agent remembers what matters and picks up where you left off.
4+
5+
Memory blocks are plain Markdown files stored on disk — human-readable, version-controllable, and fully under your control.
6+
7+
## Why memory matters for data engineering
8+
9+
General-purpose coding agents treat every session as a blank slate. For data engineering, this is especially painful because:
10+
11+
- **Warehouse context is stable** — your Snowflake warehouse name, default database, and connection details rarely change, but you re-explain them every session.
12+
- **Naming conventions are tribal knowledge**`stg_` for staging, `int_` for intermediate, `fct_`/`dim_` for marts. The agent needs to learn these once, not every time.
13+
- **Past analyses inform future work** — if the agent optimized a query or traced lineage for a table last week, recalling that context avoids redundant work.
14+
- **User preferences accumulate** — SQL style, preferred dialects, dbt patterns, warehouse sizing decisions.
15+
16+
Altimate Memory solves this with three tools that let the agent save, recall, and manage its own persistent knowledge.
17+
18+
## Tools
19+
20+
### altimate_memory_read
21+
22+
Read memory blocks from previous sessions. Automatically called at session start to give the agent context.
23+
24+
```
25+
> Read my memory about warehouse configuration
26+
27+
Memory: 1 block(s)
28+
29+
### warehouse-config (project) [snowflake, warehouse]
30+
## Warehouse Configuration
31+
32+
- **Provider**: Snowflake
33+
- **Default warehouse**: ANALYTICS_WH (XS for dev, M for prod)
34+
- **Default database**: ANALYTICS_DB
35+
- **Naming convention**: stg_ for staging, int_ for intermediate, fct_/dim_ for marts
36+
```
37+
38+
**Parameters:**
39+
40+
| Parameter | Type | Default | Description |
41+
|---|---|---|---|
42+
| `scope` | `"global" \| "project" \| "all"` | `"all"` | Filter by scope |
43+
| `tags` | `string[]` | `[]` | Filter to blocks containing all specified tags |
44+
| `id` | `string` || Read a specific block by ID |
45+
46+
---
47+
48+
### altimate_memory_write
49+
50+
Create or update a persistent memory block.
51+
52+
```
53+
> Remember that our Snowflake warehouse is ANALYTICS_WH and we use stg_ prefix for staging models
54+
55+
Memory: Created "warehouse-config"
56+
```
57+
58+
The agent automatically calls this when it learns something worth persisting — you can also explicitly ask it to "remember" something.
59+
60+
**Parameters:**
61+
62+
| Parameter | Type | Required | Description |
63+
|---|---|---|---|
64+
| `id` | `string` | Yes | Unique identifier (lowercase, hyphens/underscores). Examples: `warehouse-config`, `naming-conventions` |
65+
| `scope` | `"global" \| "project"` | Yes | `global` for user-wide preferences, `project` for project-specific knowledge |
66+
| `content` | `string` | Yes | Markdown content (max 2,048 characters) |
67+
| `tags` | `string[]` | No | Up to 10 tags for categorization (max 64 chars each) |
68+
69+
---
70+
71+
### altimate_memory_delete
72+
73+
Remove a memory block that is outdated, incorrect, or no longer relevant.
74+
75+
```
76+
> Forget the old warehouse config, we migrated to BigQuery
77+
78+
Memory: Deleted "warehouse-config"
79+
```
80+
81+
**Parameters:**
82+
83+
| Parameter | Type | Required | Description |
84+
|---|---|---|---|
85+
| `id` | `string` | Yes | ID of the block to delete |
86+
| `scope` | `"global" \| "project"` | Yes | Scope of the block to delete |
87+
88+
## Scoping
89+
90+
Memory blocks live in two scopes:
91+
92+
| Scope | Storage location | Use case |
93+
|---|---|---|
94+
| **global** | `~/.local/share/altimate-code/memory/` | User-wide preferences: SQL style, preferred models, general conventions |
95+
| **project** | `.opencode/memory/` (in project root) | Project-specific: warehouse config, naming conventions, data model notes, past analyses |
96+
97+
Project memory travels with your repo. Add `.opencode/memory/` to `.gitignore` if it contains sensitive information, or commit it to share team conventions.
98+
99+
## File format
100+
101+
Each block is a Markdown file with YAML frontmatter:
102+
103+
```markdown
104+
---
105+
id: warehouse-config
106+
scope: project
107+
created: 2026-03-14T10:00:00.000Z
108+
updated: 2026-03-14T10:00:00.000Z
109+
tags: ["snowflake", "warehouse"]
110+
---
111+
112+
## Warehouse Configuration
113+
114+
- **Provider**: Snowflake
115+
- **Default warehouse**: ANALYTICS_WH
116+
- **Default database**: ANALYTICS_DB
117+
```
118+
119+
Files are human-readable and editable. You can create, edit, or delete them manually — the agent will pick up changes on the next session.
120+
121+
## Limits and safety
122+
123+
| Limit | Value | Rationale |
124+
|---|---|---|
125+
| Max block size | 2,048 characters | Prevents any single block from consuming too much context |
126+
| Max blocks per scope | 50 | Bounds total memory footprint |
127+
| Max tags per block | 10 | Keeps metadata manageable |
128+
| Max tag length | 64 characters | Prevents tag abuse |
129+
| Max ID length | 128 characters | Reasonable filename length |
130+
131+
### Atomic writes
132+
133+
Blocks are written to a temporary file first, then atomically renamed. This prevents corruption if the process is interrupted mid-write.
134+
135+
## Context window impact
136+
137+
Altimate Memory injects relevant blocks into the system prompt at session start, subject to a configurable token budget (default: 8,000 characters). Blocks are sorted by last-updated timestamp, so the most recently relevant information is loaded first.
138+
139+
**What this means in practice:**
140+
141+
- With a typical block size of 200-500 characters, the default budget comfortably fits 15-40 blocks
142+
- Memory injection adds a one-time cost at session start — it does not grow during the session
143+
- If you notice context pressure, reduce the number of blocks or keep them concise
144+
- The agent's own tool calls and responses consume far more context than memory blocks
145+
146+
!!! tip
147+
Keep blocks concise and focused. A block titled "warehouse-config" with 5 bullet points is better than a wall of text. The agent can always call `altimate_memory_read` to fetch specific blocks on demand.
148+
149+
## Potential side effects and how to handle them
150+
151+
### Stale or incorrect memory
152+
153+
Memory blocks persist indefinitely. If your warehouse configuration changes or a convention is updated, the agent will continue using outdated information until the block is updated or deleted.
154+
155+
**How to detect:** If the agent makes assumptions that don't match your current setup (e.g., references an old warehouse name), check what's in memory:
156+
157+
```
158+
> Show me all memory blocks
159+
160+
> Delete the warehouse-config block, it's outdated
161+
```
162+
163+
**How to prevent:**
164+
165+
- Review memory blocks periodically — they're plain Markdown files you can inspect directly
166+
- Ask the agent to "forget" outdated information when things change
167+
- Keep blocks focused on stable facts rather than ephemeral details
168+
169+
### Wrong information getting saved
170+
171+
The agent decides what to save based on conversation context. It may occasionally save incorrect inferences or overly specific details that don't generalize well.
172+
173+
**How to detect:**
174+
175+
- After a session where the agent saved memory, review what was written:
176+
```bash
177+
ls .opencode/memory/ # project memory
178+
cat .opencode/memory/*.md # inspect all blocks
179+
```
180+
- The agent always reports when it creates or updates a memory block, so watch for `Memory: Created "..."` or `Memory: Updated "..."` messages in the session output
181+
182+
**How to fix:**
183+
184+
- Delete the bad block: ask the agent or run `rm .opencode/memory/bad-block.md`
185+
- Edit the file directly — it's just Markdown
186+
- Ask the agent to rewrite it: "Update the warehouse-config memory with the correct warehouse name"
187+
188+
### Context bloat
189+
190+
With 50 blocks at 2KB each, the theoretical maximum injection is ~100KB. In practice, the 8,000-character default budget caps injection at well under 10KB.
191+
192+
**Signs of context bloat:**
193+
194+
- Frequent auto-compaction (visible in the TUI)
195+
- The agent losing track of your current task because memory is crowding out working context
196+
197+
**How to mitigate:**
198+
199+
- Keep the total block count low (10-20 active blocks is a sweet spot)
200+
- Delete blocks you no longer need
201+
- Use tags to categorize and let the agent filter to what's relevant
202+
- Reduce the injection budget if needed
203+
204+
### Security considerations
205+
206+
Memory blocks are stored as plaintext files on disk. Be mindful of what gets saved:
207+
208+
- **Do not** save credentials, API keys, or connection strings in memory blocks
209+
- **Do** save structural information (warehouse names, naming conventions, schema patterns)
210+
- If using project-scoped memory in a shared repo, add `.opencode/memory/` to `.gitignore` to avoid committing sensitive context
211+
- Memory blocks are scoped per-user (global) and per-project — there is no cross-user or cross-project leakage
212+
213+
!!! warning
214+
Memory blocks are not encrypted. Treat them like any other configuration file on your machine. Do not store secrets or PII in memory blocks.
215+
216+
## Examples
217+
218+
### Data engineering team setup
219+
220+
```
221+
> Remember: we use Snowflake with warehouse COMPUTE_WH for dev and ANALYTICS_WH for prod.
222+
Our dbt project uses the staging/intermediate/marts pattern with stg_, int_, fct_, dim_ prefixes.
223+
Always use QUALIFY instead of subqueries for deduplication.
224+
225+
Memory: Created "team-conventions" in project scope
226+
```
227+
228+
### Personal SQL preferences
229+
230+
```
231+
> Remember globally: I prefer CTEs over subqueries, always use explicit column lists
232+
(no SELECT *), and format SQL with lowercase keywords.
233+
234+
Memory: Created "sql-preferences" in global scope
235+
```
236+
237+
### Recalling past work
238+
239+
```
240+
> What do you remember about our warehouse?
241+
242+
Memory: 2 block(s)
243+
### warehouse-config (project) [snowflake]
244+
...
245+
### team-conventions (project) [dbt, conventions]
246+
...
247+
```

packages/opencode/src/memory/store.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// altimate_change - Altimate Memory persistent store
12
import fs from "fs/promises"
23
import path from "path"
34
import { Global } from "@/global"

packages/opencode/src/memory/tools/memory-delete.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import z from "zod"
22
import { Tool } from "../../tool/tool"
33
import { MemoryStore } from "../store"
44

5-
export const MemoryDeleteTool = Tool.define("memory_delete", {
5+
export const MemoryDeleteTool = Tool.define("altimate_memory_delete", {
66
description:
7-
"Delete a persistent memory block that is outdated, incorrect, or no longer needed. Use this to keep memory clean and relevant.",
7+
"Delete an Altimate Memory block that is outdated, incorrect, or no longer needed. Use this to keep Altimate Memory clean and relevant.",
88
parameters: z.object({
99
id: z.string().min(1).describe("The ID of the memory block to delete"),
1010
scope: z
@@ -24,7 +24,7 @@ export const MemoryDeleteTool = Tool.define("memory_delete", {
2424
return {
2525
title: `Memory: Not found "${args.id}"`,
2626
metadata: { deleted: false, id: args.id, scope: args.scope },
27-
output: `No memory block found with ID "${args.id}" in ${args.scope} scope. Use memory_read to list existing blocks.`,
27+
output: `No memory block found with ID "${args.id}" in ${args.scope} scope. Use altimate_memory_read to list existing blocks.`,
2828
}
2929
} catch (e) {
3030
const msg = e instanceof Error ? e.message : String(e)

packages/opencode/src/memory/tools/memory-read.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import { Tool } from "../../tool/tool"
33
import { MemoryStore } from "../store"
44
import { MemoryPrompt } from "../prompt"
55

6-
export const MemoryReadTool = Tool.define("memory_read", {
6+
export const MemoryReadTool = Tool.define("altimate_memory_read", {
77
description:
8-
"Read persistent memory blocks from previous sessions. Use this to recall warehouse configurations, naming conventions, team preferences, and past analysis decisions. Supports filtering by scope (global/project) and tags.",
8+
"Read Altimate Memory blocks from previous sessions. Use this to recall warehouse configurations, naming conventions, team preferences, and past analysis decisions. Supports filtering by scope (global/project) and tags.",
99
parameters: z.object({
1010
scope: z
1111
.enum(["global", "project", "all"])
@@ -55,7 +55,7 @@ export const MemoryReadTool = Tool.define("memory_read", {
5555
return {
5656
title: "Memory: empty",
5757
metadata: { count: 0 },
58-
output: "No memory blocks found. Use memory_write to save information for future sessions.",
58+
output: "No memory blocks found. Use altimate_memory_write to save information for future sessions.",
5959
}
6060
}
6161

packages/opencode/src/memory/tools/memory-write.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { Tool } from "../../tool/tool"
33
import { MemoryStore } from "../store"
44
import { MEMORY_MAX_BLOCK_SIZE, MEMORY_MAX_BLOCKS_PER_SCOPE } from "../types"
55

6-
export const MemoryWriteTool = Tool.define("memory_write", {
7-
description: `Create or update a persistent memory block. Use this to save information worth remembering across sessions — warehouse configurations, naming conventions, team preferences, data model notes, or past analysis decisions. Each block is a Markdown file persisted to disk. Max ${MEMORY_MAX_BLOCK_SIZE} chars per block, ${MEMORY_MAX_BLOCKS_PER_SCOPE} blocks per scope.`,
6+
export const MemoryWriteTool = Tool.define("altimate_memory_write", {
7+
description: `Save an Altimate Memory block for cross-session persistence. Use this to store information worth remembering across sessions — warehouse configurations, naming conventions, team preferences, data model notes, or past analysis decisions. Each block is a Markdown file persisted to disk. Max ${MEMORY_MAX_BLOCK_SIZE} chars per block, ${MEMORY_MAX_BLOCKS_PER_SCOPE} blocks per scope.`,
88
parameters: z.object({
99
id: z
1010
.string()

packages/opencode/src/tool/registry.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ import { DatamateManagerTool } from "../altimate/tools/datamate"
103103
import { FeedbackSubmitTool } from "../altimate/tools/feedback-submit"
104104
// altimate_change end
105105

106-
// altimate_change start - import persistent memory tools
106+
// altimate_change start - import altimate persistent memory tools
107107
import { MemoryReadTool } from "../memory/tools/memory-read"
108108
import { MemoryWriteTool } from "../memory/tools/memory-write"
109109
import { MemoryDeleteTool } from "../memory/tools/memory-delete"
@@ -272,7 +272,7 @@ export namespace ToolRegistry {
272272
DatamateManagerTool,
273273
FeedbackSubmitTool,
274274
// altimate_change end
275-
// altimate_change start - register persistent memory tools
275+
// altimate_change start - register altimate persistent memory tools
276276
MemoryReadTool,
277277
MemoryWriteTool,
278278
MemoryDeleteTool,

0 commit comments

Comments
 (0)