# Reporter SDK

Truthound 3.0 reporters are authored against `ValidationRunResult`.

The recommended authoring path is:

1. Implement `render(run_result, *, context)` through `ValidationReporter`.
2. Build shared structure from `RunPresentation`.
3. Use `legacy_view = self.present(run_result).to_legacy_view()` only when you need compatibility-era row helpers inside a reporter implementation.

Scaffolding generated by `truthound scaffold reporter` targets the v3 contract directly and does not import persistence DTOs from `truthound.stores.results`.

For custom plugins:

- Canonical input: `truthound.core.ValidationRunResult`
- Shared presentation model: `truthound.reporters.presentation.RunPresentation`
- Migration helpers: `truthound.reporters.sdk.compat`
- Canonical plugin contract: `Reporter.render(run_result, *, context)`

Reporter authors should optimize for the shared presentation model instead of re-deriving summary logic from raw issues. That keeps built-in reporters, validation docs, and plugin reporters aligned.

Use `truthound doctor --migrate-2to3` to detect old `Report` assumptions before upgrading an existing reporter package.

Related references:

- [Architecture](../concepts/architecture.md)
- [Plugin Platform](../concepts/plugins.md)
- [Migration to 3.0](migration-3.0.md)
