build 4821 · retried ×2 · exit 0 legacy soap target billing-v1 wrapped → POST /v1/billing.quote p95 wrap latency 84 ms nightly cron csv-drop → GET /v1/inventory.snapshot flake budget spent 3.1% of 12% container build web-api:2f9c11 cached, 41 s saved

wrapper runtime · v1.9

Wrap it. Watch it. Retry it until green.

from a script nobody owns

ctw run billing-v1 --wrap soap attempt log
›ctw wrap billing-v1
1exec  ./legacy/quote.sh --xml     14.2s  exit 7
stderr  socket hangup after 12s
retry   backoff 4s  jitter 0.3  budget 5
2exec  ./legacy/quote.sh --xml     11.8s  exit 7
retry   backoff 9s  jitter 0.3  budget 4
3exec  ./legacy/quote.sh --xml      9.6s  exit 0
schema  inferred 14 fields, 2 pinned by contract
✓serve  POST /v1/billing.quote   openapi 3.1
wrapped in 41.9s · 3 attempts · contract billing-v1@2
Real attempt log shape: every retry keeps its exit code, duration, and captured stderr.

to a typed http endpoint

ctw is a wrapper runtime for the parts of your stack that were never designed to be called. Point it at a shell script, a Makefile target, a container build, or a service that only speaks SOAP. It runs the thing, retries it with declared backoff, keeps every attempt on the record, and publishes the result as a typed HTTP endpoint your services can actually depend on.

how the wrap is declared

Twelve lines of yaml, then it is an endpoint

One file per target. Declare the command, the retry policy, and the contract you promise callers. ctw handles execution, backoff, attempt provenance, schema drift detection, and the OpenAPI document it hands to your clients.

Runs the same on a laptop, in your existing CI job, or as a long-lived service in a private environment.

ctw.yaml config
1target: billing-v1
2exec: ./legacy/quote.sh --xml
3retry:
4  budget: 5
5  backoff: exponential
6  on: [exit != 0, stderr ~ "hangup"]
7serve:
8  route: POST /v1/billing.quote
9  contract: billing-v1@2
10  auth: oidc
11observe:
12  emit: otlp
Committed next to the code it wraps. Reviewed like code.
  1. 01

    Trigger

    Push, schedule, webhook, or an HTTP call from another service.

    ci · cron · http
  2. 02

    Execute

    The wrapped command runs in an isolated step with captured streams.

    shell · docker · make
  3. 03

    Retry

    Failure classes you declared get backoff and a fresh attempt. Everything else fails loudly.

    budget 5 · jitter 0.3
  4. 04

    Serve

    The successful result becomes a versioned endpoint with an OpenAPI document.

    openapi 3.1 · oidc

the part that pays for itself

Zero-touch retries

Flaky targets stop being an on-call problem. ctw retries inside the declared budget, records why each attempt failed, and only pages you when the failure is new.

We deleted 430 lines of retry bash and a Jenkins plugin nobody understood. The YAML is now the runbook.
platform lead, logistics saas 430 lines removed
Retry policy reference
ctw ledger --last 24h failure ledger
target          attempts  recovered  paged
billing-v1           412        38      0
inventory-csv         31         9      0
web-api build        188         4      0
pdf-render            97        12      1
flake budget 12% · spent 3.1% · window 24h
Attempt provenance is queryable. Flake budgets are a number, not a feeling.

integrations · runs inside the ci you already have

  • GitHub Actions
  • GitLab CI
  • Buildkite
  • Jenkins
  • CircleCI
  • Argo Workflows
  • Docker
  • Kubernetes
  • Terraform
  • OpenTelemetry

ctw is a single binary. It does not want to be your scheduler.

[email protected] generated
"post": {
  "operationId": "billingQuote",
  "x-ctw-attempts-max": 5,
  "x-ctw-source": "legacy/quote.sh",
  "responses": { "200": {…}, "504": {…} }
}
Generated from the wrap, versioned with it.
01

Every wrap ships a contract

Schemas are inferred on the first green attempt, then pinned. Drift is a build failure, not a 3am incident.

Contract model
ctw usage --month usage
build executions      8,412 / 25,000
wrapped api calls   1.24M / 5.00M
private envs              2 / 3
overage                   none
The same three numbers you are billed on.
02

Metered where it matters

Build executions, wrapped calls, and private environments are counted separately, so a chatty endpoint does not price like a build farm.

How metering works

pricing

Pick your execution budget

Metered on build executions, wrapped API calls, and private deployment environments. No seat tax. The binary is free forever on a laptop.

Start free Talk to an engineer

Solo

$0 forever

The binary, local wraps, and one hosted endpoint.

Included
500 build executions / mo
Included
25k wrapped API calls / mo
Included
1 shared environment
  • Retry policies
  • OpenAPI output
  • Community support
Install ctw

Team

most wrapped

$140 per month, then $0.004 / execution

For a build farm you inherited and a handful of wrapped legacy targets.

Included
25k build executions / mo
Included
5M wrapped API calls / mo
Included
3 private environments
  • Attempt ledger + OTLP export
  • Contract pinning and drift gates
  • SSO, audit log
  • Business-hours support
Start 14-day trial

Private cloud

from $1,900 per month, committed volume

Your VPC, your egress rules, your compliance auditor.

Included
Unmetered build executions
Included
Volume-priced wrapped calls
Included
Unlimited private environments
  • Self-hosted control plane
  • Air-gapped install
  • Named engineer, 1h severity-1
Request pricing

Executions are counted on completion, not per retry. Retries inside your declared budget are free.