Decision 014: Gherkin scenario docstrings on integration tests + contract-first API specs
- Status: accepted
- Date: 2026-07-02
- Deciders: @MadaraUchiha-314 (issue author intent)
- Work item: issue-11
Context
Issue #11 asks for two conventions the loop should enforce:
- Integration tests should be self-describing — a coding-agent harness (Claude, Cursor, …) should be able to query all scenarios being tested and present a tabular view, and tests tied to a
requirements.mdshould link back to it. - API contracts should be authored declaratively — RESTful specs in
specs/openapi/in the OpenAPI format, with documentation generated from them. The GraphQL equivalent was left as a TODO to figure out.
Decision
- Gherkin docstrings, extracted by text — not a BDD framework. Every integration test carries a Gherkin-syntax docstring (
Feature:/Scenario:/Given-When-Then, optionalRequirement:link). A new stdlib-only CLI command,the-loop scenarios(--format table|markdown|json), extracts them by scanning configured globs (testing.integrationTestGlobs) and stripping comment markers, so the same convention works across Python docstrings, JS/TS block comments and Go comments without adopting cucumber/behave/pytest-bdd or binding tests to step definitions. - REST: OpenAPI 3.1 under
specs/openapi/, spec-first; docs generated (default toolredocly, free-form), never hand-written (apiSpecs.rest). - GraphQL best practice: SDL-first under
specs/graphql/— the checked-in SDL (snapshotted when code-generated) is the reviewable contract; mandatory type/field descriptions; docs generated (default toolspectaql, free-form); a breaking-change check against the previous snapshot in CI (apiSpecs.graphql). This resolves the issue's GraphQL TODO. - Conventions are codified in
skills/the-loop/reference/testing.mdand driven by two new config sections,testingandapiSpecs(schema-validated).
Consequences
- Positive: scenario coverage is queryable without executing tests; requirements ↔ test traceability is explicit; API changes are reviewed as contract diffs; docs can never drift from the contract (they're generated); zero new runtime dependencies.
- Negative: the docstring convention is enforced by review/convention, not by a parser wired into the test runner; a free-text Gherkin block can drift from what the test actually does (mitigated by the review loop reading both together).
Alternatives considered
- A BDD framework (cucumber/behave/pytest-bdd) — real executable Gherkin, but binds every language's tests to step-definition machinery and violates minimalism for what is fundamentally a documentation/traceability need.
- Code-first API specs (generate OpenAPI from handlers/annotations) — keeps spec and code in one place, but makes the contract an artifact of the implementation; design-phase review of API changes needs the contract to be the source of truth.
- GraphQL code-first only (no checked-in SDL) — introspection always exists, but without a checked-in SDL snapshot there is no reviewable diff and no CI breaking-change gate.