Skip to content

Replace borrowed PostgreSQL views with Batter-owned transaction scopes - #20

Merged
featherenvy merged 15 commits into
masterfrom
feat/batter-owned-transactions
Sep 21, 2026
Merged

featherenvy merged 15 commits into
masterfrom
feat/batter-owned-transactions

Conversation

@featherenvy

@featherenvy featherenvy commented Sep 20, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Hard-cut over the canonical application/intent/queue workflow to Batter-owned atomic scopes and intent-before-queue typestate. Outputs leave the runner only after acknowledged disposition; uncertainty retains the provisional result and original cause. Schema verification owns a qualified read-only repeatable-read snapshot.

Integration review fixes

  • RunledgerDatabase owns mandatory pool hooks and a declared PgSessionProfile: authenticated/effective roles, authoritative schema, statement/lock timeouts and optional tenant settings. Custom schemas and SET ROLE are supported. Policy is restored after reset before any application work, and validated at owned scope boundaries. Ordinary APIs/workers use the same configured pool; migrations and verification take the database owner.
  • Canonical record_required_job_enqueue_intent returns only accepted pending/promoted observations. Known conflict is a typed callback rejection, so application writes roll back. Explicitly named low-level observation remains available.
  • Private mutation helpers require PgTransactionalExecutor; raw connections/read-only snapshots implement query dispatch only. Compiler-negative assertions cover the split.
  • Every workspace package is explicitly unpublished. A mandatory paired checkout uses a pinned Batter foundation, verified by bootstrap and ordinary Cargo builds. The existing migration-copy consistency guard is preserved; negative controls reject both foundation and migration drift. Clean-checkout CI starts without a sibling. Unpatched packaging is tested to reject the unavailable registry dependency; patched archives are labeled source-pair evidence, not publication proof.
  • README, crate docs and copied guides lead with the canonical profiled runner. A fresh agent's exact first-pass compile-only consumer and limitations are retained under docs/evidence/profile-consumer-2026-09-21.*.

Coordinated foundation

Graph: batter-runledger -> runledger-postgres -> batter-sqlx -> batter-core. Batter PR #2 and Batter #4 are merged. The foundation provides generic declarative profiles; this release-hook fix needs no further Batter source changes.

Foundation pin: d7728e633b3b767edde8aea40daf358ad4917ea4 (the same guarded foundation sources as merged Batter #4). Companion-only descendants are permitted only when the guarded foundation inputs are identical. No merge or publication is performed.

Latest review fix and validation

At b83abe4edd9539ddd178ac06443fc17248cadf78, mandatory after_release restores and verifies the profile before SQLx admits a returned connection to its idle queue. Errors discard the connection. This closes the native try_acquire, try_begin, and try_begin_with bypass of before_acquire.

Four pre-fix PostgreSQL 18.6 regressions failed as expected; all six profile tests pass after the fix. Coverage includes idle/open/aborted transaction returns, role/schema/search-path/tenant/timeouts, same-backend reuse, requested read-only mode, and healthy-socket policy-restoration failure followed by safe replacement. Full local core/PostgreSQL/runtime suites, lint/strict rustdoc and the unchanged Batter adapter suite passed. The focused security-finding workflow used one independent trace and one read-only candidate check; no review-fix-loop was used.

Release regression evidence. Exact-head hosted CI: all five jobs passed. Earlier receipts below are historical, not evidence for this new head.

Earlier coordinated validation

  • Full Runledger workspace suite on PostgreSQL 18.6 (Debian 18.6-1.pgdg13+2), including all 25 migration tests, downgraded privileged login, custom quoted schema, cross-path role/schema/timeout/tenant parity, contamination recovery, tampered authority rejection and conflicted-intent application rollback.
  • Full lint/strict rustdoc, positive/negative capability assertions, source consumer and nine patched archive consumer tests; license archive checks.
  • Clean paired checkout built all targets; source-pin drift rejection and honest unpatched-package rejection passed.
  • Batter full verification on Rust 1.94.0 and 1.98.1, SQLx live suite, adapter probe, all 66 reference cases plus two private library probes, and five HTTP process profiles on each toolchain passed locally.

Historical Runledger CI passed at 7da3ce5d086023ddd71d9b0e50a97d26954535a9: CI run. Historical companion Batter CI passed at 96f582ef56995efbdc8bbe1ebe48f3e5193407d7: Rust Linux/macOS matrix, repository/Jig policy. No persisted migrations or SQLx metadata changed.

Deliberate limits

Runledger accepts one authoritative ordinary schema, not fallback search-path schemas; application objects elsewhere must be qualified. Roles, schemas and grants are application-provisioned. Arbitrary SQL is not sandboxed and can cause effects before boundary validation. Accepted intent state is an observation, not a future-promotion guarantee. Cancellation/uncertainty never authorizes blind replay. Registry publication remains separate work.

@featherenvy

Copy link
Copy Markdown
Collaborator Author

Coordinated follow-up for Batter PR #4's two focused findings is pushed at 23dd1880f3be395ca6e53f93adc07442f43c9f78, pinning Batter foundation d7728e633b3b767edde8aea40daf358ad4917ea4.

  • Public profile reset/setup failures now have safe default formatting before reaching either mandatory SQLx pool hook. The native cause remains available through the retained SqlxFailure; independent query/notice logs, error-chain reporters and server logs are explicitly outside this boundary.
  • Profile keys are normalized before allowlist/duplicate validation; values are unchanged. The companion regression covers eager setup rejection with retained native SQLSTATE/message and a successful mixed-case setting control.

Validation: PostgreSQL 18.6, both database-profile integration tests, complete core/PostgreSQL/runtime suites, test-support library tests, lint/rustdoc, source-pin and migration-drift guards, package-license checks, and all nine coordinated source-archive consumer tests passed. The first full local build hit filesystem exhaustion; after preserving and relocating the build cache, the full rerun passed. This is coordinated unpublished-source evidence, not registry publication evidence.

Exact-head Runledger CI is green. No transaction-layer redesign or review-fix-loop was used.

@featherenvy

Copy link
Copy Markdown
Collaborator Author

Fixed the native fast-acquisition bypass at b83abe4edd9539ddd178ac06443fc17248cadf78.

The mandatory after_release hook now awaits profile reset/apply/verification before SQLx can publish the session as idle. Failure returns the existing redacted error to SQLx, which discards the connection. Acquisition hooks remain in place; no Batter foundation or public transaction API change was needed.

PostgreSQL 18.6 reproduced all three fast-path failures before the production fix, plus failure to discard a session whose profile could not validate. Afterward, all six profile tests pass. The new regressions check role, schema, exact search path, tenant and timeouts across idle/open/aborted transaction returns; verify same-backend reuse; preserve BEGIN READ ONLY; and reject a healthy socket after schema privilege revocation before accepting a correctly profiled replacement.

Validation passed: core/PostgreSQL/runtime suites, strict lint/rustdoc, unchanged Batter adapter suite, and all five exact-head CI jobs, including the coordinated source-archive smoke test. An independent boundary trace and one read-only candidate check found no remaining issue in scope. No review-fix-loop was used. Detailed evidence and limits.

The PR description now names the actual Batter foundation pin and separates current verification from historical receipts. Ready for re-review; nothing merged or published.

@featherenvy
featherenvy merged commit 58b02c2 into master Sep 21, 2026
6 checks passed
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