Files
summercms/.planning/phases/02-api-parity-harness-bootstrap/02-01-SUMMARY.md
Jakub Zych f9ba69c663 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 <cursoragent@cursor.com>
2026-09-17 12:22:30 +02:00

7.1 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
02-api-parity-harness-bootstrap 01 testing
tide
parity
yaml
httptest
bonfire
goccy
json-diff
phase provides
01-framework-kernel-foundation bonfire.Command kernel and cmd/summer toolCommands()
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
02-02
02-03
02-04
02-05
added patterns
github.com/goccy/go-yaml v1.19.2
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
created modified
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
cmd/summer/main.go
go.mod
go.sum
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
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
QA-01
QA-02
QA-03
7min 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

  • Key files exist on disk
  • git log --grep=02-01 returns Task 1 and Task 2 commits
  • Task acceptance criteria re-run and pass
  • Plan verification commands pass

Phase: 02-api-parity-harness-bootstrap Completed: 2026-09-17