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.
Where things live
Section titled “Where things live”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
- …
The recipe
Section titled “The recipe”-
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?" tellspnpm guard # scan for harness-leak + BUG#/FIXME/XXX/HACK markersIn 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.)
-
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. -
Stand up a stack. Add
stacks/<stack>/with the deployable compose, an observability overlay (Prometheus + Alertmanager + alert rules, Grafana), a k6 load script, and aTaskfile.ymlexposing the lifecycle phases (doctor,up,arm,run,verify,down, …). The neutral dispatcher discovers it automatically. -
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.
-
Define the scenario. Fill in
scenario.toml(id, profile, expected alert, determinism knobs, oracle weights),trigger.md(the neutral page), theinject/injector + confirm-fire gate, theverify/oracle, and a held-outsolution/. See the Scenario format reference. -
Run it through the loop. With zero new top-level wiring:
Terminal window pnpm forge fresh your-apppnpm forge incident your-app
Why no new wiring
Section titled “Why no new wiring”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.
- Scenario format — every field of
scenario.toml. - Contamination control — the invariants this recipe upholds.