Repository navigation
feat: add ownership schema foundation - #76
Merged
Merged
Conversation
Phase 1B of the Code Ownership Over Time contract (docs/ownership-data-privacy-spec.md): additive migration 012 creates the four ownership tables with database-enforced tenant/repository pairing, row-shape checks, closed error taxonomy, RLS with zero browser-facing policies, service-role-only grants, and dormant SECURITY INVOKER dash_ownership_* RPCs gated on active_version. No ingestion exists in this tranche — the tables hold zero production rows. Backup scope classifies ownership history as CORE and sync state as OPERATIONAL; the recovery drill seeds synthetic fixtures and proves tenant-FK rejection, cascades, the version serve-gate (build/promote/coexist/flip), and RPC output safety against real Postgres 17. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- month boundary check now evaluates on the UTC wall clock (AT TIME ZONE 'UTC' both ways) instead of following session TimeZone; drill proves Dubai-local midnight is rejected while the true UTC boundary is accepted - linked contributors can no longer squat the reserved synthetic keys 'unlinked'/'other' (ownership_contributors_linked) - mustFail now asserts the intended constraint name + SQLSTATE so malformed inserts cannot masquerade as passing invariant proofs - composite-FK proofs are isolated: scope-FK test uses a scope-total row on a fresh period; contributor-FK test uses a valid repo-B scope - user-delete cascade proven on a dedicated tenant whose repo and all four ownership tables hold live rows when the user row is deleted Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
9 of 10 tasks
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 1B of the Code Ownership Over Time tranche (contract:
docs/ownership-data-privacy-spec.md, RFC:docs/code-ownership-over-time-rfc.md, spike:docs/ownership-graphql-spike-results.md). Adds the production database foundation only:migrations/012_ownership.sql— four tables (ownership_scopes,ownership_contributors,ownership_snapshots,ownership_sync_state) with tenant-qualified composite FKs, row-shape CHECKs, closed phase/error taxonomies, calculation-version coexistence, RLS (zero browser-facing policies), and service-role-only grants.dash_ownership_*SECURITY INVOKER RPCs (scopes summary / head contributors / monthly timeline),p_user-scoped, serving onlyactive_versionrows — never internal ids,github_node_id,contributor_key, SHAs, or cursors.ownership_sync_stateis OPERATIONAL.scripts/recovery-drill.mjsnow seeds synthetic ownership fixtures and proves tenant-FK rejection, both cascade paths, row-shape/identity/period/version checks, and the full build → promote → coexist → flip serve-gate on real Postgres 17.test/ownership-schema.test.mjsstructural guards + backup-split assertions intest/data-minimization.test.mjs.Scope
Ownership ingestion remains disabled. No GitHub ownership API calls, no blame/history processing, no backfill, no sync/cron/webhook/worker wiring, no UI, no feature flag, no
api/dashboard.mjschanges, nolib/sync.mjschanges, noSecurityPrivacyPage.tsxchanges (the public trust record only changes when ownership actually collects). Production will hold empty ownership tables.Security / privacy impact
New empty tables with the contract's strictest posture: tenant pairing enforced by composite FKs (
(repository_id, user_id) → repositories(id, user_id), surrogate unique added — the only existing-table change); RLS enabled with zero policies;public/anon/authenticatedfully revoked; onlyservice_roleholds table and RPC privileges. Linked identity isgithub_node_id+display_login— no databaseId, email, avatar, or author-name columns can exist (CHECKs + test guards).unlinked/aggregatesynthetic rows are shape-pinned and can never carry identity.erroris a CHECK-constrained closed taxonomy — no provider text.Database / deployment impact
Migration 012 is additive and idempotent (no drops, no rewrites; only new unique index
repositories(id, user_id)on an existing table). Per the recovery runbook, a freshnpm run db:backupis mandatory before applying it to production. This PR validates it only via local/CI disposable Postgres.Verification
npm run buildnpm run typechecknpm test— 527 tests, 0 failures (new ownership suite + updated backup/data-minimization guards)npm audit --audit-level=moderate— 0 vulnerabilitiesnpm run db:drill— PASS on local Postgres 17: backup→migrate→restore round-trip, RLS/grants/SECURITY INVOKER checks, plus ~30 real-Postgres ownership proofs (tenant mismatch rejection, cascades, version serve-gate)Contributor agreement
Generated with Devin