Skip to content

DR-102: schema-coverage merges external evidence via sidecar files; declarations are never write proof

DR-102: schema-coverage merges external evidence via sidecar files; declarations are never write proof

Section titled “DR-102: schema-coverage merges external evidence via sidecar files; declarations are never write proof”

schema-coverage’s verdicts were TypeScript-only; the Python pipeline, its cocoindex declarative writes (TableSchema/mount_table_target/ declare_row), and the l_records const-SQL layer were static caveats. The initiative-12 census rule requires wiring verdicts to cover TS chains + Python + declaratives (+ a pg_proc/migrations scan). Joining the surfaces needed both a transport (how external evidence reaches the TS verdict engine) and a semantics (what a data-declared schema column proves). Shipped in PR #150 ({377.4}).

External evidence merges through a versioned sidecar file contract (v1: {schemaVersion: 1, source, rows: [{table, column|"*", direction, confidence, method, file, line, source}]}) consumed by schema-coverage --evidence <path> (repeatable). Verdict rules are unchanged by merging — evidence changes, not the rules. Declaration is never write proof: schema-declaration rows (method table-schema) are emitted at indirect confidence only, so a declared-but-never-written column verdicts undecidable, never wired/write-only; only observed write payloads (declare_row keys, SQL, chain payloads) can be exact. Table-scoped * rows merge as wildcard-reads / indirect-writes (smoke, not proof).

  • Count declarations as writes — rejected on corpus evidence: flow.py declares source_documents columns “for schema completeness” it deliberately never populates, and sd_target is mounted but written via raw SQL with 26 columns against 22 declared. Declarations lie in both directions.
  • A new “declared” confidence tier — rejected: it ripples through the envelope types and every consumer; mapping declaration→indirect produces the correct verdicts through the existing engine unchanged.
  • In-process/shell-out integration (TS invokes the Python scanner) — deferred, not adopted: sidecar files keep the runtimes decoupled, make any extractor in any language a first-class producer (pg_proc scan, Prisma/Drizzle adapters) without touching the TS core, and the extraction-phase standalone can still add a one-shot convenience wrapper.
  • The census three-surface rule is a two-command recipe (ast-dataflow-py schema-usesschema-coverage --evidence); the pg_proc/migrations scan joins by emitting the same contract ({399.1}).
  • Sidecars are point-in-time files: callers must regenerate them per run — staleness is the caller’s responsibility, and merged sidecars are named in caveats.mergedEvidence so a verdict’s evidence base is auditable.
  • Producers must be loud about blindness (unparsed/dynamic SQL, rpc payloads, unattributable declare_row sites are caveat counts, never silent drops); the consumer routes unknown tables/columns to caveats.evidenceUnknownTables instead of crashing or dropping.