# Fixture bot findings follow-up

Scope: implementation sub-agent for [#23229](https://git.cafe/pingdotgg/t3code/pull/23229), checkout `/home/ubuntu/wt/issue-15873`, branch `fix/issue-15873`, starting commit [3738c10463](https://git.cafe/pingdotgg/t3code/commit/3738c1046353ff68c88933200105df9f607615fb).

## Findings and dispositions

1. Confirmed and fixed: C changed the answer payload timestamps without updating its message `created_at`/`updated_at` or turn-item `updated_at`. The existing timestamp transformation now updates matching row columns. No answer payload value, ID, text, or ordinal changed.
2. Confirmed and fixed: removing run 2 and remapping run 3 left provider-thread numeric ordinals and A/L checkpoint ordinals at 3. Normalize provider-thread `last_run_ordinal`/`lastRunOrdinal` from the maximum retained run (A/L=2, C=1; G/S=3), and checkpoint `app_run_ordinal`/`appRunOrdinal` from its retained run (null remains null). Preserve G/S byte-for-byte by avoiding unnecessary provider-payload serialization.
3. Confirmed and fixed: the guard allowed arbitrary external `.t3` paths. Resolve the supplied destination, require `statev2.sqlite` under the script checkout's `.t3`, and separately reject the resolved live home `.t3`. Guard rejection precedes both fixture generation and `sqlite3.connect`. README documents capture/pass2 acceptance and symlink rejection. The checkout `.t3` boundary deliberately remains unresolved so a `.t3` symlink escaping the checkout cannot expand the allowed destination.

## Validation

- Ran `/tmp/15873-validate-fixtures.py` with Python `-B`: all five fixture validators pass, in-memory SQLite seeding twice preserves exact row counts/idempotence, retained run maxima are G/S=3, A/L=2, C=1; provider/checkpoint numeric columns agree with payloads and retained runs; message/item row timestamps agree with payloads.
- New validator rejects the original A/L/C fixture metadata, while original G/S still pass. Forty deliberate row/payload corruptions across all five fixtures were rejected.
- Nine rejected guard cases: arbitrary external `.t3`, sibling checkout `.t3`, checkout path outside `.t3`, wrong database filename, traversal outside `.t3`, actual live home, escaping directory symlink, escaping database symlink, and an allowed-looking path treated as live home. All rejected before database open; rejection checks also prevent fixture generation. Capture/pass2 accepted using an injected in-memory connection. No live database opened.
- Additional full fixture comparison checks table/row/key counts and every decoded payload field; exactly 13 scalar data fields differ (enumerated below). G/S outputs byte-for-byte identical. Turn-item row/payload ordinals, run million-position prefixes, and derived position rows also agree in every fixture.
- Python AST parse and `git diff --check` pass. No production files, runtime.json, evidence images, tests, auth, permissions, MCP product code, browser, server, or forge state changed. No broad test suite or new review round run.

## Exact changed data fields

Indices below are zero-based fixture row indices. All unlisted row and decoded payload fields are unchanged.

- A, `orchestration_v2_projection_provider_threads` row 0, `last_run_ordinal`: `3` -> `2`.
- A, `orchestration_v2_projection_provider_threads` row 0, `payload_json.lastRunOrdinal`: `3` -> `2`.
- A, `orchestration_v2_projection_checkpoints` row 2, `app_run_ordinal`: `3` -> `2`.
- A, `orchestration_v2_projection_checkpoints` row 2, `payload_json.appRunOrdinal`: `3` -> `2`.
- C, `orchestration_v2_projection_provider_threads` row 0, `last_run_ordinal`: `3` -> `1`.
- C, `orchestration_v2_projection_provider_threads` row 0, `payload_json.lastRunOrdinal`: `3` -> `1`.
- C, `orchestration_v2_projection_messages` row 3, `created_at`: `2026-10-21T23:25:51.738Z` -> `2026-10-21T23:24:01.000Z`.
- C, `orchestration_v2_projection_messages` row 3, `updated_at`: `2026-10-21T23:25:51.738Z` -> `2026-10-21T23:24:01.000Z`.
- C, `orchestration_v2_projection_turn_items` row 8, `updated_at`: `2026-10-21T23:25:51.738Z` -> `2026-10-21T23:24:01.000Z`.
- L, `orchestration_v2_projection_provider_threads` row 0, `last_run_ordinal`: `3` -> `2`.
- L, `orchestration_v2_projection_provider_threads` row 0, `payload_json.lastRunOrdinal`: `3` -> `2`.
- L, `orchestration_v2_projection_checkpoints` row 2, `app_run_ordinal`: `3` -> `2`.
- L, `orchestration_v2_projection_checkpoints` row 2, `payload_json.appRunOrdinal`: `3` -> `2`.

## Capture equivalence and pixel claims

All fixture identities, texts, row ordering, turn-item ordinals/positions, and preexisting payload timestamps are preserved. Only the metadata above changes; raw provider payload JSON for A/L/C is reserialized as required to change its numeric field. Existing screenshots/recordings may remain scoped to their originally recorded old SHA and original database. Do not relabel them as captures of this new commit or corrected fixture metadata. Production rendering source is unchanged, but no browser was authorized or run, so pixel equivalence at the new commit is unverified. Retained all explicitly requested evidence fixtures.

## Complexity

No regex, parser, token replacement, or input-scanning loop was changed. Added metadata work is linear in retained runs, provider-thread rows, checkpoint rows, and payload bytes: one retained-run maximum per fixture/validation plus constant-time lookups per checkpoint; existing per-row validation gains only constant-count checks. No nested run scan was introduced. Existing UUID rewrite behavior and its complexity remain unchanged. As extra bounded stress evidence, injected 3000 malformed identity tokens (750 each of invalid msg_, call_, rs_, and UUID forms) into linked message/item text; all five fixtures validated in 0.4196 seconds. This is a seeder stress result, not a production parser benchmark.

## FRICTION

```text
FRICTION
Terminal startup/read commands intermittently stalled before returning; reused each running session, waited boundedly, and did not launch duplicate shells or kill any process.
An initial comparison caught harmless G/S provider-payload reserialization; fixed by writing only when numeric metadata changes. Final G/S are byte-for-byte unchanged.
The first validation attempt stopped at that strict comparison; the complete rerun passed after the correction.
No browser/server/forge writes or permission requests. Parent owns push, review responses, and resolution.
```
