Merge (not clobber) managed .gitignore files on re-init

Re-init silently destroys user-added lines in `.claude/.gitignore` and `.ana/.gitignore`, and `.codex/` ships no `.gitignore` at all. Users legitimately customize these files; their additions vanish on the next `ana init` with no warning. Concretely, the Claude Code harness runtime lock `.claude/scheduled_tasks.lock` is not ignored by stock and gets swept into `ana init commit`, re-dirtying the tree every session.

verdict PASSscore 23 / 23findings 5 (0 risk · 1 debt · 4 obs)duration 2h 17mrejection cycles 0shipped Jun 9, 2026surface cli

Pipeline timeline

Intent to proven code in 2h 17m across Think, Plan, Build, and Verify.

Think
10m
Plan
15m
Build
13m
Verify
5m

Assertion ledger

23 claims, each independently verified. Showing 8 — show all →

IDSaysMatcher
A001A line a user added to .ana's ignore file survives re-setupverifiedok
A002A line a user added to Claude's ignore file survives re-setupverifiedok
A003Codex gets its own ignore file on first setup, listing its private filesverifiedok
A004A line a user added to Codex's ignore file survives re-setupverifiedok
A005Stock ignore entries are always restored even if the user deleted themverifiedok
A006Running setup twice leaves the .ana ignore file unchanged the second timeverifiedok
A007Running setup twice leaves the Claude ignore file unchanged the second timeverifiedok
A008Running setup twice leaves the Codex ignore file unchanged the second timeverifiedok

Findings 5 total

debtpackages/cli/src/commands/init/assets.tsmonitor
atomicWriteFile SHA-256 integrity-failure branch still untested; .claude/.codex gitignore writes now route through it
obspackages/cli/tests/commands/init/commit.test.tsmonitor
Stale @ana A001/A003/A004/A005/A006/A007/A013/A018/A021 tags on pre-existing commit.test.ts tests collide numerically with this contract's IDs, making grep-based @ana coverage ambiguous across contracts
obspackages/cli/src/commands/init/gitignore.tsacknowledge
Legacy migration (case 3) strips any user line equal to a current stock value anywhere in the file — a user's own copy of a stock line is absorbed into the managed block on first re-init. Documented benign (still ignored), one-time only.
obspackages/cli/src/commands/init/assets.tsacknowledge
mergeAndWriteGitignore wrapper added beyond the literal spec (which said 'route through atomicWriteFile'). Thin DRY helper used at 3 call sites — good factoring, not scope creep. Over-build check: no unused exports, no dead paths.
obsclosed
Verify worktree is 2 commits behind main, but both are .ana artifact updates for the unrelated remove-plan-phase-checkbox slug — no source overlap with this build, no conflict risk.

Provenance

Who ran what, and what it cost. Recomputable estimates from the shared price table — subordinate to the verdict, never gating.

model claude-opus-4-8
sessionturnstoolsinoutcachecost
ana58286.1k29.0k1.2M$1.82
plan66306.3k33.0k2.4M$2.61
build142717.3k50.3k6.5M$5.22
verify57286.5k21.1k1.1M$1.68
TOTAL 4 sessions$11.32 (table 2026-06-14)
churn 7 files · +692/−19
completeness ✓ complete (plan 1/1 · build 1/1 · verify 1/1)

Integrity seal

scopesha256:320c6e19bee9e...
contractsha256:4c8355461a47a...
plansha256:3ff6918b3bff3...
specsha256:a8a5e0cc8c1f4...
build-reportsha256:e843c8fc27d93...
build-datasha256:49511f56112f1...
verify-reportsha256:33a08ec49d231...
verify-datasha256:1259ca46f3e17...
audit cmd$ ana proof audit gitignore-merge-on-reinit   → all hashes match