Skip to content

Explain v1: a model-free Compare view for a Similar card #236

Closed

Description

@samkeen

Part of #235.

What

An Explain action on every Similar & unlinked card (beside Why?, and in the card menu for the keyboard). It opens a Compare mode in the center pane, the way Graph mode does: the open note (the anchor) against the candidate, built only from stored data.

┌ Volcano notes  ↔  Weekly journal 2024-W12 ─────────────── ●●● 2.8σ · #2 of 10 ┐
│ One section matches strongly; the rest of the note is about other things.      │
│ (Whole-note rank #87 → best-passage rank #2)                                   │
│                                                                                │
│ Where it sits among the 200 unlinked notes compared                            │
│   · ·· ····:::::||||||||:::···· ·    ·   │1.96 ●●○   │2.52 ●●●   ▲ this card   │
│                                                                                │
│ Best pairs                                                                     │
│ 1 ●●● Lava fields ↔ Thursday     2 ●○○ Eruptions ↔ Thursday    3 ...           │
│ ┌ Your note › Lava fields ───────┐  ┌ Journal › Thursday ────────────────────┐ │
│ │ ...basalt flows cool into ropy │  │ ...walked the pahoehoe crust at dawn,  │ │
│ └────────────────────────────────┘  └────────────────────────────────────────┘ │
│ Links: not linked. Shared neighbors: Hawaii trip                               │
│ [Open]  [Ask chat why ▸]                                                       │
└────────────────────────────────────────────────────────────────────────────────┘

v1 scope

  1. Facts line: rank in the served list, strength band, z; the candidate's whole-note (centroid) rank beside its best-passage rank.
  2. Summary label from fixed, documented rules (no model):
    • Identical text: the winning pair shares a text_hash (the same passage is in both notes, e.g. a template).
    • One section matches: best-passage rank far better than whole-note rank.
    • Broadly similar: several candidate passages pair at or above the ●●○ landmark.
    • otherwise Nearest in meaning.
      The labels grade nothing and gate nothing; their rules are written down in the view type's docs.
  3. Where-it-sits strip: every scored candidate's z as a dot, the two band landmarks, this card marked. Shows "strong compared with what", and the Discovery floor: the z rule assumes an unrelated tail that a single-domain vault does not have — 16 of 17 notes serve nothing #196 compression at a glance.
  4. Best pairs: the top passage pairs (discover::passage_pairs), each with both passages' heading path and text, each graded in the dot bands.
  5. Link context: directly linked (then it would not be listed), shared neighbors.
  6. Hand-off: Ask chat why runs today's Why? on the same pair.

Engine

  • discover::candidates also reports the population behind the dots (size, mean, sd of best-passage squared distances) and each row's stage-1 (centroid) rank. Row order and z are unchanged, and a test pins that.
  • New façade op Vault::explain_similar(anchor, candidate, limit) -> SimilarExplainView. Works for any pair: a candidate outside the served list still gets its facts (rank past the list, or excluded as linked).
  • CLI: b2 similar NOTE --explain OTHER [--json]. b2 similar's own --json is unchanged.
  • Desktop: one explain_similar command reusing the view type.

Out of scope for v1 (see #235 children)

Match map heatmap, shared words, the "why isn't X here?" picker, jumping to the passage inside the note (#232).

As built (PR #242)

Two decisions changed during the build. The spec above is kept as written; this is what shipped and why.

  1. discover::candidates is unchanged. The population statistics and the stage-1 (whole-note) rank are reported by a new discover::explain instead. Both read one shared field computation, so the card and its explanation still can't disagree, and b2 similar --json and the Similar list keep their exact shape and order.
  2. The summary labels count passages at the ●●○ mark instead of using a rank gap. A rank-gap rule ("whole-note rank far worse than best-passage rank") needed a new, uncalibrated threshold. Counting candidate passages whose pair reaches the existing 1.96σ mark reuses a measured number. The rules, in order: Identical text; no label when ungraded; then No passage stands out (none reach the mark), A clear match (its only passage does), One section matches (one of several), Broadly similar (at least half), A few sections match (otherwise). The whole-note vs best-passage ranks are still shown as a fact line whenever they differ. Documented in ui/src/explain.ts.

Added during review: a σ axis with a key and a "?" account on the strip; same-titled notes named by path; the card count capped at what the list shows; the CLI says when pairs are ungraded; docs say explanations agree with the list at the same --limit.

Activity

  1. added a commit that references this issue on Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions