# Changelog of CUIT Lookup — AFIP Argentine Taxpayer Registry Search (`mfapitools/cuit-lookup`) Actor

- **URL**: https://apify.com/mfapitools/cuit-lookup/changelog.md
- **Full Actor documentation**: https://apify.com/mfapitools/cuit-lookup.md

## Changelog

All notable changes to this actor will be documented here.

Format: `YYYY-MM-DD | version | description | author`

***

2026-07-23 | 0.1.0 | Initial build — CUIT Lookup actor (bulk-ingest AFIP padrón, two modes refresh/lookup, sharded KVS index, PPE for found records) | builder-agent
2026-07-23 | 0.1.2 | Orchestrator review fixes: check-digit 10→9 mapping (standard AFIP mod-11 — old code wrongly rejected valid CUITs), corrupt-index guard now counts records-found with ≥5 threshold (old version false-FAILED pre-monetization all-valid runs), removed unused import. Regression test added (48/48 green). Re-validated on platform (2 found + 1 not-found, exit 0) | OpenCode (orchestrator)
2026-07-24 | 0.1.4 | Refresh cost guard (pricing-review-2026-07.md #1, engineering-only — no pricing change): added `minRefreshAgeHours` (default 72) + `forceRefresh` inputs; `refresh` now skips download/re-ingest and exits with a `skipped:true` dataset row if the stored index is already fresher than the threshold, cutting a repeat-refresh from a measured $0.0538/158.5s ingest to a measured $0.00058/2.3s skip (~93x). Extracted pure `shouldSkipRefresh()` decision function to `index-store.ts` for testability. Capped `cuits` input array at 100,000 entries (lookup cost was already bounded by the explicit list; this just bounds the list itself). Memory: measured `memMaxBytes` on the real production refresh run (35HnuojqelLGJnUd2) is ~3.26GB out of the 4096MB allocation (~80% utilized) — left `defaultMemoryMbytes` unchanged at 4096; lowering it risks OOM on the ingest path with no validation budget to spare. Fixed a pre-existing invalid example CUIT in `input_schema.json` prefill (`20-27841710-5` fails mod-11 check-digit; replaced with a real, valid padrón record `27-27841710-2`) — the live platform `exampleRunInput` still has the old value pending an owner console update (blocked from direct API mutation by design). Tests: 48→61 green. Platform-validated: 2/2 runs (guard skip: exit 0, $0.00058, 2.3s; lookup regression: 1 found + 1 not-found + 1 invalid-skipped, charged correctly, exit 0, $0.00047). Pricing proposal for a future charged `index-refresh` event written to `handoff/cuit-lookup-pricing-proposal.md` (proposal only, no pricing changed). | Claude Sonnet (builder agent)

2026-07-24 | 0.1.6 | Wired `index-refresh` PPE charge on completed (non-skipped) refreshes (safe no-op until the owner configures the event in Console — uncharged events log a warning and return chargedCount 0). Guard-skipped refreshes never charge. Also fixed the live platform exampleRunInput via API (valid CUIT 27-27841710-2 replacing invalid 20-27841710-5). 61/61 tests. | Claude Fable 5 (orchestrator)

2026-07-25 | 0.1.8 | **Root-cause fix for `publicActorRunStats30Days` showing 2 FAILED / 0 SUCCEEDED external runs.** Cause: named KVS stores are scoped per Apify account, so every first-time customer's account starts with a completely empty `cuit-lookup-index`; the default run mode is `lookup`, so a brand-new user starting the actor with the example input hit `Actor.exit({exitCode:1, statusMessage:'No index found. Run mode=refresh first...'})` before ever seeing a result. Confirmed this is the actual bug (not just a plausible theory) via a full mocked-platform regression test that fails against the pre-fix code with the identical exitCode/statusMessage, and passes against the fix (a literal live-platform reproduction by clearing the production KVS index was attempted but blocked by the execution sandbox's destructive-action guard). Fix: `lookup` mode now auto-bootstraps the index inline (same ~150s ingest `refresh` runs explicitly, never charged) the first time it finds no `metadata` key, instead of failing — extracted the download/parse/shard/write logic shared by both modes into `ingestPadron()`. `defaultRunOptions` (3600s timeout, 4096MB memory) were already sized for the ~155s/~3.26GB ingest, so no run-options change was needed. Updated README + input schema to describe the new auto-bootstrap behavior (previously said "you must run refresh first"). Added `tests/lookup-bootstrap.test.ts` — 3 new integration-style tests driving the real `src/main.ts` against a mocked Apify SDK + network + a real zip.js-built fixture zip: (1) cold-account bootstrap now succeeds and returns real results, (2) warm path with an existing index is unaffected, (3) a genuine download failure during bootstrap still surfaces a clear `exitCode: 1` rather than crashing. 61→64 tests, all green. Deployed as build 0.1.8; platform-verified with a fresh default-input run (see LOG.md/handoff for run id). | Claude Sonnet (builder agent)
