Skip to content

feat(pg): Positions, Arguments and citations on PostgreSQL (L-R-1 #634, PR 3) - #938

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

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

Conversation

@Fooftilly

@Fooftilly Fooftilly commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

Summary

This PR ports Positions, Arguments and Stances to the PostgreSQL domain and sync protocol. It is the third L-R-1 slice, after Concepts (#937).

It keeps SQLite's rules, error codes and messages, imported from argument_sync.py, position_sync.py and research_network.py.

Positions (backend/domain/research/positions.py)

  • Create, field revisions (position-field), read, list and delete.
  • A delete is refused while an Argument or Stance targets the Position (position_in_use).
  • A delete tombstones both field scopes.

Arguments and Stances (backend/domain/research/arguments.py)

  • Fields, kind and verdict list, detail and catalog (kind filter).
  • Ordered targets with verdicts:
    • Every target write holds the per-Library Argument target lock.
    • Self-targets and cycles are refused (recursive query), as are unknown, duplicate or foreign targets and disabled verdicts.
    • A targeted Argument refuses its delete, and so does one named in a Research Note.
  • Ordered citations with the [Roadmap] Work Identity, Editions, Versions & Deduplication #60 §8.5 identity:
    • Empty pages give a Work-level citation.
    • Pages pin the Work's only Version. A Work with several Versions refuses the citation (ARGUMENT_SOURCE_VERSION_REQUIRED), and so does an ambiguous re-match of a stored citation.
    • Exact duplicates are refused.
    • A pinned citation follows its Version move through the ON UPDATE CASCADE foreign key.
  • A delete tombstones all five owned scopes.

Work delete. commands.delete_work now removes the Work's citations and advances each citing Argument's argument-sources (arguments.release_work). It takes the Work FOR UPDATE, then the citing Arguments in id order. Order gaps are kept, as with SQLite's cascade.

Concurrency

  • The lock order is documented in backend/domain/research/__init__.py:
    1. Cited Works FOR KEY SHARE.
    2. The hierarchy lock or the target lock.
    3. The row.
    4. The Concept key lock.
    5. Named rows FOR KEY SHARE.
    6. Scopes, sorted.
  • Research Note writers (works/notes.py, a Work create with a note) share the Concepts and Arguments their markup names, so a concurrent delete cannot slip past the in-use check.
  • CREATE_ARGUMENT and SET_ARGUMENT_SOURCES join PEER_WRITERS of the Work merge and run SERIALIZABLE, both in sync and in the facade.
  • The sync protocol runs lifecycle.guard on their cited Works, so a citation of a merged Work is refused with WORK_MERGED.

Sync and facade

  • backend/sync/handlers/position.py registers 3 families and argument.py registers 5. A foreign id is refused with FORBIDDEN and is not ledgered.
  • backend/pg_facade/research.py gains 15 @ported methods, and PRKSDatabase gains thin delegators so the facade can port them.

Related issues

Refs #634

Scope / non-goals

  • This PR is backend PostgreSQL only. HTTP routes still call research_network, so there is no API cutover.
  • Not included:
    • Research Note indexing (research.reindex_work) and graph projection, planned for later L-R-1 PRs.
    • The Version-aware citation API (§13.3).
    • Re-pointing citations in the Work merge command (L-W-2).
  • The scope was not split further because Positions, Arguments, targets and citations share one target lock and one delete rule set.

Validation

All checks below were run locally:

Check Result
Full tests/pg (scripts/test-postgres) 1194 tests OK
Parity leg (scripts/test-postgres --parity), including the new tests/test_arguments_parity.py 316 tests OK, every ported method reached
New tests/pg/test_arguments.py 24 tests OK
New tests/pg/test_arguments_sync.py 13 tests OK
SQLite pytest: test_argument_sync, test_position_sync, test_research_network, test_engineering_invariants, test_api_contract_positions, concept and argument parity 296 passed
Ruff on changed files clean
Pyright, typed slice (new modules added) and default config 0 errors
scripts/check_invariants.py OK
  • The PG tests cover races between a Work delete and a citation write (in both orders), between a target write and a delete, and between a note write and an Argument delete. They also cover rollback on a refused create and Library isolation.
  • E2E was not run locally because no frontend or route changes.

Migration / compatibility impact

There is no schema change: this uses 130_research.sql from #936. The documented PG/SQLite differences in backend/pg_facade/research.py are:

  • Deletes tombstone every owned scope.
  • A Work delete advances argument-sources.
  • Citations on a Work with several Versions need a Version (Version required).

Risks / follow-up

Remaining L-R-1 work:

  • Note markup indexing and the research.reindex_work job.
  • Graph projection and read endpoints.
  • The server.py route switch.
  • The Version-aware citation API.

Checklist

  • Relevant tests/checks were run and are listed above.
  • Documentation/generated files were updated when required (AGENTS.md, typed slice, invariants).
  • UI evidence is included when applicable (n/a).
  • No unrelated changes are intentionally included.

Generated by Claude Code


Devin Review


Play the walkthrough    Follow each request

Summary by CodeRabbit

  • New Features
    • PostgreSQL now supports managing Positions and Arguments, including their details, citations, targets, and verdicts.
    • Argument citations can be pinned to specific Work versions, and Arguments can reference Positions or other Arguments as targets.
    • Research notes can reference Arguments as well as Concepts.
  • Bug Fixes
    • Deleting a Work now removes its citations from Arguments and updates their source lists.
    • Positions and Arguments cannot be deleted while protected by existing references.

Port Positions, Arguments and Stances to the PostgreSQL domain with
SQLite's rules, codes and messages: field revisions, ordered targets with
verdicts (self-targets and cycles refused under the per-Library target
lock, a targeted record refuses its delete), ordered citations with the
#60 section 8.5 Work/Version pin rules, and deletes that tombstone every
owned scope. A Work delete removes its citations and advances each citing
Argument's argument-sources. Research Note writers share the Concepts and
Arguments their markup names. CREATE_ARGUMENT and SET_ARGUMENT_SOURCES
join the Work merge's peer writers and run SERIALIZABLE; the sync
protocol guards their cited Works against a merge.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017jgbjrTtg1i9iUrndjRxvp
PG integration (CRUD, lists, pins, isolation, races including Work
delete vs citation), sync decision tables and ledgering, and SQLite/PG
parity for the facade and the sync families. Pinned isolation and
not-ported lists follow the new families.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017jgbjrTtg1i9iUrndjRxvp
…nd Arguments

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017jgbjrTtg1i9iUrndjRxvp
@coldtea-pr-lens

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

Copy link
Copy Markdown
  • Redraw · drawn at 5bbf1a7, the branch has moved on

Architecture

Architecture diagram for Fooftilly/PRKS at 5bbf1a7

Play the walkthrough

Inside the changed components — 2 views

Component view — Research domain and persistence

Internal modules and persistence for positions, arguments, targets, and citations.

Architecture view of Component view — Research domain and persistence in Fooftilly/PRKS

Component view — Semantic sync integration

Sync ledger integration and handlers for positions and arguments.

Architecture view of Component view — Semantic sync integration in Fooftilly/PRKS

Data flow

Data flow diagram for Fooftilly/PRKS at 5bbf1a7

Follow each request

The other flows — 1 sequence

Releasing citations on work deletion

Sequence diagram of Releasing citations on work deletion in Fooftilly/PRKS

Review

✨ Nothing flagged · reviewed 5bbf1a7


Tip

Open a diagram on the canvas, then press W or click play to walk through the change one step at a time

🪧 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
  • 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
  • After a push, tick Redraw to draw the latest commit
  • 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

@sourcery-ai

This comment has been minimized.

@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between d0208d0 and 4327e47.

Files selected for processing: 20
  • AGENTS.md
  • backend/db_manager.py
  • backend/domain/research/__init__.py
  • backend/domain/research/arguments.py
  • backend/domain/research/positions.py
  • backend/domain/works/commands.py
  • backend/domain/works/merge.py
  • backend/domain/works/notes.py
  • backend/pg_facade/research.py
  • backend/sync/handlers/argument.py
  • backend/sync/handlers/position.py
  • backend/sync/protocol.py
  • pyrightconfig.typed-slice.json
  • scripts/check_invariants.py
  • tests/pg/test_arguments.py
  • tests/pg/test_arguments_sync.py
  • tests/pg/test_people_sync.py
  • tests/pg/test_works_sync.py
  • tests/test_arguments_parity.py
  • tests/test_engineering_invariants.py

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

Adds PostgreSQL-backed Position and Argument operations, sync handlers, and citation and target rules. Work deletion now removes citations and advances source-list revisions for affected Arguments. Tests cover PostgreSQL behavior, sync operations, concurrency, and SQLite parity.

Changes: PostgreSQL Research

Layer / File(s) Summary
Position operations and synchronization
backend/domain/research/positions.py, backend/sync/handlers/position.py, backend/db_manager.py, tests/pg/test_arguments.py, tests/pg/test_arguments_sync.py
Adds Position create, read, update, delete, and sync operations. Deletion refuses Positions referenced by Arguments or Stances and advances both field scopes before removal.
Argument rules, targets, and operations
backend/domain/research/arguments.py, backend/domain/research/__init__.py, tests/pg/test_arguments.py
Adds Argument persistence, target validation and cycle checks, revision-aware updates, and deletion constraints for note and target references.
Citation references and Work lifecycle
backend/domain/research/arguments.py, backend/domain/works/*, backend/sync/protocol.py, backend/sync/handlers/argument.py, tests/pg/test_arguments.py, tests/pg/test_arguments_sync.py
Adds Version-pinned citation handling and Work-delete cleanup. Work deletion removes citations and advances source-list revisions. Research Note writes share references to Concepts and Arguments.
Facade, sync registration, and parity validation
backend/db_manager.py, backend/pg_facade/research.py, backend/sync/handlers/{argument,position}.py, backend/sync/protocol.py, tests/pg/*sync.py, tests/test_arguments_parity.py, pyrightconfig.typed-slice.json, scripts/check_invariants.py, tests/test_engineering_invariants.py
Exposes the new operations through the facades and sync registry. Argument creation and source updates use SERIALIZABLE isolation. Adds sync, parity, and typed-slice coverage.

Priority: Normal

Estimated code review effort: 4 (Complex) | ~60 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ResearchMixin
  participant ResearchDomain
  participant PostgreSQL
  Client->>ResearchMixin: Submit Position or Argument command
  ResearchMixin->>ResearchDomain: Delegate operation
  ResearchDomain->>PostgreSQL: Validate references and apply changes
  PostgreSQL-->>ResearchDomain: Return records and revisions
  ResearchDomain-->>ResearchMixin: Return operation result
  ResearchMixin-->>Client: Return result
Loading

Possibly related issues

  • Fooftilly/PRKS issue 788: This PR adds PostgreSQL Argument-to-Work citations, which the issue identifies as a prerequisite for showing incoming Argument links on Works. It does not add the Work UI or graph projection.
  • Fooftilly/PRKS issue 614: This PR implements the PostgreSQL Research slice listed as outstanding in the implementation checklist.

Possibly related PRs

  • Fooftilly/PRKS#937: Adds the PostgreSQL Concepts slice that this PR extends, using the same research package, facade, sync registry, and reference-sharing model.
  • Fooftilly/PRKS#820: Defines Work lifecycle guards and merge peer-writer requirements used by this PR’s cited-Work checks and peer-writer additions.

Suggested reviewers: claude

Merge Risk: Minimal · up to 4327e

This change adds PostgreSQL Position and Argument operations, sync handlers, and citation cleanup on Work deletion. No actionable merge-blocking issue was found. The PR reports passing PostgreSQL, parity and SQLite tests, plus clean lint and type checks.

Pre-merge checks: Passed 6 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 29.41% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 187 functions across 18 files. (2 skipped… Write docstrings for the functions missing them to satisfy the coverage threshold.
Offline And Sync Coherence Warning The PostgreSQL sync path introduces a terminal response that the offline client cannot consume. The PR adds WORK_MERGED checks for CREATE_ARGUMENT and SET_ARGUMENT_SOURCES in `backend/sync/proto… Teach the Argument create and source sync handlers to accept and terminally record WORK_MERGED, preserve and display target_work_id, and add the code to sync diagnostics. Add browser/client regression tests for both operations that veri…
Passed Passed checks: 6 passed
Check name Status Explanation
Title check Passed The title clearly and concisely identifies the PostgreSQL implementation of Positions, Arguments, and citations.
Description check Passed The description is complete and follows the repository template. It covers the change, issue reference, scope, validation results, compatibility impact, risks, and checklist.
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 No explicit invariant violation found. The PostgreSQL slice remains outside the running HTTP backend, as required by README.md. The new research code scopes library data with library_id; the only unsc…
Ui Design Contract Passed The pull request changes only backend, synchronization, configuration, documentation, and test files. The authoritative diff contains no frontend or user-visible UI files, so the DESIGN.md interaction…
Full details: Prks Engineering Invariants

Explanation

No explicit invariant violation found. The PostgreSQL slice remains outside the running HTTP backend, as required by README.md. The new research code scopes library data with library_id; the only unscoped verdict query uses the schema’s explicitly global seed table. Argument deletion checks canonical work_notes markup, not the derived index or graph, and the changed paths add no sensitive logging. Work deletion and citation cleanup also match the updated AGENTS.md research contract.

Full details: Ui Design Contract

Explanation

The pull request changes only backend, synchronization, configuration, documentation, and test files. The authoritative diff contains no frontend or user-visible UI files, so the DESIGN.md interaction contract does not apply.

Full details: Docstring Coverage

Explanation

Docstring coverage is 29.41% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 187 functions across 18 files. (2 skipped: 2 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Full details: Offline And Sync Coherence

Explanation

The PostgreSQL sync path introduces a terminal response that the offline client cannot consume. The PR adds WORK_MERGED checks for CREATE_ARGUMENT and SET_ARGUMENT_SOURCES in backend/sync/protocol.py and backend/sync/handlers/argument.py; the new PG tests confirm a 409 WORK_MERGED response. However, frontend/js/argument-state.js accepts only WORK_NOT_FOUND/ENTITY_NOT_FOUND for source operations and omits WORK_MERGED for creates. sync-runtime.js therefore treats the valid 409 as invalid_response, resets the operation to pending, and retries it. This conflicts with the local-first design, which requires merged-Work operations to settle as terminal outcomes. The new tests cover the server response but not client recovery.

Resolution

Teach the Argument create and source sync handlers to accept and terminally record WORK_MERGED, preserve and display target_work_id, and add the code to sync diagnostics. Add browser/client regression tests for both operations that verify no retry loop, conflict/diagnostic visibility, and correct dependent-operation handling. Keep the PostgreSQL tests for the 409 ledger response.

Finishing Touches: 💡 2
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks: 💡
  • 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.

@chatgpt-codex-connector

This comment has been minimized.

@Fooftilly Fooftilly moved this to Review in PRKS Roadmap Oct 26, 2026
devin-ai-integration[bot]

This comment was marked as resolved.

Filter citation authors to Work-scoped roles and the primary Version's,
as roles.credits_by_work does, so another Version's Author never shows.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017jgbjrTtg1i9iUrndjRxvp

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Fooftilly
Fooftilly merged commit 58b48a4 into master Oct 26, 2026
36 of 38 checks passed
@Fooftilly
Fooftilly deleted the claude/project-thread-o9yqq7 branch October 26, 2026 17:35
@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
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