Skip to content

feat(OMN-13321): vendor node_pr_lifecycle_state_reducer ledger migration into infra forward-migration tree - #2112

Merged
jonahgabriel merged 2 commits into
devfrom
jonah/omn-13321-vendor-pr-lifecycle-ledger-migration
Jun 26, 2026
Merged

jonahgabriel merged 2 commits into
devfrom
jonah/omn-13321-vendor-pr-lifecycle-ledger-migration

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Jun 26, 2026 •

Copy link
Copy Markdown
Collaborator

OMN-13321 (REOPEN) — vendor the missing node migration that the batched redeploy surfaced

This reopens / completes OMN-13321. The omnimarket node code merged in omnimarket #1440, but its projection table could not persist on dev: node_pr_lifecycle_state_reducer declares projection_api over pr_lifecycle_ledger_entries, but the node-owned migration that creates the table in omnidash_analytics was never committed into omnibase_infra's tracked forward-migration tree (docker/migrations/forward/nodes/node_pr_lifecycle_state_reducer/). The forward-migration runner therefore had no SQL to apply, the table was missing on dev, and the OMN-13415 migration-sync guard correctly aborted the deploy. This is the OMN-13636 migration-gap class made concrete.

Fix

  • Vendored the node migration via scripts/sync-node-migrations.sh (the canonical OMN-12559 vendoring path). The vendored file is byte-identical to the omnimarket source @ dev/fix(OMN-10168): add orchestrator dispatcher coverage gate #1440 (cmp IDENTICAL).
  • run-forward-migrations.sh applies it under the namespaced id node:node_pr_lifecycle_state_reducer:0001_create_pr_lifecycle_ledger_entries.sql, so a clean clone / redeploy materializes pr_lifecycle_ledger_entries.
  • TDD-first: added test_pr_lifecycle_ledger_migration_vendored (failed before the vendor, passes after) pinning the vendored file, the ticket-required ledger fields, and the UNIQUE(sweep_id,repo,pr_number,iteration) conflict key.

dod_evidence

  • TDD red→green: test_pr_lifecycle_ledger_migration_vendored failed (file absent) before vendoring, passes after.
  • Sync guard PASS: scripts/sync-node-migrations.sh --check → check: in sync (exit 0). Pre-commit ONEX Node Migration Vendor Sync Check → Passed.
  • Real-SQL apply proof (Postgres 14, ephemeral): migration applies clean; re-apply is idempotent (IF NOT EXISTS); table created with all 12 columns, the UNIQUE constraint, and 3 indexes (idx_pr_lifecycle_ledger_sweep, ..._sweep_iter, ..._found_at).
  • Exact DoD probe (real SQL): 4 open PRs × 2 consecutive iterations → select count(*) from pr_lifecycle_ledger_entries where sweep_id='20260626-dodproof' returns 8; distinct iterations {0,1}, 4 rows each; re-applying iteration 1's UPSERT keeps count at 8 (no overwrite, idempotent).
  • Local verify (no -k): tests/unit/migrations/ + tests/ci/test_validate_migration_sequence.py + tests/scripts/test_check_deployed_migration_tree_sync.py → 79 passed; mypy --strict clean on changed test; ruff format/check clean; pre-commit run --files <changed> all green (migration freeze / sequence-duplicate / vendor-sync / writer-migration-coupling all Passed).

Redeploy is a separate orchestration step — a forward-migration run (batched redeploy) will apply the now-vendored SQL and create the table on dev. This PR does not mutate any runtime lane. No live deploy is performed here.

Evidence-Source: OCC#3165
Evidence-Ticket: OMN-13321

The paired OCC receipt PR #3165 carries the OMN-13321 contract update + the dod-omnibase-infra-pr-2112 receipt binding this PR; dod-occ-pr-self self-binds to OCC #3165. Relates OMN-13636, OMN-13415.

Closes OMN-13321 (vendoring gap).

…ion into infra forward-migration tree

The omnimarket node node_pr_lifecycle_state_reducer (merged in #1440) declares
projection_api over pr_lifecycle_ledger_entries and UPSERTs one user-readable
ledger row per PR EVERY sweep iteration. Its node-owned migration
(0001_create_pr_lifecycle_ledger_entries.sql) creates the table in
omnidash_analytics, but the vendored SQL was NEVER committed into
omnibase_infra's tracked forward-migration tree
(docker/migrations/forward/nodes/node_pr_lifecycle_state_reducer/). The
forward-migration runner therefore had no SQL to apply, the table was missing on
dev, and the OMN-13415 migration-sync guard correctly aborted the deploy.

Fix: vendor the node migration via scripts/sync-node-migrations.sh (1:1 mirror,
byte-identical to the omnimarket source @ dev/#1440). The runner applies it under
the namespaced id
node:node_pr_lifecycle_state_reducer:0001_create_pr_lifecycle_ledger_entries.sql,
so a clean clone / redeploy materializes pr_lifecycle_ledger_entries.

TDD: added test_pr_lifecycle_ledger_migration_vendored (failing before the
vendor, passing after) pinning the vendored file + ticket-required ledger fields
+ UNIQUE(sweep_id,repo,pr_number,iteration) conflict key.

This is the OMN-13636 migration-gap class made concrete. Redeploy is a separate
orchestration step (note for the batched redeploy).
@coderabbitai

coderabbitai Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jonahgabriel, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 56 minutes and 28 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 05e6f706-088f-44ec-a1f1-35c2352809f8

📥 Commits

Reviewing files that changed from the base of the PR and between cd7fdf2 and 113e768.

📒 Files selected for processing (2)
  • docker/migrations/forward/nodes/node_pr_lifecycle_state_reducer/0001_create_pr_lifecycle_ledger_entries.sql
  • tests/unit/migrations/test_node_migration_discovery.py
📝 Walkthrough

Walkthrough

Adds a forward migration that creates public.pr_lifecycle_ledger_entries with uniqueness and indexes, and updates migration discovery tests to verify the new vendored SQL and its key schema fields.

Changes

PR lifecycle ledger migration

Layer / File(s) Summary
Ledger table migration
docker/migrations/forward/nodes/node_pr_lifecycle_state_reducer/0001_create_pr_lifecycle_ledger_entries.sql
Creates public.pr_lifecycle_ledger_entries with the listed lifecycle, metadata, and scheduling columns, plus the UNIQUE (sweep_id, repo, pr_number, iteration) constraint and three supporting indexes.
Vendoring and schema test
tests/unit/migrations/test_node_migration_discovery.py
Adds the vendored migration path constant and a unit test that checks the SQL file exists and contains the expected table creation, uniqueness constraint, and ledger columns.

🎯 2 (Simple) | ⏱️ ~10 minutes

\o/ I dug a tidy tunnel of SQL,
🐰 ledger rows now line up well.
One hop for the table, one hop for the test,
fresh little indexes doing their best.
Carrot confetti in the moonlit stack!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: vendoring the node_pr_lifecycle_state_reducer ledger migration into the infra migration tree.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jonah/omn-13321-vendor-pr-lifecycle-ledger-migration

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/unit/migrations/test_node_migration_discovery.py (1)

331-333: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the conflict-key contract, not one DDL spelling.

This hardcodes the inline UNIQUE (...) form, so it will fail if the migration is fixed to use a standalone CREATE UNIQUE INDEX IF NOT EXISTS for warm-table reconciliation. Assert either form, or pin a dedicated unique-index name instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/migrations/test_node_migration_discovery.py` around lines 331 -
333, The test for the migration conflict-key contract is too specific to the
inline UNIQUE constraint spelling, so it will break if the migration uses a
standalone unique index instead. Update the assertion in
test_node_migration_discovery to validate the conflict-key behavior more
generally by accepting either the UNIQUE (...) table constraint form or the
CREATE UNIQUE INDEX IF NOT EXISTS form, or by asserting against the dedicated
unique-index name rather than raw SQL text.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@docker/migrations/forward/nodes/node_pr_lifecycle_state_reducer/0001_create_pr_lifecycle_ledger_entries.sql`:
- Around line 36-50: The `CREATE TABLE IF NOT EXISTS` in the
`pr_lifecycle_ledger_entries` migration only adds the `UNIQUE (sweep_id, repo,
pr_number, iteration)` constraint on fresh tables, so warm existing tables can
still miss the `ON CONFLICT` target. Update this migration to explicitly ensure
the conflict key exists for `public.pr_lifecycle_ledger_entries` even when the
table is preexisting, using the table name and unique key as the locating
symbols, so the reducer’s upsert remains idempotent.

---

Nitpick comments:
In `@tests/unit/migrations/test_node_migration_discovery.py`:
- Around line 331-333: The test for the migration conflict-key contract is too
specific to the inline UNIQUE constraint spelling, so it will break if the
migration uses a standalone unique index instead. Update the assertion in
test_node_migration_discovery to validate the conflict-key behavior more
generally by accepting either the UNIQUE (...) table constraint form or the
CREATE UNIQUE INDEX IF NOT EXISTS form, or by asserting against the dedicated
unique-index name rather than raw SQL text.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4a1df009-a1ad-4ad4-81a8-eee7bb93c3b4

📥 Commits

Reviewing files that changed from the base of the PR and between 42358da and cd7fdf2.

📒 Files selected for processing (2)
  • docker/migrations/forward/nodes/node_pr_lifecycle_state_reducer/0001_create_pr_lifecycle_ledger_entries.sql
  • tests/unit/migrations/test_node_migration_discovery.py

@jonahgabriel
jonahgabriel enabled auto-merge June 26, 2026 08:33
@jonahgabriel

Copy link
Copy Markdown
Collaborator Author

CR thread gate refresh: unresolved review threads are resolved after re-vendoring the omnimarket hardening in 113e768. Please rerun the thread gate on the current PR head.

@jonahgabriel
jonahgabriel added this pull request to the merge queue Jun 26, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 26, 2026
@jonahgabriel
jonahgabriel added this pull request to the merge queue Jun 26, 2026
Merged via the queue into dev with commit 22128bd Jun 26, 2026
110 of 116 checks passed
@jonahgabriel
jonahgabriel deleted the jonah/omn-13321-vendor-pr-lifecycle-ledger-migration branch June 26, 2026 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant