softwerkBook a factory walkthroughSign in

every control, with its switch position

Every guardrail by name, with the switch position.

Every control between an agent's keystroke and your main branch: what runs on every build today, what a switch changes and which way it is set on production, and where the code lives.

The publication screen

every build

Every word the fleet publishes outside your account passes through a local Presidio sidecar first: issue titles, run reports, failure comments, pull request bodies. A detection, a timeout or a malformed answer withholds the text and publishes a value-free reference to the mission instead. The screen is not behind a switch. The sidecar runs inside the cluster with the spaCy model in its image, and the fleet logs entity types and counts, never values. NetworkPolicy enforcement is on for the production cluster since 2026-09-14, so the sidecar's empty egress list is a real deny-all outbound; the one limit left, that the web and worker policies allow 443 to any address, is in the non-claims below.

Separate-model review

every build

The reviewing roles (verifier, compliance, merger) are marked independent in the roster and run on claude-sonnet-4-6; the building roles run on claude-opus-4-8. A role never reviews its own work. The work is reviewed by a separate model, not a separate vendor. Both are Anthropic models: claude-sonnet-4-6 reviews what claude-opus-4-8 wrote. The fleet certificate does not record which model reviewed.

Human gates

switchFACTORY_GATES_ENFORCE1

Three gates, declared once in .softwerk/factory.yaml and pinned to code by test. Plan: after architect, before any code, a person approves the plan, on every mission. Question: any role may stop and ask, and the run pauses until answered. Merge: merger stops with the pull request open, the decision is recorded, and since merger holds no merge rights a person merges the pull request.

Supervision is Linear-native. A state change on the issue, a reaction on the gate's own comment, or a threaded reply is a gate decision, and a decision through POST /api/v1/mission-gates/<id> works the same way. Each role posts its activity on the issue with a link to the run and the report. An undecided plan gate expires after 24 hours and releases the repository.

The switch is 1 on production since 2026-09-14 on all three tiers: web and worker through the overlay, the agent Deployments through cdk/config/environments.ts. The runner stops before any commit, pull request or hand-off at the plan and question gates, and with the pull request open at the merge gate; the worker writes a gate row and pauses the run; a decision resumes it. Refusing the merge ends the run and leaves the pull request open and unmerged. Decisions are audited (mission_gate.decided with kind, decision, source and resume role; mission_gate.question_read; mission_gate.expired_by_sweeper) and the stored question is sealed under the tenant's key.

Nothing merges or deploys unattended

every build

The role chain ends at merger. Merger holds no merge rights. Deployer and observer exist in the roster, are never triggered by the chain, and are refused as resume targets. Production itself is released by a person dispatching a workflow with an explicit image tag; nothing deploys on a push or a tag.

The certificate scan

every build

After a mission completes, a sweeper selects it, reads the pull request's head tree from GitHub under your own installation, runs the HIPAA, SOC 2 and HITRUST control sets over the whole tree and mints one certificate per tree: the per-framework results, a fail-closed verdict, disclosed warnings and an evidence report of finding counts. A tree already certified is reused rather than re-minted.

The certificate is a record. Minting is not enforcement: it happens after the pull request is open and, with the gates on, after the merge gate has been approved, so the certificate is the record of what was approved rather than an input to the approval. No switch turns a failed fleet verdict into a refused pull request today, and a person merges. Whether the team waits for the certificate before merging is the team's own rule.

The inherited generation path

four switches, all 0

Four more enforce switches sit in the production overlay beside the human gates, and a fleet mission never passes any of them. They are read on the generation and deploy path the factory inherited from the app builder: the worker's generation consumer, its pipeline consumer and the project deploy route. No fleet module imports them, and the fleet certificate module says so in its own words: minting is not enforcement.

Verification gate (VERIFICATION_GATE_ENFORCE): off, the gate at the generation ship boundary and on the project deploy route is a no-op; on, a failed certificate refuses the ship or deploy.

Compliance veto (COMPLIANCE_VETO_ENFORCE): off, the compliance verify on a generated build is disclosure-only; on, a failed verify withholds the generated build.

Reviewer enforce (REVIEWER_ENFORCE): off, the reviewer of a generated build is advisory and never blocks; on, a block verdict, or an independence that cannot be proven, fails the generation, and a revise verdict still ships.

Write screen (PHI_GUARD_ENFORCE): off, every file write and tool result of a generated build is scanned observe-only and detections are evented; on, a write carrying a high-precision identifier (SSN, MRN, card number, email, phone) is blocked. Names and dates are never blocked, because the detector is too noisy on source code to gate on them. Fleet code is written inside the agent pod, where only the publication screen runs, so nothing screens the executor's file writes inside a mission.

All four are 0 on production, and none of them changes what a mission does, on or off.

Credential and pod isolation

every build

The fleet holds no tenant secret at rest; per task it receives exactly one credential, sealed and single-use (see the broker). The model subprocess runs as a second uid with an environment allowlist and cannot read the runner's environment; the executor fails closed without a uid split. Instance metadata is unreachable from pods (hop limit 1). The fleet's IAM role holds its lease table, its role queues and send-only on the progress queue. GitHub tokens are per-task installation tokens scoped to one repository.

Tenant isolation

every build

Every query runs through a tenant-scoped client, and an exhaustive model registry test fails when a schema model is unclassified. Postgres row-level security is enabled on the factory tables as defense in depth (enabled, not forced, so it binds non-owner roles). Sensitive strings, including Linear tokens and gate questions, are envelope-encrypted at rest.

The switch table.

On a fleet mission every review and gate runs and is recorded, and on a completed mission every scan runs and is recorded. The certificate is minted after the mission completes and refuses nothing: no switch in the tree turns a failed fleet verdict into a refused pull request today, and a person merges.

One switch changes what a mission does: FACTORY_GATES_ENFORCE, the three human gates, set to 1 on production since 2026-09-14 in two deploys, the overlay first for web and worker, then the agent Deployments. Four more switches in the same overlay govern the inherited generation and deploy path, which a mission never passes, and are 0; their documented flip order is veto, PHI, reviewer, verification gate last. Every value is a cluster-wide environment variable on the production deployment, which serves every workspace on that cluster; there is no per-workspace setting. Each flip is one deploy.

on a fleet mission: the one switch that changes what a mission does
switchoffonproduction
FACTORY_GATES_ENFORCEweb, worker and agentsthe chain runs without stopping; gate rows, pause and resume exist in the web app and the worker, and no row is openedevery mission stops after architect until a person approves the plan, a role that asks stops until it is answered, and merger stops with the pull request open until a person decides the merge; a person still merges1
inherited generation and deploy path: enforced on no mission path, never passed by a mission
switchoffonproduction
COMPLIANCE_VETO_ENFORCEweb and workerthe compliance verify on a generated build is disclosure-only: the result is recorded and nothing is withhelda failed verify withholds the generated build0
PHI_GUARD_ENFORCEweb and workerevery file write and tool result of a generated build is scanned, observe-only: detections are evented and nothing is blockeda write carrying a high-precision identifier (SSN, MRN, card number, email, phone) is blocked0
REVIEWER_ENFORCEweb and workerthe reviewer of a generated build is advisory: the verdict is recorded and never blocksa block verdict, or independence that cannot be proven, fails the generation; revise still ships0
VERIFICATION_GATE_ENFORCEweb and workerthe verification gate at the generation ship boundary and on the project deploy route is a no-opa failed certificate refuses the ship or deploy0

scroll sideways for the production column

  • k8s/overlays/softwerk-prod/kustomization.yaml lines 159 to 187 and 291 to 319
  • cdk/config/environments.ts factoryGatesEnforce; cdk/lib/agent-fleet.ts line 457, pinned in cdk/test/stacks.test.ts
  • apps/agent/src/config.ts gatesEnforce; apps/agent/src/gates.ts FactoryGateCheck; apps/worker/src/mission-gate-open.ts
  • apps/worker/src/fleet-certificate.ts (minting is not enforcement; no fleet module reads the four inherited switches)
  • apps/worker/src/consumer.ts and apps/worker/src/pipeline-consumer.ts (where the four inherited switches are read)
  • packages/compliance/src/verification/gate.ts isVerificationGateEnforceEnabled
  • apps/worker/src/compliance-ship-verify.ts
  • apps/worker/src/reviewer-enforce.ts
  • apps/worker/src/phi-guard-policy.ts

Ask for the switch state in writing before you rely on a stop or a refusal.

What Softwerk does not claim.

One paragraph per absent attestation or unenforced control, each with the file that proves the absence.

No vendor-independent reviewer

The reviewing roles run on a different model from the builder, and both models are Anthropic's. The fleet certificate records the verdict, not the reviewer.

apps/agent/src/executor.ts BUILDER_MODEL, REVIEWER_MODEL; apps/worker/src/fleet-certificate.ts

No refusal of a fleet pull request

On a fleet mission a failed verdict lands on the certificate and the run page, the pull request is already open, and a person merges. The four enforce switches in the overlay govern the inherited generation and deploy path, not a mission, and are 0 on production. The human gates (FACTORY_GATES_ENFORCE) are 1 since 2026-09-14; they stop a mission for a decision and refuse nothing on a verdict. The switches are cluster-wide environment variables, not a per-workspace setting.

apps/worker/src/fleet-certificate.ts (minting is not enforcement); k8s/overlays/softwerk-prod/kustomization.yaml lines 159 to 187 and 291 to 319; cdk/config/environments.ts factoryGatesEnforce

No screen on the executor's file writes

The worker's write screen scans every file write and tool result of a generated build on the inherited generation path. Fleet code is written inside the agent pod, where only the publication screen runs, and a fleet certificate carries no PHI-guard result.

apps/worker/src/phi-guard-screening.ts (imported by apps/worker/src/consumer.ts alone); apps/agent/src/phi.ts; apps/worker/src/fleet-certificate.ts mint input

No unattended deploy

Deployer is in the roster and is never triggered by the chain. Production is released by a person dispatching a workflow with an explicit image tag.

apps/agent/src/roles.ts ROLE_CHAIN; .github/workflows/cd-softwerk-prod.yml

No attestation report

The tree holds scanners for the SOC 2, HITRUST, HIPAA and ISO 27001 control sets and no audit letter for Softwerk itself. A scan result on your certificate is evidence about your build, not a certification of Softwerk.

packages/compliance/src (scanners only; no report document anywhere in the tree)

No BAA

The factory is not a business-associate context and handles no PHI by design. The publication screen exists for the case where an issue, a report or a pull request body carries identifiers anyway.

SOFTWERK.md, Two compliance surfaces

No hostname allowlist on egress

NetworkPolicy enforcement is on for the production cluster since 2026-09-14: enforceNetworkPolicy is true for softwerk-prod, and the Presidio sidecar's empty egress list became a real deny-all outbound at that flip. The limit that remains: the web and worker policies allow 443 to any address, because a NetworkPolicy selects by IP block and label and cannot express a hostname, so there is no network-layer allowlist of api.anthropic.com or github.com under the application's own checks until an egress proxy holds one.

cdk/config/environments.ts enforceNetworkPolicy; plans/softwerk/b10-operator-steps.md phase 7; docs/runbooks/network-policies.md (443 is open to 0.0.0.0/0 on purpose); k8s/base/phi-guard-networkpolicy.yaml

No ISO 27001, GxP, Part 11 or PCI-DSS result on a fleet certificate

Each is a registered control set with its own scanner. The fleet passes no profile, so only the HIPAA, SOC 2 and HITRUST results land on a certificate today.

apps/worker/src/fleet-certificate.ts runComplianceVerify(files, {}); packages/compliance/src/verify.ts

No spend cap

A mission's model cost is written per role turn and shown on the run page as Model cost. Nothing stops a mission at a ceiling: the build budget guard was removed and nothing replaced it. Your Anthropic console is the cost control.

apps/worker/src/mission-cost.ts (a record, not a charge); apps/web/src/components/factory/run-detail.tsx

No customer-account deployment

The whole stack runs in Softwerk's AWS account. Deployment into your account through the same infrastructure code is planned and not live.

cdk/ is the whole stack

No GitHub or Linear connection on production today

The GitHub App and the Linear application are configured once per deployment by Softwerk, not per workspace; no tenant setting enables either, and the app offers a connect step only when the deployment's variables are set. On production the Linear values are empty placeholders, so the Linear connect step is not offered, and the GitHub App private key is a placeholder, so no mission can clone a repository or open a pull request.

apps/web/src/lib/github-app-install.ts isGitHubAppConfigured; apps/web/src/lib/linear/config.ts isLinearConfigured; docs/runbooks/linear-agent.md step 2; docs/runbooks/fleet-credentials.md

No signed bundle on production today

Evidence is signed with ed25519 only when the deployment holds EVIDENCE_SIGNING_PRIVATE_KEY. Production holds none: the property is in neither the production overlay, the CDK stacks nor the deploy workflows, so a production export is unsigned with the reason not_configured written in the bundle, and the offline verifier fails its signature check on it and says why. Every certificate's content address still checks.

apps/web/src/lib/evidence/sign-bundle.ts not_configured; k8s/overlays/softwerk-prod/external-secret.yaml (no EVIDENCE_SIGNING_PRIVATE_KEY property); scripts/verify-evidence-bundle.mjs

Connect a repository, a Linear team and an API key. Keep everything else.

Softwerk is not self-serve: sign-in is Google SSO on an allowlisted workspace domain, and a workspace is set up by Softwerk on request. The GitHub App and the Linear application are configured once for the whole deployment by Softwerk, not per workspace, and the app offers each connect step only when that deployment-level configuration is in place. On production today the Linear application is not yet seeded, so its connect step is not offered, and the GitHub App private key is a placeholder, so no mission can clone a repository or open a pull request yet. Once both are seeded, you connect your Anthropic key, your GitHub App installation and your Linear team, and the first mission ends in a pull request with its certificate beside it.

Book a factory walkthrough