docs(02): finalize parity research and validation map

This commit is contained in:
Jakub Zych
2026-09-17 01:56:49 +02:00
parent a109b52ec6
commit e3076950c3
2 changed files with 29 additions and 12 deletions

View File

@@ -20,6 +20,18 @@
6. **Normalize narrowly.** Match explicit JSON paths (`*_at`, known ids, captured values) with small in-house path rules; run a shape assertion before masking. For dates require an offset `+00:00` style where the PHP contract does, including key present with `null` where recorded. Assert ids are JSON integers before masking. Preserve nil versus `[]`, tri-state bool, fixed-decimal string versus number, envelope keys, and conditional key presence. A rule can be disabled per step; a broad “ignore timestamps/ids” filter would hide these failures.
7. **Report the whole run.** Continue after a failed comparison, but stop dependent steps within a flow after a failed capture. Print status/header/path/body differences and a route coverage table (recorded/passing/failing/unrecorded) against 154 manifest route ids. Exclude seed and client-only flows from the denominator. CLI exits nonzero on a ported failure or an unrecorded required route; app tests create one subtest per flow so `-run` can select it.
## Package Legitimacy Audit
All three proposed direct modules have an explicit project decision or requirement, an upstream-maintained module path, and a narrow use. No package in this phase is inferred from a similarly named fork or an unverified import path. Resolve versions with `go get`/`go mod tidy` at execution time, review the resulting `go.mod`/`go.sum`, and retain the existing Go 1.27 toolchain directive. Do not treat a package appearing transitively as permission to import an unrelated API.
| Package | Why it is allowed | Primary-source evidence and scope | Verdict |
|---|---|---|---|
| `github.com/goccy/go-yaml` | D-06 explicitly selects it for the framework fixture schema; project STACK.md independently selects it for YAML parsing. | The [upstream repository](https://github.com/goccy/go-yaml) documents tagged struct encode/decode and custom marshaling. Use directly in `tide` fixture and manifest IO; test unknown-field rejection and literal block body output rather than assuming encoder defaults. | VERIFIED |
| `github.com/testcontainers/testcontainers-go/modules/postgres` | QA-03 explicitly requires integration tests on testcontainers Postgres; Phase 2 D-12 requires a hermetic app test. | The [official Postgres module guide](https://golang.testcontainers.org/modules/postgres/) documents `postgres.Run`, `ConnectionString`, container cleanup and snapshots. Add only to `../fonoteka.go` test code; do not add it to framework production packages. | VERIFIED |
| `github.com/jackc/pgx/v5/stdlib` | The project already chooses Postgres/pgx via the GORM stack; the app's synthetic SQL-backed integration needs a `database/sql` driver before the real app handler exists. | The [upstream pgx `stdlib` documentation](https://github.com/jackc/pgx/blob/master/stdlib/sql.go) identifies it as the `database/sql` compatibility layer and shows `sql.Open("pgx", ...)`. Use only in the app integration test with parameterized SQL; reconcile its resolved v5 version with the app module when GORM arrives. | VERIFIED |
`net/http/httputil`, `net/http/httptest`, `encoding/json`, and `database/sql` are Go standard-library packages and need no third-party install. No JSONPath or diff dependency is needed; small path and comparison code keeps the assertion semantics explicit.
## Validation Architecture
- Fast checks at every implementation commit: `go vet ./... && go test ./...` in the framework root, plus the same in `../fonoteka.go` once that module has code. `go.work` does not make root `./...` traverse sibling modules; check each explicitly, as Phase 1's `scripts/check-phase1.sh` does for the hello modules.

View File

@@ -28,16 +28,21 @@ created: 2026-09-16
## Per-Task Verification Map
Plan/task IDs are assigned after the required plan-count checkpoint. The planner must attach each row to an exact task and automated command.
| Slice | Requirement | Threat Ref | Secure behavior | Test type | Automated command or assertion | Initial status |
|---|---|---|---|---|---|---|
| One-fixture record and replay through `summer` | QA-01, QA-02 | T-02-01 | Loopback target and bounded body handling | integration | `go test ./tide ./cmd/summer` with `httptest.Server`, fixture written then diffed | Pending |
| Live PHP proxy and scripted route recording | QA-01 | T-02-01, T-02-02 | Fixed upstream, scrub before write, no credential log | integration + operator smoke | `go test ./tide ./cmd/summer`; CLI capture from isolated PHP server | Pending |
| Structural JSON/byte diff and rule assertions | QA-02 | T-02-03 | Normalization rejects wrong token type or malformed date | unit | `go test ./tide -run 'Diff|Normalize|Capture|Scrub'` | Pending |
| 154-route manifest and client flows | QA-01 | T-02-02 | Only deterministic test identities committed | manifest audit + PHP replay | manifest validator reports `154/154 recorded`; PHP self-replay zero failures | Pending |
| Go replay seam and Postgres state | QA-02, QA-03 | T-02-04 | No false green for pending routes; seed hook allow-list | integration | `go test ./parity` in app module with testcontainers Postgres | Pending |
| Phase-wide test plan | QA-03 | T-02-01 to T-02-04 | Regression tests for all listed secure behaviors | unit + race + CLI | `go vet ./... && go test ./... && go test -race ./...` in both modules | Pending |
| Task ID | Wave | Requirement | Threat Ref | Test type | Automated evidence | Status |
|---|---:|---|---|---|---|---|
| 02-01-01 | 1 | QA-01, QA-02, QA-03 | T-02-01, T-02-SC | CLI integration | Root vet/test and `TestParityRoundTrip`/`TestParityCommands`; red state observed only before green commit | Pending |
| 02-01-02 | 1 | QA-01, QA-02, QA-03 | T-02-01 | unit + CLI | Root vet/test; malformed YAML, bounded bodies and byte/JSON diffs | Pending |
| 02-02-01 | 2 | QA-01, QA-03 | T-02-01, T-02-02 | proxy integration | `TestProxy`, `TestParityCommands`; named session, fixed upstream, safe flush | Pending |
| 02-02-02 | 2 | QA-01, QA-02, QA-03 | T-02-02, T-02-03 | unit + proxy | `TestCapture`, `TestScrub`, `TestNormalize`, `TestDiff`, `TestHeaders`, `TestFlow` | Pending |
| 02-02-03 | 2 | QA-01, QA-02, QA-03 | T-02-03, T-02-04 | CLI + manifest | `TestManifest`, `TestCoverage`; 16-route resume across two batches | Pending |
| 02-03-01 | 3 | QA-01, QA-03 | T-02-02, T-02-04, T-02-05 | PHP capture + audit | `check_corpus.go --allow-incomplete` against source; first PHP fixture and seed self-replay; both modules vet/test | Pending |
| 02-03-02 | 3 | QA-01, QA-03 | T-02-02, T-02-04, T-02-05 | batched PHP capture | Per-batch incomplete audit and PHP replay, then strict `--require-recorded` reports 154/154; both modules vet/test | Pending |
| 02-03-03 | 3 | QA-01, QA-03 | T-02-02, T-02-05 | real client capture | `capture_clients.mjs --check-deps` and `--capture`; corpus requires client flows and secret scan | Pending |
| 02-04-01 | 4 | QA-02, QA-03 | T-02-06, T-02-SC | Postgres integration | `TestParitySynthetic` starts testcontainers Postgres; both modules vet/test | Pending |
| 02-04-02 | 4 | QA-02, QA-03 | T-02-04, T-02-06 | app integration | `TestParityCorpus` shows 154 recorded/pending and zero false Go passes | Pending |
| 02-05-01 | 5 | QA-02, QA-03 | T-02-03 | contract unit | `TestFlowContract`, `TestDiffContract`, `TestManifestContract` | Pending |
| 02-05-02 | 5 | QA-01, QA-02, QA-03 | T-02-01, T-02-02, T-02-04, T-02-06 | security + app integration | `TestProxySecurity`, `TestParityCommandContract`, `TestParityContract` | Pending |
| 02-05-03 | 5 | QA-01, QA-02, QA-03 | T-02-01 to T-02-06 | phase gate | `bash scripts/check-phase2.sh --fresh-php` runs both modules' vet/test/race, Postgres, corpus audit and disposable PHP self-replay | Pending |
## Wave 0 Requirements
@@ -49,8 +54,8 @@ Plan/task IDs are assigned after the required plan-count checkpoint. The planner
| Behavior | Requirement | Why manual | Test instructions |
|---|---|---|---|
| Fresh PHP backend capture and self-replay | QA-01, QA-02 | Requires isolated PHP backend and database with local credentials | Start PHP on the agreed port with fresh parity DB, run seed/record, route manifest, Nuxt and MCP flows through proxy, then replay corpus against PHP; save command output and confirm zero failures. |
| Nuxt and MCP real sessions | QA-01 | Browser consent and external MCP interaction cannot be fully represented by synthetic handler | Point `NUXT_DEV_BACKEND_ORIGIN` and `FONOTEKA_API_URL` at proxy, perform documented flows, confirm committed fixtures under `nuxt/` and `mcp/` contain placeholders and no credentials. |
| Fresh PHP backend capture and self-replay | QA-01, QA-02 | The local PHP checkout, disposable DB and real credentials are required | Run `bash scripts/check-phase2.sh --fresh-php`; it must prove a unique empty `fonoteka_parity_*` DB, run documented artisan bootstrap, and replay all fixtures against its own `127.0.0.1:8423` child. Save output and confirm zero failures. |
| Nuxt and MCP real sessions | QA-01 | Actual browser and MCP clients are required | Run `capture_clients.mjs --capture` with the isolated PHP/proxy setup; inspect committed `nuxt/` and `mcp/` flows and the secret scan. |
## Validation Sign-Off