Skip to content

fix: harden the Postgres persistence tier#146

Open
FlyM1ss wants to merge 3 commits into
mainfrom
fix/pg-tier-hardening
Open

fix: harden the Postgres persistence tier#146
FlyM1ss wants to merge 3 commits into
mainfrom
fix/pg-tier-hardening

Conversation

@FlyM1ss

@FlyM1ss FlyM1ss commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Batch B of the agent-persistence follow-ups — three issues, one tier.

  • Closes Postgres twins have no lazy-migration path #135 — the agent twin gains a lazy-migration path (ALTER … ADD COLUMN IF NOT EXISTS for the 5 folded columns). Without it, a future column added only to CREATE TABLE no-ops on prod's existing table → UndefinedColumn 500s the whole agent surface while /health stays green. New @pg_only test recreates the pre-migration table to force the migrate path (RED before the fix, GREEN after). Scoped to the agent twin deliberately: it's the only twin with a folded migration history; version/strategy shipped complete and keep their documented convention.
  • Closes Postgres tier has five known coverage gaps #137 — five @pg_only coverage gaps closed: claim/reclaim, raw scopes default (read straight from the column, since _public_agent's or DEFAULT_SCOPES masks a wrong empty default), last_used_at touch-on-use, listing ORDER BY, and widen-path nbytes. Each was mutation-tested — inject the targeted bug, confirm the test goes red, revert.
  • Closes CI tests Postgres 16, prod Neon runs 18.4 #138 — CI Postgres 16 → 18-alpine to match prod Neon 18.x.

Verified on a local postgres:18-alpine: full suite 1113 passed / 5 skipped / 0 failed with the live tier on.

- #135: give the agent twin a lazy-migration path (ALTER ... ADD COLUMN
  IF NOT EXISTS for the five columns the SQLite store accreted), so a
  redeploy migrates an existing external_agents table instead of 500ing
  on the missing column. New @pg_only test recreates the pre-migration
  table to force the migrate path.
- #137: close five @pg_only coverage gaps (claim/reclaim, raw scopes
  default, last_used_at touch-on-use, listing ORDER BY, widen-path
  nbytes). Each mutation-verified to fail under its targeted bug.
- #138: bump CI Postgres 16 -> 18-alpine to match prod Neon 18.x.

Verified on a local postgres:18-alpine: full suite 1113 passed,
5 skipped, 0 failed with the live tier enabled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agentic-trading-lab Ready Ready Preview, Comment Jul 18, 2026 9:07am

Keep the local throwaway-DB recipe on the same major version #138 pins CI
and prod to, so the tier is exercised against prod's dialect everywhere.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Addresses self-review findings on this PR:
- migration test now seeds a real legacy row before re-running
  _init_schema and asserts the ADD COLUMN NOT NULL DEFAULT backfills
  agent_type/scopes on it -- the actual prod scenario (a populated
  pre-migration table, scopes being an authz input), not just an
  empty table gaining columns
- ordering test swaps the fixed 6-item iterator for an unbounded
  itertools.count clock: a change in create_agent's _utcnow_iso call
  count now surfaces as a clean assertion failure, not StopIteration
- bump the remaining postgres:16-alpine -> 18-alpine references in
  this workstream's plan/spec docs to match the shipped CI (#138)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@FlyM1ss

FlyM1ss commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator Author

Pushed c999e96 — self-review follow-ups:

  • Migration test → populated-table case. test_agent_schema_lazily_migrates_an_old_table_postgres now seeds a real legacy row before re-running _init_schema, then asserts the ADD COLUMN … NOT NULL DEFAULT backfilled agent_type/scopes on it (raw column read, bypassing _public_agent's scopes masking). That's the actual prod scenario — a populated pre-migration table where a NULL scopes would be an authz hole — not just an empty table gaining columns.
  • Ordering test clock. Swapped the fixed 6-item iterator for an unbounded itertools.count, so a change in create_agent's _utcnow_iso call count surfaces as a clean assertion failure instead of StopIteration.
  • Doc version consistency. Bumped the remaining postgres:16-alpine → 18-alpine refs in this workstream's plan/spec docs to match the shipped CI (CI tests Postgres 16, prod Neon runs 18.4 #138).

Verification: full non-pg suite green locally (1095 passed / 23 skipped / 0 failed). The @pg_only assertions weren't run locally (no Docker engine reachable here) — CI's pg18 tier is the live gate for them.

Out of scope, flagging: docs/superpowers/plans/2026-07-08-user-account-persistence-fix.md still has two postgres:16-alpine refs, but that's the earlier user-account workstream's doc — left untouched.

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.

CI tests Postgres 16, prod Neon runs 18.4 Postgres tier has five known coverage gaps Postgres twins have no lazy-migration path

1 participant