# REF-2158: Evolve-Run-20260330-221843

**Applies to:** FXA project
**Last updated:** 2026-03-30
**Last reviewed:** 2026-03-30
**Status:** Active

---

## What Is It?

Evolve-CLI run log for 2026-03-30. Records signals, candidates, scores, and outcomes.

---

## Signals

### Test Failures
None. 387 tests pass (pytest 4.38s).

### Code Quality (Ruff)
0 issues.

### Coverage (94% overall)
| Module | Coverage | Missing Lines |
|--------|----------|---------------|
| create_cmd.py | 89% | 164, 280, 285, 310, 312, 314, 320, 322, 327, 330, 336-337, 344, 348, 354, 374, 381, 414-415, 420, 431, 433, 445, 476-478 |
| fmt_cmd.py | 90% | 46, 102, 177, 194, 220, 237, 245, 261, 323-324, 358-360, 370-373, 378-379, 404-409 |
| status_cmd.py | 89% | 22-30 |
| update_cmd.py | 91% | 43-44, 210, 220, 225, 273, 286, 367, 392-393, 404-410, 427-428 |
| validate_cmd.py | 92% | 59, 69, 125-127, 131-132, 178-179, 194-195 |

### Source Analysis
- **assert for validation** in create_cmd.py:376,449 — stripped in `python -O`
- **No bounds check** in guide_cmd.py:83 — `active_docs[0]` without empty guard
- **Silent exception** in search_cmd.py:39 — swallows errors without diagnostics
- **scanner.py:64-65** — catches NotADirectoryError/FileNotFoundError but not PermissionError

### SOP vs Code Gaps
- FXA-2102 (Release): no CLI automation (out of evolve scope)
- FXA-2127 (Commit): no CLI automation (out of evolve scope)
- COR-1300 (Update): missing cross-reference checking (out of evolve scope)
- COR-1302 (Index): PRJ-only; no COR-0000 or USR layer support (out of evolve scope)

## Candidates

| # | Candidate | TV | SR | BC | N | Score | Pass |
|---|-----------|----|----|----|----|-------|------|
| C1 | Replace assert with ClickException in create_cmd.py | 10 | 10 | 10 | 9 | 9.85 | Yes |
| C2 | Add empty-list guard in guide_cmd.py | 9 | 10 | 10 | 7 | 9.20 | Yes |
| C3 | Catch PermissionError in scanner.py | 8 | 10 | 10 | 6 | 8.70 | Yes |
| C4 | Add coverage for status_cmd.py | 10 | 8 | 10 | 5 | 8.65 | Yes |
| C5 | Add stderr warning in search_cmd.py | 7 | 9 | 8 | 6 | 7.65 | Yes |
| C6 | Extract JSON output helper | 7 | 4 | 10 | 3 | 6.10 | No |
| C7 | Extract resource-read helper | 7 | 4 | 10 | 3 | 6.10 | No |

**Implementing this run:** C1 (highest score, clearest evidence).
**Deferred to future runs:** C2, C3, C4, C5.

## Implementation

### C1: Replace assert with ClickException in create_cmd.py

**Problem:** Lines 376 and 449 use `assert final_acid is not None`. Python's `-O` flag strips assertions, making this a silent no-op that leads to downstream `None` usage.

**Fix:** Replace with `if ... is None: raise click.ClickException(...)` with distinct messages per code path.

**PRP:** FXA-2159 — Gemini 9.5 PASS, Codex R1 7.5 FIX, Codex R2 9.0 PASS
**CHG:** FXA-2160 — Gemini 9.4 PASS, Codex 9.2 PASS
**TDD:** 2 new tests, 389 total pass, 0 ruff issues
**Issue:** #4
**Branch:** chore/4-evolve-cli-20260330

---

## Change History

| Date | Change | By |
|------|--------|----|
| 2026-03-30 | Initial version | — |
| 2026-03-30 | Completed: C1 implemented, all gates passed | Claude |
