Link 2.1.0
[2.1.0] - 2026-08-02
The inbox-zero release. 2.0 put the review gate in your menu bar; this
release makes sure there's nothing in it twice. Every change comes from
dogfooding the automatic pipeline against a real inbox that had grown to 20
pending captures — five of them the same conversation captured five times.
Added
lnk setup— one command for install day and every upgrade. Detects
every agent installed on the machine and wires them all at once:
workspace create/repair, runtime refresh, MCP provisioning, session
hooks for agents that have them. Idempotent — afterbrew upgrade, the
same command refreshes everything.--previewshows the plan without
writing. The quickstart is now two commands total.- Agent-agnostic by design: Windsurf and Zed join the roster (7 → 9
supported agents). Zed'scontext_serversschema (with its required
source: customentry) is supported natively, and writes into Zed's
main settings.json merge safely — existing user settings are preserved. - Memory poisoning benchmark (Track 5) + injection labeling. A planted
memory is injected into every future session — the highest-value prompt-
injection target an agent system has. 15 authored attacks (guardrail
bypass, unattended-execution "preferences", data-exfiltration
conventions, credential planting, spoofed approvals, agent-directed
commands) now run through the real pipeline in CI: 0 reach the inbox
unlabeled, 0 false positives on benign directives. Injection-shaped
proposals carry a warning in the capture inbox and the decision trail
("verify you actually said this before accepting") — labels, never
censorship; the review gate stays the final defense. To our knowledge
the only published adversarial benchmark on an agent-memory write path. - Dismissal ledger — deleting a capture now records its proposal
fingerprints inraw/memory-captures/.dismissed-proposals.json, so a
dismissed proposal never re-enters the inbox from a later session of any
conversation. Dismissal becomes a decision Link remembers. Inbox previews
andaccept-captureindices exclude dismissed proposals consistently. - One capture per conversation — a session-end for a conversation that
already has a pending capture refreshes that capture in place (same file,
newer transcript, newer proposals) instead of stacking a near-duplicate.
Captures carry aconversation:identity in frontmatter. - Cross-conversation proposal dedup — the session-end hook drops
proposals already waiting for review in another capture, with an honest
decision-trail line naming where ("already waiting for review in ..."). lnk dedup-captures— collapses inbox captures that offer nothing new
(already pending in a newer capture, accepted as memory, or dismissed;
or proposal-free). Dry-run by default,--confirmapplies,--jsonfor
tooling. Surfaced in LinkBar as a "Clean up" button on the inbox, and as
the MCPadminactiondedup_capturesfor agents.- LinkBar: "Why does Link believe this?" — tap any memory in the browser
to expand its trust card: the claim, whether default recall will use it
(with the reason), where it came from, when it was captured and reviewed,
and any open quality issues —lnk explain-memorymade ambient. - Trust lifecycle: memory ages honestly. Every memory now gets a typed
trust window at birth (project context 3 months; preferences, notes, and
procedures 6; decisions and stable facts 12), stamped asreview_after.
Reviewing a memory re-arms its window; a custom future date is kept.
Memories written before scheduling existed age implicitly from their last
review or capture date. An aged memory is never archived or hidden — it
is labeled due for review on every surface (inbox, audit, brief, explain
cards, LinkBar) and stays recallable, honestly flagged. No other agent
memory system re-asks whether what it knows is still true. - Live demo workspace on the homepage — the site now embeds a real
exported Link wiki (docs/demo, generated bylnk snapshot): every page
clickable, memories included, private memories excluded by the export's
own safety defaults. Snapshot styling joined the brand system
(cream/ink/rust) so a shared snapshot looks like the product. - Memory-hygiene benchmark v2 — the fixture now contains the junk we
actually observed in the wild, not just the junk we predicted: quiz/debug
questions carrying absolute keywords, pasted third-party AI advice inside
user turns, and verbatim cross-session repeats (142 events, up from 112).
Gated junk stays 0%; the ungated baseline rises to 36.5%.
Current-truth precision@1 improves to 0.881, and contradiction exposure
drops to 0.167 (10 of 12 authored revisions now supersede; v1's 0.333
was flattered — it silently measured only 9 revisions and its false
conflicts masked real exposure; see benchmarks/RESULTS.md). - Revision detection catches more contradiction shapes — three general
detector fixes: updates that add content tokens are no longer swallowed
by the echo guard (echoes add framing, revisions add content); detailed
original claims match at partial coverage; preference/decision typing
jitter no longer blocks detection across the type/scope boundary. - Semantic revision detection (opt-in, local) — when the semantic tier
is installed, revision-cued claims with no lexical link to what they
revise ("SQLite with FTS" → "DuckDB files") are compared by meaning:
claim-vs-claim embeddings, threshold calibrated on real separations
(true revisions 0.60–0.69, unrelated ≤ 0.18), surfaced as
semantic_revisionconflict candidates for review. Fully deterministic
lexical behavior when the tier is absent; the published benchmark
numbers stay lexical-only by design.
Fixed
- Product-finder round (walked the whole funnel as a stranger —
homepage, install, first five minutes): barelnknow greets with the
four commands that matter instead of an argparse error;lnk proofand
lnk tryend with the make-it-yours command (lnk setup); the homepage
Setup section and getting-started guide lead with the one-command flow
and the agent picker gained Windsurf and Zed. - Cold-walk friction round (found by walking the product end-to-end as a
new user): durability lead-ins ("From now on…", "Going forward…") are
trimmed from stored claims and titles; accepting a capture clears it from
the inbox when nothing fresh remains;review-memory --allbulk-reviews
every pending/due memory (lists first, requires--confirm); the session
brief marks unreviewed and aged memories inline (· pending review,
· review due) where agents read them; andrememberinfers the memory
type from the text's own cues — "I prefer X" saves as a preference with a
preference's trust window, not a generic note (CLI and MCP). - Questions are no longer proposed as memories. "number of walkers is
always fixed?" matched the preference cue on "always" and — worse —
ranked as a top durable memory. Interrogatives are now excluded from
classification and sunk by the durability ranker. - Pasted third-party prose is no longer attributed to the user. Bare
absolutes ("always", "never", "do not") now require the user's own voice
(first person, "please", or imperative-initial phrasing) — quoted advice
like "People on Reddit emphasize... never accept..." no longer becomes a
proposed user preference. - False memory conflicts from boilerplate overlap. "API listens on port
8080 in local development" conflicted with a squash-merge rule because
"development" read as a git branch and "decided/decision" counted as
shared subject matter. Boilerplate tokens no longer count as evidence. - Revisions are no longer swallowed by the echo guard. "We decided X
does not apply anymore" restates enough of the original claim that echo
containment dropped the update, keeping the stale memory alive forever. A
polarity flip now marks a candidate as a revision, not a restatement. - Revision sentences type consistently with what they revise. "We
decided X does not ... anymore" now classifies as a decision (the explicit
decision cue outranks the bare-absolute preference fallback), so conflict
detection sees the contradiction instead of skipping on a type/scope
mismatch. - Time-scoped observations ("does not affect us this quarter") are no
longer proposed as durable memory. - Bare imperative directives ("Plot the loss curve every 500 steps") now
outrank meta-preambles in proposal ordering instead of scoring zero. - LinkBar palette: a failed
lnkcall no longer reports "a similar or
conflicting memory exists" (it now says it couldn't reachlnk); typing
again within 1.1s of a confirmation no longer wipes the panel from under
you; a slow recall response for an old query can no longer overwrite the
results of a newer one. - LinkBar inbox at backlog scale: the full capture list is reviewable
(scrollable past 4 items) instead of showing only the top 3 of a
20-item backlog behind a count badge. - LinkBar builds with zero Swift warnings (actor-isolation conformance,
Sendable captures, and two lint-level warnings cleared).