israerusan_unwritten/docs
Israel Avila 51904e585c Unwritten 1.0.0 — report the notes you never wrote
The free tier is the whole gap report: one batch command, no listeners, no
background work. It reads the metadata cache, writes Gap Report.md, and stops.

Three heuristics, all pure functions in src/core/gaps.mjs over a plain snapshot
of the link graph, so every one of them is tested against a synthetic vault with
no Obsidian in the loop:

- Unexplained pairs. Two notes linked from the same N places with no SHORT note
  linking both. The bridge rule is the whole heuristic: a 6-link note that points
  at both is the note that explains them and the pair is dropped; a 30-link map of
  content is not, because it is a shelf. Notes above 40 outlinks are skipped for
  pairing (O(k^2)) and the report says how many.
- Stub hubs. High in-degree, low word count.
- Decisions with no stated reason. `decision: true` or #decision, with no rationale
  heading and no line that says because. Deliberately generous — nagging someone
  about a note that already explains itself is what gets a plugin uninstalled.

The report is a PROMPT, NOT A TASK LIST, and says so in a callout at the top along
with the settings it ran with. Precision on structural heuristics is genuinely low
at first and the copy does not pretend otherwise. There is not a checkbox anywhere
in it and a test asserts there never will be.

Writing it:
- Vault.process, never Vault.modify on a file we also read — process re-reads under
  the vault's own lock, so the read and the write are one operation.
- The exact bytes written are hashed (FNV-1a, shared/hash.mjs). If the file no longer
  hashes to that, it is the user's, and regenerating asks first — with "save as a new
  file" as one of the answers, so their notes on the notes are never eaten.
- The guard is re-checked INSIDE process(), so a change landing between the check and
  the write cannot be clobbered silently.
- The report is excluded from its own scan. It links every note it names; leaving it
  in would make it the biggest map of content in the vault and the heuristic would
  start feeding on its own output.

Licensing: offline Ed25519 against the shared suite key, vendored from
obsidian-plugin-core. Revocation is checked BEFORE the signature (a leaked key's
signature is perfectly valid). The committed fixture is minted under
"second-read-test" and is asserted inert against the real product id, in both
directions — the vault-spotlight leak is not repeating here.

The two Pro features (pair evidence, latent topics) need the semantic engine and
are not shipped in this version. The gate and the tier table are in place so adding
them is a feature file and a command, not a refactor.

esbuild target is es2020, not the portfolio's usual es2018: the shared hash.mjs uses
BigInt literals, and at es2018 esbuild emitted three "may crash at run-time" warnings
while passing them through untransformed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3f6GZ2A8FbZerhJEpJQBE
2026-07-14 07:52:39 -04:00
..
obsidian-release-checklist.md Unwritten 1.0.0 — report the notes you never wrote 2026-07-14 07:52:39 -04:00