Repository navigation
fix(addie): type account-link correlation parameters for PostgreSQL - #7531
Conversation
22b96a4 to
ee81e58
Compare
There was a problem hiding this comment.
Ladon verdict: Approve
Approve.
Server-only fix: adds six explicit type casts ($2::text×4, $4::text×2) to reconcile the parameter types PostgreSQL deduces for reused surface/initiating-user params in createAccountLinkCorrelation's INSERT…SELECT, resolving the 42P08 parse-time error. Behavior preserved — no change to predicates, TTL, hashing, or the consume path; casts match the varchar column types. Test file (+204) exercises cascade cleanup backed by the real ON DELETE CASCADE FK.
Scope check: touches only server/src/db/** Addie code and its integration test — no protocol surface (static/schemas/source/**, docs/reference/**, dist/**), so no changeset required and no schema↔docs coherence concerns. Not a migration under server/src/db/migrations/**.
Gates: gated_paths false; high_risk false; no no-auto-approve team match. No Critical/High/Medium findings. Rows 1–8 do not fire → row 9 approve. (Note: review_decision is REVIEW_REQUIRED, but the gated-paths hard gate only applies when gated_paths is true, which it is not here.)
Explicit Addie account-link correlation creation fails during node-postgres extended-query parsing on main, before the ownership predicates execute. Give the reused surface parameter
$2and initiating-user parameter$4a consistenttexttype at every occurrence. Slack and web correlations can then be issued for the exact originating principal and thread.Real PostgreSQL first reports
42P08: inconsistent types deduced for parameter $2(text versus character varying). Typing only$2exposes the same inherited ambiguity for$4. The final production change is exactly four$2::textcasts and two$4::textcasts; removing those six casts reproduces the base file byte-for-byte. No predicate, token generation/hash, ten-minute expiry, consume query, replay protection, or callback refusal changes.Availability repair and positive-control qualification for #7498 / #6827 only. #6827 remains open. This PR is directly on main and does not include or modify #7498's preserved patch. No migration, generated-file change, protocol changeset, historical cleanup, or broader identity-linking closure is included. Draft only, auto-merge off, unmerged. Human review renewal is gated on fresh terminal-green CI for the rebased head. No production resources were accessed.
main/cdcc8f996e8acd2417d5f7a547711cd21929289bee81e58e9f3c9be46d49dcb6c35c304eb9a9152c58dee668e4c20ebd72b54a1fb636718350ca28b8cdcc8f99verified after successful main deployment; publication uses the explicit expected-22b96a44leasePure rebase from published head
22b96a44fdc0537a3e88b050f830b441c61253abonto exact maincdcc8f996e8acd2417d5f7a547711cd21929289bafter successful deployment run34925749626. Both changed file blobs, the canonical patch, and the stat are byte-identical;git range-diffreports equivalence. Independent review found no file or semantic overlap with #7533’s CSRF/MCP changes. The update uses an explicit expected-22b96a44lease.File identities (SHA-256 over file bytes):
server/src/db/addie-account-link-correlation-db.ts5ab8370cdad5aabd374fe1e0a8fb03fb0015de7bc05cc77ab99f3a340acb3398server/tests/integration/addie-account-link-correlation-db.test.tsc701a876122fef5a245dee016a9fbcc6d062921180b82deda3d3afe69f90e3e2Reproducible delta hashes, with
BASEandHEADset to the exact commits above:git diff --binary --full-index --no-ext-diff --no-color BASE HEAD | sha256sum:34679dcc121671c848afe4c805f02c53ea23d99f6fbd484177f831d108994634git diff --stat=120 BASE HEAD | sha256sum:1ac8fbc8392d1628ee5b12d46eda090a42d5b7ef36b9a7ebc8bb13f010792c76Validation:
csrf-middleware71,mcp-route-authorization4,mcp-principal-authorization8ee81e58e9f3c9be46d49dcb6c35c304eb9a9152c; sole parent, tree, clean worktree, preserved blobs/patch and complete local gates independently verifiedee81e58e9f3c9be46d49dcb6c35c304eb9a9152c: 32 passed / 1 expected Draft AI-review skip; zero pending or failed contextsThe integration test covers Slack, web/WorkOS, and web/anonymous creation; exact versus wrong user/thread/channel/surface and unsupported user type; stored SHA-256 hash rather than raw token and unchanged TTL; two distinct concurrently issued tokens that remain independently valid; wrong-principal/wrong-surface consume without burning; one-time consumption and replay rejection; simultaneous consumption with one winner; expiry; and owner/channel/user-type/external-ID changes between creation and consumption. Every case calls the production database helper against migrated PostgreSQL.
Failure reproduction uses PostgreSQL 16.15 (
postgres:16image digestsha256:f1c3376c26f2609ab9f29f71f824103fe2fcd8ee0346485cb6122a4f93df6f94), node-postgres 8.23.0, and Node 24.19.0. The INSERT was extracted unchanged usinggit showfrom base helper blobecf334ba1d944bb7bd07c0427c90385de77de1fband sent with a values array throughpg.Client.query. Both exact and wrong Slack/web principals fail at parse time, with zero correlation inserts. The$2-only intermediate was separately reproduced failing on$4, also with zero inserts. Base SQL SHA-256:bd72ec01948177def8f5ecee4e6afac25645fcd0012caf9b8f21c948867df5da; final SQL SHA-256:3373d94d113dfdaeeb13cae458c4675bfe7ac8e6e6e4b964fbd1f3c0e3717f6c(both exclude an added file-ending newline).Local migration smoke used isolated loopback-only Docker databases and the production runner's supported
ADDIE_MATCHED_V4_EVALUATOR_SCHEMA_REQUIRED=falseoption, skipping protected evaluator-only migrations 584/585. It does not claim the full CI evaluator-role tampering matrix. No schema was mocked or rewritten. Source-runner pristine migration smoke and both parameter-failure reproductions were rerun against this base. Git object identity confirms that the compiled runner’s source, entire migrations tree, client, configuration, compiler and dependency manifests are unchanged from the previously validated candidate.Normal Git rebase does not invoke a commit hook. Every required pre-commit component was run directly, including the full server suite rather than the clean-index staged-file selector; local pre-push checks ran without publishing before release.
Focused commands (with
DATABASE_URLpointing only to the isolated Docker fixture):Reproduction scripts, logs, exact SQL delta audit, and the independent review are retained in this workspace's gitignored
.context/rebase-cdcc/(prior published-head evidence remains preserved separately). Their evidence qualifies this narrow repair only; it does not qualify #7498's entire preserved patch or close the remaining #6827 work.Open workspace in Conductor