Propose durable agent state schema 2.0 contract - #92
Conversation
Define a draft language-neutral execution/completion contract, synthetic review fixtures, and explicit cross-runtime rollout prerequisites without activating runtime writes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 532fe4f5-939b-4962-989d-a1883dccd283
Record independent gpt-5.6-sol ACCEPT of the unchanged schema-only tree 9051274. Keep the proposal commit unchanged and record both required trailers together in an append-only review record. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 532fe4f5-939b-4962-989d-a1883dccd283
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The 2.0 schema currently allows unconstrained correlationId values in typed transcript entries, undermining the stricter identifier contract used by the receipt/result maps and the stated invariants.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Lite
Findings: 1
New issues introduced by this change (1)
| Severity | Finding |
|---|---|
schemas/durable-agent-entity-state.json — In schema 2.0, conversationHistory entries are constrained to… |
What changed in this PR
This PR proposes a durable agent state schema 2.0 contract (plus legacy review snapshots) intended for joint cross-runtime review, explicitly without authorizing any runtime to emit 2.0. It adds documentation and synthetic fixtures to discuss new “terminal completion outside transcript” concepts and rollout/compatibility semantics.
Changes:
- Added a Draft 2020-12 JSON Schema that enumerates snapshot versions (1.0.0/1.1.0/proposed 1.2.0/proposed 2.0.0) and introduces 2.0 concepts like
terminalResults,completionReceipts, andhistoryBinding. - Added documentation describing semantic invariants, compatibility concerns, and rollout gating expectations.
- Added synthetic JSON fixtures for reviewing 1.2 (Python-shaped) and 2.0 state shapes, including a pruned-transcript example.
| File | Description |
|---|---|
| schemas/README.md | Documents the proposed 2.0 contract semantics, invariants, and rollout/compatibility constraints. |
| schemas/durable-agent-entity-state.json | Draft 2020-12 schema defining legacy snapshots and proposed 2.0 structure (receipts/results/binding). |
| schemas/fixtures/README.md | Explains fixture provenance and how to interpret the synthetic examples. |
| schemas/fixtures/shared-durable-agent-state-1.2-python-shape.json | Synthetic 1.2 “Python-shaped” review example emphasizing unknown-field preservation discussion. |
| schemas/fixtures/shared-durable-agent-state-2.0.json | Synthetic 2.0 example showing an available success and an expired/unavailable failure receipt. |
| schemas/fixtures/shared-durable-agent-state-2.0-pruned.json | Synthetic 2.0 example with empty transcript but retained completion evidence and TTL/truncation diagnostics. |
Suppressed comments (2)
schemas/durable-agent-entity-state.json:218
- For schema 2.0,
agentResponseshould also constraincorrelationIdto the sharedidentifierdefinition so transcript entries can’t contain correlation IDs that would be invalid asterminalResults/completionReceiptskeys.
"properties": {
"$type": { "type": "string", "const": "response" },
"usage": {
schemas/durable-agent-entity-state.json:231
- For schema 2.0,
agentErrorResponseshould constraincorrelationIdtoidentifieras well, to keep correlation IDs consistent across transcript entries and the receipt/result maps.
"properties": {
"$type": { "type": "string", "const": "errorResponse" },
"usage": { "$ref": "#/$defs/usage" }
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Thanks for the feedback. I am going to update the schema proposal based on these threads. I am marking this PR ready for review now so we can agree on the shared contract while I start opening the dependent C# implementation PRs as drafts. Those implementation PRs will remain drafts and will not activate schema 2.0 until this contract and the rollout requirements are agreed. |
Constrain v2 correlations, preserve supported JSON message and structured result shapes, make the provisional binding optional, and clarify legacy ingestion and entity-local commit semantics. Add language-neutral validation cases without runtime activation. Binding representation and expired lookup outcome remain pending agreement. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 532fe4f5-939b-4962-989d-a1883dccd283
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
Cross-runtime schema semantics remain unresolved, and the moderate legacy-version scoping issue requires correction and human review.
Review tier: Lite
Findings: None
Issues resolved since last review (1)
| Severity | Finding |
|---|---|
schemas/durable-agent-entity-state.json — In schema 2.0, conversationHistory entries are constrained to… View resolved comment |
Restore historical message and content validation, isolate expanded v2 transcript and terminal response definitions, and add full-envelope version boundary cases. Treat historyBinding as an opaque runtime profile and clarify authoritative expired outcomes without inventing legacy outcomes. No runtime activation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 532fe4f5-939b-4962-989d-a1883dccd283
Ahmed Muhsin (ahmedmuhsin)
left a comment
There was a problem hiding this comment.
Approved for the schema-only contract at eff12f4. The review concerns are addressed. The documented reader/consumer agreement remains required before merge, and runtime implementations and v2 activation need separate review and deployment gates.

Contract discussion, not runtime activation
This schema-only proposal separates execution/delivery completion from evictable
conversation transcript state. It changes only
schemas/JSON and Markdown:no .NET/Python implementation, DTOs, converters, runtime activation, samples,
test-project links, or migrations. Positive and negative validation cases are
language-neutral JSON test data, not runtime code.
Python and .NET must not emit schema 2.0 until joint agreement and compatible
readers/consumers exist. Agreement on compatible-reader/consumer semantics and
the enforced rollout floor is a prerequisite to merging this contract proposal.
Any 2.0 writes require separately reviewed implementations and deployment gates;
schema validation or merging this PR does not authorize them.
Proposed wire concepts
outside
conversationHistory.and transcript pruning; explicit available versus completed-but-unavailable
results, distinct from pending/unknown requests.
historyBindingname, preserved by compatible writers and validated only byruntimes relying on it. No shared binding shape or effective-owner policy.
content, and a named optional terminal response
valuethat distinguishesabsence from explicit null/false/zero/empty values.
truncation evidence, extension-data preservation, and known-discriminator rules.
The JSON Schema checks structural constraints. Shared documentation specifies
cross-map consistency, immutable completion, full entity-local atomic commits, lazy-expiry
polling, trust boundaries, migration limits, and unresolved deployment policy.
Fixtures are synthetic review data, not captured production output; the
Python-shaped 1.2 fixture is explicitly not byte-for-byte Python serializer
output. No runtime's support for proposed 1.2/2.0 is inferred from them.
Historical 1.0/1.1/1.2 message/content validation remains unchanged from the
pre-widening proposal. Explicit versioned definitions and full-envelope
positive/negative cases keep the expanded mappings v2-only. Existing opaque
unknown.contentshapes and all four persisted fixture blobs remain unchanged.Compatibility and rollout risks
This is proposed as a major semantic revision because completion/replay authority
moves away from transcript presence. Is major 2 the right mechanism, or is an
enforceable same-major rollout gate preferable?
At base
62afdbac03f0a81b0917abe6328203b706a2f294, Python's reader checks that aversion is present but does not gate its value, and its data reader does not
preserve unknown data fields. The revised C# preview is fail-closed. This is a
cross-runtime compatibility issue to resolve together: a major number or unknown
field preservation alone does not protect against duplicate execution or lost
completion state.
The rollout floor must cover readers, duplicate lookups, pollers, writers,
rollback writers, hosting consumers, and scheduler/dashboard tooling. Participants
must behave compatibly or reject 2.0 before processing/mutation and be isolated
from it. A rollback writer must not downgrade or discard completion evidence.
Changing only the version or adding empty maps to old pruned state is not a
migration. Whole-entity TTL, session recreation, late duplicates, receipt storage
growth, and continuation/numeric interoperability also need agreement.
Feedback requested
Ahmed/Python maintainers and .NET/Durable Task maintainers:
relying on them. Fixed-owner policy remains runtime-specific; the common
contract does not standardize a binding object or per-run transition policy.
session generation, and late duplicate semantics. Expired lookup exposes
retained success/failure with completed-but-result-unavailable and no payload.
Older receipts lacking authoritative outcome must not invent one or reopen
execution; their migration/lookup representation still needs agreement.
The agreed behavior requires aligned ADR wording and Python receipt/lookup updates.
Related context: #88 (ADR 0032).
That ADR motivates compaction/retention discussion; it does not mandate this
exact schema. This PR is ready for cross-runtime review, but the contract remains
proposed and does not authorize schema 2.0 activation. Dependent implementation
PRs will remain drafts until the contract and rollout requirements are agreed.