Repository navigation
feat(pg): Concepts on PostgreSQL (L-R-1 #634, PR 2) - #937
Conversation
Port Concepts to PostgreSQL: creation, the definition field, the name and alias set as one identity decision, the parent hierarchy, delete, and the revision state, with SQLite's rules, codes and messages imported from concept_sync.py and research_network.py. - Names and aliases resolve through the concept_keys index (identity key), never a Python scan. A create inserts its name key ON CONFLICT DO NOTHING; a rename or alias write that loses a race fails on concept_keys_pkey and reruns once, refusing with CONCEPT_EXISTS or ALIAS_CONFLICT. - Parent changes and deletes hold a per-Library Concept hierarchy lock; acyclicity is one recursive ancestor query; both ends of an edge advance concept-parents. - A delete is refused while a Research Note names the Concept by name or alias (CONCEPT_IN_USE), removes its edges, advances its neighbours and tombstones every scope it owned. - The five Concept sync families are registered on the PostgreSQL ledger. - PRKSDatabase gains thin Concept methods delegating to research_network, which ResearchMixin ports. Tests: tests/pg/test_concepts.py, tests/pg/test_concepts_sync.py and tests/test_concepts_parity.py. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017jgbjrTtg1i9iUrndjRxvp
This comment has been minimized.
This comment has been minimized.
Architecture Inside the changed components — 1 viewComponent view — Research concepts implementation Internal domain logic and PostgreSQL persistence for concepts, hierarchy acyclicity, and aliases. Data flow Review 1 finding on the diff · reviewed
|
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
| Layer / File(s) | Summary |
|---|---|
Concept rules and domain operations backend/domain/research/*, tests/pg/test_concepts.py, AGENTS.md, pyrightconfig.typed-slice.json, scripts/check_invariants.py |
Adds PostgreSQL Concept reads and mutations, identity-key conflict handling, hierarchy locking and revision updates, and deletion rules. Tests cover validation, Library isolation, permissions, and concurrent changes. AGENTS.md documents the implementation and records Work citation and merge constraints. |
Database facade and parity backend/db_manager.py, backend/pg_facade/research.py, tests/test_concepts_parity.py |
Adds Concept operations to both database facades. Parity tests compare facade results and errors across PostgreSQL and SQLite. |
Sync operations and parity backend/sync/handlers/concept.py, backend/sync/protocol.py, tests/pg/test_concepts_sync.py, tests/pg/test_works_sync.py, tests/test_concepts_parity.py, pyrightconfig.typed-slice.json, scripts/check_invariants.py, tests/test_engineering_invariants.py |
Registers Concept creation, field, identity, parent, and deletion operations in the PostgreSQL sync protocol. Tests cover sync results, conflicts, replay, concurrency, access control, and backend parity. |
Priority:
Estimated code review effort: 4 (Complex) | ~60 minutes
Change: Feature
Sequence Diagram(s)
sequenceDiagram
participant SyncClient
participant SyncProtocol
participant ConceptHandler
participant ResearchConcepts
participant PostgreSQL
SyncClient->>SyncProtocol: Submit Concept operation
SyncProtocol->>ConceptHandler: Dispatch registered operation
ConceptHandler->>ResearchConcepts: Apply operation
ResearchConcepts->>PostgreSQL: Read or update Concept data
PostgreSQL-->>ResearchConcepts: Return operation result
ResearchConcepts-->>ConceptHandler: Return acknowledgement or refusal
ConceptHandler-->>SyncClient: Return sync response
Possibly related issues
- PRKS v0.8 — Backend foundation release tracker #614: This adds PostgreSQL Concept operations to the tracked Research lane, but does not complete the broader lane.
Suggested reviewers: claude
Merge Risk: 
Low · up to 2f857
-
Concept operations are not yet routed through server routes, and the remaining issues are narrow concurrency races. Concurrent Concept deletion and Research Note edits can leave a note referencing a deleted Concept, and simultaneous identity edits can fail with a retryable 503 instead of a clean conflict result. Both are low-probability and fixable before or shortly after merge.
Pre-merge checks: 
7 · 
1
-
Failed checks: 1 warning Passed checks: 7 passed-
Full details: Title check
-
Explanation
The title "feat(pg): Concepts on PostgreSQL (L-R-1
#634, PR 2)" matches the main change: porting Concept operations, sync handlers, and facade methods to PostgreSQL. It is specific and follows conventional commit style. It omits details such as the sync families and the hierarchy lock, which is acceptable for a title.
Full details: Description check
-
Explanation
The description follows the template. It has a Summary with the change list and deliberate differences from SQLite. It names the related roadmap item (
#634, PR 2) with a 'Refs'-style reference, though it does not use the exact 'Closes' or 'Refs' keyword line. Scope is stated: Positions and Arguments are deferred, and server route switching is a follow-up. Validation lists concrete commands and results, and it states that E2E was not run. Risks/follow-up is not present as its own section, and the Related issues section uses prose, not the template format. The Migration/compatibility section is absent, though the description notes that server.py is unchanged. The checklist is not ticked. These gaps are minor, so the check passes.
Full details: Prks Engineering Invariants
-
Explanation
PASS — no explicit repository-rule violation is introduced. The PostgreSQL Concept code uses the indexed
prks.concept_keysnamespace, scopedlibrary_idpredicates, the documented hierarchy lock order, and READ COMMITTED commands. Concept deletion checks canonicalprks.work_noteswithparse_research_markup, not derived mention tables, as required by the PostgreSQL research guidance. The change adds no schema, storage, logging, authentication, or security-boundary behavior, and README.md and SECURITY.md are unchanged.
Full details: Ui Design Contract
-
Explanation
PASS: The pull request changes only backend PostgreSQL/research code, sync handlers, configuration, documentation, and tests. The authoritative diff contains no frontend, UI, template, static, or design-file changes, so the UI design contract does not apply.
Full details: Offline And Sync Coherence
-
Explanation
Concepts are marked durable in
docs/local-first-rollout-status.mdand defined as a local-first family indocs/local-first-sync.mdand the offline entity rules. The PR adds the PostgreSQL handlers to the shared ledger protocol without changing client queue or recovery behavior.tests/pg/test_concepts_sync.pycovers replay, concurrent sends, key-race retries, stale revisions, delete/recreate safety, malformed/NUL input, isolation, and access control.tests/test_concepts_parity.pychecks PostgreSQL results against SQLite. Existing offline E2E coverage remains applicable, and no frontend or recovery code changed.
-
Full details: Docstring Coverage
-
Explanation
Docstring coverage is 25.40% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 126 functions across 12 files. (2 skipped: 2 unsupported.)
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches: 💡 1
-
📝 Generate docstrings: 💡
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands.
This comment has been minimized.
This comment has been minimized.
- Every Research Note writer (a note edit, a Work created with a note) holds the Concepts its markup names FOR KEY SHARE until COMMIT, so a Concept delete overlapping the write waits for it and then refuses with CONCEPT_IN_USE instead of missing the new reference. - A Concept create inserts the row before it checks the name, so an id of another Library is refused unledgered even when this Library holds the name, instead of a ledgered CONCEPT_EXISTS. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017jgbjrTtg1i9iUrndjRxvp
A rename with an alias set writes several concept_keys rows; two such writers taking each other's keys in opposite orders could deadlock on the key index. Identity writes now take the Library's Concept key lock before reading key owners, so the second writer waits and refuses from what it reads. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017jgbjrTtg1i9iUrndjRxvp
Requested by Nikola · project thread
L-R-1 (#634) PR 2 of the Research lane. It ports Concepts to PostgreSQL on top of the schema merged in #936. Positions and Arguments come in the next slice.
What it does
backend/domain/research/concepts.pycovers creation, the definition field, identity (the rename and the alias set, decided together), the parent hierarchy, delete, the catalog and detail reads, and the sync state. The rules, codes and messages are imported fromconcept_sync.pyandresearch_network.py.concept_keysindex by identity key. No Python scan over every Concept.ON CONFLICT DO NOTHING, so two concurrent creates of one name make one Concept.concept_keys_pkeyand reruns once. The handler usesretry_constraints; the facade uses its own rerun. The rerun refuses withCONCEPT_EXISTSorALIAS_CONFLICT.concept-parents.CONCEPT_IN_USE) while a Research Note names the Concept by name or alias. That check readswork_notes, never the derived mentions.concept-parentson each neighbour.FOR KEY SHAREby id, then revision scopes in sorted order.backend/sync/handlers/concept.pyadds the five families (CREATE_CONCEPT,SET_CONCEPT_FIELD,SET_CONCEPT_IDENTITY,SET_CONCEPT_PARENTS,DELETE_CONCEPT), registered inbackend/sync/protocol.py. An id from another Library is refused unledgered.backend/pg_facade/research.pyports eight methods:list_concepts,get_concept,create_concept,update_concept,replace_concept_aliases,replace_concept_parents,delete_conceptandget_concept_sync_state.PRKSDatabasegains thin delegating methods for the first seven so they can be ported.server.pyis unchanged; switching the routes todb.*is a follow-up.prks.identity_key, soambiguous_conceptcannot occur.LOWER()orderings get a deterministic tiebreak.test_works_sync's "not ported" probe now usesDELETE_POSITION.Tests (local)
tests/pg/test_concepts.pyandtests/pg/test_concepts_sync.py: 35 tests covering identity keys, the shared namespace, renames, revisions, cycles, deletes, isolation, readers and NUL. They also cover races: two creates or renames of one key, alias vs create, a cycle closed by two concurrent parent changes, delete vs parent change and delete vs rename, the ledgered rerun, and recreated ids.tests/test_concepts_parity.py: facade and sync parity.scripts/test-postgresfulltests/pg: 1153 OK.scripts/test-postgres --parity: OK, with 0 unported skips and 0 ported methods lacking a passing PostgreSQL test.concept_sync,research_network, and agent guidance.scripts/check_invariants.pyOK.Generated by Claude Code
Summary by CodeRabbit