[FEAT]: Canonical versioned trace/result serializer (WS0-05 PR 1) - #185
Open
Nina Chikanov (nina-msft) wants to merge 12 commits into
Open
Nina Chikanov (nina-msft) wants to merge 12 commits into
Nina Chikanov (nina-msft) wants to merge 12 commits into
Conversation
Introduce rampart/core/serialization.py as the single, neutral full-fidelity Result <-> dict round-trip (Decision D6 gate). Every record carries a single root version (rampart.trace.v1) and decoding dispatches on it, failing closed on an unknown major. The canonical layer defines the supported value domain only: enums encode to .value and fail closed on unknown values, harm_category is a passthrough string, floats must be finite, and free-form maps must be JSON-safe. Transport hygiene (ANSI stripping, float normalization, repr() fallback, size caps) stays at the xdist boundary and is not duplicated here. Binary payloads fail closed pending the WS7 artifact resolver rather than being coerced to text. Also lands the written migration policy (docs/concepts/trace-schema.md): additive-optional = no bump, structural = major bump, missing = not recorded, readers fail closed on unknown major, with named reserved additive slots so WS8 provenance needs no hard migration. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Describe only the canonical serializer behavior present on this branch, express later migration and consumer work as policy constraints, generalize future additions outside the reserved collar fields, and remove the ship gate. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Remove planning references, place constant comments before declarations, drop the unused identity origin field, and make unsupported binary payload messages independent of planned work. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Remove identity and case_id until their producer is implemented, keep the existing pytest attribution fields optional, and make the reserved metadata constant private. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Fail closed on malformed collection fields, incomplete population references, and non-string harm categories. Validate result indices before serialization so the encoder cannot emit boolean indices rejected by the decoder. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Replace handwritten nested codecs with a cached TypeAdapter on Result, keep ResultRecord as the versioned envelope, and generate the open schema with a CI drift check. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Rename the record helpers to serialize_record and deserialize_record, accepting ResultRecord and JSON text respectively. Keep dictionary conversion on the existing record methods. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Restore public dataclass annotations, apply canonical policies through adapter-local schema hooks, document structural schema limits and transport preparation, and add generated round-trip coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Restore types.py to its PR-base contents and supply datetime/Path resolution inside the canonical adapter. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Nina Chikanov (nina-msft)
marked this pull request as ready for review
September 11, 2026 20:46
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
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.
WS0-05 — PR 1: Canonical versioned trace/result serializer
Establishes the neutral schema API and migration policy. Existing reporting and xdist consumers are not rewired in this PR.
What this lands
Result.to_dict()/Result.from_dict()— the canonical, unversioned body codec, backed by one cached Pydantic adapter overResult. The existing standard dataclasses remain the live models; there is no parallel body model or set of nested encode/decode functions. Encoding uses Python-mode adapter output with explicit enum/datetime serializers, followed by a canonical reader pass before returning the body. This extra pass preserves existing reader depth support without introducing a new depth cap; interpreter/parser recursion limits still apply.GetPydanticSchemahook configures copies of generated core-schema nodes. Public fields retain plain dictionary/datetime annotations; no class-wide Pydantic configuration or trace validators are attached to the live dataclasses. Other Pydantic adapters retain their normal behavior. The canonical adapter explicitly supplies its datetime/Path resolution namespace;types.pyis unchanged from the PR base.ResultRecordenvelope inrampart/core/serialization.py.serialize_record(record=...) -> strserializes an explicitly constructedResultRecordto JSON text;deserialize_record(data=...) -> ResultRecordreads JSON text.ResultRecord.to_dict()/from_dict()remain available for dictionary conversion and projections. Every record carries the single root versionrampart.trace.v1; unsupported versions fail closed through the decoder registry. Body dicts are fragments, not standalone durable records.pytest_nodeidandresult_index, omitted when not recorded. Stable identity fields and durable artifact descriptors remain deferred until their implementations exist.ValueErrors surface asSchemaError.ResultRecord.to_dict()filters only top-level transport bookkeeping from encoded output, including_rampart_source_worker. Body-only serialization and record decoding retain these keys. Re-encoding filters them from output without modifying the referenced result; nested user maps remain intact.schemas/trace.v1.schema.json.ResultRecord.json_schema()composes the adapter-derived body and versioned envelope, with narrow customizations for trace payload restrictions and the Request invariant. Runtime class docstrings are omitted in favor of concise trace-specific descriptions.scripts/generate_trace_schema.py --checkis the CI drift gate.docs/concepts/trace-schema.md: additive optional fields require no bump; structural changes require a new major; absence means not recorded, not a semantic negative. Reserved future field names and the release-based support window are documented. Transport normalization must prepare a separate result before encoding; a binary text placeholder is a lossy transport view, not a durable replay artifact.Coverage
Hypothesis-generated body and record round-trips over nested JSON values, all nine nested types, enums, optional fields, and timestamps. Example-based coverage includes field exhaustiveness, version dispatch, attribution, additive tolerance, invalid JSON/types/cycles, independent-adapter isolation, schema semantics, and payload rejection before filesystem access. Additional regressions cover surrogate-containing text and mapping keys, valid Unicode/JSON surrogate-pair escapes, deep-nesting round-trips, and recursion/error boundaries with exception chaining. A prepared-copy boundary case demonstrates canonical reuse without modifying or relaxing the original result.
hypothesisandjsonschemaare development-only dependencies.Scope
Reporting projections, xdist/failure-attachment adoption, and stable identity remain separate follow-up implementations. Existing transport coercion and payload-display behavior require explicit preparation and compatibility work, not a mechanical serializer replacement. No public transport-preparation API or artifact representation is introduced here.