Skip to content

Web UI (P3) and semantic recall (P4) - #1

Merged
jackeydou merged 7 commits into
mainfrom
web-ui-and-semantic-recall
Sep 26, 2026
Merged

jackeydou merged 7 commits into
mainfrom
web-ui-and-semantic-recall

Conversation

@jackeydou

Copy link
Copy Markdown
Owner

Implements P3 and P4 of the foundation spec. Decisions made along the way are recorded as dated notes in the spec.

P3: web UI

  • distill ui serves a local web app at http://distill.localhost:<ui.port>. It listens on loopback only, checks Host and Origin, and requires a session cookie that a one-time link sets. distill ui stop stops it. distill mcp starts it in the background before handing out note links; ui.autostart = false turns that off. Details: docs/web-ui.md.
  • Web app (apps/web, React 19 + TanStack Router/Query + Tailwind v4), embedded into the binary:
    • The sidebar has Distill and Review tabs, with every tag listed below them.
    • Distill is a timeline of notes grouped by day: each entry shows the question and the first two lines of the conclusion, and expands in place to the full note. A tag filters it.
    • Review is a dashboard: week-over-week notes, repeat rate, annotation coverage, active days, a 26-week activity calendar, notes per week, most-asked and unannotated topics, duplicate suggestions, and breakdowns by tag, project and agent.
    • The note page (add/edit/delete annotations, reopen the original session), the topic page (rename, merge) and the sync-conflict page remain.
  • Core: new operations for topic rename and merge, annotation edit and delete, conflict resolution (the losing copy is moved to <data dir>/discarded/, not deleted), a paged timeline, and extra stats.
  • API types are generated from Rust with ts-rs into apps/web/src/api/generated. CI fails if the committed files drift.

P4: semantic recall

  • distill model pull downloads a local multilingual embedding model: paraphrase-multilingual-MiniLM-L12-v2, quantized, about 257 MB, run through fastembed on ONNX Runtime.
  • With the model installed, recall merges the keyword and embedding rankings, so questions asked in other words or another language are found. Without it, recall stays keyword-only.
  • Vectors are stored and searched in sqlite-vec vec0 tables with cosine distance. Registering the extension needs one unsafe call, so the workspace lint changes from forbid to deny, with a single exception in crates/distill-core/src/index/vec.rs.
  • The web UI suggests topic pairs that look like the same question, with merge and dismiss. No background LLM is involved.
  • Thresholds were measured on 12 Chinese/English question pairs: rewordings scored 0.40–0.74 and different questions up to 0.54, so recall keeps a low floor (0.40) and merge suggestions use 0.65. See docs/recall.md.

Things to know

  • Building now needs Node 22 and pnpm. mise run install builds the web UI, then installs the binary with it embedded.
  • The release binary grows from about 12 MB to about 42 MB, mostly ONNX Runtime.
  • The model tests are #[ignore]d and CI does not run them. Run them locally after pulling the model:
    DISTILL_TEST_MODEL_HOME=<home with model> cargo test -p distill-core --test semantic -- --include-ignored

Testing

  • mise run check passes: Rust fmt, clippy, tests, plus Biome, tsc, Vitest and a build of the web app.
  • The P4 exit criterion is a test: two rewordings that keyword recall misses are found by semantic recall. It passes against the real model.
  • Clicked through in the in-app browser against a seeded vault:
    • authorize a browser, open a note, add an annotation;
    • jump from a tag to other notes with that tag;
    • expand a timeline entry, filter the timeline by tag;
    • view the Review dashboard, merge a suggested duplicate;
    • dark theme and phone width.
  • Not verified yet:
    • opening an agent-given link from a real Codex / Claude Code session;
    • the deep link from a note back to its original session;
    • *.localhost resolution on Linux and Windows;
    • CI with the new Node and ONNX Runtime steps (first run is this PR).

🤖 Generated with Claude Code

jackeydou and others added 7 commits September 26, 2026 12:26
Note, topic and topic-list reads; topic rename and merge, annotation edit and
delete, and conflict resolution that sets the losing copies aside outside the
vault. View types derive ts-rs so the web UI's API types are generated.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
A loopback-only HTTP server at http://distill.localhost:<ui.port>: session
cookie from a one-time link, Host and Origin checks, a JSON API over the core
browse and edit operations, server-sent change events from a vault watcher,
and the embedded web app. distill mcp starts it in the background before it
hands out note links; `ui.autostart = false` turns that off.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
React single-page app in apps/web, embedded into distill and served by
distill ui: home, notes search, note page with annotations and session
reopen links, topic timelines with rename and merge, tags, stats and sync
conflict resolution. API types are generated from Rust by ts-rs; mise run
check now covers lint, types, tests and a build of the web app.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
A local multilingual embedding model (paraphrase-multilingual-MiniLM-L12-v2,
quantized, on ONNX Runtime via fastembed) is fetched once with `distill model
pull`. Recall then fuses keyword and embedding rankings, so reworded and
translated questions come back; without the model it stays keyword-only.
Topic pairs that are probably one question are offered for merging in the web
UI, and can be dismissed. Vectors are cached in the index and survive reindex.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Records the answers to Q5, Q11, Q13 and Q15, the embedding model choice, why
vectors are not in sqlite-vec, the measured thresholds, how the UI server
differs from D7 as written, and what is still unverified.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Note and topic vectors now live in vec0 tables with cosine distance, and
recall, similar topics and duplicate suggestions are KNN queries instead of
in-memory scans, as spec D3 planned. Registering the statically linked
extension needs one unsafe call, so the workspace lint goes from forbid to
deny with a single audited exception in index/vec.rs. Migration 0002 is
rewritten in place; it has not shipped.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The sidebar now has two tabs with every tag listed below them. Distill is a
timeline of notes grouped by day: the question and the first two lines of the
conclusion, expanding in place to the whole note, filtered by the chosen tag.
Review is a dashboard: week-over-week notes, repeat rate, annotation coverage,
active days, a 26-week activity calendar, notes per week, most-asked and
unannotated topics, duplicate suggestions, and notes by tag, project and agent.
The core gains a cursor-paged timeline and per-day and per-agent counts.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review ✅ Completed 2026-09-26T22:18:19.366395Z 96fbf77 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@jackeydou
jackeydou merged commit 6bd19bf into main Sep 26, 2026
2 checks passed
@jackeydou
jackeydou deleted the web-ui-and-semantic-recall branch September 26, 2026 23:30
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