Skip to content

refactor(migrations): move default queue-storage substrate into v023 SQL helper (#308 PR 1)#310

Merged
hardbyte merged 2 commits into
mainfrom
brian/issue-308-substrate-helper
Jun 2, 2026
Merged

refactor(migrations): move default queue-storage substrate into v023 SQL helper (#308 PR 1)#310
hardbyte merged 2 commits into
mainfrom
brian/issue-308-substrate-helper

Conversation

@hardbyte
Copy link
Copy Markdown
Owner

@hardbyte hardbyte commented Jun 2, 2026

Summary

First PR of the #308 series: move the per-schema queue-storage DDL into a SQL helper function so the default awa substrate becomes migration-owned. The headline numbers: prepare_schema() shrinks from 1884 → 280 lines; v023 ships ~1300 lines of plpgsql that both the migration and prepare_schema() call into; awa migrate --sql now contains the complete substrate install.

Follow-ons in this series:

  • PR 2: hoist awa.runtime_storage_backends out of prepare_schema() into its own migration; activate_backend() becomes INSERT/UPDATE only.
  • PR 3: hard-reject awa storage prepare-queue-storage-schema --schema awa --reset; add docs/queue-storage-substrate.md and link from architecture / migrations / security.

Design contract

The default awa.* substrate is migration-owned and default-shaped. The helper signature:

awa.install_queue_storage_substrate(
    p_schema TEXT,
    p_queue_slot_count INT DEFAULT 16,
    p_lease_slot_count INT DEFAULT 8,
    p_claim_slot_count INT DEFAULT 8,
    p_lease_claim_receipts BOOLEAN DEFAULT TRUE
) RETURNS VOID
LANGUAGE plpgsql
SECURITY INVOKER
SET search_path = pg_catalog, awa, public
  • Single source of truth for substrate DDL. Rust prepare_schema() calls SELECT awa.install_queue_storage_substrate($1, $2, $3, $4, $5) rather than holding parallel CREATE/ALTER strings.
  • Advisory lock inside the helper with the same per-schema lock name (awa.queue_storage.install:<schema>), so CLI / Rust / Python / extracted SQL share race behavior.
  • Activation-neutral: no runtime_storage_backends insert/update, no storage-transition writes. The cross-schema seed of awa.runtime_storage_backends stays in prepare_schema() for PR 1; PR 2 hoists it to its own migration.
  • SECURITY INVOKER, no broad grant. Runtime roles don't gain DDL through the helper.
  • Reject non-default config for p_schema = 'awa': lease_claim_receipts != TRUE and non-default slot counts raise 22023 (invalid_parameter_value) with a HINT directing the operator to a custom queue-storage schema. Non-awa schemas accept any config (test/legacy paths use receipts=false ~20×).
  • lease_claim_receipts=false is NOT dropped from production in this PR — out of scope. It remains supported for non-awa schemas only.

What prepare_schema() keeps

After the shrink, prepare_schema() (now ~280 LOC) retains only the legacy upgrade edge cases that don't belong in a forward-only DDL helper:

  • ADR-023 open_receipt_claims non-empty rejection + drop.
  • Legacy rename of lease_claims / lease_claim_closures from non-partitioned shape (relkind 'r').
  • The helper call itself (passes live QueueStorageConfig).
  • Post-helper copy + drop of *_legacy tables.
  • queue_count_snapshots legacy drop.
  • awa.runtime_storage_backends CREATE + cross-schema seed (moves out in PR 2).

The outer pg_advisory_xact_lock stays — it's needed to serialize the legacy rename (before the helper) and the legacy copy + drop (after) with the helper's CREATE of the partitioned parents. pg_advisory_xact_lock is reentrant for the same session, so the helper's inner acquire is a no-op when called from prepare_schema().

Test plan

  • cargo fmt --all --check clean
  • cargo clippy --all-targets --all-features -- -D warnings clean
  • cargo build --workspace clean
  • cargo test -p awa-model --lib — 64/64 pass (incl. 6 migration tests)
  • cargo test -p awa --test queue_storage_runtime_test against clean Postgres — 77/77 pass in 108s, including all test_queue_terminal_live_counts* and queue_counts* tests. (Initial run on a stale DB showed 4 transient failures in receipts=false + custom-schema tests; verified clean DB shows 77/77.)
  • awa migrate --sql | tail -20 includes the full helper definition, the SELECT awa.install_queue_storage_substrate('awa'); invocation, and the schema_version v23 INSERT.
  • CI matrix on this PR (running on push).

Known latent quirks preserved verbatim

  • The receipts=FALSE branch of claim_ready_runtime has a $6 parameter reference that doesn't correspond to any of the function's 4 named parameters. This is a pre-existing latent bug on main (line ~2210 of awa-model/src/queue_storage.rs before this PR) that's never reached in practice — COALESCE short-circuits past it whenever p_deadline_secs > 0, and every call site passes > 0. Preserved verbatim here to keep this PR a pure refactor; will be tracked as a follow-up issue.

Refs

Closes none; refs #308. PRs 2 and 3 land separately.

Summary by CodeRabbit

  • Chores
    • Upgraded DB schema to version 23 to improve queue storage scalability, partitioning, and resilience.
  • Bug Fixes
    • Safer legacy upgrade path: legacy queue data is migrated and cleaned up automatically to prevent downtime or duplication.
  • Tests
    • Added integration and migration tests covering legacy migration and claim behavior.
  • Documentation
    • Security guidance updated to restrict installer execution privileges.

…SQL helper (#308 PR 1)

Adds `awa.install_queue_storage_substrate(p_schema, ...)` in v023 and
makes it the single source of DDL truth for per-schema queue-storage
substrate objects (sequences, ring singletons, partitioned
ready/done/lease tables, lane indexes, claim_ready_runtime). The
helper takes the same per-schema advisory xact lock previously held
by Rust (`awa.queue_storage.install:{schema}`), runs as
SECURITY INVOKER, and rejects non-default configuration against the
default `awa` schema with errcode 22023.

`awa migrate` now installs the default `awa` substrate via
`SELECT awa.install_queue_storage_substrate('awa')`, so a fresh
install no longer waits for the first worker to materialize the
queue-storage tables and `awa migrate --sql` output is now
self-sufficient for external migration tooling.

`QueueStorage::prepare_schema()` shrinks from ~1884 LOC to ~280 LOC
and now: rejects non-empty `open_receipt_claims`, renames a legacy
non-partitioned `lease_claims` / `lease_claim_closures` aside,
calls the helper, copies any renamed-aside rows into the new
partitioned parents, drops `queue_count_snapshots`, and still
creates `awa.runtime_storage_backends` (the CREATE moves into a
dedicated migration in PR 2). The helper is activation-neutral and
does not touch `runtime_storage_backends` or storage-transition
state.

`lease_claim_receipts = false` remains permitted for non-`awa`
schemas (test and legacy paths still exercise it); only the default
`awa` install requires receipts=TRUE.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

Warning

Review limit reached

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

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

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ 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.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 294d4112-7862-4c29-99d5-f1cdb361fb1e

📥 Commits

Reviewing files that changed from the base of the PR and between a0bfff7 and 4ca2d2e.

📒 Files selected for processing (9)
  • awa-model/migrations/v023_install_queue_storage_substrate.sql
  • awa-model/src/queue_storage.rs
  • awa-worker/src/client.rs
  • awa/tests/migration_test.rs
  • awa/tests/queue_storage_runtime_test.rs
  • docs/deploying-on-managed-postgres.md
  • docs/migrations.md
  • docs/security.md
  • docs/upgrade-0.5-to-0.6.md
📝 Walkthrough

Walkthrough

Adds a canonical SQL installer (v023) awa.install_queue_storage_substrate(...), installs per-schema partitioned queue-storage objects and claim runtime, migrates legacy default-schema tables into partitioned parents, updates Rust prepare_schema to invoke the installer, and registers schema version 23.

Changes

Queue Storage Installer & Integration

Layer / File(s) Summary
Installer Function & Base DDL
awa-model/migrations/v023_install_queue_storage_substrate.sql
Defines awa.install_queue_storage_substrate(...) with validation, advisory xact lock, SECURITY INVOKER, schema/sequence/ring-state bootstrapping, seed rows, and records version 23.
Ring, Slots, Partitions & Terminal Tables
awa-model/migrations/v023_install_queue_storage_substrate.sql
Creates lane/head control, partitioned leases/lease_claims/lease_claim_closures, attempt/ready/done/deferred/DLQ tables, per-slot partitions, terminal_jobs view, and queue_terminal_live_counts with backfill.
Claim Ready Runtime Function
awa-model/migrations/v023_install_queue_storage_substrate.sql
Installs {{p_schema}}.claim_ready_runtime(...) implementing aging/effective-priority claim selection, pause gating, FOR UPDATE ... SKIP LOCKED, head advancement, and receipts vs direct-lease insertion branching.
Migration Finalization & Registration
awa-model/migrations/v023_install_queue_storage_substrate.sql, awa-model/src/migrations.rs, docs/security.md
Performs one-shot legacy default-schema checks/renames/drops, calls the installer for default awa, migrates _legacy rows into new partitioned parents, drops legacy tables, updates CURRENT_VERSION to 23, registers migration V23_UP, and documents/revokes EXECUTE on the installer.
Rust prepare_schema & Legacy Backfill
awa-model/src/queue_storage.rs
Detects and renames legacy lease_claims/lease_claim_closures (regular → _legacy), drops queue_count_snapshots, delegates DDL to the SQL installer, backfills legacy rows into partitioned parents (ON CONFLICT DO NOTHING), ensures awa.runtime_storage_backends exists, tightens identifier validation and adds unit tests.
Tests & Permission Changes
awa/tests/*, awa/tests/queue_storage_runtime_test.rs
Revokes EXECUTE on the installer from runtime grants, adds test asserting PUBLIC cannot EXECUTE the installer, adds v0.23 legacy migration test that verifies partition rebuild and legacy cleanup, and adds an integration test for legacy non-receipts claim behavior.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • hardbyte/awa#306: Related to queue terminal-counter machinery and the queue_terminal_live_counts structures created by this migration.
  • hardbyte/awa#249: Related to claim runtime aging/effective-priority behavior that claim_ready_runtime implements.
  • hardbyte/awa#304: Related to queue_terminal_live_counts write-side lifecycle and backfill alignment.

Poem

🐰 I hopped into SQL to stitch the queues,
Seeds and slots and partitions all in rows,
The installer hums, old tables find new shoes,
Rust calls the helper, legacy data flows—
A tiny rabbit cheers as claims now doze.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly summarizes the main refactoring: moving queue-storage substrate initialization from Rust code into a reusable SQL helper function defined in migration v023.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch brian/issue-308-substrate-helper

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 and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 244ad26ca3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

'Installs the queue-storage substrate (sequences, ring-state singletons, partitioned ready/done/lease tables, lane indexes, claim_ready_runtime()) into the named schema. The default ''awa'' substrate is migration-owned and default-shaped: lease_claim_receipts=TRUE and (queue=16, lease=8, claim=8). Operators wanting non-default slot counts or lease_claim_receipts=FALSE must use a custom queue-storage schema. SECURITY INVOKER, takes a per-schema advisory xact lock. See #308.';

-- Install the default `awa` substrate as part of migrate.
SELECT awa.install_queue_storage_substrate('awa');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Run legacy lease-claim fixups before v23 install

When upgrading an existing database that still has the pre-partition regular awa.lease_claims or awa.lease_claim_closures tables, this migration calls the helper directly and skips the rename/copy fixups that now remain only in QueueStorage::prepare_schema(). In that scenario CREATE TABLE IF NOT EXISTS awa.lease_claims (...) PARTITION BY LIST is a no-op against the existing regular table, and the subsequent CREATE TABLE ... PARTITION OF awa.lease_claims in the helper fails because the parent is not partitioned, so awa migrate cannot complete before the application ever reaches prepare_schema().

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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 `@awa-model/migrations/v023_install_queue_storage_substrate.sql`:
- Around line 996-999: The non-receipts CTE is referencing an invalid positional
parameter `$6` for the deadline fallback but the generated function
claim_ready_runtime only defines four parameters (p_queue, p_max_batch,
p_deadline_secs, p_aging_secs); replace the `$6` usage with the correct
parameter name `p_deadline_secs` (or its proper positional `$3`) in the
expression COALESCE(v_deadline_at, v_claimed_at + make_interval(secs => ...)),
updating the expression that uses v_deadline_at and v_claimed_at, and if the
original bug was intentionally preserved add a clear inline TODO comment
referencing claim_ready_runtime and p_lease_claim_receipts to mark the follow-up
fix instead of changing code.

In `@awa-model/src/queue_storage.rs`:
- Around line 2231-2242: The backfill INSERT in the lease_claims migration is
dropping legacy columns (e.g., enqueue_shard and deadline_at) causing runtime
failures; update the INSERT into {schema}.lease_claims and its accompanying
SELECT from {schema}.lease_claims_legacy so that the INSERT column list exactly
matches the full legacy row shape (add enqueue_shard, deadline_at and any other
missing columns) and map the SELECT values (using the same current_slot subquery
for claim_slot) to preserve all fields; ensure the conflict clause (ON CONFLICT
(claim_slot, job_id, run_lease) DO NOTHING) remains unchanged.
- Line 2237: The two legacy INSERTs read claim_ring_state.current_slot
separately causing mismatched partitions if rotate_claims() runs; change the SQL
so you snapshot current_slot once (e.g., via a WITH/CTE or a single SELECT INTO
a variable) and reuse that single value for both lease_claims_legacy and
lease_claim_closures_legacy inserts; update the statements that reference
claim_ring_state.current_slot to use the captured value so both inserts use the
same slot even if rotate_claims() runs concurrently.
🪄 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: 7ff5d631-6222-4786-8c6f-0a22ec3e52a9

📥 Commits

Reviewing files that changed from the base of the PR and between 51dae18 and 244ad26.

📒 Files selected for processing (3)
  • awa-model/migrations/v023_install_queue_storage_substrate.sql
  • awa-model/src/migrations.rs
  • awa-model/src/queue_storage.rs

Comment thread awa-model/migrations/v023_install_queue_storage_substrate.sql
Comment thread awa-model/src/queue_storage.rs
Comment thread awa-model/src/queue_storage.rs Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
awa-model/src/queue_storage.rs (1)

2215-2223: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail impossible default-awa configs before this helper call.

Line 2215 is now the first place that enforces the new “default awa must be default-shaped” contract. QueueStorage::new still accepts schema == "awa" with custom slot counts or lease_claim_receipts = false, but the rest of this type branches on those config values even outside prepare_schema(). That lets a misconfigured runtime target an already-migrated default substrate and take the wrong receipt/slot path before SQL ever rejects it.

Suggested fix
     pub fn new(config: QueueStorageConfig) -> Result<Self, AwaError> {
         if config.queue_slot_count < 4 {
             return Err(AwaError::Validation(
                 "queue storage requires at least 4 queue slots".into(),
             ));
@@
         if config.queue_stripe_count == 0 {
             return Err(AwaError::Validation(
                 "queue storage requires at least 1 queue stripe".into(),
             ));
         }
+        if config.schema == DEFAULT_SCHEMA
+            && (config.queue_slot_count != DEFAULT_QUEUE_SLOT_COUNT
+                || config.lease_slot_count != DEFAULT_LEASE_SLOT_COUNT
+                || config.claim_slot_count != DEFAULT_CLAIM_SLOT_COUNT
+                || !config.lease_claim_receipts)
+        {
+            return Err(AwaError::Validation(
+                "the default `awa` queue-storage schema must use the default slot counts and lease_claim_receipts=true".into(),
+            ));
+        }
         validate_ident(&config.schema)?;
         Ok(Self {
             config,
             next_stripe_probe: AtomicUsize::new(0),
🤖 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 `@awa-model/src/queue_storage.rs` around lines 2215 - 2223, Fail early when the
config requests the canonical "awa" schema but the runtime still provides
non-default settings: in QueueStorage::new (before calling prepare_schema() or
executing the install helper that runs SELECT
awa.install_queue_storage_substrate(...)), validate if schema == "awa" and then
assert that queue_slot_count(), lease_slot_count(), claim_slot_count() equal the
expected default constants and lease_claim_receipts() is true; if not, return an
error immediately so misconfigured runtimes cannot proceed down code paths that
assume non-default values.
♻️ Duplicate comments (2)
awa-model/src/queue_storage.rs (2)

2250-2261: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve the full legacy lease_claims row shape during backfill.

Line 2250 still drops enqueue_shard and deadline_at, but later receipt paths read both from {schema}.lease_claims (ensure_running_leases_from_receipts_tx, rescue_expired_receipt_deadlines_tx, and load_job). Upgraded claims lose the shard/deadline metadata needed to materialize leases, join back to ready_entries, and rescue expired deadlines.

🤖 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 `@awa-model/src/queue_storage.rs` around lines 2250 - 2261, The backfill INSERT
from {schema}.lease_claims_legacy into {schema}.lease_claims currently omits
enqueue_shard and deadline_at, losing metadata needed by
ensure_running_leases_from_receipts_tx, rescue_expired_receipt_deadlines_tx, and
load_job; modify the INSERT and SELECT in the upgrade SQL (the INSERT INTO ...
SELECT from lease_claims_legacy block) to include enqueue_shard and deadline_at
in both the target column list and the SELECT projection so upgraded rows retain
the full legacy row shape, and keep the ON CONFLICT (claim_slot, job_id,
run_lease) DO NOTHING behavior.

2256-2256: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reuse one claim_slot for both legacy inserts.

Lines 2256 and 2297 read claim_ring_state.current_slot independently. If rotate_claims() advances between those statements on an already-active schema, closures get copied into a different partition than their claims, so the migrated attempts remain permanently “open” to every lease_claims/lease_claim_closures anti-join.

Suggested fix
+            let legacy_claim_slot: i32 = sqlx::query_scalar(&format!(
+                "SELECT current_slot FROM {schema}.claim_ring_state WHERE singleton"
+            ))
+            .fetch_one(install_tx.as_mut())
+            .await
+            .map_err(map_sqlx_error)?;
+
             if lease_claims_legacy_exists {
                 sqlx::query(&format!(
                     r#"
                 INSERT INTO {schema}.lease_claims (
@@
                 )
                 SELECT
-                    (SELECT current_slot FROM {schema}.claim_ring_state WHERE singleton),
+                    $1,
                     job_id, run_lease, ready_slot, ready_generation,
                     queue, priority, attempt, max_attempts, lane_seq,
                     claimed_at, materialized_at
                 FROM {schema}.lease_claims_legacy
                 ON CONFLICT (claim_slot, job_id, run_lease) DO NOTHING
                 "#
                 ))
+                .bind(legacy_claim_slot)
                 .execute(install_tx.as_mut())
                 .await
                 .map_err(map_sqlx_error)?;
@@
             if closures_legacy_exists {
                 sqlx::query(&format!(
                     r#"
                 INSERT INTO {schema}.lease_claim_closures (
@@
                 )
                 SELECT
-                    (SELECT current_slot FROM {schema}.claim_ring_state WHERE singleton),
+                    $1,
                     job_id, run_lease, outcome, closed_at
                 FROM {schema}.lease_claim_closures_legacy
                 ON CONFLICT (claim_slot, job_id, run_lease) DO NOTHING
                 "#
                 ))
+                .bind(legacy_claim_slot)
                 .execute(install_tx.as_mut())
                 .await
                 .map_err(map_sqlx_error)?;

Also applies to: 2297-2297

🤖 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 `@awa-model/src/queue_storage.rs` at line 2256, In rotate_claims(), avoid
reading claim_ring_state.current_slot twice; read it once into a local variable
(e.g., claim_slot) and reuse that single value for both legacy inserts (the
INSERTs that reference claim_ring_state.current_slot and the second legacy
insert around the lease_claim_closures/lease_claims anti-join) so both closures
and claims are inserted with the same slot; update references in the INSERT
statements and any subsequent logic to use claim_slot instead of querying
claim_ring_state.current_slot again.
🤖 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 `@awa/tests/queue_storage_runtime_test.rs`:
- Around line 2170-2185: Add an assertion to ensure the legacy receipts-disabled
path does not create any lease_claims: call lease_claim_count(&pool,
&store).await and assert_eq! it to 0 immediately after the existing lease
assertions (use the same pool, store, and job_id context used in this test with
variables like claimed, job_id, pool, store) so regressions that insert a
lease_claims row are detected.

---

Outside diff comments:
In `@awa-model/src/queue_storage.rs`:
- Around line 2215-2223: Fail early when the config requests the canonical "awa"
schema but the runtime still provides non-default settings: in QueueStorage::new
(before calling prepare_schema() or executing the install helper that runs
SELECT awa.install_queue_storage_substrate(...)), validate if schema == "awa"
and then assert that queue_slot_count(), lease_slot_count(), claim_slot_count()
equal the expected default constants and lease_claim_receipts() is true; if not,
return an error immediately so misconfigured runtimes cannot proceed down code
paths that assume non-default values.

---

Duplicate comments:
In `@awa-model/src/queue_storage.rs`:
- Around line 2250-2261: The backfill INSERT from {schema}.lease_claims_legacy
into {schema}.lease_claims currently omits enqueue_shard and deadline_at, losing
metadata needed by ensure_running_leases_from_receipts_tx,
rescue_expired_receipt_deadlines_tx, and load_job; modify the INSERT and SELECT
in the upgrade SQL (the INSERT INTO ... SELECT from lease_claims_legacy block)
to include enqueue_shard and deadline_at in both the target column list and the
SELECT projection so upgraded rows retain the full legacy row shape, and keep
the ON CONFLICT (claim_slot, job_id, run_lease) DO NOTHING behavior.
- Line 2256: In rotate_claims(), avoid reading claim_ring_state.current_slot
twice; read it once into a local variable (e.g., claim_slot) and reuse that
single value for both legacy inserts (the INSERTs that reference
claim_ring_state.current_slot and the second legacy insert around the
lease_claim_closures/lease_claims anti-join) so both closures and claims are
inserted with the same slot; update references in the INSERT statements and any
subsequent logic to use claim_slot instead of querying
claim_ring_state.current_slot again.
🪄 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: d06561d6-6ff9-4cdf-952b-172bd37ff231

📥 Commits

Reviewing files that changed from the base of the PR and between 244ad26 and a0bfff7.

📒 Files selected for processing (5)
  • awa-model/migrations/v023_install_queue_storage_substrate.sql
  • awa-model/src/queue_storage.rs
  • awa/tests/migration_test.rs
  • awa/tests/queue_storage_runtime_test.rs
  • docs/security.md

Comment thread awa-model/migrations/v023_install_queue_storage_substrate.sql
Comment thread awa/tests/queue_storage_runtime_test.rs
@hardbyte hardbyte force-pushed the brian/issue-308-substrate-helper branch from a0bfff7 to 70c1120 Compare June 2, 2026 10:44
Run the default awa v023 install through the same legacy cleanup shape that prepare_schema handles, so awa migrate can upgrade an already-prepared default substrate with regular lease_claims tables. Tighten helper input validation to the runtime's lowercase unquoted schema contract and revoke PUBLIC execute on the installer helper.

Fix the non-receipts zero-deadline claim body by using v_deadline_at instead of the stale positional fallback, and add regressions for the migration-only legacy path, installer privileges, identifier validation, and zero-deadline claims.

Fixes #311
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