Skip to content

feat(crawler): phase 6-e — migration verification#206

Merged
YusukeHirao merged 1 commit into
feature/impl-new-dbfrom
feature/194-phase6e-migration-verification
Jul 14, 2026
Merged

feat(crawler): phase 6-e — migration verification#206
YusukeHirao merged 1 commit into
feature/impl-new-dbfrom
feature/194-phase6e-migration-verification

Conversation

@YusukeHirao

Copy link
Copy Markdown
Member

Summary

Closes #194. Phase 6-E of the write-model refactor (#103) — replaces the four ad-hoc row-count asserts in scripts/migrate-to-phase6.mjs with the full set of eight issue #194 acceptance invariants, factored into standalone check functions under packages/@nitpicker/crawler/src/archive/phase6e/. The orchestrator now runs inside the same 6-D populate transaction so a failing invariant rolls back every 6-D INSERT; ref tables from 6-B stay committed but are additive.

Notable design decisions (details in per-file JSDoc):

Scope explicitly excluded (deferred to #197 Phase 6-H): the acceptance's third bullet (assert-compatible-version-phase6.spec.ts / pre-Phase-6 CLI rejects a Phase-6 archive) — the plan doc places info.phase6_completed_at and the reject check in 6-H; 6-E archives keep the legacy tables alongside the new entities so functional rejection is not yet needed.

Test plan

  • yarn build
  • yarn lint
  • yarn test — 3204 passed / 5 skipped
  • Unit specs for each of the 8 checks (phase6e/check-*.spec.ts) plus Phase6VerificationError message formatting (types.spec.ts).
  • Orchestrator spec covers happy path (returns summary), first-check-fails, later-check-fails, and non-verification runtime error wrapping.
  • Integration spec (migrate-to-phase6-script.spec.ts) runs the actual .mjs against an Archive.create-built fixture — happy path completes and writes output, phantom-row injection aborts with #1 in stderr and leaves the input tar bit-identical.

🤖 Generated with Claude Code

Split the acceptance invariants for scripts/migrate-to-phase6.mjs into eight standalone check
functions under packages/@nitpicker/crawler/src/archive/phase6e/, orchestrated by
verifyPhase6Migration. The orchestrator now runs inside the same knex.transaction() block as
populatePhase6DEntities so a thrown Phase6VerificationError rolls back every 6-D INSERT; ref
tables from 6-B stay committed but are additive and idempotent on re-run. On success the
orchestrator returns a Phase6VerificationSummary that the script logs to stdout so operators can
audit content_items / page_meta / anchor_edges / image_items / resource_items counts from CI
pipeline logs without re-opening the archive.

Notable design decisions (details live in the per-file JSDoc):

- Check #3 (anchor_edges vs anchors) enforces anchor_edges <= anchors rather than the strict
  `< count(anchors)` spelled in the issue text — legitimate small crawls whose (pageId, hrefId)
  pairs are all unique produce anchor_edges == anchors and are not a failure. Check #4
  (SUM(count) == count(anchors)) already covers the "no rows lost" invariant when counts happen
  to match.
- Check #8 (URL round-trip) uses deterministic stride sampling (id % stride == 0) instead of
  ORDER BY RANDOM() so retries return the same verdict for the same archive, and LEFT JOINs so
  FK gaps surface as null-side rows rather than silently trimming the sample.
- verifyPhase6Migration wraps non-Phase6VerificationError exceptions in a Phase6VerificationError
  with check='runtime' so operator log greps for "Phase 6 verification failed" catch driver-side
  failures uniformly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@YusukeHirao YusukeHirao merged commit 276e7bb into feature/impl-new-db Jul 14, 2026
9 checks passed
@YusukeHirao YusukeHirao deleted the feature/194-phase6e-migration-verification branch July 14, 2026 07:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant