--- phase: 02-api-parity-harness-bootstrap plan: 01 type: execute wave: 1 depends_on: [] files_modified: - go.mod - go.sum - tide/flow.go - tide/fixture.go - tide/record.go - tide/replay.go - tide/diff.go - tide/testdata/one-route-spec.yaml - tide/roundtrip_test.go - cmd/summer/main.go - cmd/summer/parity.go - cmd/summer/parity_test.go autonomous: true requirements: [QA-01, QA-02, QA-03] must_haves: truths: - "D-04: A developer can invoke `summer parity:record` and `summer parity:replay` through bonfire against one HTTP route." - "D-05 D-06: The recorded versioned YAML flow contains an ordered request/response step with verbatim JSON body text." - "D-12 D-13: Replaying that fixture against an arbitrary httptest HTTP backend succeeds or reports an exact structural JSON path or raw byte mismatch." artifacts: - path: tide/flow.go provides: Framework-owned, versioned flow and step contracts - path: tide/fixture.go provides: Validated YAML load and atomic save - path: tide/record.go provides: HTTP recording engine - path: tide/replay.go provides: Backend-independent replay engine - path: cmd/summer/parity.go provides: Bonfire parity commands key_links: - from: cmd/summer/main.go to: cmd/summer/parity.go via: toolCommands registration - from: cmd/summer/parity.go to: tide/record.go via: RecordFlow API - from: cmd/summer/parity.go to: tide/replay.go via: ReplayFlow API --- **As a** port developer, **I want to** record one HTTP route and replay it against another backend, **so that** I can see the first parity result before porting an endpoint. Purpose: Establish a complete fixture-to-diff path on the Phase 1 command kernel. Output: Generic `tide` flow schema, fixture IO, one-route recorder/replayer, and two working `summer parity:*` commands. @/home/jin/.codex/get-shit-done/workflows/execute-plan.md @/home/jin/.codex/get-shit-done/templates/summary.md @.planning/ROADMAP.md @.planning/REQUIREMENTS.md @.planning/phases/02-api-parity-harness-bootstrap/02-CONTEXT.md @.planning/phases/02-api-parity-harness-bootstrap/02-RESEARCH.md @.planning/phases/02-api-parity-harness-bootstrap/02-VALIDATION.md @.planning/phases/02-api-parity-harness-bootstrap/02-PATTERNS.md @bonfire/command.go @cmd/summer/main.go `bonfire.Command` is a value with `Name`, `Description`, `Flags []bonfire.Flag`, `Args []bonfire.Arg`, and `Run(context.Context, bonfire.Input, bonfire.Output) error`. Flags are strings; `bonfire.Input.Flag(name)` retrieves them. `cmd/summer/main.go` assembles values in `toolCommands()` and `main()` maps command errors to exit status 1. Define the public `tide` contract here for later plans: `Flow{Version, Name, Description, SeedHook, Steps}`, `Step{ID, RouteID, Request, Response, Capture, Normalize, Headers}`, `Request{Method, Path, Query, Headers, Body}` where Query preserves the raw query string, and `Response{Status, Headers, Body, BodyFile, SHA256}`. Use `LoadFlow`, `SaveFlow`, `RecordFlow`, `ReplayFlow`, and a `Result` carrying per-step differences. Keep transport/target, fixture filesystem and output injected; neither `tide` nor its tests import Fonoteka. Task 1: Record and replay one route through the summer CLI go.mod, go.sum, tide/flow.go, tide/fixture.go, tide/record.go, tide/replay.go, tide/diff.go, tide/testdata/one-route-spec.yaml, tide/roundtrip_test.go, cmd/summer/main.go, cmd/summer/parity.go, cmd/summer/parity_test.go bonfire/command.go, bonfire/root.go, cmd/summer/main.go, cmd/summer/main_test.go, .planning/phases/02-api-parity-harness-bootstrap/02-CONTEXT.md, .planning/phases/02-api-parity-harness-bootstrap/02-RESEARCH.md A local httptest server answers GET /sample with JSON. `parity:record --spec one-route-spec.yaml --target URL --output PATH` produces one valid flow; `parity:replay --fixtures PATH --target URL` succeeds; a changed response fails with `$.data` and expected/actual values. A non-JSON response changed by one byte reports the byte offset. In one committing task, write a version-1 one-step YAML request spec and black-box tests through `bonfire.NewRoot("summer", toolCommands(), writer)` plus `httptest.Server` (D-04, D-05, D-06). Run the focused tests once to observe RED without committing, then implement enough `tide.Flow`, validated YAML load/save, HTTP record/replay and `bonfire` command registration to make the complete round trip GREEN. The fixture keeps request/response body bytes as YAML literal block scalars, records status and Content-Type, and saves atomically; changed JSON scalar or non-JSON byte returns a nonzero CLI error with expected/actual diagnostics. Include both original and changed handlers in the tests. Before adding direct goccy/go-yaml to `go.mod`, review RESEARCH.md Package Legitimacy Audit and run `/home/jin/.local/bin/slopcheck scan go.mod`; after module resolution inspect `git diff -- go.mod go.sum` and scan again. Keep the package generic, preserve `toolchain go1.27.0`, and commit only after full root vet/test is green. Plan 05 expands behavior coverage. /home/jin/.local/bin/slopcheck scan go.mod && go vet ./... && go test ./... && go test ./tide ./cmd/summer -run 'TestParityRoundTrip|TestParityCommands' -count=1 - RED is observed before implementation within the task, then all tests are GREEN before its single commit. - A real one-route fixture records and replays through `summer` against httptest; changed JSON or bytes report a mismatch. - Full root `go vet ./...` and `go test ./...` pass at commit; tests use temp fixtures and injected writers. A developer can already record and replay one HTTP route through the CLI after this task commits. Task 2: Make the one-route record/replay path work go.mod, go.sum, tide/flow.go, tide/fixture.go, tide/record.go, tide/replay.go, tide/diff.go, cmd/summer/main.go, cmd/summer/parity.go, tide/roundtrip_test.go, cmd/summer/parity_test.go go.mod, bonfire/command.go, bonfire/root.go, cmd/summer/main.go, tide/testdata/one-route-spec.yaml, tide/roundtrip_test.go, cmd/summer/parity_test.go, .planning/phases/02-api-parity-harness-bootstrap/02-PATTERNS.md Refine the working Plan 01 Task 1 path into the full public `tide` contract above: strict `version: 1` goccy/go-yaml decode rejects unknown fields, empty flow names, unsafe paths and duplicate step ids (D-05, D-06); atomic save syncs before rename. Inject `http.Client` and context, bound request/response body reads, and reject truncation before committing a fixture. In `diff.go`, decode JSON with `UseNumber`, recursively compare exact key sets, array lengths, scalar values and token types while ignoring object key order; report `$.path` with expected and actual values. For non-JSON content types, compare bytes and report offset plus printable escaped bytes. Keep `parity:record` and `parity:replay` in `toolCommands()` with string flags `--spec`, `--target`, `--output`, `--fixtures`; errors return through bonfire so main exits nonzero (D-04, D-12, D-13). Reinspect the `go.mod`/`go.sum` diff and rerun slopcheck if dependency metadata changes. Do not add an app route, PHP-specific field or standalone CLI. go vet ./... && go test ./... && go test ./tide ./cmd/summer -run 'TestParityRoundTrip|TestParityCommands' -count=1 - `parity:record` writes one replayable YAML flow and `parity:replay` accepts it. - Identical JSON with changed object key order passes; missing keys and changed string/number types fail at named paths. - Non-JSON changes fail with byte diagnostics; malformed YAML and oversized bodies fail before committing a fixture. - Root `go vet ./...` and `go test ./...` exit 0. A developer can record and replay one fixture using the installed summer tool. ## Trust Boundaries | Boundary | Description | |---|---| | YAML spec and HTTP target → local process | Untrusted paths, headers and bodies become outbound requests and fixture files. | ## STRIDE Threat Register | Threat ID | Category | Severity | Component | Disposition | Mitigation Plan | |---|---|---|---|---|---| | T-02-01 | Tampering/Denial of service | high | `tide.LoadFlow`, recorder and fixture writer | mitigate | Strict schema, bounded request/response body, context cancellation, safe output path and atomic writes; reject partial recordings. | | T-02-SC | Tampering | high | Go module changes | mitigate | Apply RESEARCH.md Package Legitimacy Audit before module resolution and run slopcheck; block any package marked ASSUMED/SUS pending human verification. | Run the one-route CLI smoke against httptest, then root `go vet ./...` and `go test ./...`. Confirm the written YAML can be loaded and replayed without changing the input spec. One route fixture records and replays through bonfire, a modified JSON field produces a structural path diff, and modified non-JSON bytes produce a byte diff. Create `.planning/phases/02-api-parity-harness-bootstrap/02-01-SUMMARY.md` after completion.