Files
narratio/docs/roadmap/remediation.md

105 lines
5.4 KiB
Markdown

# Transcription Checkpoint Review Remediation
Status: Complete.
Reviewed commits `7b0bf99` through `96b4e73` against the speaker-checkpoint and
upload-replay roadmap and the original user request. No production changes were
made during review. The two failures below were reproduced with temporary tests
using the existing stage fixtures; those temporary tests were removed afterward.
## 1. Reconcile Aggregate State Even When No Speaker Needs HTTP Work
Priority: P2. Status: Complete.
Implemented read-only aggregate identity/evidence checks before resume skips.
Regression tests cover removed inputs, missing/duplicate/mismatched outputs,
repair without HTTP requests, downstream invalidation, and exclusion of removed
speakers from merge without deleting their files. Equivalent path forms and
output ordering remain reusable. Focused app/stage tests and documentation
checks pass.
Location: `internal/stage/transcribe_resume.go:21` and the reconciliation result
consumed there.
`ValidateResume` returns reusable whenever `reconciliation.work` is empty. That
only establishes that the remaining speakers need no transcription; it does
not establish that the stored speaker collection and aggregate outputs match
the current input set. Removing a speaker while the remaining inputs are
unchanged produces an empty work list, so a succeeded record can be skipped
without pruning the removed speaker. Its old aggregate output can then remain
available to merge. Likewise, missing/inconsistent aggregate output references
are not repaired when all individual checkpoints remain valid. A prepare rerun
may already stale transcribe in some workflows, but the resume validator cannot
rely on that to satisfy its own current-input/output checks.
Reproduction: create complete alice/bob checkpoint records and aggregate
outputs with the existing fixture, mark the stage succeeded, remove bob from
the manifest's audio inputs, and call `ValidateResume`. It returns reusable
despite still retaining bob in the stored collection and aggregate outputs.
Required change:
- Distinguish no HTTP work from no reconciliation work. Validate that the
committed speaker set and aggregate transcript references represent the
reconciled current set, including relevant identity/evidence, before skipping.
- When only collection/output repair is needed, return non-resumable and let
normal execution checkpoint the pruned collection and rebuild aggregate
outputs without retranscribing reusable speakers. Preserve existing dependent
invalidation; do not force otherwise-current speaker jobs.
- Keep resume inspection read-only. Do not fix this by deleting incidental
transcript files or changing stage selection rules.
Verification: add removed-only input coverage (not just removal combined with
an added speaker), plus incomplete/inconsistent aggregate output coverage.
Exercise the runner skip path and assert zero additional WhisperX requests,
correct rebuilt outputs, and no removed speaker reaching merge.
## 2. Remove the Unrequested Positive Audio-Size Requirement
Priority: P2. Status: Complete.
Audio evidence now permits zero size while still rejecting negative values.
Regression tests verify zero-size manifest round trips, successful service
results being checkpointed and reused, and service rejection being propagated
without creating a completion record. Nonempty valid-JSON output validation is
unchanged. Both new success regressions failed before the fix.
Location: `internal/manifest/transcribe_state.go:95`.
The new record validator requires `AudioSize > 0`. Previously Narratio accepted
a regular `.flac` file and delegated transcription acceptance to WhisperX;
neither the user request nor the roadmap introduced minimum audio size or a new
audio-content validation policy. Zero-byte content still has a valid checksum
and can be represented by the checkpoint mechanism. The current check runs
after a successful response and output materialization, causing the entire
stage to fail instead of retaining the completed work.
Reproduction: prepare one speaker, replace its prepared audio with an empty
regular file, and use the existing successful fake WhisperX client. Stage
execution fails at checkpoint validation with `audio_size must be positive`.
This demonstrates the extra Narratio restriction; it does not assert that a
particular production WhisperX deployment accepts empty audio.
Required change:
- Permit zero audio size and reject negative sizes. Keep byte hashing and
size equality checks. Let the downstream service decide whether the input
can be transcribed, as before.
- Do not remove the nonempty valid-JSON output requirement, which has a separate
existing justification. Do not add a new early empty-audio rejection instead.
- Update any new tests/documentation that promote strictly positive input size
to a contract.
Verification: cover a zero-size record round-trip and successful adapter result
being checkpointed/reused for that input; retain negative-size rejection and
ordinary downstream-failure tests.
## Verification After Remediation
Completed on 2026-09-22 with Go 1.26.8: focused stage/application tests,
changed-package race tests, `go test ./...`, `go test -race ./...`,
`go vet ./...`, `go build ./...`, `go test ./internal/doccheck`,
`go test ./internal/config -run '^TestExamplesLoadAndValidate$'`, and
`git diff --check` all passed. Existing replay and cancellation regression
tests remain intact; the HTTP adapter required no changes.