Monitoring · Coverage and recovery ·
When a rejected assessment stopped a company from being monitored
TickerTrac checks new evidence against an investor's saved reasons for following a company. On October 13, 2026, the daily job completed while leaving two companies unchecked. The run record named both failures. The rest of the sweep could finish under the existing tolerance policy, so a completed job did not mean complete coverage.
The cause was a rejected model response. The consequence was much larger: each rejection rolled back the company's entire check, including unrelated news and prices. Its checkpoint stayed put, which offered the same troublesome filing again on the next run. The next retry could therefore reproduce the same rollback.
I run TickerTrac as a solo project and use Codex and Claude Code for implementation and investigation. This case comes from that work, including a correction found during review. It concerns the project's own monitoring, with no customer-scale reliability claim.
Incident on October 13; recovery observed on October 14, 2026.
Reproducing the failure changed the fix
The rollback policy had a useful purpose. If an assessment failed during a company's check, rolling back prevented an incomplete transaction from claiming success. Reports that had completed successfully carried receipts; reports without receipts could be retried.
That policy assumed the next attempt could succeed. Here, the end-of-sweep retry failed on the same documents. Keeping the checkpoint unchanged then preserved the input that caused the rejection.
The first proposed repair relaxed several parsing rules that might explain the failure. The change was written before anyone had seen the rejected responses, which had not been retained. A bounded reproduction used three model calls, with an estimated usage cost of about two cents, to rebuild the source and request contexts from retained inputs. Both failing contexts matched their original fingerprints, and the reproduced responses exposed a different cause: an unknown novelty judgment, meaning the model could not say whether the evidence was new or already seen. The parser rejected that uncertainty even on neutral, unrelated answers.
The repair kept that uncertainty explicit. It accepted those non-alerting answers without weakening the requirements for an answer that could alert a reader. The captured responses then passed an offline replay without additional model calls. The original raw responses had not been retained, so this established a matching-context reproduction, not a byte-for-byte recovery of the incident's output.
The parser correction addressed the reproduced failure. The transaction policy also needed to survive a future rejection.
Keep completed work and expose the gap
Relaxing the parser alone would leave the rollback mechanism in place for the next unexpected output. Silently skipping the report would hide a coverage gap. I kept the company in the sweep, recorded the unresolved assessment and made the checkpoint claim only completed work.
An unparseable report assessment now leaves an explicit coverage gap and earns no completion receipt. Other completed work for that company can commit. The filing checkpoint remains at the earliest failed filing's day, so the next sweep can offer that report again while deduplicating completed reports by their receipts.
This changes what success means. A company can finish with partial coverage, and its digest says it could not be fully checked. The unresolved assessment stays visible and eligible for retry.
There is a residual cost. A later periodic report within the parked checkpoint window can be assessed again because that path does not have the same completion receipts. I accepted and documented that bounded duplicate-work risk. Unexpected exceptions still roll back the company transaction; the change specifically handles an unavailable assessment.
Regression tests cover an older rejected filing followed by a later successful one. They check that the later result and receipt commit, the failed report gets no receipt, and the next sweep retries the unresolved report. Separate cases keep alerting answers subject to the existing validation requirements.
Observe coverage from outside the worker
The incident also exposed a gap in how the daily job was watched. An error tracker can record a rejected assessment. A missed schedule or a killed worker may produce no exception at all. Existing off-host monitoring did not provide the daily sweep's start and coverage outcome.
A job-specific heartbeat now reports a cycle's start and final outcome to an independent receiver. Retries remain part of the same cycle. Completion is reported unhealthy whenever a company was not checked, including a company whose sweep finished with one source unread. A start with no completion inside the receiver's grace period is treated as a failure. That covers a sweep killed mid-run, which a handler inside that worker cannot report.
The heartbeat carries counts and reason codes without company names or thesis text. Its requests are bounded, and receiver failures do not change the sweep's result. It adds a view of execution and coverage; it cannot establish whether an individual investment assessment is correct.
What was observed
The changes shipped before the next ordinary scheduled sweep. That run completed in under six minutes with no unchecked companies. The worker journal separately showed both previously affected companies assessed normally. Nothing was forced or replayed solely to produce this result.
The receiver recorded the real cycle's start at the scheduled minute and its successful completion under six minutes later. Before that run, a dedicated synthetic check moved from down to up after failure and recovery signals. That verified the receiver transitions. The retained receipt did not separately confirm delivery to the human notification channels.
One successful scheduled cycle is a narrow result. It establishes recovery from this incident and a working heartbeat path. It does not prove exhaustive evidence coverage, exactly-once execution or behavior under every worker failure. The regression tests establish the intended handling of a future rejected assessment; the successful production run did not exercise that partial-coverage branch.
The decision I would reuse is to keep a rejected assessment unresolved at the smallest useful boundary. Completed evidence can commit, the gap stays visible, and a retry can return to it without taking the rest of the company out of monitoring.