Skip to content

Link 2.1.0

Choose a tag to compare

@gowtham0992 gowtham0992 released this 03 Aug 05:35
· 61 commits to main since this release
e12cc31

[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 — after brew upgrade, the
    same command refreshes everything. --preview shows 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's context_servers schema (with its required
    source: custom entry) 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 in raw/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
    and accept-capture indices 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 a conversation: 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, --confirm applies, --json for
    tooling. Surfaced in LinkBar as a "Clean up" button on the inbox, and as
    the MCP admin action dedup_captures for 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-memory made 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 as review_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 by lnk 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_revision conflict 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): bare lnk now greets with the
    four commands that matter instead of an argparse error; lnk proof and
    lnk try end 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 --all bulk-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; and remember infers 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 lnk call no longer reports "a similar or
    conflicting memory exists" (it now says it couldn't reach lnk); 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).