Files
cortex/USAGE.md
omigamedev f1b59a2d1a Add freshness scoring, auto-decay, and USAGE.md
Add lastAccessedAt timestamp to nodes with schema migration and
backfill. Touch timestamp on read, apply exponential freshness decay
(~69-day half-life) to search scoring alongside BM25 and vector
weights. Add auto-decay that marks untouched nodes as stale after a
configurable threshold, with CLI command and server-side daily interval.
Include comprehensive USAGE.md documenting all CLI commands and REST API.
2026-02-02 22:07:06 +01:00

7.0 KiB

Cortex — AI Project Memory & Knowledge Graph

Overview

Cortex is a CLI tool and web server for storing, linking, and searching project knowledge as a graph of typed nodes and edges. It supports hybrid search (BM25 + vector similarity + freshness), auto-decay of stale nodes, and a web portal for visualization.

Data is stored in .memory/cortex.db (SQLite) in the current working directory.


CLI Reference

All commands are invoked as memory <command>.

memory add <kind>

Add a node to the knowledge graph.

Argument / Option Required Description
<kind> yes Node kind: memory, component, task, decision
-t, --title <title> yes Node title
-c, --content <content> no Node content/description
--tags <tags> no Comma-separated tags
--status <status> no Status (e.g. todo, doing, done, active, deprecated)
memory add memory -t "Auth flow design" -c "OAuth2 PKCE flow for SPA" --tags auth,security --status active
memory add task -t "Implement login page" --status todo
memory add decision -t "Use PostgreSQL" -c "Chose Postgres over MySQL for JSON support"
memory add component -t "UserService" -c "Handles user CRUD operations" --tags backend

memory query <text>

Search the knowledge graph using natural language. Uses hybrid BM25 + vector + freshness scoring.

Argument / Option Required Description
<text> yes Natural language search query
--kind <kind> no Filter by node kind
--limit <n> no Max results (default: 10)
--format <fmt> no Output format: text or json (default: text)
memory query "authentication"
memory query "database decisions" --kind decision
memory query "user service" --limit 5 --format json

memory show <id>

Show a node's full details and its connections. The <id> can be a full UUID or a unique prefix.

Each call to show updates the node's lastAccessedAt timestamp, which affects freshness scoring.

Argument / Option Required Description
<id> yes Node ID or unique prefix
--format <fmt> no Output format: text or json (default: text)
memory show abc123
memory show abc123 --format json

memory list

List nodes in the knowledge graph.

Option Required Description
--kind <kind> no Filter by kind
--status <status> no Filter by status
--tags <tags> no Comma-separated tags to filter
--limit <n> no Max results
--stale no Include stale/decayed nodes
--format <fmt> no Output format: text or json (default: text)
memory list
memory list --kind task --status todo
memory list --tags auth,security
memory list --stale
memory list --format json

memory update <id>

Update an existing node's fields.

Argument / Option Required Description
<id> yes Node ID or unique prefix
-t, --title <title> no New title
-c, --content <content> no New content
--status <status> no New status
--tags <tags> no Replace tags (comma-separated)
--stale no Mark as stale
memory update abc123 --status done
memory update abc123 -t "Updated title" -c "New content"
memory update abc123 --tags newtag1,newtag2

memory remove <id>

Remove a node. Default is soft delete (marks as stale). Use --hard for permanent deletion.

Argument / Option Required Description
<id> yes Node ID or unique prefix
--hard no Permanently delete instead of marking stale
memory remove abc123
memory remove abc123 --hard

Create a directed edge between two nodes.

Argument / Option Required Description
<fromId> yes Source node ID or prefix
<toId> yes Target node ID or prefix
--type <type> yes Edge type: depends_on, contains, implements, blocked_by, subtask_of, relates_to, supersedes, about
memory link abc123 def456 --type depends_on
memory link abc123 def456 --type contains

memory graph [id]

Visualize the knowledge graph as an ASCII tree. Optionally root at a specific node.

Argument Required Description
[id] no Root node ID or prefix. Omit for full graph.
memory graph
memory graph abc123

memory decay

Run auto-decay to mark old untouched nodes as stale. Nodes whose lastAccessedAt exceeds the threshold are marked stale and hidden from default listings and search.

Option Required Description
--days <number> no Max age in days before decay (default: 180)
memory decay
memory decay --days 90
memory decay --days 0   # decay all nodes not accessed today

memory serve

Start the Cortex Portal web server. Auto-decay runs on startup and every 24 hours.

Option Required Description
-p, --port <number> no Port number (default: 3100)
memory serve
memory serve --port 8080

Node Kinds

Kind Purpose
memory General knowledge, notes, context
component Code components, services, modules
task Work items, todos
decision Architectural or design decisions

Edge Types

Type Meaning
depends_on Source depends on target
contains Source contains target
implements Source implements target
blocked_by Source is blocked by target
subtask_of Source is a subtask of target
relates_to General relationship
supersedes Source supersedes/replaces target
about Source is about target

Search Scoring

Search combines three signals:

  • BM25 (weight 0.25) — text relevance
  • Vector similarity (weight 0.60) — semantic similarity via embeddings (requires Ollama)
  • Freshness (weight 0.15) — exponential decay based on lastAccessedAt

Freshness multiplier: e^(-0.01 * ageDays) — half-life ~69 days. Recently accessed nodes are boosted; old untouched nodes are penalized but not zeroed.

REST API

The web server exposes these endpoints under /api:

Method Path Description
GET /api/nodes List nodes. Query params: kind, status, tags, limit, includeStale
GET /api/nodes/:id Get node + connections
POST /api/nodes Create node. Body: { kind, title, content?, status?, tags?, metadata? }
PATCH /api/nodes/:id Update node. Body: { title?, content?, status?, tags?, metadata?, isStale? }
DELETE /api/nodes/:id Delete node. Query param: hard=true for permanent delete
POST /api/edges Create edge. Body: { fromId, toId, type, metadata? }
DELETE /api/edges/:id Delete edge
GET /api/graph Get full graph (nodes + edges) for visualization
POST /api/search Search. Body: { text, options?: { kind?, tags?, limit?, includeStale? } }