Operate Cortex, the LifeOS memory system — the typed Knowledge Archive (People, Companies, Ideas, Research with typed related: links) plus recall of prior work
复制下面这句话,粘贴给 Claude Code、Codex、Cursor 等 AI 编程工具,它会读取安装说明并在你确认后完成安装。
请阅读 https://ai.atlankj.com/install/asset/gh-cortex-f64352eeb0ab ,按照其中的说明把「Cortex」安装到你(当前 AI 工具)中。执行前先告诉我将运行的命令和写入的位置,等我确认。
查看 AI 将读取的安装说明正在读取 GitHub 原文…
内容来自 GitHub 原始文件,由原作者维护。在 GitHub 查看
Operate Cortex, the LifeOS memory system, from one skill. Two halves: the Knowledge Archive — a curated, typed graph of notes across six entity domains (People, Companies, Ideas, Research, Blogs, Books), every note shipping typed related: cross-links so the archive is a connected graph, not a pile of files — and recall — finding prior work (sessions, ISAs, conversations) by topic or date phrase. Operations cover search, add, harvest, develop, ingest, contradiction-finding, graph traversal, compressed retrieval, conversation mining, the weekly distill pass, and session recall.
Notes you save in isolation are notes you never find again. A flat folder of facts has no way to tell you that two notes contradict each other, that a new source updates an old claim, or that an idea connects to a person and a company you wrote up months ago. Knowledge dies when it can't be retrieved or related. This archive forces every note into a typed schema with mandatory cross-links and ripples updates through related notes on ingest, so the connections are built in at write time instead of being reconstructed by hand later.
Manage the LifeOS Knowledge Archive at ~/.claude/LIFEOS/MEMORY/KNOWLEDGE/. Each operation routes through a subcommand below; notes follow the archive schema and ship with typed cross-links.
Archive schema: ~/.claude/LIFEOS/MEMORY/KNOWLEDGE/_schema.md
Hard rule — never write KNOWLEDGE/ directly. All writes route through this skill (add, harvest, ingest, develop) — never cp, mv, Write, or Edit straight into the directory, even during migration or bulk import. The skill enforces typed frontmatter, mandatory cross-links, and domain classification; raw filesystem writes skip those guarantees and corrupt the graph silently (broken links don't fail loudly — they produce phantom entries retrieval misses). Migration tooling MUST call this skill per chunk, never shell out to cp. The one sanctioned exception is the Algorithm's LEARN phase, which writes to KNOWLEDGE/ directly because it holds the best context and applies the same schemas (see Gotchas).
Workflows are inline command sections in this file (no Workflows/ dir); each row routes to the matching H2 section below.
| Trigger | Workflow | Action |
|---|---|---|
/knowledge (no args) | status | Health dashboard |
/knowledge <query> | search | Search for notes matching query |
/knowledge search <query> | search | Explicit search |
/knowledge add <type> | add | Create a new note (People, Companies, or Ideas) |
/knowledge harvest | harvest | Run KnowledgeHarvester on all sources |
/knowledge develop | develop | Surface seedlings and enrich them |
/knowledge ingest <url-or-file> | ingest | Read source, create note, ripple updates to related notes |
/knowledge contradictions | contradictions | Find and review conflicting claims across notes |
/knowledge graph | graph | Knowledge graph stats and navigation |
/knowledge graph <slug> | graph | Traverse graph from a note |
/knowledge retrieve <query> | retrieve | Compressed context retrieval |
/knowledge mine | mine | Mine recent conversations for memory candidates |
/knowledge distill | distill | Weekly harvest of the archive into a routed, cited digest |
/cortex recall <query> (also /cs) | recall | Find prior work — sessions, ISAs, conversations — by topic or date phrase |
/cortex <args> and legacy /knowledge <args> route identically — the subcommand decides.
If $ARGUMENTS doesn't match a subcommand, treat it as a search query.
Run the harvester status command and display results:
bun ~/.claude/LIFEOS/TOOLS/KnowledgeHarvester.ts status
Also show:
Present in NATIVE mode.
Search the Knowledge Archive for notes matching $ARGUMENTS.
Step 1 — Lexical search:
rg -i "$ARGUMENTS" ~/.claude/LIFEOS/MEMORY/KNOWLEDGE/ --type md -l
Step 2 — Frontmatter search (tags and titles):
rg -i "title:.*$ARGUMENTS|tags:.*$ARGUMENTS" ~/.claude/LIFEOS/MEMORY/KNOWLEDGE/ --type md -l
Step 3 — Wikilink search:
rg "\[\[.*$ARGUMENTS.*\]\]" ~/.claude/LIFEOS/MEMORY/KNOWLEDGE/ --type md -l
Deduplicate results across all three. For each match, read the first 5 lines of frontmatter to show title, domain, status, tags.
Present results as a table:
| Note | Domain | Status | Tags | Relevance |
If no results found, say so and suggest checking the full MEMORY/ system or running a harvest.
Create a new note manually in the specified entity type.
related: frontmatter array. No Knowledge note ships without typed links. See Canonical Linking Requirement below._schema.md — the validator (LIFEOS/TOOLS/KnowledgeSchema.ts ENVELOPE) requires all EIGHT of: id (mint via mintId(slug, created) — kb_ + 12 hex chars), type, title, tags (min 1), quality (0-10), created, updated, convention: kb-v3 — plus type-specific body sections. A note built from the old six-field list can never validate (public issue #1678, @christauff). Set created: and updated: to today's date from date +%Y-%m-%d — archive-entry dates, never a source's publication date (public PR #1604, @asdf8675309).KNOWLEDGE/<Type>/<kebab-case-title>.md — slug max 60 charsrelated: exists in the archive before savingbun ~/.claude/LIFEOS/TOOLS/KnowledgeHarvester.ts index
Topic is a tag, not a type. A security insight is an Idea with a security tag. A security company is a Company with a security tag. The entity type determines the schema; the tag determines the topic.
Every new Knowledge note must ship with typed cross-links. This is not optional. The normative contract is _schema.md (regenerated by the schema tools): every note carries typed related: links naming the target note and the relationship type, so the archive is a graph, not a pile.
Every write must include:
related: frontmatter array — 2-4 typed entries linking to other Knowledge entries (any domain: People, Companies, Ideas, Research)[[slug]] references woven into the prose where natural (Implications, Evidence, or Context sections)9 relationship types (pick the most accurate, prefer specific over generic):
| Type | Meaning |
|---|---|
related | Generic association (default only if no better fit) |
supports | Provides evidence for the linked note |
contradicts | Conflicts with the linked note |
extends | Builds upon the linked note |
part-of | Component of a larger whole |
instance-of | Example of a pattern |
caused-by | Result of the linked note |
preceded-by | Came before temporally |
derived-from | Distilled from the linked source note (e.g. blog → idea) |
Frontmatter format:
related:
- slug: other-note-slug
type: extends
- slug: another-note-slug
type: supports
How to find related notes before writing:
# By topic/keyword
rg -l "TOPIC" ~/.claude/LIFEOS/MEMORY/KNOWLEDGE/ --type md
# By tag overlap
rg "^tags:.*TAG" ~/.claude/LIFEOS/MEMORY/KNOWLEDGE/ --type md -l
# For People/Companies — grep by name
rg -l "Person Name" ~/.claude/LIFEOS/MEMORY/KNOWLEDGE/
Enforcement:
related: are incomplete and must be fixed before the skill/workflow returns successingest workflow runs this as part of the ripple passRun the KnowledgeHarvester to pull new knowledge from all LifeOS sources:
bun ~/.claude/LIFEOS/TOOLS/KnowledgeHarvester.ts harvest
Display results. If nothing was harvested, explain that sources are already up to date.
Optionally accept --source filter: /knowledge harvest work or /knowledge harvest memory.
The weekly gardening workflow. Surface seedling notes that are ready for enrichment.
Step 1 — Find seedlings:
rg "^status: seedling" ~/.claude/LIFEOS/MEMORY/KNOWLEDGE/ --type md -l
Step 2 — For each seedling:
Step 3 — Present the diff to the user for approval.
Step 4 — If approved:
seedling to budding (or evergreen if comprehensive)updated: to today's date from date +%Y-%m-%d; leave created: untouchedIf no seedlings exist, report archive is clean.
Ingest a source into the Knowledge Archive. This is the key Karpathy-inspired upgrade: reading a source doesn't just create one note — it ripples updates through existing related notes.
If no argument provided: Show usage: /knowledge ingest <url-or-file-path>
curl -sL via Bash.Summarize the source in 2-3 sentences. Identify key entities, claims, and insights.
Determine entity type (People, Companies, Ideas, or Research) using the classification rules in _schema.md. Most ingested sources become Ideas.
Create the primary note using the schema for that type:
KNOWLEDGE/<Type>/<slug>.md with proper frontmattercreated: and updated: to today's date from date +%Y-%m-%d — both record when the note entered the archive, not when the source was published. A stated publication date belongs in source_date:; never let it reach created:, and never guess a date the source does not state (public PR #1604, @asdf8675309)source_url: or source_path: in frontmatterrelated: array with 2-4 typed links — the ripple pass (Step 3) identifies these, and they must be baked into the frontmatter of the primary note at creation time, not added afterSearch for existing notes that relate to this new content:
# Search by extracted tags
rg -i "TAG1|TAG2|TAG3" ~/.claude/LIFEOS/MEMORY/KNOWLEDGE/ --type md -l --glob '!_*'
# Search by key entities/concepts mentioned
rg -i "ENTITY1|ENTITY2" ~/.claude/LIFEOS/MEMORY/KNOWLEDGE/ --type md -l --glob '!_*'
For each related note found (up to 10):
Present the ripple plan to the user:
📥 INGEST RIPPLE PLAN:
PRIMARY: Ideas/new-note-slug — "Title" (created)
PRIMARY related: frontmatter links (MANDATORY):
→ Ideas/existing-note-1 — type: extends
→ Ideas/existing-note-2 — type: supports
→ People/person-slug — type: related
RIPPLE (reverse-direction updates to existing notes):
→ Ideas/existing-note-1 — add body [[new-note-slug]] wikilink + add to its related: array (type: extends)
→ Ideas/existing-note-2 — update Evidence section with new data point + add to related:
→ Ideas/existing-note-3 — ⚠️ CONTRADICTION: new source says X, note says Y — type: contradicts
NO CHANGE: Ideas/tangentially-related — mentioned same tag but no substantive connection
After the user approves (or you determine updates are low-risk cross-references):
related: frontmatter array has 2-4 typed entries — this is mandatory, not optionalrelated: entries to their frontmatter with appropriate types[[wikilinks]] in existing prose where natural (not forced)updated: to today's date from date +%Y-%m-%d on modified notes; leave their created: untouched> ⚠️ **Contradiction:** [note] claims X — see [[new-note]] for counter-evidence callout, AND add type: contradicts in related: arraysAppend to KNOWLEDGE/_log.md:
## [YYYY-MM-DD] ingest | Title
- Source: <url or path>
- Primary: <Type>/<slug>
- Ripple: N notes updated, N contradictions flagged
Regenerate MOCs:
bun ~/.claude/LIFEOS/TOOLS/KnowledgeHarvester.ts index
Present in NATIVE mode.
Find and review conflicting claims across Knowledge notes.
Run the KnowledgeHarvester contradiction finder:
bun ~/.claude/LIFEOS/TOOLS/KnowledgeHarvester.ts contradictions
This outputs pairs of notes with high tag overlap (2+ shared tags), ranked by overlap count.
For each pair (up to 10 highest-overlap pairs):
Present findings:
🔍 CONTRADICTION SCAN:
Pairs checked: N
Contradictions found: N
Superseded claims: N
⚠️ CONTRADICTION:
[[note-a]] claims: "X"
[[note-b]] claims: "Y"
Resolution: [suggest which is correct, or flag for the user]
📅 SUPERSEDED:
[[older-note]] (2026-01-15): "X was true"
[[newer-note]] (2026-03-20): "X is no longer true because Y"
Action: Update older note with correction
If the user approves resolutions:
> 📅 **Updated:** See [[newer-note]] for current informationupdated: datesPresent in NATIVE mode.
Navigate the Knowledge Archive as a graph.
No argument — stats overview:
bun ~/.claude/LIFEOS/TOOLS/KnowledgeGraph.ts stats
Show node count, edge count, top clusters, most connected hubs, and isolated nodes.
With slug — traverse from a note:
bun ~/.claude/LIFEOS/TOOLS/KnowledgeGraph.ts traverse <slug> --hops 2
Show all notes connected within 2 hops via tags, wikilinks, and typed relationships. Useful for exploring how knowledge connects across domains.
Related notes only:
bun ~/.claude/LIFEOS/TOOLS/KnowledgeGraph.ts related <slug>
Present in NATIVE mode.
Compressed context retrieval over the Knowledge Archive using BM25-lite scoring.
bun ~/.claude/LIFEOS/TOOLS/MemoryRetriever.ts "<query>" --top 5
Returns the top matching notes with compressed summaries, ranked by title match, tag overlap, and content frequency. Useful for loading relevant knowledge context without reading full files.
For raw excerpts without LLM compression:
bun ~/.claude/LIFEOS/TOOLS/MemoryRetriever.ts "<query>" --raw
Present in NATIVE mode.
Mine recent conversations for memory candidates (decisions, preferences, milestones, problems).
bun ~/.claude/LIFEOS/TOOLS/SessionHarvester.ts --mine --recent 10
Candidates are written to KNOWLEDGE/_harvest-queue/ for review — never directly to KNOWLEDGE/. Use /knowledge harvest to process the queue.
For dry run (preview only):
bun ~/.claude/LIFEOS/TOOLS/SessionHarvester.ts --mine --recent 10 --dry-run
Present in NATIVE mode.
Weekly harvest of the archive into routed outputs. Distill is a router, not a destination: every item lands in the system of record that already owns it, and the digest is an index pointing at those destinations. It never creates or edits KNOWLEDGE notes (mutations belong to develop/contradictions/ingest), and it never re-surfaces an item a previous run already routed.
Done looks like: a dated digest at ~/.claude/LIFEOS/MEMORY/DIGESTS/YYYY-MM-DD-distill.md with ≤10 items across three lanes, every item citing its source notes and linking its routed destination; ≤5 content-idea issues filed; ≤5 upgrades filed; all surfaced items marked in state. Overflow is named with a dropped-count, never silently truncated.
bun ~/.claude/LIFEOS/TOOLS/KnowledgeDistill.ts gather --days 7
Returns JSON: in-window notes (created/updated, minus previously surfaced), hot tag clusters (window count vs archive baseline), seedling and contradiction stats.
Cluster the candidates into digest items. Quality bar per item: ≥2 source notes, a why-now line (recency, cluster growth, or TELOS relevance), and a one-sentence pitch in plain language. Three lanes:
/knowledge contradictions or /knowledge develop.Content lane (≤5). The destination repo and label come from LIFEOS/USER/CUSTOMIZATIONS/SKILLS/Cortex/DistillConfig.json (contentRepo, contentLabel) — never hardcoded here:
gh issue create --repo <contentRepo> --label <contentLabel> \
--title "<pitch>" --body "<why-now + source note paths + suggested format>"
No config file → skip the issue lane and list content candidates in the digest only.
System lane (≤5; dedupe is claim-hash based, duplicates exit 0 silently):
bun ~/.claude/LIFEOS/TOOLS/Upgrades.ts add --claim "<one sentence>" --source autonomous \
--recommendation "<proposed encoding>" --target <hook|doctrine|rule|skill|settings|context> \
--evidence "<source note path>"
Write the digest file (lanes as sections; every item: pitch, sources, destination link or "empty — "), then:
bun ~/.claude/LIFEOS/TOOLS/KnowledgeDistill.ts mark --digest <digest-path>
which records surfaced slugs and item hashes in MEMORY/STATE/distill.json.
bun ~/.claude/LIFEOS/TOOLS/KnowledgeDistill.ts run --headless [--dry-run] performs all four steps unattended (synthesis via Inference.ts, never a nested claude session). The weekly launchd job com.lifeos.distill (Sun 09:00) runs exactly this. --dry-run prints the full routing plan and writes nothing.
Present in NATIVE mode.
Find prior LifeOS work — sessions, ISAs, conversations — by topic, partial words, or date phrases like "yesterday" or "last week". A deterministic Bun CLI searches five sources in parallel (work registry, session names, work dir names, ISA bodies, conversation jsonl), scores by token-overlap × recency, applies date filters, and returns ranked results with snippets.
bun run ~/.claude/skills/Cortex/Tools/ContextSearch.ts "$ARGUMENTS" --pretty --limit 10
Flag patterns: --limit N · --since YYYY-MM-DD · --json | jq '.results[0]'. Date phrases parse inline: "yesterday markdown" becomes a single-day since/until window plus token search for markdown.
Usage modes:
/cs <topic> or an explicit recall ask) — present the pretty block, then: "Context loaded on [topic]. Most recent: [X]. What would you like to do?"path when deeper detail helps. Don't dump the search block unless asked.Recall gotchas (ported from the retired ContextSearch skill):
today/yesterday/last week/N days ago/YYYY-MM-DD parse out as bounded date filters; remaining tokens still score content.security tag. Never create topic-based folders._schema.md. Always read the schema before writing.[[prompt-injection]] not [[Prompt Injection]]./knowledge develop promotes them.valid_from/valid_until frontmatter fields to track when facts were true. The contradiction detector uses these to skip non-overlapping time windows.Example 1: Search the archive
User: "what do we know about prompt injection?"
→ Routes to search — 3-pass (lexical + frontmatter + wikilink) over MEMORY/KNOWLEDGE/
→ Returns table of matching notes with domain, status, tags
Example 2: Ingest a source
User: "/knowledge ingest https://example.com/article"
→ Fetches the source, classifies entity type, creates primary note with typed related: links
→ Ripple pass proposes updates to existing related notes; user approves; MOCs regenerated
Example 3: Status check
User: "knowledge status"
→ Runs KnowledgeHarvester.ts status
→ Shows domain note counts, orphan wikilinks, stale seedlings, time since last harvest