Capxul #934 — S14 payroll screen on CapxulPayroll + CapxulPayrollRun

Infrastructure #1629 / #1631. Dev server of branch codex/1629-payroll-s14-refit (head 4170314d) merged locally with dev @ a3e9db53 (Capxul #945, @capxul/sdk@2.5.4) on http://localhost:3100 against Railway staging, embedded Openfort signer (no dev seed). Driven by apps/web/tests/e2e/payroll-s14.spec.ts with PAYROLL_PROOF_SEND=true (Playwright, headed Chromium, trace on). Desktop 1440×900 and mobile 390×844 per frame. E-mail echoes masked in-page. Every frame was inspected; findings are written under each frame.

ItemValue
Staging Site / APIconvex-site-production-29eb.up.railway.app / convex-backend-production-f220.up.railway.app, backend head c1b9f62b; AA gateway deployment 07195ae8 (integration/capabilities be6e311e) at send time
Packages@capxul/sdk@2.5.4, @capxul/sdk-react@2.5.4 (signer readiness #1695, personal-payment guard #1705)
Organizationorg_01M1GPHHE5NB07H2F1RF21V8M5 ("Payroll Run mtjvu7rh"), created through the product on 2026-09-02 09:17:45Z by a reserved-lane owner with the embedded signer; treasury Safe 0xcedba816…11cd9 funded 10,000 USDX by the operator faucet (tx 0xe33d5337…2e2d); two payees invited and on the roster (pending role grant, which the address book admits)
Runpayroll_run_d5b498f0…aa8fde created 2026-09-02 09:21:59Z; two payments rows purposeKind: payroll, 1.000000 USDX each
ChainuserOp 0x1c83feeb…46c8 bundled in tx 0x47d833e9…b635, status 0x1, block 0x2c245ef, 2 ERC-20 Transfer logs; balances after: payee Safes 0x06f213d7… and 0xccc66e02… 1.000000 each, treasury 9,998.000000 (evidence RPC read)
Payslipstwo paymentDocuments rows kind: payslip, hashes 0xfb3dc181…, 0x8cef246f…, issued 09:21:59Z (no payslip screen exists in Capxul; document-level proof only)
Settlement readbackrun settled and both payments settled at 09:47:37Z; the payment command needed 7 verification attempts (retry_wait backoff, ~26 min after chain inclusion at 09:22:04Z). Frames 8 and 9 show the screens after settlement.
Earlier attempt08:51Z on org_01M1FP6X… (the 9/1 runner): confirm enabled, but payroll/actions:authorizeRun rejected with Invalid signerAddress: does not match the authenticated Account signer — that owner had been onboarded on 9/1 while the dev signer seed was on, so its Account signer is the dev key. Proof-lane hazard, not a #934 defect. Observation for the app: the sheet showed no failure state at +120 s after that rejection (whether the transient "Payroll not sent" toast fired is unverified).

1. Payroll page (fresh organization)

1. Payroll page (fresh organization), desktop1. Payroll page (fresh organization), mobile

Shows: "Wallet Balance 10,000 USD · Funds Available" and "Paid This Month 0 USD" from CapxulPayroll.Summary; "Active Streams" and "Scheduled Payroll" on their frozen "Not available yet" (STREAMS); three action cards; "Ongoing Payrolls" empty state "Payroll schedules: Not available yet · Use Pay now" (row 14.11, frozen); "Payroll Groups" with only "Create Group". Mobile: same values, cards stacked; the bottom tab bar covers the top of the "Pay now" card until the page scrolls (mobile shell, pre-existing).
Defects: none.

2. Create payroll group sheet

2. Create payroll group sheet, desktop2. Create payroll group sheet, mobile

Shows: group name, colour, both payees selected from the live roster, 1 USD each, "Recipients 2 People · Total default payout 2 USD". Roster labels are the member mailboxes (masked here) because the party has no display name yet (infrastructure #1651); the "Full-time" badge is the frozen placeholder pending Aaron's ruling. Mobile: full-height sheet, both actions reachable.
Defects: none new.

3. Group card after save

3. Group card after save, desktop3. Group card after save, mobile

Shows: "Proof group … · 2 members · 2 USD/payroll · Manage" from CapxulPayroll.Groups, toast "Payroll group created". Mobile: the toast renders bottom-left over the tab bar and is partly hidden by it (also by the Next.js dev badge, dev-only). Defect (pre-existing, app-wide toast placement on mobile, not introduced by #934): toast overlaps the bottom navigation.

4. Pay-now sheet — confirm enabled

4. Pay-now sheet — confirm enabled, desktop4. Pay-now sheet — confirm enabled, mobile

Shows: two recipients at 1 USD, Token "USDC (Base) - 10,000 USD" (label frozen, value from .Asset), "Recipients 2 People · Total payout 2 USD · Platform fee $0.00 (Free tier - 1% /month) · Total deducted 2 USD · Balance after 9,998 USD", the onchain notice, and "Confirm & Send" enabled: the embedded signer reached ready on a fresh session, which is @capxul/sdk@2.5.4 (infrastructure #1695) working in the browser. Mobile: same, sticky footer.
Defects: none.

5. Payroll sent

5. Payroll sent, desktop5. Payroll sent, mobile

Shows: after one double-click on Confirm & Send (the engine's submit gate sends exactly one run): sheet closed, toast "Payroll sent", group still listed, balance still 10,000 USD at this instant (the summary refetches on the next frame). Mobile: toast clipped by the tab bar ("…ll sent"), same pre-existing placement defect as frame 3.
Defects: none new.

6. Group deleted — balance after the run

6. Group deleted — balance after the run, desktop6. Group deleted — balance after the run, mobile

Shows: "Wallet Balance 9,998 USD" (2 USD left the treasury), "Paid This Month 0 USD" because the counter sums settled runs and the run was still authorized / payments settling at capture (see the readback table), groups empty after "Delete group". Mobile: same values.
Defects: none.

7. Dashboard after the run (desktop, supplementary)

Dashboard after the run, desktop

Shows: "Total Account Balance 9,998 USDX", assets row 9,998 USDX, and "Recent Transaction: USD −$1.00 · Payment activity · Bob Payroll · Sep 2, 9:21 AM" (the ACTIVITY feed, Capxul #937 territory). "Upcoming Payroll 0 Active · No Upcoming Payroll" is expected (schedules frozen). Not a screen #934 changes; included as the second read of the money movement. Observation: the dashboard "Send Payroll" button renders muted; not exercised here.

8. Payroll page after settlement (desktop)

Payroll page after settlement, desktop

Shows: "Paid This Month 2 USD · Organization payments" now counts the settled run from CapxulPayroll.Summary; "Wallet Balance 9,998 USD"; groups empty. Captured at 09:49Z through payroll-see-all.spec.ts (desktop only; the mobile frame of this state is frame 6).
Defects: none.

9. Dashboard after settlement (desktop, supplementary)

Dashboard after settlement, desktop

Shows: the Recent Transaction row for the payroll payment now offers "Receipt ↓" where it read "Not available" before settlement; balances unchanged at 9,998 USDX. Not a screen this PR changes.

10. Recording