Skip to content

Create new production release - #1325

Open
ebma wants to merge 66 commits into
mainfrom
staging
Open

Create new production release#1325
ebma wants to merge 66 commits into
mainfrom
staging

Conversation

@ebma

@ebma ebma commented Aug 7, 2026

Copy link
Copy Markdown
Member

No description provided.

Sharqiewicz and others added 30 commits July 30, 2026 11:03
Resolved 7 conflicts, all where staging's refactors met the email
notification work:

- models/index.ts, vars.ts, phase-processor.ts,
  alfredpay-customer.service.ts: both sides added adjacent declarations;
  kept both. Dropped the TaxId associations, since staging removed that
  model in the provider_customers cutover.
- security-spec/README.md: kept the Resend row, dropped the Stellar
  Anchors row that staging deleted along with the spec file.
- alfredpay.md: both sides added an invariant 24; kept staging's at 24
  and renumbered the notification invariants to 25 and 26.
- brla.md: took staging's anonymous-quote row, which matches the merged
  registerRamp (rejects only when quote and request users both exist and
  differ); this branch's row described pre-cutover behavior. Kept the
  four added webhook threat rows.
…ed ramps

The 055 prefix collides with 055-create-financial-operations on staging -- the
exact duplicate-prefix situation MIGRATION_RENAMES in migrator.ts was added to
clean up. Renumbering now, while branch-only, avoids another rename shim entry.

The backfill closes a first-deploy hazard: reconcileMissedRampCompletedEmails
deliberately has no age cutoff, so an empty table would re-enqueue every
historical completed ramp and mass-mail users about months-old completions.
Tombstoning them as skipped at table creation keeps the sweep anomaly-only.
getEffectiveUserId fills rampState.userId with the credential's linked profile
on API-key requests, so the null-userId check alone mailed the partner once per
end-customer ramp -- the opposite of the documented behavior. A ramp whose quote
carries an api_credential_id now records a skipped tombstone instead, which
also stops the hourly reconcile sweep from re-surfacing it forever.

The reconciliation integration test now seeds real ramps and asserts the
anti-join's semantics instead of running it against an empty database.
ebma added 18 commits August 6, 2026 19:19
Empirically (2-file probe): mock.module mutates already-imported namespace
objects in place, so spreading the namespace at restore time copies the
stubs back -- the restore was a silent no-op. Snapshots are now plain-object
copies taken before the first mock.module call, and the new Avenia enqueue
suite resolves its subject in beforeAll because the webhook controller test
mocks that exact module path and bun's file execution order is not the CLI
order.
Same in-place-mutation flaw fixed for the email suites earlier: spreading a
live namespace at restore time copies the stub back, so the fund-ephemeral
and offramp-subsidy suites and the FakeSquidRouter harness restore() were
silent no-ops. All three now restore from a plain-object snapshot taken
before the first mock.module call. The canary additionally checks that
shared's getRoute is not a leftover FakeSquidRouter stub, which the name
and class-shape checks cannot see.
The route persisted Approved/Rejected without ever queuing an email. Once a
case is terminal both this route's short-circuit and the KYB worker stop
observing the attempt, so a client polling ahead of a lost webhook lost the
notification forever. The outcome is queued before the terminal writes --
mirroring the Alfredpay enqueue-before-persist invariant -- and a failed
enqueue fails the request, leaving the case pollable.
…empts

Three review findings on the hourly sweep: partner-owned cases passed the
row filter and could permanently occupy the 250-slot batch (now excluded in
the join); a capped oldest-first prefix re-selected the same rows every
cycle since pending cases are never modified (now an id-ordered keyset like
the Alfredpay sweep); and the returned attempt id was trusted, letting a
malformed provider response enqueue another attempt's outcome and reason
for this case's profile (now discarded, mirroring the authenticated
route's guard). Spec updated in the same change, including its stale
enqueueCompletionEmail/055 identifiers.
sendRequest used a bare fetch, so one hung Avenia connection stalled its
caller indefinitely -- for cron workers with waitForCompletion that means
no future cycle ever runs. Timeouts land in the existing transport-failure
path (BrlaApiError status 0) that callers already normalize to a 502.
The recovery query had no limit, so a prolonged outage made a single hourly
cycle arbitrarily large (one quote plus locale lookup per missing ramp).
250 oldest-first per cycle, with a log line when the cap is hit; processed
ramps gain a queue row and leave the anti-join, so the backlog drains
across cycles without giving up the no-age-cutoff guarantee.
The architecture doc's security-spec link broke when the doc moved into
docs/ (its ../ now resolved outside the tree), and the section 7 comparison
table still named migration 055.
Send ramp completion and verification outcome emails
The Settings checkboxes were uncontrolled defaultChecked stubs -- toggling
persisted nothing and reset on reload. They now load and mutate
/v1/notifications/preferences with optimistic rollback. Two categories
remain: onboarding updates fan out to the three verification_* types and
transfer status maps to ramp_completed -- the stored type strings the
dispatch worker consults, pinned by a test because the PUT endpoint accepts
any keys without validation. The recipient-approvals toggle is dropped (no
such notification type exists yet) and the transfer caption no longer
mentions failures.
…icing-metadata

Add transparent AlfredPay quote pricing metadata
…contract

The dashboard's preference toggles write prefs keyed by these strings and the
API's dispatch worker mutes on them, but each side carried its own literals --
the preferences endpoint accepts arbitrary keys, so drift would mute nothing,
silently. The enum now lives in shared and the API model re-exports it under
its historical NotificationType name.
Review follow-ups on the Settings toggles: a checkbox now reflects
emailEnabled AND the per-type keys, and enabling a category under a global
mute lifts the switch while pinning the other category to its effective
(muted) state. Toggling is blocked until the GET resolves -- a PUT built
from a fallback would replace the saved document -- and while a PUT is in
flight, since overlapping full-document snapshots can complete out of
order. The optimistic handlers are extracted and tested against a real
QueryClient (apply, rollback, no-op without loaded data), and the stale
operations spec that still declared email dispatch unimplemented now
documents the delivery-time preference gating.
…ion-preferences

Wire the Settings email notification toggles to the backend
@netlify

netlify Bot commented Aug 7, 2026

Copy link
Copy Markdown

Deploy Preview for vortex-sandbox ready!

Name Link
🔨 Latest commit 96e44da
🔍 Latest deploy log https://app.netlify.com/projects/vortex-sandbox/deploys/6a798c20c571e700082675d9
😎 Deploy Preview https://deploy-preview-1325--vortex-sandbox.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Aug 7, 2026

Copy link
Copy Markdown

Deploy Preview for vrtx-dashboard canceled.

Name Link
🔨 Latest commit 96e44da
🔍 Latest deploy log https://app.netlify.com/projects/vrtx-dashboard/deploys/6a798c20e8abd40008561ba9

@netlify

netlify Bot commented Aug 7, 2026

Copy link
Copy Markdown

Deploy Preview for vortexfi ready!

Name Link
🔨 Latest commit 96e44da
🔍 Latest deploy log https://app.netlify.com/projects/vortexfi/deploys/6a798c20efa6960008003081
😎 Deploy Preview https://deploy-preview-1325--vortexfi.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

ebma added 9 commits August 8, 2026 10:21
Reviews are probabilistic; live integrator breakage should be caught
deterministically. The gate renders the shared endpoint types and the
public SDK API into a structurally expanded snapshot, so any change to
what partners consume - including transitive type/enum drift - fails CI
until the snapshot is regenerated and the diff is reviewed on purpose.
vortex-review encodes the multi-lens finder fleet with loop-until-dry
and adversarial verification; address-feedback turns one PR review
round into a single verify-fix-gate-push command.
ship chains plan approval, implementation with tests, vortex-review
until dry, and PR creation; babysit-pr watches an open PR and reacts
to new reviews and CI failures so feedback rounds need no ferrying.
Copilot review on #1326 found three blind spots: generic conditional
aliases rendered as self-references, signature type parameters and
their constraints were dropped, and readonly was erased. All three
let partner-facing drift pass the gate; the serializer now expands
conditional bodies, emits type-parameter constraints and defaults,
and preserves readonly, with fixture coverage for each.
Inline review comments are not returned by gh pr view and live on a
paginated endpoint; the address-feedback and babysit-pr instructions
now fetch them explicitly so findings cannot be silently dropped.
Second Copilot round on #1326: readonly index signatures and readonly
tuples serialized identically to their mutable forms, so mutability
changes to those constructs would pass the gate unseen.
Review, feedback, and babysit skills execute branch-local commands;
on a public repo with forks that would let an untrusted PR run code
under local credentials. Fork or external-author PRs are now
inspect-only in all three skills.
…ooling

Add wire-contract CI gate and agent review workflow skills
Skills are agent-agnostic capabilities, so they live in the shared
.agents/skills directory alongside the existing integration skills;
.claude/skills keeps symlinks because Claude Code only scans that
path (symlinked skill directories are officially supported). Hook
bypassed for this commit: lint-staged's stash backup fails on staged
symlinks; biome verify was run manually and is clean.
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.

2 participants