Documentation

Ship releases that earned their green check

Everything you need to run your first rehearsal, gate a GitLab pipeline on it, and run FutureFault yourself.

Quickstart

  1. Create an account. You get a private workspace on the Free plan.
  2. Follow onboarding: name the workspace, pick a default policy, and run your first rehearsal of the bundled ledgerly-mr-42 merge request.
  3. Open the rehearsal: the Hypotheses tab shows what was reproduced, Evidence graph traces every conclusion, and Decision explains each policy rule.
  4. Invite your team from Settings → Team and create a CI key in Settings → API keys.

Want to look around first? Explore the public demo as a guest, no account needed.

Core concepts

ConceptWhat it means
RehearsalAn eleven-step run for one change: intake, impact, hypotheses, experiments, evidence, remediation, verification, packaging, staging, validation, governance.
HypothesisA falsifiable failure claim that cites the lines that triggered it, with ordinal severity and likelihood (never a probability).
ScenarioAn approved, sandboxed experiment registered by ID. Hypotheses without an approved scenario are recorded as not tested.
VerificationRe-running the original experiment, new regression tests, the full suite and a security rescan in a fresh copy of the patched tree.
PolicyTwelve deterministic rules in a profile (development or release). Each decision stores the profile’s SHA-256 digest.
Evidence bundleA self-validating JSON export of every record, edge and digest behind a decision.

GitLab CI

Store a workspace API key as a masked CI/CD variable named FUTUREFAULT_API_KEY, then start rehearsals from any job:

rehearse:
  stage: test
  image: curlimages/curl:8.10.1
  rules:
    - if: $CI_MERGE_REQUEST_IID
  script:
    - >
      curl --fail-with-body -sS -X POST "$FUTUREFAULT_URL/api/runs"
      -H "Authorization: Bearer $FUTUREFAULT_API_KEY"
      -H "Content-Type: application/json"
      -d "{\"change_set_id\":\"ledgerly-mr-42\",\"remediation\":\"catalog\",
           \"source\":{\"provider\":\"gitlab\",\"sha\":\"$CI_COMMIT_SHA\",\"number\":$CI_MERGE_REQUEST_IID}}"

With source set and the GitLab integration connected, the rehearsal reports back on its own: a futurefault/release commit status (running, then success or failed) and a comment on the merge request with the decision and a link to the evidence. Use "provider":"github" with a pull request number for GitHub.

To make the pipeline itself the gate, run the CLI in the job. It exits non-zero unless the policy allows promotion, and writes the evidence bundle as an artifact:

rehearse:release:
  image: python:3.12-slim
  script:
    - pip install -e services/api
    - python -m futurefault rehearse --change-set ledgerly-mr-42 --profile release
        --trigger gitlab-ci --ci-status success --bundle-out evidence.json
  artifacts:
    paths: [evidence.json]

GitLab Duo agent flow

The repository ships a five-agent custom flow in .gitlab/duo/flows/futurefault-release-rehearsal.yml: impact analyst → hypothesis generator → experiment coordinator → remediation agent → governance reporter.

  1. In your GitLab project: AI → Flows → New flow, paste the YAML.
  2. Add a Merge request ready trigger on the Triggers page.
  3. Merge .gitlab/duo/agent-config.yml to the default branch.

Agents write hypotheses as validated data, run only the bounded CLI, open remediation merge requests, and post the policy decision verbatim. The remediation MR’s own pipeline re-verifies the fix; an agent’s claim is never used as evidence.

API

The full, searchable API reference has code samples and an in-browser console (raw schema: /api/openapi.json). Authenticate with a session cookie (browser) or Authorization: Bearer ff_… (workspace API key). Common endpoints:

MethodPathPurpose
POST/api/runsStart a rehearsal
GET/api/runs/{id}Run state and steps
POST/api/runs/{id}/rerunRepeat with the same configuration
GET/api/runs/{id}/bundleDownload the evidence bundle
GET/api/overviewWorkspace dashboard data
GET/api/workspace/usagePlan limits and current usage

Self-hosting

FutureFault is one container: API, web app and rehearsal worker.

docker build -f deploy/docker/Dockerfile -t futurefault .
docker run -p 8080:8080 -v futurefault-data:/data futurefault

Render + Supabase is the quickest hosted setup: Render runs the container from render.yaml, Supabase Postgres keeps every record and a private Supabase Storage bucket keeps artifacts, so restarts lose nothing that is finished. Create a Blueprint from the repository and paste three values from Supabase. The step-by-step guide is docs/deploy-render-supabase.md.

Configuration

VariablePurpose
FF_DATA_DIRLocal working files, and the SQLite database when no Postgres URL is set
FF_DATABASE_URLPostgres (for example Supabase) instead of SQLite. Tables live in the private FF_DATABASE_SCHEMA (default futurefault), never public
FF_SUPABASE_URL, FF_SUPABASE_SERVICE_KEYKeep artifacts in a private Supabase Storage bucket, restored and digest-checked on read
FF_PUBLIC_URLBase URL for links in emails and the OAuth callback
FF_COOKIE_SECURESet to 1 behind HTTPS
FF_SECRET_KEY32-byte base64 key that encrypts integration credentials (AES-256-GCM). Required in production
FF_RESEND_API_KEY or FF_SMTP_HOST, FF_SMTP_USER, FF_SMTP_PASSWORD; FF_MAIL_FROMEmail delivery for invites, password resets and run alerts
FF_STRIPE_SECRET_KEY, FF_STRIPE_WEBHOOK_SECRET, FF_STRIPE_PRICE_TEAMSelf-serve upgrades with Stripe Checkout and the customer portal (webhook at /api/billing/webhook)
FF_OIDC_ISSUER, FF_OIDC_CLIENT_ID, FF_OIDC_CLIENT_SECRET, FF_OIDC_NAME, FF_OIDC_ALLOWED_DOMAINSSingle sign-on with any OpenID Connect provider (PKCE, verified emails only)
FF_SENTRY_DSNError reporting to Sentry, without personal data
FF_ALLOW_PRIVATE_INTEGRATIONSLet integrations reach self-managed GitLab or Jira on a private network
FF_GITLAB_OAUTH_CLIENT_ID, FF_GITLAB_OAUTH_CLIENT_SECRETEnable Sign in with GitLab
FF_API_TOKENOperator token for metrics and cross-workspace automation
FF_ALLOW_SIGNUP, FF_ALLOW_GUESTControl self-service sign-up and guest access