Repository navigation
feat(witan-core): send and check the Omnigraph-Http-Api contract header - #464
Merged
Merged
Conversation
omnigraph-server 0.13 answers 400 api_contract_mismatch to any protected request without exactly one `Omnigraph-Http-Api: 0.13`, and stamps the same header on every response. PooledTransport is our only direct HTTP client, and it sent none. This sends the header on every request. A 0.11 server ignores it, so this is safe ahead of the pin. It also checks the response's header before decoding the body, following upstream's rule that a missing or incompatible one means unknown effects and never permission to replay. A violation is its own outcome kind, CONTRACT_VIOLATION: never retried, and raised as WriteIndeterminate for a write. A stamp naming another contract is always a violation. A missing stamp is one for a 2xx and for any refusal of a write, because a 429/503/409 from something other than the server does not prove the write was not applied. A read that failed unstamped keeps its ordinary classification. 0.11 sends no stamp, so the missing-stamp rule is gated on `_OMNIGRAPH_INTERNAL_SCHEMA >= 14` and turns on with the pin bump. Claude-Session: https://claude.ai/code/session_01Mfmuz4DTn557AV8V17o98A
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Response validation currently occurs after body decoding and permits retries that conflict with the accepted contract.
2 open findings
What changed in this PR
Adds Omnigraph 0.13 HTTP contract negotiation to witan-core while retaining 0.11 compatibility.
Changes:
- Sends and validates
Omnigraph-Http-Api: 0.13. - Adds terminal and indeterminate outcome handling.
- Expands compatibility and retry-policy tests.
| File | Description |
|---|---|
packages/witan-core/witan_core/omnigraph.py |
Handles write contract violations. |
packages/witan-core/witan_core/omnigraph_http.py |
Implements contract headers and validation. |
packages/witan-core/tests/test_omnigraph_http.py |
Tests contract behavior and retries. |
packages/witan-core/changelog.d/20261008_133544_blarghmatey_omnigraph_013_http_api_header.md |
Documents the feature. |
mcp/servers/witan-code/tests/test_store.py |
Updates the HTTP response test double. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The response body was UTF-8 decoded one line before the stamp check, which the check's own comment and upstream's rule both say comes first. The decode now happens after the violation branch. The WriteIndeterminate message said the response was "without" a stamp. A violation also covers a stamp for another contract and a repeated one, and the appended detail can then read "found '0.14'". It now says the response did not carry exactly the expected stamp. Claude-Session: https://claude.ai/code/session_01Mfmuz4DTn557AV8V17o98A
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


What are the relevant tickets?
N/A (witan task tk-send-and-check-the-omnigraph-http-api-0-12-heade-a85e58, part of the omnigraph 0.13 upgrade, spec in #461 D7)
Description (What does it do?)
omnigraph-server 0.13 answers
400 api_contract_mismatchto any protected request without exactly oneOmnigraph-Http-Api: 0.13header, and stamps that header on every response.PooledTransportis our only direct HTTP client and sent none, so every HTTP read and write would fail after the pin bump.This sends the header on every request. A 0.11 server ignores it, so this can merge ahead of the pin.
It also checks the response's header before decoding the body. Upstream's rule is that a missing or incompatible response header "means unknown effects, never permission to replay". A violation is a new outcome kind,
CONTRACT_VIOLATION. It is never retried, and for a write the retry loop raisesWriteIndeterminate, as it does for the recovery barrier.0.11 sends no stamp, so the missing-stamp rule is gated on
_OMNIGRAPH_INTERNAL_SCHEMA >= 14and turns on with the pin bump. Two consequences for that bump, recorded on its task:The contract value is its own constant. Upstream keeps it separate from the package version, so it is not derived from
_OMNIGRAPH_VERSION.How can this be tested?
just test-witan-core728 passed,just test-witan-council1429 passed,just test-witan-code682 passed.curland by drivingPooledTransportat them:CONTRACT_VIOLATION, which is the mixed-fleet case above.400 {"code":"api_contract_mismatch"}without it or with0.12. It stampsomnigraph-http-api: 0.13on 200, 400, 403 and 404 responses. With the rule forced on, query and mutate returnok, and an unknown graph's 404 keeps its ordinary classification.https://claude.ai/code/session_01Mfmuz4DTn557AV8V17o98A