J
Hosting and deploymentPartial

A private runtime with controlled public entry points

OpenAnvil separates the web app, run control plane, mobile compute, and durable run data. Deployment validates each boundary before cloud mutation begins.

01

How the web app is hosted

The Next.js app runs privately in ECS behind an internal ALB. API Gateway with VPC Link is the controlled public entry. https://openanvil.ai is the canonical public URL, manually managed outside IaC.

Cloud topology

Public clients enter through API Gateway. The app, workers, control plane, and data remain behind managed private boundaries.

WorkingPartialTarget
OpenAnvil cloud topologyBrowser and CLI traffic enters API Gateway. The app runs on ECS behind an internal load balancer, while events coordinate workers and all run data is stored in S3.PRIVATE AWS RUNTIMEBrowserdocs + run explorerThin CLIPOST /runsAPI Gatewaypublic ingressInternal ALBVPC Link targetECS FargateNext.js appAPI Lambdamanifest + run_startEvent controlEventBridge + queuesWorkersLinux EC2 + MacS3 runsdurable evidenceVPC ENDPOINTSECR + S3 + SSM, no NATIMMUTABLE IMAGESapp + agent + gradersSECRETSnamed env + Secrets Manager
Browser or CLI
https://openanvil.ai via Cloudflare
API Gateway
Custom domain openanvil.ai, regional TLS 1.2, ACM cert in us-west-2, $default stage
VPC Link
Private connection to internal ALB
Internal ALB
Routes app traffic, private scheme
ECS Fargate
Runs immutable Next.js image
Read path
The web app reads run metadata, transcripts, code, grading output, and screenshots from the runs bucket through server routes.
Command path
Actions such as stop, clone, and boot grader go to SQS. The app does not invoke control Lambdas directly.
Canonical URL
https://openanvil.ai is the canonical public URL. Cloudflare CNAMEs for apex and www point DNS-only to the API Gateway regional domain d-sdwt2g8fg7.execute-api.us-west-2.amazonaws.com. ACM certificate arn:aws:acm:us-west-2:480007296405:certificate/f23a896b-617e-4363-8b0c-edb2157e991c covers openanvil.ai and www.openanvil.ai.
Manual management
Cloudflare DNS and API Gateway custom-domain creation plus API mapping are manually managed. Preserve the two ACM validation CNAMEs _400290845bf85cc294598ea648cb4b5e and _affd546feb6354d5adc503d08b04c638 for auto renewal. No Route 53 zone, no CloudFront, no stack 17.
02

Three planes keep responsibilities clear

The architecture is easier to reason about when storage, control, and execution are separated.

Data plane

S3 is the durable run record

The runs bucket stores manifests, machine state, transcripts, generated code, grading evidence, and reward. Versioning protects the record.

Control plane

Events coordinate the lifecycle

EventBridge, SNS, SQS, and Lambda route start, submit, stop, clone, and grader actions without coupling clients to compute.

Execution plane

Workers build and grade apps

Linux EC2 workers run agent and Android images. Dedicated Mac hosts run Tart and iOS Simulator workloads.

03

How a cloud run reaches compute

The client starts a run without holding AWS credentials or launching EC2 directly.

  1. 1The client calls POST /runsAPI Gateway (default prod https://j54iumeh78.execute-api.us-west-2.amazonaws.com/prod from yaml cloud.api_url) forwards the request to the API Lambda. The request includes trial, platform, model, and safety limits.
  2. 2The API records intentThe Lambda creates the run identifier, writes initial machine.json status queued to S3 so GET returns queued immediately (fix for not_found persisting), and emits run_start.
  3. 3Events fan outEventBridge openanvil-orchestrator-bus forwards the event through SNS. Filtered SQS queues isolate app updates, run launch, grader boot, and indexing.
  4. 4The control Lambda launches computeThe run-launch queue invokes the control Lambda. It creates an EC2 worker in a private subnet, writes machine.json status provisioning → running, waits for SSM Online.
  5. 5SSM starts the runtimeThe Lambda sends an asynchronous nohup command that pulls the immutable image and starts the OpenAnvil agent loop inside docker.
  6. 6S3 reports progressThin CLI now live-follows via GET /runs/{id} and /runs/{id}/logs polling every 3s, showing 📥 Queued → 🔧 Provisioning (instance_id) → 🖥️ Machine Booted → 🤖 Agent Loop → 🧪 Grading, with transcript events, not just single snapshot.
04

CI and deployment workflows

Three workflows form the app deployment chain. A fourth workflow builds reusable runtime and grader artifacts independently.

GitHub Actions control plane

The app deployment chain is sequential. Builder images run on an independent path-triggered and scheduled workflow.

WorkingPartialTarget
01No AWS mutation

Validate Repo

Trigger: push or pull request to main

Proves: code, trials, app, infra, image input

02OIDC, no execute

Cloud Predeploy

Trigger: 01 completed successfully or manual

Proves: live account readiness and change sets

03Cloud mutation

Deploy Platform

Trigger: 02 completed successfully or manual

Proves: immutable image, ECS, health, ingress

90Independent

Build Images

Path changes, manual dispatch, or Monday schedule.

Publishes Android grader, agent runtime, iOS pantry, and code bundle artifacts.

Verified checkout trust
Every workflow requires the runner-mounted CA bundle for Git, Node, curl, and OpenSSL. Jobs fail before checkout when the bundle is missing, and TLS certificate verification is never disabled.
01

Validate Repo

Fast, deterministic, no AWS mutation

Trigger and permissions

Runs on every push and pull request to main. The ubuntu-latest label resolves through the internal Actions runner, and this workflow does not request AWS credentials.

What must pass

Secret and dash checks, Python tests on 3.11 and 3.12, every trial validator (now checks description required, category, platforms), the Next.js build, workflow parsing, CloudFormation lint, shellcheck, infra contracts, and a Docker build without push. CI validate-trials loops openanvil validate $trial for each trial.

Job dependency shape
Harness tests and infra checks fan out after lint. The app build waits for harness tests. Docker validity waits for both the app build and infra contracts.
Handoff
A successful run on main emits the workflow completion event that starts Cloud Predeploy. Pull requests stop after repository validation.
02

Cloud Predeploy

Live account proof, no execution

Automatic trigger

Runs only after 01 Validate Repo completes successfully on main. A manual dispatch can start it directly.

Authentication

GitHub OIDC assumes the openanvil-infra-deployer role. No long-lived AWS key is stored in the workflow.

Readiness checks
The workflow resolves VPC, private subnet, and ALB listener outputs. It also surfaces orphan IAM roles, bad bucket wrapper stacks, external bucket ownership, and the external ECS log group.
Dry-run checks
The full validator creates no-execute CloudFormation change sets for stacks 15 and 16 when their upstream outputs exist, then removes those change sets.
Precise mutation boundary
This stage does not execute a stack update. Creating and deleting a change set still changes CloudFormation metadata, so it is non-deploying rather than strictly read-only.
03

Deploy Platform

Only cloud-mutating app path
14
Build image

Tag with 8-character commit SHA, push SHA and latest, reject images below 10 MB.

15
Deploy ECS

Require VPC outputs, ensure the log group, then update the ECS and internal ALB stack.

15b
Verify runtime

Poll ECS up to ten times and inspect load balancer target health.

16
Deploy ingress

Run only when verify-ecs emits READY=true. Manual dispatch cannot bypass this gate.

17
Report

Always print final stack states, endpoints, and the public health-check result.

Current readiness semantics
The verifier emits READY when ECS reports one running task or the ALB target reports healthy. API Gateway remains blocked when the script exits with READY=false.
90

Builders: Build Images

Independent artifact pipeline

Triggers

Runs when runtime specifications, Dockerfiles, iOS build inputs, ECR templates, or code-bundle files change. It also supports manual dispatch and runs Mondays at 02:00 UTC.

Four parallel products

Android grader image, agent runtime image, iOS pantry package, and versioned OpenAnvil source bundle.

Android and agent
Linux Buildx publishes pinned and latest tags to ECR, then reports the resolved image digest.
iOS
A GitHub Mac runner creates the bare React Native template and pantry archives. S3 manifest upload is intended to trigger the Mac builder Lambda and Tart image build.
Code bundle
The workflow creates openanvil.zip, uploads a current key plus dated history, and retains a GitHub artifact for 14 days.
Current weakness
Some iOS and bucket-upload branches warn or skip instead of failing. Treat the builder workflow as partially fail-closed until those paths become strict.
05

Deployment is a three-stage safety ladder

Static errors, live account problems, and cloud mutations fail in different ways. The workflows keep those risks separate.

Deployment confidence ladder

Each stage proves a stronger claim. Cloud mutation begins only after static and live-account checks pass.

WorkingPartialTarget
01
Static proof

lint, contracts, tests, builds

Repository coherent
02
Live readiness

outputs, ownership, dry runs

Account ready
03
Cloud mutation

image, ECS, verify, ingress

Runtime healthy
01

Validate repository

Parse YAML, lint CloudFormation and shell, run contracts and tests, build the app, and validate Docker inputs. No AWS mutation.

02

Cloud predeploy

Read live stack state, require real upstream outputs, detect ownership collisions, and create no-execute change sets.

03

Deploy platform

Build and push an immutable app image, deploy ECS, verify the task and ALB target, then expose it through API Gateway.

One mutation path
deploy-platform.yml is the only workflow that mutates the app hosting path. Shared scripts hold reusable logic, while the workflow owns ordering and gates.
Automatic failure propagation
If workflow 01 fails, workflow 02 is skipped. If workflow 02 fails, workflow 03 is skipped. Within workflow 03, each job depends on the previous proof.
Manual dispatch boundary
Manual dispatch can start predeploy or deploy, but it cannot bypass the semantic READY gate between ECS verification and API Gateway deployment.
06

The AWS account is private by default

OpenAnvil does not assume public subnets, an internet gateway, or an internet-facing load balancer.

Private services
ECS tasks, EC2 workers, Mac hosts, ECR traffic, S3 access, and the internal ALB live in private networking.
Service endpoints
VPC endpoints provide access to ECR, S3, SSM, and related AWS services without adding a NAT gateway to the core design.
Public ingress
API Gateway exposes only the intended HTTP boundary. VPC Link carries traffic to the internal ALB.
Secrets
API keys live in Secrets Manager or named environment variables. Configuration references key names rather than embedding values.
07

Current deployment boundary

The infrastructure contract is clearer than the complete runtime path. These states should remain visible in the docs.

Working
The private network model, runs bucket, event bus, queues, control Lambda, API Lambda, app container build, and workflow separation exist in code.
Partial
The ECS and API Gateway path has active deployment fixes. Cloud worker launch exists but still needs complete lifecycle validation with production artifacts.
Target
Android and iOS grader fleets, end-to-end submit routing, complete cleanup, and verified app ingestion remain the target production path.