The stamp
- Ask does a Jama cell still name the payload
- Stamp ICD last pass. two INT-REQs still share auth→user
- Why each spec is well-formed. nobody asked for one ID
Topic · Interface contract duplicates
Gist
Two active INT-REQs on the same caller→callee signature are not two contracts. Proof runs proof audit --check interface_contract_duplicates. A NASA ICD PDF is not this hop. Jama still authors.
proof audit --check interface_contract_duplicates
Keep the Jama shall if it already names the payload. Keep the ICD if it already names the caller and callee. Neither one fails closed when two live INT-REQs still describe the same surface.
01 · The silent last pass
You can ship two active contracts for auth → user with the same signature, keep both individually valid, and still look connected on paper. This hop stays quiet until the same caller, callee, and signature share two live IDs.
The check is interface_contract_duplicates. It is SPEC-stage. Default severity is warning. It always runs. It groups active INT-REQs that carry a structured interface: block by the triple (normalized caller, normalized callee, normalized signature). Whitespace and case collapse before the key is built, so a cosmetic rename does not hide a real duplicate. Terminal specs (retired, superseded, rejected) are excluded. An empty caller is its own bucket. A missing callee or signature is not grouped. Distinct callers of the same callee are not this hop. Those are multi-consumer contracts. It does not ask whether a real A → B call has any covering INT-REQ. That existence hop stays on
interface coverage.
It does not ask whether an INT-REQ's artifacts still match the last review sha256. That freshness hop stays on
interface staleness clean.
It does not ask whether an ICD-shaped document still names the caller and callee. That document hop stays on
interface control document.
The wired-boundary witness stays on
integration testing.
Each spec in a duplicate group can look fine on its own. The older one is cited by more traces. The newer one has cleaner wording. When the callee changes, two files need the same edit. Over time they diverge: different guarantees, different callers listed, different cited tests. Other SPEC hops miss this because they never ask whether two live IDs describe the same surface.
The expensive miss is a deploy that updates one INT-REQ and leaves the twin. Reviewers argue about which shall is current. Downstream traces keep pointing at the quieter copy. The producer ships the new payload. The consumer still reads the old one. This hop is the gate that names the group so a reviewer can pick a canonical ID and supersede the rest.
# INT-REQ-015 and INT-REQ-022
# caller: auth
# callee: user
# GET /users/{id} returns the profile or 404
# proof audit --check interface_contract_duplicates
# [SPECIFICATION] interface_contract_duplicates
# 1 duplicate interface contract group(s)
# auth→user: GET /users/{id} shared by INT-REQ-015, INT-REQ-022
# WARNING
# keep one. supersede the other. two live IDs are not two contracts
The fix is a human authorization, not a rewrite of Go. Pick the canonical INT-REQ: richer authored content, or the one already cited by more downstream specs. Then supersede each duplicate. Do not delete the extra YAML to silence the checker. Do not invent a third ID. Then re-run SPEC.
proof req supersede <duplicate-id> --replacement <canonical-id> \
--reason "consolidating duplicate interface contracts" \
--by "<reviewer>"
proof audit --check interface_contract_duplicates --verbose
proof workflow check --stage spec --only interface_contract_duplicates
proof help interface_contract_duplicates
02 · The exhibit
One last green SPEC while INT-REQ-015 and INT-REQ-022 still share auth → user. Click the tabs.
The stamp
This hop
Nobody asked whether two live INT-REQs describe the same caller, callee, and signature. Two YAML files are not two contracts. The finding kind is this hop.
Need unreadThe stamp
Keep the Jama cell. Keep the ICD PDF. That is not this hop.
Keep the recordProof
Same caller→callee signature. Silent last pass, or this hop. Click the tabs.
| Surface | What they do | What Proof does | What we lose |
|---|---|---|---|
| Green tests | The last samples that still unioned. | Whether two live INT-REQs share one surface. | We do not rerun the suite here. A green stamp is not this hop. |
| Interface coverage | Whether a real A → B call has any covering INT-REQ. | Whether two covering INT-REQs describe the same triple. | Not existence. See interface coverage. |
| Interface control document | Whether an INT-REQ still names the caller and callee. | Whether two named INT-REQs are the same contract twice. | Not the document. See interface control document. |
| Interface staleness clean | Whether an existing INT-REQ's artifacts still match the last review. | Whether the graph holds one canonical ID for that surface. | Not freshness. See interface staleness clean. |
| Integration testing | Whether the wired boundary still holds at runtime. | Whether the authored contract is unique before you wire it. | Not the wired witness. See integration testing. |
| LDRA / VectorCAST | An avionics toolchain that already owns MC/DC on C. | A warning the audit can name next to a duplicate group. | We do not replace LDRA. We have not run a frozen VectorCAST corpus. See Proof vs LDRA. |
| Jama cell | A shall, and a parent if you type it. | A warning the audit can name next to the extra INT-REQ. | Not Jama's V&V. Jama still authors. We have not run a frozen Jama pack. |
The teaching graph is still two live INT-REQs on one caller→callee signature. Close it by superseding the extra ID. Do not delete the YAML. Do not invent a third contract. Two different callers of the same callee are not this hop. That is a multi-consumer surface, and the check leaves it alone.
# INT-REQ-015 kept. INT-REQ-022 superseded
# caller: auth
# callee: user
# GET /users/{id} returns the profile or 404
# proof audit --check interface_contract_duplicates
# 0 duplicate interface contracts
# SPEC may move on. pass sits on one ID
The existence hop stays on interface coverage. The document hop stays on interface control document. The freshness hop stays on interface staleness clean. The wired-boundary hop stays on integration testing. The rewrite hop stays on characterization testing and mirrors. Jama still authors. Proof vs Jama.
03 · The honest loss
A quiet proof audit --check interface_contract_duplicates can still mean every extra ID is already terminal. Jama still authors.
Warning when two or more active INT-REQs share caller, callee, and signature after whitespace and case collapse. Default severity does not fail the merge unless you raise it in proof.yaml. Zero groups is a pass, not a proof that the remaining ID is the one you meant. An empty caller is a separate bucket, not a skip. Distinct callers of the same callee pass this hop. Terminal specs are excluded, so a superseded twin does not re-fire. The hop does not supersede. It does not pick the canonical ID. It does not write the INT-REQ. It does not add a shall. It does not prove the Go. It does not run Kind2. It does not measure independence. It does not say a real boundary is covered. That existence hop is
interface coverage.
It does not say the implementation sha256 still matches the last review. That freshness hop is
interface staleness clean.
It does not say an ICD-shaped document exists. That document hop is
interface control document.
A quiet hop is not a proof that the remaining contract is unique in Jama, only that the active graph no longer holds two live IDs on the same triple. We have not scored this floor against a frozen Jama pack or a VectorCAST corpus. The loss is named, not scored.
The existence hop stays on interface coverage. The document hop stays on interface control document. The freshness hop stays on interface staleness clean. The rewrite hop stays on characterization testing and mirrors. The engagement stays on software correctness audit. Jama still authors.
04 · Nearby questions
What is interface contract duplicates? Same question. Same URL.
Is this interface coverage? No. That hop is whether a real boundary has any covering INT-REQ at all. This hop is whether two covering INT-REQs describe the same triple. See interface coverage.
Is this an interface control document? No. That hop is whether an INT-REQ still names the caller and callee. This hop is whether two named INT-REQs are the same contract twice. See interface control document.
Is this interface staleness clean? No. That hop is whether the implementation sha256 still matches the last review. This hop is uniqueness of the live ID. See interface staleness clean.
Is this integration testing? No. That hop is the wired-boundary witness. This hop is the authored contract's uniqueness. See integration testing.
Is this characterization testing? No. That page is rewrite-with-a-ledger. This hop is duplicate interface IDs. See characterization testing and mirrors.
Does a quiet hop prove the Go matches the shall? No. The hop observes live IDs. It does not prove the Go.
Do two callers of the same callee fail this hop? No. Distinct callers are multi-consumer contracts. The check leaves them alone.
Does a superseded twin fail this hop? No. Terminal specs are excluded.
Does a duplicate group fail the merge? No by default. The check keeps warning severity unless you raise it in proof.yaml.
Is Proof an LDRA alternative for the instrument? No. LDRA still owns the avionics toolchain. Proof vs LDRA.
Is Proof a Jama alternative for the shall? No. Jama still authors. Proof vs Jama.