# Changelog of CRM Contact Cleanup & Duplicate Review (`critd/contact-cleanup`) Actor

- **URL**: https://apify.com/critd/contact-cleanup/changelog.md
- **Full Actor documentation**: https://apify.com/critd/contact-cleanup.md

## Changelog

All notable changes to this actor are recorded here.

### 4.1.0 (2026-09-23)

- Distinguish no possible matches from matches omitted by the review display limit; clarify the Contact 4.0 input-name migration and add direct starts and pre-run help.

### 4.0.0 (2026-09-23)

- Rename the inactive `dedupeKeyMode` input to `legacyMatchMode`. Its accepted values, default, prefill and lack of effect on cleanup, matching and charging are unchanged.
- This is a breaking hosted-schema change: callers using the old field must rename it or continue selecting the retained 3.2.1 build. The Rust input parser retains the old spelling for historical fixtures, but Apify validates the published schema before execution. Candidate status and any warning clearance are recorded separately.

### 3.2.0 (2026-09-22)

- Updated the product name and getting-started guide to explain the review workflow, included results and pricing more clearly. No cleanup, matching, research or charging behavior changed.
- Clarify the first-file check, separately tested capacity profiles, per-accepted-row base pricing and input/result privacy boundaries.
- Label legacy form controls as inactive while preserving accepted API values, defaults, prefills and validation. The installed schema validator requires their enum editors to remain visible.
- Lead the read-only review page with complete-file links, original-versus-suggestion guidance and the customer's approval-to-import step. Label record listings and rows requiring decisions accurately.
- Align support guidance around run IDs, redacted descriptions and fictional examples. These source changes are not a hosted release.

### 3.1.0 (2026-09-18)

- Documentation follow-up, September 22: correct the API/task integration recipe to describe both encrypted inline fields and the separate file, source-storage, output and historical-input boundaries. No schema, runtime or charging change.
- Add a worked approval-to-import handoff with explicit human decisions, original-column CSV, unresolved destination blockers and independent cell verification. Preserve every source row and do not imply automatic merging or a completed CRM import.
- Qualify the 5%/15%/25% Store discount ladder and exact spending-cap boundaries without changing the base price or per-row event. Activation and settlement are recorded separately.
- Verify secret-input failures stop before storage effects; retain encrypted inline input and explicit file/output privacy boundaries.

### 3.0.0 (2026-09-16)

- Encrypt both inline input arrays using Apify secret JSON editors. Literal submitted JSON and outputs are unchanged; direct readers of stored INPUT.records must handle ciphertext. Never replay ciphertext into another run.
- Prioritize confidential/file routes and add labeled column-mapping controls without changing the four-key API map.
- Add a short first-file walkthrough, downloadable fictional input, price examples and integration recipes. Keep full technical reference collapsed and recovery/privacy guidance visible.

### 2.2.0 (2026-09-15)

- Choose the fictional example or a real data route directly in the native form. Existing API and saved inputs remain compatible. Field/row errors provide repair guidance without input values.
- Accept the native form's unchecked preview checkbox on explicitly selected example and inline routes; a checked source-only preview remains an error on those routes.
- Add a bounded, static Contact review page and versioned focused candidate JSON. Combine matching reasons into unique pairs, retain differences and shared-mailbox caveats, and exclude domain-only context. Display limits disclose omitted work; original import cells and raw groups remain unchanged.
- Prepare review files before billable Dataset writes, without new charge events. Failed review publication stops without retrying Dataset effects.

Source candidate; hosted acceptance, quality recommendation clearance and discount activation remain separately recorded.

### 2.1.0 (2026-09-14)

- Read a resolved event price from the current run for spending preflight; reject
  unresolved tier maps. Keep automatic Dataset-item charging and expose whether
  the estimate came from run pricing or a local fixture price.

- Preserve extra inline fields through the published schema; make storage
  pickers and sample-to-source instructions explicit. Route errors explain how
  to remove conflicting sample input without echoing supplied values.

- Bound platform input reads, reject invalid UTF-8, and avoid unbounded splitting
  of malformed encrypted envelopes. Input encryption still does not encrypt outputs.

- Patch Rustls to 0.23.45 for RUSTSEC-2026-0285 (TLS record-boundary validation).

Source candidate; hosted publication and discount activation are recorded separately.

### 2.0.0 (2026-07-27)

#### Confidential inline input (2026-08-13)

- Added the optional Apify-encrypted `confidentialRecords` lane without
  removing plaintext `records` or any source route. Exactly one nonempty lane
  is accepted, and both inline lanes enter the same Contact 2.0 workflow.
- Kept the existing 12-row Console prefill, smoke input, output/storage
  contracts, per-Dataset-item billing semantics, Cargo `2.0.0`, and Actor
  version `2.0` unchanged.
- Documented that secret-input encryption protects stored run input, not
  Dataset/KVS/OUTPUT results, retention, deletion, or portable ciphertext
  replay.

#### Buyer surface refresh (2026-08-11)

- Reordered the README around the start path, four workflow files, human review
  boundary, inspect-first recovery, and migration so buyers can reach the
  decision path before implementation detail.

- Added a dated point-in-time Store price/unit statement, explicit
  no-maximum-invoice boundary, and a privacy-safe support diagnostic checklist
  without claiming response time, delivery, or an SLA.

- Aligned Cargo `2.0.0`, Actor version `2.0`, remote Actor-version request
  identity `2.0`, and `contact-cleanup-output-v3`.

- Made the v3 whole-file workflow the sole production entry in this source
  package. The retained v2 behavior is hidden behind an explicit historical
  compatibility test/fixture harness and is not a buyer runtime selector.

- Reframed the package around four discoverable buyer files:
  `CLEANED_CONTACT_REVIEW.csv|json`, `RECORDS_TO_REVIEW.json`,
  `POSSIBLE_MATCH_GROUPS.json`, and `RUN_SUMMARY.json`.

- Added a step-by-step route, field-mapping, preview, export-mode,
  export-format, review, reimport, and recovery guide without implying
  verification, deliverability, automatic merge, or survivor selection.

- Froze documentation examples from the committed 12-row smoke input through
  the maintained whole-file runtime rather than maintaining independent
  hand-authored output claims.

- Corrected the supported buyer ceiling to the selected machine-qualified
  separate profiles of 1,000 accepted rows at 6 source fields and 261 source
  fields at 12 rows; their cross-product was not qualified. The retained 10,000-row
  parser/runtime guard is not marketed as supported: that qualification
  candidate failed before Dataset publication at the single-record KVS
  boundary.

- Documented exact same-format preservation and replay boundaries, including
  compact JSON-text encoding for JSON-origin values in CSV cells and native
  source value types in JSON exports.

- Added GET-first recovery guidance for deterministic rejection, unknown
  Dataset commit, final `OUTPUT` uncertainty, and hard process death. No
  caught-failure state authorizes blind replay.

- Recorded the selected local configured estimate of `$0.100000` for 1,000
  synthetic Dataset-item event units and kept it explicitly separate from
  current live pricing, a bill, or settled charged-event proof. The separately
  reserved `$0.125000` later-test cap candidate is not a price or run
  authorization.

- Kept deployment, Store availability, pricing, and rendered Console state out
  of this source-package history; those remain point-in-time Apify
  observations.

#### Migrating from 1.0

- Existing input shapes remain accepted with deterministic v3 workflow
  defaults; compatibility fields are not runtime-version selectors.
- The Dataset is now an accepted-row review projection. Use the KVS cleaned
  artifact for whole-file reimport, and use `RECORDS_TO_REVIEW.json` for blank
  or rejected source identities.
- The KVS package now includes the cleaned file, focused review queue,
  possible-match groups, and run summary before final `OUTPUT`.
- `OUTPUT` now uses `contact-cleanup-output-v3` and follows acknowledged KVS
  artifacts and Dataset batches. On caught failures, inspect KVS, Dataset, and
  `OUTPUT` before any retry because commit state may be unknown.

### 1.0.0 (2026-05-20)

- Scheduled the public Apify Store billing model to move from free
  pricing to Pay Per Event at `$0.10 / 1,000` default dataset rows,
  effective June 3, 2026 at 18:20 UTC after Apify's required notice
  window.
- Uses Apify's synthetic `apify-default-dataset-item` event for the
  scheduled price, so each emitted cleanup row will be the billing unit
  and no custom runtime charge call is required.
- Updated buyer-facing pricing guidance to explain that invalid,
  review-needed, and no-actionable rows are still emitted rows and count
  toward the per-row charge after the scheduled price takes effect.
- Kept runtime cleanup behavior, inputs, dataset rows, structured
  `OUTPUT`, and unsupported-capability boundaries unchanged.

### 0.1.0 (2026-04-25)

- Added the initial repo-local `contact-cleanup` aggregate runtime for
  supplied-record URL, email, and U.S.-leaning address cleanup.
- Added one-row-per-input dataset rows with `recordStatus`, grouped
  normalized values, changed fields, review flags, dedupe keys,
  same-run candidate labels, cross-field signals, warnings, invalid
  reasons, and processing metadata.
- Added structured `OUTPUT` summaries with
  `schemaVersion = "contact-cleanup-output-v1"`, selected controls,
  row counts, diagnostic summaries, first-release limits, and explicit
  unsupported-capability booleans.
- Added the repo-local Actor manifest, input schema, deterministic
  smoke input, dataset schema, output schema, and key-value-store
  schema.
- Added the technical README and changelog contract, with manifest
  links to both local files.
- Added the local benchmark fixture and baseline, plus factory registry
  and source-foundation metadata for the aggregate package.
- Added factory control-plane placeholders so release, publication,
  monitoring, operations, frugality, pricing, and legacy-disposition
  evidence can be tracked outside the runtime changelog.

#### Store-surface documentation notes

- Polished the README first screen and body around supplied-record
  cleanup, row preservation, review routing, dedupe/match-key
  preparation, pay-per-usage/no-custom-charge posture, and explicit
  no-verification, no-enrichment, no-merge boundaries.
- Added the fixture-backed output examples and support interpretation
  pack under `docs/output-examples.md`.
- Added repo-owned Store icon source/raster assets and factory
  publication-contract references for icon, categories, and SEO
  metadata.
- Kept publication, Store pricing, recurrence, workflow ownership, and
  legacy Actor disposition out of runtime release notes unless they
  change user-visible package behavior.
