From f9ba69c663702d05d59d436aa43eb57a5bbffc24 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Thu, 17 Sep 2026 12:22:30 +0200 Subject: [PATCH] docs(02-01): complete record-and-replay one fixture plan Tasks completed: 2/2 - Record and replay one route through the summer CLI - Lock the one-route tide record and replay contract SUMMARY: .planning/phases/02-api-parity-harness-bootstrap/02-01-SUMMARY.md Co-authored-by: Cursor --- .../02-01-SUMMARY.md | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 .planning/phases/02-api-parity-harness-bootstrap/02-01-SUMMARY.md diff --git a/.planning/phases/02-api-parity-harness-bootstrap/02-01-SUMMARY.md b/.planning/phases/02-api-parity-harness-bootstrap/02-01-SUMMARY.md new file mode 100644 index 0000000..4538f79 --- /dev/null +++ b/.planning/phases/02-api-parity-harness-bootstrap/02-01-SUMMARY.md @@ -0,0 +1,162 @@ +--- +phase: 02-api-parity-harness-bootstrap +plan: 01 +subsystem: testing +tags: [tide, parity, yaml, httptest, bonfire, goccy, json-diff] + +requires: + - phase: 01-framework-kernel-foundation + provides: bonfire.Command kernel and cmd/summer toolCommands() +provides: + - Version-1 tide Flow/Step request/response contracts + - Validated YAML load and atomic fixture save + - HTTP RecordFlow/ReplayFlow against an injected target + - summer parity:record and parity:replay commands +affects: [02-02, 02-03, 02-04, 02-05] + +tech-stack: + added: + - github.com/goccy/go-yaml v1.19.2 + patterns: + - Fixture bodies are YAML literal block scalars; JSON compares structurally with UseNumber + - Record/replay inject http.Client, context, target URL and a body size cap + - Bonfire string flags --spec --target --output --fixtures; errors exit through cobra + +key-files: + created: + - 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/parity.go + - cmd/summer/parity_test.go + modified: + - cmd/summer/main.go + - go.mod + - go.sum + +key-decisions: + - "tide is the framework-owned parity library; it does not import Fonoteka" + - "goccy/go-yaml v1.19.2 decodes fixtures with DisallowUnknownField; save uses a dedicated encoder so literal bodies keep nested indent" + - "JSON diffs ignore object key order and fail on missing keys or token-type changes at $.path" + - "Non-JSON bodies compare raw bytes and report offset plus printable escaped windows" + - "toolchain go1.27.0 is restored after go mod tidy drops it" + +patterns-established: + - "Pattern: CLI tests drive bonfire.NewRoot with an injected writer and httptest.Server, never a real TTY" + - "Pattern: SaveFlow writes a temp file, Syncs, then rename; RecordFlow errors never create the destination" + +requirements-completed: [QA-01, QA-02, QA-03] + +duration: 7min +completed: 2026-09-17 +--- + +# Phase 2 Plan 1: Record and Replay One Fixture Summary + +**A developer can record GET /sample through `summer parity:record` and replay it with `summer parity:replay` against httptest, with JSON path diffs at `$.data` and non-JSON byte-offset diffs** + +## Performance + +- **Duration:** 7 min +- **Started:** 2026-09-17T10:14:10Z +- **Completed:** 2026-09-17T10:21:51Z +- **Tasks:** 2 +- **Files modified:** 12 + +## Accomplishments + +- Generic `tide` package owns version-1 Flow/Step contracts, validated YAML IO, HTTP record/replay and structural JSON/byte diffs +- `parity:record` and `parity:replay` register on the Phase 1 bonfire kernel with string flags `--spec`, `--target`, `--output`, `--fixtures` +- One-route testdata spec records and replays against httptest; changed JSON or bytes fail the CLI with expected/actual diagnostics + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Record and replay one route through the summer CLI** - `f6e1b89` (feat) +2. **Task 2: Make the one-route record/replay path work** - `f669d05` (feat) + +**Plan metadata:** pending `docs(02-01)` commit + +_Note: TDD RED was observed as compile/command discovery failure inside Task 1 and was not committed separately, per the plan's single-green-commit instruction._ + +## Files Created/Modified + +- `tide/flow.go` - Flow/Step/Request/Response types, Result, MismatchError, validation +- `tide/fixture.go` - LoadFlow/ParseFlow/SaveFlow with unknown-field rejection and atomic sync+rename +- `tide/record.go` - RecordFlow with injected client, context and bounded bodies +- `tide/replay.go` - ReplayFlow against an arbitrary HTTP target +- `tide/diff.go` - UseNumber JSON compare and non-JSON byte-offset diffs +- `tide/testdata/one-route-spec.yaml` - version-1 GET /sample request spec +- `tide/roundtrip_test.go` - TestParityRoundTrip library round trip and contract cases +- `cmd/summer/parity.go` - parity:record and parity:replay commands +- `cmd/summer/parity_test.go` - TestParityCommands through bonfire.NewRoot +- `cmd/summer/main.go` - registers the parity commands on toolCommands() +- `go.mod` / `go.sum` - direct github.com/goccy/go-yaml v1.19.2, toolchain go1.27.0 kept + +## Decisions Made + +- Named the harness library `tide` as allowed by CONTEXT.md discretion +- Decode with goccy; encode fixtures with a small dedicated writer so `body: |-` content is indented under nested mappings (goccy BytesMarshaler dropped indent) +- Compare JSON structurally (key sets, array lengths, scalars, json.Number token types) and ignore object key order +- Inject `http.Client`, context and MaxBody; default cap is 8 MiB; truncation fails before SaveFlow +- Keep the package generic: no Fonoteka route names, PHP fields, or standalone CLI + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 2 - Missing Critical] Restored toolchain go1.27.0 after go get/tidy dropped it** +- **Found during:** Task 1 (module resolution) +- **Issue:** `go get github.com/goccy/go-yaml@v1.19.2` and `go mod tidy` removed the `toolchain go1.27.0` directive the plan requires +- **Fix:** Re-inserted `toolchain go1.27.0` in go.mod after tidy +- **Files modified:** go.mod +- **Verification:** `grep toolchain go.mod` shows `toolchain go1.27.0`; go vet/test pass +- **Committed in:** f6e1b89 (Task 1 commit) + +**2. [Rule 1 - Bug] Dedicated YAML encoder for literal nested bodies** +- **Found during:** Task 1 (GREEN of SaveFlow) +- **Issue:** goccy BytesMarshaler parsed `|-` scalars but re-emitted content without nested indent, so LoadFlow failed with `unexpected map key` +- **Fix:** SaveFlow writes version-1 YAML with correctly indented block scalars; LoadFlow still uses goccy with DisallowUnknownField +- **Files modified:** tide/fixture.go +- **Verification:** TestParityRoundTrip records YAML containing `body: |-` and reloads it +- **Committed in:** f6e1b89 (Task 1 commit) + +--- + +**Total deviations:** 2 auto-fixed (1 missing critical, 1 bug) +**Impact on plan:** Required for the pinned toolchain and for round-tripping recorded JSON bodies. No scope creep. + +## Issues Encountered + +- slopcheck on the updated go.mod reported goccy as OK. Pre-existing SUS findings on `golang.org/x/term` and `golang.org/x/sys` were unchanged and not newly added +- QA-01/QA-02/QA-03 remain phase-level: this plan delivers the one-route CLI path, not the 154-route corpus, normalizer classes, or testcontainers. Frontmatter copies the plan's requirements list; they should not be treated as milestone-complete + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness + +Ready for 02-02-PLAN.md (proxy sessions and manifest-driven record with strict diffs). Public APIs: `LoadFlow`, `SaveFlow`, `RecordFlow`, `ReplayFlow`, `Flow`, `Result`. + +## Verification + +- RED observed: `go test ./tide ./cmd/summer -run 'TestParityRoundTrip|TestParityCommands'` failed with undefined LoadFlow/RecordFlow and missing `parity:record` before implementation +- GREEN: same focused tests pass; `go vet ./...` and `go test ./...` exit 0 +- slopcheck: goccy VERIFIED/OK; toolchain pin preserved + +## Self-Check: PASSED + +- [x] Key files exist on disk +- [x] `git log --grep=02-01` returns Task 1 and Task 2 commits +- [x] Task acceptance criteria re-run and pass +- [x] Plan verification commands pass + +--- +*Phase: 02-api-parity-harness-bootstrap* +*Completed: 2026-09-17*