AI agent index: /llms.txtFull content index for AI agents: /llms-full.txt
Business

Document generation from platform data (welcome letters, fee schedules) — templates done right

A practical control model for approved inputs, governed templates and recoverable delivery.

Two Words/13 October 2026/9 min read/Document generation
A shared snapshot branches into two paths: WELCOME crosses a release boundary into a retained document, while FEES stops before the boundary at TERMS PENDING.

Consider a client account whose welcome letter is ready but whose fee terms still await approval. Both documents might render perfectly. Only one is ready for release. The decision to automate should turn on that distinction, not on whether the template produces a polished page.

We recommend treating controlled document generation as publication of a specified, approved snapshot of facts and terms. Here, “done right” means a practical control model, not a compliance guarantee. Establish what may be published, block unresolved inputs and retain what was delivered. Leave ownership of account facts and commercial terms with their authoritative sources.

Treat each document as a publication event

For this hypothetical account, keep activation, generation and dispatch as distinct events. The account platform should own activation; document controls should establish publication readiness. Delivery records should distinguish a dispatch attempt from an acknowledged outcome. A generated welcome letter should neither activate the account nor prove that an authorised recipient received it. Record the available level of delivery confirmation; provider acceptance alone does not prove recipient receipt.

Name the snapshot being published and preserve its source versions. If account details change during generation, continue only if the fixed snapshot remains approved for publication; otherwise stop for a newly approved snapshot. Do not combine an earlier account status with a later service selection merely because each is available when the renderer requests it.

Two Words / process
Recommended publication sequence
01
Fix inputs

Select the approved snapshot, document type, template and rules.

02
Validate

Block unresolved approval, mapping, pricing and date exceptions.

03
Render and release

Render, complete required review and store approved output.

04
Deliver and reconcile

Dispatch separately; retain the sent output, provider references and level of confirmation.

Give each stage its own outcome, rather than one shared “complete” status.

Keep publication stages separate from account activation.

Separate account facts from commercial terms

For a welcome letter, require authoritative client contacts, account status and selected services. For a fee schedule, require independently approved pricing terms as well. Approval of the account relationship should not stand in for approval of its price.

Two Words / comparison
Welcome letter and fee schedule
01
Welcome letterAuthoritative account facts

Contacts, account mapping, status and services; approved wording consistent with that status.

02
Fee scheduleIndependently approved terms

Pricing reference, effective dates, currency and applicable tax conventions, tiers, basis, period, minimums, caps and rounding.

Recommended controls: a template should not supply a missing commercial decision.

Apply different approval requirements to the two documents.

Keep fee schedule generation separate from authoritative charge calculation. If the schedule displays computed amounts, reconcile them to the approved calculation version, its inputs and typed monetary results before release. Unknown pricing should stop generation, not trigger a default rate.

Check presentation separately. Microsoft's .NET documentation states that currency formatting rounds excess fractional places in the result string according to the specified or default decimal-place setting. That behaviour does not establish a fee-calculation policy. Specify the permitted relationship between displayed and calculated amounts, including any approved presentation rounding.

Fix the publication inputs before rendering

Define an input package containing the document type, client and account identifiers, snapshot identifier, source versions, approval state, applicable effective dates, approved template version, and rule and clause versions. Make selection explicit: if two templates apply, require approved precedence rather than using whichever matches first.

Use typed inputs so dates, monetary amounts, currencies and account references retain their meaning until presentation. Define missing, null and zero separately. A confirmed zero fee is a value; absent pricing is an exception. For optional fields, specify when omission is permitted and which approved wording follows. Keep a calendar effective date as a date-only value rather than converting it through a timestamp or time zone. For actual instants, record the time-zone and display policy explicitly.

Require generation to stop when any of the following conditions applies:

  • Missing required fields or stale approval for the selected inputs.
  • Invalid client/account mapping.
  • Unknown pricing or contradictory dates.
  • Unrecognised currency or locale.
  • Overlapping applicable templates without approved selection precedence.

Route each exception to an accountable owner. Do not substitute blanks or zeroes to obtain a successful render.

Adopt an explicit date, currency and number-formatting policy. For .NET numeric formatting, Microsoft documents that results for a specific culture can vary with operating-system settings, user settings, environment variables and .NET version. Pin and test the relevant environment rather than assuming a locale selection makes output stable. Treat tax conventions as a separate approval decision, not something inferred from locale formatting.

Choose exact decimal or fixed-precision handling for money deliberately. PostgreSQL recommends numeric rather than floating-point types for exact storage and calculations such as monetary amounts. This supports the storage and calculation choice in PostgreSQL; it does not settle fee rules, tax treatment or rendered rounding.

Limit what templates can decide and execute

Allow conditional content through reviewed rules and approved clauses. A service selection may select an approved paragraph; it should not introduce arbitrary wording from an input field. Version reusable headers, clauses and tables, and specify their compatibility with each consuming template. Changes to shared components should pass through approval rather than silently alter released templates.

Handlebars shows why the technical owner must check engine-specific behaviour. Its ordinary double-brace expressions HTML-escape returned values. Treat that as a control for those expressions, not as sanitisation of arbitrary raw HTML or protection for every output context. Require handling appropriate to the engine and context for untrusted names, addresses and other platform text.

Handlebars also gives a registered helper priority over an input property with the same name unless the property is explicitly resolved using this. In that implementation, control helper names and resolve fields deliberately so a naming collision does not change which value is published.

Restrict template editing and release to authorised roles. Never evaluate platform user data or arbitrary clause strings as template logic. Permit raw HTML and external-resource fetching only within explicitly approved boundaries. Aim for deterministic rendering where feasible by fixing inputs, template components, fonts, assets and rendering settings.

Make generation and delivery recoverable

Assign a stable request identifier to one intended document issuance. Bind it to the complete approved input manifest: document type, client, account, snapshot, template, rule and component versions, and formatting context. Reuse that identifier for retries and compare the stored manifest; reject reuse with different inputs. Record the request, manifest and initial operation state together so concurrent attempts reuse the same operation and retrieve its existing outcome. A separately authorised issuance or changed approved input needs a new identifier and a traceable successor or revision, without overwriting delivered output.

Amazon Web Services (AWS) recommends idempotent Lambda code: validate events and handle duplicates consistently. Apply that principle to generation and delivery, with separate state for each. It does not guarantee exactly-once delivery. If a send outcome is uncertain, reconcile it before deciding whether to resend.

Give the handoff to delivery an explicit consistency mechanism. AWS describes the transactional outbox pattern as addressing the dual-write problem: a database write and a message notification can leave inconsistent data if one fails. Consider that pattern where persisted generation state must trigger delivery work. Its scope is database/message consistency, not approval of document content.

Two Words / comparison
Recommended evidence to retain
01
Generation recordWhat was approved and produced

Link the publication identity, approved input versions, processing evidence and retained output.

02
Delivery recordWhat was sent and acknowledged

Link the authorised recipient, dispatch history and confirmed or reconciled delivery outcome.

Keep the evidence connected without treating successful generation as successful delivery.

Link generation and delivery records through the same publication identifier.

The manifest and linked delivery record should retain the following fields:

  • Generation identity: document and generation IDs, client and account.
  • Approved inputs: snapshot, source, template, rule and component versions.
  • Processing: time, actor or service, validation, review and renderer version.
  • Retained output: checksum and approved bytes.
  • Delivery publication: identifier, retained sent output and manifest.
  • Recipient: identity and authority.
  • Dispatch: provider/message references, delivery state and attempts.
  • Outcome: level of confirmation and reconciliation result.

Archive delivered bytes with their manifest, the record linking the output to its inputs and processing history, and protect them from overwrite. Retrieve that copy for inspection rather than rebuilding from today's data. Use an output hash or checksum to detect byte changes, not as proof of the original facts, authenticity or authority. Assign archive access and retention decisions to accountable owners.

For investigations, AWS Lambda guidance recommends structured logs in JavaScript Object Notation (JSON), which makes them easier to search, filter and analyse. Use consistent publication identifiers in operational records while retaining the output and manifest separately. The guidance does not prescribe document audit fields, archival controls or retention periods.

Test exceptions before expanding automation

Make release approval depend on expected behaviour under exceptions, not just an attractive standard document. For each test, define whether the service should produce output, stop or enter review, and what evidence should remain.

  • Welcome letters: standard data, missing required contacts, long names and addresses, and multi-custodian context. Verify account mapping, status, services and recipient.
  • Fee schedules: tiers, basis, period, currency, rounding, effective dates, applicable minimums and caps, and zero versus missing. Reconcile displayed amounts to the approved calculation.
  • Trust and versioning: malicious-looking names remain safely escaped text; withdrawn or inapplicable templates and stale approvals stop generation; concurrent changes do not mix snapshots.
  • Recovery: duplicate requests, rendering failures, delivery failures and missing acknowledgements follow the defined retry or reconciliation path without blindly resending.
  • Output and retrieval: Unicode characters, fonts, multi-page tables and page breaks remain readable; the archived delivered copy and manifest can be retrieved.

Assign a business owner for wording and commercial approval, and a technical owner for source mapping, rendering and delivery. Govern template changes as versioned releases with reviewed differences, applicable effective dates and a defined withdrawal path. A wording edit should pass the checks relevant to what it changes.

Use human review where a person has a defined decision to make: approving changed commercial wording, resolving contradictory terms or authorising an exception within their remit. Keep unresolved source facts blocked until the responsible owner corrects or approves them. For routine documents within tested rules, consider automatic release rather than inspection of every copy.

Before increasing volume, ask the team to retrieve one delivered publication and demonstrate why it was authorised, what it contained and how its delivery outcome was reconciled. If they must reconstruct that answer from today's data or someone's memory, keep the workflow constrained. Make that demonstration, rather than rendering success, the condition for expanding automation.

Keep reading

All posts
Start here

Some of our best projects started with a two-line email.

Most of our work starts with a conversation. No deck required.

Start yours