# Securities TPC-E Read-Only Workload SOP

This SOP runs the securities read-service lane without changing the canonical
TPC-E foreground workload. It models customer portals, trader workbenches, and
broker reporting as a separate `tpce_read_only` scenario. Big Query remains an
independent operation and is not part of this workload mix.

The mac-mini-2 reference result and exact acceptance evidence are recorded in
[the Issue #75 E2E report](tpce-read-only-e2e-report.md).

## 1. Select the scenario

Use the first-class template or copy the reusable 50G spec:

```bash
tipoc init --template securities-tpce-read-only \
  --out runs/<run-id>/attempt-001

# Or use the checked-in executable contract.
cp testcase/securities-tpce-read-only.yaml /tmp/<run-id>.yaml
tipoc init --spec /tmp/<run-id>.yaml \
  --out runs/<run-id>/attempt-001 \
  --remote-bootstrap plan
```

Before `init`, edit identity, attempt paths, target endpoints, object-store
references, nodes, duration, and concurrency. Keep credentials as secret
references. Do not edit the compiled manifest.

The required pressure identity is:

```yaml
pressure:
  workload_mix: tpce_read_only
  read_only_profile:
    traffic_classes:
      - customer_portal
      - trader_workbench
      - broker_reporting
    tenant_count: 1
    tenant_concurrency: 32
```

Traffic classes map to these read families:

| Traffic class | Transaction families |
| --- | --- |
| `customer_portal` | Market-Watch, Customer-Position |
| `trader_workbench` | Trade-Status, Security-Detail, Trade-Lookup |
| `broker_reporting` | Broker-Volume |

Unknown classes, duplicate classes, non-positive tenant counts, and mismatched
workload/runtime identities fail before SQL execution.

## 2. Prepare and run

Use the normal four-stage product flow:

```bash
tipoc prepare --manifest runs/<run-id>/attempt-001/run-profile-manifest.json
tipoc prepare --manifest runs/<run-id>/attempt-001/run-profile-manifest.json --finish
tipoc run --manifest runs/<run-id>/attempt-001/run-profile-manifest.json
tipoc cleanup --manifest runs/<run-id>/attempt-001/run-profile-manifest.json
```

The read-only runtime may execute only the six declared query families. It
must not emit Trade-Order, Trade-Update, Send-to-Market, MEE, Market-Feed,
Data-Maintenance, Trade-Cleanup, or SQL mutation evidence.

## 3. Continue another pressure round

Continuation is allowed only when the predecessor has the same
`tpce_read_only` runtime adapter, normalized traffic profile, effective family
set, and mode digest. Use the Issue #65 recovery path; never hand-edit a
manifest or boundary:

```bash
tipoc prepare --manifest <attempt>/run-profile-manifest.json --finish \
  --continuation-from <attempt>/run/try-02/run-profile-manifest.json
tipoc run --manifest <attempt>/run-profile-manifest.json
```

After a completed same-mode run, `scripts/rerun/run-again.sh` may create the
next try and invoke the same `run` recovery path. If the process was killed,
bind the newest earlier terminal predecessor and let `run` recover the live
trade-ID high-water. A canonical `tpce` or `exchange_matching` continuation
must be rejected rather than silently converted into read-only evidence.

A prepared dataset may be reused only through product-validated immutable
prepare evidence. Changing the workload identity by editing an old manifest is
not a valid reuse procedure and must not be reported as E2E evidence.

## 4. Acceptance evidence

Treat the run as passed only when all of the following agree:

1. `run-profile-manifest.json` binds `tpce_read_only` to
   `industries/securities/runtime/read_only` and records the mode digest.
2. `live-runtime-execution.json`, `run-receipt.json`, `summary.json`,
   `global-run-closeout.json`, and `run-continuation.json` carry the same mode,
   runtime ref, traffic profile, and effective family set.
3. All six configured families appear over the run, or the selected subset
   exactly matches its traffic classes.
4. `mutation_guard_status` is `passed`, with zero forbidden events and zero
   mutation statements.
5. Started/completed/failed/cancelled iteration counts are present. A cancelled
   partial iteration does not advance the safe continuation cursor.
6. The read-only timeline and semantic proof pass, blocked statements are zero,
   and continuation status is ready unless the trade-ID budget is exhausted.
7. The report names the machine, CPU, memory, TiDB/TiKV topology, dataset size,
   concurrency, stable window, QPS/TPS, and artifact paths.

For one-, two-, and three-node pressure placement, the physical ownership may
change, but the normalized traffic profile, effective families, and mode
digest must remain identical.

## 5. Optional Big Query coexistence campaign

Big Query must be declared at `init` as an independent operation; do not add it
by editing a compiled manifest. Follow
[the Big Query interference SOP](big-query-interference-sop.md), preserve its
operation receipt, and verify that the foreground read-only mutation guard and
continuation still pass. A bounded operation may finish with one in-flight
query cancelled at its stop boundary; that is distinct from a query failure.
