Memory that understands
and stays bound to your code
Most AI memory is a pile of text chunks that never notices when the code moved on. SecondOS stores a structure-aware map, keeps it bound to the real symbols, and lets every tool read it. Here is what that buys you.
Memory intelligence
The whole category sells the same line: add memory to your agent. The hard part it skips is knowing when that memory is wrong. SecondOS scores it, dates it, catches it contradicting itself, and proposes it for you.
recall("how does auth hash?")
▸ "argon2id, m=64MB" trust 0.92 ✓ anchored, reused 7×
▸ "bcrypt, cost 12" trust 0.18 ⚠ stale · valid ≤ v1.2
≠ conflict: two answers, same scope → reviewConfidence / trust score
Every note gets one 0..1 score, folded from signals we already track: anchored to real code lifts it, going stale or aging sinks it, notes your agents reuse earn it. So a caller knows what to lean on versus verify.
Code-version validity
A memory can be marked no-longer-true as of a version and down-weighted in recall — not deleted. Hard validity windows sit next to soft temporal decay, so “true in v1.2” stays queryable instead of quietly lying.
Conflict detection
Same-subject notes that diverge are flagged for review by embedding distance alone — no model needed. Connect a completer and it upgrades to a real contradiction check that proposes which note supersedes which.
AI distillation
After a sync, SecondOS proposes durable memories from your codebase map — you accept or reject. Assisted, never auto-written, and map-only so it never reads your source. Proposals need a connected model; it degrades quietly without one.
Memory graph
Browse how notes attach to real symbols in a navigable graph, colored by trust so stale and low-confidence memory is visible at a glance. The memory finally has a map of its own.
Org / workspace memory
A workspace-scoped memory that isn't bound to one project — repo-spanning conventions that fold into every project's recall. One home for the rules your whole team keeps re-explaining.
A map of symbols, not a bag of chunks
SecondOS parses your repo with tree-sitter into real symbols, signatures, routes, imports and call-sites. Your tools get structure they can navigate, not a fuzzy pile of text they hope is relevant.
- Exact symbols + signatures, resolved imports and re-exports
- who_uses / impact_of — will-break vs might-break, ranked by confidence
- Body-chunk embeddings so search hits logic, not just names
# the map, not the source UserService.authenticate(email, token) ← called by routes/auth.ts:31 (resolved) ← called by jobs/session.ts:12 (resolved) → reads users, sessions (drizzle) impact_of: 2 will-break · 1 might-break
Memory that knows when it went stale
Every note is anchored to a real symbol at a real sync. When the code it describes changes, the memory is marked stale instead of quietly lying to your next agent. Freshness is a property, not a hope.
- Notes bound to path:symbol, resolved against the latest sync
- Code moves → bound memory flagged stale, ranked down in recall
- Temporal decay: six-month-old advice loses to today's
remember("auth uses argon2id")
scope packages/auth/hash.ts:hashPassword
state verified ✓ (symbol resolved)
… later, hashPassword rewritten …
state stale ⚠ (bound symbol changed)Catch the schema lie before it ships
SecondOS reads your Drizzle schema and the columns your code actually writes, then flags the gap. A column you insert that the schema doesn't have is surfaced as a read-only alert, with both locations.
- Parses pgTable / pgEnum into a schema model
- Extracts db.insert().values() / .update().set() write shapes
- High-confidence findings only — dynamic writes are skipped, not guessed
drift: users
code writes .values({ lastSeenAt })
schema has id, email, createdAt
⚠ column "lastSeenAt" not in schema
code routes/ping.ts:44
schema db/schema.ts:usersEvery note is anchored, versioned, revertible
Writes are validated against the graph before they land. Supersede a note and the old one is kept, not deleted. You get a history axis and a one-call restore, so memory accretes instead of drifting.
- Validated writes: unresolved refs saved as unverified, never silently dropped
- History + diff for any note, restore an earlier version without data loss
- Belief-revision pass dedups contradictions instead of poisoning recall
GET /memories/42/history v3 today "retry: 5x, backoff 2s" ← current v2 3 weeks ago "retry: 3x" superseded v1 sync-0f2 "no retry" superseded POST /memories/42/restore → v4 supersedes v3
One sync. Every tool reads the same map
This is the whole point. You index once and Cursor, Claude Code, Copilot, Cline and the rest read the same structure-aware map over MCP. No re-scanning per tool, no re-explaining per session.
- Six MCP tools: overview · search · recent_activity · who_uses · impact_of · schema_drift
- GitHub Action re-extracts on push so the map is always fresh
- Portable and exportable — the memory is yours, not locked in one IDE
$ bunx @secondos/cli push . ✓ 342 symbols · 51 routes · 13 tables Cursor → reads map over MCP Claude Code → reads map over MCP Copilot → reads map over MCP one index, every tool.
Read and drive your tools, with a confirm step
Beyond memory, SecondOS connects to ClickUp with an encrypted API key and lets you drive it from chat. Every write is drafted as a preview you explicitly confirm before anything happens.
- Connect ClickUp with an API key, hashed at rest
- Read tools are safe by default; writes draft a preview first
- Preview → explicit confirm → execute, with an audit log
you: close the login-bug task
daemon: preview
▸ update #4821 "login redirect bug"
status In Progress → Done
confirm? [y/N] ← nothing runs until you say soIndex once. Let every tool remember.
> daemon: isimleri değil, neyin neyi çağırdığını da bilirim.