Audit source-derived KB rebuild coverage

This commit is contained in:
twentyOne2x 2026-07-13 10:58:53 +02:00
parent 279962fe8a
commit ed6b4b8b69
4 changed files with 1396 additions and 0 deletions

View file

@ -65,6 +65,18 @@ The simple retained-row joins currently reproduce:
- 4,878 of 4,916 canonical edge rows can be accounted for by a staged relation;
historical duplicate multiplicity still needs an explicit replay rule.
Re-run this aggregate, read-only coverage audit against any restored local
clone:
```bash
.venv/bin/python ops/audit_kb_rebuild_coverage.py \
--container <restored-local-postgres-container> \
--database teleo
```
The auditor emits no claim bodies or source excerpts and separates snapshot
recovery from source-derived recompilation readiness.
The remaining gaps are concrete rather than mysterious:
- 30 claims were created after or outside the mapped import;

View file

@ -0,0 +1,71 @@
# KB Source Recompile Coverage
Generated UTC: `2026-07-13T08:51:50.309130+00:00`
Status: **partial**
This audit ran inside a repeatable-read, read-only transaction against a fresh
restored canonical database. It emitted aggregate counts only: no claim bodies,
source excerpts, credentials, or database writes. The disposable container was
removed and a later Docker inspection confirmed it was absent.
## What Can Be Rebuilt From Retained Import State
| Surface | Covered | Canonical | Coverage |
|---|---:|---:|---:|
| Claims with canonical mappings | 1,807 | 1,837 | 98.37% |
| Sources with canonical mappings | 4,145 | 4,145 | 100.00% |
| Eligible mapped claim field projection | 1,807 | 1,807 | 100.00% |
| Eligible staged source field projection | 3,861 | 3,861 | 100.00% |
| Evidence links from staged claim-source rows | 4,254 | 4,670 | 91.09% |
| Edge rows accounted for by resolved staged relations | 4,878 | 4,916 | 99.23% |
| Applied proposals with replayable apply payload | 1 | 2 | 50.00% |
The claim projection compares type, title-to-text, status, confidence, tags,
creator, and applicable legacy creation time. The source projection compares
type, URL, storage path, excerpt, hash, capture time, and creator. Relation
coverage does not by itself reconstruct row IDs, timestamps, creators, or
historical duplicate multiplicity.
## Retained Import State
- Import runs: `2`
- Inventory items: `11,624` (`5,812` per run)
- Staged claims: `2,277`
- Staged sources: `4,715`
- Staged claim-source rows: `5,195`
- Staged claim-edge rows: `6,593`
- Canonical mappings: `5,952`
Both imports point to the same retained 5,812-file Forgejo-era workspace
inventory. The second run reflects the corrected classifier mapping.
## Exact Remaining Gaps
- `30` canonical claims have no canonical mapping.
- `284` source mappings do not resolve to a staged source in their recorded
first import run.
- `66` distinct staged claim keys and `85` staged source keys have no canonical
mapping.
- `155` staged claim-source rows cannot resolve both mapped endpoints.
- `416` canonical evidence links have no exact staged relation projection.
- `700` staged edges are not resolved; another `152` resolved staged edges
cannot resolve both mapped endpoints.
- `38` canonical edge rows have no matching resolved staged relation.
- `1` applied proposal has no non-empty replayable `apply_payload`.
## Command
```bash
.venv/bin/python ops/audit_kb_rebuild_coverage.py \
--container <restored-local-postgres-container> \
--database teleo
```
## Interpretation
Fast exact snapshot recovery is complete and separately proven. Source-derived
recompilation is close for the original mapped claim/source graph, but it is not
yet a complete blank-database rebuild. The practical next step is to preserve
the current snapshot as genesis, backfill the listed gaps, and require every
future accepted change to carry a replayable apply payload and row receipt.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,244 @@
from __future__ import annotations
import json
import re
from collections.abc import Sequence
from typing import Any
import pytest
from ops.audit_kb_rebuild_coverage import (
CommandResult,
audit_database,
build_audit_sql,
build_report,
)
def aggregate_fixture() -> dict[str, Any]:
return {
"identity": {"database": "teleo", "transaction_read_only": "on", "server_version_num": "160004"},
"canonical_counts": {"claims": 10, "sources": 8, "claim_evidence": 12, "claim_edges": 9},
"staging_counts": {
"canonical_mappings": 17,
"import_runs": 1,
"inventory_items": 20,
"staged_claims": 11,
"staged_sources": 8,
"staged_claim_sources": 13,
"staged_claim_edges": 10,
"kb_proposals": 4,
},
"mappings": {
"claims": {
"rows": 9,
"legacy_keys": 9,
"target_ids": 9,
"missing_canonical_targets": 0,
"with_first_run_staged_row": 9,
"canonical_target_rows_covered": 9,
"canonical_target_rows_unmapped": 1,
"staged_distinct_keys": 10,
"staged_distinct_keys_unmapped": 1,
},
"sources": {
"rows": 8,
"legacy_keys": 8,
"target_ids": 8,
"missing_canonical_targets": 0,
"with_first_run_staged_row": 7,
"canonical_target_rows_covered": 8,
"canonical_target_rows_unmapped": 0,
"staged_distinct_keys": 8,
"staged_distinct_keys_unmapped": 0,
},
"unsupported_target_rows": 0,
},
"claim_parity": {
"compared_fields": ["type", "text_from_title"],
"eligible_rows": 9,
"exact_projection_rows": 9,
"field_matches": {"type": 9, "text_from_title": 9},
"projection_limits": {"staged_body_nonempty": 9},
},
"source_parity": {
"compared_fields": ["source_type", "hash"],
"eligible_rows": 7,
"exact_projection_rows": 6,
"field_matches": {"source_type": 7, "hash": 6},
"projection_limits": {"staged_title_nonempty": 7},
},
"claim_evidence_reconstruction": {
"compared_fields": ["claim_id", "source_id", "role", "weight"],
"not_replayed_fields": ["created_by", "created_at"],
"staged_rows": 13,
"rows_with_mapped_claim": 12,
"rows_with_mapped_source": 13,
"rows_with_both_mapped_endpoints": 12,
"distinct_projected_rows": 11,
"projected_rows_present_in_canonical": 11,
"canonical_rows_covered": 11,
"canonical_rows_total": 12,
},
"claim_edge_reconstruction": {
"compared_fields": ["from_claim", "to_claim", "edge_type"],
"not_replayed_fields": ["id", "weight", "created_by", "created_at", "duplicate_multiplicity"],
"staged_rows": 10,
"resolution_state_resolved_rows": 9,
"resolved_rows_with_from_mapping": 9,
"resolved_rows_with_to_mapping": 8,
"resolved_rows_with_both_mapped_endpoints": 8,
"distinct_projected_rows": 8,
"projected_rows_present_in_canonical": 8,
"canonical_rows_covered": 8,
"canonical_rows_total": 9,
},
"later_and_unmapped": {
"latest_import_completed_at": "2026-01-01T00:00:00+00:00",
"canonical_created_after_latest_import": {
"claims": 1,
"sources": 0,
"claim_evidence": 1,
"claim_edges": 1,
},
"canonical_without_mapping": {"claims": 1, "sources": 0},
"canonical_relations_not_reconstructible": {"claim_evidence": 1, "claim_edges": 1},
"staged_distinct_keys_without_mapping": {"claims": 1, "sources": 0},
},
"proposal_apply_payload": {
"total_rows": 4,
"status_counts": {"applied": 2, "pending_review": 2},
"with_apply_payload_key": 2,
"with_valid_apply_payload": 2,
"applied_rows": 2,
"applied_with_valid_apply_payload": 1,
},
"import_runs": [
{
"id": "run-id",
"label": "fixture-run",
"repo_path": "/workspace",
"inventory_path": "/inventory/fixture.jsonl",
"started_at": "2026-01-01T00:00:00+00:00",
"completed_at": "2026-01-01T00:01:00+00:00",
"inventory_items": 20,
"staged_claims": 11,
"staged_sources": 8,
"staged_claim_sources": 13,
"staged_claim_edges": 10,
}
],
}
def test_sql_is_guarded_and_read_only() -> None:
sql = build_audit_sql()
assert "BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ READ ONLY" in sql
assert "current_setting('transaction_read_only')" in sql
assert "expected_schema_absent" in sql
assert "\\if :schema_ok" in sql
assert sql.count("ROLLBACK;") >= 2
assert not re.search(r"\b(INSERT|UPDATE|DELETE|CREATE|ALTER|DROP|TRUNCATE|COPY)\b", sql, re.IGNORECASE)
def test_report_separates_snapshot_recovery_from_source_recompile_and_calculates_gaps() -> None:
report = build_report(aggregate_fixture(), container="teleo-test", database="teleo")
semantic = report["source_derived_recompile_readiness"]
assert report["audit_status"] == "complete"
assert report["exact_snapshot_recovery"]["verified_by_this_database_only_auditor"] is False
assert report["exact_snapshot_recovery"]["current_state_counts"]["canonical"]["claims"] == 10
assert semantic["status"] == "partial"
assert semantic["canonical_mappings"]["claims"]["canonical_coverage"] == {
"covered": 9,
"total": 10,
"gap": 1,
"percent": 90.0,
}
assert semantic["canonical_mappings"]["sources"]["first_run_stage_origin_coverage"]["percent"] == 87.5
assert semantic["claim_evidence_from_staged_claim_sources"]["canonical_reconstruction_coverage"]["percent"] == 91.67
assert semantic["claim_evidence_from_staged_claim_sources"]["not_replayed_fields"] == [
"created_by",
"created_at",
]
assert "duplicate_multiplicity" in semantic["claim_edges_from_resolved_staged_claim_edges"]["not_replayed_fields"]
assert semantic["proposal_apply_payload_coverage"]["applied_proposal_payload_coverage"]["percent"] == 50.0
gap_codes = {gap["code"] for gap in semantic["explicit_gaps"]}
assert "canonical_claims_without_mapping" in gap_codes
assert "source_mappings_without_first_run_stage" in gap_codes
assert "mapped_source_projection_mismatch" in gap_codes
assert "canonical_claim_evidence_not_reconstructible" in gap_codes
assert "canonical_claim_edges_not_reconstructible" in gap_codes
assert "applied_proposals_without_valid_apply_payload" in gap_codes
assert semantic["import_run_metadata"][0]["inventory_path"] == "/inventory/fixture.jsonl"
assert report["safety"]["contains_private_bodies_or_source_excerpts"] is False
def test_audit_uses_named_container_database_and_injected_runner() -> None:
captured: dict[str, Any] = {}
def fake_runner(command: Sequence[str], stdin: str, timeout: int) -> CommandResult:
captured.update(command=list(command), stdin=stdin, timeout=timeout)
return CommandResult(0, json.dumps(aggregate_fixture()) + "\n", "")
report = audit_database(
container="teleo-local",
database="teleo",
db_user="postgres",
timeout=45,
runner=fake_runner,
)
assert captured["command"] == [
"docker",
"exec",
"-i",
"teleo-local",
"psql",
"-X",
"-U",
"postgres",
"-d",
"teleo",
"-Atq",
"-v",
"ON_ERROR_STOP=1",
]
assert captured["timeout"] == 45
assert "READ ONLY" in captured["stdin"]
assert report["target"]["container"] == "teleo-local"
assert report["safety"]["transaction_read_only_readback"] == "on"
def test_missing_schema_fails_closed_with_structured_json() -> None:
def fake_runner(_command: Sequence[str], _stdin: str, _timeout: int) -> CommandResult:
payload = {
"status": "error",
"error": "expected_schema_absent",
"missing_relations": ["kb_stage.canonical_mappings"],
"missing_columns": ["kb_stage.canonical_mappings.legacy_key"],
}
return CommandResult(3, json.dumps(payload) + "\n", "")
report = audit_database(container="empty-postgres", database="teleo", runner=fake_runner)
assert report["audit_status"] == "error"
assert report["error"] == "expected_schema_absent"
assert report["details"]["missing_relations"] == ["kb_stage.canonical_mappings"]
assert report["details"]["missing_columns"] == ["kb_stage.canonical_mappings.legacy_key"]
assert "source_derived_recompile_readiness" not in report
def test_invalid_docker_identifier_is_rejected_before_runner() -> None:
called = False
def fake_runner(_command: Sequence[str], _stdin: str, _timeout: int) -> CommandResult:
nonlocal called
called = True
return CommandResult(0, "{}", "")
with pytest.raises(ValueError, match="container must match"):
audit_database(container="--privileged", database="teleo", runner=fake_runner)
assert called is False