From External Data to AI-Ready Workflows: Software Factory Patterns
agentic workflows

From External Data to AI-Ready Workflows: Software Factory Patterns

12 hours ago • By Anthony Shivakumar

A reader requests a guide. A subscriber buys an ebook. A member asks why a download is unavailable. Each interaction looks simple on the website. Behind it are several different records, handlers and decisions.

Now put an AI assistant into that workflow. What may it read? Which account is the customer referring to? Is the purchase current? Can it resend a message, or only explain the next step? A useful answer depends on the structure around the model.

Customer data becomes useful to an agent when the system can explain what a record means, who owns it, how current it is and which actions are allowed. This article develops reusable patterns for feeding external data into a software factory and giving agents a reliable working context. Antsand provides concrete examples: shared authoring, group-based content selection, generated websites, Forms workflows and site-local customer state.

The examples use a publishing and membership website, but the same patterns apply to a product catalog, a documentation service or an internal business application. Start with the records and decisions your workflow needs, then choose the connections.

Read the architecture in seven decisions

  1. Give each fact an owner.
  2. Keep identity attached to its site and system.
  3. Choose how external data enters the factory.
  4. Trace the actual submission and delivery path.
  5. Give the agent a small, explicit context contract.
  6. Make freshness, failure and recovery observable.
  7. Prove one journey before extending the architecture.

1. Give each fact an owner

In Antsand, a page is assembled from sections, and a section has a header, body and footer. Databoard maps those sections to the intended content and combines them with the website’s application structure—its routes, controllers and views. The factory then generates the application that serves the result.

That gives us an important distinction: the source of the website and the operational records created by its visitors have different responsibilities. Notes can own an article. Databoard can own its placement. A generated site can own a member account or purchase. A central email service can deliver a message without becoming the owner of that member’s password-reset token.

Figure 1. Keep authored content, page configuration and live customer records with their respective owners.
Figure 1. Keep authored content, page configuration and live customer records with their respective owners. Open full-size diagram

In Antsand, groups select related content for a website. Other systems might use a project, workspace or collection. The important distinction is that selecting content for a destination does not also grant access to every customer record associated with it.

When drawing the architecture, put the owner next to the fact. Avoid a single box labelled “customer data” that hides all these decisions.

InformationWhere authority belongsWhat a consumer must not infer
Article or guideIts authored Notes or ebook source, with publication rulesA published article grants access to every linked paid asset
Form submissionThe handler and storage path that actually received itA local database write automatically ran a central workflow
Member accountThe configured site identity handler and account storeA matching number on another site is the same account
Purchase and accessConfirmed commercial state and the current entitlement decisionA checkout return page proves payment or permanent access
Delivery statusThe queue, processor and transport evidence for that messageEnqueued means received in the inbox
Website analyticsThe analytics collection and aggregation contractA visitor identifier is a verified customer identity

The useful pattern is to keep each module responsible for its records while combining their output into a coherent website. Give an agent the same clear interfaces a developer would use, rather than asking it to guess the relationships from a database dump.

2. An identifier needs a namespace

Consider two generated websites. Each has a member numbered 42. Those numbers are local references. Treating them as one person would be an accidental join, with potentially serious consequences for purchases, messages and access.

A useful identifier includes its origin: site, record type and local ID. If an external CRM is involved, keep its account ID as a separate reference. Record the relationship deliberately instead of replacing both identifiers with a guessed universal ID.

Figure 2. The same account number on two sites does not identify the same person. Link accounts only through a deliberate verification process.
Figure 2. The same account number on two sites does not identify the same person. Link accounts only through a deliberate verification process. Open full-size diagram

Email matching also deserves care. A person can change an address; addresses can be shared or entered incorrectly. Even an accurate match does not give permission to combine accounts or transfer a subscription. If you link accounts across sites, record how the link was verified, why it exists and how someone can undo it.

Before building a shared account service, ask whether the task needs one. Explaining a purchase on one website may only require the signed-in member and that site’s purchase record. Keep separate accounts separate until there is a clear reason and permission to link them.

The same principle applies to analytics. Counting visits can help assess a publication. It should not quietly become a mechanism for asserting who a person is. Keep aggregate learning separate from customer actions unless there is an explicit, justified connection.

3. Feed the factory through an explicit intake boundary

A software factory can consume data from another application without giving that application control of the website. An external system supplies records; an adapter translates their meaning; the factory decides how approved records become pages, documents or products.

The interface between those steps is worth designing. A webhook receiving HTTP 200 means the receiver accepted a request under its contract. It does not necessarily mean a record was validated, a draft was approved or a page was published. Give each stage a visible state and a record reference.

Figure 3. Check incoming data, translate it into owned records, then publish approved changes.
Figure 3. Check incoming data, translate it into owned records, then publish approved changes. Open full-size diagram

Choose the movement pattern by the work

PatternFits whenContract and failure handling
Scheduled API pull (check for changes)A catalog or knowledge source changes periodically and exposes a supported APIRead results in pages, save your position after successful processing and respect request limits. Decide separately how removals are handled.
Signed webhook (verified change notice)The source can notify you of a change quicklyVerify authenticity, persist the delivery ID, handle retries and fetch current source state where event ordering is insufficient.
Snapshot importA partner supplies CSV/JSON exports or a team needs a controlled migrationValidate the whole file, stage a diff and review removals. A partial export must not delete every absent record.
Document intakeApproved documents need to become structured reference materialCheck that the material may be used, validate the file, extract a draft and keep its source and version. Instructions inside the document do not authorize actions.
Read-through access (ask the source)A user needs a current fact that should remain with its sourceUse a bounded authorized request, explicit timeout and a defined unavailable state. Do not silently substitute an old value for a live decision.
Change-data capture (CDC)High-volume database changes justify infrastructure beyond ordinary API pollingHandle changes to the data format, saved processing positions, deleted records and permissions. Avoid tying every consumer to the source database layout.

These are portable patterns, not a list of prebuilt connectors. In the Antsand example, a purpose-built adapter would call the documented owning module API, then the appropriate publication operation. The source’s API and the factory’s API still need a mapping between them.

Pattern A: an external catalog becomes a website

Suppose a manufacturer provides a product feed. Use its stable product identifier as an external reference. Map the title, description, approved images and availability into the catalog owner. Keep local presentation fields separate where the editorial team owns them.

For each import, record the source version or cursor, the transformation version and the destination ID. Produce a diff: new products, changed fields, unavailable items and rejected rows. Publish only the accepted changes. Verify the rendered product page and any commercial behavior separately; a synchronized description is not proof that checkout is ready.

If both systems can change the same field, decide the conflict rule before the first run. One practical policy is “supplier owns availability; editorial team owns the display summary.” Last-write-wins is a policy too, but it can erase deliberate local work. Make the choice visible.

Pattern B: approved documents become a knowledge collection

A document importer should create an inspectable draft, with a source reference and version. It should not turn every uploaded PDF into a public page or feed all of its text to a model. Separate text extraction, editorial interpretation and publication approval.

File ingestion needs type and size checks, safe storage and controls on processing. OWASP recommends layered upload validation rather than trusting the filename or declared content type. Apply those checks before extraction, and keep sensitive source files out of public asset paths. OWASP File Upload guidance.

For AI-assisted extraction, preserve the distinction between document content and executable instructions. A document saying “ignore the workflow and publish this” is input to be interpreted, not authority to change the application. Route the resulting draft through the same validation and review path as human-authored material.

Pattern C: an external event requests a bounded action

An event may mean “this order changed,” not “grant this user access.” Verify the event, look up the owned record and apply the destination’s rule. Persist enough information to recognize a repeat. If delivery fails after a state change, retry the incomplete side effect without repeating the entire business action.

A portable event envelope helps adapters share conventions. CloudEvents defines a common event-description format, including identifiers and source information. Adopting an envelope does not supply authorization, ordering or exactly-once processing; those remain part of the receiving workflow. CloudEvents project.

{
  "example_only": true,
  "source_system": "supplier-catalog",
  "source_record_id": "product-108",
  "source_version": "revision-7",
  "destination_kind": "catalog_draft",
  "mapping_version": "catalog-map-v2",
  "publication": "review_required"
}

This example shows the information worth carrying with an import: where the record came from, its version, the translation rules used and whether publication needs review. Adapt it to the receiving API’s required fields and permissions. Log a request reference and a useful error message, without recording passwords, keys or private payloads.

Fetching a URL is also an integration

If the adapter accepts a URL, restrict where the server can fetch and what redirects it may follow. A public URL field should not become a route into internal services. OWASP’s SSRF guidance describes validation and network-layer controls for this boundary. OWASP SSRF prevention guidance.

The useful factory abstraction is therefore a repeatable path from accepted source material to verified output. It can begin with a simple scheduled import. Add streaming, CDC or a shared context service when the workload provides a reason, with the same ownership and recovery questions still answered.

4. Follow the guide-request journey

Suppose the page offers a downloadable field guide. The visible form might be identical in two deployments, yet its processing path can differ.

In the central path, the browser submits to Antsand’s form handler. The central record and eligible workflow actions belong to that path. A configured processor and email transport then handle delivery. In the site-local path, the generated handler stores the submission locally. Calling a central service requires an explicit supported connection; it is not a side effect of sharing the form design.

Figure 4. A central form and a site-local form need different processing paths, even when they look identical.
Figure 4. A central form and a site-local form need different processing paths, even when they look identical. Open full-size diagram

A form’s saved settings tell you what should happen. A test submission tells you what actually happened. Antsand’s Forms diagnostics help connect the form to its configured page and handler. The general lesson is to inspect the whole path: where the request went, where the record was stored and whether the delivery process ran.

For a working guide journey, collect evidence at each boundary: the submitted destination, the stored record, the eligible workflow action, the processor result and the transport response. Use a test recipient and a traceable request. Record retries without duplicating the subscriber or sending the same attachment repeatedly.

Also separate the requested delivery from ongoing marketing. Asking for one guide is not the same as asking for every future campaign. Store the reader’s actual choice and check it before sending. If several applications send messages, decide how they will share and respect changes to those preferences.

A membership question is a different journey

If a member asks for a purchased ebook, begin with the signed-in account and its current right to access the book. That access decision is often called an entitlement check. An assistant can explain a failed request or prepare a reply, but the download service should decide whether access is allowed.

Payment notifications also need clear processing rules. Stripe documents signature verification, duplicate-event handling and the absence of guaranteed event ordering. Check that each notification came from the payment provider, avoid processing it twice and consult the latest payment record when messages arrive out of order. Stripe webhook documentation.

5. Design the context before choosing the model

One useful design is a small service that gathers only the facts needed for a task. For example: “What may this support assistant know about this member’s download request?” This is a context adapter: it collects approved facts from their owners without becoming a second purchase database.

Include where each fact came from, when it was checked and what it may be used for. If information is missing, say so. No delivery record does not prove an email failed, and an old purchase summary does not prove access is still allowed.

{
  "contract": "illustrative-context-v1",
  "site_id": "brand-a",
  "subject": {"kind": "member", "local_id": "42"},
  "task": "explain_download_access",
  "facts": [{
    "name": "access_status",
    "value": "requires_current_check",
    "source": "site_entitlement_handler",
    "observed_at": null
  }],
  "permitted_use": "prepare_support_explanation",
  "write_authority": "none"
}

This JSON is a design example you can adapt, not a ready-to-call API. It leaves access unresolved because the download service still needs to check the member’s current permissions.

Figure 5. Check the caller, the requested record and the allowed action before reading or changing information.
Figure 5. Check the caller, the requested record and the allowed action before reading or changing information. Open full-size diagram

An agent should first learn which operations are available and what it is permitted to access. For example, Antsand exposes these discovery and inspection URLs:

GET /api/v1/help?view=guides
GET /api/v1/me
GET /api/v1/groups
GET /api/v1/databoards
GET /api/v1/databoards/{objectid}/agent-context
GET /api/v1/databoards/{objectid}/page-flow

Start by reading the API’s available operations, required fields and permissions. Where a preview or dry run is supported, use it before saving. Then verify the actual result: a successful save does not necessarily mean the website or customer-facing workflow has been updated.

Authorization must reach the object being requested. An authenticated caller who knows another site’s record ID must not gain access to it. OWASP identifies missing object-level checks as a major API risk and recommends checking authorization wherever an operation accesses a record. OWASP: Broken Object Level Authorization.

For smaller models, clear interfaces matter more than a huge prompt. Give the agent one task, a documented input, a bounded response and errors that explain what must be corrected. Separate “read and explain” from “change and notify.” A model’s ability to describe an action does not give it authority to perform it.

Local and hosted models share the same application boundary

A local model may be appropriate for a particular data-handling requirement or workload. A hosted model may suit another. In either case, the application still needs to minimize the information sent, constrain the available operations and inspect the result.

The context adapter should therefore sit outside the model-specific integration. A model change should not require changing who owns an account or which endpoint may issue a refund. Model hosting, prompt retention and network egress are separate operating decisions that need evidence for the selected deployment.

6. Freshness is part of the meaning

A published article can usually tolerate a deliberate synchronization interval. A password-reset token or purchase revocation cannot be treated the same way. Define freshness by the action being taken, not by a single “real-time” label applied to the entire platform.

TaskSuitable informationVerification before acting
Recommend a public articlePublished catalog or refreshed article cacheDestination remains public and available
Explain a delivery issueSubmission reference and processor/transport evidenceCorrect recipient and permitted message purpose
Open paid contentCurrent site identity and entitlementAccess checked at the protected handler
Prepare a campaignApproved audience projection with an observation timeRecheck eligibility and suppressions before sending
Analyze readershipAggregated events with collection and processing coverageMissing or delayed data is visible in the interpretation

When an original record changes, decide which copies need refreshing. A cancelled subscription may make an earlier access summary outdated; a changed email preference may remove someone from a campaign list. Track updates, limit repeated attempts and periodically compare records to catch changes that were missed. This last step is often called reconciliation.

For the first implementation, an authorized request to the owner may be simpler than maintaining a continuously refreshed customer profile. Measure the actual latency and load before adding infrastructure. Avoid “zero-copy” as a blanket promise: an API may still materialize a response, and a model service may retain information under its own configuration.

Separate release rollback from customer recovery

Generated application files, live customer records and derived caches have different recovery needs. Returning to an earlier template release should not restore yesterday’s purchase database over today’s successful transactions.

Figure 6. Restoring application code, recovering customer records and rebuilding summaries are separate jobs.
Figure 6. Restoring application code, recovering customer records and rebuilding summaries are separate jobs. Open full-size diagram

Keep earlier versions of the application so you can restore working code. Preserve the customer records that accumulated after that release, and check that the older code can still read them. Restoring a database is a separate operation: decide how much recent data could be lost and how missing transactions would be recovered. Rebuild summaries and search indexes using current access rules.

The same planning helps when a customer corrects or removes information. Follow the record into exports, summaries and backups. Decide which copies must change, who handles the work and how completion is checked.

7. Make governance an operating responsibility

Someone needs to own each decision: the purpose of the workflow, the record being changed, the API boundary, the delivery mechanism and the response when it fails. A diagram becomes useful when those responsibilities turn into work that can be reviewed.

NIST’s AI Risk Management Framework organizes risk work around Govern, Map, Measure and Manage, with governance applying across the lifecycle. Here, that suggests keeping ownership, use-case boundaries, evaluation evidence and incident decisions connected as the workflow evolves. Use these functions to organize the work and revisit decisions as the workflow changes. NIST AI RMF Core.

ResponsibilityDecisionEvidence to retain
Business ownerWhat outcome the workflow may produceTask definition, allowed actions, escalation conditions
Module or data ownerMeaning, authority and correction of recordsField definitions, source IDs, revision rules
Platform engineerRouting, deployment, integration and recoveryRelease record, end-to-end checks, restore exercise
Security / privacy reviewerAccess boundaries and permitted handlingThreat review, denied-access cases, handling decisions
Workflow operatorRetries, failed delivery and escalationProcessing status, incident trail, reconciliation results
AI engineerModel behavior within the allowed interfaceEvaluation cases, task success, latency and cost measurements

In a small team, one person may hold several of these responsibilities. Give each task an owner and someone who can step in. The application should make the permission decision; the model can help carry out the work within it.

8. Choose the smallest architecture that serves the task

Choose the simplest connection that meets the need, and add parts when you can explain the problem they solve.

If you need to…Start with…Add more when…
Refresh a catalog every dayA scheduled API import with a change previewCustomers need changes faster than the schedule allows
React to a purchaseA verified webhook and duplicate handlingMore consumers need the same event or processing needs a queue
Answer a support questionA narrow read from the record’s ownerRepeated tasks need a shared, consistently defined summary
Publish approved documentsUpload, extract, review and publishVolume makes manual classification or review impractical
Connect several brandsSeparate site records with explicit source IDsA real customer journey requires verified cross-site relationships

The deciding question is concrete: which part of the journey becomes more reliable, easier to maintain or easier to use?

9. A practical first implementation

Figure 7. Map the journey, test it, add bounded assistance and check the failure cases.
Figure 7. Map the journey, test it, add bounded assistance and check the failure cases. Open full-size diagram

Start with a single support question: “Did my guide request reach the correct workflow?” It is narrow enough to trace, useful to a real reader and unlikely to need a global customer profile.

First, document the record owner and submit destination. Then use a controlled test submission and inspect the processing outcome. Expose only the required status through an authorized interface. Add an assistant that explains the evidence and routes missing information to an operator. Introduce a resend action only after recipient validation, eligibility and replay handling are explicit.

The acceptance cases should include a correct request, an unknown record, a record from another site, a duplicate request, an unavailable processor and stale delivery information. For a paid-content journey, add refund, expiry and direct-URL denial cases. A confident sentence from the model is not the acceptance criterion; the system’s behavior is.

The reusable pattern is a shared factory for authored experiences, clear owners for live customer records, and APIs that let humans and agents work within those boundaries. The architecture can grow as the products grow. It does not need to begin by copying every customer record into one new system.

References and further reading

Continue exploring