All notable changes to this Actor will be documented in this file.
- A genuine no-match search no longer FAILS the run.
fleet_status.py
flagged 11 of the last 57 customer runs (30d) FAILED, with our own runs
clean (1/1 SUCCEEDED) — the failures are customer traffic against build
0.1.2. main() raised SystemExit(1) any time the summed row count across
every (query, jurisdiction) pair was zero (spec REQ-8, "fail loud on
zero rows"), charging the customer actor-start and then reporting
FAILED. Reproduced locally: a made-up company name against the live CO
SODA endpoint completes the HTTP request successfully (no retries, no
exception) and still exited 1. This Actor covers only 4 states
(NY/CO/CT/OR) with jurisdictions defaulting to all four, so an ordinary
batch-verify query for a company not registered in any of them is a
legitimate zero-match answer, not a failure — the exact pattern that
already delisted reverb-sold-listings once (see
ops/os/EMPTY-IS-NOT-A-FAILURE-2026-08-19.md).
_fetch_query_jurisdiction now returns (rows, completed) and _run
returns a RunOutcome(total, any_completed). main() only fails loud
when any_completed is False — i.e. every single search errored out
and we never got a real answer from any state host. A completed search
that matched nothing now finishes SUCCEEDED with a status message naming
what was searched.
tests/test_empty_result_succeeds.py — pins the no-match-succeeds
behaviour at both the _run and main() layers, and pins that main()
still fails loud when every search genuinely errors (all state hosts
unreachable), and that the happy path (Done — N entity row(s)) is
unchanged.
- Zero-match "Try for free" trap.
input_schema.json's searchQueries
prefill was "Acme Robotics LLC" — a name that doesn't exist in any of
the 4 state registries (NY/CO/CT/OR), so every customer who ran the
Actor with the default sample input got a guaranteed REQ-8 zero-match
FAILED run. This is the most likely explanation for the 2/2 recent
public-run failures flagged by the daily health report (30-day
publicActorRunStats). Replaced with "Blue Sky Consulting LLC",
verified live against all 4 SODA endpoints to return real matches.
client._get_with_retry never retried network-level exceptions.
design.md's own REQ-5 text says "retry on HTTP 429, 5xx, and
curl_cffi network exceptions", but the implementation only retried
on HTTP status codes — a bare connection timeout/reset talking to any
one of the 4 independent state open-data hosts raised an uncaught
curl_cffi.requests.exceptions.RequestException past
_fetch_query_jurisdiction's except RuntimeError guard and crashed
the entire run (losing results from every other jurisdiction/query in
the same batch). Now caught and retried with the same exponential
backoff as retriable HTTP statuses; only raises RuntimeError (which
the caller already treats as a graceful per-jurisdiction skip) after
MAX_RETRIES is exhausted.
- Scaffold:
.actor/ (actor.json, input_schema.json, output_schema.json,
dataset_schema.json, pay_per_event.json, Dockerfile), src/models.py
(fully implemented ActorInput + Officer + ResultRow), stubs for
adapters.py / client.py / parser.py / main.py (signatures per
design.md, filled in during T04-T08), src/scraper.py (ADR-0004
verifier stub), pyproject.toml, README.md, tests/fixtures/input.qa.json.
- Two PPE events:
actor-start ($0.005), result-row ($0.005).