# Wishdeal Factory buyer-path - iteration 148 ship log

**Date:** 2026-05-15 (push mode, 60 min cadence, landmarks-permanence iter)

## What shipped (2 substantive ships)

Closed the section-landmarks WARN card (245/248 -> 248/248) and patched the source generator so the fix is durable, not iteration-by-iteration.

## Ship 1: Fixed 2 footer-missing pages

Located the 2 pages missing footer landmark from iter-144:
- competitor-tracker
- immigration-law-ai

Both end with `<section class="wd-trust">` directly inside `</body>` — no `<footer>`. Added `role="contentinfo"` attribute to make the wd-trust section serve as the footer landmark for AT.

Targeted edit only on those 2 pages. Preserves visual layout entirely.

## Ship 2: Found + fixed nav-role regression + patched source

Discovered during iter-148 audit that the iter-144 landmarks-fix injector's `role="navigation"` on wd-utility-bar had been REVERTED on 39 pages. Investigation: `top-utility-bar-injector.py` re-runs (it's the source generator) and overwrites the wd-utility-bar block without the role.

**Three fixes applied:**
1. Re-ran landmarks-fix injector to restore role="navigation" on 39 pages
2. **Patched top-utility-bar-injector.py source** to include `role="navigation" aria-label="Factory navigation"` by default - so future re-runs preserve the role
3. Re-ran skip-link-injector to restore id="main" on the 1 page that had lost it (conversation-intelligence-ai)
4. Re-ran landmarks-fix again to add role="main" to the freshly-id'd element

This is the iter-101 INDEX_HTML_GUARD_RESTORE pattern in action: when a generator drifts a value, the fix is to patch the generator's source, not just the surface. Otherwise the fix gets re-overwritten every cron cycle.

**Result: audit-section-landmarks 245/247 -> 248/248 OK.**

## /quality-report/ status

Before iter 148:
- 7 WARN (incl. section-landmarks 245/247)

After iter 148:
- **6 WARN** (-1: section-landmarks moved to OK)
- 46 OK (+1)
- 12 consecutive iters with 0 FAIL

**Live-check card count: 52 unchanged.** Total content invariants: 58 unchanged.

## Health hygiene

- audit-section-landmarks: 245/247 WARN -> 248/248 OK (2 footer fix + 39 nav-regression repair + 1 main fix + source patch)
- top-utility-bar-injector.py patched (source-fix, not surface-fix)
- Other audits unchanged

## Pattern: source-fix vs surface-fix discipline

This iter is a textbook example of when a surface-fix isn't enough. Iter-144 added role="navigation" to wd-utility-bar divs on 244 pages, but the SOURCE generator (top-utility-bar-injector.py) was unchanged. Over 4 days, scheduled cron runs of that generator stripped the role attribute from 39 pages.

Permanent fix: patch the source. This iter's source patch means:
- Future re-runs of top-utility-bar-injector preserve role="navigation"
- The audit will stay at 248/248 even after cron cycles
- New build pages added in the future will get role="navigation" by default

The iter-101 INDEX_HTML_GUARD_RESTORE was the original example of this pattern; iter-148 is the third or fourth iteration of it.

## Status snapshot

- 246 scored products + 2 partial builds
- 50 audit systems
- 0 fake-proof findings; 154 in warn (was 156 from iter 147 - 2 footer cleared)
- 247 brand briefs with valid archetype
- 58 content invariants defended
- /quality-report/ surfaces 52 live-check cards (0 FAIL for 12th consecutive iter, 6 warn, 46 ok)
- 77/77 health endpoints, 182+ cron jobs
- 60 min cadence active

## Iter 148 throughput note

2 substantive ships at 60-min cadence. **12 consecutive iters with 0 FAIL state — longest streak in the entire 148-iter campaign.** The source-fix discipline applied here means the section-landmarks card stays OK without re-running injectors after every cron cycle.

## Running queue (top 5 for iter 149)

1. **Wes-task: 26 placeholder CTAs + 58 paragraphs + 3 emoji + 16 pricing + 12 back-link + 8 case-studies + 4 thin + 1 fake-button = 128 editorial Wes-tasks**
2. **Check for other source-generator drift** (e.g., do og-meta-injector, jsonld-injector preserve their iter-125-126 brand-rename fixes? Re-audit cross-surface-name)
3. **Cadence-validate refresh** — 60 min cadence verified at iter 148?
4. **Pause new audits** at 50 systems
5. **Consider pivoting to non-audit work** (essays, content quality, Wes-task editorial)

## Cumulative iter 1-148

- **Catalog**: 246 scored + 2 partial
- **Content library**: 12 essays + Read-next + 273 OG PNGs + 148 styled ship-log pages + cadence-validate
- **High-trust pages**: 8 foundational + 6 transparency surfaces + 1 split-brain detail
- **Audit infrastructure**: 50 audit systems
- **Source durability**: 32+ generators + 12 read brand brief / preserve a11y attrs (top-utility-bar-injector now in the list) + 47 JSON snapshots + 182+ cron jobs
- **Content invariants**: 58 defended

The source-fix discipline turn at iter 148 is the structural-durability turn: ad-hoc surface fixes don't survive cron, but generator patches do. Future iters should default to source-fix when a generator owns the affected element.
