# iMBrace build guide, edition 1.0.3 - every page in one file


==================== AGENTS.md ====================

# Building on iMBrace - instructions for an AI coding tool

You are helping a person build on iMBrace, an enterprise AI platform: agents people talk to,
boards that hold structured records, DocIQ that reads documents into records, workflows that
run steps on their own, and channels that connect it all to email, chat and the web. This
folder is the method - how to design and build well. The reference for facts is
engineer.imbrace.co.

## Words this guide uses

- **Organisation** - one tenant on the platform: its boards, agents, workflows and people.
- **Test organisation** - an organisation used only for building and testing, never for real
  work or real data.
- **Board** - a table of typed columns and rows, the platform's structured record store.
- **Workflow** (or flow) - a sequence of steps that runs on its own once triggered.
- **Native step** - a ready-made workflow step the platform ships; nothing to write or host.
- **Agent** - the conversational front end a person or a channel talks to.
- **DocIQ** - the part of the platform that reads documents into board records.
- **Document model** - what DocIQ extracts from one type of document, and where it goes.
- **Gateway** - the address the SDK, the CLI and the MCP connection all talk to.
- **MCP** - the Model Context Protocol connection that lets your coding tool see and, with
  write access, change the organisation.

## Where iMBrace runs

An organisation lives either on iMBrace's cloud or on the customer's own installation - on
their own servers or in a private cloud. Ask the person which, before you design anything.

- On their own installation, point the SDK and the MCP connection at that installation's
  gateway address, never at the cloud addresses in the site's examples.
- Which AI models read the data is set per installation and per organisation. Before any
  personal data goes in, the person confirms with whoever runs the installation that every
  model the organisation uses - for chat, document reading and search - runs inside the
  deployment. Until that is confirmed, use invented data only.

## The stance

- **The person decides; you assist.** Propose designs, rules and approvals; do not settle them
  on the person's behalf.
- **Never trust a report on a build, including your own.** Run it, check the result on the
  platform, and show the output. A green you did not see is not a green.
- **Say the honest status** of every part you touch: **proposed** (designed, not built),
  **built** (not yet run on the platform and checked), or **live** (run, and the result
  checked by a person).

## Where facts come from

- **SDK, CLI, MCP and API facts: never from memory.** Fetch https://engineer.imbrace.co/llms.txt
  and read the page it points to - the page itself, not a summary of it. The site is also
  served as developer.imbrace.co; the two addresses are the same site. If you cannot reach
  it, read the installed SDK package (type definitions in TypeScript, source in Python). If
  neither is available, say so and ask; do not guess a method, a field or an endpoint. In a
  plan as well as in code, name the engineer.imbrace.co page you will read for each SDK, CLI
  or MCP fact the build depends on.
- **What exists in the organisation** - boards, workflows, agents, connections, recent runs:
  ask the organisation over the MCP connection. Look before you build.
- **How to design it:** this folder.

## The MCP connection

- **Read-only until write access is added.** The MCP page shows the flag that adds create and
  update, and the one that adds delete. Use them only on a test organisation.
- **Agents and file uploads go through the SDK** or the platform's own screens.
- **Where MCP is not enabled on an installation**, work through the SDK or the CLI.

## Read order for designing a new build

1. `build-it-well/use-case-shapes.md` - name the shape the problem takes and sketch the parts
   in plain words. Show the person the sketch before building anything.
2. `build-it-well/native-first.md` - find the platform's own step or capability before you
   write code.
3. The principle in `build-it-well/the-eight-principles.md` that governs the decision in front
   of you. Not all eight at once.
4. `build-it-well/human-approval.md` - wherever a person has to decide.
5. `build-it-well/document-models.md` - whenever documents are read.
6. `build-it-well/anti-patterns.md` and `build-it-well/review-checklist.md` - before calling
   anything done.

When the person is following the tutorial (`build-it/vibe-coding-tutorial.md`), follow its
steps in order instead; this read order is for designing a new build. When they go on to
make the desk wait for a person, follow `build-it/make-it-wait-for-a-person.md` in the same
way. New to the platform: `build-it/set-up-your-coding-tool.md` first. How to work with the
person: `build-it/working-with-ai.md`.

## Rules for every build

1. **No credential** in a workflow, a code step, a prompt, a webhook call, or a committed
   file. Credentials live in the organisation's connection store, or in a local `.env` that is
   never committed.
2. **A test organisation's key only.** Never a production key.
3. **Rules and thresholds live as rows a person can edit**, not in an agent's instructions.
4. **The model decides which rule applies; a calculation step does the arithmetic.**
5. **Every number in an answer carries its source**, or the answer says plainly that it is not
   in the data.
6. **A decision that matters is a recorded value on a row** - who, what, when - and nothing
   downstream runs without it. The person decides from where they already work: an email with
   Approve and Reject buttons, each opening a confirm page, where only the page's Confirm
   decides (opening a link decides nothing) - never by editing a cell in a board. The run
   pauses while it waits, then the same run carries on and tells the requester. A reply in a
   chat is not an approval. The agent must never be
   able to write the decision itself: give an agent narrow tools that write only what it owns,
   never a whole board.
7. **A code step is pure** - inputs in, a result out, no network call, no key - or it says
   plainly why not. Never write a network address of the machine into a workflow.
8. **A refusal is data; a skipped check is never a pass; a step is verified by its outcome.**
   Check the record the step should have written.
9. **Personal data stays inside the deployment it belongs to.** Not in test data, logs,
   examples, or prompts to services outside that deployment. Invent test data.
10. **Reusable logic carries no customer names.** Everything specific to one company arrives as
    configuration.

## Working with the person

- Start from the business outcome: who uses it, what breaks today, what it unlocks.
- Let the person sketch the design before you propose one, then disagree with evidence where
  you must.
- Anchor every claim about their build: a board row, a run's id, pasted output.
- When you were wrong, say so, with the date. Do not quietly change the answer.
- Match the ceremony to the size of the change.

## Language

This guide ships in three languages: English at the paths above, Traditional Chinese under
`zh-tw/` and Simplified Chinese under `zh-cn/`, each with the same pages at the same relative
paths. When the person writes in Chinese, read the copy under `zh-tw/` or `zh-cn/` that matches
how they write, and answer in the language they used. English is the reference: where a
translated page and the English page differ, the English page governs.

## About this guide

This is the community edition: the same method as the partner build guide, with no
partner name attached. `VERSION` says which edition this is; `CHANGELOG.md` says what
changed. If a page misled you, tell the person - open an issue at
https://github.com/imbrace-co/api-sdk/issues (the public iMBrace repository). This edition has no partner-specific contact, so that is
the most useful place to send it.

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== understand/overview.md ====================

---
title: What iMBrace is
description: What iMBrace is, how it keeps AI dependable, and what governs it - enough to explain to a customer who might fit.
level: '0'
track:
- sell
- build
- deploy
verified_on: 2026-09-29
---

# What iMBrace is

iMBrace is an enterprise AI platform. It gives a company AI agents that answer questions from
its own approved knowledge, software that reads documents and turns them into structured
records, and workflows that carry out everyday business processes. A company can run it fully
on its own servers, in a private cloud, or as SaaS. The company chooses where its data lives
and which AI model reads it.

## Intelligent and accurate

iMBrace pairs AI that understands with steps that are exact, so a whole business process runs
end to end, reliably.

- Agents understand what people ask and answer from the company's own approved knowledge. When
  something is not in that knowledge, the agent says so.
- Workflows carry out the work precisely: routing, checks, calculations and updates to other
  business systems, the same way every time.
- People make the decisions that matter: a workflow waits for the right person's approval, then
  carries on by itself.

Together they run real business processes, not just conversations.

## Why it is governed

An AI agent that works inside a company's systems needs clear controls. iMBrace builds them in.

- Access is layered: by team, so people only see the knowledge and data of the teams they
  belong to; by role, so a person's permissions match what they are meant to manage versus use;
  and, on Enterprise installations, by individual field on a record, so one board can show
  different detail to different readers.
- The platform keeps a record of activity across it - logins, file uploads, channel changes,
  and changes to a Data Board - each one timestamped and, where a person did it, attributed to
  them. On Enterprise installations, that record extends to AI agent activity too.
- A workflow can pause at a decision that matters and wait for a named approver - for hours
  or days if needed. The approver decides from where they already work: an email with Approve
  and Reject buttons, each opening a page where they confirm. Opening the link decides
  nothing. Once they confirm, the same workflow picks up on its own and finishes what it was
  doing. Who decided, what they decided, and when is recorded with it.
- These rules are enforced by the platform's own checks, not by anything typed into a prompt.
- The company decides where the platform runs and which AI model it uses, including a model
  that never leaves its own building.

## How the pieces fit together

Customers and staff reach the platform through a channel they already use: a chat widget,
WhatsApp, or another connected channel. An agent answers, backed by the company's approved
knowledge. When something needs doing, a workflow does it, reaching into the company's other
business systems as needed. Anything the platform pulls from a document, or produces as a
record, lands on a structured board - and that record is what makes the answer, or the action,
checkable afterwards. One set of governance rules sits across the whole loop.

Screen: Diagram: how iMBrace works, from channel to agent, workflow and board, under one governance layer
*How iMBrace works: a channel reaches an agent, backed by approved knowledge; a workflow does the work; results land on a board - all under one governance layer.*

That is the platform in one pass. [What iMBrace does today](./capability-truth-table.md) sets
out the detail, area by area, with a page or a screen where you can see each capability for
yourself.

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== understand/capability-truth-table.md ====================

---
title: What iMBrace does today
description: A capability-by-capability list of what iMBrace can do right now, with a page or a screen where you can check each one yourself.
level: '0'
track:
- sell
- build
- deploy
verified_on: '2026-09-30'
---

# What iMBrace does today

Every row below is a capability that works in iMBrace today, checked against a real page or
the product itself - not a plan or a roadmap. Where a row is marked "(Enterprise
installations)", that capability belongs to that kind of installation; everything else is
available generally. Edition and pricing questions go to your iMBrace contact.

## Reaching customers and staff

| What you can do | Where to see it |
|---|---|
| Talk to customers over WhatsApp, Facebook Messenger, Instagram, LINE, WeChat, email, or a web chat widget on your own site - all from one shared inbox | the product (Conversations) |
| See every conversation tracked with its own status - online, overdue, rep needed, pending, or closed - so your team always knows what needs a reply | the product (Conversations) |
| Split conversations by team, in either a first-come-first-served mode or one where everyone on the team can join freely | the product (Teams, Conversations) |

## Agents and knowledge

| What you can do | Where to see it |
|---|---|
| Build an AI agent with its own personality, tone, and core task, and give it reference material to answer from - PDF, Word, plain text, CSV, or Excel files are all accepted | the product (AgentIQ) |
| Point an agent at knowledge your organisation already holds, instead of re-uploading it | the product (AgentIQ, Knowledge) |
| Limit a knowledge folder or board to selected teams, so only the people on those teams can see what is in it | the product (Knowledge) |
| Keep an agent's context through a longer back-and-forth: it remembers earlier turns in the same conversation | the product (AgentIQ, Advanced Settings) |
| Set up an orchestrator agent that hands part of a task to one or more specialised sub-agents | the product (Create Your AI - Orchestrator) |
| Call an agent, or a document-extraction step, from inside an automated workflow, so an AI step runs as part of a bigger process rather than a separate chat | the product (Workflows - AI Agent Skills) |

## Documents

| What you can do | Where to see it |
|---|---|
| Turn a PDF or an image - an invoice, a form, a receipt, a contract, a business card, and more - into a structured record, using a model that reads the layout rather than a fixed template | https://engineer.imbrace.co/sdk/document-ai |
| Set up the extraction once, as a Document Model, and reuse it for every document of that type; a version history shows how it changed | the product (DocIQ, Document Models) |
| Send the extracted result straight to a Data Board, mapped to the columns you choose, and to more than one board at once if you need it | the product (DocIQ) |
| Tell DocIQ which language your documents are in, to improve extraction accuracy, including documents with handwriting | the product (DocIQ, Settings) |
| Upload reference material to a knowledge folder in a wide range of formats - PDF, Word, PowerPoint, Excel, CSV, video, or image files | the product (Knowledge) |
| Limit which teams can use a given Document Model, the same way you limit a knowledge folder | the product (DocIQ, Document Models) |

## Data and workflows

| What you can do | Where to see it |
|---|---|
| Keep structured records on a shared Data Board that every workflow, agent, and person reads and writes | the product (Knowledge, DataIQ) |
| Start a workflow from an incoming message on a connected channel, a schedule, or a change to a Data Board record - created, deleted, or a chosen field updated | the product (Workflows, FlowOps) |
| Reach an outside system from inside a workflow through a pre-built connector - iMBrace ships natively integrated with more than 100 services, from a CRM to a spreadsheet to a ticketing tool | the product (Integrations) |
| Keep a connector's credentials in the organisation's own store, separate from the workflow itself, so a shared or exported workflow definition carries no key | https://engineer.imbrace.co/sdk/workflows |
| Pause a workflow at a decision that matters and hold its place while a specific person decides, then pick the same run back up when they answer, with who decided, what they decided, and when recorded against it. If nobody answers, the run stays paused and visible, and nothing goes out | the product (FlowOps) |
| Ask that person from where they already work: an email with a card of the facts and two buttons, Approve and Reject, each opening a page where they press Confirm. Opening a link decides nothing, and once one answer is confirmed the other button stops working | the product (FlowOps), and the emailed card |
| Finish the job after the answer: once approved, the finished PDF and Excel documents are emailed to the person who asked; if rejected, that person is told and no documents go out. A request that already meets the rules skips the approval, and its documents are emailed straight away | the product (FlowOps, and the requester's inbox) |

## Access and governance

| What you can do | Where to see it |
|---|---|
| Restrict a knowledge folder or a Data Board to selected teams, so a person only sees the teams they belong to | the product (Teams, Access Control) |
| Set a member's permissions by role within a team - for example, a Team Admin versus a Representative | the product (Teams) |
| Restrict an individual field on a record to a specific role, so one board can show different detail to different readers (Enterprise installations) | the product (Access Control) |
| Look back at a record of activity across the platform - logins, file uploads, channel changes, and changes to a Data Board - each one timestamped and, where a person did it, attributed to them | the product (Audit Log) |
| Extend the activity record to AI agent actions as well (Enterprise installations) | the product (Audit Log) |
| Have access rules enforced by the platform's own permission checks, not by anything written into a prompt | the product |

## Where it runs

| What you can do | Where to see it |
|---|---|
| Run iMBrace as a hosted service on iMBrace's own cloud, with nothing to install | https://engineer.imbrace.co/getting-started/setup |
| Install iMBrace on your own infrastructure - a single on-premise server, or a private cloud deployment - instead of the hosted service | https://engineer.imbrace.co/install/kubernetes |
| Choose which AI model answers each agent's questions - a system default, or a provider you connect and manage yourself, model by model | the product (LLM Providers) |

## Building on it

| What you can do | Where to see it |
|---|---|
| Build against iMBrace with an official SDK in TypeScript or Python | https://engineer.imbrace.co/sdk/installation |
| Connect an AI coding tool to a live organisation over one URL and one key - read-only until you turn on write access, one permission at a time | https://engineer.imbrace.co/mcp/overview |
| Hand your coding tool the platform's own map of itself, so it writes correct code on the first try instead of guessing a method name | https://engineer.imbrace.co/llms.txt |
| Manage boards, agents, workflows, and document-extraction jobs from the terminal | https://engineer.imbrace.co/cli/overview |

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== build-it/index.md ====================

---
title: Build it
description: Level 2 of the iMBrace course - build a small working return desk on a test organisation, then make it wait for a person.
level: '2'
track:
- build
---

# Build it

Earlier levels of the course explain what iMBrace is and show a use case working end to end.
This level has you build one yourself.

## What this level gets you

By the end you can build a small working return desk on a test organisation, and make it
wait for a person's decision, with whatever AI coding tool you already use. Nobody needs to
hand you source code to get there - you need a test organisation, a key, and your coding
tool connected over MCP.

- [Set up your coding tool](set-up-your-coding-tool.md) - a test organisation and key, and
  your coding tool connected to the organisation. Do this first.
- [Vibe coding on iMBrace - Build it](vibe-coding-tutorial.md) - the written tutorial.
  Follow it in order; it is written to be followed once, start to finish, on a real test
  organisation.
- [Make it wait for a person](make-it-wait-for-a-person.md) - a second sitting that starts
  from the finished desk and makes it ask a person by email and wait for the answer before
  anything is promised to the customer.
- [Working with an AI coding tool](working-with-ai.md) - the stance and guardrails that keep
  what your tool builds trustworthy.

## Before you start

- A test organisation and an API key. Never a production key.
- Any AI coding tool that can hold an MCP connection and read a text file. This tutorial
  names none, on purpose - it works with whichever one you already use.
- About an hour for the tutorial. Make it wait for a person is a second sitting, and needs
  two email addresses you can read.

## After this level

Level 3, Build it well, is the method behind the habits this page teaches: why each one
matters, what it looks like when it is missing, and how to tell the difference before a
customer does. Level 2 gets you a working agent. Level 3 is what makes one worth shipping.

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== build-it/set-up-your-coding-tool.md ====================

---
title: Set up your coding tool
description: Connect an AI coding tool to a test organisation over MCP and give it the SDK's map - a test organisation and key, the MCP connection, and a check that it all works.
level: '2'
track:
- build
verified_on: 2026-09-29
---

# Set up your coding tool

Five steps, about fifteen minutes. At the end, your AI coding tool can see what exists in a
test organisation and write code against the SDK without guessing.

**Direction here, facts there.** The SDK, CLI and MCP documentation lives at
[engineer.imbrace.co](https://engineer.imbrace.co) and changes on its own schedule. This page
names the page to read for each step and copies nothing, because a copied reference goes
stale and a stale reference is worse than none.

*Last checked against the site: 23 September 2026.*

## 1. A test organisation and an API key

Build in a test organisation, never in production. Treat an API key like the organisation's
own password: it acts with its role's full access. A production key never goes into a coding
tool, a test run, or a pipeline.

A test organisation can live on iMBrace's cloud or on your own installation - on your own
servers or in a private cloud. Whoever runs your installation can create one.

How to generate a key from the dashboard: the [API key
guide](https://engineer.imbrace.co/guides/api-key/).

Screen: Settings Generate External Token tab with the expiration field and Generate Token button
*1 Settings > Generate External Token tab. 2 The Generate Token button.*

## 2. Install the SDK and set its credentials

Follow the docs' [Setup Guide](https://engineer.imbrace.co/getting-started/setup/): it installs the SDK, sets the credentials and points the client at your organisation. Keep the key in a `.env` file that is never committed, and give your coding tool the variable names, not the values: a live key pasted into a chat with a coding tool is a key you no longer control.

## 3. Connect your coding tool to the organisation

The platform's gateway hosts a Model Context Protocol (MCP) server, so there is nothing to
install or run. You give your tool the server's address and your key, and it then sees
what that key's role allows and no more - and, until you add write access, only the reading
side of it (see below).

The per-tool steps are on the [MCP page](https://engineer.imbrace.co/mcp/overview/). Follow
them there rather than from a copy, because the address and the flags are the site's to
change. If you would rather run a local server, the [CLI](https://engineer.imbrace.co/cli/overview/)
can do that too.

What the connection covers:

- **It is read-only until you add write access.** Out of the box your tool can look but not
  change anything. The MCP page shows the flag that adds create and update, and the one that
  adds delete. Use them only on a test organisation.
- **Agents and file uploads go through the SDK** or the platform's own screens.
- **Availability depends on your installation and edition.** Whoever runs your installation
  can confirm it is enabled. Where it is not, your tool works through the SDK or the CLI.

With the connection in place your tool has both halves: this guide answers "how should this
be built", and the organisation answers "what exists here" and "what did that workflow do on
its last run".

## 4. Give your tool the SDK's own map

When your tool writes code against the SDK, it should fetch the site's
[llms.txt](https://engineer.imbrace.co/llms.txt) and read the page it points to, rather than
answer from memory. The site's [vibe coding guide](https://engineer.imbrace.co/guides/vibe-coding/)
shows how to hand it over in each tool.

If your machine cannot reach the site - an isolated network, for example - the SDK you
installed carries its own description of every method: type definitions in the TypeScript
package, readable source in the Python one. Your tool can read those instead. Either way, it
must never guess a method name.

## 5. Prove the setup

Ask your tool two things, then check both yourself:

1. "List the boards in this organisation." It should answer through the MCP connection. On a
   new organisation an empty list is the right answer, not a failure.
2. "Make one read-only SDK call that lists the boards, and show me the output." The same
   list should come back through the SDK.

If both agree with what you see in the platform, you are set up. If either fails, it is a
credentials or connection problem; fix it here before you build anything.

## Next

[The tutorial](vibe-coding-tutorial.md) builds a small working agent with your tool, one
step at a time. [Working with an AI coding tool](working-with-ai.md) is the stance that
keeps what it builds trustworthy.

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== build-it/vibe-coding-tutorial.md ====================

---
title: Vibe coding on iMBrace - Build it
description: Build a small working agent on a test organisation, with any AI coding tool.
level: '2'
track:
- build
verified_on: 2026-09-30
---

# Vibe coding on iMBrace - Build it

This is Level 2 of the course: Build it. Earlier levels show a use case working end
to end; this page has you build one yourself.

By the end you will have a small working return desk on your own test organisation: two
boards, a refund rule anyone can edit, a calculation and an assistant that takes a return in
conversation. It is small on purpose. The point is not the desk - it is four habits that make anything
you build on iMBrace easy to trust, which Level 3 (Build it well) then covers in depth.
The next lesson, [Make it wait for a person](make-it-wait-for-a-person.md), builds on this
desk and adds the fifth: a person decides before anything is promised to the customer.

## What you will build

Imagine a fictional company, Harbor Bicycle Co., that sells and services bicycles online.
You are building their return desk. A customer writes in asking to return an item. The
desk should:

1. Log the request as a row on a board, instead of leaving it in a chat transcript.
2. Work out the refund amount from a rule anyone at Harbor could edit, not from the
   model's own arithmetic.
3. Have an assistant take the return in conversation: it logs the return, names no refund
   figure and promises nothing - a person has not decided yet.

The desk stops there on purpose. Decision, Decided by and Decided at stay empty: they are
the record that [Make it wait for a person](make-it-wait-for-a-person.md) fills in when a
person answers an email - never by typing into a cell.

Nothing here is Harbor Bicycle Co.'s real system - it does not exist. Swap the company,
the items and the rule for your own before you show this to anyone.

## What you need

- A test organisation and an API key. If you do not have one yet, the [API key
  guide](https://engineer.imbrace.co/guides/api-key/) shows how to generate one from the
  dashboard. Use a test organisation's key here - never a production one.
- An AI coding tool connected to that organisation over MCP, so it can see your boards and
  workflows directly instead of guessing. This page names no tool; any coding assistant
  that can hold an MCP connection and read a text file works. The [MCP
  guide](https://engineer.imbrace.co/mcp/overview/) has the exact connection steps for
  your tool - do that first, before Step 1 below. If MCP is not enabled on your installation,
  [Set up your coding tool](set-up-your-coding-tool.md) shows the SDK route.
- If your tool prefers to write real SDK code rather than call the platform directly, install
  the SDK for your language:

  ```bash
  npm install @imbrace/sdk
  ```

  ```bash
  pip install imbrace
  ```

  Either way, your tool will end up needing two environment variables:
  `IMBRACE_API_KEY` and `IMBRACE_ORGANIZATION_ID`. Keep them in a local `.env` file that
  is never committed anywhere, and never paste a live key into a chat with your coding
  tool if you can hand it the variable name instead.
- About an hour. Most of it is reading what the platform hands back to you, which is the
  habit this whole page is trying to build.

A few words this page uses: a **board** is a structured table you shape yourself - rows and
typed columns, like a lightweight CRM sheet. A **workflow** (also called a flow) is a
sequence of steps that runs on its own once triggered. A **native step** is a ready-made
step the platform ships - nothing to write, nothing to host, no key of your own to manage.
An **agent** is the conversational front end a person or a channel talks to.

## Steps

### 1. Look before you build

Do not open an editor yet. Ask your coding tool what already exists.

**You type**, roughly:

> Before we build anything: what boards already exist in this organisation? And
> search the platform's catalog of native workflow steps for anything related to sending
> an email and reading one.

**You should see**: on a new test organisation, an empty list of boards - that is expected, not a
failure. On an organisation that already holds other work, other boards appear at this first
check instead - that is fine too; once you create yours in Step 2, look for it there by name.
Either way you should also see a short list of native steps for email, likely alongside other
channels you did not ask about. Read the list. This is the first habit: find the node the
platform already ships before you consider writing one yourself. A step your tool writes from
scratch costs you a credential to hold and a piece of code to maintain; a native step costs
neither. The email steps on that list are the ones [Make it wait for a
person](make-it-wait-for-a-person.md) uses.

### 2. Create the board that holds return requests

**You type**:

> Create a board called Return Requests with these columns: Customer name, Order
> reference, Item, Condition, Price, Refund amount, Decision, Decided by, Decided at.

**You should see**: a new board in your organisation with those nine columns and no rows yet.
Open it in the platform and check the column names and types by eye - do not just trust
your tool's summary of what it did. The last three columns, Decision, Decided by and Decided
at, are the record of a person's answer: nothing in this lesson fills them in, and [Make it
wait for a person](make-it-wait-for-a-person.md) does.

If your tool says it cannot create anything, its MCP connection is read-only - that is the
default. Add write access as the MCP page describes (a flag on the connection address), and
only ever on a test organisation.

### 3. Add two test rows

Use synthetic data. Never real customer or order information, even in a test organisation.

**You type**:

> Add two rows to Return Requests. Make up obviously fake customer names and order
> references. Row one: an unopened helmet, price 45. Row two: a used bike lock, price 28.
> Leave Refund amount, Decision, Decided by and Decided at blank.

**You should see**: two rows, Condition set to "unopened" and "used", Price filled in, the
last four columns empty.

Screen: Return Requests board open, showing its columns and two rows
*1 Knowledge > DataIQ in the sidebar. 2 The Return Requests board's columns and rows.*

### 4. Put the refund rule where a person can change it, not in a sentence

This is the second habit, and the one that matters most on this page. It would be faster to
tell the agent "refund in full if unopened, half if used" in its instructions. Do not. A
rule written into an agent's instructions cannot be edited by anyone who is not editing the
agent, cannot be quoted back to a customer, and cannot be audited later. A rule that lives
as a row can be all three.

**You type**:

> Create a second board called Refund Rules with two columns, Condition and Refund
> percent. Add two rows: unopened, 100. used, 50.

**You should see**: a two-row, two-column board. Anyone at Harbor Bicycle Co. could open
this and change 50 to 60 without touching a workflow or an agent.

Screen: Refund Rules board, its two rows anyone at Harbor could edit
*1 Knowledge > DataIQ in the sidebar. 2 The Refund Rules board's two rows.*

### 5. Build the workflow, and let one small step do the arithmetic

**You type**:

> Build a workflow called Calculate refund amount on the Return Requests board that runs
> when a row is added or changed. It should: read the row's Condition, look up the matching
> row on Refund Rules, multiply
> Price by Refund percent using a plain calculation step, and write the result into Refund
> amount. Use native steps for the board reads and writes. Only the multiplication itself
> should be a step you write, and keep it pure - it takes the two numbers in, returns one
> number out, and touches nothing else. No network call, no credential, inside that step.

**You should see**: a workflow you can open in the platform's own editor and read top to
bottom without opening any code. Most of its steps are native. Exactly one step is the
short calculation your tool wrote, and it is short enough to read in ten seconds. Run it
once by hand if your tool offers a test-run option, and check Refund amount lands at 45
for the unopened helmet and 14 for the used lock.

Screen: Calculate refund amount workflow: the board read, the calculation step and the board write, top to bottom
*1 Find the matching row on Refund Rules (native). 2 Calculate refund - the one step written by hand. 3 Write Refund amount back to the row (native).*

This is the third habit: a model is good at deciding which rule applies and bad at being
trusted to multiply correctly under pressure, silently, every single time. Let a
calculating step do the arithmetic. Ask the model to decide; let code compute.

### 6. Create the agent

Agents are created with the SDK's AI agent methods (the site has them) or in the platform's
agent screens, so this step uses one of those. Either way, your tool can write the agent's
instructions.

**You type**:

> First build a workflow called Log return request that the agent can call as a tool. It
> takes Customer name, Order reference, Item, Condition and Price, creates one row on
> Return Requests with only those five values, and writes nothing else. Then create an AI
> agent called Return Desk Assistant and give it that one tool - not the board itself. Its
> job: when a customer describes an item they want to return, log it with the tool and reply
> that their request is being reviewed. It must never state a refund amount and never
> promise anything - a human has not decided yet.

Screen: AgentIQ's agent list, the Return Desk Assistant card
*1 Actions > AgentIQ in the sidebar. 2 The Return Desk Assistant agent's card.*

Why a tool and not the board: an agent given the whole board can write any column on it,
including Decision - it could approve its own request. The tool can only write the five
columns a customer supplies, so the decision stays with a person (the next lesson builds how
a person decides). This is the fourth habit: give an agent one narrow tool for the one thing
it must do.

One more point worth building into the agent's own instructions: Refund Rules is matched by
an exact value, so tell the agent to write Condition using the rule's own two words -
"unopened" or "used" - never the customer's own phrasing or a translation of it. Any board a
natural-language agent writes to, when a workflow looks a row up by exact match, needs the
same care.

**You should see**: chatting to the new agent with something like "I'd like to return
order HB-2044, a helmet, still unopened. My name is Morgan Ellery and it cost 39" produces a
new row on Return Requests with those details filled in, and a reply along the lines of
"your return request has been logged and is being reviewed by the team" - no number, no
promise. A few seconds later Refund amount fills in on that row by itself: 39 for the
unopened helmet. Nobody reviews the request yet; [Make it wait for a
person](make-it-wait-for-a-person.md) adds the person who does. If your tool's draft
instructions let the agent guess a refund figure itself, that is worth catching here: send it
back and ask for the number to be removed from what the agent is allowed to say. Then ask it
to approve the request itself: it must not be able to, because nothing in its tool can write
Decision.

Screen: Return Desk Assistant's reply: logged and under review, no figure, no promise
*1 InsightsIQ in the sidebar. 2 The assistant's reply names no refund figure and makes no promise.*

## How to check it worked

Do not take your coding tool's summary of what it did as proof. A plausible account of a
working build is easy to produce and easy to mistake for a real one - go and look.

- Open Return Requests. Both rows should show a correct Refund amount: 45 and 14. Decision,
  Decided by and Decided at are empty on both.
- Open the run history of Calculate refund amount and read the actual status of each run,
  not a summary of it: each run shows as finished.
- Talk to the Return Desk Assistant with a new, made-up return. Confirm a row appears, its
  Refund amount fills in by itself a few seconds later, and the agent's reply carries no
  figure and no promise.
- Ask the assistant to approve a request. Confirm Decision stays empty: the agent has no way
  to write it.

If any of these do not hold, that is more useful than a build that looked fine and was
not. Fix the one thing that failed and check again.

## What to do next

- Go on to [Make it wait for a person](make-it-wait-for-a-person.md), a second sitting. It
  starts from this desk and makes it ask a person by email before anything is promised to the
  customer.
- Try a second condition - a part returned with a missing box, say - and a second rule row.
  Confirm you can change the refund rate without touching the workflow or the agent.
- Read Level 3, Build it well, for the fuller method behind these habits - it covers
  what makes a build like this one survive being handed to a real customer, not just a
  test organisation.
- For anything about the SDK, the CLI or the MCP connection itself, [engineer.imbrace.co](https://engineer.imbrace.co)
  is the source that stays current - this page will drift before that one does. [Set up
  your coding tool](set-up-your-coding-tool.md) has the set-up in full.

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== build-it/make-it-wait-for-a-person.md ====================

---
title: Make it wait for a person
description: Make the return desk ask a person by email and wait for the answer, so the same run records the decision and tells the customer.
level: '2'
track:
- build
verified_on: 2026-10-02
---

# Make it wait for a person

This lesson makes the return desk from [the tutorial](vibe-coding-tutorial.md) wait for a
person. A new return sends the duty manager an email with two buttons, Approve and Reject,
and nothing is promised to the customer until they answer. When they do, the same workflow
run carries on: it writes the decision, the reviewer's name and the time on the row, then
tells the customer.

It is a second sitting. Start from the finished desk; nothing you built in the tutorial is
thrown away.

## What you will build

A return that waits for a person before anything reaches the customer. You play the
reviewer, Jordan Vance, the duty manager at Harbor Bicycle Co., from your own inbox.

1. A new return lands on the board and its refund is worked out, as before.
2. The desk emails the reviewer the facts of the return with two buttons, Approve and
   Reject, and pauses. While it waits, nothing goes to the customer.
3. Each button opens a page that shows the choice. Opening it decides nothing; only the
   page's Confirm button does.
4. When the reviewer confirms, the same run carries on: it writes Decision, Decided by and
   Decided at on the row, then emails the customer - the refund amount if approved, a plain
   apology with no figure if not.

Nobody types into a cell to decide. Nothing here is Harbor Bicycle Co.'s real system - swap
the company, the reviewer and the wording for your own before you show this to anyone.

## What you need

- The desk you finished in [the tutorial](vibe-coding-tutorial.md), on the same test
  organisation: the Return Requests and Refund Rules boards, the Calculate refund amount
  workflow (a new row gets its Refund amount by itself) and the Return Desk Assistant.
- The same AI coding tool, connected to that organisation over MCP with write access, as in
  the tutorial.
- Two email addresses you can read: one to play the reviewer, one to play the customer.
  Two addresses that reach one inbox will do, such as an alias of your mail account. Use only
  your own addresses - never a real customer's, never a colleague's.
- An email connection named Gmail on the organisation, or a person who can sign in to make
  it. Step 1 shows where to look.

A few words this page uses: a **run** is one go of a workflow, and a run that is **paused**
has stopped at its wait and carries on from the same place once someone answers. The
**reviewer** is the person the email goes to; Decided by records their name. A **one-time
link** is an address that works for one answer and ends in a random code; the desk keeps
only a **fingerprint** of that code, a one-way scramble that can check a code but never give
it back. After the answer, the link says the return is already decided. The **confirm page**
is the page a button in the email opens: it shows the choice, and only its Confirm button
records it. An **approval task** is the item the run creates and waits on, with two answers,
Approve and Reject; the person answering never has to see it. A **decision link** is the
approval task's own link for one answer: it decides the moment it is opened, so it stays on
a private board (Step 2 builds it) and never goes in an email. A **code step** is a small
step your tool writes, as against a native step the platform ships.

## Steps

In the prompts below, square brackets mark a value your tool fills in. The only ones you
supply are the two email addresses you read: the reviewer's in Step 3 and the customer's in
Steps 4 and 5.

### 1. Get the desk ready

Two small things first: a place for the customer's address, and the email connection.

**You type**:

> Add a Customer email column (plain text) to Return Requests. Leave every row as it is.

The confirmation email goes to the address on the row, so the desk needs that column. The
email itself goes out through the platform's own connection, never through anything inside
a workflow. Open Actions > FlowOps > More > Connections: the email credential is there as its
own named connection, Gmail. If it is not, a person has to sign in to Gmail once, in each
organisation, to make it - do that before Step 3. Use the button the Connections list
offers for a new connection and sign in with a Google account you can read; the desk's emails
go out from that account.

Screen: FlowOps Connections list showing one connection named Gmail
*1 FlowOps > More > Connections. 2 The one connection named Gmail.*

This lesson is written and checked for a Gmail connection. If you use another kind of email
connection, replace the word Gmail in point 9 of Step 3 with its name before you paste, and
check that both emails arrive before you trust the run.

This is the tutorial's first habit, use what the platform ships, carried through: a credential
belongs to the platform's own connection store, never to a workflow. If you export a workflow
later, open the exported file and confirm no key or password is inside it.

**You should now see**: Return Requests with ten columns, Customer email the last, empty on
every row; and a Connections list with one connection named Gmail.

### 2. Build the page where a decision is confirmed

Before anyone can be asked to decide, decide where they answer. The reviewer will decide from
an email with two buttons, and each button opens a page on iMBrace that shows the choice and
asks them to confirm. This step builds that page and the private board of one-time links it
checks. Step 3 builds the workflow that sends the email.

Read the plain-words list under the prompt first, then paste the whole prompt. It is written
for your tool, so you do not need to follow every technical word in it.

**You paste**, in one message:

> Build the place where a decision gets confirmed, in two pieces.
>
> First, a private board called Return Decision Links with these plain-text columns:
> Fingerprint, Group, Action, Order reference, Decision link, Expires at, Used at, Used
> action, Created at. No Link-type column. Decision link will hold the link that carries the
> decision of an approval task, which the next step creates. Only workflows use this board;
> do not give it to any agent.
>
> Second, a workflow called Confirm a return decision that answers as a public page - no
> sign-in, no key. Use the trigger that answers the caller directly, and reply with raw HTML
> (content type text/html). The page address takes a random code called t. It works like
> this:
>
> 1. Take the code from t (from the address on a visit; from the form field named t when the
>    page's own button is pressed). Work out a one-way fingerprint of it. Compare
>    fingerprints only; never store or show the code.
> 2. Find the row on Return Decision Links with that fingerprint. No code, or no row: show a
>    plain page that says "This link is not valid." with no button.
> 3. If there is a row, read every row that shares its Group, and read the return on Return
>    Requests by Order reference. A link is fresh (not used, not expired), used (Used at is
>    filled) or expired (past Expires at).
> 4. A visit only shows a page and changes nothing. Fresh: "Approve return [order
>    reference]?" (or "Reject return [order reference]?"), the customer, the item and the
>    refund amount, one Confirm button that posts the code back, and the line "Nothing is
>    decided until you press Confirm." Used: "This return has already been decided."
>    Expired: "This link has expired."
> 5. Only when Confirm is pressed on a fresh link: first use the link in Decision link (a
>    plain GET with no credentials; carry on if it fails, so you can read its status). If the
>    status is 200 to 299, mark BOTH rows of that Group used (Used at is now, Used action is
>    the action) and show "Return [order reference] approved" (or "rejected") with a line
>    saying the customer is being emailed. If it fails, change nothing, leave the links
>    usable, and show "Your decision was not recorded. Try the button again in a minute."
>
> Every path ends in a page. Build the page in one small code step that only turns values
> into text and escapes every value it inserts: no network call, no credential. Use native
> steps for the board reads and writes, the call and the responses. When it is published,
> tell me the page address.

**In plain words.** The private board comes first. Each row holds one button's one-time link,
kept as a fingerprint and never as the code itself, and that button's decision link, which
Step 3 fills in. A Group ties a return's two buttons together. Only workflows use the board,
so no agent is given it. Then the page, point by point:

1. The page reads the code from the link and keeps only its fingerprint, so the code itself is
   never stored anywhere.
2. A link that matches nothing gets a plain "not valid" page and no button.
3. A real link is judged fresh, used or expired from the private board; the return's own row
   supplies the facts the page shows.
4. A visit only shows the facts and a Confirm button. Mail scanners and previews open every
   link they find, so opening one must decide nothing.
5. Confirm is the only thing that decides. The page records the answer first, then retires
   both buttons, so a return is decided once; if recording fails, nothing changes and the
   page says so.

Most steps are native. The rest are small code steps that only compute over what they are
given; none makes a network call or holds a credential.

**You should now see**: in Knowledge > DataIQ, a new board, Return Decision Links, with nine
columns and no rows. In Actions > FlowOps, a published workflow, Confirm a return decision;
open the workflow to reach its run history. Ask your tool for the page's address and open it
in a private window with nothing after the address, then with `?t=` and nothing after it,
then with `?t=notacode`. Each time you see one plain page that says "This link is not valid."
with no button. In the run history each visit shows as a finished run, and no board has
changed.

Screen: The confirm page opened with no link: one plain sentence and no button
*The page opened with no link: one plain sentence and no button.*

That plain page is the right first answer: with no link there is nothing to decide, and no
button to press. You meet the page with a real link in Step 4.

If you see anything other than that one sentence, tell your tool exactly what you saw and ask
it to make the workflow answer with a web page that needs no sign-in, then open the address
again before you go on.

The rule behind the page: a link in an email is not a decision. Opening the link only shows a
page; only Confirm decides. The random code is never stored, only its fingerprint, and the
board that holds the fingerprints is private. [Human approval](../build-it-well/human-approval.md)
sets out why.

### 3. Ask by email, wait for the answer, then tell the customer

This is the step where the desk starts to wait. One workflow asks a person by email, stops at
a wait, and only when they confirm does the same run write the decision on the row and tell
the customer. Give your tool the whole prompt in one message - the asking half and the
finishing half belong together - and add no return until it says the workflow is published.
The one value you supply here is the reviewer's address. As in Step 2, read the plain-words
list under the prompt first: the prompt is written for your tool.

**You paste**, in one message:

> Build a workflow called Apply return decision that asks a person to decide by email, waits
> for the answer, then finishes the job. It starts when a Return Requests row's Refund amount
> is written - a "column updated" automation on Refund amount, not "row created". The
> reviewer is Jordan Vance, at [your own address]. Do this, in order:
>
> 1. Read the row. Do nothing unless Order reference and Refund amount are filled in and
>    Decision is empty.
> 2. Read Return Decision Links for this Order reference, newest Created at first, one row.
>    If a row comes back and its Used at is empty, or the read fails, someone is already
>    being asked: stop here. No second task, no second email.
> 3. Get the current time (UTC) with the platform's own date step.
> 4. One small code step turns the row into the decision card: the title "Return [order
>    reference] needs a decision", a one-line summary, and a table of Customer, Order
>    reference, Item, Condition, Price and Refund amount. No decide-by time on it.
> 5. Create an approval task with the platform's own task step: that card as its description
>    and two options, Approve (green) and Reject (red). Assign it to the user my API key
>    acts as. Never leave the assignee empty and never assign it to a colleague.
> 6. One small code step makes two random codes, one for Approve and one for Reject, and a
>    one-way fingerprint of each - the same method the confirm page uses. Each one-time link
>    is the Confirm a return decision page address plus ?t= and its code, valid for seven
>    days. The approval task also has its own decision link for each answer, the link that
>    carries the decision: read those in this point and nowhere else, and never put them in
>    an email, a page, a Return Requests row or a reply.
> 7. Write two rows to Return Decision Links with native board steps, one per button: the
>    fingerprint, Group (the task's id, the same for both), Action, Order reference, Decision
>    link (the approval task's decision link for that answer, as plain text), Expires at and
>    Created at. Used at and Used action stay empty. Never store a code.
> 8. One small code step renders the same card as an HTML email with two buttons, Approve
>    (green) and Reject (red), each pointing only at its one-time link from point 6, never
>    at a decision link, plus the line "Each button opens a page where you confirm. Nothing
>    is decided by opening a link."
> 9. Send it with the platform's own Send Email step for Gmail, through the organisation's
>    Gmail connection, using the newest version of that step the organisation offers. If
>    there is no email connection yet, stop and tell me: a person has to sign in to make it.
>    Sender name "Harbor Bicycle Returns Desk", with no comma in it. Subject "Return [order
>    reference] needs your decision".
> 10. Wait for the approval task (the task step that waits for the answer). Points 5 to 10
>     must run back to back: nothing between them, and nothing anywhere before point 10 that
>     pauses or sleeps.
>
> When the answer comes back and the run carries on:
>
> 11. Read the return again by Order reference.
> 12. Act on the answer. Approve or Reject only counts if Decision is still empty and the row
>     you just read is the row that started the run; anything else writes nothing. Approve:
>     get the time (UTC); write Decision "Approved", Decided by "Jordan Vance (confirmed by
>     email)" and Decided at on the row; only then email the customer at Customer email,
>     subject "Your Harbor Bicycle return is approved", plain text naming the refund amount.
>     Reject: the same with Decision "Rejected", subject "Your Harbor Bicycle return was not
>     approved", and a plain apology that names no refund amount and says to contact the
>     returns desk.
>
> Use native steps for every board read and write, the task, the wait, the clock and the
> emails. Small code steps only for points 4, 6 and 8.

**In plain words**, point by point. The asking half:

1. Do nothing unless the return is ready: it has an order reference and a refund, and nobody
   has decided it yet.
2. One ask at a time: if this return is already waiting for an answer, stop, so a second
   write to the row does not start a second ask.
3. Read the clock, so the links get an expiry time.
4. Put the facts the reviewer needs on one card.
5. Create the approval task the run will wait on: an item with two answers, Approve and
   Reject, owned by the user your API key acts as.
6. Make the two one-time links, one per button, and take the approval task's own decision
   links. Only this point takes them from the approval task; from then on they live only on
   the private board, and only the confirm page uses them.
7. Save each button's fingerprint and its decision link on the private board, where the
   confirm page finds them.
8. Turn the card into an email with the two buttons.
9. Send it to the reviewer through the organisation's Gmail connection.
10. Wait. The run pauses here and holds its place until the reviewer answers.

The finishing half, after the answer:

11. Read the return again, so the run works from the row as it is now.
12. Write Decision, Decided by and Decided at first, then email the customer. Only a first
    answer for the same row counts; anything else writes nothing.

Points 4, 6 and 8 are small code steps of the same kind as the tutorial's calculation: each
only computes over what it is given, makes no network call and holds no credential.

**You should now see**: in Actions > FlowOps, Apply return decision published, and Calculate
refund amount unchanged. Open Apply return decision and read it from the top: the step that
creates the approval task, the step that sends the email through Gmail and the step that
waits come in that order, with nothing that pauses before the wait. To check it, ask your
tool to list the steps of Apply return decision in order, names only, and compare the list
with the canvas. Ask it also to confirm that the fingerprint made here uses the same method
as the one in Confirm a return decision. Do not add a return yet; Step 4 does that.

If your tool asks a question, answer it. If it builds something that does not match the
numbered points, ask it to change the workflow to match them, then read the steps again.

Read a run by the status of each step. A step's contents can hold the links that decide, so
you never need to open one. On a real organisation, let only the people who review builds
open the run history and the Return Decision Links board, and clear old runs.

Screen: Apply return decision workflow: the step that emails the reviewer, then the step that waits
*1 FlowOps in the sidebar. 2 The step that emails the reviewer. 3 The step that waits for the decision.*

### 4. Try an approval

Now run it the way the reviewer would. Use a new order reference for every test return, one
that is not already on the board: the desk tracks each return by its order reference.

**You type**:

> Add a row to Return Requests: customer Morgan Ellery, order reference HB-3001, item
> helmet, condition unopened, price 45, Customer email [the address you play the customer
> from]. Leave Refund amount, Decision, Decided by and Decided at blank.

**You should now see**, one moment at a time:

1. Within seconds Refund amount fills in on the row: 45. Decision, Decided by and Decided at
   are still empty. In Actions > FlowOps, the run history of Apply return decision shows one
   new run, and the run is paused. The steps that create the approval task and send the
   email are marked succeeded. While it waits, ask your tool for the approval task's status
   and assignee only: it is open and assigned.

Screen: Apply return decision run history: the new run is paused
*1 FlowOps in the sidebar. 2 The new run of Apply return decision, paused.*

2. The reviewer's inbox holds one email, with the subject you asked for. It gives the facts of
   the return - customer, order reference, item, condition, price and refund amount - and two
   buttons, Approve and Reject. Return Decision Links now has two rows, one per button, with
   Used at empty.

Screen: The reviewer's email with its Approve and Reject buttons
*The reviewer's email: the facts of the return and the two buttons, Approve and Reject.*

3. Open Approve. A page shows the choice: the customer, the item and the refund amount, with
   one Confirm button. Nothing has changed. Open it a second time if you like: the run is
   still paused and the row still has no decision.

Screen: The confirm page reached from the Approve button
*The confirm page: the facts of the return and one Confirm button. Nothing is decided until it is pressed.*

4. Press Confirm. The page says the return is approved and that the customer is being
   emailed. In FlowOps the run that was paused is the one that finishes, and no run is left
   paused for this return. On the board the row now reads Decision Approved, Decided by
   Jordan Vance (confirmed by email) and a Decided at time. The customer's inbox holds an
   email that names the refund amount, and both rows on Return Decision Links have Used at
   filled in.

Screen: Return Requests scrolled to Decision, Decided by and Decided at, written by the run
*1 Knowledge > DataIQ in the sidebar. 2 Decision, Decided by and Decided at, written by the run.*

Screen: The same run of Apply return decision, finished, with its two Send Email (Gmail) steps marked succeeded
*1 FlowOps in the sidebar. 2 The same run, finished, with its two Send Email (Gmail) steps marked succeeded.*

5. Back in the reviewer's email, open Reject. The page says this return has already been
   decided. Both buttons retire together, so a return is decided once.

This is the fifth habit: a decision is a value written on a row by the run that asked - the
answer, the reviewer's name and the time - not a person typing "looks fine" into a chat, and
not a cell someone edits. Until somebody answers, nothing goes to the customer and the run
simply waits.

Decided by shows the reviewer you named followed by "(confirmed by email)": the decision was
confirmed from that reviewer's own email, so keep the email to yourself and do not forward it.

If a check in this step does not hold, work back one link at a time. Is Refund amount filled in? Is there
a new run of Apply return decision, and is it paused rather than failed? Are the steps that
create the task and send the email marked succeeded? Then look in your spam folder. Tell your
tool which check stopped and ask it to fix that one thing.

### 5. Try a rejection

Answer a second return the other way.

**You type**:

> Add a row to Return Requests: customer Riley Okafor, order reference HB-3002, item bike
> lock, condition used, price 28, Customer email [the same customer address]. Leave Refund
> amount, Decision, Decided by and Decided at blank.

**You should now see**:

1. The same start as before: within seconds a new paused run, and one email with two buttons
   in the reviewer's inbox.
2. Open Reject, then press Confirm. The page says the return is rejected. The same run goes
   from paused to finished, and the row reads Decision Rejected, with Decided by and Decided
   at filled in.
3. The customer's inbox holds an email that says the return was not approved: a plain
   apology and a line to contact the returns desk, with no refund figure.
4. Open Approve in the same email: the page says the return has already been decided. No
   approval email went to the customer for this return.

## How to check it worked

Do not take your coding tool's summary of what it did as proof. A plausible account of a
working build is easy to produce and easy to mistake for a real one - go and look. You have
already run most of these checks in Steps 4 and 5. The extras are the button-address check,
the approval-task read-back, one ask at a time, the connection and the assistant. If you run
a return again, use a new order reference.

### Approve

1. **It waits.** A new run of Apply return decision is paused within seconds, and its steps
   that create the approval task and send the email are marked succeeded. On the row, Refund
   amount is filled in, and Decision, Decided by and Decided at are empty. While it waits,
   ask your tool for the approval task's status and assignee only: it is open and assigned.
2. **One email, no shortcut.** Exactly one email arrived for the return, with two buttons.
   Ask your tool to print the two button addresses from the email you received, with each code
   shortened. Each is the confirm page's address followed by `?t=` and one code, and nothing
   more. Keep the codes to yourself.
3. **A visit decides nothing.** Open Approve twice. You get a page with one button, the run is
   still paused, and both rows on Return Decision Links still have Used at empty.
4. **Confirm decides.** Press Confirm. The run that was paused finishes, and no run is left
   paused for this return. Decision is Approved, Decided by is the reviewer's name followed
   by "(confirmed by email)", Decided at is a time, and the customer's address received the
   email naming the refund amount. Both rows on Return Decision Links have Used at filled in.
5. **The other button retires.** Reject from the same email says the return has already been
   decided.
6. **The approval task agrees.** Ask your tool for its status only: it now shows answered as
   Approve. Never print its links.

### Reject

1. **The same start.** A paused run and one email with two buttons.
2. **Reject decides.** Press Reject, then Confirm. The same run goes from paused to
   finished. Decision is Rejected, Decided by and Decided at are filled in, and the approval
   task shows answered as Reject.
3. **No figure goes to the customer.** The customer's email says the return was not approved:
   a plain apology and a line to contact the returns desk. Read it for a refund figure - it
   carries no mention of a refund amount and no amount equal to the price.
4. **No approval went out.** The customer received no approval email for this return, and
   the Approve button now says the return has already been decided.

### One ask at a time, the connection and the assistant

- Add one more return and leave it waiting. Use this return only for this check and leave it
  unanswered. Change its Condition. No second email arrives and the first run is still
  paused. A second, short run may appear and finish at once: point 2 of Step 3 stops it.
- Open Actions > FlowOps > More > Connections and confirm the email credential is a named
  connection, Gmail, not text inside a step.
- Ask your tool to read the Return Desk Assistant's setup back: one skill, Log return
  request, and no board, so the links and the decision stay with the workflows.

If any of these do not hold, that is more useful than a build that looked fine and was not.
Fix the one thing that failed and check again.

## What to do next

- Leave a return unanswered. The run stays paused and nothing goes to the customer while it
  waits. The links you asked for in Step 3 are valid for seven days.
- Talk to the Return Desk Assistant with a new, made-up return and watch the run history of
  Apply return decision. Before you decide a return the assistant logged, add the customer
  address in Customer email on its row.
- Read [Human approval](../build-it-well/human-approval.md) for the method behind this lesson:
  where a decision is placed, what makes a gate hold, and how to prove it is wired end to end.
- See [The building blocks](building-blocks.md) for where each part of the desk lives on
  screen: the boards, the workflows, the agent and the email connection.
- For anything about the SDK, the CLI or the MCP connection itself,
  [engineer.imbrace.co](https://engineer.imbrace.co) is the source that stays current - this
  page will drift before that one does. [Set up your coding tool](set-up-your-coding-tool.md)
  has the set-up in full.

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== build-it/working-with-ai.md ====================

---
title: Working with an AI coding tool
description: The stance, habits and guardrails that keep what an AI coding tool builds on iMBrace trustworthy.
level: '2'
track:
- build
verified_on: '2026-09-23'
---

# Working with an AI coding tool

Most building on iMBrace can now be done with an AI coding tool. That is fine, and it changes
almost nothing about what "done" means. This page is what does change.

## The stance

**The tool assists; the person decides.** Not because the tool is weak, but because
accountability does not transfer. Someone signs off that the build works, and it cannot be
the thing that wrote it.

**A build's report on itself is never trusted.** AI tools make this sharper: a convincing
summary of a passing test is easy to produce and hard to tell from a real one. Run it. Watch
it. Look at the result on the platform. A green you did not see is not a green.

**Say the honest status.** Every piece of a build is one of three things:

- **proposed** - designed, not built;
- **built** - built, but not yet run against the platform and checked;
- **live** - run on the platform, and the result checked by a person.

Nobody is judged for "built". Writing "live" for something that never ran is the failure.

## What to give the tool

- **This guide's `AGENTS.md`**, or the one page that governs the job in front of you. Not
  everything at once: a tool that reads everything has less room left for your problem.
- **The SDK's own map**, fetched fresh from [engineer.imbrace.co](https://engineer.imbrace.co/llms.txt)
  when it writes SDK code. Never an old copy.
- **The organisation itself**, over the MCP connection, when the question is about what
  exists or what happened - see [Set up your coding tool](set-up-your-coding-tool.md).

## The guardrails

- **No credential in a workflow, a code step, a prompt, or a committed file.** Credentials
  live in the organisation's connection store, or in a local `.env` that is never committed.
- **A code step is pure** - numbers in, a result out, no network call, no key - or it says
  plainly why it is not.
- **A refusal is data, not an error.** "I could not find that" is a valid, useful answer.
- **A skipped check is never a pass.** If a test could not run, say it did not run.
- **No personal data** in test data, logs, prompts or examples. Invent it.
- **Write for a stranger.** Plain sentences, no shorthand, nothing that only makes sense to
  whoever was in the conversation.

## Habits that carry most of the weight

1. **Business outcome first.** Who uses it, what breaks today, what it unlocks. A clever
   answer to a question nobody asked is a wrong answer.
2. **The person sketches first.** Have the person draw the use case - the shape, the parts,
   where a human decides - before the tool proposes a design. It keeps the design theirs.
3. **Disagree with evidence.** When the tool thinks the person is wrong, it says so at once,
   with the evidence, rather than quietly doing what was asked.
4. **Every claim carries an anchor.** A board row, a run's id, a pasted output. No anchor,
   no claim.
5. **Correct records with a date.** When a finding or a decision note turns out to be wrong,
   say so in place, with the date, and leave the original visible.
6. **Someone else reviews it.** The person who did not build it runs the
   [review checklist](../build-it-well/review-checklist.md) before it ships.
7. **Match the ceremony to the size of the change.** A small change gets a small record.

## Keep delegation shallow

If your tool hands work to its own helpers, keep the hand-off at the top level, give each
helper a complete brief, and check each result yourself: when a helper says it fixed
something, open the file and look.

## What done means

Something another person can install, a note they can follow, a test they can run, and an
honest status on each part.

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== build-it/building-blocks.md ====================

---
title: The building blocks
description: Recognise the five things every iMBrace build is made from, plus the three ways to extend and deliver them, by name and by where each one lives on screen.
level: '2'
track:
- build
verified_on: 2026-09-29
---

# The building blocks

Every use case on iMBrace, however different they look, is built from the same five
things: a board, an agent, a document model, a workflow and a channel. This page names
each one, says what it is for, and shows where it lives in the product, so that nothing on
the sidebar is a mystery the first time you open a training organisation. It closes with
three ways to extend one of these or hand it on to someone else: skills, the MCP
connection, and installing a module.

## A board

A board is a structured table you shape yourself - rows and typed columns, like a
lightweight CRM sheet. It is for holding whatever a build needs to remember: a list of
return requests, a priced quotation, a set of rules a person can edit.

In the sidebar this lives under **Knowledge > DataIQ** (the SDK and its permission scope
call it a board, or a databoard; the product name on screen is DataIQ). Every other
block reads or writes a board: a workflow's steps, an agent's one narrow tool, and a
document model's own extraction all land on one.

Screen: A DataIQ board open as rows with typed columns
*1 Knowledge > DataIQ in the sidebar. 2 The board's typed columns.*

The habit that makes a board trustworthy: put a rule a business person might need to
change - a threshold, a rate, a limit - on a board as an editable row, never inside an
agent's own instructions. [The eight principles](../build-it-well/the-eight-principles.md)
explains why.

Do it in code: [Board](https://engineer.imbrace.co/reference/board/).

## An agent

An agent is the conversational front end a person or a channel talks to. It is for having
the conversation itself: understanding what someone is asking for, and calling the right
tool to act on it.

In the sidebar this lives under **Actions > AgentIQ**. An agent is reached through a
channel, and it acts by calling a workflow - one of its skills, covered below - which is
where any reading or writing of a board actually happens.

Screen: AgentIQ Active AI tab, one agent per card
*1 Actions > AgentIQ in the sidebar. 2 The Sales Quoting agent's card.*

The habit that makes an agent trustworthy: give it one narrow tool for the one thing it
must do, never the whole board, so it can log a request but can never write the decision
that approves it. [Human approval](../build-it-well/human-approval.md) sets out why the
agent must never be able to write that decision itself.

Do it in code: [AI agent](https://engineer.imbrace.co/reference/ai-agent/).

## A document model

A document model tells extraction what to pull out of a file. It is for turning an
unstructured document - an invoice, a form, a scanned packing slip - into the structured
fields a board can hold.

In the sidebar this lives under **Knowledge > DocIQ**, on the **Document Models** tab. What
it extracts lands as rows on a board, the same board a workflow or an agent then reads.

Screen: DocIQ Document Models tab, one model's extraction fields
*1 The Document Models tab. 2 The model's fields table.*

The habit that makes a document model trustworthy: adopt the platform's own default model
before writing a new one, and point extraction at a single board's own fields rather than
leaving the choice of model to chance.
[Document models](../build-it-well/document-models.md) sets out the order to try them in.

Do it in code: [Document AI](https://engineer.imbrace.co/sdk/document-ai/).

## A workflow

A workflow (also called a flow) is a sequence of steps that runs on its own once
triggered. It is for doing the actual work, in a fixed and checkable order: reading a
board, running a calculation, waiting for a person to decide, sending a message.

In the sidebar this lives under **Actions > FlowOps** (the SDK and its permission scope
call it a workflow; the product name on screen is FlowOps). A workflow reads and
writes a board, can be the one tool an agent calls, and can start from a channel event as
easily as from a board changing.

Screen: FlowOps list of workflows
*1 Actions > FlowOps in the sidebar. 2 The list of workflows.*

The habit that makes a workflow trustworthy: build it from the platform's own ready-made
steps first, and keep any step you do write pure - it computes over the values it is given
and holds no credential of its own. [Native-first](../build-it-well/native-first.md) sets
out what that buys you.

Do it in code: [Workflow](https://engineer.imbrace.co/reference/workflow/).

## A channel

A channel is where a person actually reaches an agent - a website chat widget, WhatsApp,
email, or another connected messaging app - and it is the address a reply goes back to.

In the sidebar this lives under **Actions > ConnectIQ**, on the **Channels** tab. A channel
is how a conversation with an agent begins, and a workflow can use one of its events as its
own trigger.

Screen: ConnectIQ Channels tab listing the Web Widget and messaging channels
*1 The Channels tab. 2 The Web Widget's channel list.*

The habit that makes a channel trustworthy: set up its login once as the organisation's
own connection, never as a value sitting inside a workflow. A connection that needs
someone's sign-in, such as a hosted mail service, is made by a person once per
organisation; a mail-server connection is configured once with the server's own details.
[Native-first](../build-it-well/native-first.md) sets out why nothing in a flow should
ever carry a credential.

Do it in code: [Channel](https://engineer.imbrace.co/reference/channel/).

## Three ways to extend and deliver them

### Skills - what an agent can do

A skill is a workflow given to an agent as a named tool it can call. It is for extending
what an agent can actually do beyond talking - logging a row, looking something up,
running a calculation - always through a workflow, never by handing the agent a board
directly.

In an agent's setup under **AgentIQ**, skills sit on the **Behavior Settings** tab, in its
**Skills** section (the SDK's full flow guide calls these tools, under Workflows). Add a workflow here and the agent can call it in a
conversation; its description is what the agent reads to decide when that is the right
moment.

Screen: An agent's Behavior Settings tab, its Skills list of functions
*1 The Behavior Settings tab. 2 The Skills section's list of functions.*

Do it in code: [Full Flow Guide](https://engineer.imbrace.co/sdk/full-flow-guide/).

### The MCP connection - how a coding tool sees an organisation

The MCP connection is how an AI coding tool sees and changes an organisation directly,
rather than being told about it secondhand. It is for building: point a coding tool at it
with an address and a key, and it can list what boards and workflows already exist before
writing a line of anything.

In the sidebar this lives under **Actions > ConnectIQ**, on the **MCP** tab, and it opens
the very guide you would read directly at
[engineer.imbrace.co/mcp/overview](https://engineer.imbrace.co/mcp/overview/).
[Set up your coding tool](set-up-your-coding-tool.md) walks through connecting a coding tool to a test
organisation this way, step by step.

Screen: ConnectIQ MCP tab opening the MCP connection guide
*ConnectIQ MCP tab opening the MCP connection guide*

Do it in code: [MCP Server guide](https://engineer.imbrace.co/mcp/overview/).

### Installing a module

Installing a module copies a whole use case - its workflows, its agent set-up and its
boards - into an organisation in one step, as a single package. It hands someone a working
starting point instead of a set of instructions to follow by hand. Your iMBrace contact
installs modules into your organisation.

Once installed, its boards, workflows and agent appear in their usual screens - DataIQ,
FlowOps and AgentIQ - where an admin can see and edit them like anything else in the
organisation. For a single agent, **AgentIQ** also has a **Marketplace** tab of ready-made
agent templates to start from.

Screen: AgentIQ Marketplace tab of ready-made agent templates
*1 The Marketplace tab. 2 The ready-made template card.*

Do it in code: [SDK overview](https://engineer.imbrace.co/sdk/overview/).

## How they fit together

Harbor Bicycle Co.'s return desk, from the tutorial and [Make it wait for a
person](make-it-wait-for-a-person.md), uses every block at once. A customer
talks to the Return Desk Assistant. The agent listens, and its one skill - a workflow
called Log return request - writes a new row on the Return Requests board. A second
workflow works out the refund from the Refund Rules board. A further workflow asks the duty
manager: it emails a card with Approve and Reject buttons and waits. Each button opens a page
where the manager confirms; then the workflow carries on from where it paused, records the
decision, the reviewer's name and the time on the row, and emails the customer. Nothing here
needed a document model, because nothing arrived as a file - a return that came in as a
scanned packing slip would be read by a document model first, and land as a row on that same
board.

Every one of Harbor's blocks could be packaged as a single module and installed into a
second organisation, its boards, workflows and agent set-up
travelling together for that organisation's own admin to open and adjust. And the same MCP
connection that let a coding tool build all of it in the first place is what lets it check
the result afterwards: list the board, read the workflow's last run.

Build it yourself, one step at a time, in [the tutorial](vibe-coding-tutorial.md), then make
it wait for a person in [Make it wait for a person](make-it-wait-for-a-person.md).

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== build-it-well/index.md ====================

---
title: Build it well
description: What it takes to design an iMBrace build that survives contact with real use, real load, and real oversight.
level: '3'
track:
- build
verified_on: '2026-09-23'
---

# Build it well

A demo shows that something can work once. Building it well means it keeps working: with
real data, under real load, with a person genuinely in the loop, and without anyone having
to remember to be careful.

This is not about writing more code. Most of what makes a build solid is design choices you
make before you write anything: which parts you assemble it from, where a human signs off,
what runs on the platform's own capability instead of custom code, and what never leaves the
build's own configuration.

## The eight principles, in one line each

1. **Provenance** - every number in an answer can be traced back to where it came from, or
   the answer says plainly that it is not in the data.
2. **Determinism** - the AI picks which rule applies; the rule itself lives as data a person
   can edit; the arithmetic is always done the same, reliable way.
3. **Modularity** - the build is assembled from parts that each do one job and have a clear
   contract, not one large tangle of custom logic.
4. **Domain-free cores** - the reusable logic carries no customer names, no specific
   business detail; everything specific to one company arrives as configuration.
5. **Human governance** - a real decision is a recorded fact - who decided, what, and when -
   not a friendly "yes" typed into a chat window.
6. **Native-first** - use what the platform already gives you before writing custom code;
   nothing in a build should ever hold a login credential.
7. **Operability** - a build can be reset, tested, and checked independently, not just run
   once by the person who built it.
8. **Security and sovereignty** - credentials, secrets and sensitive data stay in
   configuration and out of the build's own logic.

## What is on this page and what is on the rest

| Page | What it covers |
|---|---|
| [The eight principles](the-eight-principles.md) | Each principle in full: what it means, what good looks like, how it goes wrong, and the questions to ask of your own build. |
| [Use-case shapes](use-case-shapes.md) | Nine recurring shapes a business use case takes, and the kinds of parts each one is typically assembled from. |
| [Human approval](human-approval.md) | How a person decides from an email with Approve and Reject buttons, confirmed on a page - and why a chat reply is not a decision. |
| [Native-first](native-first.md) | Why you reach for the platform's own capability before writing code, and what that buys you. |
| [Document models](document-models.md) | How to choose what DocIQ extracts from a document: adopt the default, extend it, write your own last. |
| [Anti-patterns](anti-patterns.md) | The mistakes that get built again and again, what each one costs, and the fix. |
| [Review checklist](review-checklist.md) | The same eight-principle review, as a checklist you can run on your own build before you ship it. |

None of this requires memorising anything. Pick the page that matches the decision in front
of you, use its questions, and move on.

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== build-it-well/the-eight-principles.md ====================

---
title: The eight principles
description: The eight principles behind a build that survives contact with real use - what each one means, what good looks like, and how it goes wrong.
level: '3'
track:
- build
verified_on: '2026-09-30'
---

# The eight principles

Eight ideas separate a build that works once from a build that keeps working. None of them
require exotic technology. Most are decisions about where a piece of logic lives, and who
gets to change it.

## 1. Provenance

**What it means.** Every number an answer contains can be traced to where it came from, or
the answer says plainly that it is not in the data. A figure with no source behind it is not
a cheaper version of a sourced figure - it is a different kind of thing, and the difference
is invisible until someone acts on it.

**What good looks like.**
- Every figure in an answer comes with the records it was drawn from, and the date the data
  is current to.
- A quoted line is checked against the document it claims to come from, and the answer says
  where in that document it appears.
- When the answer is not in the data, the reply says so plainly, with no invented figure to
  fill the gap.
- Each kind of answer has a fixed shape - which figures, from which sources, in which order.
  A fixed shape stops invented figures where written rules alone do not.

**How it goes wrong.**
- **The confident summary.** A number that reads well, produced by an AI, with nothing
  behind it. It survives review precisely because it reads well.
- **Provenance as decoration.** A source list that names a document but not the specific
  rows or passage, so nobody can actually check the figure without redoing the work.
- **The softened finding.** A flagged problem quietly downgraded on a later pass, with
  nobody noticing it changed.
- **The quote that only exists.** A check that a quoted line appears in the source proves the
  line exists, not that it supports the verdict it is quoted for.

**Questions to ask.**
1. Pick any figure in a recent answer. Can you get from it to the record it came from,
   without asking the person who built it?
2. Does the answer carry an as-of date?
3. Take a quoted line. Can the system prove it appears in the source, and say where?
4. When the data cannot answer a question, what does the person actually see?
5. Does each quoted line actually support the verdict it is attached to, or does it only
   appear in the source?

## 2. Determinism

**What it means.** The AI picks which rule applies. The rule itself lives as data a person
can read and change. The arithmetic is always carried out the same way. Nothing consequential
is worked out inside an AI's own reasoning, and the same question asked twice gets the same
answer.

**What good looks like.**
- Arithmetic always goes through one dedicated calculating step, with every input shown.
- Rules live as rows or fields a person can edit, so changing a threshold does not need a
  developer or a new release.
- A rule the system does not yet implement refuses cleanly rather than being silently
  skipped or guessed at.

**How it goes wrong.**
- **The rulebook in the prompt.** Limits, criteria or thresholds written into an AI's
  instructions, where nobody can edit, quote, or audit them.
- **The calculator you can skip.** Nothing forces the AI to use the dedicated calculating
  step, so under load it works the sum out itself - and is usually right, until it is not,
  silently.
- **The mixed-up rules.** Numbers a system applies automatically and wording an AI is meant
  to quote, stored together in a way that blurs which is which.
- **The negative rule.** A rule written as what must not happen is easy to read the wrong way
  round, by a person or a model. State each rule as the condition you want to see, and keep an
  either-or requirement as one rule, not two.

**Questions to ask.**
1. Where, specifically, does each number in an output get computed?
2. Can a business person change a threshold or a limit without asking a developer?
3. Ask the same question twice. Are the two answers identical?
4. What happens today when the system meets a rule it has not been taught yet?

## 3. Modularity

**What it means.** A build is assembled from parts, each with a clear job and a clear
contract, rather than one large tangle of bespoke logic. Something is only "shared" once two
separate, named uses actually use it as it stands - not because it looks reusable.

**What good looks like.**
- Each part does one job, has a defined input and output, and can be tested on its own.
- A part called shared genuinely has two real users using it unchanged. At least one of
  those uses is not the one it was originally built for.
- Two versions of something that differ by an edited internal detail are honestly two
  different parts, not one part pretending to be generic.

**How it goes wrong.**
- **Shared by aspiration.** A part labelled reusable with exactly one real user, so the next
  team inherits a promise that was never actually true.
- **The forked copy.** A second version that needed one more tweak, so someone copied the
  whole thing rather than parameterising it. Now there are two things to maintain and one
  name for both.
- **The part with no user.** Built because it seemed generally useful. Maintained forever.
  Used once, if at all.

**Questions to ask.**
1. Pick something labelled shared. Name its two real, separate users.
2. Does any "variant" actually differ by an edit to the core logic, rather than by its
   configuration?
3. Can one part be tested on its own, without a live account or a network connection?
4. Is there anything in the build with no real, named user? Why does it exist?

## 4. Domain-free cores

**What it means.** The reusable logic at the centre of a build - an agent's core
instructions, a shared skill - carries no customer name, no specific business process, no
detail that belongs to one company. Everything specific to one company arrives as
configuration, supplied alongside the core rather than baked into it.

**What good looks like.**
- The core reads like a description of a role or a job to do, not like one company's
  process written out in prose.
- Every piece of company-specific detail is supplied through configuration, and the core
  contains nothing beyond what that configuration actually declares.
- The same core can serve a different company or a different industry by changing only its
  configuration, with no edit to the core itself.

**How it goes wrong.**
- **The baked-in business.** A prompt or a body of logic carrying one company's product
  list, terminology or process, which goes stale the moment that company's data changes.
- **The company name in a general part.** A part named for one deal or one customer, which
  the next team cannot reuse without renaming and rewriting it.
- **The configuration that lies.** Settings declared and never actually used by the core, or
  used by the core without ever being declared - so nobody can tell what the core actually
  depends on.
- **The baked address.** A machine's network address written into a workflow. It ties the
  build to one network, so moving the installation means finding and changing every step that
  used it. Refer to services by the installation's own internal names, and confirm them with
  whoever runs it.

**Questions to ask.**
1. Search the core logic for a company name, an account identifier, or a customer-specific
   term. What comes back?
2. Could this core serve a different company or industry by changing only its
   configuration?
3. Does every setting in the configuration actually get used by the core, and does the core
   use nothing beyond what is declared?
4. Does any workflow contain a machine's network address?

## 5. Human governance

**What it means.** A gate is a recorded decision on a specific item - who decided, what they
decided, and when - and it fails closed. No decision recorded means no output goes out. The
person decides from where they already work - by default an email with Approve and Reject
buttons, each opening a confirm page - and that the decision gets recorded is not optional.

**What good looks like.**
- The gate works out its own answer from the underlying data, rather than trusting whatever
  the AI just said in the same turn.
- The decision is written down with who decided, what they decided, and when - captured by
  the system itself, not just visible in a chat transcript.
- The person decides from where they already work, with the document in front of them: an
  email whose buttons open a confirm page. Opening the link decides nothing; only the page's
  Confirm does.
- Nothing consequential is auto-approved. A missing decision blocks the output rather than
  letting it through by default.
- The ask pauses the process, it does not end it. Once the decision lands, the same run
  carries on by itself - finishing the job or telling the person who asked - without anyone
  having to come back and ask again.

**How it goes wrong.**
- **The gate with nothing behind it.** A status field a person is meant to update, with
  nothing actually watching it or acting on the change. It looks like oversight and provides
  none.
- **The decision typed into a cell.** The person is asked to approve by picking a value in a
  data board. It sits in a grid they have no reason to open, does nothing until it is saved,
  and does not feel like deciding.
- **The link that decides when opened.** A button that records the decision on a plain visit
  is decided by the first mail scanner or preview that opens it.
- **The conversational yes.** A person types "yes" to an AI and nothing is recorded anywhere
  durable, so the decision exists only in a transcript nobody will read again.
- **The trusting gate.** The approval step reads the number the AI proposed instead of
  working it out independently, so a wrong number can approve itself.
- **The self-approving agent.** The agent can write the decision itself - the status, the
  approval, the decider - through the same tool it uses for everything else. Columns that
  record a decision should take their starting value when the record is created and refuse
  every later write from the agent.
- **The missing verdict read as a pass.** A check that has not run yet, or that failed, leaves
  a record looking exactly like one that passed. Stamp a verdict on every record, clear ones
  included, and make every later step wait for it and refuse without it.
- **The ask that hangs up.** The decision gets recorded and nothing after it moves. The
  person who asked has to notice and follow up themselves.

**Questions to ask.**
1. Show the record of the last decision that was made. Who, what, when?
2. If the approver were unavailable, would anything still go out?
3. Does the gate work out its own answer, or does it trust a number it was handed?
4. Where does the reviewer already work, what do they see, and was that exact route walked
   end to end as that person? Does opening the link alone decide anything?
5. What happens if the same decision arrives twice?
6. Can the agent write the columns that record a decision?
7. What does a later step do when the check has not stamped the record yet?
8. Approve it, reject it, and leave one unanswered. In each case, does the process carry on
   by itself - the job finished or the outcome reported - with nobody having to ask twice?

See [Human approval](human-approval.md) for how a person decides from an email, what the
confirm page does, and why a chat reply on its own is not a decision.

## 6. Native-first

**What it means.** If the platform already gives you a way to do something - move data,
send a message, wait for a person, connect to another system - use that, rather than writing
custom code to do it yourself. If you can name a capability as a feature of the
platform, rebuilding it in custom code hides it, ages badly, and usually ends up needing a
credential that the built-in way would never have needed.

**What good looks like.**
- The build reads step by step through the platform's own building blocks, understandable to
  someone who is not a developer.
- Connections to other systems are held in the platform's own connection store, scoped and
  reusable, never embedded inside the build's logic.
- Where custom code is genuinely needed, it only computes over the inputs it is given; it
  does not call out to anything else on its own.
- Any exception is written down: which capability was considered, why it was not used, and
  what would let it be retired.

**How it goes wrong.**
- **The hand-rolled shortcut.** Custom code doing something the platform already offers,
  usually because nobody checked first. It typically needs a credential the built-in way
  would not have needed, and it breaks the moment the build moves somewhere else.
- **The glorified script.** One large piece of custom logic with a thin layer of AI on top.
  It gets the right answer and demonstrates nothing about whether the design holds up.
- **The silent credential.** A login or key embedded somewhere in a build that nobody wrote
  down, so nobody ever goes back to remove it.

**Questions to ask.**
1. Open the build. Can someone who is not a developer say what each step does?
2. Search the build for anything that looks like a credential or an access key. What comes
   back?
3. For each piece of custom code: which platform capability was considered, and why was it
   not enough?
4. Move the build to a different account or environment. What breaks?

More on this in [Native-first](native-first.md).

## 7. Operability

**What it means.** Keeping a build running is part of building it, not an afterthought: a
way to reset it back to a known state, a fixed set of test cases to score it against, every
mode of the build actually exercised, and a second, independent pass that checks the first
one's work.

**What good looks like.**
- Every part of the build has a test that can run with no live account or credential, and
  those tests run automatically before anything ships.
- A fixed set of test cases is scored the same way every time, and a case that could not run
  is reported as skipped - never silently counted as a pass.
- A second, independent check reviews the main path and flags disagreements, without quietly
  fixing them itself.
- The build can be reset to its starting state from within the platform, not by someone
  manually restoring it from a laptop.
- Error replies from tools are short, and each conversation is sized to fit the context of
  the model that runs it.

**How it goes wrong.**
- **The unseen green.** A report that a test passed, pasted in rather than actually watched
  run.
- **Everyone's own scoring.** Each build inventing its own way of comparing results to
  expectations, so no two reported scores mean the same thing.
- **The unresettable demo.** A build that works once and then needs its author personally to
  put it back together before it can be shown again.
- **The unaudited pass.** One result, believed, because nothing else ever checked it.
- **The status taken as the outcome.** A step's status tells you the step ran; the record it
  was meant to produce tells you the work happened. Check the record.
- **The trusted answer key.** Test answers are written by people and can be wrong. Where a
  result disagrees with the key, check the key too, and report results against both the
  original key and the corrected one.

**Questions to ask.**
1. Did you run the tests yourself, and did you watch them pass?
2. Where is the fixed test set, and when was it last scored?
3. Reset the build. Does it come back to exactly the same state?
4. What independently checks the main path, and when did it last find a disagreement?
5. Could someone who did not build this install and run it from the package and the
   documentation alone?
6. For each step, which record proves its work happened?

## 8. Security and sovereignty

**What it means.** A credential on this kind of platform is a key to a great deal, not a
single password to one small thing. Treat it that way: scoped narrowly, held in
configuration, never embedded in the build's own logic, never committed to a shared
document, and never handed to an AI coding tool as part of its working context.

**What good looks like.**
- A build reaches other systems through the platform's own connections, so its logic
  contains no credential at all and can be shared or moved safely.
- Any deliberate exception is written down on the build itself, naming what it is and what
  would remove the need for it.
- Automated checks catch the rest before anything ships: no credential-shaped text, no
  internal machine names or file paths, no personal contact details.
- Masking of sensitive fields is enforced by the platform itself on the underlying data, not
  by a step in the logic that could be skipped or forgotten. A store of raw, unmasked
  identifiers is never connected to an AI at all.
- Which AI models read the data is set per installation and per organisation. Before personal
  data goes in, confirm with whoever runs the installation that every model it uses - for
  chat, document reading and search - runs inside the deployment.

**How it goes wrong.**
- **The convenient shortcut.** Temporarily connecting the store of raw, sensitive data
  straight to an AI to answer one awkward question. The separation was the whole guarantee,
  and it just quietly stopped being true.
- **The credential in the export.** A shared package that only works because it carries a
  live credential inside it, handed to someone outside the team.
- **The indistinguishable credential.** Nothing in the process marks a throwaway test
  credential as different from a live one, so a build can end up using the wrong one. Label
  test and live credentials differently, and confirm which kind a build is holding before
  sharing or running it.
- **The unchecked export.** Sharing an export without opening it first. Open every export
  before it leaves the team and confirm it holds no credential, no customer data and no
  personal details.
- **The credential sent to a webhook.** Run history keeps each run's inputs so a run can be
  reviewed later - which is exactly why a credential never belongs in a webhook call. Send an
  identifier and let the workflow use a stored connection.

**Questions to ask.**
1. Search everything about to be shared for anything that looks like a credential. What
   comes back?
2. Is the credential an AI coding tool has access to a limited, disposable one?
3. Is sensitive-field masking enforced by the platform, or by a step someone could skip?
4. Who can see the raw, unmasked data, and what actually stops an AI from being connected to
   it?
5. What does the last package you shared with someone else actually contain?
6. Which AI models read this build's data, and is any of them outside the deployment?

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== build-it-well/use-case-shapes.md ====================

---
title: Use-case shapes
description: Nine recurring shapes a business use case takes on iMBrace, and the kinds of parts each one is assembled from.
level: '3'
track:
- build
verified_on: '2026-09-30'
---

# Use-case shapes

Most business use cases are not as different from each other as they first look. Once you
have seen enough of them, they sort into a small number of recurring shapes. Find the shape
your problem looks like, and you have a first draft of what to assemble - something to argue
with, not a finished design.

Each shape below names what it looks like, then the kinds of parts it is typically built
from. These are kinds of parts and what they do, not specific products - the actual building
blocks live in the platform's own part library.

## 1. Transactional resolver

**It looks like:** someone asks, in plain words, for a priced or configured thing - a quote,
a booking, a specific option worked out for them.

**Typically assembled from:**
- an agent tuned to this kind of transaction
- a skill that looks up existing records
- a skill that searches for matching records
- a skill that runs the calculation, showing every input it used
- a skill that saves the resulting record
- a skill that puts together a document from a template
- a skill that asks a person to approve, by email with a confirm page, before anything goes out
- a skill that sends the finished document to the requester
- where capacity is limited, a skill that reserves a slot against what is genuinely still
  available, not just against a raw quantity

## 2. Extraction back office

**It looks like:** documents arrive - invoices, applications, forms - and need to become
checked, structured records.

**Typically assembled from:**
- an agent that reads incoming documents
- the platform's own document intake
- a skill that splits a document into its separate parts before reading them
- a skill that compares one record against another, including a three-way match where a
  third source is involved
- a skill that checks extracted values against rules
- a skill that finds duplicate records, even ones written slightly differently
- a skill that saves records
- a skill that asks a person for a decision on anything that does not clearly pass
- a skill that sends a message with the outcome
- an independent pass that audits what the first pass did

## 3. Insights desk

**It looks like:** people ask plain-language questions about data that already exists
somewhere in the business.

**Typically assembled from:**
- an agent built for answering questions over data
- a skill that queries the underlying records and returns the query it actually ran, not
  just an answer with no working shown
- a skill that groups and totals records
- a skill that runs calculations
- a skill that sends the answer by email
- an automation that links a new record back to its parent as soon as it appears

Where a figure has to be provable, use the query skill above, which returns the query it ran
with the answer, so anyone can check the number afterwards.

## 4. Conversational front door

**It looks like:** a channel where anyone might arrive - a chat widget, a messaging app, an
inbox - and the build has to work out who it is talking to before it can do anything useful.

**Typically assembled from:**
- an agent standing at that channel
- a skill that verifies who the sender actually is
- a skill that finds a matching record, with a sensible fallback when nothing matches
- the platform's own document intake, for anything sent as a file
- a skill that screens incoming free text for anything that should not be acted on
  automatically
- a skill that asks a person for a decision
- a skill that issues a single-use access link
- a skill that sends a message
- a skill that saves records

## 5. Multi-agent examiner

**It looks like:** a case has to be judged against a rulebook, and the judgment genuinely
needs more than one point of view - a lead coordinating several specialists.

**Typically assembled from:**
- a lead agent, one or more specialist assessor agents, a rulebook reader, and a report
  writer
- a skill that queries the underlying records
- a skill that checks values against rules
- a skill that verifies a quoted line against its source
- a skill that compares records
- a skill that runs calculations
- a skill that saves the resulting records
- a skill that asks a person for a decision
- an independent audit pass over the whole case

## 6. Self-filling CRM

**It looks like:** notes, calls and messages arrive continuously, and need to turn into
records a person then confirms, rather than types in by hand.

**Typically assembled from:**
- an agent that reads incoming notes and messages
- a skill that splits an incoming document into its separate parts
- a skill that verifies a quoted line
- a skill that saves records, including any nested child records that belong to them
- a skill that keeps a running history of what changed and when
- a skill that asks a person to confirm before anything is treated as final
- a skill that writes a short report
- a skill that composes and sends an email
- an automation that waits for a burst of related activity to settle before acting, rather
  than firing on the very first item and being wrong the moment the rest arrive

## 7. Contract or document management

**It looks like:** one long document - a contract, an agreement, a long-form filing - drives
a working record and a schedule of things that need to happen against it.

**Typically assembled from:**
- an agent (sometimes two, working together) that reads the document
- a skill that splits and routes the document to the right handling
- a skill that extracts a wide set of fields and checks the result against the full field
  list
- a skill that verifies a quoted line
- a skill that checks values against rules
- a skill that fills in a template
- a skill that issues a single-use access link
- a skill that stores the resulting file
- a scheduled automation that runs the whole cycle at a set cadence

## 8. Knowledge kit

**It looks like:** people ask questions of a body of documents - policies, manuals, past
correspondence.

This is the one shape where the easy first instinct is often the wrong one, so it is worth
splitting in two:

- **"How do I do this"** is a genuine search question. The platform's own built-in retrieval
  over a set of documents handles this well, and needs nothing more built on top.
- **"How many" or "which document said this, on what page"** is a counting and citing
  question, best answered from records rather than retrieval. Index every page as its own
  record, then use a skill that queries those records and a skill that groups and totals
  them. Counting and citing are then exact.

## 9. Governance showcase

**It looks like:** the point of the build is demonstrating who may see what - access,
masking, and audit, rather than any one transaction.

**Typically assembled from:**
- the platform's own access administration, view-level masking, model governance, and read
  audit
- a skill that masks sensitive fields in anything an agent writes out
- a skill that screens text
- a skill that issues a single-use access link
- an output check on the agent's own answers, as a second layer alongside the platform's
  view-level masking

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== build-it-well/human-approval.md ====================

---
title: Human approval
description: How a person decides from where they already work - an email with Approve and Reject buttons, confirmed on a page - and how the build carries on afterwards.
level: '3'
track:
- build
verified_on: '2026-09-30'
---

# Human approval

Every build that matters has a moment where a person needs to say yes before something goes
out. Design that moment first: who is asked, where they already work, which document is in
front of them, what they see, and what happens after they answer.

## The decision is one thing, the surface is another

The decision part works out what should happen from the underlying records, refuses to
proceed if nobody has decided, and writes down who decided, what they decided, and when.
That part does not change from build to build.

The surface - where and how a person actually makes that decision - is chosen per use case,
but the default is not a free choice: a person decides from where they already work. For most
reviewers that is their inbox.

## The default: an email with Approve and Reject

The reviewer gets an email that carries everything needed to decide: the facts, the document
itself (the quotation, the CV, the contract) linked or attached, and the recommended action.
Below it are two buttons, Approve and Reject.

1. The build pauses and emails the reviewer. While it waits, nothing goes out.
2. The reviewer reads the email, with the document in front of them.
3. A button opens a confirm page that shows the choice. Opening it decides nothing.
4. Only the page's Confirm records the decision. The other button then stops working, so one
   person gives one answer.
5. The same run carries on: it finishes the job - for example the documents go to the rep -
   and tells the person who asked what happened.

Write the moment in five lines before you build anything: who is asked, where they already
work, which document is in front of them, what they see, and what happens after they answer.
Then keep three things in mind.

- **People, messages and documents lead.** The moment is a person, an email and the document,
  not a grid. The board holds the record behind it.
- **The email is a card, not a notice.** If the reviewer has to open something else to decide,
  the card is missing a fact.
- **Every branch ends somewhere the requester can see:** approved, rejected, expired, no
  answer.

## Other ways, and when to use them

| Surface | How it works | Use it when |
|---|---|---|
| **An email with a confirm page** | one button per outcome; opening a button shows a page, and confirming on it writes the decision | the default, for every reviewer who works in their inbox |
| **A field on a record** | a person flips a status field on a board; the next step fires once it is saved | a fallback, only when the reviewer already works from that board every day. Not for a business person |

Do not ask a business person to approve by picking a value in a data board. It sits in a
grid they have no reason to open, does nothing until it is saved, and does not feel like
deciding.

Which surfaces are available depends on your installation and version; your iMBrace contact
can confirm them. Whatever you choose, walk the path as the reviewer before you rely on it:
they get the email, open it, confirm, and the build finishes.

## The rule that does not bend

**A friendly "yes" typed into a chat is not, by itself, a decision.** It is flow control - it
might tell the conversation to keep going - but it leaves no durable record that anyone can
point to later and say: this was approved, by this person, at this time. A decision is a
recorded answer tied to a specific item, with who decided and when.

Two more rules worth holding onto:

- **The gate works out its own answer.** It recomputes the outcome from the underlying
  records rather than trusting a number it was just handed in the same interaction. A gate
  that trusts what it is told will happily approve a wrong number.
- **No decision means no output.** Not a default. Not a timeout that lets things through
  after a while. If nobody has decided, nothing goes out.

## Details that make a gate hold

- **Opening a link decides nothing.** A person, a mail scanner or a preview may open it. A
  visit shows the page; only the confirming step decides.
- **One email per person, one set of buttons per person.** Record on your own row whose
  buttons they were and when they confirmed, so "approved by" always comes from your record.
- **A second answer changes nothing.** Once one answer is confirmed, the other outcome is
  retired, and the step after the pause is safe to run twice.
- **The confirm page tells the truth.** It shows "done" only after the decision was recorded,
  and says so plainly if it was not.
- **Send the email only once the build is waiting for the answer.**
- **The agent must never be able to write the decision.** Build the columns that record a
  decision so they take their starting value when the record is created and refuse every later
  write from the agent - give the agent narrow tools that cannot reach them.
- **"No verdict yet" must never read as a pass.** A check that has not run, or that failed,
  leaves the record looking exactly like one that passed. Stamp a verdict on every record,
  clear ones included, and make every later step wait for it and refuse without it.
- **A board edit takes effect when it is saved.** If a reviewer does use the board, test the
  gate from the saved state and include "press Save" in their instructions.

## Prove the gate is wired, not just present

A control point is only as good as what is bound to it. Wire the surface to something that
genuinely depends on it, and exercise the whole path end to end as the reviewer: for each
outcome - approve, reject and no answer - start the run, answer from the email they would
really get, and check that the job finished or the requester was told, with no further prompt
from anyone. A gate is not built until that has been done.

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== build-it-well/native-first.md ====================

---
title: Native-first
description: Why you reach for the platform's own building blocks before writing code, and what that buys you.
level: '3'
track:
- build
verified_on: '2026-09-23'
---

# Native-first

Before writing custom code to do something, check whether the platform already does it. This
is not a style preference. It changes what your build costs to run, how safely it can be
moved, and how easily someone else can understand it later.

## The idea in one sentence

If a person could point at a capability and name it as a feature of the platform, it is
almost certainly already built in. Rebuilding it yourself in custom code hides what it does
behind code someone has to read, tends to age badly as the platform evolves, and very often
ends up needing a login credential that the built-in way would never have needed at all.

## What the platform typically gives you, out of the box

A working platform of this kind ships with a large amount of ready-made capability: reading
and writing structured records, sending mail and chat messages across the usual channels,
calendars, spreadsheets, file storage, handling incoming documents, pausing a process to
wait for a person, calling one process from another, routing and looping within a process,
and stopping a run cleanly. Connections to accounts and other systems live in the platform's
own connection store - configured once, referenced by a build, and never carried inside the
build's own logic.

Before writing a line of custom code, it is worth checking the platform's current capability
list for something that already does the job. New capability ships regularly, and the safest
default is always to look before you build.

## When custom code is genuinely justified

Two things both need to be true:

1. **Nothing built in does the job**, and you can say specifically what you checked and why
   it was not enough.
2. **The code is pure** - it only computes over the values it is given. It does not itself
   call out to another system with a credential of its own. If it genuinely needs to reach
   another system, it does that through one of the platform's own connections, not through a
   key embedded in the code.

Any exception to native-first should be written down plainly: what was considered, why it
was not used, and what would let the custom code be retired later. Treat an exception as a
temporary, named debt rather than a quiet permanent choice - and retire it the moment a
built-in way to do the same job ships.

## Why this matters more than it sounds like it should

- **Nothing in a build should ever hold a credential.** A build that only ever uses the
  platform's own connections contains no login details, no API keys, nothing of that shape
  at all. That means the build itself can be shared, exported, or moved to another account
  safely - there is nothing inside it that needs to be rotated, redacted, or worried about.
- **A build using built-in capability is readable by someone who is not a developer.** They
  can open it and see, step by step, what each part does, without opening any code.
  Custom code hides that behind a wall only a developer can read.
- **It survives being moved.** Export a build made from built-in capability into a
  different account, and it needs no rewiring. A build with a credential baked into it
  breaks, or worse, quietly keeps working using the wrong account's access. Connections that
  use a provider sign-in, such as Gmail, are authorised once per account by someone with
  access; a mail-server (SMTP) connection is configured once with the server's details.

## What good looks like

- The build reads step by step in the platform's own view, understandable without opening
  any code.
- A search of the build's logic for anything credential-shaped turns up nothing.
- Every piece of custom code, if any, has a note saying which built-in capability was
  considered and why it was not enough.
- Moving the build to a different account changes nothing about how it behaves.

## A worked example

Take a quoting assistant: sending the finished document needs no custom code at all - the
steps read the record, route on its status, format a date, send the mail and update the
record, all built in. The approval step works the same way, with a built-in task that pauses
the process until a person decides, then picks up again on its own and sends the document.
Custom code is typically limited to a few things: the arithmetic, a database query, a final
verification check and the layout of the document itself.

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== build-it-well/document-models.md ====================

---
title: Document models
description: How to choose what DocIQ extracts from a document - adopt the platform's default model, extend it, and write your own only as a last resort.
level: '3'
track:
- build
verified_on: '2026-09-23'
---

# Document models - adopt, extend, write

When DocIQ reads a document - a CV, an invoice, a purchase order - a **document model** tells
it what to pull out and which record to fill. There are three ways to get one, and they are
in strict order.

1. **Adopt the organisation's default.** The platform ships a large library of models,
   including resumes, invoices, purchase orders and onboarding checklists. Adopting one costs
   nothing, and every future build on the organisation sees the same fields.
2. **Extend a default when a field is genuinely missing.** Ask your iMBrace contact. Adding
   a field to the default puts it in front of every organisation, instead of forking a model
   for one customer.
3. **Write your own only where no default exists**, and write it in the platform's own style,
   so that a future default can replace it cleanly.

## What not to do

- **Manage a model as its own deliberate step, never as a side effect of a build.** Create or
  change a document model outside a running build, so every build that reads a given document
  type points at the same, single model.
- **Do not leave the choice of model to chance.** Where a step always reads one kind of
  document, tell it which model to use, so every document lands on the board you intend.

## Validate with your own documents

Check each of these with a few of your own documents before a design depends on it:

- **A wide model.** A model with dozens of fields is easier to validate as several focused
  passes. Whatever the size, check each result against the field list so every field is
  accounted for.
- **Nested rows.** Line items on an invoice, jobs in a CV's work history: confirm in your
  test set that each child row lands on the board linked to its parent.
- **A document that is really a table** - a price list, a statement - is many records, not
  one. Read it as rows.
- **A document that does not look like its type.** Include atypical examples in your test
  set - a job description with no duties section, a form missing its standard headings - and
  make sure the agent reports an unrecognised document as unrecognised, never as a success.
- **Organisation-wide settings.** DocIQ's model settings are shared across the organisation.
  Record the settings your build was tested with next to your test set, and re-run the set
  whenever they change.
- **Where the models run.** Which model reads your documents is set per installation and per
  organisation. Where personal data must stay on premises, have whoever runs the installation
  confirm that every model DocIQ uses - for reading and for search - runs inside it, before
  the first real document goes in.

## Design choices that pay off

- **Fewer models is cheaper and more accurate.** Classification compares each document with
  every model in the organisation, so every unused model adds cost and room for error. Keep
  the models you use, and where a step always reads one kind of document, point it at that
  document's board so the model is fixed.
- **Give a closed vocabulary to any field you will group or chart by.** List the allowed
  values in the field's description, so grouping and charting work from a fixed, known set
  of terms.
- **Describe each document type by what it is and what it is not.** Descriptions that name the
  near-identical types a document is not are what keep them apart.

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== build-it-well/anti-patterns.md ====================

---
title: Anti-patterns
description: The mistakes that get built again and again, what each one costs, and the fix.
level: '3'
track:
- build
verified_on: '2026-09-30'
---

# Anti-patterns

Each of these looks reasonable at the time, which is exactly why they are worth naming in
advance.

## The gate with nothing behind it

A status field a person is meant to update, with nothing actually watching it or acting on
the change. **What it costs:** it looks like oversight in a review and provides none in
production - things go out with nobody having genuinely approved them. **The fix:** wire the
surface to something that truly depends on it, and exercise the full path - including the
"nobody decided yet" case - end to end before calling it done.

## The decision typed into a cell

A person is asked to approve by editing a value in a data board. **What it costs:** the value
sits in a grid the person has no reason to open, does nothing until it is saved, and no
business person thinks of it as deciding - so approvals arrive late or not at all. **The fix:**
ask them where they already work: an email card whose buttons open a confirm page, with the
document in front of them, and record the decision on the row afterwards. See [Human
approval](human-approval.md).

## The ask that hangs up

A build asks a person for a decision, then stops there. The decision gets recorded, but
nothing downstream moves: the document is not sent, the person who asked is not told, and
they have to notice and come back to ask again. **What it costs:** it passes a review and
fails in production - work sits recorded but unfinished, and someone has to chase it by
hand. **The fix:** design the ask to pick back up once it is answered - approved, rejected,
or left open - so the process finishes the job or reports the outcome on its own.

## The confident summary

An AI-produced answer that reads well and has nothing behind it. **What it costs:** it
survives review precisely because it reads convincingly, and a decision gets made on a
number nobody can actually trace. **The fix:** require every figure to carry the record it
came from; when the answer is not in the data, say so plainly instead of filling the gap.

## The calculator you can skip

Nothing forces arithmetic through one dedicated, checkable step, so under load the AI just
works the sum out itself. **What it costs:** it is usually right, which is what makes it
dangerous - the failures are rare, silent, and easy to miss until someone checks. **The
fix:** route all arithmetic through one dedicated calculating step, every time, with the
inputs shown.

## The rulebook in the prompt

Limits, criteria or thresholds written into an AI's instructions instead of held as
editable data. **What it costs:** a business person cannot change a number without going
through a developer, and nobody can audit which rule actually fired on a given case. **The
fix:** hold rules as data on a record a non-developer can open and edit directly.

## The forked copy

Copying a working build's internals to create a near-identical version for a new case,
instead of parameterising the original. **What it costs:** two things to maintain that
quietly drift apart, and the next person often does not even know a second copy exists.
**The fix:** parameterise instead of copying. If a genuine second version is truly needed,
give it its own name and its own documentation rather than letting it masquerade as the
first.

## The hand-rolled shortcut

Custom code doing something the platform already offers as a built-in capability, usually
because nobody checked first. **What it costs:** it typically needs a credential the
built-in way would never have needed, and it breaks the moment the build is moved to another
account. **The fix:** check the platform's current capability list before writing any code.
See [Native-first](native-first.md).

## The unchecked extraction

Trusting an extraction result without comparing it with what was asked for. **What it
costs:** a missing field is easy to overlook when nobody checks the output against the field
list. **The fix:** check every result against the field list, and keep a long field list as
several focused passes.

## The retrieval count

Treating a counting or citing question - "how many," "which document, on what page" - as a
search question. **What it costs:** that kind of question needs structured records to answer
exactly; retrieval alone cannot show its working. **The fix:** index the material into
structured records and query them. Save search-and-retrieve for genuine "how do I"
questions.

## The leading-edge fire

A process reacts to the very first item in a related burst of activity, instead of waiting
for the burst to settle. **What it costs:** the result is generated before the rest of the
related items have arrived, and it is wrong or incomplete the moment they do. **The fix:**
wait for the burst to go quiet, then act once, on the complete picture.

## The trusting gate

An approval step that reads the number the AI just proposed instead of working it out
independently from the underlying records. **What it costs:** a wrong number can approve
itself, because nothing ever checked it against the source. **The fix:** the gate always
re-derives its own answer.

## The self-report

A build reporting its own success - a plausible-looking pasted result, a status of "done" or
"live" for something nobody actually watched run. **What it costs:** confidence in a state
of the world that was never actually observed. **The fix:** run it yourself, watch it
happen, and only mark something as working once someone has genuinely seen it work.

## The convenient shortcut around privacy

Temporarily connecting a store of raw, sensitive data directly to an AI to answer one
awkward question. **What it costs:** the separation between sensitive data and the AI was
the entire privacy guarantee, and it has just quietly stopped being true - even if only for
a moment. **The fix:** never connect it, even briefly. If a question genuinely needs the raw
data, it is the wrong question for that AI to be answering.

## The answer key in the prompt

The expected answers - the figures a demo should show - written into the agent's own
instructions. **What it costs:** the demo passes while the tools behind it are wrong, and
nobody finds out until a real question is asked. **The fix:** expected values live in the
test set, never in the instructions, and a check before the agent goes live refuses
instructions that contain them.

## Memory as the data source

An agent answers a live-data question from what it remembers, or from a document attached to
it some time ago, instead of reading the source in front of it. **What it costs:** a
confident answer with yesterday's figures in it. **The fix:** attach no documents to an agent
that answers from live data, give it a standing rule never to save figures to memory or
answer from memory, and keep a test question that would catch a stale answer. Keep the
conversation's own history on for any agent that holds a conversation - it needs it to stand
by what it said earlier.

## Conceding a disputed figure

A person offers their own number and the agent drops its correct, tool-computed figure to
agree with them. **What it costs:** the answer becomes whatever the most confident person in
the conversation says. **The fix:** give the agent a challenge rule - re-run the tool, try to
reproduce the person's figure with a tool, and say plainly what each figure covers.

## The pivot photograph

Reading a pivot table in a converted spreadsheet as if it still calculated. When an Excel
workbook is converted to Google Sheets, its pivot tables keep the values they showed at that
moment and stop updating. **What it costs:** every figure taken from the pivot is frozen at
the conversion date, however current the rows beneath it are. **The fix:** calculate from
the raw rows, and say so wherever the pivot is shown.

## The whole tab in the turn

A large sheet or table handed whole to an agent in a single turn. **What it costs:** it is
more than the agent can take in at once, and whatever follows is built on a partial read
that looks complete. **The fix:** read it with the platform's own read step, total it in a
calculation step, and give the agent only the finished figures, with the rows, filters and
dates they came from. See [Native-first](native-first.md).

## The unused shared part

Something built because it seemed generally useful, then never actually reused, but still
maintained indefinitely. **What it costs:** ongoing upkeep for something that returns no
value, and a false sense that the build is more modular than it actually is. **The fix:**
do not label something reusable until at least two real, separate, named needs for it exist.

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*


==================== build-it-well/review-checklist.md ====================

---
title: Review checklist
description: The eight-principle review, as a checklist you can run on your own build before you ship it.
level: '3'
track:
- build
verified_on: '2026-09-30'
---

# Review checklist

This is the same review used internally, written so you can run it on your own build.
It takes about an hour, and it is far more useful when the person running it did not build
the thing being reviewed.

## How to run it

1. Copy the scoring table below next to the build you are reviewing.
2. Work through each principle's questions, drawn from
   [The eight principles](the-eight-principles.md).
3. Score every question: **achieved**, **partial**, **not achieved**, or **not
   applicable**.
4. Every score needs an **anchor** - something concrete that proves it: a specific record, a
   pasted result you watched happen, a screenshot of the actual behaviour. A score with
   nothing behind it is an opinion, not a review.
5. Anything scored **not achieved** becomes either a fix before you ship, or a written,
   dated note saying who accepted the gap and why.

## The rules that make it worth doing

- **The reviewer did not build it.** A person reviewing their own work tends to find only
  what they already knew about.
- **Run things; do not just read about them.** Do not assume a test passes because it looks
  like it should. Run it and watch the result.
- **"Not applicable" needs a reason.** It is a legitimate score, but silence is not - write
  down why the question does not apply here.
- **A partial is not a pass.** It is a named gap with an owner and, ideally, a date to
  revisit it.
- **This reviews the build, not the person.** The goal is a better artifact, not a
  judgement on whoever made it.

## 1. Provenance

| # | Question | Score | Anchor | Note |
|---|---|---|---|---|
| 1 | Can you get from a figure in the output to the record behind it, unaided? | | | |
| 2 | Does the answer carry an as-of date? | | | |
| 3 | Is a quoted line proved against its source, with a location? | | | |
| 4 | What does a person see when the data cannot answer the question? | | | |
| 5 | Does each quoted line support its verdict, or does it only appear in the source? | | | |

## 2. Determinism

| # | Question | Score | Anchor | Note |
|---|---|---|---|---|
| 1 | Where, specifically, is each number computed? | | | |
| 2 | Can a business person change a threshold without a developer? | | | |
| 3 | Does the same question, asked twice, give the same answer? | | | |
| 4 | What happens when the system meets a rule it does not yet implement? | | | |

## 3. Modularity

| # | Question | Score | Anchor | Note |
|---|---|---|---|---|
| 1 | For anything labelled shared, name both real, separate uses of it. | | | |
| 2 | Does any variant actually differ by an edit, rather than by its configuration? | | | |
| 3 | Can a part be tested on its own, with no live account or network? | | | |
| 4 | Is there anything in the build with no real, named user? | | | |

## 4. Domain-free cores

| # | Question | Score | Anchor | Note |
|---|---|---|---|---|
| 1 | Does the core logic contain a company name or a customer-specific detail? | | | |
| 2 | Could this core serve a different company by changing only its configuration? | | | |
| 3 | Does every setting in the configuration get used, and is everything used declared? | | | |
| 4 | Does any workflow contain a machine's network address? | | | |

## 5. Human governance

| # | Question | Score | Anchor | Note |
|---|---|---|---|---|
| 1 | Show the record of the last decision made. Who, what, when? | | | |
| 2 | If the approver were unavailable, would anything still go out? | | | |
| 3 | Does the gate work out its own answer, or trust one it was handed? | | | |
| 4 | Where does the reviewer already work, and was that exact route walked end to end, as them? Does opening the link alone decide anything? | | | |
| 5 | What happens when the same decision arrives twice? | | | |
| 6 | Can the agent write the columns that record a decision? | | | |
| 7 | What does a later step do when the check has not stamped the record yet? | | | |
| 8 | Approve it, reject it, and leave one unanswered. Does the process carry on by itself each time? | | | |

## 6. Native-first

| # | Question | Score | Anchor | Note |
|---|---|---|---|---|
| 1 | Can someone who is not a developer read the build and say what each step does? | | | |
| 2 | Does a search of the build turn up anything credential-shaped? | | | |
| 3 | For each piece of custom code, which built-in capability was considered and rejected, and why? | | | |
| 4 | Move the build to a different account. What breaks? | | | |

## 7. Operability

| # | Question | Score | Anchor | Note |
|---|---|---|---|---|
| 1 | Did you run the tests yourself, and watch them pass? | | | |
| 2 | Where is the fixed test set, and when was it last scored? | | | |
| 3 | Does a reset restore the build to exactly the same starting state? | | | |
| 4 | What independently checks the main path, and when did it last disagree with it? | | | |
| 5 | Could a stranger install and run this from the package and the documentation alone? | | | |
| 6 | For each step, which record proves its work happened? | | | |

## 8. Security and sovereignty

| # | Question | Score | Anchor | Note |
|---|---|---|---|---|
| 1 | Does anything about to be shared contain a credential shape? | | | |
| 2 | Is the credential any AI tool has access to a limited, disposable one? | | | |
| 3 | Is sensitive-field masking enforced by the platform, or by a step that could be skipped? | | | |
| 4 | Who can see raw, unmasked data, and what actually stops an AI being connected to it? | | | |
| 5 | What does the last package you shared actually contain? | | | |
| 6 | Which AI models read this build's data, and is any of them outside the deployment? | | | |

## Gaps accepted

| Gap | Why it is acceptable now | Accepted by | Date | Revisit when |
|---|---|---|---|---|
| | | | | |

---

*Edition 1.0.3, 4 October 2026. Community edition, published on engineer.imbrace.co - a method guide for building on iMBrace with an AI coding tool.*
