Quick answer: The completeness gate classifies every parameter, body, and response in a scanned route as proven, proven-empty, or gap, so nothing is left silently blank. Proven means the code confirms the value, proven-empty means the code confirms there is no value, and gap means the scan could not determine it. A route is never emitted as a bare URL with empty contracts, and gaps stay visible rather than being guessed away.
Why empty contracts are dangerous
A document that lists a path with no parameters, bodies, or responses looks complete while saying almost nothing. Downstream tools treat the blanks as facts, and a reader cannot tell whether the emptiness is real or simply unresolved. That ambiguity is exactly what the gate is built to remove.
Instead of emitting blanks, the scan labels the state of each element.
The three statuses
| Status | Meaning | How to read it |
|---|---|---|
| Proven | The code confirms the value and its shape | Trust it as extracted fact |
| Proven-empty | The code confirms no value exists here | Trust the emptiness, do not fill it |
| Gap | The scan could not determine the value | Keep it open, it is not a fact |
Proven-empty is a positive result, not a missing one. It says the code was read and confirmed to have no value, which is different from a gap where the answer is unknown.
Take a GET endpoint that takes no request body. A scan that simply leaves the body blank cannot tell you whether the handler rejects a body or whether the scanner never looked. Proven-empty confirms the handler signature and the framework wiring show no body is accepted, so the document can state that with confidence. A response field the scanner cannot resolve gets the opposite label, and the gap stays open until the source or an AI fill answers it. The two labels sit next to each other in the same route and answer different questions.
How the gate keeps a route honest
A route only enters the document with its contracts classified, so a bare URL with empty contracts is not a valid output. This keeps two failure modes out of the spec:
- A guessed value that pretends an unknown was resolved.
- A blank that pretends an unexamined element was empty.
When an element is a gap, the label stays on it rather than being rounded into proven or proven-empty. AI can later fill a specific gap with a small slice, but it cannot reclassify a route without evidence.
Working with gaps after the scan
The practical move is to read the gaps first, because they name the exact elements that need a person or an AI fill.
- Open the flagged gaps and note the handler and gap code.
- Confirm the value in the source where the scan could not resolve it.
- Let AI fill specific gaps, or fill them yourself.
- Re-run the scan and confirm the gate updates.
A gap that stays open is honest evidence of an unknown, and it is safer than a confident blank. The scan does not run the app, and a classified contract is not a runtime guarantee.
Powerduck keeps the gate status attached to every element, so you can distinguish confirmed values, confirmed emptiness, and unresolved gaps at a glance.
Frequently asked questions
Is proven-empty the same as a gap? No. Proven-empty means the code confirms there is no value, while a gap means the scan could not determine the answer. The first is resolved, the second is open.
Can a route be emitted with no contracts? No. The gate requires every element to be classified, so a bare URL with empty contracts is not produced.
Do gaps get filled automatically? AI can fill specific gaps with bounded slices, but it cannot invent the route, and unresolved gaps remain visible rather than being hidden.
The bottom line
The completeness gate removes the ambiguity of blank contracts by naming every element as proven, proven-empty, or gap. Treat proven and proven-empty as confirmed facts in opposite directions, and keep gaps open as explicit unknowns rather than blanks or guesses. A document that never emits a bare URL stays trustworthy downstream, even though the gate itself does not prove runtime behavior. Naming the unknown is the whole point. Read more in the code-to-OpenAPI guide.
Top comments (0)