# 2026-05-09 — TIP No-Valid-Match Resolver

## Operator Requirement

- Continue TIP verification until source-backed work is exhausted.
- Do not invent competitor matches just to turn products green.
- Use deterministic TIP robots/scrapers only.
- Keep Erik safe; do not restart crawler daemons while active jobs are running.
- Write crawler/scraper/robot learnings into the TIPLLM training pool.

## Change

Added `packages/scraper/src/utils/resolve-no-valid-competitor.ts` and package script:

```bash
pnpm -C packages/scraper run verify:no-valid-competitor
```

The resolver is dry-run by default. Applying changes requires:

```bash
NO_VALID_MATCH_APPLY=1 pnpm -C packages/scraper run verify:no-valid-competitor
```

The default vendor scope is Flexoptix:

```bash
NO_VALID_MATCH_VENDOR=Flexoptix
```

## Rules

A product can be resolved as `competitor_status='no_valid_match'` only when:

- the product is active and not in a known artifact category
- price, image, and details are already verified
- competitor verification is still unresolved
- no other vendor has a source-backed strict candidate with the same form factor, speed, fiber, reach within max(25m, 5%), and compatible wavelength when both sides expose it
- no pending/approved equivalence above confidence `0.50` already exists

The robot writes `competitor_no_match` evidence and then calls `checkAndSetFullyVerified`.

## Live Result

On Erik:

- dry-run Flexoptix scope found `73` candidates
- apply run updated `73`
- `73` products earned `fully_verified`
- evidence ledger now has `73` `competitor_no_match` records

Live health after the resolver run:

- active products: `17414`
- price verified: `11523`
- image verified: `12125`
- details verified: `16814`
- fully verified: `10831`
- competitor status:
  - `matched=11158`
  - `no_valid_match=73`
  - `ambiguous=0`
  - `needs_research=6183`

## Post-Restart Reconcile / Matcher

After QSFPTEK/NADDOD pricing jobs cleared:

- restarted `tip-scraper-daemon` once
- queued `maintenance:reconcile-verification`
- queued `maintenance:find-equivalences`
- both jobs completed

Live health after matcher:

- active products: `17414`
- price verified: `11523`
- image verified: `12125`
- details verified: `16814`
- fully verified: `10831`
- competitor status:
  - `matched=11158`
  - `no_valid_match=73`
  - `ambiguous=192`
  - `needs_research=5991`

The matcher moved `192` products into `ambiguous`. This is intentional: ambiguous is safer than a false 1:1 match.

Remaining fully populated product rows with `needs_research`:

- `FS.COM=74`
- `Flexoptix=15`
- `ATGBICS=2`

## Operational Notes

- `tip-scraper-daemon` was only restarted after active pg-boss jobs completed.
- After restart, queue reconcile and matcher.
- This is the correct pattern for rare products: explicit no-match evidence beats false 1:1 matches.
