recall — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited recall (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Pull relevant memory from iroha so you reuse past decisions and prior work instead of re-deciding or re-building from scratch — the core of a living, growing team memory. Notion is the single source of truth, and notion-search works on the free plan (workspace_search), so recall reads canonical, always-current team data directly — there is no local copy to drift.
L="${CLAUDE_PLUGIN_ROOT}/scripts/_lib/config.ts"
bun "$L" get decisions_ds_id
bun "$L" get session_ds_idRun notion-search once per database, passing the user's query ($ARGUMENTS) and data_source_url: "collection://<id>". Keep page_size ~5 and max_highlight_length ~160.
decisions_ds_id) — for "did we decide X / why / what did wereject?". The Rationale appears in the highlight; notion-fetch the top hit for the full Rationale / Alternatives.
session_ds_id) — for "have we built something like this before?".notion-fetch a promising hit to read its summary, its Decisions, and the Changed files toggle, so you can point at the actual prior implementation.
notion-search orders by semantic relevance only. Re-rank the hits before presenting, combining three signals (Generative Agents' recency + importance + relevance):
Date outranks an older one;architecture / dependency decisions outweigh process; an Activedecision outranks a Superseded one.
Present at most 3-5 hits, most important first — models read the start and end of a context window most reliably (Lost in the Middle), so lead with the load-bearing decision rather than burying it in a long flat list. Drop weak / irrelevant hits instead of padding the list: a low-confidence hit presented as fact is worse than a shorter, honest answer (Self-RAG / CRAG). For a completeness-critical "does a decision on X exist at all?" check, consult the local index — exhaustive where search is not:
bun "${CLAUDE_PLUGIN_ROOT}/scripts/_lib/index.ts" find-topic "$PWD" "<topic>"notion-search returns only a top-N semantic slice, and a just-saved decision is missing from its index for a few minutes (Notion search has write-lag). So also enumerate the complete, instantly-current local index and pick anything relevant that search missed:
IDX="${CLAUDE_PLUGIN_ROOT}/scripts/_lib/index.ts"
bun "$IDX" list "$PWD" decision # every decision: id / topic / status / date / title
bun "$IDX" list "$PWD" session # every sessionRead the titles/topics, pick any that match the query but were not already returned by search, and notion-fetch those by id for full content. Merge with the search hits, dedup by id, then rank (step 2b). This makes recall complete (the index has every row) and fresh (it includes work saved moments ago) — search alone is neither. If the index is empty/stale (a workspace predating it), say so and fall back to search only.
the Session link. Treat a Status = Superseded hit as outdated — prefer the current decision and mention what replaced it.
list the files it changed and the decisions it set — "we've done this before; here's the reference and what to reuse." This is what makes iroha pay off more the more the team uses it.
recorded ## Failures (symptom → cause → fix) from prior Sessions so the dead-end is not repeated — "we hit X before; the cause was Y; the fix was Z." Avoiding a known dead-end is as valuable as reusing a decision.
Summary is a snapshot from its date and maydescribe a since-changed state (an old session may say "2 DB" when the project now has 3). Sessions are immutable history (no supersede), so treat the newest Session, the State page, and `Active` Decisions as current — never echo a stale Session summary as today's fact.
If notion-search returns no relevant hit, say so explicitly — report (in the user's conversation language) that no record was found for these search terms, and stop. Do not invent a past decision, reconstruct one from the current code, or present a plausible-sounding answer as if it were recalled. LLMs default to fabricating rather than abstaining (this is an unsolved failure mode that does not improve with scale — AbstentionBench), so a confidently wrong recall is worse than an honest miss.
Scope every negative correctly. For decisions/sessions the hybrid index cross-check (step 2c) is exhaustive, so if neither search nor the index has a relevant entry you can say "no such decision exists" with confidence. For anything the index does not cover (e.g. free-text deep inside a page body), a notion-search miss only means not found for these terms — retry with different terms before concluding it is absent.
UserPromptSubmit hook(recall-inject.ts → recall.ts :: recallLocal) runs the cheap, always-on local stage on every substantive prompt — offline, no LLM, no Notion round-trip — and proactively surfaces the top matching decisions as pointers. Its FREE tier is a hand-rolled TS BM25 (search.ts); an OPT-IN HEAVY tier adds a local dense bi-encoder (embed.ts) for the semantic near-matches BM25 misses and a cross-encoder that promotes strong matches above the BM25 list (it never vetoes a BM25 hit — that cost real recall). This skill is the deep second stage: the user or Claude escalates to /iroha:recall when that cheap pointer is not enough, and here we add Notion semantic search plus full Rationale / Alternatives / changed-files synthesis.
corpus an off-topic prompt that merely shares the project's software vocabulary can surface an irrelevant decision — and no local signal (BM25 score, dense rank, or the cross-encoder's low end) cleanly separates that from a real-but-terse match (measured). The floor is intentionally not raised to suppress it, because that trades away real recall (the north-star value). So the hook's injected pointers are advisory ("possibly relevant; verify"): if a surfaced decision does not actually bear on the request, treat it as noise and ignore it — never force it into the answer. This /iroha:recall semantic stage + your judgement are the precision filter.
so it is always current. The repo's .iroha/index.ndjson is not a content mirror — it holds keys + a short derived search snippet (id / topic / status / date / title / a rationale condensation) so recall can enumerate the complete set, cover search's top-N and write-lag gaps, and power the local BM25 stage; the full text always comes from notion-fetch. The SessionStart hook separately injects State from .iroha/state.md.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.