Reveal only the fields that apply

Three Gates (Noul) decide which optional sections appear, and useScore decides how much help text each field carries — a judgment driving props rather than a subtree. All four resolve in one request. Gates only ever add fields here: content hidden by a judgment is an accessibility problem, and it is invisible to whoever needed it.

the request

THE QUESTION — sent as instructions · backticked paths scope what it reads
reference state:
STATE THIS QUESTION RECEIVES — combine freely · sets the pick prop
all channels — the default, so no pick prop is needed
THE ORDER — pick one · what the three Gates read
WHO IS FILLING IT IN — pick one · one of your own app.* fields
DATA SENT TO THE GATES — edit it and the form below follows
useScore read “returning” and returned 0.00 — knows this form well; labels alone are enough — so verbose help is off for every field below.

what the judgment returned

this render —
nothing resolved yet
no judgments resolved yet

your state, as codegenerated from the editor on the right

// app/providers.tsx — the state every question on this page receives
<JevProvider
  resolve={askJev}
  scope={{ app: { product: "Northwind Analytics", user: "ana", role: "analyst", familiarity: "returning" } }}
  initialAmbient={{ recent_actions: [], time_spent: "short" }}
>

the componentapp/form/Demo.tsx

'use client';import { Gate, useJev, useScore, type DecisionCost } from 'jev-ui';import { useState } from 'react';// … demo scaffolding — answer panel, controls, mock orders, and the Field componentexport function FormDemo() {  const [scenario, setScenario] = useState(ORDERS[0]!);  const [order, setOrder] = useState(ORDERS[0]!.order);  const [draft, setDraft] = useState(JSON.stringify(ORDERS[0]!.order, null, 2));  const [invalid, setInvalid] = useState(false);  const { state, setState } = useJev();  const appState = (state.app ?? {}) as Record<string, unknown>;  const familiarity = String(appState.familiarity ?? '');  const [cost, setCost] = useState<DecisionCost | undefined>();  const { pick, ask } = usePick();  // … keeps the editable JSON and the presets in sync  const guidance = useScore({    id: 'guidance',    ask: 'How much explanation does this person need on a shipping form, given `app.familiarity` and what they have done in `recent_actions`?',    levels: HELP_LEVELS,    pick,  });  const verbose = guidance.normalized >= 0.5;  const help = (text: string) => (verbose ? text : undefined);  return (    <>      <section className="card" data-testid="demo-live" style={{ display: 'grid', gap: 14 }}>        // … the controls that drive the demo        <form data-testid="shipping-form" onSubmit={(event) => event.preventDefault()}>          <Field label="Recipient name" />          <Field label="Delivery address" />          <Gate            id="needs_customs"            ask="Does the shipment described in `data.order` cross an international border, so that a customs declaration is required?"   ← set by the controls above            data={{ order }}            pick={undefined}   // every channel — the default   ← set by the controls above            threshold={0.6}            onResolved={setCost}          >            <CustomsFields help={help} />          </Gate>          <Gate            id="needs_tax_id"            ask="Does the buyer in `data.order` appear to be a registered business rather than an individual, so that a tax registration number should be collected?"            data={{ order }}            pick={undefined}   // every channel — the default   ← set by the controls above            threshold={0.6}          >            <TaxFields help={help} />          </Gate>          <Gate            id="needs_dangerous_goods"            ask="Do the contents in `data.order` include anything restricted for air freight, such as batteries, aerosols, or flammable liquids?"            data={{ order }}            pick={undefined}   // every channel — the default   ← set by the controls above            threshold={0.6}          >            <DangerousGoodsNotice />          </Gate>          <button type="submit" className="ctl">            Continue          </button>        </form>      </section>      // … omitted    </>  );}