# Daily PRICE_UNMATCHED manual-price review implementation

## Metadata

- Date: 2026-08-06
- Status: Implemented; integer-input/finalization repair deployed, explicit employee retry pending
- Scope: `artifact_callback/fixed_processor` daily XML path only; legacy `direct_mcp` remains an explicit v3,
  no-review compatibility projection
- Confidence: High; local regression plus the later controlled migration/runtime and exact-XML initial-review acceptance agree
- Last verified: 2026-08-06
- Stale trigger: a later migration, processor/rule change, successful run-67 retry, or new 0805 re-upload

## Implemented boundary

- Active processor/result schemas are v4. A result becomes `review_required` only when its non-empty actionable error
  set is entirely `PRICE_UNMATCHED`; it exits technically successfully with `result.json` and
  `structured-result.json` only, no daily/exception XLSX.
- The review result includes candidate auto-priced rows, grouped normalized `(company, Rate Code, Opera price)` issues,
  existing fixed-price comparisons and aggregate room/room-night impact. It contains no guest name, comment or raw
  trace in the review API/read model.
- Staff PATCH only a verified missing key using a non-negative integer string, including `0`. ARR normalizes it to
  exact `numeric(18,2)` and canonical `.00` manifest text. Case revision, session username, old/new price and timestamps
  are permanently recorded without a free-form note field.
- Finalization freezes canonical JSON bound to job/case/source SHA/business date/processor/rules/full issue key set and
  re-materializes the registered original XML. Processor and independent validator both replay that exact manifest;
  final retained manual rows use `pricing_method=manual_review` and `MANUAL_PRICE_APPLIED`.
- Initial `recorded_review` creates no Finance/rejected version, download, `arr.processing_failed` or monthly event.
  One final atomic success creates/activates Finance lineage and emits `arr.daily_version_committed`. Infrastructure
  errors retain the frozen manifest as `generation_failed`; deterministic final errors fail the case/run.

## Evidence

- `.venv/bin/python -m unittest discover -s tests -p 'test_*.py' -v`: 387 passed, with three intentional skips for a
  private acceptance fixture not bundled in the repository. This includes active v4 behavior and direct-MCP v3
  no-review compatibility.
- `python3 -m unittest tests.test_arr_opera_daily_ingest -v`: 14 passed, including pure-review grouping, mixed-error
  failure, zero-price final replay and package source/archive parity.
- `python3 -m unittest tests.test_arr_ingestion_validation -v`: 7 passed for outer review/manual independent replay.
- `python3 -m unittest tests.test_arr_ingestion_postgres -v`: 16 passed, including source-artifact reload plan, no-Finance
  review receipt and deterministic-final-failure audit path.
- `python3 -m unittest tests.test_arr_programmatic -v`: 5 passed, including original-source `0.00` final replay and
  deterministic finalization failure closure.
- `python3 -m unittest tests.test_arr_web -v`: covers authenticated/CSRF review routes, strict integer grammar and
  privacy-safe response shape. `tests.test_arr_web_job_trace`, `tests.test_arr_web_repository_schema` and migration
  static tests also passed during the implementation run.
- `shasum -a 256 -c CHECKSUMS.sha256` passes after rebuilding byte-identical `.zip`/`.skill`; archive filenames are
  UTF-8-preserved, including `价格对照.xlsx`.
- Browser QA used a temporary localhost fake service: logged in with test-only credentials, opened the review panel,
  rendered candidate/impact fields, saved `0`, finalized to a successful state, and observed no browser console
  errors. No production service, private XML, database or object storage was used.

## Live follow-up

- The authorized follow-up reconciled already-live 016 semantics, corrected and applied 017 after an exact up/down
  rollback probe, fixed a delivery-placeholder defect exposed by the first real attempt, and proved run 65 reaches the
  expected two-key initial-review state with no Finance/event change. See
  `2026-08-06-live-daily-price-review-rollout.md`.
- A later repair changed the operator surface to integer prices, applied additive migration 018 for the omitted
  `manual_override_json` artifact kind, and corrected the Finance INSERT bind count. Latest run 67 remains frozen at
  `200/0` and awaits an explicit employee retry; see `2026-08-06-integer-review-finalize-repair.md`.
- Remaining evidence is Finance-owned finalization: verify run 67's frozen values, retry once, require 153 retained lines
  with two `manual_review` rows and one final daily-commit/monthly event, and leave rejected version 28 unchanged.
