Runtime Verification
Contract
Iron law: no completion until the code builds, runs, and behaves correctly; if you cannot verify it, build the infrastructure to verify it. Invoked after quality checks pass by /flow:start Phase 4 step 2, /flow:pr Phase 4 via Agent(integration-verifier), and the address-pr, debug, and start-issue workflows. Returns the Runtime Verification Results and Acceptance Criteria Verification tables, with failures as P1 findings (category=runtime). Permitted skips: only markdown-only, config-only, or dependency-bump-only, each with its listed evidence; any other skip needs an approved six-field escalation via AskUserQuestion.
Skip Whitelist
| Category |
Definition |
Required evidence |
markdown-only |
Only .md, .markdown, .txt, .rst files |
git diff --name-only origin/$DEFAULT_BRANCH..HEAD showing only doc extensions |
config-only |
Only config files (.json, .yaml, .yml, .toml, .ini, .env.example, dotfiles) with no code-path change; syntax still validated (lint/schema, dry-run) |
Full file list plus validation output |
dependency-bump-only |
Only lockfiles and manifest version strings (package.json version, package-lock.json, poetry.lock, Gemfile.lock, go.sum, Cargo.lock); no source, config semantics, or new dependencies; build still succeeds |
Full file list plus build output |
Mixed diffs (a whitelisted category plus one .py file, a new dependency, or a behavior-changing config value) get full verification. "Small change", "CI-only", "tests cover this", "just a refactor" are not categories.
Out-of-whitelist skips (anything uncovered): raise a Proactive-Autonomy escalation per references/escalation-format.md via AskUserQuestion and wait for approval; Situation cites why the whitelist misses the change, Tried lists the fast-path, build, and smoke attempts. Blanket repo-wide authorization is never valid.
Sequence
- Fast path: an executable
verify.sh or scripts/verify.sh is run and its results returned.
- Build (mandatory, every project type; per-stack commands and tables in
runtime-verification-probes.md). Build failure IS the finding: read errors, fix, rebuild up to closedLoop.maxBuildIterations (default 5).
- LSP diagnostics when
lsp.enabled and lsp.diagnosticsAsQuality (both default true): Error=P1, Warning=P2, Info/Hint=P3, deduplicated against CLI output, bounded by lsp.timeout (default 5000 ms); timeout or no server is N/A, never a block.
- Dev server: use
capability-discovery output. Won't start: read the error, fix, retry up to closedLoop.maxServerRetries (default 3); port busy: another port; startup wait timeouts.devServerStartup seconds (default 30).
- Smoke:
curl /health and /; non-200 is a P1 finding (references/finding-schema.md).
- E2E when a framework exists, within
timeouts.e2eTest (default 120); otherwise ad-hoc verification by project type (reference); "no test framework" is a problem to solve, not a skip.
- Acceptance criteria: map each to a method (reference table) and record Pass/Fail/N/A.
On any failure: read the full error, root-cause it (debugging-patterns), fix, re-verify, up to closedLoop.maxDebugIterations (default 5), then escalate; the user never supplies logs.
Completion
UI-relevant diffs (rules in skills/visual-verification/SKILL.md) also run Skill(visual-verification) in parallel; if the dev server cannot start, that skill returns SKIP ("dev server unavailable") and the server failure is the primary finding; tables render side by side. visualVerification.* settings belong there.
Complete only when every testable criterion has Pass/Fail/N/A with a reason and every failure, including a dev server that won't start, is a P1 finding.
Output Format
### Runtime Verification Results
| Check | Status | Details |
|-------|--------|---------|
| Dev server | {Running/Not found} | Port {N} |
| Health check | {Pass/Fail/N/A} | HTTP {status} |
| E2E tests | {Pass/Fail/N/A} | {framework} |
| Smoke tests | {Pass/Fail/N/A} | {details} |
| LSP diagnostics | {Pass/Fail/Skip/N/A} | {errors: N, warnings: N, files checked: N} |
### Acceptance Criteria Verification
| # | Criterion | Verified | Method |
|---|-----------|----------|--------|
| {n} | {ui criterion} | Pass/Fail | visual-verification `Observed:` blocks → bundle `### Visual analysis` |
1---2name: runtime-verification3description: Verify code works at runtime through build verification (mandatory), LSP diagnostics, ad-hoc verification for projects without frameworks, E2E and smoke tests, and visual verification (screenshot-analyze-verify for UI changes). Skip whitelist strictly enforced (markdown-only, config-only, dependency-bump-only with evidence); all other skips require Proactive-Autonomy escalation. Use after quality checks pass to confirm the code actually runs. This skill MUST be consulted because no test framework is not an excuse to skip; build failure IS a finding and must be fixed.4---56# Runtime Verification78## Contract910Iron law: **no completion until the code builds, runs, and behaves correctly; if you cannot verify it, build the infrastructure to verify it.** Invoked after quality checks pass by `/flow:start` Phase 4 step 2, `/flow:pr` Phase 4 via `Agent(integration-verifier)`, and the `address-pr`, `debug`, and `start-issue` workflows. Returns the Runtime Verification Results and Acceptance Criteria Verification tables, with failures as P1 findings (`category=runtime`). Permitted skips: only `markdown-only`, `config-only`, or `dependency-bump-only`, each with its listed evidence; any other skip needs an approved six-field escalation via `AskUserQuestion`.1112## Skip Whitelist1314| Category | Definition | Required evidence |15|----------|------------|-------------------|16| `markdown-only` | Only `.md`, `.markdown`, `.txt`, `.rst` files | `git diff --name-only origin/$DEFAULT_BRANCH..HEAD` showing only doc extensions |17| `config-only` | Only config files (`.json`, `.yaml`, `.yml`, `.toml`, `.ini`, `.env.example`, dotfiles) with no code-path change; syntax still validated (lint/schema, dry-run) | Full file list plus validation output |18| `dependency-bump-only` | Only lockfiles and manifest version strings (`package.json` version, `package-lock.json`, `poetry.lock`, `Gemfile.lock`, `go.sum`, `Cargo.lock`); no source, config semantics, or new dependencies; build still succeeds | Full file list plus build output |1920Mixed diffs (a whitelisted category plus one `.py` file, a new dependency, or a behavior-changing config value) get full verification. "Small change", "CI-only", "tests cover this", "just a refactor" are not categories.2122**Out-of-whitelist skips** (anything uncovered): raise a Proactive-Autonomy escalation per [`references/escalation-format.md`](../../references/escalation-format.md) via `AskUserQuestion` and wait for approval; Situation cites why the whitelist misses the change, Tried lists the fast-path, build, and smoke attempts. Blanket repo-wide authorization is never valid.2324## Sequence25261. **Fast path**: an executable `verify.sh` or `scripts/verify.sh` is run and its results returned.272. **Build** (mandatory, every project type; per-stack commands and tables in [`runtime-verification-probes.md`](../../references/runtime-verification-probes.md)). Build failure IS the finding: read errors, fix, rebuild up to `closedLoop.maxBuildIterations` (default 5).283. **LSP diagnostics** when `lsp.enabled` and `lsp.diagnosticsAsQuality` (both default `true`): Error=P1, Warning=P2, Info/Hint=P3, deduplicated against CLI output, bounded by `lsp.timeout` (default 5000 ms); timeout or no server is N/A, never a block.294. **Dev server**: use `capability-discovery` output. Won't start: read the error, fix, retry up to `closedLoop.maxServerRetries` (default 3); port busy: another port; startup wait `timeouts.devServerStartup` seconds (default 30).305. **Smoke**: `curl` `/health` and `/`; non-200 is a P1 finding (`references/finding-schema.md`).316. **E2E** when a framework exists, within `timeouts.e2eTest` (default 120); otherwise ad-hoc verification by project type (reference); "no test framework" is a problem to solve, not a skip.327. **Acceptance criteria**: map each to a method (reference table) and record Pass/Fail/N/A.3334On any failure: read the full error, root-cause it (`debugging-patterns`), fix, re-verify, up to `closedLoop.maxDebugIterations` (default 5), then escalate; the user never supplies logs.3536## Completion3738UI-relevant diffs (rules in `skills/visual-verification/SKILL.md`) also run `Skill(visual-verification)` in parallel; if the dev server cannot start, that skill returns `SKIP` ("dev server unavailable") and the server failure is the primary finding; tables render side by side. `visualVerification.*` settings belong there.3940Complete only when every testable criterion has Pass/Fail/N/A with a reason and every failure, including a dev server that won't start, is a P1 finding.4142## Output Format4344```markdown45### Runtime Verification Results4647| Check | Status | Details |48|-------|--------|---------|49| Dev server | {Running/Not found} | Port {N} |50| Health check | {Pass/Fail/N/A} | HTTP {status} |51| E2E tests | {Pass/Fail/N/A} | {framework} |52| Smoke tests | {Pass/Fail/N/A} | {details} |53| LSP diagnostics | {Pass/Fail/Skip/N/A} | {errors: N, warnings: N, files checked: N} |5455### Acceptance Criteria Verification56| # | Criterion | Verified | Method |57|---|-----------|----------|--------|58| {n} | {ui criterion} | Pass/Fail | visual-verification `Observed:` blocks → bundle `### Visual analysis` |59```