---
milestone: v1.3
audited: 2026-02-26
status: tech_debt
scores:
  requirements: 26/26
  phases: 6/6
  integration: 24/26
  flows: 3/4
gaps:
  requirements: []
  integration:
    - id: "DEVX-03-dual-inject"
      status: "partial"
      phase: "Phase 16 / Phase 17"
      description: "Dual inject_bridge_script implementations in mcp-preview/handlers/api.rs and pmcp/mcp_apps/widget_fs.rs — both must stay in sync"
      affected_requirements: ["DEVX-03", "PREV-04"]
      evidence: "mcp-preview reimplements inject_bridge_script rather than importing from pmcp core (documented decision: mcp-preview does not depend on pmcp)"
    - id: "WASM-02-e2e-bypass"
      status: "partial"
      phase: "Phase 19"
      description: "E2E tests inject mock window.mcpBridge via CDP, bypassing the App/AppBridge/PostMessageTransport chain from Phase 16"
      affected_requirements: ["WASM-02", "SHIP-03", "SHIP-04", "SHIP-05"]
      evidence: "Tests pass via mock injection; the postMessage protocol chain has no automated test coverage"
  flows:
    - id: "proxy-dual-bridge"
      description: "Proxy-served widgets receive ChatGPT skybridge from ChatGptAdapter AND postMessage App bridge from wrapWidgetHtml — duplicate bridge condition"
      affected_requirements: ["PREV-04", "DEVX-03"]
      evidence: "installCompat() overwrites window.mcpBridge, so last-registered wins; not a crash but creates confusing DevTools output"
tech_debt:
  - phase: 14-preview-bridge-infrastructure
    items:
      - "GET /api/status endpoint registered but never called from frontend (useful for external health checks)"
      - "GET /ws WebSocket route exists but frontend uses HTTP for all bridge calls"
      - "Reconnect handler response (toolCount) ignored by frontend"
  - phase: 15-wasm-widget-bridge
    items: []
  - phase: 16-shared-bridge-library
    items:
      - "Dual inject_bridge_script implementations (mcp-preview vs pmcp core) — dual maintenance surface"
  - phase: 17-widget-authoring-dx-and-scaffolding
    items:
      - "WidgetDir::inject_bridge_script is public but only consumed in unit tests"
  - phase: 18-publishing-pipeline
    items: []
  - phase: 19-ship-examples-and-playwright-e2e
    items:
      - "E2E tests validate widget UI via mock bridge but do not exercise the real postMessage bridge chain"
      - "SHIP-01/SHIP-02 requirement text says 'cargo build --features mcp-apps' but examples are workspace-excluded standalone binaries (documented deviation)"
---

# v1.3 Milestone Audit: MCP Apps Developer Experience

**Audited:** 2026-02-26
**Status:** TECH DEBT (all requirements met, no critical blockers, accumulated debt)
**Score:** 26/26 requirements satisfied

## Milestone Progress

| Metric | Score | Notes |
|--------|-------|-------|
| Requirements | 26/26 | All requirements across all 6 phases satisfied |
| Phases | 6/6 | All phases complete with verification passed |
| Integration | 24/26 | 2 partial integration points (non-blocking) |
| E2E Flows | 3/4 | 1 flow uses mock bypass (tests pass, real chain untested) |

## Completed Phase Verifications

### Phase 14: Preview Bridge Infrastructure — PASSED
- **Score:** 15/15 observable truths verified
- **Requirements:** PREV-01 through PREV-07 all SATISFIED
- **Anti-patterns:** None
- **Quality gates:** cargo check, clippy, fmt all pass

### Phase 15: WASM Widget Bridge — PASSED
- **Score:** 11/11 observable truths verified
- **Requirements:** WASM-01 through WASM-05 all SATISFIED
- **Anti-patterns:** None

### Phase 16: Shared Bridge Library — PASSED
- **Requirements:** DEVX-03, DEVX-05 SATISFIED
- **Deliverables:** packages/widget-runtime/ TypeScript library, bundled widget-runtime.mjs/js

### Phase 17: Widget Authoring DX and Scaffolding — PASSED
- **Requirements:** DEVX-01, DEVX-02, DEVX-04, DEVX-06, DEVX-07 SATISFIED
- **Deliverables:** File-based widgets, cargo pmcp app new scaffolding, WidgetCSP

### Phase 18: Publishing Pipeline — PASSED
- **Requirements:** PUBL-01, PUBL-02 SATISFIED
- **Deliverables:** cargo pmcp app manifest, cargo pmcp app landing

### Phase 19: Ship Examples and E2E Tests — PASSED
- **Score:** 18/18 observable truths verified
- **Requirements:** SHIP-01 through SHIP-05 all SATISFIED
- **Deliverables:** 3 examples (chess, map, dataviz), 20 E2E tests via chromiumoxide CDP

## Requirements Cross-Reference (3-Source)

### All Requirements Satisfied (26/26)

| Requirement | VERIFICATION.md | SUMMARY Frontmatter | REQUIREMENTS.md | Final |
|-------------|----------------|---------------------|-----------------|-------|
| PREV-01 | Phase 14: passed | 14-02 | `[x]` Complete | **satisfied** |
| PREV-02 | Phase 14: passed | 14-01 | `[x]` Complete | **satisfied** |
| PREV-03 | Phase 14: passed | 14-01 | `[x]` Complete | **satisfied** |
| PREV-04 | Phase 14: passed | 14-01 | `[x]` Complete | **satisfied** |
| PREV-05 | Phase 14: passed | 14-02 | `[x]` Complete | **satisfied** |
| PREV-06 | Phase 14: passed | 14-02 | `[x]` Complete | **satisfied** |
| PREV-07 | Phase 14: passed | 14-02 | `[x]` Complete | **satisfied** |
| WASM-01 | Phase 15: passed | 15-01, 15-02 | `[x]` Complete | **satisfied** |
| WASM-02 | Phase 15: passed | 15-02 | `[x]` Complete | **satisfied** |
| WASM-03 | Phase 15: passed | 15-01 | `[x]` Complete | **satisfied** |
| WASM-04 | Phase 15: passed | 15-01, 15-02 | `[x]` Complete | **satisfied** |
| WASM-05 | Phase 15: passed | 15-02 | `[x]` Complete | **satisfied** |
| DEVX-01 | Phase 17: passed | 17-01 | `[x]` Complete | **satisfied** |
| DEVX-02 | Phase 17: passed | 17-02 | `[x]` Complete | **satisfied** |
| DEVX-03 | Phase 16: passed | 16-01, 16-02 | `[x]` Complete | **satisfied** |
| DEVX-04 | Phase 17: passed | 17-01 | `[x]` Complete | **satisfied** |
| DEVX-05 | Phase 16: passed | 16-01, 16-02 | `[x]` Complete | **satisfied** |
| DEVX-06 | Phase 17: passed | 17-02 | `[x]` Complete | **satisfied** |
| DEVX-07 | Phase 17: passed | 17-02 | `[x]` Complete | **satisfied** |
| PUBL-01 | Phase 18: passed | 18-01 | `[x]` Complete | **satisfied** |
| PUBL-02 | Phase 18: passed | 18-02 | `[x]` Complete | **satisfied** |
| SHIP-01 | Phase 19: passed | 19-01 | `[x]` Complete | **satisfied** |
| SHIP-02 | Phase 19: passed | 19-01 | `[x]` Complete | **satisfied** |
| SHIP-03 | Phase 19: passed | 19-02 | `[x]` Complete | **satisfied** |
| SHIP-04 | Phase 19: passed | 19-02 | `[x]` Complete | **satisfied** |
| SHIP-05 | Phase 19: passed | 19-02 | `[x]` Complete | **satisfied** |

**Orphaned requirements:** None
**Unsatisfied requirements:** None

## Cross-Phase Integration

### Complete Flows (3/4)

| Flow | Status | Evidence |
|------|--------|----------|
| Developer: scaffold → add widgets → preview → publish | COMPLETE | cargo pmcp app new → cargo run → cargo pmcp preview → cargo pmcp app build |
| Widget: HTML → bridge library → MCP server → response | COMPLETE | App.connect() → PostMessageTransport → AppBridge → toolCallHandler → proxy/WASM |
| Landing: detect project → read widgets → generate demo | COMPLETE | detect_project() → load_mock_data() → generate_landing() → dist/landing.html |

### Partial Flow (1/4)

| Flow | Status | Issue |
|------|--------|-------|
| E2E: serve widgets → bridge → verify rendering | PARTIAL | Tests inject mock window.mcpBridge via CDP, bypassing App/AppBridge postMessage chain |

### Integration Risks (non-blocking)

1. **Dual `inject_bridge_script`** (DEVX-03, PREV-04) — `mcp-preview/handlers/api.rs` and `pmcp/mcp_apps/widget_fs.rs` both implement bridge injection independently. Documented design decision.

2. **E2E tests bypass bridge chain** (WASM-02, SHIP-03/04/05) — Tests validate widget UI via mock, not the postMessage transport layer.

3. **Proxy-served widgets: dual bridge** (PREV-04, DEVX-03) — ChatGPT skybridge from ChatGptAdapter AND postMessage App bridge both activate when widgets served via proxy path. `installCompat()` last-write-wins.

## Tech Debt Summary

**Total: 6 items across 4 phases**

### Phase 14: Preview Bridge Infrastructure
- `GET /api/status` registered but unused by frontend
- `GET /ws` WebSocket route unused (frontend uses HTTP)
- Reconnect handler response body ignored by frontend

### Phase 16: Shared Bridge Library
- Dual `inject_bridge_script` implementations (mcp-preview vs pmcp core)

### Phase 17: Widget Authoring DX
- `WidgetDir::inject_bridge_script` public but only consumed in unit tests

### Phase 19: Ship Examples and E2E Tests
- E2E tests validate widget UI via mock bridge, not real postMessage chain
- SHIP-01/SHIP-02 requirement text references `cargo build --features mcp-apps` but examples are workspace-excluded standalone binaries (documented deviation)

---

_Audited: 2026-02-26_
_Auditor: Claude (milestone audit orchestrator + gsd-integration-checker)_
