Skip to content

Prepare 1.6.0 release - #46

Merged
gowtham0992 merged 25 commits into
mainfrom
develop
Jul 9, 2026
Merged

Prepare 1.6.0 release#46
gowtham0992 merged 25 commits into
mainfrom
develop

Conversation

@gowtham0992

Copy link
Copy Markdown
Owner

Prepare 1.6.0 release

…pture at end

lnk connect claude-code --hooks installs SessionStart/SessionEnd hooks that
run the new agent-agnostic 'lnk hook' runtime: session-start injects a bounded
project-scoped memory brief, session-end extracts bounded transcript text
(skipping tool calls/outputs) into the review-gated session-end capture path.
Settings writes are idempotent and preserve existing user hooks; the hook
runtime never fails the agent session. Claude Code is the first wired agent;
the hook agent table is ready for others.
…ion loop

- lnk connect --hooks now supports Codex (~/.codex/hooks.json, nested schema,
  session-start only: Codex has no session-end event) and Cursor
  (~/.cursor/hooks.json, flat version-1 schema, JSON additional_context
  envelope via lnk hook --emit cursor), alongside Claude Code.
- Session-end capture noise controls: sessions with no memory-worthy
  proposal candidates are skipped and duplicate end events are deduplicated
  with a local fingerprint, so automatic hooks cannot flood the inbox.
- New lnk consolidate and MCP review(action=consolidate): a read-only backlog
  plan with pending captures, review queue, duplicate-capture groups, and
  paste-safe accept/discard commands. The injected session-start brief nudges
  the agent to offer consolidation when the backlog crosses thresholds;
  nothing is ever merged, deleted, or saved without per-action user approval.
Lexical recall stays the default and the fallback. With the optional
link-mcp[semantic] extra and a one-time explicit 'lnk semantic --setup',
a small local static-embedding model (model2vec potion-base-8M) retrieves
close paraphrases that token matching misses, across CLI recall, memory
briefs, MCP recall, and smart query packets.

Local-first guarantees preserved: the model loads offline-only so recall
can never trigger a download; embeddings are plain JSON in .link-cache/;
similarity is in-process cosine with no vector database or service;
LINK_SEMANTIC=off disables the layer.

Scoring is standout-based (z-score against the corpus for each query)
because raw cosine thresholds are not comparable across queries with
static models. Semantic-only matches are labeled match=semantic with
capped confidence so agents verify paraphrases before acting on them,
and they never outrank exact lexical hits.

New scripts/eval_recall_quality.py benchmarks lexical vs hybrid with a
regression gate. Real-model results: paraphrase hit@1 0.50 -> 0.62,
hit@3 0.62 -> 0.75; exact-token queries unchanged at 1.00.
- scripts/recall_dataset.py: deterministic, fully authored benchmark corpus
  (62 memories incl. 20 distractors, 294 authored queries + phrasing
  variants = 1,176 cases). Queries are classified by MEASURED significant
  stemmed-token overlap with their target, so the zero-overlap paraphrase
  group is provable, not asserted.
- scripts/eval_recall_quality.py: hit@1/3/5, MRR@5, per-domain breakdown,
  recall latency, JSON output, small (CI) and full suites, and a hard
  regression gate: hybrid may never score below lexical on any metric.
  CI runs the gate with a deterministic abstaining fake embedder.
- benchmarks/RESULTS.md: methodology, hardware, model-size ablation
  (potion-base-8M vs 32M), honest limitations, and reproduction steps.
  Measured (Apple M4, real model): token-overlap hit@1 0.589 -> 0.703,
  zero-overlap paraphrase hit@3 0.064 -> 0.136 and hit@5 0.082 -> 0.202,
  ~2.8 ms per recall in-process.
- python -m link_mcp --semantic-setup: explicit one-time model fetch and
  index build for MCP-only installs (found during an external-customer
  walkthrough: pip-only users had no lnk CLI to enable semantic recall).
  The serving path still never touches the network.
…, architecture-first positioning

1. Paraphrase recall: measured that static embeddings are the ceiling
   (retrieval-tuned potion-retrieval-32M and multi-view embeddings did not
   move zero-overlap results; ablations documented). Added a second local
   provider tier — fastembed all-MiniLM-L6-v2 (contextual ONNX) — preferred
   automatically when installed, with the static model kept as the
   instant-load fast tier for CLI and hooks. Quality tier on the full
   1,176-case suite: token-overlap hit@1 0.589 -> 0.749; zero-overlap
   paraphrase hit@3/hit@5 ~4x lexical (0.255/0.338); ~10 ms per recall.
   Offline guard verified empirically for both providers: a recall can
   never download a model.

2. Self-authored benchmark: added a third-party track. scripts/eval_locomo.py
   scores the retrieval stage of LoCoMo (ACL 2024) with turns as memories
   and evidence-annotated questions as queries — no LLM anywhere. Hybrid
   lifts any-evidence hit@10 0.578 -> 0.685 and evidence recall@10
   0.517 -> 0.608 across 1,536 third-party queries over 5,882 turns.
   Dataset downloaded by the user (CC BY-NC 4.0, Snap Inc.), never
   redistributed; the script contains no network code.

3. Positioning: rewrote docs/why-link.html to lead with the four
   architectural commitments (readable Markdown memory, review-gated
   writes, no LLM in the memory layer, CI-enforced zero network), with
   named Mem0/OpenMemory and Zep/Graphiti comparisons and the benchmark
   as supporting evidence. README and RESULTS.md updated with tiered and
   third-party numbers.
…v guidance, loop consistency

- Documented hooks, semantic recall, and consolidation in every surface an
  external user or agent reads: PyPI package README, LINK.md, installed agent
  instructions (both variants), the MCP link://instructions resource, the
  docs landing page copy, and the CLI reference.
- connect/onboard --hooks now refresh a workspace runtime that predates
  session hooks (preview warns, --write repairs), preventing exit-2 hook
  noise after upgrades.
- lnk semantic now names the interpreter it checked and, when the Link MCP
  Python differs, prints the exact venv-side setup command
  (python -m link_mcp --semantic-setup), fixing the extras-in-the-wrong-env
  trap. Quality-tier setup states the ~5s CLI load tradeoff explicitly.
- The memory-backlog consolidation nudge moved into the core brief payload,
  so CLI start, MCP briefs, skills, and hooks all surface it consistently
  (and the hook no longer double-scans captures).
- lnk onboard gained --hooks; hook captures are titled with their project;
  consolidation groups near-duplicate captures by token overlap, not just
  exact matches; semantic status counts active memories only; Codex/Cursor
  hook support is labeled as new in output and docs.
Walked the product as a brand-new user (fresh clone, fake HOME, README
paths: proof -> onboard --hooks --write -> day-1/day-2 hook briefs ->
semantic status -> consolidate -> common mistakes) and fixed what hurt:

- Empty-workspace session-start briefs are now two actionable lines
  (seed project context, approval rule) instead of a fifteen-line
  skeleton of zeros injected into every new session on day one.
- Every 'Missing wiki directory' CLI error (25 sites) now prints a
  concrete next step: point at your workspace or lnk init here.
- Verified end-to-end in the walkthrough: onboard --hooks --write writes
  MCP config plus both hooks in one command; the stale-runtime guard
  warns in preview and repairs on write; day-2 briefs recall real
  memories; consolidate and semantic empty states read cleanly.
- getting-started.html: new steps 9 (session hooks: one command makes the
  memory loop automatic) and 10 (optional hybrid semantic recall with both
  tiers and MCP-only setup), onboard --hooks example, ToC entries.
- mcp.html: semantic extras + --semantic-setup in the MCP-only install,
  offline-loading guarantee, hooks-installed workflow note, and the
  review consolidate action.
- security.html: privacy bullets for offline-only semantic models, plain
  JSON embeddings, and proposal-only hook capture.
- Landing page: design-principle cards updated — hooks-injected shared
  memory, and 'No services, no APIs' reworded for the optional local
  semantic tier measured in the open.
- README now reads as a product doc: new 'Why Link Is Different' section
  (four architectural commitments + measured-not-asserted with benchmark
  links) placed before Quick Start; recall/review tool bullets cover
  match labels and consolidate; privacy section covers semantic offline
  loading and proposal-only hooks.
…ansion

Both candidate mechanisms measured worse than or equal to the shipped
approach on the recall benchmark; documented so the methodology shows
its negative results.
A full editorial audit before the 1.6.0 cut found the flagship features
documented on the primary surfaces (README, landing, getting-started,
CLI, MCP, why, security) but absent from the surfaces skill-first agents
and troubleshooting users actually read:

- Official skills: link-memory teaches the hooks-installed rule (skip
  the manual brief) and the read-only consolidation pass; link-retrieve
  teaches confidence + match labels (verify semantic/weak matches);
  link-health adds the lnk semantic status check.
- memory-contract.html: the hooked loop, honest recall signals, and the
  consolidate action are now part of the documented contract.
- concepts.html: hybrid two-tier retrieval and the automatic lifecycle
  (automation changes when memory is proposed, never who decides).
- skills.html: the two new agent rules.
- troubleshooting.html: 'Session Hooks Are Not Firing' (including
  hook session-end --explain) and 'Semantic Recall Is Not Working'
  (wrong-interpreter, setup, kill-switch causes).
- scale.html: links the measured recall benchmarks.
'no embeddings' became imprecise once optional local embedding tiers
shipped; the footer now says 'no services', matching the design
principle card. Also ignore local .claude/ tooling configs.
…asured

The flagship features existed on the home page only as card fine print;
the hero and meta description still told the pre-1.6 story. A skimming
visitor never learned the two headline facts. The hero paragraph and
meta description now lead with them: memory injected automatically at
session start, proposals at session end with every save approved by the
user, and hybrid local recall measured in the open.
The 1.6 hero rewrite kept four of the five founding claims (inspectable
wiki, review-gated saves, local, cross-agent) but dropped the provenance
word. Source-backed memory is a load-bearing differentiator, not
decoration; it belongs in the first paragraph a visitor reads.
Every release pulls attention toward its newest features; three releases
from now the site could read like a benchmark product with the founding
story reduced to a footnote. This test encodes the claims that made Link
through 1.5.0 — source-backed provenance, inspectable Markdown,
review-gated writes, local-first, cross-agent, the proof loop — and
fails any landing or README rewrite that drops one, so forgetting
becomes a deliberate decision instead of an accident.
Markdown wraps lines mid-phrase; the guard now judges claims on prose,
not line breaks.
The guard protects claims, not exact strings: the cross-agent pillar now
accepts the README's established phrasings (shared across multiple
agents, reusable by different agents) alongside the landing's literal
wording.
Went through the exact path a brand-new user walks (README -> proof ->
onboard -> try the pitch) and hit real walls where the two headline 1.6
features were hidden or silently off. Fixes:

P0 - flagship features were undiscoverable on the guided path:
- lnk onboard now surfaces the automatic-memory path: explains --hooks
  and prints the ready-to-run --agent <hook-capable> --hooks --write
  command; each hook-capable agent preview offers 'Make memory automatic
  (recommended)'. Before, onboard never mentioned hooks at all.
- A recall that finds nothing while memories exist now tells the user
  paraphrase matching (semantic recall) is off by default and how to
  enable it, instead of a bare 'No matching memories found'. The README
  paraphrase example is reframed as opt-in and the landing hero calls
  hybrid recall optional, so the marquee demo never reads as a broken
  default.

P1 - command identity whiplash and workspace confusion:
- Source-checkout commands now show a friendly 'python3 link.py' instead
  of the raw interpreter path (python@3.14 ...); Homebrew users still see
  plain lnk.
- lnk proof labels its workspace a throwaway demo, adds a 'what this
  means for you' line, and points to lnk onboard for real memory.

P2:
- prepare_release.py reminds maintainers to bump the Homebrew tap so
  brew install never serves an older Link than the docs describe.

Four regression tests pin the onboard-hooks and recall-miss-hint
behaviors. 819 tests + guards green.
Second cold new-user walk: after 'onboard --agent X --hooks --write'
succeeded, the generic 'add --hooks' teaching hint still printed at the
bottom, telling the user to do the thing they just did. Suppress the
generic hint when the user already passed --hooks; the teaching still
fires for users who onboard without it.
…or README GIF)

The cold new-user walk showed the two mind-blown moments were told in
prose but never shown. Now they are:

- docs/assets/link-aha.svg: a hand-built, brand-matched animated terminal
  (plain text, no external runtime, no binary, theme-safe dark terminal)
  looping the two aha moments — recall that matches 'how should I name my
  git branches' to a 'feat/short-topic' memory (meaning, not keywords),
  then a new agent session greeted with memory automatically. Embedded at
  the top of the Getting Started page; registered in the media verifier.
- docs/media/link-aha.tape: a charmbracelet vhs script that renders the
  matching README GIF from real lnk commands, with the one-time render
  command in its header. The GIF is not checked in until rendered, so no
  binary or broken reference lands early.

Option 2 (the site SVG) ships now; option 1 (the README GIF) renders with
one 'brew install vhs' when ready.
Rendered docs/assets/link-aha.gif (144K) with charmbracelet vhs from the
checked-in tape: real 'lnk recall' output showing a memory saved as
'Name branches feat/short-topic, never long' surfacing for the query
'how should I name my git branches' — different words, match: moderate,
matched by meaning. Placed near the top of the README with a caption,
registered in the media verifier.

Hardened the tape's cleanup (capture the original dir before cd) and
gitignored docs/media/.aha-demo so a render can never leave a stray
workspace to be committed.
The landing described the product and had a decorative hero graph but
showed no real product output. Embedded the animated demo terminal
(the existing self-contained link-aha.svg) in the 'How it works'
section, right after 'the agent builds the memory' and before the
Capture/Compile/Remember steps — a 'here's the payoff, then here's how'
beat.

Verified with a headless-Chrome render of the live bundle: the first
insertion broke it (the landing template is JSON, and I'd escaped single
quotes as \' which JSON rejects). Reverted and re-inserted with
JSON-valid escaping; the page now renders end to end.
Session-end hooks extracted the whole transcript (user + assistant) and
fed it to the memory-proposal extractor, which is speaker-blind. A cue
like the assistant writing "you prefer small commits" was mined and
proposed as the user's own preference — found while dogfooding 1.6.

Mine proposals from the user's turns only via a new roles= parameter on
extract_transcript_text; keep the full transcript in the raw capture for
review context via session_end(proposal_text=...). Precision over recall
for automatic writes: the user can always remember explicitly, and junk
proposals are worse than the occasional miss.

Regression tests cover both the extractor (assistant prose excluded,
user preference kept) and the hook (assistant-only session captures
nothing; a user-stated decision still captures).
Cold-walking 1.6.0 as a brand-new pip user: python -m link_mcp --help
was swallowed by parse_known_args (add_help=False) and the stdio server
started, hanging in the terminal with zero output — a dead end on the
first exploratory command anyone runs.

Handle -h/--help explicitly before the parser: print the module usage
docstring (install, usage, MCP config snippet) plus an options list and
exit 0. Agent launch behavior is unchanged; unknown args still never
crash the server. Regression test asserts --help exits 0 with usage on
stdout and nothing on stderr.
First Windows CI run of the hooks tests (CI is PR-triggered, so the 1.6
work had only seen POSIX until the release PR) failed on two assertions,
both test bugs — the product output is correct on both platforms:

- test_build_preview_includes_both_events_and_commands asserted POSIX
  shlex single-quoting; display_command intentionally uses
  list2cmdline double quotes on Windows. Assert the platform's quoting.
- test_connect_hooks_preview_includes_session_hooks_payload compared the
  absolute temp path, but Windows mkdtemp returns the 8.3 short form
  (RUNNER~1) while the built command holds the resolved long form
  (runneradmin). Assert the stable demo/link.py path tail instead.
@gowtham0992
gowtham0992 merged commit e99e933 into main Jul 9, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant