Skip to content

Post-migration validation (--validate) - #23

Open
Doug Guthrie (dpguthrie) wants to merge 3 commits into
mainfrom
feat/post-migration-validation
Open

Post-migration validation (--validate)#23
Doug Guthrie (dpguthrie) wants to merge 3 commits into
mainfrom
feat/post-migration-validation

Conversation

@dpguthrie

Copy link
Copy Markdown
Collaborator

Summary

Adds an optional post-migration validation phase. Pass --validate (or MIGRATION_VALIDATE=true) and, after migrating, the tool validates the destination against the source per project:

  • Object parity for project-scoped resources (datasets, experiments, prompts, functions, project_scores, views, project_tags, span_iframes): compares source vs destination and reports the specific items missing in the destination.
  • Event count-parity for datasets, experiments, and logs: compares a cheap count of events per dataset/experiment and per project for logs.

Results are summarized per resource in the console (mismatches listed, with a pointer to the full report) and recorded under each project's validation block in migration_report.json.

Design notes

  • Mirrors migration policy — intentionally skipped items (e.g. bundle-backed code functions) are not reported as missing — and honors the same --created-after/--created-before window.
  • Matching: pairs source→dest via the migration id_mapping when available, falling back to slug/name.
  • Counts only for events: enumerating which events are missing requires diffing full id sets and does not scale. Counts are reported per dataset/experiment/project so a discrepancy can still be localized.
  • Out of scope: roles, groups, ai_secrets, and ACLs.

Implementation

  • validation.py — reusable core (validate_resource, count_events, VALIDATION_SPECS). (committed earlier on this branch)
  • resources/base.py — extracted module-level list_resources() so the core can list resources without a migrator instance; the existing method now delegates.
  • config.pyvalidate_migration field + MIGRATION_VALIDATE env parsing.
  • cli.py--validate/--no-validate option + console validation summary.
  • orchestration.py_validate_project phase + inclusion in the migration report.

Tests

  • tests/unit/test_validation.py — 7 tests for the core.
  • tests/unit/test_validation_wiring.py — orchestrator aggregation, console rendering, and from_env flag parsing.
  • Full suite: 315 passed.

Not yet done

  • Unverified end-to-end against live data (unit-tested only). Can live-verify against the SaaS instances on request, as with prior features.

🤖 Generated with Claude Code

Doug Guthrie (dpguthrie) and others added 3 commits June 8, 2026 16:15
New braintrust_migrate/validation.py provides the reusable validation engine:

- Object parity: list source vs dest for a project-scoped resource, compare,
  and report the specific items missing in the destination (cheap; small N).
- Event count-parity: a single cheap BTQL count() per parent (per dataset /
  experiment / project) compared source vs dest. We do NOT enumerate which
  events are missing — that requires diffing full id sets and doesn't scale;
  counts are reported per parent so a gap can still be localized to an object.

Mirrors migration policy via per-resource specs: functions exclude bundle-
backed code (intentionally skipped), and roles/groups/ai_secrets/ACLs are out
of scope. validate_resource() dispatches by resource name; matching pairs by
slug/name and uses the migration id_mapping when available; counts honor the
same created_after/before window as the migration.

This is the engine only — wiring (a --validate flag, orchestrator phase, and
report/console output) is separate. Tests cover object missing-items, the
function bundle exclusion, event match/mismatch, logs, and the count window.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds the --validate/--no-validate flag (MIGRATION_VALIDATE env), a
validate_migration config field, the orchestrator validation phase
(_validate_project) that runs after each project migrates, inclusion of
the validation block in migration_report.json, and the console summary
rendering. Extracts a module-level list_resources() in base.py so the
validation core can list destination resources without a migrator
instance. Documents the feature in README and CHANGELOG.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Skipping a bundle-backed code function is expected behavior, not a
problem — demote the per-function skip log from warning to info so it
doesn't surface as noise during normal migrations.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant