Skip to content

feat(send): the review shows to, the amount, the privacy strip and the fee - #1797

Open
alejoamiras wants to merge 17 commits into
send-build-1-a1from
send-build-1-a2
Open

alejoamiras wants to merge 17 commits into
send-build-1-a1from
send-build-1-a2

Conversation

@alejoamiras

@alejoamiras alejoamiras commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

The review sheet's body is rebuilt as the owner picked it, then changed on page 138: To, the amount (with its dollar figure when a price is known), "This send publishes" over its three rows, the warning when the fee names your account, the fee row, then Send now. Plan: implementations-plan/send-build-1/plan.md; owner asks with what ships now: implementations-plan/send-build-1/OWNER-ASKS.md. Arc 2 of the three-arc send-build-1 stack (the form, the review, the close-out), on send-build-1-a1 (#1795). No issue is linked on pages 129, 131, 133 or 138, so this PR closes none. The title stays as first opened; the strip it names became the rows on page 138.

Changed after page 138

Each entry is quoted from the answers file the orchestrator keeps for this lane, then what shipped. Each change is its own commit.

The review's publish block (page 138's P138-01): the three "This send publishes" rows, not the strip

  • Asked: page 138 shows arc 2's review with the privacy strip (RV2's cells: You, To, Amount, each a mark and a word, heard as one sentence), built on P131-09's note and P133-05 = RV4a. Page 137 shows today's sheet with the heading "This send publishes" over three rows. The owner in chat, 2026-11-12 at about 15:20 UTC: "In general, on p137 and p138 im seeing two types of warnings for the user on the review of the send. The "this send publishes" and the one-strip preview. I like better the "This send publishes" though I know I previously said I liked the strip. What's going to be the reality?" The orchestrator proposed: keep RV4a's order (To, the amount, the publish block, the fee row) and put the three "This send publishes" rows back in the strip's slot.
  • Answer: the owner, same conversation: "Agreed." and, on recording it: "Can't you do it yourself if you already know I don't want the strip anymore?"

Shipped (plan.md D25): RV4a's order with today's heading and three rows in the strip's slot, each row in today's words and marks, read as today's sentences; the warning box under the rows, 12 px above the fee row; the rows wrap at 240 px as today's do. A hand-added sponsor's "Your address" row carries the form's sentence. PublishStrip.vue (with its test, story and type-role exceptions) is deleted: nothing mounted it once the form's strip left. Home's re-ask review mounts the same sheet and follows. No new words.

P138-02 = a (2026-11-12 15:37 UTC)

The sheet's title stays "Review". Nothing changes.

P138-03 = b (2026-11-12 15:37 UTC)

  • Asked: the review's hero amount as the token amount alone (a) or with the prototype's "≈ $43.20" beside it (b) when a price is known.
  • Answer: b, on the page, no note.

Shipped (D26): with a price known, "≈ $43.20" after the token amount (send-review-amount-fiat). It is the form's own readout: AmountCard hands out the same ≈ $ words it draws under the field (usdFigure, the live quote in token mode, the frozen quote in USD mode), so the two cannot round differently. The figure sits on the amount's baseline 8 px after it, in the prototype's meta type and secondary ink, is read right after the amount, and wraps whole under it, flush left, when the line is full. No price or no amount: the token amount alone, nothing reserved.

P138-04 = read (2026-11-12 15:38 UTC)

  • The owner's note, verbatim: "I need "b" with a picture too. can't remember."

Shipped: (a), the form's line on one line with its notes under it, as the page said. (b), the prototype's two-line row, is captured below beside (a) at the same state, not built.

P138-05 = a (2026-11-12 15:38 UTC)

The review's warning box, when the fee names your account, carries no link. Nothing changes.

P138-06 = a (2026-11-12 15:39 UTC), and its note answered (16:04 UTC)

  • Answer: a, the form's sentence, "Nulo can't tell what this FPC publishes about you.", in the review as on the form.
  • The owner's note, verbatim: "fee paying contract? Or FPC with glossary? We are assuming the user knows what an FPC is."

P138-06, the FPC wording: dot "FPC" with the existing glossary entry (2026-11-12 16:04 UTC)

  • Asked: the owner's P138-06 note ("fee paying contract? Or FPC with glossary? We are assuming the user knows what an FPC is."). The orchestrator put two ways to the owner: dot "FPC" with the glossary's existing fpc entry on the form and the review, or spell it out as the glossary writes it, "Fee Payment Contract".
  • Answer: the owner in chat, 2026-11-12 at about 16:04 UTC: ""Your P138-06 question needs one answer from you. " => dot the FPC then. your rec."

Shipped (D27): FpcSentence.vue makes the "FPC" of "Nulo can't tell what this FPC publishes about you." and of "Nulo can't tell what this FPC charges you." a dotted term keyed to the glossary's existing fpc entry (send-fpc-term), on the form (the publish line and the fee line) and the review (the "Your address" row and the fee row). No glossary entry or definition changes, and the term has no text of its own. Only the constant sentence is dotted, so a sponsor's or payee's name after it never is. A screen reader hears each sentence as before, with the glossary's definition on the term.

Dotted terms per screen (measured on the built extension): with a hand-added sponsor in effect, the form 2 and the review 2, the cap; with any other payer, 0 on each. Neither screen reaches 3, so nothing went to OWNER-ASKS.md. The answers file expected the form to dot priority-fee already (AppFeeLine.vue); it does not: AppFeeLine mounts only in the dApp windows.

What the answers leave open ships as listed in OA-19: when the fee names your account, the "Your address" row's sentence and the warning box both say so; Home's re-ask shows no dollar figure (it has no form to price it); in USD mode the figure is the sent amount priced at the frozen quote; each dotted FPC is a Tab stop.

What changed and why

  • SendReviewSheet.vue, in order: PayeeBlock ("To", the name, the whole address in two lines of 33, the check line for an address the wallet does not know), the hero amount with its dollar figure when a price is known, "This send publishes" over its three rows (today's, after page 138), the form's warning box when the fee names your account, and the fee row, label left and value right. Send now takes focus when the sheet opens.
  • One rule for the fee (RS2): the fee line's state machine moved out of SendFeeLine.vue into feeLine() and feeLineNotes() in fee-line-words.ts. send.vue hands one feeLineState to the form's line and to the review, so the two read the same words in every state: paid, sponsored, a hand-added sponsor, estimating, slow, failed, queued with and without a cap. A component test mounts both on each state and compares them.
  • The rows' words stay today's (FACT_SENTENCES, rowSentence, noticeBodyFor in publish-facts.ts); a hand-added sponsor's "Your address" row reads the form's sentence. The strip's sentence (stripSentence) and stripAriaLabel, built first, are gone with PublishStrip.vue.
  • The dollar figure comes from AmountCard as usdFigure, the words its own readout draws; the dotted FPC is FpcSentence.vue, used by the form's publish line and fee line and the review's rows and fee row.
  • Home's re-ask review mounts the same sheet with its own fee sentence and no check line (OA-15).
  • Send now is never natively disabled. While it arms, cannot send or is sending it carries aria-disabled and the base's faded look with pointer-events: none. A key or pointer press that met it refusing never sends, at its start or while held, including across a re-arm when the payer changes.
  • The fee card's unused queuedCapText model is gone; ARCHITECTURE.md and the e2e-testing skill describe the review as built.

UI impact (the owner's sign-offs, verbatim)

  • Review sheet (Send's review, and Home's re-ask review, which mounts the same sheet). Before: "Review", the amount, "to Name · head…tail", "This send publishes" over three rows with their sentences and the bridge link, "Fee · ~X FJ ($Y)" with "paid by …"; focus on the title. After: "Review", To, the amount with "≈ $43.20" beside it when a price is known, "This send publishes" over its three rows as today, the warning when the fee names your account, the fee row as the form's line, Send now focused; no edit control; a hand-added sponsor's "FPC" dotted with the glossary's entry, here and on the form. Page 138's entries, quoted above, are the sign-offs for the rows, the figure and the dot.
    • P133-05 = RV4a, "To, the amount, the privacy strip, the fee row. Every strip cell refers to something already above it, and when the fee names your account the strip's Fee payer cell sits 12 px above the warning and the fee row that cause it. 392 px. The lane's recommendation."
    • P133-07 = RS2, "One rule for one fact: the review's fee row reads exactly as the form's row under your P133-02 pick (SP1 keeps the strike there too; SP2 or SP3 drop it on both screens). P131-10 is then superseded by P133-02."
    • P131-10 (approved with the page), "The review's Fee row and the wallet's You pay row are label left, value right, on their neighbours' grid".
    • T1 and A4 for To, as signed for the form in feat(send): pay a person: the person first, the fee line pinned over review send #1795: P131-15 = T1, "A section label: "To" set as the form's other labels are, 6 px above A4's block, which is otherwise unchanged." P131-01 = A4, "No initials and no square: the name in bold, the whole address under it in two even lines of 33 with its bold start and end at the line edges; a pasted address shows no name line, only the address and the yellow check line."
  • The edit control (OA-1, answered). The owner's P133-05 note (2026-11-11 14:34 UTC): "I don't love that "EDIT" minimal button, I'd rather remove it, and let the user press the "X" if they want to edit? It looks very weird tbh. Maybe it can be below the "SEND" button, an "edit" with the same format as "use a passkey I already have" link." Asked as (a) no edit control, the X back to the form with every value kept, or (b) an "edit" link under Send now. Answer, the owner in chat, 2026-11-11 at about 14:55 UTC: "(a) on p133-05 then". Shipped: no edit control; the X (and Escape) returns to the form, which keeps every value; two Tab stops, the close and Send now.
  • After Send now: unchanged. P129-09 = D2, "Back to Home with the Sending notice, as today, so the test measures the form alone."

Owner asks this arc ships in their "what ships now" form: OA-15 (Home's re-ask review: today's sentence and payer words on the row's grid, no name line, no check line) and OA-19 (what page 138's answers leave open, above). OA-16 is answered by page 138.

Captures

After page 138

From the real popup over the local sandbox (never Testnet), 360 x 600 unless marked; every frame also exists in the other theme. The local network has no price feed; the priced frames seed the sandbox token's quote at $1.

A named payee on Nulo's sponsor, light and dark; the same review at 240 px (the rows wrap as today's do)

a2b-review-named-sponsor a2b-review-named-sponsor-dark a2b-review-240

P138-03: with a price, light and dark; a long amount at 240 px, the figure wrapped whole under it

a2b-review-priced a2b-review-priced-dark a2b-review-priced-wrap-240

Paid from private Fee Juice; paid from public Fee Juice with the warning, light and dark

a2b-review-paid-private a2b-review-paid-public-warning a2b-review-paid-public-warning-dark

A pasted address nobody has paid; a public send; the priced review at 240 px

a2b-review-pasted a2b-review-public-send a2b-review-priced-240

P138-06's dotted FPC: the form paid by a hand-added sponsor ("Mine"), light and dark; its first term focused

a2b-form-fpc a2b-form-fpc-dark a2b-form-fpc-focused

The review paid by the same sponsor, light and dark; its first term focused

a2b-review-fpc a2b-review-fpc-dark a2b-review-fpc-focused

P138-04 (b), the prototype's two-line fee row at (a)'s state ("paid public with warning" above), light and dark, cropped to the row: drawn for the owner's pick, not built

p138-04-b-light p138-04-b-dark

Measured on Chrome, the sheet's dialog: 406 px paid privately, 506 px named on the sponsor (priced or not), 539 px a public send, 558 px pasted (the check line), 545 px with the warning, 441 px on a hand-added sponsor. Tab stops: the close and Send now in every state but the hand-added sponsor's, which adds its two dotted terms (four). With the rows back the sheet is taller than as first built (309 to 384 px) and than the prototype's RV4a (392 and 410 px); at 360 x 600 it still fits without scrolling.

As first built (superseded on page 138: the strip in place of the rows)

A named payee on Nulo's sponsor, light and dark; the same review at 240 px

a2-review-named-sponsor a2-review-named-sponsor-dark a2-review-240

Paid from private Fee Juice; paid from public Fee Juice, with the warning, light and dark

a2-review-paid-private a2-review-paid-public-warning a2-review-paid-public-warning-dark

A pasted address nobody has paid (its check line); a public send; Send now while it arms

a2-review-pasted a2-review-public-send a2-review-arming

Queued behind an earlier send (Queue send); Home's re-ask review, light and dark (the earlier send's toast closed first, #1796)

a2-review-queued-cap a2-home-reask-review a2-home-reask-review-dark

Home right after Send now (unchanged, D2); dark at 240 px; dark, Send now while it arms

a2-home-after-send a2-review-240-dark a2-review-arming-dark

As first built, measured on Chrome: the sheet's dialog was 309 px paid privately, 326 px sponsored (named or public), 345 px pasted (the check line) and 384 px with the warning; the prototype's RV4a drew 392 and 410 px, with "≈ $43.20" beside the amount and the method on a second line. Tab stops in every state: the close and Send now (three while the fee's Try again shows).

Accessibility calls (under the 2026-10-19 delegation)

  • Send now takes focus on opening (Popup's initial-focus) and is never natively disabled, so focus survives the arm and every change of state; aria-disabled announces the refusal, the press guards enforce it.
  • A press that met Send now refusing never sends: a repeat Enter or Space is refused; Space and a pointer click at their release, so a press begun before the arm, or held across a re-arm (a payer change in another window), is cancelled. Probed in Chrome and Firefox 158 on a plain page: an unguarded button clicks on the carried release; the guarded one does not, and a fresh Space or Enter still sends.
  • No document-level Enter: Send now is the keyboard path.
  • The rows are read as today's sentences, each row's name, word and sentence in order; the dollar figure is read right after the amount.
  • Each dotted FPC is a Tab stop described by the glossary's definition, as every dotted term is; a review paid by a hand-added sponsor has four stops (the close, the two terms, Send now).
  • Try again, when it replaces itself with the estimate it started, hands the keyboard to Send now.

Testids

  • Kept: send-review-sheet, send-review-amount, send-review-fee, send-review-fee-cap, send-review-fee-queued, send-review-fee-slow, send-review-fee-retry, send-review-fee-reask, send-review-submit; the payee block's send-payee* (the review's sits in #popup, so the fixtures scope the form's to send-page).
  • Restored after page 138: send-review-row-you, send-review-row-to, send-review-row-amount (data-visibility; the "Your address" row also data-notice-shape). The specs that had moved to the strip moved back: fixtures/send-page.ts readReview reads the rows again, and fee-methods, send-amount-exact and same-token-concurrent-sends read the review through it. No smoke spec opens the review, before or after.
  • New: send-review (the dialog), send-review-warning (data-notice-shape), send-review-fee-value, send-review-amount-fiat, send-fpc-term.
  • Retired, with the specs that moved: send-review-recipient and send-review-recipient-address (the type-roles inventory), send-fee-privacy-remedy in the review (fixtures/send-page.ts, fee-methods; the form's warning keeps its fix). send-review-strip{,-spoken} and send-review-unvouched, added as first built, are gone and never shipped.

Validation

Every run at retry 0 on 0b4170356, the last code commit (the commits after it are plan notes and the captures), on a shared host at load 45 to 95 on 188 cores.

  • Static: bun run lint, bun run typecheck:all, bun run test:all (extension 18,421 passed), bun run check:plans, bun run test:ci-gating (755 pass), build-storybook: green.
  • Smoke, full suite: Chrome 290 passed, Firefox 295 passed, 0 red.
  • Network, the 24 specs the send fixtures reach (every one that opens the review through submitSend or readReview, plus the plan's three concurrent-sendtx specs): Firefox 62 passed, 0 red. Chrome 60 passed and 2 red, both in type-roles-windows: the per-test fixture timed out opening the playground page (connectPlayground:openPlayground, 30 s) before "the capabilities window holds its roles" ran, and "every identifier site the network suite owns was read in its role" then listed only that window's six sites. This round touches neither the playground nor the capabilities window; that file, rerun alone once, went 6 of 6. The three opt-in specs (send-chaos, store-captures, stale-network-a10-capture) ran armed on Chrome: 3/3.
  • Unit and component tests for this round's changes: the review's rows on wire-shaped fixtures (a named payee on the sponsor, paid private, paid public with the warning, a pasted address, a public send, a hand-added sponsor) and the order of the sheet's parts; the dollar figure beside the amount and absent without a price; on the page, the review's figure equal to the form's readout on the real amount card and none before a quote; AmountCard's figure in token and USD mode; FpcSentence (the dotted word, a name after the sentence never dotted, other text plain, the glossary's definition); the dotted terms counted on the form and the review with a hand-added sponsor, two each.
  • No review loop ran on this round's a2 changes: the round's brief asked for the build, the gates and the captures.
Suite, retry 0 Chrome Firefox
Smoke, before (a2 as first built) 1714 s 2795 s
Smoke, after 1991 s 3019 s
Network, the 24 specs, before 2225 s 2593 s
Network, the 24 specs, after 2353 s (plus the 296 s rerun) 2665 s

The suites' content barely moved (the rows replace the strip; no scenario was added), so the rises track the host's load.

No e2e scenario is added or changed in this round: readReview reads the rows again, and the dotted terms and the figure are proven in component and page tests; the captures read both on the built extension.

Found on the way and filed: #1796 (an in-flight send's toast sits over the review's fee row; it predates this arc).

🤖 Generated with Claude Code

@alejoamiras
alejoamiras added this pull request to stack #1798 November 12, 2026 04:18
@alejoamiras alejoamiras changed the title send build 1 a2 feat(send): the review shows to, the amount, the privacy strip and the fee Nov 12, 2026
@alejoamiras
alejoamiras marked this pull request as ready for review November 12, 2026 04:18
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
nulo-landing 6d8c94f Commit Preview URL

Branch Preview URL
Nov 13 2026, 12:28 AM

@github-actions

github-actions Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Extension preview build — 6d8c94f

Version 1.2.0-pr.1797 · workflow run · artifacts expire after 7 days.

Load it
  1. Download and unzip (GitHub wraps the dist/ folder in a zip).
  2. Chrome: chrome://extensions → Developer mode → Load unpacked → pick the unzipped folder.
    Firefox: about:debugging#/runtime/this-firefox → Load Temporary Add-on… → pick manifest.json.

alejoamiras and others added 17 commits November 12, 2026 20:57
…e fee

The review sheet follows RV4a: the payee block, the amount, the privacy
strip heard as one sentence, the warning when the fee names the account,
and the fee row reading the form's line through one shared rule. Send now
takes focus and stays focusable while it arms. No edit control: the close
returns to the form with every value kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`readReview` reads the strip's cells, the warning and whether Send now
refuses a press; the form's payee is read inside the page, since the review
draws its own. The warned send's review is checked to open on Send now,
refuse a press until armed, hold two Tab stops and send by Enter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Space clicks at its release, so a press started while Send now refused
would send once the sheet armed. Such a press is now refused at keydown
and at keyup, and a held key's repeats never start one. The fee line's
notes come from one rule beside `feeLine`, the hand-added sponsor's
sentence is no longer heard twice, the card's unused cap model is gone,
and ARCHITECTURE and the e2e-testing skill describe the review as built.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Space and a pointer click at their release, so a press begun while Send
now was armed, held while the payer changed and released after the
sheet armed again sent what it never saw. The sheet keeps one press
record from keydown or pointerdown, marks it refused whenever Send now
stops being sendable, and the click reads it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Enter acts at its keydown, so a refused Enter's record no longer waits
for the next press and cannot refuse a later click-only activation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e strip

The owner preferred today's heading "This send publishes" over its three
rows to the strip (page 138). The rows return in the strip's slot, in RV4a's
order: To, the amount, the rows, the form's warning when the fee names the
account, then the fee row. Each row keeps today's words, marks and
`send-review-row-{you,to,amount}` testids and is heard as today's sentence;
a hand-added sponsor's "Your address" row carries the form's sentence. The
review's bridge link stays gone (P138-05 = a).

`PublishStrip`, unmounted since the form's strip left, is deleted with its
type-role exceptions; the review's fixture, page tests, ARCHITECTURE and the
e2e skill read the rows, and the skill's fee paragraphs read the radios.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
P138-03 = b: with a price known, the review's hero reads the token amount
then "≈ $43.20" in the prototype's form, the very figure the form's readout
shows: `AmountCard` hands its own `≈ $` words out as `usdFigure`, priced at
the live quote in token mode and at the frozen quote in USD mode, so no
second rounding rule exists. The figure sits on the amount's baseline, is
heard after it, and wraps whole under it, flush left, when the line is full.
No price, no amount: the token amount alone, nothing reserved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ary's entry

The owner, on P138-06's note (2026-11-12 16:04 UTC): "dot the FPC then".
`FpcSentence` prints a line and, when it opens with "Nulo can't tell what
this FPC publishes about you." or "Nulo can't tell what this FPC charges
you.", makes that sentence's "FPC" a `DottedTerm` keyed to the existing
`fpc` entry; only the constant is dotted, so a name after it never is. The
form's publish line and fee line, and the review's "Your address" row and
fee row, print through it. A screen reader hears each sentence as before,
the term described by the glossary's definition.

Dotted terms per screen with a hand-added sponsor in effect: the form two,
the review two, the cap; none elsewhere on either.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OA-16 is answered with page 138's entries quoted; the publish block's
reversal gets its own section; the ledger gains D25 (the rows back),
D26 (the hero's dollar figure) and D27 (the dotted FPC, with the counts per
screen), and D18, D19, D20 and the review's UI impact line follow. OA-19
lists what the answers leave open, each with what ships now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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