Scaffold the GitHub Actions workflow that runs the V1 API tests on every PR. Returns the exact YAML content to write to .github/workflows/keploy.yml + the Bash command to set the KEPLOY_API_KEY secret. The AI walks the playbook with its Write tool + the `gh` CLI.
PRECONDITIONS — CHECK BEFORE CALLING. Calling this tool out of order is a DEVLOOP violation; the doc-stated user-flow ordering is generate → run → mutation-prove (opt-in) → expand (opt-in) → CI (opt-in). Specifically you must have:
1. Generated at least one test via devloop_generate_resource_flow AND watched it pass via "keploy test-gen run --ci".
2. SURFACED the mutation-prove opt-in to the dev verbatim: "Want me to prove the test catches bugs by applying 3 small mutations to your handler and reverting?" — and the dev answered (yes-walked through devloop_mutation_demo, or explicit no/skip/later). Doing the test runs is NOT the same as offering mutation-prove; the offer is a separate dev-facing question.
3. ASKED the dev "want me to wire this into CI?" — explicit yes from the dev.
If ANY of those three are missing, STOP and back up. The mutation-prove gate is what builds the dev's trust before they commit Keploy to CI; skipping it ships shallow tests into a workflow the dev hasn't validated.
What this tool does NOT do (intentionally — the dev keeps custody):
* Mint the CI API key server-side. The dev provisions it themselves in the Keploy dashboard (Step 2 of the returned playbook walks them through it). The AI never sees the kep_* value — it transits dashboard clipboard → terminal stdin → gh CLI's encrypted POST. This is a security property, not a limitation.
* Post structured PR comments from api-server. V1 relies on GitHub Actions' native status-check rendering; the structured comment renderer is a V1.5 lift.
The emitted workflow runs on pull_request (default base branch) and reads app_id / test-dir / context-dir from keploy/api-tests/keploy-test-gen.yaml — the dev never has to thread flags through the workflow.
TIME-FREEZING — DEFAULT ON, ALMOST ALWAYS NEEDED FOR BACKEND APPS.
Almost every backend app has authentication (login → JWT/session/OAuth). The dev's recorded tests carry those tokens in headers. Between record time and the first PR's CI run, the tokens' exp claims pass real wall-clock — CI then 401s on every authenticated step, and the dev blames Keploy. Keploy's time-freezing rewinds the app's clock to the record moment so the recorded tokens validate.
Default policy: time_freezing=true. The AI MUST inspect the dev's test suites BEFORE calling this tool:
- <app_dir>/keploy/api-tests/<resource>/test.yaml (V1 sources)
- <app_dir>/keploy/<SuiteName>/tests/*.yaml (captured sandbox tests)
Look for: Authorization Bearer headers; steps hitting /login /auth /signin /token /oauth; response bodies containing jwt / token / access_token / refresh_token / expires_in / iat / exp. If any of those signals appear (or you're unsure), keep time_freezing=true. Only pass time_freezing=false when you've audited every suite and confirmed zero time-sensitive tokens (rare for a real backend).
When time_freezing=true, this tool also requires app_language (go / node / python / java / ruby / other) and app_service (docker-compose service name). Output then includes:
- Modified workflow YAML (pre-populates keploy-sockets-vol; uses -f docker-compose.yml -f docker-compose.keploy.yml; passes --freezeTime)
- docker-compose.keploy.yml override (volume mount + LD_PRELOAD for non-Go, or Dockerfile.keploy build for Go)
- Dockerfile.keploy (Go ONLY — vDSO bypasses LD_PRELOAD, requires -tags=faketime rebuild)
The dev's plain "docker compose up" is unaffected. Time-freezing only activates when CI (or the dev locally) explicitly passes both compose files.
TIME-FREEZING IS REPLAY-ONLY — STRICT INVARIANT.
The Dockerfile.keploy / docker-compose.keploy.yml / --freezeTime flag this tool emits exist purely to make recorded JWTs validate at REPLAY time. They MUST NEVER apply when recording. Concretely:
- Record uses the dev's PROD Dockerfile + plain "docker compose up" (no override file).
- Replay uses Dockerfile.keploy + "docker compose -f docker-compose.yml -f docker-compose.keploy.yml up" + the --freezeTime flag on the CLI.
If a recording is captured against a faketime-built binary, every timestamp in the captured mocks is wrong and the whole capture is corrupt — there is no recovery short of re-recording from scratch with the prod binary. The CI YAML this tool emits in ci_mode=sandbox-replay is a REPLAY workflow; it boots via the compose override on purpose. The dev's separate record flow (devloop_record_sandbox) must NOT touch the override.
TIME-FREEZING IS FORCED ON FOR ci_mode=sandbox-replay — NON-NEGOTIABLE.
Any explicit time_freezing=false passed alongside ci_mode=sandbox-replay is silently overridden back to true. Rationale: sandbox replay processes the recorded request stream verbatim — any time-sensitive token in any captured request (JWT exp, OAuth iat, session cookie) goes stale the moment wall-clock passes the recorded moment, and silently fails replay. Whether the dev's suite happens to carry such a token is not auditable at scaffold time, and the failure is silent (401 on the first auth-gated step in CI). The cost of force-ON for a hypothetical zero-token app is one dormant volume mount + a no-op CLI flag; the cost of force-OFF for a token-bearing app is every PR failing. Asymmetric — force-ON wins. For ci_mode=api-tests, the workflow runs against live deps with current wall-clock so recorded tokens never enter the picture; time_freezing defaults to false and is overridable by the AI if they want the artifacts pre-staged for a later sandbox switch.