Skip to content

Add inert source-backed claims schema foundation#118

Merged
jeffgreendesign merged 2 commits into
mainfrom
claude/claims-schema-foundation-tiexfk
Jun 21, 2026
Merged

Add inert source-backed claims schema foundation#118
jeffgreendesign merged 2 commits into
mainfrom
claude/claims-schema-foundation-tiexfk

Conversation

@jeffgreendesign

@jeffgreendesign jeffgreendesign commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Summary

Establishes a storage-only foundation for future source-backed claim packets, the next step after the merged source-span resolver (src/utils/source-span.ts).

This PR is deliberately inert: nothing reads from or writes to the new table yet. No extraction (LLM), queue, MCP tools, API routes, search fusion, or dashboard — existing search behavior is untouched and no new tools are registered.

What's included

  • Schema (4 provider variants, dimension-only diffs): scripts/setup-db-claims.sql (1536), -google.sql (3072), -ollama.sql (1024), -ollama-v2.sql (768). Mirrors the insights schema pattern: inline RLS (deny anon/authenticated), generated weighted FTS column (claim > question > quote), and reuse of the shared update_updated_at() trigger.
  • Types: Claim, ClaimStatus, ClaimState, ClaimSensitivity in src/types/database.ts.
  • Test: src/db/__tests__/claims-schema.test.ts — a pure text-contract smoke test (65 assertions) modeled on uploads-schema.test.ts, keeping the four variants in sync and asserting that no vector index is present.
  • Docs: Claims entry added to the CLAUDE.md feature schema list.

Key design decisions

  • Chunk-anchored (chunk_id NOT NULL, ON DELETE CASCADE). The offsets are UTF-16 indices into chunks.content — the only basis that round-trips per the source-span resolver. A claim cannot exist without its anchoring chunk. document_id is kept (NOT NULL, CASCADE) as a denormalized convenience.
  • Nullable embedding vector(N) with NO vector index. No embedding pipeline writes claims yet. Provider-safe vector indexes — including the pgvector >2000-dim HNSW question on the Google 3072d variant — are deferred to the future retrieval PR. The schema test enforces the absence of any hnsw/ivfflat index.
  • Light constraints only: status/state/sensitivity CHECK sets, ordered non-negative offsets, confidence in [0,1] when present, no self-supersession (superseded_by self-FK with ON DELETE SET NULL). Avoids over-constraining before real extraction exists.

Out of scope (future PRs)

LLM/claim extraction, a writer/db module, processing queue, MCP tools, API routes, search/retrieval fusion, visual retrieval, and the project-wide Google 3072d HNSW story.

Verification

pnpm verify:fast passes locally: lint, typecheck, 416 tests (65 new), security, docs, and tool-sync checks all green. Confirmed inert — no runtime src/ code references the table.

🤖 Generated with Claude Code

Establish storage-only foundation for future source-backed claim packets.
Nothing reads or writes this table yet: no extraction, queue, MCP tools,
API routes, search fusion, or dashboard — existing search is untouched.

- scripts/setup-db-claims*.sql: claims table across all four provider
  variants (1536/3072/1024/768), dimension-only diffs mirroring the
  insights schema pattern (inline RLS, generated FTS column, shared
  update_updated_at trigger).
- Claims are chunk-anchored: chunk_id is NOT NULL and offsets are UTF-16
  indices into chunks.content, the only basis that round-trips per
  src/utils/source-span.ts. embedding is a nullable vector(N) column with
  NO vector index in this PR (provider-safe indexes, incl. the Google
  3072d HNSW question, deferred to the retrieval PR).
- Light constraints only: status/state/sensitivity CHECK sets, ordered
  non-negative offsets, confidence in [0,1], no self-supersession.
- Add Claim/ClaimStatus/ClaimState/ClaimSensitivity types.
- Add claims-schema text-contract smoke test (65 assertions) that keeps
  the four variants in sync and asserts no vector index is present.
- Document the schema in CLAUDE.md feature schema list.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SscVJjuHF4BMezAxW9by5m
@vercel

vercel Bot commented Jun 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
dashboard Building Building Preview, Comment Jun 21, 2026 2:12pm
textrawl Ready Ready Preview, Comment Jun 21, 2026 2:12pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5ca2d1cf-c7ce-4c4d-899b-b53281fcc6ae

📥 Commits

Reviewing files that changed from the base of the PR and between 0b9a61d and 046763d.

📒 Files selected for processing (5)
  • scripts/setup-db-claims-google.sql
  • scripts/setup-db-claims-ollama-v2.sql
  • scripts/setup-db-claims-ollama.sql
  • scripts/setup-db-claims.sql
  • src/db/__tests__/claims-schema.test.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/db/tests/claims-schema.test.ts
  • scripts/setup-db-claims-google.sql
  • scripts/setup-db-claims-ollama.sql
  • scripts/setup-db-claims-ollama-v2.sql
  • scripts/setup-db-claims.sql

Walkthrough

Four provider-specific SQL setup scripts are added (setup-db-claims.sql, setup-db-claims-google.sql, setup-db-claims-ollama.sql, setup-db-claims-ollama-v2.sql), each creating a claims table with identical structure but differing nullable embedding vector dimensions (1536, 3072, 1024, 768). The table stores claim text with chunk-anchored provenance via (document_id, chunk_id) composite foreign keys, UTF-16 source offsets, lifecycle/review fields (status, state, confidence), classification metadata (tags, entities, sensitivity), a stored fts tsvector column, and self-referential supersession. Each script adds non-vector and GIN indexes, a BEFORE UPDATE trigger reusing the shared update_updated_at() function, and RLS deny policies for anon and authenticated roles. TypeScript types (ClaimStatus, ClaimState, ClaimSensitivity, Claim) are exported from src/types/database.ts, and a contract test suite validates all SQL variants. CLAUDE.md is updated to document the new Claims entry.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: establishing a foundational schema for source-backed claims storage without any functional read/write logic.
Description check ✅ Passed The description covers the main changes (schema variants, types, test, docs), key design decisions, scope limitations, and verification steps, providing comprehensive context for reviewers.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/claims-schema-foundation-tiexfk

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/setup-db-claims.sql`:
- Around line 103-104: The CREATE POLICY statement for claims_deny_anon will
fail on subsequent script runs because the policy already exists. Add a DROP
POLICY IF EXISTS claims_deny_anon ON claims statement immediately before the
CREATE POLICY claims_deny_anon statement to make the policy creation idempotent.
This ensures the policy is safely dropped (if it exists) before being recreated
on each run.
- Around line 35-37: The table is missing a constraint to ensure that the
chunk_id actually belongs to the document_id. Currently, document_id and
chunk_id are validated independently against their respective tables, but there
is no guarantee they form a valid document-chunk pair. Add a composite foreign
key constraint that references both the document_id and chunk_id columns
together against the chunks table to enforce this relationship, ensuring that
only chunk_id values that actually belong to the specified document_id are
allowed in the table.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9866a068-cc1e-4bfb-a754-6cdecebd4b60

📥 Commits

Reviewing files that changed from the base of the PR and between 13f803b and 0b9a61d.

📒 Files selected for processing (7)
  • CLAUDE.md
  • scripts/setup-db-claims-google.sql
  • scripts/setup-db-claims-ollama-v2.sql
  • scripts/setup-db-claims-ollama.sql
  • scripts/setup-db-claims.sql
  • src/db/__tests__/claims-schema.test.ts
  • src/types/database.ts

Comment thread scripts/setup-db-claims.sql
Comment thread scripts/setup-db-claims.sql
…/chunk FK

- Make RLS policy creation rerunnable: DROP POLICY IF EXISTS before
  CREATE POLICY claims_deny_anon, so re-applying the script no longer
  errors (the rest of the script was already idempotent).
- Enforce provenance pair integrity at the schema level: a claim's
  (document_id, chunk_id) must be a real pair, not two independently
  valid ids. Replace the standalone chunk_id FK with a composite
  FOREIGN KEY (document_id, chunk_id) REFERENCES chunks(document_id, id)
  ON DELETE CASCADE. The required unique index on chunks(document_id, id)
  is created by the claims script itself (chunks.id is already unique, so
  it always builds), keeping the base setup-db*.sql ingestion path
  untouched for deployments that don't enable claims.
- Extend the schema smoke test to assert the composite FK, its unique
  index target, and the idempotent policy across all four variants.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SscVJjuHF4BMezAxW9by5m
@jeffgreendesign jeffgreendesign merged commit 891662b into main Jun 21, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants