Skip to content

Evidence: the API contract and the scenario table (issue-239)

Testing-plan row T4. apiSpecs makes the OpenAPI document the authored source of truth and the docs generated from it, so what is verified here is that the served surface and the checked-in contract agree.

The served schema matches the authored contract

text
..                                                                       [100%]
2 passed in 0.58s

The contract describes the stream

yaml
operationId: streamEvents
parameters:
- workItem
- transcript
- Last-Event-ID
responses:
  '200':
  - text/event-stream
  '400': (no body)
  '404': (no body)
  '503': (no body)
  '422':
  - application/json

text/event-stream alone on the 200. The first attempt at this offered both that and application/json, because FastAPI infers a JSON response from the return annotation and merges it with a declared one — so the published contract described a media type the route never sends. response_class=StreamingResponse on the decorator is what makes the inferred half agree with the declared half. Caught by reading this evidence file, not by a test: the parity test compares paths, methods and operation ids, and both documents were equally wrong.

The config schema validates, and the packaged copy is the authored one

text
VALID   .the-loop/collaborators.yaml
VALID   skills/the-loop/templates/collaborators.yaml
VALID   .the-loop/cli-config.yaml
VALID   skills/the-loop/templates/cli-config.yaml
........                                                                 [100%]
8 passed in 0.04s

test_docs_parity P4 is the one that matters for this work item: every leaf of the config schema must be documented, so service.stream's three keys could not have been added without the reference section that describes them.

The Gherkin scenarios this work item added

the-loop scenarios renders every integration test's Gherkin docstring as a queryable table (testing.gherkinDocstrings). All 13 of this work item's scenarios are registered, each naming the requirement it proves:

#FeatureScenarioRequirementLocation
254the control plane learns without askingan event is appended while a subscriber is connecteddocs/specs/issue-239/requirements.md R1.1, R1.2cli/tests/test_stream_integration.py:171
255a subscriber sees only what it asked fortwo work items are active and the subscriber filters to onedocs/specs/issue-239/requirements.md R1.3cli/tests/test_stream_integration.py:200
256the stream cannot feed itselfthe control plane refreshes while streamingdocs/specs/issue-239/design.md §Trade-offscli/tests/test_stream_integration.py:225
257a dropped connection loses nothinga subscriber reconnects quoting the last frame it sawdocs/specs/issue-239/requirements.md R1.5cli/tests/test_stream_integration.py:259
258an idle connection is not reaped, and can be told from a dead onenothing happens on a connected streamdocs/specs/issue-239/requirements.md R1.4cli/tests/test_stream_integration.py:291
259watching a work item does not slow down working oneevery allowed stream connection is open and idledocs/specs/issue-239/requirements.md R5.1cli/tests/test_stream_integration.py:332
260an open dashboard cannot starve the servicemore connections are opened than the configuration allowsdocs/specs/issue-239/requirements.md R5.2 (abuse case 1)cli/tests/test_stream_integration.py:357
261a closed tab frees its capacitythe only allowed connection is opened and closeddocs/specs/issue-239/requirements.md R5.4cli/tests/test_stream_integration.py:380
262a bad cursor is a caller error, not a silent full replayLast-Event-ID is not a byte offsetdocs/specs/issue-239/requirements.md R1.5 (abuse case 3)cli/tests/test_stream_integration.py:410
263an unparseable filter never widens to "everything"the workItem parameter is not a work-item refdocs/specs/issue-239/requirements.md R1.3 (abuse case 3)cli/tests/test_stream_integration.py:427
264replay cannot be used to read unbounded historya client resumes from an offset far behind the end of the logdocs/specs/issue-239/requirements.md R1.5 (abuse case 4)cli/tests/test_stream_integration.py:447
265a deployment can narrow itself to REST-onlyservice.stream.enabled is falsedocs/specs/issue-239/requirements.md R1.1, R4.1cli/tests/test_stream_integration.py:469
266the event log answers "who was watching, and what was refused?"a connection is opened, a second refused, and the first closeddocs/specs/issue-239/requirements.md §Non-functional (observability)cli/tests/test_stream_integration.py:491

A note on the command, since the next person will hit it: --root . resolved to a completely different repository on this machine, and --root "$(pwd)" was needed. Not this work item's defect, and not investigated here.

Released under the MIT License.