Skip to content

feat(schemas): add discriminated union to QualityMetricsSchema#51

Merged
EdwardIrby merged 2 commits intomainfrom
feat/add-discrimination-union-to-QualityMetricsSchema
Feb 11, 2026
Merged

feat(schemas): add discriminated union to QualityMetricsSchema#51
EdwardIrby merged 2 commits intomainfrom
feat/add-discrimination-union-to-QualityMetricsSchema

Conversation

@EdwardIrby
Copy link
Member

Summary

  • Adds type: z.literal('run') discriminator to QualityMetricsSchema and type: z.literal('trial') to TrialsQualityMetricsSchema
  • Aligns quality metrics with the existing discriminated union pattern used by ReliabilityMetricsSchema / TrialsReliabilityMetricsSchema
  • Eliminates the need for custom type guards — consumers can now narrow with metrics.type === 'run' or metrics.type === 'trial'

Closes #50

Test plan

  • bun run check passes (type-check, lint, format)
  • bun test passes (563 tests, 0 failures)
  • New assertions verify type: 'run' in compare-statistical.spec.ts
  • New assertions verify type: 'trial' in compare-trials.spec.ts
  • Confirmed discriminator pattern matches ReliabilityMetricsSchema

🤖 Generated with Claude Code

…alsQualityMetricsSchema

Add `type: 'run'` to QualityMetricsSchema and `type: 'trial'` to
TrialsQualityMetricsSchema, aligning with the existing discriminated
union pattern in ReliabilityMetricsSchema. This enables TypeScript
narrowing without custom type guards.

Closes #50

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Migrate rules from separate .agents/rules/*.md files to inline content
in AGENTS.md between PLAITED-RULES markers, matching the new approach
in @plaited/development-skills 0.8.0. Remove now-unused .claude/rules
and .cursor/rules symlinks.

Dependency updates:
- @plaited/development-skills 0.7.0 → 0.8.0
- @biomejs/biome 2.3.12 → 2.3.14
- @types/bun 1.3.6 → 1.3.9

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Feb 11, 2026

Review Summary

Approved - This is a clean, well-tested enhancement that improves type safety and consistency.


Code Quality

Strengths:

  • ✅ Perfectly aligns with existing pattern in ReliabilityMetricsSchema / TrialsReliabilityMetricsSchema
  • ✅ Adds discriminator fields to both QualityMetricsSchema (type: 'run') and TrialsQualityMetricsSchema (type: 'trial')
  • ✅ Comprehensive test coverage with new assertions in both test files
  • ✅ TSDoc comments appropriately updated
  • ✅ Follows core conventions: proper TypeScript, clean diff, minimal changes

Implementation correctness:

  • The schemas remain separate (not merged into z.discriminatedUnion) because they're used in different contexts:
    • QualityMetricsSchemaComparisonReport.quality (schemas.ts:812)
    • TrialsQualityMetricsSchemaTrialsComparisonReport.quality (schemas.ts:1056)
  • This matches the reliability metrics pattern exactly

Test Coverage

Excellent coverage

  • New assertions in compare-statistical.spec.ts:809-812 verify type: 'run'
  • New assertion in compare-trials.spec.ts:480 verifies type: 'trial'
  • All 563 tests passing per PR description
  • Tests verify the discriminator at the output boundary (after computation)

Best Practices Compliance

Checked against .agents/rules/:

Rule Status Notes
core.md Uses type (not interface), proper TSDoc, no violations
testing.md Uses test(), clear assertions, both code paths tested
accuracy.md Implementation verified against existing ReliabilityMetrics pattern
modules.md No new files, clean edits to existing modules
documentation.md TSDoc comments properly describe discriminators

Potential Improvements (Optional)

Consider for future (not blocking):

  1. Type narrowing helper - While the discriminator enables manual narrowing, consumers might benefit from a helper:

    export const isRunQuality = (m: QualityMetrics | TrialsQualityMetrics): m is QualityMetrics => m.type === 'run'
    export const isTrialQuality = (m: QualityMetrics | TrialsQualityMetrics): m is TrialsQualityMetrics => m.type === 'trial'

    However, this assumes consumers receive both types in a union, which may not be the common case.

  2. Migration guide - If this is consumed by external projects, a changelog entry documenting the new required field would help downstream consumers update their parsers.


Security & Performance

  • ✅ No security concerns (pure schema changes)
  • ✅ No performance impact (single field addition)
  • ✅ No breaking API changes (additive only)

Final Verdict

This PR is ready to merge. It successfully addresses issue #50 by adding type discriminators to quality metrics schemas, making them consistent with reliability metrics and improving TypeScript developer experience.

The implementation is minimal, well-tested, and follows all repository conventions.


Files reviewed:

  • src/schemas/schemas.ts - Schema definitions
  • src/pipeline/compare.ts - Run quality metrics computation
  • src/pipeline/compare-trials.ts - Trial quality metrics computation
  • src/pipeline/tests/compare-statistical.spec.ts - Run metrics tests
  • src/pipeline/tests/compare-trials.spec.ts - Trial metrics tests

🤖 Review performed by Claude Sonnet 4.5

@claude
Copy link

claude bot commented Feb 11, 2026

PR Review: Add discriminated union to QualityMetricsSchema

Summary

This PR adds type discriminators (type: 'run' and type: 'trial') to quality metrics schemas, aligning them with the existing reliability metrics pattern. The implementation is clean, well-tested, and follows repository conventions.


✅ Code Quality

Strengths:

  • Perfect consistency with existing ReliabilityMetricsSchema / TrialsReliabilityMetricsSchema pattern (schemas.ts:694-696, 882-884)
  • Minimal, focused changes - only touches necessary files
  • Proper TSDoc comments for new discriminator fields
  • Follows all core conventions (type over interface, arrow functions, PascalCase)

Implementation:

  • QualityMetricsSchema gets type: z.literal('run') (schemas.ts:794-795)
  • TrialsQualityMetricsSchema gets type: z.literal('trial') (schemas.ts:947-948)
  • Discriminators added at computation sites:
    • compare.ts:368 - run quality metrics
    • compare-trials.ts:265 - trial quality metrics

✅ Test Coverage

Excellent coverage:

  • New assertions in compare-statistical.spec.ts:809-812 verify type: 'run'
  • New assertion in compare-trials.spec.ts:482 verifies type: 'trial'
  • Tests verify discriminators at output boundaries (after computation)
  • All 563 tests passing (per PR description)

Pattern validation:
Both test files now verify discriminators consistently with existing reliability metrics tests.


✅ Architecture & Design

Why separate schemas (not z.discriminatedUnion)?
The implementation correctly keeps schemas separate because they're used in different contexts:

  • QualityMetricsSchemaComparisonReport.quality (schemas.ts:812)
  • TrialsQualityMetricsSchemaTrialsComparisonReport.quality (schemas.ts:1056)

This matches the reliability metrics pattern exactly - schemas are structurally similar but serve different comparison types.

Type narrowing:
Consumers can now narrow with metrics.type === 'run' or metrics.type === 'trial', eliminating need for custom type guards.


🔍 Additional Changes Review

Rules consolidation (AGENTS.md):

  • Deleted individual .agents/rules/*.md files
  • Consolidated all rules into AGENTS.md between <!-- PLAITED-RULES-START/END --> markers
  • Removed symlinks (.claude/rules, .cursor/rules)
  • This aligns with the scaffold-rules skill update (SKILL.md:273-302)

Rationale: Rules are now inline in AGENTS.md for better discoverability and single-source-of-truth maintenance.

Dependency updates:

  • @biomejs/biome: 2.3.12 → 2.3.14
  • @types/bun: 1.3.6 → 1.3.9
  • @plaited/development-skills: 0.7.0 → 0.8.0

These are minor version bumps (patch/minor) - safe to include.


🛡️ Security & Performance

  • ✅ No security concerns (pure schema changes)
  • ✅ No performance impact (single field addition)
  • ✅ Additive change - no breaking API changes

📋 Best Practices Compliance

Checked against .agents/rules/ (now in AGENTS.md):

Rule Status Notes
Bun APIs No Bun API changes
Core conventions Uses type, proper TSDoc, correct naming
Testing Uses test(), clear assertions, both paths tested
Modules No new files, clean edits to existing modules
Documentation TSDoc properly describes discriminators
Workflow Conventional commit format, proper PR structure

💡 Optional Future Enhancements (Not blocking)

  1. Type narrowing helpers - If consumers receive both types in a union context:

    export const isRunQuality = (m: QualityMetrics | TrialsQualityMetrics): m is QualityMetrics => 
      m.type === 'run'

    However, this may not be a common use case based on current architecture.

  2. Migration note - If this library has external consumers, consider documenting the new required field in CHANGELOG.


✅ Final Verdict

LGTM - Ready to merge

This PR successfully addresses issue #50 by:

  • Adding type discriminators to quality metrics schemas
  • Maintaining consistency with existing reliability metrics pattern
  • Improving TypeScript developer experience
  • Including comprehensive test coverage
  • Following all repository conventions

The implementation is minimal, well-tested, and production-ready.


Files reviewed:

  • src/schemas/schemas.ts - Schema definitions ✅
  • src/pipeline/compare.ts - Run quality metrics computation ✅
  • src/pipeline/compare-trials.ts - Trial quality metrics computation ✅
  • src/pipeline/tests/compare-statistical.spec.ts - Run metrics tests ✅
  • src/pipeline/tests/compare-trials.spec.ts - Trial metrics tests ✅
  • AGENTS.md - Rules consolidation ✅
  • package.json / bun.lock - Dependency updates ✅

🤖 Review performed by Claude Sonnet 4.5

@EdwardIrby EdwardIrby merged commit 08ed406 into main Feb 11, 2026
8 checks passed
@EdwardIrby EdwardIrby deleted the feat/add-discrimination-union-to-QualityMetricsSchema branch February 11, 2026 03:28
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.

Add discriminated union to QualityMetricsSchema (like ReliabilityMetrics)

1 participant