---
title: From orchestration to production
scope: 3dmk
type: documentation
subject: orchestration
group: Overview
status: current
version: "2.1.3"
source: https://3dmk.com/documentation#orchestration
author: Nick Olson
contact:
  email: 3dmk@3dmk.com
  site: https://3dmk.com
license: CC BY 4.0
license_url: https://creativecommons.org/licenses/by/4.0/
attribution: Nick Olson, 3dmk.com
---

# From orchestration to production

Seeded work runs through one trigger and ships through one release route. The orchestration trigger reads an initiative’s state from Scrolls and agrees on a scope with the developer. It then plans the work, hands each item to a subagent, and checks every result before the item closes. Publishing turns the finished work into one tagged build that every environment runs. This page follows Trailcast from its first ready task to production.

*Figure: One way Trailcast could run, in three sessions. The drawing is on the page.*

## A schedule for Trailcast

The schedule shows one way the Trailcast initiative could run, in three sessions. Each session opens with a stop, where the developer confirms the scope and approves the plan. Foundation runs alone, because every later item depends on the repository, the schema, and the bootstrap.

The second session fans out. Once the bootstrap lands, the trails endpoint, the readings endpoint, and the feed daemon start together, each with its own subagent. As each item closes, the items that waited on it start. At the busiest point, four subagents run at once.

The hatched segments mark work that a check sent back. The readings endpoint failed its acceptance criteria once, and the feed daemon stepped out of bounds once. Each went back to a subagent and passed the second time. A point marks each epic’s close, where the graph gets checked. The release runs last, and production waits for the developer’s approval.

## State

The trigger, `trigger orchestration`, takes an initiative name. If the initiative does not exist in Scrolls, the trigger stops. Otherwise it loads every epic and work item, each with its dependencies, its agent specification, and its status. It then sorts the items into four states.

| State | Meaning |
|---|---|
| Completed | Done and closed in Scrolls |
| In progress | Started and not yet finished |
| Ready | Every dependency complete, and not yet started |
| Blocked | Waiting on a dependency that is not complete |

For a fresh Trailcast initiative, the foundation tasks are ready. The API, daemon, and website tasks are blocked behind them. Each later session reads the same state and starts where the last one stopped.

## Scope and plan

The agent presents that state, grouped by epic, and stops. The developer names where the work starts and where it stops for this session. Nothing runs until the developer confirms.

The agent then enters plan mode. From the confirmed scope, the Technical document, and each item’s agent specification, it writes a step-by-step plan. The plan orders the items by their dependencies and marks the ones that can run in parallel. It names the model for each item and the checks each item must pass. The developer approves the plan before any file changes.

## The orchestrator

Once the plan is approved, the main agent becomes the orchestrator. It writes little of the code itself. It routes each item to a subagent, checks what comes back, and keeps Scrolls current.

Before the first item, the orchestrator checks that every epic in scope is ready or in progress. An epic in any other state stops the run. When the first item of an epic starts, the epic moves to in progress.

Each subagent starts from a brief, not from the conversation. The brief holds the item’s agent specification and the Technical sections it cites. It also holds the Magi nodes the item touches, with the item’s acceptance criteria and testing subtasks. The item’s size picks the model: Haiku for small, Sonnet for medium, and Opus for large.

Items that do not depend on each other run in parallel. An item waits for every item it depends on. Every item then runs the same loop, and every release runs the same route.

*A figure on the page draws this.*

## Validation

A subagent’s report is a claim, not proof. The orchestrator runs every check itself before it closes an item. Every task carries two subtasks from the seed, and both must pass:

- Acceptance criteria: the code does what the item says, under the conditions the item states

- Testing: the tests the item calls for exist and pass

The two prove different things. Tests can pass while the work is still wrong. For the readings endpoint, the subagent’s tests passed, but the endpoint returned readings oldest first. The criteria asked for the last day of readings, newest first.

Any failed check sends the item back. The orchestrator returns it to a subagent with the failed check, its output, and the evidence of what is wrong. The item stays open until every check passes.

Only then does the orchestrator close the item and its subtasks in Scrolls. It commits and pushes the change before the next item starts. An epic closes when every item under it is completed or cancelled.

## Automated tests

Each item adds unit tests for the code it adds. The goal is coverage as close to 100% as the code allows. The language standard sets the test framework, the file names, and the layout.

The whole suite runs after every item, not only the new tests. Each change proves that it did not break the work before it. A failure in an earlier module counts against the new item, and the item goes back.

For Trailcast, the suite holds three kinds of test.

| Kind | Covers | Runs |
|---|---|---|
| Unit | Each function and class on its own, with the feed and the database stubbed | After every item |
| Integration | The API and both daemons against a test database | After every item |
| End to end | The site in a browser against a running deploy | After each deploy |

## Atlas in the loop

Atlas is how the orchestrator sees the code without reading it file by file. Each snapshot records every file, class, function, constant, and import at one commit. The orchestrator pulls it after each change, both to check the change and to trace a failure to its source.

A change is in bounds when it matches its agent specification and the Magi nodes it touches. A class the specification never named is out of bounds. So is an import the library matrix does not approve, or code that does a job the graph gives another node. The orchestrator sends that change back with the Atlas entry as evidence.

The feed daemon’s first pass shows both uses. A test failed because some readings arrived without a trail. The Atlas showed two report parsers, and the daemon imported an old one that an earlier attempt left behind. It also showed a function in the feed daemon that wrote summaries, a job the graph gives only to the summary daemon. The subagent removed both, and the next run passed.

The orchestrator reads these from the Atlas during testing.

| Need | What the Atlas shows |
|---|---|
| Where a failure starts | The file and line of each class and function the failing test reaches |
| What a change added | New files, classes, functions, and imports, against the previous snapshot |
| What depends on a module | Every import of that module across the repository |
| Whether a model matches | The class fields, compared with the model on the Magi edge |

## Magi at each epic’s close

Atlas checks the detail inside the loop. Magi checks the shape at a higher level. When an epic closes, the orchestrator runs `trigger magi` against the code the epic produced. Every node needs running code, and every data edge needs a model that matches the class that carries it.

A gap at this point has one of two causes. Either the code drifted from the design, or the design missed something the work needed. The first goes back to a subagent as a fix. The second stops for the developer, because only an approved document changes the design.

Larger stretches of work end with the reconciliation jobs, which the reconciliation page describes. Between those runs, Atlas and Magi hold every item to the design that seeded it.

## Tagging a release

A release starts only when every check passes. For Trailcast, that means the whole suite of the API and both daemons, plus the site’s page checks. A failed check stops the release, and the agent reports its output in place of a summary.

One command versions the repository. It bumps every file that declares the version, commits the staged work with it, tags the commit, and pushes. Major and minor versions always get a tag, and a patch gets one when it ships. The Trailcast site prints its version in the footer, so a check of the running page can read it.

The tag is the release. A deploy refuses a tag that is not on the remote. The build starts from an archive of the tag, never the working tree, so an uncommitted file never ships. The deploy specification and the compose file come from the tag too. The image carries the same version, and a version is never reused, so one version always names one build.

## Development first

Every release runs at home before it reaches Amazon Web Services (AWS). The development deploy builds the image once from the tag and starts it on the development host. Each deploy runs a fixed series of named steps, from export and build through start, register, and retain. A failure names its step.

Guards protect running work. A deploy holds while users are still connected, and it fails before any change when the host lacks disk space. Database patches apply before the new containers start.

The agent then verifies the running release against what changed. For Trailcast, the footer shows the new version, and the health check reports the database and both daemons. The feed daemon logs its first pull. The end-to-end run drives the site in a browser against the development deploy.

A failure here never becomes a fix in place. The fix lands on the main branch as new work, and a new version takes the same route from the start.

## The same build in production

Production waits for the developer’s approval, and one approval covers one deploy. The production deploy ships the image that development verified to the production host in AWS. Nothing rebuilds between the two.

Each environment supplies its own configuration when the container starts. The image stays the same, so what passed at home is what runs in production. The agent then repeats the checks against the public site.

Publishing records each deployment with its commit, tag, image, and status. The Registry records which release runs in each environment. Each host keeps its running release and the one before it. A rollback deploys the previous version, and the build and ship steps skip because the image is already there.

Database patches only move forward. A patch adds tables and columns and never renames or drops in the same release, so the previous release still runs on the new schema.

## Infrastructure on demand

The production side does not wait on a console. An infrastructure service in Core speaks to seven AWS services directly, and every resource type answers the same five operations.

*Figure: One infrastructure service, seven AWS services. The drawing is on the page.*

Apply creates a resource or updates it to match a request. Describe and list read what the service manages, and discover enumerates everything in the account, including resources made elsewhere. Destroy removes a resource. Publishing never calls AWS itself, and every resource it needs goes through this service.

The production host came from the same service: its instance, network, storage, and address. For the first Trailcast release in production, one work item asks for a DNS record for the site’s public name. The production edge then adds a route for the site and serves it over HTTPS.

A static site takes different resources: a bucket in Simple Storage Service (S3), a CloudFront distribution, a certificate, and an alias record. A serverless route takes Lambda functions behind API Gateway. Each one is a request to the same service.
