# Transactional Execution Guide — the transactional shape at build

A genome whose Transactional Shape is not the stub ([transactional-shape-guide.md](transactional-shape-guide.md)) adds three things to [execution-guide.md](execution-guide.md): the split questions, the projects their answers materialise, and the REFramework surfaces each consumer project is built on. The behaviour the genome states is owed whatever the answers.

## Split questions

Asked once per **flow** of the Transactional Shape (its `### Flow N` blocks, in the order of the `Flows:` line), after the genome questions and before any scaffolding question, because the project list depends on every flow's answers. A component that takes part in several flows is resolved once, after all its flows are answered (§ Projects from the split answers). Every option is concrete; the first is **prepared from the genome** — the As-is table, the Evidence line and the derivation table of [transactional-shape-guide.md](transactional-shape-guide.md) rule 8 — and marked "(Recommended)"; the As-is option is the recommendation when the evidence favours nothing else. Questions whose condition does not hold are not asked.

| Topic | Question | Options (first = Recommended, prepared from the genome) |
|---|---|---|
| Unit of work | Which item is the transaction? | the genome's unit of work; each Alternative unit of work, with its fit condition and the Requires and Changes cells of its Split option rows quoted. When the unit is the child of a container that has its own rejections or end-of-parent work (a mail and its rows, a folder and its files), each option says where that work runs: at the child unit in the item fetch, outside the framework's handling of an item's outcome; at the container unit inside the transaction, its children a loop there |
| Split | How are the producer and consumer roles divided? | the genome's Split option rows **for the unit just chosen** — A (one process, both roles, no queue), B (a producer process and a consumer process) or C (one process, both roles, with a queue), the one the Evidence favours first (as-is when nothing favours another), each with its Requires and Changes cells; an excluded option shown last with its reason. The number of runners is not asked here: it is a deployment setting of each resulting process (Triggers) |
| Producers *(As-is names several sources)* | One producer for every source, or one per source? | one producer with every source (as-is); one producer per source, each with its own trigger, in one project; one producer per source as separate components |
| Consumers *(As-is names several item kinds)* | One consumer for every kind, or one per kind? | one consumer with a route step (as-is); one consumer per kind with one queue per kind; one consumer per kind sharing one queue by a reference convention — flagged fragile |
| Item store | Where do the items live? | B and C: one Orchestrator queue per unit of work (under C filled and worked by the same process); A: in-process list read once per run (one runner) — no queue; the source's own database when the As-is names one the process owns ([transactional-shape-guide.md](transactional-shape-guide.md) rule 3); one queue per unit of work **plus** the source's coordination stores kept (parent queue, ledger, lock) — offered only with the reason the genome's Coordination row gives |
| Template | Build each consumer project on the REFramework template? | REFramework in the mode the store implies — queue for a queue store, direct for an in-process store, and under C the producer steps in its initialisation behind the once-guard (Recommended); plain project — the per-item loop, outcomes, retries and per-item records authored from the genome's Error Handling and Transactional Shape |
| Shared steps *(B chosen; or two components' genomes describe behaviour that [genome-format-guide.md § Two Levels](genome-format-guide.md) rule 6 gives a library component the genome lacks — asked once, not per flow)* | The steps several projects need — configuration, guards, logging, run setup and cleanup, the mail client, the error mail — are duplicated or shared? | duplicated in each project (Recommended below about five steps); a common non-UI library component the executor creates, named in the report; under B also: kept in the consumer only, the producer re-implements the minimum it needs |
| Triggers and runners | How does each resulting project start, and on how many runners? | B producer: time trigger at the as-is cadence, one runner; B consumer: queue trigger with a robot cap (Recommended) or a time trigger on the robot pool; A: one time trigger, one runner; C: one time trigger at the as-is cadence on the as-is runner count, the once-guard making a later runner's population a no-op; manual start for replays — recorded for Deployment and the open-items file; the build creates no trigger |

Rules:

1. The split questions are asked once per flow of every Transactional Shape that is not the stub — the genome describes and never decides, so the questions are never skipped because the As-is "seemed clear". A component that is not an RPA process cannot consume ([transactional-shape-guide.md](transactional-shape-guide.md) rule 2); a genome whose As-is names one has a defect: report it and do not ask. The answers are recorded under `Scaffolding`, one line per flow, as `Split: Flow <N> (<components>) — <A|B|C> — unit <item>; producers <n> (<sources>); consumers <m> (<kinds>); runners <producer n, consumer m>; store <one queue per unit | in-process | queues + kept coordination stores: …>; template <REFramework <queue|direct> | plain> per consumer project; shared steps <duplicated | library <name> | consumer only>; triggers <…>`. A "plain" template answer changes the project template, never the behaviour owed: every outcome, retry, postponement and per-item record the genome states is still built.
2. Autonomous runs ([execution-guide.md § 1.3](execution-guide.md)): for the split questions the default, for every flow, is the As-is option with the genome's unit of work — B with a queue store when the As-is runs the producer and the consumer as separate processes or entry points; C with a queue store when one process both produces and consumes and shares its items across robots, runs or a later reader; A with an in-process store otherwise — its implied template, and the As-is runner count.

## Projects from the split answers

**Resolve the split answers** (§ Split questions, one per flow) before creating anything:

- **Per flow first.** Each flow's answer says, for its producer and consumer: one process holding both roles, without a queue (A) or with one (C), or a producer process and a consumer process (B). For a flow inside one component, A and C keep one project and B splits it (below). For a flow between two genome components, B is one project per component (as-is) and A or C materialises **one project holding both components' roles** (under C with the queue between them kept), listed in the report's Files table under both components.
- **Then per component, across its flows.** A component in several flows takes the union of what its flows imply: a chain component that is the consumer of Flow 1 and the producer of Flow 2 hosts the Flow 1 consumer and creates the Flow 2 items inside its per-item steps (never in a once-per-run surface); a component that consumes two flows gets one consumer entry point, and one REFramework consumer project, per flow it consumes. Answers that pull a component two ways — Flow 1 merging it with its upstream component while Flow 2 splits the same component into producer and consumer projects, or two merges that chain three components into one project — are shown to the user with the resulting project list and confirmed before anything is created.

- Option A: the project the flow lands in — the component's own, or the one project of a merged pair above — keeps an in-process store and no queue; the producer's steps run inside the one job before its items are taken.
- Option C: the project the flow lands in, as under A, has one entry point and one trigger, and the unit-of-work queue declared as a solution resource as under B; every job runs the producer steps first behind a **once-guard** — the unique reference the queue refuses twice, or the source's ledger when the user kept it — and then takes items from the queue, so any number of runners can start the same process without producing twice.
- Option B: one genome component **materialises as several processes** — several projects, or one project whose producer and consumer entry points are each published as their own process when the As-is already has that shape — named after the component and the role — `<Component>.Dispatcher`, `<Component>.Performer`, or `<Component>.Dispatcher.<Source>` / `<Component>.Performer.<Kind>` — each created through the owning skill with that component's scaffolding answers. The genome's Components table is **not** edited; the report's Files table lists the materialised projects under their genome component with the split option that produced them.
- The store answer decides the solution resources: one Orchestrator queue per unit of work (or per consumer kind) declared with the attempt limits and the unique-reference rule the Outcomes table and the Reference rule imply; a source coordination store (parent queue, ledger, lock) is declared only when the user kept it.
- A common library chosen under "Shared steps" is created as a library project beside the projects that call it and packed first ([execution-guide.md § 1.5](execution-guide.md)).

**REFramework chosen** for a consumer project: create it from the REFramework template through the owning skill's project-creation step and its template-selection rules (it searches the template feed and never silently picks a Marketplace template), with the same scaffolding answers. The template's own files — the state-machine entry point, the configuration loader, the item fetch and status surfaces, retry, close and kill, screenshot — are the framework's: keep them and configure them per § REFramework at build. Never scaffold a blank project and hand-write a state machine, and never rewrite a framework file from memory.

## Groups and surfaces

Groups are planned per **materialised project**: a consumer project lists the surface each of its steps lands on — once per run → initialisation, per item → the per-item process, at the end → close — taken from the As-is Step groups row of the genome's Transactional Shape; a producer's steps go to the producer project or entry point, never to a consumer's initialisation; shared once-per-run steps go where the Shared steps answer put them.

## REFramework at build

Build each consumer project chosen for the REFramework on the template's surfaces per the owning skill's REFramework guidance, never from memory:

1. **Mode from the store answer.** A queue store: the queue named for the unit of work goes into the settings and the template's item fetch and status surfaces stay as shipped; queue retries own the per-transaction retry, so the framework's own retry count is 0 and the source's in-phase retries (close the application, sign in again, retry the phase) stay inside the phase workflow. An in-process store (option A, the owning skill's tabular mode): a source complete at the start of the run is read once in the initialisation surface; a source the run polls until an end time (a mailbox, a drop folder) is polled by the item fetch, whose waits between polls follow the owning skill's stop-signal rule for waits inside the item fetch. The item fetch returns the next row or file, and nothing when the source is exhausted or the run ends; the status surface writes back where the Traceability line says instead of updating a queue item.
2. **Steps.** Consumer once-per-run steps into the application-open surface; per-item steps into the per-item process surface; at-the-end steps into the close surface. A Workflow step is a unit of the genome, not a file: the owning skill's rule for when a workflow file is worth writing decides the files, so a step of a few activities stays inline in its surface or in the workflow of the step it serves. **Where a producer's steps go follows the split**: A — the initialisation surface reads the source into the in-process list (item 1); C — the initialisation surface runs them once per job, before the first item fetch, behind the once-guard, and a failure there ends the job before any item is taken and is never retried as a transaction; B — never in the consumer: they are the producer entry point or project.
2a. **Applications.** Beside the at-the-end steps the close surface holds, the close and kill surfaces cover every application the project opens — its Target Applications and the applications its libraries launch — as the owning skill's checklist asks: an application is not a step, so no step mapping brings it there. The source's force-closes, which an extracted genome words as cleanup, name the processes. Where the source reuses an application a previous run left open, the framework's kill at the first initialisation changes that behaviour: keeping or dropping it is a decision recorded with its reason and reported as a deviation.
3. **Outcomes.** Every rule the outcomes table lists as a business exception is thrown as a business-rule exception carrying the genome's reason wording; everything else propagates as a system exception; a Postponed row becomes the queue postponement (or the pending write-back) with its limit; the retry and consecutive-failure counts go into the constants, from the outcomes table or from the Configuration Answers when the genome asks them. When the genome's system-exception outcome is retries **inside** the step (a re-logon count, a write attempt count) followed by a run stop, the framework's per-item retry is 0 and its consecutive-failure limit 1: the framework must neither multiply the in-step retries nor repeat a posting the step may already have made; with a queue store the queue's attempt limit is the only cross-run retry. Outcomes of the level above the item — a folder or a mail rejected before any row of it has been taken — have no transaction item yet: they are handled where the item fetch takes that container, recorded with their reason and reply as the genome says, and the fetch moves on; they are not thrown as a transaction's business exception. A stop decided outside the per-item surface (in the fetch, in the status surface) carries its reason to the end state so the job ends faulted. So does a failure of the close surface's own steps (the final mail, the clean-up) where the source's end fails the run: the framework only logs a failure there (the owning skill's End Process guidance), so the reason is set before those steps run, and each of them is contained so the others still run.
4. **Configuration.** Settings and constants from the Configuration Answers per the section's split, where the Settings store answer puts them; the assets sheet from Platform Dependencies and from the settings that answer makes Orchestrator assets; no secret in any sheet. A setting the source addresses by number (a row of its configuration table) keeps that number in the configuration file, so it traces back to the source, and is read through one named member defined where the settings load: no workflow reads a setting by its number, and the guards ([execution-guide.md § 1.3](execution-guide.md) rule 8) name the same members.
4a. **State.** The run's settings, identity and reference data are one object the initialisation surface fills and no later workflow writes; an item's values travel on the transaction item or as arguments of the workflows that use them, and a workflow that changes a value takes it as an in/out argument. One mutable object handed to every workflow hides which step writes what.
5. **Traceability.** The per-item record carries the outcome reason where the Traceability line says (queue status, progress and output; or the write-back); the template's screenshot on system exception stays.
6. **Coordination.** Source coordination the user did **not** keep (a parent queue, a ledger, a lock) is realised as what the split makes it: de-duplication on the unit-of-work queue, a derived parent view, a single producer job; what the user kept is built as declared. Under C the once-guard is the kept ledger when the user kept it, otherwise the unique-reference add on the unit-of-work queue — a later runner's duplicate adds are refused and it goes on to consume. Every such realisation is a deviation from the As-is and is listed in [execution-guide.md § 3.3](execution-guide.md).
7. **Checklist.** The owning skill's REFramework customisation checklist is worked through in full before the group is reported complete, and the group report lists every item as done or not applicable with the reason; no global exception handler is added.

The framework's own files are configured, not authored, and are not workflow steps in the group report.

**Alternative unit of work chosen** (§ Split questions): re-derive the As-is and the outcomes at that granularity before item 1. The unit-of-work line and the producer's reference rule take the alternative's item and reference; the steps that iterated over the genome's unit of work become a loop inside the per-item group; a rejection of one former item is recorded in the new item's outcome reason and does not end the item, unless a Business Rule rejects the whole; the outcomes table is re-read at the new level. Record the unit under `Scaffolding` and report it in [execution-guide.md § 3.3](execution-guide.md) as a deviation from the As-is, with its reason. The genome is not edited ([execution-guide.md § Anti-patterns](execution-guide.md) 6).

**Verify the group** ([execution-guide.md § 2.2](execution-guide.md) step 3): when a consumer project is built on the REFramework, the group also reports the customisation checklist complete and, where the owning skill offers a local run, drives one synthetic item through each exit — success, business exception, system exception retried, system exception stopping the run — and reports each exit as passed, failed with the observed behaviour, or not runnable; a failed exit blocks the group from being reported complete.

## Anti-patterns

1. **A shape asserted in the genome or chosen silently at build.** Skipping a split question because the As-is seemed clear; folding a producer's steps into the consumer's initialisation state outside option C, or under C without the once-guard; carrying a source's parent queue, ledger or lock into the build because the source had it, without the user having kept it; two queues for one unit of work, or one queue for two units; materialising projects the report does not tie to the split option that produced them; wrapping a linear flow in a state machine; scaffolding a blank project and hand-writing the state machine or its plumbing; adding a Global Exception Handler to a framework project; writing a secret into a configuration sheet; or reporting a framework group complete without the customisation checklist and the exits it exercised (§ Split questions, § Projects from the split answers, § REFramework at build).
