diff --git a/.planning/phases/25-catalog-enrichment-agent-tools/25-01-PLAN.md b/.planning/phases/25-catalog-enrichment-agent-tools/25-01-PLAN.md
index 3efc5f1..7407e5e 100644
--- a/.planning/phases/25-catalog-enrichment-agent-tools/25-01-PLAN.md
+++ b/.planning/phases/25-catalog-enrichment-agent-tools/25-01-PLAN.md
@@ -18,10 +18,10 @@ requirements:
must_haves:
truths:
- - "globalItems table has sourceUrl, imageCredit, imageSourceUrl columns"
- - "globalItems table has a unique constraint on (brand, model)"
+ - "upsertGlobalItem called with sourceUrl, imageCredit, imageSourceUrl returns them in the result"
+ - "Two upserts with the same (brand, model) return the same item id and created: false on the second call"
- "Inserting a duplicate (brand, model) updates the existing row instead of failing"
- - "Bulk upsert returns accurate created vs updated counts"
+ - "bulkUpsertGlobalItems returns accurate created vs updated counts matching input mix"
- "Tags are synced (create-if-not-exists) when provided, left untouched when omitted"
artifacts:
- path: "src/db/schema.ts"
@@ -189,6 +189,7 @@ export const categories = pgTable("categories", {
- src/db/schema.ts contains `unique().on(table.brand, table.model)`
- A new migration SQL file exists in drizzle-pg/ directory
- `bun run db:push` exits 0
+ - CATL-01 manufacturer requirement satisfied by existing brand column per D-02 — no new column needed
globalItems table has 3 new attribution columns and a unique constraint on (brand, model), migration generated and applied
diff --git a/.planning/phases/25-catalog-enrichment-agent-tools/25-02-PLAN.md b/.planning/phases/25-catalog-enrichment-agent-tools/25-02-PLAN.md
index 4ccd81e..3f7a321 100644
--- a/.planning/phases/25-catalog-enrichment-agent-tools/25-02-PLAN.md
+++ b/.planning/phases/25-catalog-enrichment-agent-tools/25-02-PLAN.md
@@ -423,7 +423,7 @@ interface GlobalItemWithOwnerCount extends GlobalItem { ownerCount: number; }
Add a `describe("catalog tools")` block with tests:
- `upsert_catalog_item` creates a new global item and returns it with created: true
- `upsert_catalog_item` updates existing item on (brand, model) match
- - `upsert_catalog_item` includes attribution fields (sourceUrl, imageCredit, imageSourceUrl) in result
+ - `upsert_catalog_item` includes attribution fields (sourceUrl, imageCredit, imageSourceUrl) in result — pass all three attribution fields and assert they appear in the returned item (SEED-03 coverage)
- `bulk_upsert_catalog` processes array and returns created/updated counts
- `bulk_upsert_catalog` returns totalProcessed matching input length
- Tool definitions include all attribution fields in inputSchema
@@ -442,6 +442,7 @@ interface GlobalItemWithOwnerCount extends GlobalItem { ownerCount: number; }
- src/server/mcp/index.ts contains `import.*catalogToolDefinitions.*registerCatalogTools`
- src/server/mcp/index.ts contains `registerCatalogTools(db)`
- tests/mcp/tools.test.ts contains `upsert_catalog_item` in at least 2 test descriptions
+ - tests/mcp/tools.test.ts contains at least one test that passes sourceUrl, imageCredit, and imageSourceUrl to upsert_catalog_item and asserts they appear in the returned item (SEED-03 coverage)
- `bun test tests/mcp/tools.test.ts` exits 0
Two MCP catalog tools registered and functional with attribution fields, all MCP tool tests passing
@@ -534,7 +535,7 @@ interface GlobalItemWithOwnerCount extends GlobalItem { ownerCount: number; }
- `bun run build` exits 0 (no TypeScript errors)
- `bun run lint` exits 0
- Catalog detail page shows image attribution inline below image (credit + source link) and product page link, client types updated
+ Catalog detail page shows image attribution inline below image (credit + source link) and product page link, client types updated. Manual verification required: open a catalog item with imageCredit set and confirm credit and source link render below the image (CATL-03 is visual — no automated test).
diff --git a/.planning/phases/25-catalog-enrichment-agent-tools/25-VALIDATION.md b/.planning/phases/25-catalog-enrichment-agent-tools/25-VALIDATION.md
index 1734904..34a6e04 100644
--- a/.planning/phases/25-catalog-enrichment-agent-tools/25-VALIDATION.md
+++ b/.planning/phases/25-catalog-enrichment-agent-tools/25-VALIDATION.md
@@ -2,8 +2,8 @@
phase: 25
slug: catalog-enrichment-agent-tools
status: draft
-nyquist_compliant: false
-wave_0_complete: false
+nyquist_compliant: true
+wave_0_complete: true
created: 2026-04-10
---
@@ -38,11 +38,11 @@ created: 2026-04-10
| Task ID | Plan | Wave | Requirement | Test Type | Automated Command | File Exists | Status |
|---------|------|------|-------------|-----------|-------------------|-------------|--------|
-| 25-01-01 | 01 | 1 | CATL-01 | unit | `bun test tests/services/global-item.service.test.ts` | ❌ W0 | ⬜ pending |
-| 25-01-02 | 01 | 1 | CATL-02 | unit | `bun test tests/services/global-item.service.test.ts` | ❌ W0 | ⬜ pending |
-| 25-01-03 | 01 | 1 | CATL-04, CATL-05 | integration | `bun test tests/routes/global-items.test.ts` | ❌ W0 | ⬜ pending |
-| 25-02-01 | 02 | 1 | SEED-01, SEED-02, SEED-03 | integration | `bun test tests/mcp/catalog-tools.test.ts` | ❌ W0 | ⬜ pending |
-| 25-03-01 | 03 | 2 | CATL-03 | manual | N/A | N/A | ⬜ pending |
+| 25-01-01 | 01 | 1 | CATL-01 | unit | `bun test tests/services/global-item.service.test.ts` | yes (existing file, new tests added inline) | ⬜ pending |
+| 25-01-02 | 01 | 1 | CATL-02 | unit | `bun test tests/services/global-item.service.test.ts` | yes (existing file, new tests added inline) | ⬜ pending |
+| 25-01-03 | 01 | 1 | CATL-04, CATL-05 | integration | `bun test tests/routes/global-items.test.ts` | yes (existing file, new tests added inline) | ⬜ pending |
+| 25-02-01 | 02 | 2 | SEED-01, SEED-02, SEED-03 | integration | `bun test tests/mcp/tools.test.ts` | yes (existing file, new tests added inline) | ⬜ pending |
+| 25-03-01 | — | — | CATL-03 | manual | N/A | N/A | ⬜ pending |
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
@@ -50,9 +50,7 @@ created: 2026-04-10
## Wave 0 Requirements
-- [ ] `tests/services/global-item.service.test.ts` — stubs for CATL-01, CATL-02 (upsert, attribution fields, unique constraint)
-- [ ] `tests/routes/global-items.test.ts` — stubs for CATL-04, CATL-05 (bulk import endpoint, upsert semantics)
-- [ ] `tests/mcp/catalog-tools.test.ts` — stubs for SEED-01, SEED-02, SEED-03 (MCP catalog tools)
+All three test files (`tests/services/global-item.service.test.ts`, `tests/routes/global-items.test.ts`, `tests/mcp/tools.test.ts`) already exist in the codebase with established test structure. New test cases are added inline within existing `describe` blocks — no new stub files needed. Wave 0 is satisfied.
---
@@ -66,11 +64,11 @@ created: 2026-04-10
## Validation Sign-Off
-- [ ] All tasks have `` verify or Wave 0 dependencies
-- [ ] Sampling continuity: no 3 consecutive tasks without automated verify
-- [ ] Wave 0 covers all MISSING references
-- [ ] No watch-mode flags
-- [ ] Feedback latency < 10s
-- [ ] `nyquist_compliant: true` set in frontmatter
+- [x] All tasks have `` verify or Wave 0 dependencies
+- [x] Sampling continuity: no 3 consecutive tasks without automated verify
+- [x] Wave 0 covers all MISSING references
+- [x] No watch-mode flags
+- [x] Feedback latency < 10s
+- [x] `nyquist_compliant: true` set in frontmatter
-**Approval:** pending
+**Approval:** approved