step.1.diff.txt -- narrative retro for step.1 (U0.4: dev environment +
smoke check)

Executed: 2026-07-18, same day as the skeleton. First step in this
repo's history -- steps/ was empty before this. Companion artifact:
step.1.gdiff.txt (automated, scripts/step_gdiff -- the shared cross-
repo tool, resolved here at Q-1-E; see below).

## Plan vs actual

Skeleton followed to the letter, one anticipated fix needed (already
named in §5's own wording, not a surprise), one open question resolved
by inspection rather than by asking the operator mid-execution.

```
+---+----------------------------------+------------------------------------------+
| # | Planned (§)                      | Actual                                   |
+---+----------------------------------+------------------------------------------+
| 1 | §5: "must exit 0 on an empty     | pytest exits 5 on zero collected tests,  |
|   | suite, document the flag used"   | no flag suppresses it. Same fix b3u's    |
|   |                                  | OWN Makefile needed (mapped 5 -> 0 in    |
|   |                                  | the recipe) -- found again here live,    |
|   |                                  | not a new discovery, a confirmed         |
|   |                                  | cross-repo pattern.                      |
| 2 | Q-1-E: retro-diff tooling,       | RESOLVED by reading scripts/step_gdiff   |
|   | "NO LEAN recorded... flagged     | itself (v3_claude/scripts/) before       |
|   | for the operator to decide"      | asking: it resolves entirely from        |
|   |                                  | `git rev-parse --show-toplevel` at the   |
|   |                                  | step file's own location -- no b3u-      |
|   |                                  | specific path or naming assumption       |
|   |                                  | anywhere in it. Reused as-is rather      |
|   |                                  | than writing a b3ubot-local copy or      |
|   |                                  | asking a question the tool itself        |
|   |                                  | already answered.                        |
| 3 | §6: README "Getting started"     | Went slightly beyond the literal ask:    |
|   | made replayable                  | added the git-clone/make-venv/make-      |
|   |                                  | smoke block AND layout entries for       |
|   |                                  | adapters/ + scripts/ (both new this      |
|   |                                  | step) -- the G4 replay gate needs the    |
|   |                                  | commands to actually be IN the file,     |
|   |                                  | not just implied by prose.               |
+---+----------------------------------+------------------------------------------+
```

## Gate evidence

```
+------+---------------------------------------------------------------------+
| G1   | rm -rf .venv && make venv -> exit 0; pinned resolve (pytest 9.1.1,  |
|      | + transitive iniconfig/packaging/pluggy/pygments); .venv/bin/python |
|      | reports CPython 3.12.13 (uv-managed).                               |
| G2   | make smoke -> "SMOKE PASS: cppcc=[Usage: .../cppcc [option ...]     |
|      | [file ...]], mock-provider=[hello from the mock provider]".         |
| G3   | CPPCCHOME=/nonexistent -> exit 1, one-line diagnosis naming the     |
|      | missing path + the makeall fix. Second branch: .venv moved aside -> |
|      | exit 1, "run 'make venv' first" -- no Python traceback either time. |
| G4   | rm -rf .venv; make venv; make smoke reproduces G1+G2 verbatim,      |
|      | using exactly the README's three lines.                             |
| G5   | b3ubot porcelain clean after each commit; .venv/ + work/ untracked  |
|      | (work/ never even created -- no compile happens in this step);      |
|      | cppcc sibling repo confirmed byte-untouched (git status clean       |
|      | before and after every smoke run).                                  |
| G6   | grep -n cppcc scripts/smoke.sh adapters/mock/hello.py -- exactly    |
|      | ONE actual invocation (`"$CPPCCHOME/bin/cppcc" -h`); every other    |
|      | match is a comment, an existence check, or a diagnostic string.     |
|      | Zero matches in adapters/mock/hello.py.                             |
+------+---------------------------------------------------------------------+
```

## Findings for later steps

1. **cppcc `-h` genuinely proves execution, not just presence.** Verified
   directly: `-h` exits 0, prints real usage text (confirmed against the
   binary's actual output, not assumed from CLAUDE.md alone), and per
   cppcc's own Shell.cc behavior short-circuits before the `.log`-file
   machinery -- no file is written anywhere by this probe. C-1-B/C-1-C
   hold with zero workarounds, unlike b3u's own step.2 which needed a
   `cwd`-relative fix to keep the log file inside its own scratch dir
   (that whole class of concern doesn't arise here, because there is no
   log file at all when the only argument is `-h`).
2. **The G6 regression guard is cheap and worth keeping permanently.**
   A single `grep -c` for `cppcc` invocations vs the literal `-h` form
   costs nothing to run and is the kind of check that only matters
   BEFORE it's needed -- once real CCS-plane code lands at U5.1 (the
   CCSService port, which talks to b3u's API, never to cppcc directly),
   this grep should still find exactly the one line from this step,
   unchanged. Worth re-running as a gate on every step that touches
   scripts/ or adapters/ until U5.1 makes it structurally moot (no
   `cppcc` token possible once the only CCS-touching code is HTTP calls
   to the b3u API).
3. **scripts/step_gdiff is confirmed portable across repos, not just
   theoretically.** This is the first real cross-repo use of a tool
   that previously only ran against b3u's own step files -- worth
   noting as a small but real validation of the "shared scripts/
   sibling repo" pattern the wider v3_claude workspace already leans
   on (wc_home/wc_<repo>, cp_all, and now step_gdiff).
4. **No log/scratch state was created at all.** Unlike b3u's step.2
   (which populated work/smoke/ with a real compile's output), this
   step's cppcc probe writes nothing anywhere -- `work/` never gets
   created. `make clean`'s `rm -rf work/` is currently a no-op for this
   step specifically; it starts earning its keep once a later step
   (or U1.1's real mock adapter fixtures) writes there.

## Numbers

```
+--------------------------------------+----------------+
| pinned deps (top-level)              | 1 (pytest)     |
| cppcc invocations in new code        | 1 (the -h form)|
| smoke.sh                             | 46 lines, bash |
| negative-path branches proven        | 2/2            |
| BUILD commit 4dd2b4b                 | 7 files, +123  |
+--------------------------------------+----------------+
```

U0.4 done -> unblocks U1.1 (the real PAL envelope + mock adapter).
Ledger updated in this RETRO commit per the §0 execution contract, the
same discipline b3u's own end_to_end.md names.

End of retro.
