fix: audit remediation Wave 1 — correctness fixes C-1, C-4, C-11 (+ doc fixes) #12

Merged
user2595 merged 4 commits from fix/audit-wave-1 into main 2026-06-16 04:53:20 +00:00

4 Commits

Author SHA1 Message Date
Tarik Moussa
6193f5630d docs: fix two doc/code contradictions (audit D-2, D-4)
- D-2 config.py: graph_cite_boost_alpha described the OLD inverted formula
  (score = dense * (1 + alpha*pr)); the code divides distance. Document the
  actual boosted_distance = distance / (1 + alpha*pr).
- D-4 synthesis.py: write_leads claimed an 'append-only' INDEX.md that keeps
  previously-recorded ids; _update_index actually rebuilds from on-disk glob.
  Docstring now matches the implementation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-15 11:13:52 +02:00
Tarik Moussa
eee147275a fix(discover): resolve cited_id via shared resolver (audit C-1)
discover.py compared the raw OpenAlex cited_id against papers.id (a DOI/arXiv
id), so an ingested paper cited by its OpenAlex id was mis-reported as a
discovery lead. graph.py already resolved this via papers.openalex_id, but the
fix was never propagated — two 'dangling' implementations disagreed.

Extract the resolution into one shared constant RESOLVED_CITATIONS_SQL in
graph.py; build_citation_graph and all four discover.py queries
(discovery_leads / citing_papers / cited_by / cocited_papers) now go through it,
so the 'what counts as ingested' rule cannot drift again.

Live-DB validated: before, 13 ingested papers leaked into discovery_leads;
after, the real discovery_leads() returns 0 ingested papers among its leads.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-15 11:12:55 +02:00
Tarik Moussa
3092f1814e fix(synthesis): namespace lead ids by kind to stop collisions (audit C-11)
Each stage (find_connections/gaps/improvements/propose_conjectures) numbered its
leads from seq=1, so connection L-0001, gap L-0001 and improvement L-0001 all
resolved to grounded/L-0001.md. The CLI concatenates them
(connections + gaps + improvements) and write_leads writes in order, so later
kinds silently overwrote earlier ones — survivors = max(per-kind count), not the
sum. Reproduced: 4 distinct leads -> 2 files.

_make_lead_id now takes the kind and emits L-C-/L-G-/L-I-/L-X- prefixes, keeping
same-seq ids distinct across stages. Regression tests cover the format and the
no-collision invariant.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-15 11:09:24 +02:00
Tarik Moussa
115bb63f2d fix(wiki): quarantine zero-citation pages instead of publishing (audit C-4)
compile_all's quarantine gate was guarded by `total_claims > 0`, so a page
with no parseable citations — including the LLM-outage case where
compile_concept returns an empty page — fell through to the publish branch and
was written to wiki/ + marked compiled. Such a page carries zero grounding
evidence.

Now: total_claims == 0 (or grounding_rate below threshold) quarantines and does
NOT update the compile-state, so a transient LLM failure retries next run
instead of freezing an empty/uncited page as 'compiled'. Empty bodies are
recorded but not written as draft files.

Regression test reproduces the exact bypass (uncited LLM output -> quarantined,
not published).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-15 11:06:12 +02:00