Skip to content

otel/11: assert span timestamp relationships - #34

Merged
zhongkechen merged 3 commits into
mainfrom
codex/span-timestamp-assertions-main
Jul 24, 2026
Merged

otel/11: assert span timestamp relationships#34
zhongkechen merged 3 commits into
mainfrom
codex/span-timestamp-assertions-main

Conversation

@zhongkechen

@zhongkechen zhongkechen commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • validate that every span starts at or before it ends
  • add before, after, and inside span assertions
  • require asserted parents to contain the complete child timespan
  • document the timestamp assertion syntax

This extracts the dependency-free timestamp assertion support from #30 so it can merge into main first. It intentionally excludes the #28-specific requirement catalogs, and PR #30 remains unchanged until this PR lands.

Testing

  • hatch run test:all (177 passed)
  • hatch run types:check
  • hatch run yaml:lint
  • hatch fmt --check packages scripts
  • hatch run dist:all

@zhongkechen
zhongkechen had a problem deploying to ai-pr-review-runtime July 24, 2026 23:40 — with GitHub Actions Failure
@zhongkechen
zhongkechen had a problem deploying to ai-pr-review-runtime July 24, 2026 23:40 — with GitHub Actions Failure
@zhongkechen zhongkechen changed the title test(otel): assert span timestamp relationships otel/11: assert span timestamp relationships Jul 24, 2026
@zhongkechen zhongkechen self-assigned this Jul 24, 2026
@zhongkechen
zhongkechen temporarily deployed to ai-pr-review-runtime July 24, 2026 23:50 — with GitHub Actions Inactive
@zhongkechen
zhongkechen temporarily deployed to ai-pr-review-runtime July 24, 2026 23:50 — with GitHub Actions Inactive
@github-actions

Copy link
Copy Markdown
Contributor

Codex AI review

  • [P1] Preserve topology-only parent assertionspackages/aws-durable-execution-conformance-tests-otel/src/aws_durable_execution_conformance_tests_otel/validators.py:203: OpenTelemetry parentage is causal and does not require temporal containment; asynchronous children may outlive or start after a completed parent. Applying containment to every existing expect.parent can reject valid continuation, retry, and callback traces until polling times out. Keep parent topology-only and require explicit inside assertions where containment is intended. Add a regression test allowing a child outside its parent’s timespan without inside.

Reviewed commit cc1d5fbebf328c2d4cdbc437021997385d3a1bb5. Workflow run

@github-actions

Copy link
Copy Markdown
Contributor

Claude AI review

No actionable findings. The change is well-scoped and internally consistent.

Verification performed:

  • Relation semantics (_temporal_relation_errors): before requires selected.end <= other.start, after requires selected.start >= other.end, inside requires full containment. All use strict </> so boundary-touching passes — this matches the documented "at or before / at or after" contract. Single-match enforcement (matched no spans / matched N spans) and the non-mapping guard are correct and covered by tests.
  • Parent containment (_parent_expectation_errors): correctly returns span-expectation errors first and only then checks the child timespan against the parent, using the Span models via the new span_models_by_id map. The serialized spans_by_id is still built and passed to _link_expectation_errors, so link matching is unaffected.
  • Key filtering: expected_properties now excludes before/after/inside (via _TEMPORAL_RELATION_KEYS) in addition to links/parent, so relation keys aren't misreported as missing span properties.
  • Whole-trace check: start_time > span.end_time uses strict >, allowing zero-duration spans, consistent with the documented start_time <= end_time rule. All timestamps are UTC-aware (parse_timestamp normalizes; fixtures use datetime.now(UTC)), so comparisons are safe.
  • Indexing: selected_span_index is the global span index and matches enumeration over zip(trace.spans, spans, strict=True); the equal-length invariant holds since spans is derived from trace.spans.
  • Test reconciliation: the 6-error violation test reconciles exactly (2 before/after, 2 inside, 2 parent-containment); the valid-case and invalid-selector tests are accurate. The _trace() fixture was widened so existing parent: assertions still pass under the new containment rule (no in-repo regression).

Residual risk (not a defect — intended per PR description):

  • Enforcing strict parent time-containment on every existing expect.parent assertion (used across otel-1..otel-18) and the whole-trace start_time <= end_time invariant now applies to real SDK telemetry. Cross-process clock skew or backend timestamp rounding could produce sub-millisecond containment/ordering violations that manifest as conformance failures. This is the documented goal ("require asserted parents to contain the complete child timespan"), so no change is requested — but there is no tolerance/skew allowance, and no test exercises near-boundary skew. If real backends surface flaky failures, a configurable tolerance would be the mitigation.
  • Spans referenced only via before/after/inside are not added to covered_span_indexes, so they don't satisfy require_all_spans. This is consistent with the existing parent/links behavior and appears intentional.

Reviewed commit cc1d5fbebf328c2d4cdbc437021997385d3a1bb5. Workflow run

@zhongkechen
zhongkechen merged commit 2f3ff9b into main Jul 24, 2026
13 of 15 checks passed
@zhongkechen
zhongkechen deleted the codex/span-timestamp-assertions-main branch July 24, 2026 23:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants