Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2db0975
Add agent session hooks: auto memory brief at start, proposal-only ca…
gowtham0992 Jul 8, 2026
bb1677a
Extend session hooks to Codex and Cursor; add review-gated consolidat…
gowtham0992 Jul 8, 2026
6e2a23d
Add optional hybrid semantic recall with a local embedding model
gowtham0992 Jul 8, 2026
d17ad98
Add publication-grade recall benchmark with measured results
gowtham0992 Jul 8, 2026
6fa6ff0
Fix the three publication weaknesses: quality tier, third-party track…
gowtham0992 Jul 8, 2026
323b326
Address post-1.5.0 audit findings: docs everywhere, upgrade guard, en…
gowtham0992 Jul 8, 2026
784f911
Fix frictions found in a cold fresh-user walkthrough
gowtham0992 Jul 8, 2026
7ee5853
Update Pages site and README with the new feature story
gowtham0992 Jul 8, 2026
a19fe89
Record two rejected recall ablations: static MaxSim and PMI query exp…
gowtham0992 Jul 8, 2026
4e0c8fe
Complete 1.6 coverage in shipped skills and second-tier docs pages
gowtham0992 Jul 8, 2026
792464e
Fix stale landing footer tagline for the optional semantic tier
gowtham0992 Jul 8, 2026
76d3ae8
Lead the landing hero with the 1.6 story: automatic, review-gated, me…
gowtham0992 Jul 8, 2026
5f3f0c1
Restore 'source-backed' to the landing hero
gowtham0992 Jul 8, 2026
55b2d93
Guard the founding identity claims in landing and README
gowtham0992 Jul 8, 2026
c17e21a
Normalize whitespace in the founding-identity guard
gowtham0992 Jul 8, 2026
237deb5
Accept claim phrasings in the founding-identity guard
gowtham0992 Jul 8, 2026
7ed8c95
Fix first-ten-minutes friction found by walking Link cold as a new user
gowtham0992 Jul 9, 2026
b1b2684
Don't re-nag about --hooks in onboard once hooks are installed
gowtham0992 Jul 9, 2026
064e0ce
Add an animated aha demo to the docs (self-contained SVG + vhs tape f…
gowtham0992 Jul 9, 2026
a543c75
Render the README aha GIF from real lnk commands (vhs)
gowtham0992 Jul 9, 2026
50ea157
Show the aha demo on the landing home page
gowtham0992 Jul 9, 2026
42a24fc
Fix automatic capture attributing assistant prose to the user
gowtham0992 Jul 9, 2026
2d2c322
Print usage on link_mcp --help instead of silently starting the server
gowtham0992 Jul 9, 2026
e20d824
Prepare 1.6.0 release
gowtham0992 Jul 9, 2026
cb739de
Make hook-command path assertions portable to Windows
gowtham0992 Jul 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,9 @@ id_rsa
id_ed25519
# Local design references
Link Console Handoff.html

# Local editor/agent tooling
.claude/

# vhs demo render workspace
docs/media/.aha-demo/
44 changes: 44 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,50 @@ Release sections use `MAJOR.MINOR.PATCH` versions that match `link-mcp` on PyPI

## [Unreleased]

## [1.6.0] - 2026-07-09

- Added an animated "aha" demo to the Getting Started page: a self-contained SVG (`docs/assets/link-aha.svg`, plain text, no external runtime, animates in any browser) showing the two moments Link is built for — recall that matches by meaning rather than keywords, and memory injected into a new agent session automatically. The README shows the matching recorded GIF (`docs/assets/link-aha.gif`), rendered from real `lnk` commands via a checked-in charmbracelet vhs tape (`docs/media/link-aha.tape`) so it is reproducible, not synthetic.

- Fixed first-ten-minutes friction found by walking Link cold as a brand-new user:
- `lnk onboard` now surfaces the automatic-memory path: it explains `--hooks` and prints the ready-to-run `--agent <hook-capable> --hooks --write` command, and each hook-capable agent preview offers "Make memory automatic (recommended)". Previously the flagship 1.6 feature was invisible in the guided setup.
- A recall that finds nothing while memories exist now tells the user paraphrase matching (semantic recall) is off by default and how to turn it on, instead of a bare "No matching memories found". The README's paraphrase example is reframed as opt-in so it never reads like a broken default, and the landing hero calls hybrid recall optional.
- Generated commands in source-checkout mode use a friendly `python3 link.py` instead of the raw interpreter path (e.g. `python@3.14`); Homebrew users still see plain `lnk`.
- `lnk proof` now says its workspace is a throwaway demo and points to `lnk onboard` for real memory, with a plain "what this means for you" line.
- `scripts/prepare_release.py` reminds maintainers to bump the Homebrew tap so `brew install` never serves an older Link than the docs describe.

- Completed 1.6 coverage across the second-tier docs and shipped skills: the official CLI skills now teach the hooks-installed rule, the consolidation pass, semantic match labels, and the `lnk semantic` status check; the memory contract documents the hooked loop and honest recall signals; concepts covers hybrid retrieval and the automatic lifecycle; troubleshooting gains "hooks not firing" and "semantic recall not working" sections; and the scale page links the measured benchmarks.

### Added

- Added `lnk connect <agent> --hooks` to install agent session hooks alongside MCP config for Claude Code, Codex, and Cursor: every new session starts with a bounded Link memory brief injected automatically, and session end stores proposal-only session notes with memory candidates, so the memory loop no longer depends on the agent remembering to call Link. Codex has no session-end hook event, so it gets the session-start brief only; Cursor uses its flat `hooks.json` schema and JSON `additional_context` envelope.
- Added `lnk consolidate` and MCP `review(action="consolidate")` for a read-only backlog plan: pending capture counts, memories needing review, duplicate-capture groups, and paste-safe accept/discard/review commands — nothing is merged, deleted, or saved without the user approving each action.
- Added an automatic backlog nudge to the injected session-start brief: when pending captures or review items cross a threshold, the brief tells the agent to offer the user a short consolidation pass instead of letting the inbox silently grow.
- Added session-end capture noise controls: sessions with no memory-worthy proposal candidates are skipped entirely, and duplicate end events for the same conversation content are deduplicated with a local fingerprint, so automatic hooks cannot flood the capture inbox.
- Added optional hybrid semantic recall (`pip install "link-mcp[semantic]"` + `lnk semantic --setup`): a small local static-embedding model retrieves close paraphrases that token matching misses, across CLI recall, memory briefs, MCP recall, and smart query packets. Lexical recall stays the default and the fallback.
- Kept the local-first guarantee for semantic recall: the model loads offline-only so a query can never trigger a download (only the explicit `--setup` may fetch the model once), embeddings live in plain JSON under `.link-cache/`, similarity is computed in-process with no vector database or service, and `LINK_SEMANTIC=off` disables the layer.
- Added standout-based semantic scoring: candidates are selected by how much they stand out from the rest of the corpus for the query (not by raw cosine thresholds, which are not comparable across queries for static models), and semantic-only matches never outrank exact lexical hits.
- Added honest labeling for semantic recall: recalled memories now carry `match` (`lexical`, `semantic`, or `hybrid`) and `semantic_similarity`, and a match with no lexical evidence is capped at moderate confidence so agents verify paraphrase matches before acting on them.
- Added `lnk semantic` for the layer's status (provider, model, index state, mode) with explicit setup/rebuild actions and next-step guidance.
- Added a publication-grade recall benchmark: `scripts/recall_dataset.py` (62-memory corpus with distractors, 294 authored queries plus deterministic phrasing variants for 1,176 total cases, every query auto-classified by measured token overlap so the paraphrase group provably shares no significant stemmed token with its target) and `scripts/eval_recall_quality.py` (hit@1/3/5, MRR@5, per-domain breakdown, recall latency, JSON output, and a regression gate that fails if hybrid ever scores below lexical). CI runs the gate with a deterministic no-model embedder.
- Published measured results in `benchmarks/RESULTS.md` with methodology, hardware, model-size ablation, honest limitations, and reproduction steps: hybrid recall lifts token-overlap hit@1 0.589 → 0.703 and doubles-to-triples zero-overlap paraphrase hit@3/hit@5, at ~2.8 ms per recall in-process.
- Added `python3 -m link_mcp --semantic-setup` so MCP-only installs (no `lnk` CLI) can run the explicit one-time semantic model fetch and index build; the MCP server itself still never touches the network.
- Added a second semantic tier: `pip install "link-mcp[semantic-quality]"` uses a local contextual ONNX model (all-MiniLM-L6-v2 via fastembed) and is preferred automatically when installed; the static-model fast tier remains for instant-load CLI and hook use, and `LINK_SEMANTIC_PROVIDER` picks explicitly. On the bundled benchmark the quality tier roughly quadruples pure-paraphrase hit@3/hit@5 over lexical recall. Ablations that did not survive measurement (retrieval-tuned static models, multi-view embeddings) are documented in `benchmarks/RESULTS.md`.
- Added a third-party benchmark track: `scripts/eval_locomo.py` scores Link recall on the LoCoMo long-term conversational memory dataset (turns as memories, evidence-annotated questions as queries; retrieval stage only, no LLM anywhere). Hybrid recall lifts any-evidence hit@10 from 0.578 to 0.685 and evidence recall@10 from 0.517 to 0.608 over 1,536 third-party queries. The dataset (CC BY-NC 4.0, Snap Inc.) is downloaded by the user, never redistributed; the script contains no network code.
- Rewrote the public "Why Link?" positioning around the four architectural commitments competitors cannot bolt on — readable Markdown memory, review-gated writes, no LLM in the memory layer, CI-enforced zero network — with named comparisons against Mem0/OpenMemory, Zep/Graphiti, and Letta, and the benchmark as supporting evidence.
- Added `lnk onboard --hooks` so the guided first-run path can install session hooks alongside MCP wiring, and made `connect`/`onboard --hooks --write` refresh workspace runtimes that predate session hooks (preview warns first), preventing broken hooks after upgrades.
- Made the memory-backlog consolidation nudge part of the core brief payload so CLI `start`, MCP briefs, skills, and session hooks all surface it consistently.
- Improved `lnk semantic` diagnostics: status names the Python interpreter being checked, and when the Link MCP Python differs, errors print the exact venv-side setup command; quality-tier setup states the ~5s short-lived-CLI load tradeoff explicitly.
- Made the injected session-start brief compact for empty workspaces (two actionable lines instead of an empty statistics skeleton) and gave every missing-wiki CLI error a concrete next step instead of a dead end.
- Titled automatic session captures with their project, clustered near-duplicate captures in consolidation plans by token overlap instead of exact text, and documented session hooks, semantic recall, and consolidation across the PyPI README, LINK.md, installed agent instructions, MCP instructions resource, and the docs site.
- Added `lnk hook session-start` to print the bounded session-start memory brief (readiness, relevant memories with confidence, pending review and capture state, and retrieval guidance) for agent hook runtimes; it scopes the brief to the hook's working directory project and never fails the agent session.
- Added `lnk hook session-end` to turn an agent transcript into review-gated memory: it extracts bounded user/assistant text (skipping tool calls and outputs), skips trivial sessions, and stores proposal-only session notes through the same duplicate/conflict-safe capture path as `lnk session-end`.
- Added idempotent, non-destructive session-hook writing to `~/.claude/settings.json` that preserves existing user hooks and settings, replaces only Link's own hook entries on rerun, and skips re-injection on session resume.

### Fixed

- `python -m link_mcp --help` now prints usage and the MCP config snippet instead of silently starting the stdio server (which hung in a terminal with no output). The parser still ignores unknown arguments so an agent launch config can never crash the server.
- Automatic session-end capture now mines memory proposals from the user's own turns only, not the assistant's replies. Dogfooding showed the assistant's prose (e.g. a summary line like "you prefer small commits") was being extracted and proposed as the user's own preference. The raw capture still keeps the full transcript for review context; only the proposal candidates are restricted to what the user actually said (`extract_transcript_text(..., roles=("user",))`).

## [1.5.0] - 2026-07-03

### Added
Expand Down
6 changes: 6 additions & 0 deletions LINK.md
Original file line number Diff line number Diff line change
Expand Up @@ -623,3 +623,9 @@ If the wiki is empty, start here:
If the wiki already exists, read `wiki/index.md` and `wiki/log.md` first to understand current state before doing anything.

To verify MCP access, run `python3 link.py verify-mcp .` when `link.py` is available. It checks whether `link_mcp` imports in the configured Python and prints the MCP client config for the current wiki.

## Memory Maintenance

- **Session hooks.** Agents with hook support (Claude Code, Codex, Cursor) can install Link session hooks (`python3 link.py connect <agent> . --hooks --write`): the memory brief is injected automatically at session start and proposal-only session notes are stored at session end. Durable memory always requires review.
- **Consolidation.** When briefs report a memory backlog (pending captures or reviews above threshold), run `python3 link.py consolidate .` (or MCP `review(action="consolidate")`) for a read-only plan with accept/discard/review commands. Apply actions only after the user approves each one.
- **Semantic recall (optional, local).** With `link-mcp[semantic]` or `link-mcp[semantic-quality]` installed and a one-time `python3 link.py semantic . --setup`, recall also finds paraphrases. Recalled memories then carry `match: lexical|semantic|hybrid`; treat semantic-only matches as hints to verify, not facts.
89 changes: 86 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ The wiki is the storage layer. The product is durable memory that stays on your
machine, remains readable in plain files, and can be shared across multiple
agents instead of locked inside one vendor profile.

<p align="center">
<img src="docs/assets/link-aha.gif" alt="lnk recall finds a memory saved in completely different words — matched by meaning, not keywords" width="760">
</p>
<p align="center"><em>Ask in your own words; Link matches by meaning, not keywords. All local, all plain files.</em></p>

## How It Works

Link gives agents four simple moves:
Expand All @@ -73,6 +78,29 @@ Link follows Andrej Karpathy's
keep knowledge outside the chat window, make claims inspectable, and let context
compound over time.

## Why Link Is Different

Every other agent-memory system stores memory as embeddings in a vector
database or as an LLM-extracted graph. Link made four architectural
commitments those designs cannot bolt on:

1. **Memory you can read.** Every memory is a plain Markdown file — open it,
grep it, git-diff it. If Link disappeared tomorrow, your memory is still yours.
2. **Review-gated writes.** Agents propose; you approve. Even the automatic
session hooks capture proposals, never facts.
3. **No LLM in the memory layer.** Ingestion and recall are deterministic —
nothing can hallucinate a fact into your memory, because there is no model
in the write path.
4. **Provably local.** CI blocks outbound network code in the runtime, and the
optional semantic models load offline-only after one explicit setup.

And the claims are measured, not asserted: a reproducible 1,176-case recall
benchmark plus a third-party LoCoMo retrieval track, with published miss rates
and a CI gate against regressions —
[benchmarks/RESULTS.md](benchmarks/RESULTS.md). Named comparisons against
Mem0/OpenMemory, Zep/Graphiti, and Letta:
[Why Link?](https://gowtham0992.github.io/link/why-link.html)

## Quick Start

Start with the memory proof. It creates a clean local workspace, writes one
Expand Down Expand Up @@ -320,6 +348,53 @@ lnk connect kiro ~/link --write
lnk verify-mcp ~/link
```

For agents with session-hook support — Claude Code, Codex, and Cursor — add
`--hooks` (works with `lnk onboard` too) to make the memory loop automatic:
the brief is injected at session start and proposal-only notes are captured at
session end, so memory no longer depends on the agent remembering to call
Link. Empty sessions and duplicate end events are skipped, and when the
backlog builds up the brief nudges the agent to offer a read-only
`lnk consolidate` pass. Durable memory still requires your approval. Codex and
Cursor hook support is new (wired to their documented schemas — report
issues).

```bash
lnk connect claude-code ~/link --hooks --write
lnk connect codex ~/link --hooks --write # session-start brief (Codex has no session-end event)
lnk connect cursor ~/link --hooks --write
lnk consolidate ~/link # read-only backlog plan, apply only with approval
```

### Optional: hybrid semantic recall (still fully local)

Lexical recall is always the default and the fallback. Paraphrase matching is
opt-in: after the two setup commands below, "how should I structure my pull
requests" finds a memory saved about commit style. Until then, recall matches
on shared words, and a miss tells you how to turn paraphrase matching on.
Installing the optional semantic extra adds a small local static-embedding
model. Recall never touches the
network: the model loads offline-only after a one-time explicit setup,
embeddings live in plain JSON under `.link-cache/`, similarity runs in-process
with no vector database, and semantic-only matches carry capped confidence
labels so agents verify before trusting them.

```bash
pip install "link-mcp[semantic]" # fast tier: tiny static model, instant load
pip install "link-mcp[semantic-quality]" # quality tier: contextual model, best recall
lnk semantic ~/link --setup # one-time model fetch, with your approval
lnk semantic ~/link # status: lexical only vs hybrid, active tier
python3 -m link_mcp --semantic-setup --wiki ~/link/wiki # MCP-only installs
```

Measured, not asserted: on the bundled 1,176-case benchmark, the quality
tier lifts token-overlap hit@1 from 0.589 to 0.749 and pure-paraphrase
(zero token overlap) hit@3/hit@5 by ~4×, at ~10 ms per recall with no
service or vector database. On the third-party LoCoMo retrieval track
(1,536 evidence-annotated questions over 5,882 conversation turns), hybrid
recall lifts any-evidence hit@10 from 0.578 to 0.685. Full methodology,
honest limitations, and reproduction steps:
[benchmarks/RESULTS.md](benchmarks/RESULTS.md).

<details>
<summary>MCP-only install</summary>

Expand Down Expand Up @@ -400,15 +475,18 @@ model-facing tools. CLI and skill workflows call the same core behavior through
next actions.
- `recall`: the one read path for startup briefs, answer-ready query packets,
wiki search, graph context, token budgets, and follow-up actions. Every
recalled memory carries a `confidence` label (`strong`, `moderate`, `weak`),
so agents verify weak lexical matches with the user instead of trusting them.
recalled memory carries a `confidence` label (`strong`, `moderate`, `weak`)
and a `match` field (`lexical`, `semantic`, `hybrid` when the optional local
semantic tier is installed), so agents verify weak or paraphrase matches with
the user instead of trusting them.
- `remember`: durable local memory only after explicit user approval, with
duplicate/conflict checks, provenance, review state, visibility, optional
`review_after`, and optional `expires_at`.
- `ingest`: exact next steps for raw files, source safety, stale ingest
detection, validation, and rebuild checks.
- `review`: memory inbox, profile, audit, log, explain, archive, restore,
forget, and lifecycle review workflows.
forget, and lifecycle review workflows — plus `review(action="consolidate")`,
a read-only backlog plan applied only with per-action user approval.
- `admin`: the escape hatch for backup, migrate, validate, graph export, pages,
captures, rebuilds, compatibility actions, and advanced updates.

Expand Down Expand Up @@ -508,6 +586,11 @@ Link itself is local-first:
checks. `lnk validate` and `lnk doctor` also fail if secret-looking values
are found inside wiki pages before they can be served through the local UI or
returned through agent context.
- Optional semantic recall stays local: models load offline-only at recall
time (only the explicit `lnk semantic --setup` may fetch a model, once), and
embeddings live in plain JSON under `.link-cache/`.
- Automatic session hooks store proposal-only notes; transcript extraction
skips tool calls and outputs, and no durable memory is written without review.
- The local web server binds to `127.0.0.1` and is not meant to be exposed to
the internet without additional auth.

Expand Down
Loading
Loading