feat(graph): add relation taxonomy guardrails#79
Conversation
There was a problem hiding this comment.
Code Review
This pull request refines the relationship taxonomy by splitting the overloaded OWNED_BY predicate into ASSIGNED_TO and OWNS, separating real-world occurrence dates (OCCURRED_ON) from bookkeeping dates (RECORDED_ON), and introducing Organization as a first-class node type. It also adds relationship predicate shape guardrails to filter out invalid relationship shapes during extraction. The feedback recommends optimizing database query performance by joining object nodes and metadata directly in the predicate shape audit to avoid large inArray clauses, splitting an OR condition in a migration subquery into separate NOT EXISTS clauses to allow efficient index usage, and importing aliasedTable in the cleanup graph job.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Summary
Graph extraction and cleanup now have hard relation-shape guardrails instead of relying on the model to infer valid edge direction and endpoint types. Invalid relationships are rejected during extraction, prioritized during iterative cleanup, and auditable through a dedicated predicate-health report.
This also makes organizations first-class graph nodes, replaces passive
OWNED_BYwith canonicalOWNS/ASSIGNED_TO, and moves bookkeeping date facts from overloadedOCCURRED_ONedges toRECORDED_ON.Design Decisions
OWNED_BY; ownership isowner OWNS owned, task responsibility isTask ASSIGNED_TO Person.OCCURRED_ONfor real-world occurrence dates and useRECORDED_ONfor observed/ingested/bookkeeping dates.Organizationfor companies, institutions, named teams, communities, clubs, and informal named groups.Real-Data Dry Run
Ran the migrations in a rollback-only transaction against the imported graph:
OWNED_BYpredicatesOWNED_BYclaimsOWNSclaimsRECORDED_ONclaimsOrganizationnodesThe remaining invalid-shape buckets are now regular cleanup targets rather than taxonomy-migration fallout.
Test Plan
pnpm exec vitest run src/db/migrations-claims.test.ts --pool=threads --poolOptions.threads.singleThread=truepnpm exec vitest run src/evals/memory/run-all.test.ts --pool=threads --poolOptions.threads.singleThread=truepnpm exec vitest run src/types/graph.test.ts src/lib/claims/predicate-shapes.test.ts src/lib/claims/predicate-shape-repair.test.ts src/lib/structured-output-schemas.test.ts src/lib/context/assemble-bootstrap-context.test.ts --pool=threads --poolOptions.threads.singleThread=truepnpm run build:checkgit diff --check