Skip to content

Add a use-case

New coverage in SREForge is never an engine change. It is a new use-case, stack, or scenario. This guide is the recipe for the most common case: importing a real app and authoring an incident-profile scenario on it.

A use-case is a tree under use-cases/; the harness never names it in engine-level code.

  • Directoryuse-cases/
    • Directoryyour-app/
      • Directorystacks/
        • Directorysome-stack/
          • Directorycompose/ the deployable substrate + observability overlay
          • Directoryobservability/ prometheus / alertmanager / rules
          • Directoryload/ the k6 load script
          • Directoryscripts/ lifecycle helpers
          • Taskfile.yml the per-stack lifecycle (up · arm · run · verify · down)
      • Directoryscenarios/
        • Directoryyour-scenario/
          • scenario.toml machine-readable manifest
          • trigger.md the neutral page the agent receives
          • Directoryenvironment/ compose + CI/CD hooks + observability overlay
          • Directoryinject/ the organic-regression injector + confirm-fire
          • Directoryverify/ the Problem / Oracle code (incident profile)
          • Directorysolution/ reference fix (held out)
          • Directoryrecords/ committed pruned run records
  1. Pick a low-recognizability real app. Run the 3-axis intake gate on a throwaway clone:

    Terminal window
    pnpm detell # score the candidate for "is this a rig?" tells
    pnpm guard # scan for harness-leak + BUG#/FIXME/XXX/HACK markers

    In v1, rig-confidence is gated; recognizability and memorization are report-only — but memorization is the decisive signal. Prefer apps that score low on all three. (Avoid the canonical observability demos — they’re maximally memorised and used by other benchmarks.)

  2. Import the app into the local forge, keeping its real git history (git clone --mirror + push, or Gitea’s API migration). Each use-case provisions its own maintainer identity at import — login = the upstream owner handle, name/email = the repo’s real last author — so the branch / PR / merge an agent sees look like that app’s maintainer, not a harness account.

  3. Stand up a stack. Add stacks/<stack>/ with the deployable compose, an observability overlay (Prometheus + Alertmanager + alert rules, Grafana), a k6 load script, and a Taskfile.yml exposing the lifecycle phases (doctor, up, arm, run, verify, down, …). The neutral dispatcher discovers it automatically.

  4. Author an organic regression. Edit a fault into the app’s existing code on a real hot path (e.g. weaken a timeout or disable an existing cache on an external-API call). Use real tooling — real migrations, real revert artifacts, deploy receipts — so the deployment’s history looks genuine. Never a bolt-on module.

  5. Define the scenario. Fill in scenario.toml (id, profile, expected alert, determinism knobs, oracle weights), trigger.md (the neutral page), the inject/ injector + confirm-fire gate, the verify/ oracle, and a held-out solution/. See the Scenario format reference.

  6. Run it through the loop. With zero new top-level wiring:

    Terminal window
    pnpm forge fresh your-app
    pnpm forge incident your-app

The command surface is use-case-neutral: pnpm forge <verb> <use-case> resolves <use-case>[:<stack>] to that stack’s Taskfile.yml. Adding a second use-case is pnpm forge <verb> your-app with no changes to package.json or the engine. The use-case-specific values (alert names, service names, the repo) live in the stack scripts and the scenario manifest — never in the engine.