Skip to content

KYC rework: Smart Paperwork Verification, setup status and account availability - #3620

Draft
innolope-dev wants to merge 185 commits into
devfrom
innolope/kyc-document-selection
Draft

innolope-dev wants to merge 185 commits into
devfrom
innolope/kyc-document-selection

Conversation

@innolope-dev

@innolope-dev innolope-dev commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

The KYC rework in the app, in one PR. It pairs with peanutprotocol/peanut-api-ts#1931.

Smart Paperwork Verification is the one new identity flow: Peanut asks only what the user's features need, then one Sumsub ID check runs. The API decides who gets it (plan.flow, sent the x-kyc-paperwork-verification: 1 header on every KYC call). Everyone else, including users with an existing applicant, keeps today's flow. The document-first picker is gone, and the client never sends x-kyc-document-selection.

Design: the "Extra Details Questionnaire" prototype and the screen-picks canvas.

The flow

  1. Home → Verify identity opens /verify directly. If the KYC plan has not loaded yet, the tap waits for it, so a new-flow user never sees the old "Unlock account" drawer. The drawer stays for an outage, a region-restricted ID or a plan that fails to load.
  2. "A few steps to verify your ID": residence (done), the questions or the ID photo (current), selfie, review, unlock. It shows once per visit. A deep link to a step skips it, and Back from the first question returns to it.
  3. Questions. Short sentence screens that save each step to Sumsub.
    • One job list for the card and the bank account, in four languages.
    • Bridge's source-of-funds answers in its high-risk residences.
    • The EU details in the EEA: purpose, employment, citizenship, country of birth, and city of birth, picked in a drawer with place hints after three letters.
    • Manteca's answers in Argentina and Brazil, with sex on the ID in Brazil. The declarations come right after the card's questions, with "I'm a US citizen or tax resident" first.
    • Phone and address: asked together, the phone sits on the address screen. Asked later on its own, it gets its own screen with a "No spam" row.
    • The country stays locked, with a "Change your country of residence" link.
  4. "Answers saved!" after the last answer. Back from the ID screen skips it.
  5. "Which document will you use?": one row per document, each opening Sumsub on it.
    • A residence permit from the residence.
    • A passport and a national ID from the citizenship the questions asked (the residence when they didn't).
    • "Other document": driving licences, a dual resident's documents from the residence, Ukrainian temporary protection, and "A document from another country" (type, then country).
    • A row names a proof of address when that ID's country makes Bridge ask for one.
    • "Change residence" opens the residence drawer.
  6. Sumsub: ID photos and selfie, preselected on the picked document (WebSDK documentDefinitions, Cordova withPreferredDocumentDefinitions).
  7. "Checking your ID" lists photos received, the ID being read, and the features being set up. The copy keeps the real timing: minutes, or 1 to 3 business days when a reviewer looks.
  8. "Your ID is confirmed!", then a suggested proof of address when the ID and the residence differ. It is skippable, and Bridge is never held for it.

Adding a feature later asks only its missing answers. A verified user who needs a different document restarts on the same list (/verify?step=id&restart=1).

After verification

  • Setup status drawer (KycSetupStatusDrawer): one row per picked feature. The states are Available, Setting up, Under review, Document needed, Terms needed, Agreements needed, Verify ID, and Not available (with the reason), each with its one step.
    • A feature whose own rail works always reads Available.
    • A refused personal Manteca account closes only local transfers; QR stays available.
  • Bridge asks reach the user. A blocking Bridge ask is its own Home task, and the push and email land there. The buttons follow the ask: "Answer questions", "Retake ID photo", "Upload document". A Bridge wait over 24 hours says it is taking longer than usual and offers support. The final refusal says it is the partner's decision.
  • A closed Manteca account (folded in from Show a closed Manteca account instead of a KYC prompt #3762): when Manteca declines a country, its deposit and withdraw screens say the account is closed and offer support, instead of sending the user to a verification that can never reopen it. QR pay keeps working.
  • Rain asks for verification: the card offers its own selfie-and-ID step instead of a dead end, on the card page, the application status and the Home task.
  • Accounts a residence can't get (Smart Paperwork Engine, GET /users/kyc/paperwork).
    • A Bridge deposit corridor whose product comes back available: false with account_unavailable_in_residence is never offered. Examples: USD for Bangladesh, Pakistan, Kenya and nine more; EUR and GBP for the Central African Republic, Eritrea and Mali.
    • The account shows as Not available, sorted last, and explains itself on tap. A direct claim link, the country pick and the bank rows lead to the same drawer.
    • The app holds no country lists; only the corridor-to-product map. A missing product or a failed read changes nothing. A held account and a rail that already moves money stay open.
    • Also fixed: CountryList no longer leaves a spinner on a country whose tap opened a drawer in place.

PostHog

Every screen here reports to PostHog; names are in analytics.consts.ts.

  • Funnel: kyc_paperwork_viewed → _steps_viewed → _steps_continued → _step_viewed → _step_submitted → _step_saved → _saved_viewed → _id_viewed → _id_submitted (with the row's source) → _id_outcome → _identity_submitted → _review_viewed → _verified_viewed. Then the proof-of-address and add-later events.
  • Confusion and errors: _field_error (server or typing), _step_rejected, _form_error, _why_opened, _picker_opened/_closed, _search_empty, _back, _residence_change_opened, _local_refused.
  • Setup drawer: kyc_setup_status_viewed/_action, with each row's state and reason.
  • Privacy: fields are named by key and errors by code, never by value. A test checks that typed values never reach posthog.capture.

Validation

  • Typecheck is clean.
  • These suites pass: /verify (flow, acceptance, document screen, restart, add-later, analytics), Home activation and follow-up, setup status, deposit accounts (the paperwork overlay: Bangladesh and Mali verdicts, held accounts, working rails, absent products), and i18n (including duplicate-value drift).
  • The ds-lint ratchet is at baseline. The wordiness baseline is raised for screens whose copy grew; each string says what happened and what to do next, so it stays as written.
  • Checked in the dev server at 375×812 with /verify?__fixture=paperwork-verification-de, -midpoint, -review and -verified: the steps overview, the document list and its Other-documents drawer, "Checking your ID" and "Your ID is confirmed!" match the prototype.
  • Not yet checked on a phone: APK Claim #4 from this head is being built against the kyc preview backend.
  • Fixtures: /verify?__fixture=paperwork-verification-de (city search), -br, -ar, -us, -ph, -midpoint, -review, -verified, -proof-of-address, -add-card, -add-local, -save-fails; /history?__fixture=kyc-setup-*.
  • Copy is in en, es-419, es-AR (deltas only) and pt-BR. API types are synced from peanutprotocol/peanut-api-ts#1931's openapi.json.

Activation

Keep this a draft until sandbox acceptance. Deploy peanutprotocol/peanut-api-ts#1931 first, then this UI, then publish a checked policy. No native binary or tenant change is needed.

Known limit: entry points other than Home (the QR gate, deposit gates, withdraw) still show the start drawer first, and its Verify button then opens /verify.

@innolope-dev innolope-dev self-assigned this Oct 7, 2026
@vercel

vercel Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
peanut-wallet Ready Ready Preview Oct 28, 2026 5:34am UTC

Request Review

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

🧪 UI test report — 🔴 3 failing

Suites

  • 🔴 unit: 14838 ran, 3 failed, 0 skipped, 4.1m

🔴 Failing tests

  • src/components/0_Bruddle/__tests__/conceptIconsUsage.test.ts › product concept bubbles come from CONCEPT_ICONS › every exemption still matches a call site — 0.28s
  • src/app/__tests__/ClientProviders.harness.test.tsx › fetches the reproduce manifest from the root client boundary, on any user agent — 1.01s
  • src/app/__tests__/ClientProviders.harness.test.tsx › is a no-op without the reproduce param — 0.01s

📊 Coverage (unit)

metric %
statements 86.3%
branches 78.4%
functions 80.1%
lines 87.6%
⏱ 10 slowest test cases
time test
🐢 9.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › Network failure keeps loading while retries remain, then shows the generic error
🐢 5.0s scripts/__tests__/indexable-urls.test.ts › excludes missing locale files, drafts, redirects, and retired pages from crawl and submission lists
4.4s scripts/__tests__/signup-attribution-paths.test.ts › includes newly published articles and locale fallbacks without editing the manifest
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › routes the KYC rejection on its wire code, and does not retry it
4.0s src/features/setup/__tests__/useSignupPasskey.test.tsx › opens the help drawer for NotReadableError and retries from it with one more ceremony
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_SOURCE_OVER_MONTHLY_CAP fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_MERCHANT_RECENT_REFUND fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › User KYC not approved fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › a refused idempotency key tells the user to scan again, not to contact support
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_MERCHANT_VOLUME_NEAR_CAP fails fast with copy that names the real cause
📍 Inline annotations are in the **Unit test report** check above. Coverage artifact: `coverage-unit`. Generated by `.github/workflows/tests.yml`.

@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Code-analysis diff

Painscore total: 10579.15 → 11008.03 (+428.88)
Findings: +313 net (+1354 new, -1041 resolved)

🆕 New findings (1354)

  • critical complexity — src/app/(mobile-ui)/withdraw/manteca/page.tsx — CC 264, MI 50.44, SLOC 941
  • critical complexity — src/features/paperwork-verification/PaperworkVerificationFlow.tsx — CC 250, MI 61.24, SLOC 840
  • critical complexity — src/hooks/useSumsubKycFlow.ts — CC 201, MI 47.82, SLOC 875
  • critical complexity — src/hooks/useMultiPhaseKycFlow.ts — CC 174, MI 54.77, SLOC 763
  • critical complexity — src/components/AddWithdraw/AddWithdrawCountriesList.tsx — CC 173, MI 55.9, SLOC 506
  • critical complexity — src/utils/capability-gate.ts — CC 173, MI 59.2, SLOC 435
  • critical complexity — src/features/card/useCardFlow.ts — CC 152, MI 51.58, SLOC 617
  • critical complexity — src/components/Profile/views/MoneySettings.view.tsx — CC 141, MI 58.29, SLOC 435
  • critical complexity — src/dev/surfaces/registry.tsx — CC 125, MI 68.09, SLOC 623
  • critical complexity — src/features/paperwork-verification/taxIdChecks.ts — CC 122, MI 72.98, SLOC 455
  • critical complexity — src/features/paperwork-verification/paperworkVerification.utils.ts — CC 117, MI 63.33, SLOC 298
  • critical complexity — src/components/Kyc/InitiateKycModal.tsx — CC 116, MI 48.66, SLOC 248
  • critical complexity — src/features/paperwork-verification/components/QuestionFields.tsx — CC 112, MI 63.98, SLOC 286
  • critical complexity — src/utils/friendly-error.utils.tsx — CC 108, MI 43.81, SLOC 348
  • critical complexity — src/features/withdraw/useBridgeOfframpFlow.ts — CC 107, MI 45.72, SLOC 492
  • critical complexity — src/components/Claim/Link/views/BankFlowManager.view.tsx — CC 106, MI 50.02, SLOC 475
  • critical complexity — src/features/deposit-accounts/components/DepositAccountsFlow.tsx — CC 106, MI 61.06, SLOC 203
  • critical complexity — src/utils/kyc-setup-status.utils.ts — CC 105, MI 58.72, SLOC 266
  • critical complexity — src/services/signup-geo.ts — CC 103, MI 58.01, SLOC 322
  • critical complexity — src/components/TransactionDetails/useReceiptViewModel.ts — CC 100, MI 58.41, SLOC 162

…and 1334 more.

✅ Resolved (1041)

  • src/app/(mobile-ui)/withdraw/manteca/page.tsx — CC 249, MI 50.77, SLOC 903
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx — CC 173, MI 55.88, SLOC 507
  • src/hooks/useSumsubKycFlow.ts — CC 156, MI 49.22, SLOC 677
  • src/components/Profile/views/MoneySettings.view.tsx — CC 153, MI 57.75, SLOC 483
  • src/features/card/useCardFlow.ts — CC 133, MI 50.99, SLOC 561
  • src/utils/capability-gate.ts — CC 120, MI 60.77, SLOC 305
  • src/dev/surfaces/registry.tsx — CC 119, MI 68.18, SLOC 600
  • src/hooks/useMultiPhaseKycFlow.ts — CC 118, MI 54.87, SLOC 526
  • src/utils/friendly-error.utils.tsx — CC 108, MI 43.84, SLOC 347
  • src/features/withdraw/useBridgeOfframpFlow.ts — CC 107, MI 45.89, SLOC 484
  • src/features/deposit-accounts/components/DepositAccountsFlow.tsx — CC 104, MI 61.35, SLOC 199
  • src/components/Claim/Link/views/BankFlowManager.view.tsx — CC 103, MI 48.83, SLOC 460
  • src/components/TransactionDetails/useReceiptViewModel.ts — CC 100, MI 58.42, SLOC 162
  • src/components/Global/Icons/Icon.tsx — CC 95, MI 73.15, SLOC 295
  • src/components/Kyc/InitiateKycModal.tsx — CC 84, MI 52.02, SLOC 193
  • src/services/rain.ts — CC 83, MI 58.63, SLOC 331
  • src/components/Setup/Views/SignTestTransaction.tsx — CC 79, MI 53.57, SLOC 287
  • src/context/authContext.tsx — CC 78, MI 57.62, SLOC 362
  • src/utils/support-context.ts — CC 76, MI 57.18, SLOC 202
  • src/components/AddMoney/components/MantecaAddMoney.tsx — CC 75, MI 53.93, SLOC 253

…and 1021 more.

📈 Painscore deltas (top movers)

File Before After Δ
src/features/paperwork-verification/PaperworkVerificationFlow.tsx 0.0 22.8 +22.8
src/features/paperwork-verification/paperworkVerification.utils.ts 0.0 11.9 +11.9
src/features/paperwork-verification/components/QuestionStepScreen.tsx 0.0 10.7 +10.7
src/services/signup-geo.ts 0.0 10.7 +10.7
src/features/paperwork-verification/components/QuestionFields.tsx 0.0 10.6 +10.6
src/utils/kyc-setup-status.utils.ts 0.0 10.5 +10.5
src/components/Kyc/KycSetupStatusDrawer.tsx 0.0 10.3 +10.3
src/features/paperwork-verification/taxIdChecks.ts 0.0 10.2 +10.2
src/features/paperwork-verification/components/IdentityDocumentScreen.tsx 0.0 9.9 +9.9
src/features/paperwork-verification/components/AnswerPicker.tsx 0.0 9.9 +9.9
src/features/paperwork-verification/components/StatusScreens.tsx 0.0 8.4 +8.4
src/features/paperwork-verification/components/PlaceField.tsx 0.0 8.4 +8.4
src/hooks/useGateActions.ts 0.0 8.2 +8.2
src/app/actions/kyc-paperwork-verification.ts 0.0 8.1 +8.1
src/components/Profile/views/ProfileDetails.view.tsx 0.0 7.8 +7.8
src/features/paperwork-verification/IdentityRestartFlow.tsx 0.0 7.7 +7.7
src/features/paperwork-verification/AddFeatureFlow.tsx 0.0 7.5 +7.5
src/features/paperwork-verification/useAnswerForm.ts 0.0 7.0 +7.0
src/features/paperwork-verification/components/VerifySetupPrelude.tsx 0.0 7.0 +7.0
src/features/paperwork-verification/callingCodes.ts 0.0 6.9 +6.9

# Conflicts:
#	android/app/src/main/java/me/peanut/wallet/MainActivity.java
#	ios/App/App.xcodeproj/project.pbxproj
#	ios/App/App/AppViewController.swift
#	src/context/authContext.tsx
Every KYC entry point read GET /users/kyc/plan first, and a failed read
threw out of initiate and restart. An API without the route (UI or OTA
ahead of the backend, a rollback), a 5xx or a timeout therefore blocked
verification with an untranslated "KYC request failed", and the mount
status sync silently stopped. A failed plan read now means the legacy
flow, which works while the policy is absent and is refused with a coded
answer while it is active.

Three fixes for the policy-active flow ride along:
- An approved user's feature ticks are sent only on Continue. Each tick
  ran the provider replan at once, so a mis-tap submitted the dossier to
  a provider; an unchanged Continue now just closes.
- A cross-region or country-specific entry for an approved user goes to
  the enrolment initiate performs instead of the feature picker, which
  dropped the target country.
- Closing the document list calls onManualClose like every other close,
  so drawers and modal state are released.
@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

English · Español · Español (Argentina) · Português (Brasil)

Open screen library dashboard

Review preview: fdc1307 → e89896b. Incomplete capture; unavailable states are listed in the report.

When resuming a saved document attempt failed, the hook's generic catch
put the action's English error ("KYC request failed", "Invalid KYC
verification session") on screen, inside otherwise Spanish or Portuguese
copy. Both resume paths (initiate and restart identity) now show the
localized initiate/restart failure message and release the
user-initiated guard.

The resume action also read the body with a bare response.json(), so a
non-JSON gateway error surfaced a SyntaxError message. The body read now
falls back to null and the session check tolerates it.
The backend will only require document selection first from clients
that can show the picker. Every POST /users/identity now sends
x-kyc-document-selection: 1 so this client opts in, while older
binaries keep the legacy initiate.
Every feature toggle re-plans and hands the picker a new plan object,
which reset the route to the first one and wiped the chosen document
type and issuing country. The picker now keeps the selected route while
it is still offered and keeps each choice the new plan still allows;
only switching routes starts the documents over.

The features fieldset was disabled while the re-plan ran, which dropped
keyboard and screen-reader focus from the checkbox just changed. It now
stays enabled with aria-busy and ignores changes until the plan returns.
Slava, 2026-10-27:
- "When two countries are compared in the sign up flow (for residence and
  citizenship different) the list is incorrect. Check what is shown for
  every country and make sure it's correct."
- "Brazil is showing Bank transfer (USD, EUR, GBP, MXN) while Macedonia is
  not showing the currencies, even though they are available."

Checked against the API for all 250 countries (intentAvailability, the
engine the verification applies): the comparison was wrong for 178.
- 176 countries read "Bank transfers where supported" although the bank
  feature opens USD, EUR and GBP accounts there (India, Turkey, Ukraine…).
- Brazil and Argentina listed only Pix or Argentine transfers, missing the
  bank accounts the server also opens.
- South Korea showed bank transfers the server refuses.

The comparison and the payment plan now read GET /config/kyc-intents for
the country (useKycIntents, cached an hour, no auth). With it, a country
lists its local rail when the local feature is open, Bridge's USD, EUR and
GBP accounts when the bank one is (plus MXN in Mexico, home currency first),
and the card when Rain takes it. The bundled tier lists stay as the
fallback when the read fails. Offers wait until the answer is in.

The payment plan's options follow the same answer, and "Bank transfer"
names its currencies for every residence that has it, not only next to a
Pix or ARS option.

Also fixed:
- two pt-BR strings that read "a Peanut" (glossary test);
- duplicate React keys in the payment-plan picker for Brazil and
  Argentina, where two options share the short label "Bank transfer";
- tests pinned to the old verified button and the retired-route target.
… into innolope/kyc3620-dev-merge2

# Conflicts:
#	src/components/Setup/Views/__tests__/Residence.test.tsx
#	src/components/Setup/components/ResidenceCompare.tsx
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ This PR changes CI workflows or the backdoor scan itself

The scan in tests.yml runs this PR's own workflow, so a change here could switch it off. This check stays red until the change is merged. Someone other than the author must read these files before anyone runs the branch:

  • .github/workflows/tests.yml

The plan's documentRefusals names, per ID issuing country, the features
the user asked for that a provider refuses with that ID. In the picker an
ID that closes all of them is greyed with the reason; one that closes some
says which ("The Peanut card isn't available with this document") and
asks before Sumsub opens, pointing at a document from the residence when
that one has no such limit. Copy in en, es-419 and pt-BR.
Slava could type any random number as his tax number and go on: Continue
only waited for a non-empty field (or refused an ITIN), and the API's
rejection surfaced late because the save runs behind the next screen.

The API now names, on the tax field, the stdnum validators of the
residence's tax numbers (`checks`, such as ["de.idnr"]). The tax step loads
just those validators' country modules from stdnum (1.12.6, the version the
API pins), one small chunk per country, and runs them as the user types:
Continue stays disabled until one accepts the number, and "Check the number.
It doesn't look right." shows once the number is whole, or when the field is
left part-typed. While the chunk loads Continue waits; if it cannot load,
the API's own check decides. A check this app does not know turns the live
check off rather than refusing what the API would accept.
The plan answer gained a required flow field; the mock still built it
without one, which failed the typecheck.
The plan read now types flow as required, so the one mock without it
failed the typecheck. A null flow is what the test meant: no
document-first timeline, so the setup status opens.
Slava, 2026-10-28 (item 13): a verified user who moves to a restricted
country loses the services that country restricts once the move is
approved, and is warned before confirming it.

The residence drawer compares what the server opens in the verified
residence and in the new one (GET /config/kyc-intents) and names the
services the move closes: the Peanut card, bank accounts, local bank
transfers or QR payments. The save button then reads Move anyway. A
first declaration, or a move that closes nothing, keeps the short notes
as before. The closing itself happens on the server when the move is
approved.
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ This PR changes CI workflows or the backdoor scan itself

The scan in tests.yml runs this PR's own workflow, so a change here could switch it off. This check stays red until the change is merged. Someone other than the author must read these files before anyone runs the branch:

  • .github/workflows/tests.yml

The comparison was retitled "Link your profile to one country"; the
prelude test still looked for the old heading.
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ This PR changes CI workflows or the backdoor scan itself

The scan in tests.yml runs this PR's own workflow, so a change here could switch it off. This check stays red until the change is merged. Someone other than the author must read these files before anyone runs the branch:

  • .github/workflows/tests.yml

The comparison screen's title changed with its redesign; the test pinned
the old words.
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ This PR changes CI workflows or the backdoor scan itself

The scan in tests.yml runs this PR's own workflow, so a change here could switch it off. This check stays red until the change is merged. Someone other than the author must read these files before anyone runs the branch:

  • .github/workflows/tests.yml

… into innolope/kyc-consistency-fixes-ui

# Conflicts:
#	src/features/paperwork-verification/__tests__/VerifySetupPrelude.test.tsx
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ This PR changes CI workflows or the backdoor scan itself

The scan in tests.yml runs this PR's own workflow, so a change here could switch it off. This check stays red until the change is merged. Someone other than the author must read these files before anyone runs the branch:

  • .github/workflows/tests.yml

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ This PR changes CI workflows or the backdoor scan itself

The scan in tests.yml runs this PR's own workflow, so a change here could switch it off. This check stays red until the change is merged. Someone other than the author must read these files before anyone runs the branch:

  • .github/workflows/tests.yml

This branch was successfully deployed

1 active deployment
Preview — d8cd26ba Deployed Oct 28, 2026 by vercel[bot]
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