Recording the full mcp-lifecycle fixture against real isolated PHP
(08-09-PLAN.md Task 2) uncovered three byte-level gaps between wristband's
assumed contract and actual production PHP behavior:
- Every explicit "Cache-Control: no-store" PHP sets is actually delivered
as "no-store, private" (Laravel's session-cookie default merges "private"
onto any explicit value); wristband's own default for unheadered JSON
error responses is "no-cache, private" (matching the house convention
already used elsewhere), not empty.
- PHP's redirect responses (authorize success and every error redirect)
render Symfony's default HTML redirect body with Content-Type
"text/html; charset=utf-8"; Go's bare 302 with no body never matched.
wristband/redirect_html.go ports that exact byte template, including
PHP's htmlspecialchars(ENT_QUOTES) escaping (Go's html.EscapeString uses
different quote entities).
tide/normalize.go: isIDKey now also masks "_ids" plural array fields
(e.g. collection_ids), a latent parity-corpus gap no prior fixture had
exercised with a literal, non-empty, non-placeholder array value.
- Record/replay baselines plus mutated fixtures for nil vs [], dates, tri-state bools, envelopes, money and ids
- Header, CSV/image byte, sidecar digest and two-flow continuation cases fail with path diagnostics
- Manifest coverage still reports later flows after a comparison failure
Co-authored-by: Cursor <cursoragent@cursor.com>
Value-based replace can miss a code_verifier when an authorization code is a substring of it, which 502'd MCP token capture.
Co-authored-by: Cursor <cursoragent@cursor.com>
Consent returns the callback URL in JSON, so replay can fill {{oauth:code}} from $.data.redirect_to before the token request.
Co-authored-by: Cursor <cursoragent@cursor.com>
RFC 7591 registration returns a string client_id and unix client_id_issued_at; treating those as Carbon/integer foreign keys would fail PHP self-replay of MCP OAuth.
Co-authored-by: Cursor <cursoragent@cursor.com>
Album sync payloads hash the collection and stamp a checkpoint that
change across seed runs and must not fail PHP self-replay.
Co-authored-by: Cursor <cursoragent@cursor.com>
Re-running bootstrap against an already seeded PHP instance 409s.
Route --update must not recapture a complete seed fixture.
Co-authored-by: Cursor <cursoragent@cursor.com>
PHP album payloads leave discogs_id null. The id mask required an
integer and failed PHP self-replay on otherwise identical bodies.
Co-authored-by: Cursor <cursoragent@cursor.com>
Unquoted numeric id placeholders made recorded JSON illegal to parse.
Replay now recaptures, persists vars, expands the expected body, and
diffs against the live response.
Co-authored-by: Cursor <cursoragent@cursor.com>
Numeric seed ids like 1 were substring-replaced through /api/v1 paths
and 15-style JSON integers. Keep ReplaceAll for long secrets and isolate
short values so the corpus stays replayable.
Co-authored-by: Cursor <cursoragent@cursor.com>
Manifest seed paths are fixtures-relative. Skip re-hitting the backend
only when every seed step already has a recorded status so a hand-written
spec can be recorded in place.
Co-authored-by: Cursor <cursoragent@cursor.com>
Drive ordered route cases through RecordFlow, resume in batches of
15, and print recorded/passing/failing/unrecorded coverage.
Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve named placeholders from a private variable store, mask
dates and ids after shape checks, and keep comparing independent steps.
Co-authored-by: Cursor <cursoragent@cursor.com>
Record Nuxt/MCP traffic as ordered flows via parity:proxy, pin
loopback upstream, and refuse oversized or credential-shaped fixtures.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Reject unknown YAML fields, empty names, duplicate steps and unsafe sidecars
- Treat JSON key order as insignificant and fail missing keys and token types at $.path
- Bound request bodies and refuse oversized or malformed input before writing a fixture
Co-authored-by: Cursor <cursoragent@cursor.com>
- Add a generic tide flow schema with YAML fixture IO and HTTP record/replay
- Register parity:record and parity:replay on the bonfire summer tool
- Diff JSON scalars at $.path and non-JSON bodies at the changed byte offset
Co-authored-by: Cursor <cursoragent@cursor.com>