Skip to content

feat(pg): Concepts on PostgreSQL (L-R-1 #634, PR 2) - #937

Merged
Fooftilly merged 3 commits into
masterfrom
claude/project-thread-o9yqq7
Oct 26, 2026
Merged

Fooftilly merged 3 commits into
masterfrom
claude/project-thread-o9yqq7

Conversation

@Fooftilly

@Fooftilly Fooftilly commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

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.py covers 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 from concept_sync.py and research_network.py.
    • Key resolution: names and aliases resolve through the concept_keys index by identity key. No Python scan over every Concept.
      • A create inserts its name key with ON CONFLICT DO NOTHING, so two concurrent creates of one name make one Concept.
      • A rename or alias write that loses a key race fails on concept_keys_pkey and reruns once. The handler uses retry_constraints; the facade uses its own rerun. The rerun refuses with CONCEPT_EXISTS or ALIAS_CONFLICT.
    • Hierarchy: parent changes and deletes take a per-Library Concept hierarchy lock. Acyclicity is checked with one recursive ancestor query. Both ends of an edge advance concept-parents.
    • Delete:
      • It is refused (CONCEPT_IN_USE) while a Research Note names the Concept by name or alias. That check reads work_notes, never the derived mentions.
      • Otherwise it removes the Concept's edges and advances concept-parents on each neighbour.
      • It tombstones every scope the Concept owned, including scopes never edited.
    • Lock order: hierarchy lock, then the Concept row, then named Concepts FOR KEY SHARE by id, then revision scopes in sorted order.
    • Isolation: every command runs READ COMMITTED (§7.1).
  • backend/sync/handlers/concept.py adds the five families (CREATE_CONCEPT, SET_CONCEPT_FIELD, SET_CONCEPT_IDENTITY, SET_CONCEPT_PARENTS, DELETE_CONCEPT), registered in backend/sync/protocol.py. An id from another Library is refused unledgered.
  • backend/pg_facade/research.py ports eight methods: list_concepts, get_concept, create_concept, update_concept, replace_concept_aliases, replace_concept_parents, delete_concept and get_concept_sync_state. PRKSDatabase gains thin delegating methods for the first seven so they can be ported. server.py is unchanged; switching the routes to db.* is a follow-up.
  • Deliberate differences from SQLite, documented in the facade docstring:
    • Keys compare by prks.identity_key, so ambiguous_concept cannot occur.
    • A delete tombstones all of the Concept's own scopes.
    • Equal LOWER() orderings get a deterministic tiebreak.
    • An id containing NUL is not found.
  • Other changes:
    • test_works_sync's "not ported" probe now uses DELETE_POSITION.
    • The new modules are added to the Pyright typed slice: the config, the invariant script and the pinned test copy.
    • The AGENTS.md lane line is updated.

Tests (local)

  • tests/pg/test_concepts.py and tests/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-postgres full tests/pg: 1153 OK.
  • scripts/test-postgres --parity: OK, with 0 unported skips and 0 ported methods lacking a passing PostgreSQL test.
  • Targeted SQLite suites passed: registry, parity fixture, invariants, concept_sync, research_network, and agent guidance.
  • Ruff clean; pyright clean on the typed slice and the default config; scripts/check_invariants.py OK.
  • The E2E suite was not run locally; CI is the gate.

Generated by Claude Code


Devin Review


Play the walkthrough    Follow each request

Summary by CodeRabbit

  • New Features
    • PostgreSQL now supports managing Research Concepts: create, view, update names and descriptions, manage aliases and parent relationships, and delete.
    • Concept changes can sync across clients, with validation, conflict handling, and safeguards against cycles and deletion of referenced Concepts.

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
@sourcery-ai

This comment has been minimized.

@coldtea-pr-lens

coldtea-pr-lens Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
  • Redraw · drawn at 2f85709, the branch has moved on

Architecture

Architecture diagram for Fooftilly/PRKS at 2f85709

Play the walkthrough

Inside the changed components — 1 view

Component view — Research concepts implementation

Internal domain logic and PostgreSQL persistence for concepts, hierarchy acyclicity, and aliases.

Architecture view of Component view — Research concepts implementation in Fooftilly/PRKS

Data flow

Data flow diagram for Fooftilly/PRKS at 2f85709

Follow each request


Review

1 finding on the diff · reviewed 2f85709

Tip

After a push, tick Redraw to draw the latest commit

🪧 More tips
  • Run npx skills add coldteadotai/pr-lens, then tell your coding agent: "Diagram the change you just made with PR Lens and attach it to the pull request."
  • Run npx @coldtea/pr-lens-cli analyze --base origin/main on a branch, then npx @coldtea/pr-lens-cli render .pr-lens/graph.json. Same lenses, your own model key, before the pull request exists
  • Click the link under each diagram to open it on a canvas you can zoom, pan and step through
  • The diagrams are links. Click one to open it on the canvas, then press W or click play to walk through the change
  • Open a diagram on the canvas, then press W or click play to walk through the change one step at a time
  • The CLI's render reads .github/pr-lens.yml and applies your renames, exclusions and lane pins at draw time
  • Set github.comment.collapsed: true in .github/pr-lens.yml to fold the comment behind one View architecture and data flow row. Drawing still runs as before
  • Set github.draw: on-demand in .github/pr-lens.yml and PR Lens stops drawing pull requests on its own. Comment @pr-lens draw on a pull request when you want that one drawn
  • Add .github/workflows/pr-lens.yml with coldteadotai/pr-lens/packages/action@v0 and your model provider's key as its api-key to run PR Lens from your own CI. Any /chat/completions endpoint works
  • Switch GitHub to dark mode and the diagrams follow. The moving dots are this pull request's data in motion
  • Set github.description: false in .github/pr-lens.yml to stop PR Lens adding buttons to your PR descriptions

Thanks for using PR Lens! It's free for OSS. If it helped, a star helps other teams find it.  Star PR Lens on GitHub

@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
Walkthrough

This change adds PostgreSQL Concept operations for identity, hierarchy, revisions, and deletion. It exposes those operations through the database facade and sync protocol. New tests cover PostgreSQL behavior, concurrent operations, and parity with SQLite.

Changes: PostgreSQL Concept Operations

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: Pending latest changes

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
Loading

Possibly related issues

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: Passed 7 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning 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… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 7 passed
Check name Status Explanation
Title check Passed 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 convent…
Description check Passed 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…
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.
Prks Engineering Invariants Passed PASS — no explicit repository-rule violation is introduced. The PostgreSQL Concept code uses the indexed prks.concept_keys namespace, scoped library_id predicates, the documented hierarchy lock or…
Ui Design Contract Passed 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 desi…
Offline And Sync Coherence Passed Concepts are marked durable in docs/local-first-rollout-status.md and defined as a local-first family in docs/local-first-sync.md and the offline entity rules. The PR adds the PostgreSQL handlers …
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_keys namespace, scoped library_id predicates, the documented hierarchy lock order, and READ COMMITTED commands. Concept deletion checks canonical prks.work_notes with parse_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.md and defined as a local-first family in docs/local-first-sync.md and 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.py covers replay, concurrent sends, key-race retries, stale revisions, delete/recreate safety, malformed/NUL input, isolation, and access control. tests/test_concepts_parity.py checks 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.

❤️ Share

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

@Fooftilly Fooftilly moved this to Review in PRKS Roadmap Oct 26, 2026
@chatgpt-codex-connector

This comment has been minimized.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

coldtea-pr-lens[bot]

This comment was marked as resolved.

- 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
coderabbitai[bot]

This comment was marked as resolved.

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
@Fooftilly
Fooftilly merged commit d0208d0 into master Oct 26, 2026
57 of 58 checks passed
@Fooftilly
Fooftilly deleted the claude/project-thread-o9yqq7 branch October 26, 2026 09:26
@github-project-automation github-project-automation Bot moved this from Review to Done in PRKS Roadmap Oct 26, 2026
@Fooftilly Fooftilly mentioned this pull request Oct 28, 2026
6 of 9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants