Build Recall

KINDAreplaces $10/mosaves $120/yrback to the verdict

0%0 of 17 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

A personal knowledge tool that summarises sources and connects them automatically, where the whole difficulty is that automatic linking produces mostly noise, and a graph where everything connects to everything is the same as a graph with no links at all.

estimated effort multi-daythe files for this build are in the project pack

CaptureSources saved with their extracted text at capture timeEntitiesExtracted with resolution across sourcesLinksTyped, evidenced and thresholded rather than generated freelySummariesGenerated with citations into the stored textRuntimeTypeScript with a local application and SQLite

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. installfree

    Why Runs the local application and the extraction pipeline.

    Get it nodejs.org, or nvm install 22. open ↗

    Verify node --version prints v22 or higher

  2. installfree, needs memory

    Why Reading history and summaries are personal, and entity extraction runs over everything you save.

    Get it Any local runner with a model that returns structured output reliably for extraction. open ↗

    Verify Ten extractions return valid structured output with positions

  3. have readyfree

    Why Graph density, entity resolution and link quality are all uninteresting below a hundred sources and become the entire problem above two hundred.

    Get it Import from wherever you save things now, including the duplicates and the articles about the same topic from different angles.

    Verify Two hundred sources exist with overlapping subject matter

  4. decidefree

    Why An unthresholded graph connects everything, and choosing the threshold after seeing the graph means choosing whichever makes it look best.

    Get it Decide the minimum link strength and the density above which you consider the graph degraded, before generating any links.

    Verify Both numbers are written down and configured

  5. have readyfree

    Why Entity resolution quality is only assessable where you know the right answer, including the cases where two similar names are genuinely different people.

    Get it From your sources, list ten entities including two pairs that look similar and are distinct.

    Verify The list exists with the correct merges and non-merges noted

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- sources(id, kind, url, title, text, author, published_at, captured_at)
- entities(id, kind, canonical_name, aliases_json, first_seen_source_id) · kind is person, organisation, concept or work
- mentions(source_id, entity_id, char_start, char_end, surface_form, confidence)
- links(id, from_entity_id, to_entity_id, kind, strength, evidence_source_ids_json, created_at) · kind names the relationship
- summaries(source_id, body, cited_spans_json, model, generated_at, validated)
- reviews(entity_id, merged_into_id, decided_by, at) · entity merges are decisions and are reversible
- A link stores the sources that evidence it, so a connection can be inspected rather than trusted, and a weak link can be found and removed.

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
DB_PATHrequired~/.local/share/recall/graph.dbSources, entities and links. A record of what you have been reading.
EXTRACTION_MODELrequiredlocalRuns over everything you save, so local is the sensible default.
LINK_STRENGTH_THRESHOLDrequired0.6Below this no link is created. Unthresholded graphs connect everything.
MAX_ENTITY_DEGREErequired200An entity connecting to more than this is flagged as a hub rather than accepted.
AUTO_MERGE_ENTITIESrequiredneverPresent as a constant. Combining two people is not recoverable.
PRUNE_AFTER_DAYSrequired365Weak links and orphaned entities are pruned on a policy to keep the graph legible.

The build, in order

  1. Sources saved whole

    What you read is stored as text, not as a link.

    1. Fetching later means a page that changed or vanished.

      Files src/capture.ts

    2. A claim's provenance depends on both.

      Files src/extract.ts

    3. Any field at capture time is a decision, and decisions end habits.

      Files src/capture.ts

    done when · tick each as it passes
    watch out
    • Storing a link and fetching the content when needed means a source that changed or disappeared takes your notes and summaries with it, and the failure appears months later when the reference is most valuable. Extract and store the text at capture.
  2. The same thing named three ways

    Entity mentions across sources resolve to one node.

    1. So a link can point at the sentence rather than the document.

      Files src/entities.ts

    2. Combining two people is not recoverable from the mentions.

      Files src/merge.ts

    3. With the decision recorded. You will get some wrong.

      Files src/merge.tstests/merge-reversal.test.ts

    done when · tick each as it passes
    watch out
    • Merging entities automatically on name similarity combines two different people who share a surname, and afterwards there is no way to separate their mentions because the information about which was which is gone. Propose, require confirmation, and keep merges reversible.
  3. Links that mean something

    The graph is sparse enough to be useful.

    1. Co-occurrence alone connects everything to everything.

      Files src/links.ts

    2. An untyped association is barely more useful than none.

      Files src/links.ts

    3. Rising density is a defect, not coverage.

      Files src/graph-health.ts

    done when · tick each as it passes
    watch out
    • Linking every pair of entities that co-occur in any source produces a graph where a common concept connects to everything, and a graph where everything is connected carries exactly as much information as one with no links. Threshold on strength, type the relationship, and treat rising density as a defect rather than as coverage.
  4. Summaries you can check

    Every summary line cites the text it came from.

    1. Validated against the stored text, not against the source URL.

      Files src/summarise.tssrc/validate.test.ts

    2. A summary with one invented line silently removed is still untrustworthy.

      Files src/summarise.ts

    3. Your reading history is a record of what you were thinking about.

      Files src/policy.ts

    done when · tick each as it passes
    watch out
    • A summary of a source you have not read is exactly the artefact people quote later without checking, and a model summarising a long article will confidently smooth over a qualification. Require a citation per line, validate that it resolves, and reject the whole summary rather than dropping the offending line.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more reading.