# Read-only rollup drift inventory (epic #3873)

**One-time, agent-supervised diagnostic procedure.** The script inventories
historical Quote and Order headers whose stored rollups disagree with their
current child rows. It performs authenticated `GET` queries only. It has no
execute flag, database connection, maintenance POST, line-item mutation, or
retry path.

This procedure is not a standing utility. Retire it after the historical stock
has passed the normal consistency probe.

## Why execution is not available

The supported `recalculate-rollups` endpoint is synchronous and full-object.
Its current request contract does not carry or atomically verify a server boot
epoch, expected runtime revision, and expected installed-pack generation before
mutation.

A client can attest `/health` and installed-pack identity immediately before a
POST, but a same-revision backend can crash and be restarted automatically
between those requests. Deployment workflow concurrency and a TiDB advisory
lock do not fence that automatic restart. The successor process would have the
same `/health.version` while never having been attested by the client.

For that reason this L2 patch cannot safely invoke the endpoint. The former
dummy OrderItem/QuoteLineItem POST+DELETE workaround is also unavailable: a
normal DELETE is soft, and its audit, recycle-bin, outbox, Flow, and streaming
effects cannot be undone.

## Inventory mechanism

The script:

1. maps the selected environment to one fixed HTTPS origin;
2. rejects redirects before a bearer token can be forwarded;
3. keyset-paginates Quote, QuoteLineItem, Order, and OrderItem through
   authenticated Salesforce v63 query GETs;
4. applies the same `_sum_check` owner used by
   `scripts/probe_derived_field_consistency.py`;
5. fails closed on malformed responses or pagination that does not advance;
6. reports inconsistent parent counts with IDs redacted by default.

## Procedure

Keep the pre-issued read-only bearer token out of shell history:

```bash
export NEXUSCRM_PROBE_TOKEN='<pre-issued bearer token>'

python3 backfill_rollup_touch.py \
  --environment staging --object quote

python3 backfill_rollup_touch.py \
  --environment staging --object order
```

Use `--show-ids` only when an operator explicitly needs record identities.
`--base-url` is optional and, when supplied, must exactly equal the fixed origin
for the selected environment.

## Safety and failure semantics

- Quote and Order are both inventory-only.
- The script accepts only a pre-issued bearer token; it does not create a login
  session.
- Every application request is `GET`; there is no generic request-method
  parameter or hidden write helper.
- Environment names map to fixed HTTPS origins. Redirects are rejected before
  they can be followed.
- A transport error, non-JSON body, missing records array, missing record
  identity, or non-advancing cursor blocks the inventory instead of reporting a
  partial result.
- Failure output never includes request URLs, pagination cursors, response
  bodies, or underlying transport/decode exception text. HTTP failures report
  only the status code.
- IDs remain redacted unless `--show-ids` is explicitly supplied.

## Required platform follow-up

The server owner must add a scoped, resumable maintenance contract that binds a
request to the exact serving process and installed-pack generation inside the
handler before any write. At minimum:

1. expose an immutable boot/serving epoch in the attestation response;
2. require that epoch plus expected runtime revision, pack source revision, and
   pack payload hash on the maintenance request;
3. reject a stale epoch or generation with `409` or `412` before mutation;
4. hold the server-owned Controlplane/catalog mutation fence through the
   precondition check and bounded recalculation;
5. provide durable progress and an idempotent resume contract.

Only after that owner-native fence exists should L2 add a new execution path.
Do not restore dummy child writes or a client-side attestation/POST gap as a
fallback.
