9.7 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 | 03 | testing |
|
|
|
|
|
|
|
|
|
61min | 2026-09-17 |
Phase 2 Plan 3: Record all 154 PHP routes and real Nuxt/MCP flows Summary
Isolated PHP on :8423 yielded a 154-route live fixture corpus plus Playwright Nuxt and MCP SDK OAuth/PKCE sessions, all placeholder-scrubbed and self-replay green
Performance
- Duration: 61 min
- Started: 2026-09-17T10:46:38Z
- Completed: 2026-09-17T11:47:00Z
- Tasks: 3
- Files modified: 180+ (154 route fixtures plus seed, manifest, clients, tide fixes)
Accomplishments
- Isolated parity SQLite +
winter:up+fonoteka:oauth-client; PHPartisan serveon127.0.0.1:8423; no PHP/Nuxt/MCP source edits. - Seed bootstrap recorded from live API calls; vars file mode 0600 under
/tmp/summercms-parity/. - All 154
routes.phpIDs have a committed one-step route fixture fromsummer parity:record(batches of ≤12 routes, ≤15 files per commit). - Real client corpus:
nuxt-browse(56 steps, login/dashboard/albums/genres write),mcp-tools(3 steps, list+create genre withtoken:mcp-read),mcp-oauth(20 steps, discovery/register/authorize/consent/PKCE token). check_corpus.go --require-recorded --require-clients --check-secretsprintsrecorded 154/154.- Fresh-DB PHP self-replay: seed then
--manifest --self-check --require-recorded→recorded 154/154 passing 154 failing 0 unrecorded 0. Seed then Nuxt/MCP/OAuth (withpkce.varsmerged) all matched.
Task Commits
Each task was committed atomically (app repo fonoteka.go unless noted):
- Task 1: Seed an isolated PHP instance and capture its first real route -
8b5bd23(feat) - Task 2: Record a case for each of the 154 PHP routes -
ef68d80,66ed0bb,0ee0bc7,6bc255c,29544c4,351fd3f,3211634,fc343ff,029d8a8,db02ecb,c87e78b,8869405,ddb9ae9,f3a3040(feat batches) - Task 3: Capture unchanged Nuxt and MCP client journeys -
a7511b5(feat)
Framework tide/CLI fixes in summercms.go (same plan): 4451c2f, 1ea3c59, 591a0d4, 5b947c7, 39ddf78, 4c1259a, 0307510, 8f94b07, 22f02ee, 8881df9, 2eb9b4b, 7a6c669.
Plan metadata: this SUMMARY commit
Files Created/Modified
../fonoteka.go/parity/manifest.yaml— 154 route IDs, auth groups, fixture names,status: pending../fonoteka.go/parity/routes.snapshot— canonical IDs + PHP source digest../fonoteka.go/parity/fixtures/seed/bootstrap.yaml— API-created parity dataset../fonoteka.go/parity/fixtures/routes/*.yaml— one live PHP case per route../fonoteka.go/parity/capture-rules.yaml— kept headers and named captures, no values../fonoteka.go/parity/capture_clients.mjs— Playwright + MCP SDK orchestrator../fonoteka.go/parity/fixtures/nuxt/nuxt-browse.yaml— real Nuxt multi-step flow../fonoteka.go/parity/fixtures/mcp/mcp-tools.yaml— personal-token MCP tools../fonoteka.go/parity/fixtures/mcp/mcp-oauth.yaml— OAuth discovery/PKCE../fonoteka.go/parity/check_corpus.go— 154-ID audit,--require-clients,--check-secrets../fonoteka.go/parity/php_parity.sh— reset/serve/artisan with parity-name refuse../fonoteka.go/parity/README.md— isolation, record, replay, client capture commandstide/variables.go— PHP-JSON/scrub,response.json.query, form-field PKCE/code scrubtide/normalize.go— stringclient_idand unix*_issued_atmaskstide/proxy.go— 502 bodies include record-step errors
Decisions Made
- Record/reset refuse any
DB_DATABASEwhose basename does not containparity. - Ordered
--updaterecapture is required so 154 fixtures match a fresh-DB replay; DELETEs target missing ids so seed rows remain. - Cookie request headers are not kept; Laravel session cookies must not enter the corpus.
- OAuth authorization codes are captured from consent
$.data.redirect_toquerycodeso replay can fill{{oauth:code}}before the token POST. - The S256
code_verifiercannot be reconstructed from the recordedcode_challenge;capture_clients.mjswrites/tmp/summercms-parity/pkce.vars(0600, not committed) and README merges it after seed replay.
Deviations from Plan
Auto-fixed Issues
1. PHP json_encode slash-escaping left OAuth codes in consent JSON
- Found during: Task 3 (client secret scan)
- Issue: Captured redirect URLs used
/while PHP bodies used\/, so{{oauth:redirect}}never replaced?code= - Fix:
replaceAllalso substitutesphpJSONEscape(/→\/) - Files modified:
tide/variables.go,tide/capture_test.go - Verification: recapture consent body is
{"data":{"redirect_to":"{{oauth:redirect}}"}};--check-secretsgreen - Committed in:
8f94b07
2. RFC 7591 registration fields failed JSON compare on client replay
- Found during: Task 3 (OAuth self-replay)
- Issue:
client_idis a string andclient_id_issued_atis unix, not Carbon*_at - Fix: mask string
client_idand integer*_issued_at - Files modified:
tide/normalize.go,tide/normalize_test.go - Verification:
mcp-oauth.yamlreplay matched - Committed in:
22f02ee
3. Token capture 502 when authorization code was a substring of the PKCE verifier
- Found during: Task 3 (recapture after json.query)
- Issue: value-based
replaceAllcorruptedcode_verifierthenrejectUnclassifiedCredentialsfailed the proxy - Fix: after value replace, scrub
request.formfields by name - Files modified:
tide/variables.go,tide/capture_test.go,tide/proxy.go - Verification: live recapture wrote
mcp-oauth; token step hascode_verifier={{pkce:mcp}} - Committed in:
7a6c669(scrub),2eb9b4b(502 detail),8881df9(json.query)
4. Short captured numeric ids rewrote 127.0.0.1
- Found during: Task 2/3 replay
- Issue: isolated replace of id
1inside IPv4 literals - Fix: earlier
1ea3c59token-boundary replace; remaining127.0.0.{{id:*}}expands back to1on this seed - Files modified:
tide/variables.go - Verification: client and 154-route self-replay green
- Committed in:
1ea3c59
Total deviations: 4 auto-fixed (secret scrub, OAuth JSON mask, form-field PKCE, short-id isolation) Impact on plan: Required for a secret-clean, self-replayable corpus. No scope creep onto PHP/Nuxt/MCP.
Issues Encountered
- Playwright
@playwright/testhas nochromiumexport; resolve nestedplaywrightviacreateRequire. - Nuxt login required waiting for
#__nuxt.__vue_app__before filling#email. - Seed replay on a mutated DB returns 409; every recapture resets
php_parity.shfirst. - Client flows must replay on a freshly seeded DB, not after the 154 mutating route cases.
User Setup Required
None - no external service configuration required. Local PHP, Node (Nuxt/MCP deps), and /tmp/summer are enough. Recreate pkce.vars with capture_clients.mjs --capture before OAuth token replay if that file was deleted.
Next Phase Readiness
Ready for 02-04 (in-process Go replay with testcontainers Postgres). The PHP corpus is complete and self-consistent; route rows stay pending until ported.
Phase: 02-api-parity-harness-bootstrap Completed: 2026-09-17