Review: Data migration: retype doc notes to new types (pal-e-api #224)

review-224-2026-03-27 Review

review needs-refinement

Review: Data migration retype doc notes (pal-e-api #224)

Verdict: NEEDS_REFINEMENT
Reviewed 2026-03-27 by Dottie. Issue: forgejo_admin/pal-e-api#224.

1. Template Compliance (template-issue-task)

Required Section Present? Notes
Type YES "Task" -- correct, this is a non-code data migration via Alembic
Scope YES Nine retype rules with WHERE clauses and counts
Acceptance Criteria YES Seven verifiable criteria with zero-count assertions and a net count target
Related YES Links project-pal-e-agency and parent spike #180
Template compliance: PASS. All four required sections present.

2. Scope Clarity

The scope is clear and agent-executable. Each rule specifies: count, filter condition, and target note_type. The Alembic migration pattern (data-only, no schema change) is implicit from #223 dependency.
Gap: The issue says "Task" but lives in pal-e-api (a code repo). This IS code work -- it produces an Alembic migration file, a branch, and a PR. It should be typed as Feature, not Task, per template-issue-task signal table: "It produces code changes (branch, PR, merge) = Feature or Bug." This is a minor template mistype, not a blocker.

3. Acceptance Criteria Verifiability

All seven AC items are verifiable via SQL COUNT queries or pal-e-docs API list_notes calls post-migration. The "doc note count drops from ~257 to ~48" criterion provides a sanity-check net target. PASS.

4. Dependency Statement

Issue explicitly states: "depends on pal-e-api issue: Add 4 new NoteTypes" (issue #223). Issue #223 is currently open with an associated PR #226. The dependency is stated but #223 must merge first. PASS -- dependency is clear.

5. Migration SQL WHERE Clause Verification

Rule 1: doc + tag "review" -> review (claims 191)

list_notes(note_type="doc", tags="review") returned a result set exceeding 125,000 characters. Count is plausible at ~191 but could not be precisely verified via API alone -- the result was too large to parse inline. The WHERE clause logic (join notes to note_tags to tags where tag.name='review' AND note_type='doc') is sound.
Status: PLAUSIBLE, recommend agent verify exact count with a direct SQL query or paginated API call before writing migration.

Rule 2: doc + slug LIKE 'arch-%' -> architecture (claims 16)

list_notes(note_type="doc", tags="architecture") returned 16 results, but only 14 have arch- prefix slugs:
  • arch-sitemap-westside-basketball
  • arch-deployment-westside-basketball
  • arch-dataflow-westside-basketball
  • arch-domain-westside-basketball
  • arch-generic-checkout
  • arch-auth-westside-basketball
  • arch-deployment-mcd-tracker
  • arch-dataflow-mcd-tracker
  • arch-domain-mcd-tracker
  • arch-domain-pal-e-agency
  • arch-deployment-pal-e-pac
  • arch-dataflow-pal-e-pac
  • arch-domain-pal-e-pac
  • arch-secrets-pipeline
Two non-arch-prefix notes also have the architecture tag but would NOT match slug LIKE 'arch-%': agent-paradigm and tf-environment-strategy. There may also be arch- prefix docs WITHOUT the architecture tag that the tag-based query missed.
Status: DISCREPANCY. Count is 14 confirmed, not 16. The executing agent must run a precise WHERE note_type='doc' AND slug LIKE 'arch-%' query to get the real count before writing the migration.

Rule 3: doc + slug LIKE 'validation-%' -> validation (claims 6)

list_notes(note_type="doc", tags="validation") returned exactly 6 notes, all with validation- prefix slugs:
  • validation-159-2026-03-27
  • validation-35-2026-03-27
  • validation-36-2026-03-27
  • validation-182-2026-03-27
  • validation-173-2026-03-27
  • validation-157-2026-03-27
Status: CONFIRMED. Count matches. Note: more validation notes may be created between now and migration execution -- the migration should use the WHERE clause, not a hardcoded ID list.

Rule 4: doc + slug LIKE 'board-%' -> board (claims 7)

Only 4 board-prefix doc notes confirmed:
  • board-180-note-type-audit (has board tag)
  • board-109-rename-westside-landing (has board tag)
  • board-validation-pipeline (no board tag, has active tag)
  • board-109-westside-landing-split (no board tag, has active tag)
Status: DISCREPANCY. Count is 4 confirmed, not 7. The issue may have counted notes that were created and then renamed, or the count was taken at a different point in time. The executing agent must verify with a direct SQL query.

Rules 5-9: Legacy type folding (reference, journal, incident, post, issue -> doc)

Type Claimed Actual Match
reference 27 27 YES
journal 3 3 YES
incident 3 3 YES
post 3 3 YES
issue 1 1 YES
Status: ALL CONFIRMED.

6. Findings Summary

Check Result
Template compliance PASS (minor: should be Feature not Task)
Scope clarity PASS -- agent-executable
AC verifiability PASS
Dependency stated PASS (#223 must merge first)
Rule 1 count (review) PLAUSIBLE (~191, needs exact verification)
Rule 2 count (arch-*) DISCREPANCY (14 confirmed, claims 16)
Rule 3 count (validation-*) CONFIRMED (6)
Rule 4 count (board-*) DISCREPANCY (4 confirmed, claims 7)
Rules 5-9 counts ALL CONFIRMED

7. Recommendations

  • Update counts in issue body -- arch-* and board-* counts do not match live data. Either the counts changed since the spike, or they were estimated. Update to actuals before executing.
  • Add "counts are approximate" caveat -- or better, specify that the migration uses WHERE clauses, not hardcoded counts. The AC already does this correctly (zero-assertions), but the scope section's counts are misleading if stale.
  • Consider changing Type to Feature -- this produces an Alembic migration file and a PR. Task type is for non-code work per template-issue-task.
  • Executing agent should run exact SQL counts before writing the migration, not trust the issue body counts.
  • template-issue-task -- template used for review
  • forgejo_admin/pal-e-api#224 -- reviewed issue
  • forgejo_admin/pal-e-api#223 -- blocking dependency
  • board-180-note-type-audit -- parent audit board