Repository
StackShip is a pnpm workspace orchestrated with Turborepo. Applications live in
apps/; shared libraries belong in packages/.
Each production surface has its own Worker and Wrangler configuration. Custom domains are explicit in source control.
Definition of done
A product change is done only when:
- The implementation is type-safe and passes its local checks.
- Relevant tests or protocol probes pass.
- User-facing behavior and operational changes are documented in Nimbus.
- New configuration is represented in
.env.exampleor deployment docs. - No privileged credential is committed.
- Production health is checked after deployment.
Documentation workflow
Write documentation alongside implementation. Use
apps/docs/src/content/docs/ for pages and
apps/docs/src/content/partials/ for shared sections. Run:
pnpm --filter @stackship/docs checkNimbus publishes clean Markdown alternates and agent indexes. Treat broken internal links or invalid frontmatter as build failures.
Local release browser gate
The deterministic browser gate starts the dashboard, API, and MCP server on
0.0.0.0:3000, 0.0.0.0:3001, and 0.0.0.0:3002. OAuth endpoints use the
loopback issuer http://localhost:3001, and the real OpenTofu callback probe
captures http://localhost:10010/login. The listeners remain reachable from
containers and browser automation while Better Auth retains a valid loopback
HTTP issuer.
Run the full browser suite or its accessibility subset:
pnpm opentofu:install-release --destination "$PWD/.stackship/opentofu"
export STACKSHIP_OPENTOFU_BINARY="$PWD/.stackship/opentofu/1.12.5/tofu"
export STACKSHIP_OPENTOFU_VERSION=1.12.5
pnpm test:e2e
pnpm test:a11yThe installer streams the pinned archive to disk, verifies the release and
binary SHA-256 checksums, and then verifies tofu version -json. The native
cloud tests fail closed unless both environment variables select that exact
absolute binary and supported version. CI and the protected production
deployment run the same installer before the browser gate and export those
values through the job environment. The login compatibility probe sends its
confirmation only after the real CLI emits the interactive value prompt; this
prevents a busy shared runner from racing or losing pre-buffered input while
retaining the real OAuth PKCE exchange.
Release runs do not reuse processes already listening on those ports. This
prevents an arbitrary stale service from satisfying readiness and supplying
browser evidence. A developer deliberately debugging against services they
already started may opt in with
STACKSHIP_E2E_REUSE_SERVERS=1; evidence from that mode is not a release gate.
Both commands run in CI and are repeated before the protected production
deployment.
For interactive cross-service testing, pnpm dev:e2e first prepares the same
loopback-only database and then starts all six production services. The docs,
orchestrator, and credential broker listen on 0.0.0.0:3003,
0.0.0.0:3004, and 0.0.0.0:3005. Run
node scripts/verify-local-listeners.mjs while the harness is active to prove
that every fixed port is reachable through the shared interface. Wrangler
devtools remain loopback-only on distinct 9231, 9232, 9234, and 9235
ports so the four Workers can run concurrently without exposing inspector
access.
CI also starts PostgreSQL 17.10 and runs the execution-commit, apply-recovery,
run-launch concurrency, and GitHub installation-lifecycle repositories against
that real engine. The execution gate proves relation-scoped locks across
nullable joins by racing two policy commits and two apply commits, then
accepting only their exact replays and publishing one terminal result. The
run-launch gate proves that simultaneous same-workspace and cross-workspace
creates serialize on the versioned production control row, admit exactly one
run at a capacity of one, and return the documented workspace or organization
capacity error to the other caller. The recovery gate covers
PostgreSQL-qualified row locks, an initial prepare and exact replay,
database-clock lease issuance, concurrent expired takeover with one owner, and
the old-owner commit fence. The test runner fails closed unless it receives a
PostgreSQL URL for the exact loopback
stackship_test database; non-loopback hosts and other database names are
rejected before any schema setup. The GitHub portion proves callback and
lifecycle audit failures roll back installation, repository, state-token, and
delivery-deduplication changes, including cross-tenant provider-ID conflicts.
The encrypted-object package keeps its 100 MB streaming and overflow probes serial within one Vitest worker. Those probes retain the production byte boundary and bounded-read-ahead assertions; they receive a 120-second per-test ceiling so shared CI runners cannot turn CPU contention into a false failure. Do not shrink the fixtures or enable file-level parallelism to make the gate faster, because doing so would stop testing the launch-size streaming path.
Global setup migrates only the exact loopback database stackship_test. If
PostgreSQL is absent, it starts the disposable stackship-local-postgres
Docker container on 127.0.0.1:5432; the script refuses non-loopback hosts and
other database names. It resets only the fixed local E2E identity’s sessions,
OAuth grants, and consents, plus the dedicated database’s Better Auth signing
rows before the API starts. Better Auth recreates those local-only keys under
the fixed test secret, so a prior debug server cannot leave undecryptable JWKS
material behind. Immediately before each synthetic sign-in or OAuth
authorization, the fixture also clears Better Auth rate-limit counters through
the same explicit marker and exact loopback-database guard. That reset cannot
target a remote database; production and ordinary local authentication retain
the distributed PostgreSQL limits. Chromium’s exact warning that
Cross-Origin-Opener-Policy is ignored on the intentionally insecure
http://0.0.0.0 test origin is excluded from the navigation error collector;
the production HTTPS header remains mandatory, and every other console or page
error still fails the test. The suite covers sign-up and sign-in, organization,
project and workspace creation, variables, state, OpenTofu token disclosure,
policy and run inventory, real OAuth discovery and PKCE exchange, the inclusive
port-10010 callback, MCP audience separation, authenticated tool discovery,
an organization-bound MCP status call, missing-token rejection, and serious or
critical axe violations. It also follows every authenticated control-plane
navigation item, requires an explicit inventory or empty state, and fails on
browser console or page errors. These credentials and database defaults are
local test fixtures and must never be used for a deployed environment.
The browser gate also starts the real credential-broker Worker and its local
Durable Object. Its native-cloud publication/read case issues a workspace token
through the dashboard, observes OpenTofu fetch the dashboard’s real
/.well-known/terraform.json document, follows its cross-origin tfe.v2
service to the real Wrangler /api/v2 surface, publishes envelope-encrypted
state through R2 and the broker, reads outputs and state back through OpenTofu,
and verifies the same immutable version through the authenticated v1 API and
dashboard. That case is publication/read evidence, not migration evidence. It
uses the workspace cloud_name, including the case where the display name
contains spaces, and covers OpenTofu lineage values that are canonical hex but
not RFC UUID variants.
Tests that issue a workspace token use a credential-safe Playwright fixture. That fixture disables screenshots, traces, and video for the complete test before any plaintext is disclosed. It installs the exact issuance-response wait before each token-creation action, captures only the service-account and token IDs before the test proceeds, and revokes every captured token through the authenticated dashboard API during teardown. Teardown still runs after an assertion failure, attempts every unique revocation, and fails the browser gate if any token cannot be captured or revoked. Browser artifacts must never be re-enabled for these tests because a Playwright trace can retain the one-time response body even after the dashboard clears its visible disclosure.
A separate native-cloud case performs two local applies before adding the
cloud block and accepting OpenTofu’s migration prompt. It proves exact output
and resource preservation. It also records OpenTofu 1.12.5’s empty-destination
metadata behavior: the client replaces the source lineage and serial with a
new lineage at serial 1 before upload, and StackShip returns and exposes the
same client-supplied metadata through state pull, the authenticated v1 API,
and the dashboard. The direct TFE route suite separately proves that StackShip
preserves caller-supplied lineage, serial, and streamed raw state. These tests
do not claim that OpenTofu 1.12.5 preserves source lineage or serial during an
empty-cloud initialization.
A third native-cloud case models an external cloud export/import with separate
source and clean destination directories. It creates a serial-greater-than-one
source with a non-empty built-in resource, stores the copied snapshot and cloud
CLI configuration at mode 0600, runs tofu init -input=false, and executes
tofu state push source-state.json without a CLI force flag. OpenTofu 1.12.5
produces the same empty-destination rebase: a new lineage at serial 1. The
case proves exact non-empty resource/output preservation and agreement between
state pull and the authenticated control-plane record. Its token deliberately
lacks state:recover, and a streaming loopback probe directly observes
data.attributes.force as false on the state-create request. A regression to
force: true would also be rejected before upload reservation.
Deterministic lifecycle fixture
apps/web/e2e/full-lifecycle.spec.ts provides repeatable browser evidence for
the run-review lifecycle. It creates three local scenarios: a soft mandatory
policy finding that a permitted user overrides before exact-plan approval and
state publication, a policy-passing run that the user rejects, and a hard
mandatory policy finding that exposes no override or approval controls. The
browser always uses the production override, approval, and rejection API
contracts. State publication revalidates the production approval gate and
commits through ExecutionCommitRepository. The fixture publication carries
the exact managed-run principal across the attempt sandbox, state lock, writer
reservation, immutable state version, and published upload record, so the
production chain resolver and commit fence are exercised without a provider.
The existing run reservation must still belong to that exact run before the
fixture transitions it to the attempt-bound apply principal.
The fixture setup and final publication control are package CLI commands, not
Worker routes. They require the exact stackship_test database on a loopback
host, verify the fixed local E2E user owns the target workspace, and identify
their records as stackship-local-e2e-lifecycle-fixture. They cannot be
invoked through a production HTTP surface. Run this focused gate with:
pnpm --filter @stackship/web exec playwright test e2e/full-lifecycle.spec.tsThis fixture proves dashboard transitions and control-plane invariants only. It deliberately does not invoke GitHub, Daytona, Cloudflare Workflows, or R2 and is not evidence that those external integrations work in production. Release evidence for those boundaries must come from their separate real service canaries.