Skip to content

feat(self): deterministic fan-out smoke test against a fixture target (closes #64) - #65

Merged
robercano-ghbot merged 2 commits into
mainfrom
feat/issue-64-fanout-smoke
Jul 7, 2026
Merged

feat(self): deterministic fan-out smoke test against a fixture target (closes #64)#65
robercano-ghbot merged 2 commits into
mainfrom
feat/issue-64-fanout-smoke

Conversation

@robercano-ghbot

Copy link
Copy Markdown
Collaborator

Closes #64 — Phase 2 of the self-host plan (#11).

What

  • examples/fixture-target/ — a tiny consumer-shaped repo (one fixture-core module over src/, node-only gates, node test).
  • .claude/self/smoke-fanout.sh — deterministic end-to-end smoke of the fan-out scaffold: stages the fixture into a temp git repo with the real gate.sh (consumer layout), plays a recorded implementer (isolated worktree → canned diff → module-boundary assert → build/lint/test gates through gate.sh → ff-merge to main), plus the failure path: a broken canned diff must fail the build gate non-zero.
  • Wired into the self adapter's test gate → runs in the existing self / test CI job on every PR. test_affected stays static-only (Stop-hook fast path).

Why deterministic (no live agents)

Option (a)+(b) from the #11 plan: live fan-outs need tokens and are nondeterministic — bad CI fit. The scaffold (worktrees, boundaries, gate plumbing, merge) is what regresses silently; that's what this locks down, on the fixture, never on the harness itself (no bootstrap regress).

The failure-path check already paid for itself

First CI-shaped run caught a real env-leak bug: the outer gate.sh exports GATES_FILE=.claude/self/gates.json; the inner fixture gate.sh inherited it, couldn't find that path in the fixture, and skipped every gate — passing vacuously on broken code. Inner gates now run env -u GATES_FILE.

Testing

  • Standalone: PASS
  • Via GATES_FILE=.claude/self/gates.json gate.sh test: PASS
  • With CI=1 (verbose runner path): PASS
  • All under the strict sandbox (git init/worktree/merge in $TMPDIR).

🤖 Generated with Claude Code

robercano and others added 2 commits July 7, 2026 12:59
…closes #64)

Phase 2 of the self-host plan (#11). smoke-fanout.sh stages
examples/fixture-target as a consumer-shaped temp repo (fixture adapter as
.claude/gates.json + the REAL gate.sh), then plays a recorded implementer:
isolated worktree -> canned diff -> module-boundary assert -> build/lint/test
gates through gate.sh -> ff-merge to main. Failure path included: a broken
canned diff must fail the build gate non-zero.

No agents, no tokens, no network - deterministic and CI-safe (option (a) from
the #11 plan). Wired into the self adapter's 'test' gate so it runs in the
'self / test' CI job on every PR; test_affected stays static-only (Stop-hook
fast path). Verified under the strict sandbox (all git ops in $TMPDIR).

The failure-path check caught a real bug during development: the outer
gate.sh's GATES_FILE leaks into the inner fixture gate.sh, which then skips
every gate (vacuous pass). Inner gates now run with env -u GATES_FILE.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NTZEsfFT4mrZpv8CY67Frd
…moke failure

CI (node 24) failed the fixture's 'node --test test/' while node 20 passed it
locally — directory-arg semantics differ across majors. Use an explicit shell
glob (test/*.test.js) instead. Also: the smoke swallowed inner gate output, so
the CI log showed only 'gate test failed' with no cause — now it prints the
gate's last 40 lines on failure and logs the toolchain versions up front.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NTZEsfFT4mrZpv8CY67Frd
@robercano-ghbot
robercano-ghbot merged commit 96ae715 into main Jul 7, 2026
9 checks passed
@robercano-ghbot
robercano-ghbot deleted the feat/issue-64-fanout-smoke branch July 7, 2026 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Self-host Phase 2: deterministic fan-out smoke test against a fixture target

2 participants