Prepared for the Product Designer role at Lendable

Product design, with the decisions shown.

Three product ideas with their flows, edge states and decisions, built on a process that keeps its evidence.

Discovery question bank
76entries
Build-check groups in CI
51groups

Three ideas for the Zable app

Built from Lendable’s public site only. Not Lendable work, and every figure is a placeholder. No research was run, so each research question is something to test.

First statement on a credit-building card

Illustrative. Placeholder figures (£480 balance, 2.5% a month). Not a Lendable product or quote.

Screen 1 of 5

Your first statement

£480.00

Balance to pay. Due 28 Nov. Card limit £1,000.

You can pay all of it, some of it, or the minimum. Next screen shows what each costs.

Choose how to pay

Three ways to pay £480.00. None is chosen for you.

What helps a limit grow

Lenders decide limits their own way, so none of this is a promise.

  • Paying at least the minimum, on time, each month.
  • Keeping the balance well under the limit.
  • Not applying for lots of credit close together.
  • Time. Longer-held accounts tend to count for more.

We review limits from time to time. We can’t say when, or by how much.

Your bank declined this payment

Nothing was taken. Your due date is still 28 Nov, so there is time.

Your choice is saved, so you will not retype it.

Tell us now and we will look at options

This is common, and it is better to say before the due date than after. There is no form to fill in first.

  • Talk to a person about this month.
  • Free, independent money advice is available from MoneyHelper.

Which options exist is a policy decision, left blank in this sketch.

Need Pay my first bill without paying more than I meant to.

Research would ask Do people choose after seeing each option's cost in pounds and time?

Flow map You are at: Statement
  1. Statement back here from 2, 3 and 5
    • Choose how to pay
    • I can’t pay this month
    • What helps my limit grow
  2. Choose how to pay full, minimum or other
    • Paid: What helps a limit grow
    • Bank declines: Payment declined
    • None, or no amount: asks again
  3. What helps a limit grow
    • Start again: Statement
  4. Payment declined
    • Try again: Choose how to pay
    • Talk about paying: Can’t pay
  5. Can’t pay this month
  6. Talk to a person not built

Screen 2

Decision
Three equal payment options, costs in pounds and months, none selected.
Because
A pre-selected minimum quietly costs more.
Rejected
Minimum by default, full payment as a link.
Would measure
Share of customers who can say what their choice costs.

Screen 4

Decision
Decline says nothing was taken and the due date stands.
Because
A failed payment feels personal; certainty calms it.
Rejected
A generic “Something went wrong” banner.
Would measure
Declined payments followed by a successful one within 48 hours.
Third decision: screens 1 and 5

Screens 1 and 5

Decision
Statement offers “I can’t pay this month”, routing to a person.
Because
Asking is easier before a payment is missed.
Rejected
Settings menu behind a contact form.
Would measure
Share of customers who reach out before the due date.

Consolidate card balances

Illustrative. All figures are placeholders, not a Lendable offer.

Screen 1 of 5

Which balances do you want to clear?

Card rate 24.9% APR
Card rate 29.9% APR
Card rate 21.9% APR

Total to clear: £5,400

Need. Would one loan leave me better off, in pounds and months?

Flow map You are at: Balances
  1. Balances
    • Outside the limits: says why, stays
  2. Your rate soft search
    • Full offer: on to Comparison
    • Partial offer: continue, or change the amounts
    • No quote: try again, change the amounts or keep paying
  3. Comparison says if it costs more
    • Term: pick one, back to Comparison
  4. After payout
    • Go ahead: nothing is sent
    • Keep paying as now: nothing changes
    • Start again: back to Balances

To test. When the loan costs more, do people still find the comparison fair? No research run.

Decision
Show keeping the cards beside the loan; say plainly when the loan costs more.
Because
A lower payment can hide a higher total.
Rejected
Showing only the monthly saving.
Would measure
Share who correctly name the cheaper option.
Decision
Show each term’s payment and total side by side, none marked best.
Because
Only the person knows what monthly payment fits.
Rejected
Defaulting to the longest term.
Would measure
Share who can say what a shorter term changes.
Third decision
Decision
List what happens to the cards, with no advice to close or keep.
Because
Both choices have consequences that depend on the person.
Rejected
Copy urging closure.
Would measure
Share who know cards stay open unless closed.

One app, two products, a hard month

Illustrative placeholders. Not Lendable or Zable policy. Designed with Consumer Duty in mind.

Step 1 of 6

Your accounts

  • Card ending 0000Balance £1,200
  • Loan ending 0000Balance £4,800

Your payments this month

  • Card minimum, due 14 Oct£45
  • Loan, due 20 Oct£210
  • Together£255

No reason needed. Nothing changes until you choose.

Your options

Pick per product. Nothing is pre-selected.

Card, £45 due 14 Oct
Loan, £210 due 20 Oct

Payment break: not offered on this loan.

Nothing chosen yet.

Tell us more, if you want to

Optional. If you share, the person who calls sees it first, so you do not repeat it. Options and prices stay the same. Skipping loses nothing.

Anything that applies

Request received

The Support team will phone you by 5pm on Monday 6 Oct.

A person, not a message. They agree your choices with you first. Until then nothing changes.

    Talk to someone

    One person can help with both products.

    • Phone us0000 000 0000
    • Open8am to 8pm daily

    User need See what is due, what each choice costs and who can help, without explaining myself first.

    Flow map You are at: Home
    1. Home
    2. Own words optional
      • Sure: What we understood
      • Unsure: one question first
      • Skip: Both payments, original order
      • Model slow or down: original order, no message
    3. One question if unsure
    4. What we understood change it here
    5. Both payments
    6. Options
      • One or both chosen: continue
      • None chosen: asks again
      • Change: back to What we understood
    7. Share optional, share or skip
    8. Confirm
      • Change my choices: back to Options
      • Start again: back to Home
    9. Talk to someone from every screen

    To test Do both payments and costs on one screen help, or is it too much at once?

    1. Entry point

      Decision
      A visible “I’m finding payments hard” button on home. No reason asked.
      Because
      A question before help is a hurdle.
      Rejected
      Burying it under Help and settings.
      Would measure
      Taps on it that reach a confirmation.
    2. Options

      Decision
      Price each option per product. Nothing pre-selected. “Do nothing” shows its consequence.
      Because
      Doing nothing becomes a choice made knowingly.
      Rejected
      One blended plan across both products.
      Would measure
      Share reaching confirmation with a choice for both products.
    One more decision
    1. Disclosure and a person

      Decision
      Optional disclosure that says what it changes. A person reachable from every screen.
      Because
      Skipping costs nothing; no path dead-ends.
      Rejected
      A required form first.
      Would measure
      Call-backs made inside the promised window.
    Own words: four rules
    1. Ask, don’t guess

      Decision
      Below 60% on what changed or how long, ask one question instead.
      Because
      Jev, a typed decision model from TypeSafe, returns a probability for each declared answer. A low one is a reason to ask.
      Rejected
      Acting on the top answer whatever its probability.
      Would measure
      Corrections made after a confident read.
    2. Support brings people forward

      Decision
      A support signal puts the named team first on the options screen. It never removes or blocks an option.
      Because
      A signal is a probability, not a fact. The choice stays with the person.
      Rejected
      Sending them to a call instead of their options.
      Would measure
      Call-backs after the signal, and options still chosen.
    3. Show what we understood

      Decision
      One plain line per answer, how sure in words, and “Not right? Change it”. Numbers only on request.
      Because
      People can only correct what they can see.
      Rejected
      Reordering silently.
      Would measure
      Answers changed by hand.
    4. Fail quietly

      Decision
      No answer within 3 seconds, or any error: the usual order, no message.
      Because
      Own words are a shortcut, not a gate.
      Rejected
      An error screen or a retry loop.
      Would measure
      Fallback rate and time to options.

    How I work, behind the product.

    ux-factory runs the design process and commits the evidence: the questions asked, the answers given, the agent runs and the checks that passed. Decisions are recorded first, and the build reads them.

    I build with AI agents in a PIV loop: plan, implement, validate. Each change starts as a written plan that I approve. Agents implement it, often several in parallel, and every change then runs the same checks. What fails becomes a rule for the next loop. Agents write most of the code; I make the product decisions. This page was built that way.

    1. PlanBrief, context, a written planI approve
    2. ImplementAgents build to the planAgents
    3. ValidateTests, accessibility, reviewChecks, then me
    4. LearnFailures become rulesNext loop
    The PIV loop. Each pass ends with a rule the next one starts from.

    One brief moves through four stations.

    In: a product brief. Out: a public replay a reader can check.

    Solid is shipped, outlined is in progress. Choose a station to see what goes in and comes out.

    Show as text

    Status as of 3 October 2026.

    1. Decide Shipped

      In
      A product brief and the person who owns it.
      What happens
      A scripted, attributed question bank (76 entries, stages 1 to 9, a 12-question opening set and five facet modules) runs as a live agent session in the portal. The agent judges each answer against that question’s own weak-answer note. Every op is one tool call into an applier.
      Out
      A generated PRD: every decision names its evidence and its kill criterion.
      • Shipped Discovery partner, epic #279, closed 14 September 2026
      • In progress PRD fidelity: from complete-looking to buildable (epic #504)
    2. Build In progress

      In
      The PRD and its run package.
      What happens
      A free canvas: real components under the brand pack on real screens, states as base plus overrides, the flow as recorded connections. The agent composes only within the validated vocabulary and proposes the rest for the owner to ratify. A refusal is visible, never a silent fallback.
      Out
      Screens, their states and the flow between them.
      • Shipped Free canvas in place of the grid
      • Shipped Generic primitives: stack, text, list, icon, choice
      • Shipped Import from Brilliant and Figma
      • Shipped Compose loop, ratify, and a ledger of what the agent did, refused and corrected
      • In progress Run 1: Faster Payment built from its PRD (#316), then close-out

      Epic #295, open.

    3. Hand off Partly shipped

      In
      The built screens, states and flow.
      What happens
      A pack is generated, never edited by hand: ComponentSpec and DataContract from one source, token targets for CSS, iOS and Android, the agent vocabulary, Web Component wrappers and the Figma import path.
      Out
      An engineer-ready handoff pack.
      • Shipped The pack, with an llms.txt routing index
      • In progress Backend seam: bindings, one command contract, a conformance check (epic #329, six open slices)
    4. Show Shipped

      In
      The pack and the committed agent runs.
      What happens
      The public site replays committed runs: two data-connected prototypes with agentic slots (ask, propose, adjust), the component catalogue, traces and gates. A company brief compiles to a private, unlisted instance under that company’s derived pack.
      Out
      A public replay a reader can check step by step.
      • In progress Trace player marks what the agent said against what it did (#496)

    The shared spine, under all four

    • Token contract. One DTCG source generates the CSS; a re-skin is one line in the head.
    • Gates. Build checks, generator drift, token lint, a pixel gate and CodeQL run in CI on every change.
    • Recorded traces. Agents run at build time and are replayed at view time, labelled “real run, curated”.

    Evidence: epics #279, #295 and #329, read on 3 October 2026.

    Decide and Show shipped, Hand off partly, Build in progress

    Questions turn the brief into a PRD.

    In: a product brief. Out: a PRD where every decision names its evidence.

    The brief meets the question bank: 76 entries across nine stages.

    Show as text

    Status as of 3 October 2026.

    1. Question bank Shipped

      76 entries over nine stages: 65 from the source research, plus 11 added (four non-functional, six on AI interaction, one on scope parked for later). Each carries a source method, a provenance label (observed, derived or thin) and a weak-answer note.

      1. Problem framing6
      2. Demand and evidence7
      3. Market, wedge and strategy6
      4. Solution shape and scoping12
      5. Business model, especially SaaS8
      6. Complex, regulated and workflow-heavy products8
      7. Measurement and kill criteria7
      8. AI-era questions18
      9. The famous killer questions, with provenance checked4

      A session asks a selection, never the whole bank: scope check 6, opening set 12, full discovery up to 31.

    2. Live agent session Shipped

      The agent judges the form of each answer against the weak-answer note, never its substance; it may not say an answer is wrong. A weak answer gets one more ask, and the second answer closes the question.

      Each op is one tool call: record_decision, flag_weak_answer, open_question, file_evidence. A decision op has no field for answer text; only the server writes answers, verbatim.

    3. Generated PRD Shipped

      A pure fold of the recorded ops: the same run gives the same page. Every decision names its evidence or is flagged no evidence. Every decision states its kill criterion, wrong_if; the applier refuses one without it.

      In progress Epic #504: grading 11 committed PRDs on 22 criteria found no decision log, acceptance criteria or sign-off line in any. Being added.

    4. Requirements hierarchy Shipped

      Each decision is filed at one level and names the decision above it that it serves. No parent means orphan. Levels come from BABOK.

      Business
      What and why. No parent.
      Stakeholder
      What a person can do. Serves Business.
      Solution
      Functional and non-functional. Serves Stakeholder.
      Transition
      Getting from today to there. Serves Solution.
    5. Feeds the Build station In progress

      A screen on the canvas cites the decisions it answers, by ledger number. Open: one real flow built from its PRD (#316); links from decisions forward to screens (#514).

    One question worked through: Rate path Illustrative

    Built from Lendable’s public site only; not Lendable work. The question and its weak-answer note are real bank entries; the answers, follow-up and decision are written for this page.

    Question
    “What would this metric look like if we were gaming it, and what counter-metric would catch that?” Stage 7, derived, standard in the North Star literature as guardrails. Weak-answer note: no counter-metric. Every engagement metric has a degenerate maximum, usually notifications.
    Weak answer
    “We track how many people opt in to the later re-quote. If that goes up, Rate path is working.”
    Follow-up
    “The answer names one metric and no counter-metric. Opt-ins would also rise if the screen talked people out of borrowing now. What would you see if that were happening, and which number would catch it?” Op: flag_weak_answer, missing: a counter-metric; what gaming the metric would look like.
    Stronger answer
    “Gaming it would look like opt-ins going up while people who opt in never come back for the re-quote. That would mean we delayed them rather than helped them. So the counter-metrics are two. Among Fair and Limited quotes, the share choosing borrow now should not drop against the screen without Rate path. And people who opt in should reach a re-quote and see their band hold or improve.”
    Level
    Solution, serving the stakeholder decision “an applicant quoted in the Fair or Limited band can compare borrowing now with waiting, in pounds, and choose either”.
    Evidence
    None filed yet, so the page flags it no evidence. The session would ask for quote-to-offer-to-drawdown by band.
    Wrong if
    At the first read after launch, opt-ins have risen while borrow-now choices among Fair and Limited quotes have fallen, or most people who opted in never reached a re-quote.

    Evidence: epic #279 closed on 14 September 2026; #504 is open.

    Shipped, follow-on open

    Every surface reads one token contract.

    In: one DTCG token source. Out: token targets for CSS, iOS and Android.

    Handoff. One token source generates CSS, iOS and Android tokens, with mobile still in progress. CI fails the build on any drift.

    Show as text

    For a design team: an off-brand value or drifted token is flagged by a gate, not spotted by eye.

    Three layers, loaded in order

    1. The contract

      tokens.contract.css

      Every semantic token, each with a neutral fallback. No brand.

      Shipped
    2. A brand pack

      tokens.neutral.css · tokens.verdant.css · tokens.saulera.css

      Primitives bound to the semantic names. A re-skin is one <link> line.

      Shipped
    3. Token-only components

      components.css

      No literals. Token lint in CI fails any token the contract does not declare.

      Shipped
    Primitive behind each token, in two token sets
    Semantic tokenThis page's packInverse setRead by
    --color-bg-surfaceln-cardln-inkCard, Link, Chip
    --color-fgln-inkln-paperCard, Chip
    --color-fg-mutedln-greyln-paper at 62%Card
    --color-borderln-sandln-paper at 14%Card, Chip
    --color-accentln-orangeln-orangeCard, Chip
    --color-accent-secondaryln-peacockln-orangeLink

    Every token is generated into the CSS, iOS and Android outputs. Illustrative components, built for this page.

    Same component, two token sets

    Same markup and CSS. Only the wrapper's bindings differ.

    This page's pack

    Agreement

    Monthly repayment

    £214.60

    Next due 14 November

    Inverse set, six overrides

    Agreement

    Monthly repayment

    £214.60

    Next due 14 November

    .scope--inverse {
      --color-bg-surface: var(--color-bg-inverse);
      --color-fg:         var(--color-fg-on-inverse);
      --color-fg-muted:   var(--color-fg-on-inverse-muted);
      --color-border:     var(--color-inverse-line);
      /* …two more, all token to token */
    }

    Illustrative card and figures, built for this page.

    One source, generated targets

    1. DTCG token source, the source of truth

      system/tokens.source.json

      W3C Design Tokens format. New tokens enter here first.

      Shipped
    2. Generators: gen-token-css · gen-handoff · gen-vocabulary

      agent-layer/*.mjs, with Style Dictionary for the platform builds

      Drift-check gate. CI regenerates every output and compares it with what is committed. Any difference fails the build.

      Shipped
    3. The handoff pack, never edited by hand

      Generated and committed today. Six open slices remain. Partly shipped

    • CSS tokens

      tokens/css/contract.css · neutral.css Shipped
    • iOS and Android tokens

      FactoryTokens.swift · tokens.xml

      Generated today. Spec-matching names, contract group and type tokens are an open slice.

      In progress
    • ComponentSpec

      pack.json, from system/specs/*.md Shipped
    • DataContract

      contracts/*.contract.json · JSON Schema Shipped
    • Agent vocabulary

      vocabulary.json

      The only parts an agent may compose with.

      Shipped
    • Web Component wrappers

      wc/vd-*.mjs

      Shadow DOM, styled only by declared tokens. Three data-bound components so far.

      Shipped
    • Routing index

      llms.txt

      One line per pack file. Generated and gated.

      Shipped
    • Shipped component CSS and data bindings

      components.css · bindings · one command contract

      Lets an engineer wire a real service to the pack. Open slices.

      In progress
    • Figma import path

      figma-import.md · tokens.dtcg.json

      Four import routes documented. Parity run against a real Figma file has not landed.

      In progress

    Evidence: the token contract and handoff pack in the repo.

    Partly shipped

    Agents propose. The owner decides.

    In: the owner’s brief. Out: a committed trace the public site replays.

    An illustration, not a recorded trace. Owner writes the brief: the problem, never the answer.

    Show as text

    Agents at build time, replayed at view time. The public site only reads committed files.

    The run, step by step

    An illustration, not a recorded trace. The validator refuses; the owner decides. Both are recorded.

    1. Owner writes the brief. The problem, never the answer.
    2. Agent proposes op 1. A verb from the vocabulary.
    3. Validator accepts op 1. It is committed.
    4. Agent proposes op 2. A verb outside the vocabulary.
    5. Validator refuses op 2, by name. No silent fallback.
    6. Owner decides on op 2. Ratify it into the vocabulary, or keep the refusal.
    7. Agent proposes op 3. A verb from the vocabulary.
    8. Validator accepts op 3. It is committed.
    9. Agent proposes op 4. Another verb outside the vocabulary.
    10. Validator refuses op 4, by name. Outside the vocabulary.
    11. Owner decides on op 4. Ratify it, or keep the refusal.
    12. Ledger records the run. What the agent did, refused and corrected stays readable.
    13. Trace committed. The public site only reads this file.

    Build time: the only place a live model runs

    127.0.0.1 portal, never deployed.

    • Owner writes the brief. The problem, never the answer. No board, no worked example. Shipped
    • Agent proposes an op. One of the eight verbs in the op vocabulary, nothing else. Shipped
    • One tool call per op, into an applier. The run is fenced: no file writes, the brief is the only read. Shipped
    • Validator accepts or refuses. A refusal is shown by name, never a silent fallback. Shipped
    • Owner ratifies anything outside the vocabulary. A proposal joins the vocabulary only on the owner's word; every gate runs and the diff comes back. Shipped
    • Composition judge and evals. Named rules checked against each committed composition. Raw counts, no score. Shipped
    • Ledger records the run. What the agent did, refused and corrected stays readable. Shipped
    • Trace committed. Raw and curated pair in the repo, beside the board it built. Shipped

    Commit: the boundary between build time and view time.

    View time: no model call

    Public site, the reader's browser.

    • Vanilla HTML, CSS and ES modules. No framework, no build step, no runtime dependency. Shipped
    • Replay driver steps through the trace. The committed ops play back at the run's real pacing. Shipped
    • Labelled "Real run, curated for length". The label lives in the trace file itself, and the raw run sits beside it. Shipped
    • Prototypes with agentic slots. Ask, propose, adjust. Shipped
    • Trace player marks said versus did. Each replayed card shows whether the agent said it or did it. In progress

    Why it is built this way

    • Verifiable. Open the trace and check the run yourself.
    • Cheap and safe. No live model at view time: no per-visit cost, no prompt for a reader to steer.
    • Honest. A bad run is fixed by a tighter prompt and a re-run, never hand-edited.

    Evidence: every run is committed and can be replayed.

    Shipped

    Gates check every change.

    In: a change, often written by an agent. Out: a gate record.

    Choose something to break, or press play to send a clean change through all 13 checks.

    Show as text

    Every change to ux-factory passes named checks before it reaches main. Source: the repo’s gate reference and CI workflow, 3 October 2026.

    1. Change

      A branch, often written by an agent.

    2. Authoring checks

      Journey drivers, morph checks, the composition judge. Run by the operator; they do not block a merge.

    3. Pull request

      Opened ready for review.

    4. CI gates

      Four jobs: verify, visual, codeql, audit.

    5. gates-green

      The one check branch protection on main requires.

    6. Merge

      Into main.

    7. Deploy

      A manual operator step; nothing deploys on merge.

    Tokens and brand

    1. token-lint

      CI and authoring Shipped
      What it proves
      Every token the component stylesheet names is declared in the token contract, every contract token has a consumer, and the DTCG token source validates. Today: 63 contract tokens, 0 undeclared, 0 orphaned.

      For a designer: a component cannot ask for a colour, space or type step the brand contract does not define, and dead tokens do not pile up.

      What failure looks like
      The verify job stops and names the undeclared or orphaned token.
      What it cannot see
      A raw colour value typed straight into a stylesheet. It reads token names, not literal values.
    2. drift-check

      CI and authoring Shipped
      What it proves
      15 legs re-run the generators without writing and compare against what is committed: token CSS, the icon subset, the handoff pack and component vocabulary, replay files, each build package’s handoff.

      For a designer: the token files, icons and handoff pack a developer receives are exactly what the source produces. A hand-edited generated file fails.

      What failure looks like
      The leg and the drifted file are named, and the run exits.
      What it cannot see
      The per-company projection chain, which needs a jobs folder outside the repo.

    Components and composition

    1. build-checks

      CI and authoring Shipped
      What it proves
      51 groups import the shipped modules with no browser: pattern rules, slots, compositions against the generated vocabulary of 26 components, the share link’s tamper refusals, the catalogue, the icon subset, the import chain, ratify. Every container’s declared children are rendered one level deeper, with a control that must go red.

      For a designer: every component in the vocabulary has a render path, and a broken composition rule fails by name instead of shipping an empty box.

      What failure looks like
      The group and case print red and the run exits; a container that drops a child is named as the parent and child pair.
      What it cannot see
      How anything looks or behaves in a browser. That belongs to the pixel gate and the journey drivers.

    Journeys and pixels

    1. Pixel gate
      visual-regression

      CI Shipped
      What it proves
      11 shipped pages, each under two token packs, screenshotted and compared pixel by pixel against 22 committed baselines.

      For a designer: an unintended visual change to a shipped page fails the merge. An intended one must re-baseline in the same pull request, so it shows in review.

      What failure looks like
      The visual job goes red and uploads a diff report showing what moved.
      What it cannot see
      It never interacts, so a dead control compares clean. Up to 100 changed pixels pass. It captures without reduced motion. On feature/v3-* branches it reports but does not block, by design.
    2. Journey drivers (7)

      Authoring Shipped
      What it proves
      Seven drivers (build, canvas, catalog, instance, proto, ratify, studio) use real pages in Chromium, Firefox and WebKit: tamper refusals, an emptied board, an oversized file refused, reduced motion, the same command from pointer, keyboard and agent giving the same result.

      For a designer: the edge and error states in a flow are exercised in three browser engines, not only the happy path.

      What failure looks like
      The driver’s own last line reads “N assertion(s) failed”, with passed and failed counts per engine.
      What it cannot see
      They are not registered in CI, so a red driver does not block a merge.
    3. vt-verify

      Authoring Shipped
      What it proves
      View-transition morphs actually open, in each engine: none on page load, one per interaction family, none under reduced motion while the interaction still completes.

      For a designer: motion that silently stopped firing is caught, and reduced-motion users still reach the end state.

      What failure looks like
      A missing or extra transition group, named.
      What it cannot see
      Whether the motion looks right. It counts and names transitions; it does not judge the animation.
    4. vt-stack-audit

      Authoring In progress
      What it proves
      Before an element is named for a view transition: nothing moves when the names are removed, and nothing positioned overlaps a named element from outside it. That is the bug class that once hid a board’s connection lines at rest.

      For a designer: adding motion cannot quietly break the layout people see when nothing is moving.

      What failure looks like
      A hazard reported per page, naming the element.
      What it cannot see
      It false-positives on 3 of 7 shipped pages, so it is not yet an unattended gate.

    Content and honesty

    1. Composition judge

      Authoring; CI proves it can fail Shipped
      What it proves
      A judge with no model in it runs 10 named rules over every committed composition, each one a rule the agent was already given: buttons are verbs (never “Submit” or “OK”), link text says where it goes, a critical row says why, an empty state offers a next step, sentence case throughout.

      For a designer: copy rules are checked on what the agent actually produced, and the judge is never fed back into the prompt.

      What failure looks like
      One line per failed rule. On 3 October 2026: one scenario 55 of 55, the other 53 of 55, with two sentence-case misses (“east warehouse”). The fix is a tighter prompt and a re-run, never a hand edit.
      What it cannot see
      It does not render, and it does not decide whether a composition answers the question. Taste stays with a person.
    2. Trace and replay legs

      CI and authoring Shipped
      What it proves
      Every committed agent trace passes the trace-format validator, and the replay files the site plays regenerate from those traces to exactly what is committed.

      For a reader: an agent run shown on the site is the recorded run, not a re-authored one.

      What failure looks like
      drift-check names the trace or replay file that disagrees.
      What it cannot see
      Whether the run was a good one. That is the judge’s read and a person’s.
    3. Group-count leg

      CI and authoring Shipped
      What it proves
      The build-checks pass line, the project rules file and the gate reference must all state the same number of groups.

      For a reader: the documentation cannot claim more coverage than the code runs.

      What failure looks like
      drift-check names the document whose count disagrees.
      What it cannot see
      Counts stated anywhere else in prose are not checked.

    Security and merge

    1. codeql

      CI Shipped
      What it proves
      Static analysis, read back in two passes: the pull request’s own diff, and the full tree on main. Any open high or critical alert fails. The 14 high alerts it first found were fixed in code, none dismissed.
      What failure looks like
      The job lists the blocking alerts and says whether this pull request or main carries them.
      What it cannot see
      Files outside its hand-kept path list. Origin checks and the honesty rules stay with build-checks and review.
    2. audit

      CI Shipped
      What it proves
      The difference in npm security advisories between the base and the change, across every lockfile. A new advisory fails.
      What failure looks like
      The new advisory is named.
      What it cannot see
      Advisories the base already carried, or ones published after the merge.
    3. gates-green

      CI, required check Shipped
      What it proves
      Green only when verify, visual, codeql and audit all succeeded, reading the pixel gate’s true outcome. A pull request cannot merge until it is green.

      For a designer: what reaches main has passed every CI gate above.

      What failure looks like
      The pull request cannot merge.
      What it cannot see
      The owner can still merge past red, deliberately. A pull request is not re-tested if main moves after it ran.

    Not gated: the screen-reader pass and judgement-level accessibility (labels that say what they do, colour never the only signal) are checked by hand. No automated accessibility scanner is in the stack.

    Planned, not yet a gate: a conformance check that tests a running service against the handoff pack’s contracts (contract-check, in progress).

    Evidence: each check is code a reviewer can open and run.

    Shipped, one check in progress

    Follow one idea through every station.

    In: Rate path, typed as a problem. Out: a private instance, five illustrative screens.

    Intake. The problem is typed as a blank idea and opens a run package.

    Show as text

    Illustrative: an idea sketched for the factory, from Lendable’s public site. Not Lendable work.

    Rate path

    Hypothesis to test People who check their rate and land in the Fair or Limited band either borrow at the highest cost or leave, and neither outcome is good for them or for the lender.

    Step 1: IntakeDiscovery drawer · run package
    Person
    Types the problem as a blank idea, picks the Create PRD posture and states plain facts, such as “a regulator can inspect it”.
    Agent
    Opens a run package and starts on the twelve opening questions. Each stated fact adds its own module, so the regulated module joins.

    Artefact

    A run package

    The problem recorded as a problem, never as the answer.

    Step 2: DecideQuestion bank · op applier · PRD projection
    Person
    Answers up to 31 questions from a 76-entry, source-backed bank, and parks what belongs in a later version.
    Agent
    Judges each answer against the question’s weak-answer note and asks again when it is thin.

    Artefact

    prd.md

    Generated from the recorded answers. Decision: offer a wait-and-re-quote path beside the quote, with borrowing now kept equal. Kill criterion: stop if opted-in re-quote uptake, or later approval in a better band, does not beat a stated baseline, or if complaints rise.

    Step 3: Company packCompany brief · derivation engine · ethics gate
    Person
    Writes a company brief with source links, then approves or corrects every proposed value.
    Agent
    Proposes a pack from the public site’s brand colours and writes down every contrast adjustment. The ethics gate rejects habit mechanics: a loan is taken rarely, so the verdict is utility.

    Artefact

    A private, derived pack

    Token values under the shared contract, the derivation trace, and the ethics verdict. This page carries none of Lendable’s logo, fonts or colours.

    Step 4: Build on the canvasFree canvas · component vocabulary · ledger · ratify
    Person
    Lays out screens, then states, and accepts or refuses each proposal. “Borrow now” and “wait and re-quote” stay the same size and weight.
    Agent
    Composes only from the validated vocabulary. Anything outside it is refused in the open and logged in the ledger.

    Artefact

    Screens: a base plus overrides

    Six states and three edge states (soft search unavailable, affordability check failed, vulnerable customer routed to a person). The screens are drawn below. Built examples of the same thinking (illustrative figures): financial difficulty · consolidation loan

    Step 5: GatesBuild checks · journey drivers · pixel gate
    Person
    Reads each gate’s result and runs the journeys through the edge states before trusting a green run.
    Agent
    Fixes what the gates name, with a tighter prompt and a re-run, never a hand edit.

    Artefact

    A gate record

    Token lint, composition, journeys on Chromium, Firefox and WebKit, pixel baselines, and contrast at AA (4.5:1 text, 3:1 controls).

    Step 6: Hand offHandoff pack generator
    Person
    Gives engineers the pack, or drags its token file into a Figma variable collection.
    Agent
    Generates the pack from the specs and the build. Nothing is edited by hand.

    Artefact

    The handoff pack

    A ComponentSpec per part, a DataContract, tokens for CSS, iOS and Android, an llms.txt index and the Figma import path.

    Step 7: ShowInstance builder · replay · trace player
    Person
    Runs the printed deploy command, so the private link goes live only when they choose.
    Agent
    None in the reader’s browser. The instance replays committed runs, labelled “real run, curated”.

    Artefact

    A private, unlisted instance

    Noindex, labelled as speculative work from public statements, sources linked, not affiliated or endorsed.

    Step 8: Product screensFive key screens · illustrative

    Illustrative. Brand, figures and copy are placeholders. Not Lendable work.

    1. Quote result in a higher band

    2. Cost side by side

    3. What moves a band

    4. Choose: borrow now or re-quote later

    5. Re-quote reminder

    Affordances, data and gates per screen

    How to read it

    • Underlined items are affordances; the arrow after each names the place it leads to.
    • Data lists the DataContract fields a state needs: quote band, amount, term, total repayable, factors, consent flag.
    • Gate names the factory gate that would check that state. The gates are real; this idea is a sketch, not a committed run.
    1. 1 Quote result in a higher band

      • See the cost next to a better band → 2
      • Continue → 4

      Data quote band, amount, term

      Gate journey driver: Fair and Limited branch here, Great and Good skip to 4

      • Soft search unavailable

        “We couldn’t check your rate just now. Nothing was recorded on your file.” Try again → 1.

        Data amount, term (kept, so nothing is retyped)

        Gate journey driver: the error branch

    2. 2 Cost side by side

      • What moves a band → 3
      • Choose what to do → 4

      Data quote band, amount, term, total repayable (both bands)

      Gate WCAG pair check: both columns at AA, neither band styled as the winner

    3. 3 What moves a band

      • Back to my choice → 4

      Data factors (two or three, from the lender’s own model)

      Gate journey driver: the place returns to 4 with the quote unchanged

    4. 4 Choose: borrow now or re-quote later

      • Borrow now → application
      • Re-quote me later → 5
      • Talk to a person → support

      Data quote band, amount, term, consent flag

      Gate ethics gate (Manipulation Matrix): equal weight, no pre-selected option, no countdown

      • Affordability check failed

        After Borrow now: a plain reason, no offer pushed. Re-quote me later → 5 stays available.

        Data amount, term, consent flag

        Gate journey driver: the decline branch

      • Difficulty or vulnerability signalled

        Reachable from every place. The flow stops selling and routes to a person.

        Data none beyond the session; no band shown

        Gate journey driver: every place has the route

    5. 5 Re-quote reminder

      • Get a new quote → 1
      • Stop reminders → opted out

      Data consent flag (true), amount, term

      Gate ethics gate (frequency filter): a rare event reads as utility, so no streaks or habit hooks

      • Opted out

        Consent off: nothing is sent. One confirmation, “Reminders are off”, and the journey ends.

        Data consent flag (false)

        Gate journey driver: no reminder after opt-out

    Idea, public facts and sample exchange

    The idea: after a soft-search quote in a higher band, show the total cost in plain pounds next to a better band, the factors that most often move a band, and an opt-in to be quoted again later. Borrowing now stays an equal choice.

    Public site only: personal loans of £1,000 to £25,000 over one to five years; “See your rate before you apply - it won’t affect your credit score”; offers set by credit band (Great, Good, Fair, Limited).

    Sample Decide exchange

    Question “What happens today, and how do you know?”

    Weak answer “People in the lower bands drop off.”

    Agent “Drop off where: at the quote, the offer or the drawdown? Which number shows it, by band?”

    Illustrative: built from Lendable's public site only, not Lendable work.

    Illustrative

    What runs today, and the target.

    Status as of 3 October 2026. The finished state is each epic's own target, not a date.

    Ux-factory stations: today and finished state
    StationTodayFinished state
    DecideShipped, follow-on openEpic #279 closed 14 September 2026; #504 open.A discovery session reaches a build-ready PRD in one sitting.
    BuildIn progress, epic #295Free canvas and five primitives landed; first run #316 open.Faster Payment built from its PRD across four screens, with a handoff pack.
    Hand offPartly shipped, epic #329Pack generated: 26 component specs, tokens, wrappers; six slices (#331 to #336) open.An engineer wires a real API from the pack with no round trip to design.
    ShowShipped, follow-ups open14 site pages and two prototypes; #496 open.A public replay site, and a private instance under a company's own pack.

    Where the job description shows.

    The prototypes are ideas built from Lendable's public site, not Lendable work, and every figure in them is illustrative.

    01Flows, prototypes, edge cases and error states

    Build fails when a declared state is missing; the hardship flow prices every option with nothing pre-selected.

    02Discovery with product managers and engineers

    Decide records each decision with its evidence and kill criterion. In agency work I was the primary client contact for most of my time there.

    03Design system and brand guidelines, inconsistencies flagged

    One token contract under every component; token lint fails the build on an undeclared token. Before this, design systems in Taxi for Email let non-technical marketers assemble on-brand campaigns they could not break.

    04Documented work for engineers and AI tools

    The handoff pack has component specs, tokens for three platforms and an llms.txt index; the Figma parity run has not landed.

    05AI in daily work

    Agents propose and people decide, and every run is committed.

    06Accessibility to WCAG AA

    Axe reported 0 violations across 11 routes in light and dark on a separate concept site, with 42 text pairs AA by computation; ux-factory has no automated accessibility scanner, and none of this is a screen-reader audit.

    07Fair customer outcomes

    The credit-building card shows minimum and full payment as equal choices, and the consolidation loan says when it costs more. Designed with Consumer Duty in mind.

    08Mobile product design

    ugoki, my own native iOS and Android wellness app, 2026.

    The gap, honestly: no moderated user research or usability testing on my record, and the prototypes have not been tested with customers. No product designer title in a squad, and no employment in an FCA-regulated firm.