Hello Alex Docs
Pathway Builder Guide
Build, test, and publish conversation flows in the Pathway Builder — step by step for every node type. Read the Pathways guide in Hello Alex documentation.
Overview
Pathway Builder is the workspace where you define what Alex says, listens for, and does at each point in a conversation, which is why it is the core control center for call, SMS, and chat outcomes. A clear pathway turns intent into predictable service quality, so your team can scale responses without losing consistency.
How it works
- When you map a conversation on the canvas and connect each node intentionally, Alex follows that logic in sequence, so callers experience consistent routing and messaging instead of ad-hoc responses.
- When Global Prompt guidance, node-level instructions, and variable extraction align, Alex can interpret context accurately, which reduces repeated questions and improves completion rates.
- When you validate drafts in Chat & Test, then publish and assign the right pathway, you catch logic gaps before live traffic, so production interactions stay reliable.
Important fields
- Pathway: The full conversation flow Alex runs on a call, SMS, or chat.
- Node (step): One action in the flow — for example, Speak, Wait for Response, IVR, SMS, or Transfer.
- Canvas: The visual workspace where you arrange and connect nodes.
- Draft: Your work-in-progress copy. You can edit it freely without affecting live calls.
- Published: The live copy that real calls and messages use today.
- Production version: The published snapshot callers hear right now. Older numbered versions stay saved for rollback.
- Global Prompt: Business-wide instructions that apply on every step — tone, rules, and guardrails.
- Extract variable: A detail Alex remembers from a caller's answer — for example, their name or preferred day.
Tips
- Good to know: keep your first draft simple and expand once each branch behaves as expected, because stable foundations make later edits safer.
- Good to know: published versions power live channels, so draft changes are safe for iteration until you intentionally release them.
1. The Pathway Canvas
The pathway canvas is the visual map of your conversation system, and it matters because every branch you draw becomes runtime behavior for Alex. A readable layout lowers review friction, so teams can spot logic problems before publishing.
Next, define what caller details should be captured so downstream nodes can act on reliable context.
- When nodes are positioned in conversational order and connected by clear paths, dependencies become obvious, so both editors and reviewers can validate intent quickly.
- When each node is configured from the edit panel and saved into draft, your structural map and node logic stay synchronized, which prevents hidden behavior mismatches.
- When teams maintain spatial consistency across pathways, future updates take less time, because orientation and branch purpose are immediately recognizable.
- Flow Builder tab: The design view where you arrange nodes and branches.
- Node dock: The toolbar you add steps from: Speak, Wait for Response, IVR, SMS, Transfer, Transfer Pathway, Route, Webhook, Custom Code, Knowledge, and End Call.
- Start node: The single entry point where every conversation begins.
- Global Prompt node: Always on the canvas, one per pathway. It is not in the dock and cannot be deleted — click it to edit the instructions every node follows.
- Edit panel: The right-side panel where you configure the selected node.
- Edit connection panel: Click a connector instead of a node and the panel edits that path instead: a label of up to 100 characters and an optional description. Alex reads the label to decide which way to go, so keep it short and literal.
- Good to know: consistent left-to-right flow reduces review mistakes, especially when multiple people maintain the same pathway.
2. How to Capture Caller Details
Extract variables are structured values Alex stores from caller input, and they matter because reusable context drives accurate routing, responses, and handoffs. Capturing the right detail once prevents repeat prompts later in the same interaction.
Next, align Global Prompt guidance so extracted values are handled with the right tone and policy constraints.
- When variable extraction is attached to the node where the caller provides information, Alex can normalize that response immediately, so later nodes reference a clean value instead of raw language.
- When variable names and extraction prompts are specific, ambiguity drops, which improves reliability for conditions, transfers, and external integrations.
- When extracted values are validated in Chat & Test, edge-case phrasing is caught early, so production paths remain stable under real caller variation.
- Variable name: A short label for the captured detail — for example, caller_name or preferred_day.
- Type: The kind of answer you expect: text, number, yes/no, decimal, or list.
- Extraction prompt: Plain-language instructions for what to pull from the caller's answer at this step.
- Variables tab: A pathway-wide list of every detail you collect and which node captures it.
- Good to know: concise variable names and strict types make webhook mapping and reporting cleaner over time.
3. Global Prompt
Global Prompt is the instruction layer every node inherits, and it lives on the canvas as its own violet node — one per pathway, always present, and the only node you cannot delete. It is critical because it carries tone, policy, and safety boundaries in one place instead of being copied into every Speak node.
Next, learn the settings every other node shares before configuring individual steps.
- When business rules are centralized in Global Prompt, node content can stay focused on local intent, so pathway maintenance is faster and less error-prone.
- When guardrails define restricted topics and escalation behavior, unsafe or off-policy responses are less likely, which improves trust and reduces operational risk.
- When global instructions are reviewed alongside pathway edits, tone and policy drift is detected early, so published behavior remains predictable.
- Global Prompt node: The violet node on the canvas. It has no title and no type of its own, and it is added for you rather than dragged from the dock.
- Global Prompt field: The single box holding your instructions. There is no character limit.
- Prompt length meter: A live count of characters, words, and approximate tokens, with warnings. Long prompts slow voice responses and make instructions contradict each other, which is why the meter is there.
- View as formatted text: A switch that renders the prompt read-only for reviewing. Switch it off to edit again.
- The Settings tab holds the same value: Editing this node changes the pathway's global prompt, and editing it in Settings changes this node. They are one value, not two.
- Good to know: updating shared policies in one Global Prompt change is safer than duplicating policy text across many Speak nodes.
- Good to know: guardrails and brand voice are things you write inside this one box — there are no separate switches for them.
5. Welcome and Speak Nodes
Welcome and Speak nodes define what Alex says at each conversational moment, and they matter because wording quality directly affects caller confidence and response clarity. Precise prompts reduce misunderstandings and improve branch accuracy.
Next, place Wait for Response nodes after key prompts so Alex can capture intent before routing.
- When your first Speak node sets context and asks a single clear question, callers know what to do next, so Wait for Response nodes receive cleaner input.
- When static phrasing is used for regulated or approved language, messaging stays compliant, while AI Prompt mode supports adaptive responses where flexibility is beneficial.
- When each message is tested for brevity and intent alignment, the flow feels natural, which lowers abandonment and repeated clarification loops.
- Title: The label shown on the canvas — for example, Welcome.
- Static message: The exact words Alex speaks, sent unchanged.
- AI Prompt: Instructions for what Alex should accomplish here, phrased fresh each call. Variables such as {{customer_name}} work in both modes.
- Optimize with Alex: Rewrites the message or prompt you already have, in place.
- Model and voice behavior: Temperature, interruptions, and the rest live under Advanced options — see “Settings Every Node Shares” above.
- Good to know: short prompts with one intent per node improve response quality more than long multi-question scripts.
6. Wait for Response Nodes
Wait for Response nodes capture caller input and pause progression until meaningful signal arrives, which is essential because routing quality depends on what Alex hears next. Well-tuned response handling creates smoother, less repetitive conversations.
Next, add IVR nodes where external phone systems require keypad navigation before the conversation can continue.
- When a Wait for Response node follows a focused Speak prompt, caller intent is easier to classify, so branch logic can trigger with less ambiguity.
- When silence limits, timeout behavior, and fallback routing are configured deliberately, stalled conversations recover gracefully, which prevents dead ends.
- When keyword rules and branch connections are tested against real phrasing variation, route accuracy improves, so escalation and self-service paths activate more reliably.
- Timeout (seconds): How long Alex waits for an answer, 1 to 120. Default 30.
- Max Silence (seconds): How much quiet counts as no answer, 1 to 30. Default 5.
- End on Silence: Stops listening once Max Silence passes instead of waiting out the timeout.
- Keywords: Comma-separated words to listen for — for example, yes, no, help, transfer.
- Fallback Node: Where to go when nothing usable is heard. Leave it on No fallback to stay put.
- Fallback Message: What Alex says before taking that fallback.
- Enable Transcription: Captures the full transcription for this step. On by default.
- Sentiment Analysis: Scores how the caller sounds at this step. Off by default.
- Good to know: balance timeout and silence settings carefully, because aggressive limits can cut off callers while long limits can feel unresponsive.
7. IVR Nodes
IVR nodes send DTMF input to automated phone systems, and they matter because many transfers and partner workflows depend on successful menu navigation. Correct IVR timing prevents failed handoffs and repeated retries.
Next, add an SMS node when the caller needs something in writing while still on the line.
- When IVR nodes are inserted at points where external menus block progress, Alex can continue the workflow autonomously, so callers avoid manual redial loops.
- When DTMF sequences include realistic pauses, menu prompts are met at the right moment, which improves successful option selection.
- When IVR paths are validated on real calls, timing differences across providers are exposed, so production transfers remain dependable.
- Title: The label shown on the canvas — for example, Navigate Billing IVR.
- Type: Fixed to IVR for steps that navigate automated phone menus.
- Dialogue prompt: The keypad tones Alex sends — for example, w1# to wait, press 1, then pound. This node has no Static/AI switch and no Optimize with Alex: the tones are sent exactly as typed.
- Good to know: production IVR behavior often differs from sandbox assumptions, so live call validation is the safest way to finalize sequences.
8. SMS Nodes
SMS nodes send a text message in the middle of a live conversation, and they matter because some answers are easier to read than to hear — a booking link, an address, or a confirmation code. Sending it while the caller is still on the line means they have it before they hang up.
Next, configure Transfer nodes so callers can be handed to the correct destination when a text is not enough.
- When an SMS node is placed right after the detail is agreed, the caller receives the text while the call is still open, so they can confirm it out loud instead of calling back.
- When the message uses the same variables you extract earlier in the pathway, each text arrives personalized without a separate template, which keeps the wording consistent across every call.
- When the From Number is a number your account is allowed to text from, delivery is predictable, so messages are not silently dropped by the carrier.
- Title: The label shown on the canvas — for example, Text the booking link.
- Type: Fixed to SMS for steps that send a text message.
- From Number: The number the text is sent from. Required when you bring your own Twilio account, and that number must belong to an A2P campaign. Optional otherwise — leave it empty and your account's number is used.
- SMS message: The text itself, up to 306 characters. It is sent word for word, and variables such as {{customer_name}} are filled in before sending.
- Good to know: the message is sent exactly as written — Alex does not rewrite it, so a variable name that does not match the one you extract will send as raw text.
- Good to know: an SMS node has no prompt, tags, or model settings, because it does not speak or decide anything — it sends one message and the pathway moves on.
9. Transfer Nodes
Transfer nodes move callers from Alex to a person or external line, and they are critical because escalation quality influences caller trust and issue resolution speed. Choosing the right transfer mode keeps context intact during handoff.
Next, add Webhook nodes where live system data is needed before confirming next actions.
- When transfer destinations are explicit and validated, routing failures decrease, so callers reach the intended team with fewer retries.
- When warm transfer mode is used for high-context escalations, Alex can brief the receiving agent first, which shortens resolution time and reduces repeated questioning.
- When fallback behavior is defined for no-answer outcomes, conversations still close with direction, so callers are not dropped into uncertainty.
- Title and Type: Transfer is the one node whose Type you can change; it defaults to Transfer Call and lists every type the voice engine supports.
- Transfer number: A country and number, or switch on Use Variable to take the destination from a variable captured earlier. An extension is optional.
- Cold or Warm transfer: Cold hands the call straight to the number. Warm has Alex brief the person first, and reveals the four steps below.
- SIP REFER transfer: Hands the call off with SIP REFER instead of bridging a new leg. Cold transfers on SIP calls only.
- Warm step 1 — While User Waits: Play hold music (with your own Hold Music URL) or keep talking to the caller.
- Warm step 2 — Briefing the Live Agent: What Alex tells the person picking up, either written out or generated from a prompt.
- Warm step 3 — When Calls Merge: What Alex says at the moment both sides are joined.
- Warm step 4 — If Agent Unavailable: Say a message, go to another node, or hang up.
- Warm Advanced Settings: A custom proxy number, a DTMF sequence, a hold timeout, Optimize for IVR/Queue Systems (on by default), and letting Alex decide when to merge.
- Retry Count: How many times to retry the transfer, 0 to 5.
- Voicemail Handling: Hang up, leave a message (which reveals the message box), or retry the transfer.
- Webhook URL (transfer notification): Notifies your system when the transfer happens.
- Return After Transfer: Continues the conversation when the transfer fails instead of ending the call.
- Good to know: Transfer and End Call have no Loop Condition. Once the call leaves, there is nothing left to loop on.
10. Webhook Nodes
Webhook nodes connect Alex to external systems during live conversations, and they matter because real-time data turns generic scripts into operational workflows. Integrated calls enable accurate confirmations, lookups, and downstream automation.
Next, add Custom Code nodes where a value needs to be worked out or reshaped before Alex uses it.
- When webhook requests include validated variables from earlier nodes, external systems receive complete context, so responses can be used immediately for next-step decisions.
- When success and failure branches are both configured, system outages and edge responses remain manageable, which protects caller experience under degraded conditions.
- When response fields are mapped into pathway variables, later nodes can reference fresh data, so Alex can confirm outcomes without manual intervention.
- Method & URL: The HTTP verb and endpoint. POST by default.
- Authorization: Optional. Bearer, Basic, or API Key, with the token stored hidden.
- Headers: Optional key and value rows for anything your endpoint requires.
- Request body: On by default. Use {{variable_name}} for pathway variables; the body is sent as-is.
- Timeout and Retry attempts: How long to wait (10 seconds by default) and how many times to retry, 0 to 5.
- Response data: Pull values out of the reply by JSON path — for example, $.results[*].text — and name each one.
- Pathway after API request response: Route to different nodes based on the reply, most often on the status code.
- Speech while waiting: What Alex says while the request is in flight.
- Extraction variables: A second variable list belonging to this node. It accepts String, Integer, and Boolean only, and when it holds anything it replaces the shared Variable Extraction list.
- Good to know: a webhook node shows two variable editors. The one inside Webhook Configuration wins, so fill in one or the other rather than both.
11. Custom Code Nodes
Custom Code nodes run a short piece of JavaScript in the middle of a live call, and they matter when a step needs a calculation or a reshaped value rather than a call to your own system. Whatever the code returns becomes variables that later nodes can use.
Next, use Transfer Pathway and Route nodes to hand a call to another pathway, or to send it down a path based on a value you already have.
- When the node lists the variables your code needs — typed values, or {{variables}} from earlier in the call — they arrive in your code together as one JSON object, so the code works with the caller's real details.
- When the code returns a JSON object, each key becomes a variable later nodes can reference as {{key}}, so Alex can quote a computed total, a formatted date, or a yes/no result without a separate webhook.
- When you save the code and run it in Test Mode before deploying, you see the status, how long it took, and every value it returned, so a mistake is caught in the editor instead of on a live call.
- Title and Type: The label shown on the canvas. Type is fixed to Custom Code.
- Variables this code receives: Rows of a name and a value. The name is how your code reads it — json['name']. The value is typed text or a variable picked from the list: Call variables such as the caller's number, city, or the current time, and Pathway variables your other nodes extract. A row with no name is ignored.
- Generate code: Adds one line per named variable right under const json = await request.json();, so each one is ready to use. Keep that line inside fetch() for it to work.
- Custom Code Execution: The code editor. Insert starter code gives you a working example that receives the variables and returns them unchanged. Return a JSON object with Response.json(...) — its keys become the node's variables. Tab indents; press Esc, then Tab, to move on. The expand button opens a larger view.
- Save Code: Stores the code so it can run on calls and in Test Mode, up to 100 KB. Save and deploy the pathway as usual afterwards so calls use the new code.
- Test Mode and Run Test: Switch on Test Mode and press Run Test to run the code with the variables as they are set. Unsaved code is saved first. The result shows Response Success or Response Failed, the status, the latency, and each value returned — or the error when the run fails.
- Execution Timeout: How long a call waits for the code before continuing without it, from 1000 to 60000 milliseconds. Leave it blank for the 10-second default.
- Good to know: Run Test sends each value exactly as it is set, so a picked variable such as {{call_id}} arrives as that placeholder text rather than a real call's value. Type a sample value in its place when you want a realistic test, then pick the variable again before deploying.
- Good to know: a Custom Code node has no prompt, tags, or model settings, because it does not speak — it runs the code and the pathway moves on. Keep the code quick, because the call waits for it.
12. Transfer Pathway and Route Nodes
Transfer Pathway nodes hand the call to another pathway, or to a live agent through your webhook, and Route nodes send the call down a path based on a value you already have — a variable Alex extracted, or one the call arrived with. Neither node speaks or thinks: a Transfer Pathway ends this pathway's part of the call, and a Route picks the next step by comparing values, with no AI in between.
Next, incorporate Knowledge nodes for open-ended questions that should be answered from trusted documents.
- When a Transfer Pathway node is reached, the call continues in the pathway you picked, at the version and node you chose, so a shared pathway such as billing or verification can be built once and reached from anywhere.
- When the Live agent transfer tab is used instead, your webhook URL is called as the node is reached, so your own system can connect a person.
- When a Route node is reached, its routes are checked top to bottom and the first one whose conditions all hold takes the call; when none does, the call goes to the fallback node, so every value has somewhere to go.
- Title and Type: The label shown on the canvas. Type is fixed to Transfer Pathway or Route; neither has a prompt, tags, variables, or model settings.
- Transfer Pathway, Pathway Version, Pathway Transfer Node: Pick one of your pathways, then a version (Production follows whatever is live; a number pins one), then the node the call should start at. Turn on Manual Input to type an id the list does not hold — another account's pathway, or a {{variable}} such as {{conversation_pathway_id}}. Only the pathway is required before you save.
- Live Agent Webhook URL: On the Live agent transfer tab: the https address your system listens on. Required on that tab.
- Routes: Each route is one or more conditions — a variable, an operator such as is or not equals, and a value — plus the node to go to. Add a condition when every part must hold; add a route for each separate destination. Dragging a connection from a Route node on the canvas adds a route too, and deleting that connection removes it.
- Fallback node: Where the call goes when no route matches. Leave it empty only when every case is covered by a route.
- Good to know: a Transfer Pathway node has no outgoing connection, because the call carries on in the other pathway. Put it where this pathway's job is done.
- Good to know: the pathway you are editing is not offered in the Transfer Pathway list — transferring to itself would loop — and the version list is read from the voice engine, so a version published a moment ago can take up to half a minute to appear.
- Good to know: a Route node's connections on the canvas are drawn from its routes, not the other way round. Edit the route in the panel to change where a connection points; its label shows the condition.
13. Knowledge Nodes
Knowledge nodes answer caller questions from approved documents, and they matter because retrieval-based responses improve factual consistency and reduce hallucinated answers. Document-scoped search keeps guidance aligned with your source material.
Next, finalize End Call behavior so successful and fallback paths close with clear summaries.
- When relevant document sets are attached to a Knowledge node, Alex can retrieve grounded answers, so callers receive information tied to your approved content.
- When fallback text is defined for low-confidence retrieval, unresolved questions still move toward a clear next action, which prevents conversational dead ends.
- When knowledge scope is curated by topic, retrieval quality increases, so answers remain specific rather than overly broad.
- Sources: The knowledge bases this step may answer from. Only bases that have finished syncing can be picked; the rest are greyed out with the reason — processing, sync pending, awaiting documents, or sync failed.
- Cite Sources: Includes source references in the answer.
- Fallback Text: What Alex says when nothing relevant is found.
- Good to know: focused source sets outperform mixed libraries, because tighter scope improves retrieval relevance and confidence.
14. End Call Nodes
End Call nodes explicitly terminate interactions and record outcomes, and they matter because clean closure protects caller confidence and reporting accuracy. Defined endings prevent loops and keep post-call systems synchronized.
Next, validate the full draft in Chat & Test to confirm branches and variable carryover before publishing.
- When each logical branch routes to an End Call node, callers receive a definitive outcome, so interactions do not linger in ambiguous states.
- When summaries include key captured variables, teams can act without replaying calls, which shortens follow-up cycles.
- When after-call notifications are configured, CRM and operational tools update automatically, so downstream workflows stay aligned with conversation results.
- End Reason: How the conversation ended — for example, completed or transferred. Shows in call history.
- Summary Template: The recap text saved after the call. You can include details Alex collected.
- After-Call Webhook URL: A web address Hello Alex notifies when the call ends.
- Send Summary Email: Emails the recap to addresses you configure for your team.
- Good to know: concise end summaries with only actionable details are easier for teams to process and triage quickly.
15. Chat & Test
Chat & Test simulates conversations in-text against your current pathway draft, and it matters because rapid iteration exposes routing gaps before phone testing. Fast feedback cycles reduce publishing risk and speed up refinement.
Next, run a live Test Call on the published version to confirm voice, pacing, and transfer behavior on real telephony.
- When you test representative caller intents in chat, branch transitions become visible immediately, so misrouted logic can be corrected before release.
- When difficult scenarios are replayed with alternate wording, extraction and fallback behavior are stress-tested, which improves resilience to real-world language variation.
- When draft edits are revalidated in short loops, confidence rises quickly, so only stable logic moves to published versions.
- Chat Test tab: A free text simulation of your current draft. No call credits required.
- @alex mentions: Ask for help improving wording or debugging a branch during a test session.
- Active node highlight: The blue glow on the canvas shows which step Alex is on right now.
- Good to know: intentionally test unclear and contradictory caller language, because edge phrasing is where routing defects usually appear.
16. Test Call
Test Call places a real phone call using your published pathway, and it matters because voice, timing, and telephony behavior can differ from text simulation. Live validation confirms production readiness before customer exposure.
Next, review how versions move between Staging and Production so the flow you just validated is the one callers receive.
- When you test the published version over an actual phone connection, audio pacing and handoff behavior are evaluated in realistic conditions, so final release decisions are evidence-based.
- When voice, version, and duration settings are selected deliberately, comparisons across iterations stay meaningful, which helps isolate changes that improve or degrade quality.
- When transcript and recording review follows each test, subtle breakdowns are captured quickly, so the next draft revision targets concrete issues.
- Your phone number: Where Hello Alex places the test call. Use a mobile you can answer right away.
- Voice: Which voice callers will hear on this test.
- Version: Which published snapshot to test. Production is the live default.
- Max duration: Caps how long the test call can run while you iterate.
- Good to know: run one final call after major transfer or IVR updates, because those behaviors are most sensitive to real network timing.
17. Versions, Staging, and Production
Every saved pathway keeps a numbered version, and each version sits in one of three places: your working draft, Staging, or Production. Separating where a change lives from what the change is means you can keep editing safely while callers stay on the version you already trust.
Next, use version history to compare what changed between two versions before you deploy.
- When you edit a pathway you are always working on the draft, so nothing you type reaches callers until you deploy it, which lets you rework a flow mid-day without interrupting live calls.
- When you deploy to Staging, that version becomes the one you can rehearse against with Chat & Test and Test Call, so behavior is proven on the exact snapshot before anyone answers it.
- When you deploy to Production, the version callers hear changes, which is why the Production card always names the version and the date it went live — so you can tell at a glance what is answering right now.
- When a pathway is created — from a script, the AI wizard, an interview, or a duplicate — it records its first version immediately, so version history is available from the very first save rather than appearing only after your first publish.
- Draft: Your unsaved and unpublished edits. Only you see them, and callers are unaffected.
- Staging: The version you rehearse against. Shows its version number, name, and when it was created.
- Production: The version callers actually hear, with the date it went live.
- Deploy to staging: Sends your current draft to Staging so you can test it end to end.
- Deploy to production: Makes a version the live one. Take this step after a Test Call on Staging looks right.
- Good to know: deploying to Staging costs nothing and changes nothing for callers, so it is the safe place to rehearse a rewrite before it goes live.
- Good to know: check the version number on the Production card before troubleshooting a reported issue, because the behavior someone described may belong to an older version than the one you are editing.
18. Version History and Compare
Version history lists every version a pathway has had, where each one currently sits, and what it was built from. Being able to read that trail matters because most pathway questions are really questions about what changed and when.
Next, publish or re-publish confidently and assign the validated pathway to your target number, campaign, or widget.
- When you compare two versions, the differences are grouped by Global Prompt, nodes, and connections, so a wording tweak is easy to tell apart from a change that re-routes the conversation.
- When you compare Staging against Production before deploying, you see exactly what callers are about to experience differently, which turns a deploy decision into a review rather than a guess.
- When an earlier version was better, you can restore it as your working draft and deploy from there, so recovering from a regression does not mean rebuilding the flow by hand.
- Branch: The version's name, and a marker showing whether it is currently on Staging or Production.
- Source: What the version was created from — a save, a duplicate, a restore, or a deploy.
- Updated: When the version last changed.
- Version actions: Rename a version so its purpose is obvious later, duplicate it to try an alternative, or remove one you no longer need.
- Good to know: rename versions with the reason for the change rather than a date, because 'shorter opening question' tells a colleague more in six months than 'v4' does.
Next step
Next, review the canvas layout so your baseline node flow is easy to audit before deeper logic changes.