Problem
The bounded SQLite task-ledger reader maps decoding/schema failures to ReadLaneError::Unavailable. The CLI then tells the operator to ensure the daemon is installed or restore daemon health, which obscures an incompatible persisted event/schema.
This was observed with installed ATM CLI/daemon binaries reporting 1.5.14, querying a live database already migrated to the Phase BA (BA.2) schema. That binary/schema mismatch is tracked by #1409; this issue isolates the error-classification gap and targets develop, outside the Phase BA implementation scope per Fenix's assessment: #1409 (comment).
Evidence and root cause
crates/atm-storage-rusqlite/src/task_ledger_reader.rs wraps row decoding errors with sqlite_error(..., "failed to decode async task event", ...), then read_lane_error(error: AtmError) unconditionally constructs ReadLaneError::Unavailable { message: error.message().to_owned() }.
A persisted event that the installed binary cannot decode therefore yields exit 4 and:
bounded mailbox reader lane request failed
Recovery: Ensure atm-daemon binary is installed, then restore the single local daemon to a healthy serving state and retry.
The original live repro commands were:
atm list --team atm-dev --task-events BA1-FIX-R2-1789162822 --json
atm list --team atm-dev --task-events BA2-TASK-IDENTITY-QUEUE-SOLAR-1789162312 --json
The backend was reachable; repeated requests hit incompatible event data. Restart advice did not identify the binary/schema mismatch. No production task writes are necessary to reproduce this failure class: seed an unsupported event or incompatible schema in an isolated test database.
Proposed change
Preserve typed decoding/schema-incompatibility errors across the storage reader, contract/API, and CLI boundary. Use a distinct stable machine-readable classification with actionable version/schema recovery context. Reserve unavailable/outage classification for actual availability failures. Do not relabel unrecognized events as success or recommend database restoration without explicit operator review.
No implementation branch is proposed yet. The local codex/task-event-reader-fix / 12f9eb3a0 patch from #1409 does not fix this classification and is superseded by Phase BA for the event-vocabulary mismatch.
Acceptance
- A reachable fixture database with an unsupported event/schema yields a distinct decoding/compatibility error, not a daemon-outage error.
- The classification and cause survive the bounded async reader, API response, and CLI output.
- Actual daemon unavailability and timeouts retain their appropriate classifications.
- Valid Phase BA events remain readable with the matching Phase BA binary/schema pair.
- Add regression coverage for these distinct paths and document the recovery guidance.
Problem
The bounded SQLite task-ledger reader maps decoding/schema failures to
ReadLaneError::Unavailable. The CLI then tells the operator to ensure the daemon is installed or restore daemon health, which obscures an incompatible persisted event/schema.This was observed with installed ATM CLI/daemon binaries reporting 1.5.14, querying a live database already migrated to the Phase BA (BA.2) schema. That binary/schema mismatch is tracked by #1409; this issue isolates the error-classification gap and targets develop, outside the Phase BA implementation scope per Fenix's assessment: #1409 (comment).
Evidence and root cause
crates/atm-storage-rusqlite/src/task_ledger_reader.rswraps row decoding errors withsqlite_error(..., "failed to decode async task event", ...), thenread_lane_error(error: AtmError)unconditionally constructsReadLaneError::Unavailable { message: error.message().to_owned() }.A persisted event that the installed binary cannot decode therefore yields exit 4 and:
The original live repro commands were:
The backend was reachable; repeated requests hit incompatible event data. Restart advice did not identify the binary/schema mismatch. No production task writes are necessary to reproduce this failure class: seed an unsupported event or incompatible schema in an isolated test database.
Proposed change
Preserve typed decoding/schema-incompatibility errors across the storage reader, contract/API, and CLI boundary. Use a distinct stable machine-readable classification with actionable version/schema recovery context. Reserve unavailable/outage classification for actual availability failures. Do not relabel unrecognized events as success or recommend database restoration without explicit operator review.
No implementation branch is proposed yet. The local
codex/task-event-reader-fix/12f9eb3a0patch from #1409 does not fix this classification and is superseded by Phase BA for the event-vocabulary mismatch.Acceptance