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
Owner

Wave 1 of audit remediation

Targets the correctness findings that need no data migration — the identity
normalization (C-7) and its re-ingest are Wave 2. This branch is stacked on
audit/loop-1, so the PR diff is exactly the four fix commits below.

Fixes

  • C-4 (HIGH) fix(wiki)compile_all published zero-citation pages
    (incl. the LLM-outage empty-page case) because the quarantine gate was guarded
    by total_claims > 0. Now quarantines them and does not freeze them as
    "compiled" in the compile-state. Regression test reproduces the bypass.
  • C-11 (HIGH) fix(synthesis) — every stage numbered leads from L-0001,
    so connection / gap / improvement leads collided in grounded/ and silently
    overwrote one another (4 distinct leads → 2 files). Ids are now kind-prefixed
    (L-C-/L-G-/L-I-/L-X-). Regression tests added.
  • C-1 (HIGH) fix(discover)discover.py compared the raw OpenAlex
    cited_id against papers.id, mis-reporting ingested papers as discovery
    leads. The cited_id→paper resolution is now a single shared
    RESOLVED_CITATIONS_SQL used by both graph.py and discover.py, so the
    rule cannot drift again. Live-DB validated: 13 → 0 ingested papers leaking
    into discovery_leads.
  • D-2 / D-4 docs — corrected the cite-boost formula docstring and the
    write_leads / _update_index "append-only" contradiction.

Verification

  • Full suite: 332 passing (2 net new tests); ruff + mypy clean.
  • C-1 validated against the live Jetson DB; C-4 / C-11 reproduced end-to-end.

Findings reference: docs/audit/AUDIT-2026-06-15-full-repo.md (on audit/loop-1).

🤖 Generated with Claude Code

## Wave 1 of audit remediation Targets the correctness findings that need **no data migration** — the identity normalization (C-7) and its re-ingest are Wave 2. This branch is stacked on `audit/loop-1`, so the PR diff is exactly the four fix commits below. ### Fixes - **C-4** (HIGH) `fix(wiki)` — `compile_all` published zero-citation pages (incl. the LLM-outage empty-page case) because the quarantine gate was guarded by `total_claims > 0`. Now quarantines them and does not freeze them as "compiled" in the compile-state. Regression test reproduces the bypass. - **C-11** (HIGH) `fix(synthesis)` — every stage numbered leads from `L-0001`, so connection / gap / improvement leads collided in `grounded/` and silently overwrote one another (4 distinct leads → 2 files). Ids are now kind-prefixed (`L-C-/L-G-/L-I-/L-X-`). Regression tests added. - **C-1** (HIGH) `fix(discover)` — `discover.py` compared the raw OpenAlex `cited_id` against `papers.id`, mis-reporting ingested papers as discovery leads. The cited_id→paper resolution is now a single shared `RESOLVED_CITATIONS_SQL` used by both `graph.py` and `discover.py`, so the rule cannot drift again. **Live-DB validated: 13 → 0** ingested papers leaking into `discovery_leads`. - **D-2 / D-4** `docs` — corrected the cite-boost formula docstring and the `write_leads` / `_update_index` "append-only" contradiction. ### Verification - Full suite: **332 passing** (2 net new tests); `ruff` + `mypy` clean. - C-1 validated against the live Jetson DB; C-4 / C-11 reproduced end-to-end. Findings reference: `docs/audit/AUDIT-2026-06-15-full-repo.md` (on `audit/loop-1`). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
user2595 changed target branch from audit/loop-1 to main 2026-06-16 04:53:08 +00:00
user2595 added 4 commits 2026-06-16 04:53:08 +00:00
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>
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>
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>
- 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>
user2595 merged commit dca0dd793f into main 2026-06-16 04:53:20 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: user2595/codex-py#12
No description provided.