You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Architect state files (codev/state/<name>.md, read/written by /arch-init from PR #1136) are per-person and were neither tracked nor gitignored, risking cross-team collisions if ever committed. This PR adds the ignore rule pair codev/state/*.md / !codev/state/*_thread.md to the single constant all three scaffold commands (init, adopt, update) already share, so the fix lands in all three at once, and adds a new codev doctor audit (auditStateFileIgnore) that verifies the split is actually in effect by probing real git check-ignore behavior rather than string-matching .gitignore text — which also catches an already-tracked architect state file and a shadowed-negation ordering bug that string matching would miss.
Files Changed
packages/codev/src/lib/gitignore.ts (+88) — rule pair added to CODEV_GITIGNORE_ENTRIES via two named constants (STATE_IGNORE_RULE, THREAD_KEEP_RULE), new auditStateFileIgnore() function
packages/codev/src/commands/doctor.ts (+4) — wires the audit into checkCodevStructure's existing warnings list
packages/codev/src/__tests__/gitignore.test.ts (+128) — new suites for the rule pair, an end-to-end git check-ignore validity test, and 5 auditStateFileIgnore cases
packages/codev/src/__tests__/doctor.test.ts (+24) — extended the "properly migrated" mock to answer the new git check-ignore/ls-files calls realistically
Built CLI codev init in a scratch dir → .gitignore contains the rule pair; git check-ignore codev/state/main.md ignored, git check-ignore codev/state/x_thread.md not ignored.
Compiled auditStateFileIgnore() exercised directly against scratch git repos: emits the "not gitignored" warning when the rule is absent, and the "tracked by git" warning (naming the file, recommending git rm --cached) when an architect state file was force-added.
In this worktree: git check-ignore codev/state/main.md succeeds; git check-ignore codev/state/pir-1192_thread.md does not — confirming the split is live here too.
Architecture Updates
Added to codev/resources/arch.md, appended to the existing /arch-init paragraph in Agent Farm Internals (the section already described codev/state/<name>.md state recovery, so the versioning fact belongs right next to it): the per-person/gitignored vs. builder-thread/versioned split, which constant sources the rule pair, and which function audits it.
No arch-critical.md (HOT tier) change — the file is at its 10-fact cap, and this fact is narrow enough (specific to the codev/state directory and /arch-init) that it doesn't warrant displacing an existing cross-cutting fact. The hot-tier map already points readers to "Agent Farm Internals" for state/terminal/messaging topics, which now covers this detail too.
Lessons Learned Updates
Added to codev/resources/lessons-learned.md under Testing: probe the tool's actual resolved behavior (git check-ignore on a phantom path) rather than string-matching config text when auditing config-driven behavior — string matching misses rule-ordering bugs (a negation shadowed by a later conflicting rule) and false-positives on a user's equivalent-but-differently-worded rule. This generalizes beyond gitignore to any "is this configuration actually in effect" check, so it's cold-tier reference rather than a hot-tier behavior-changer.
No lessons-critical.md (HOT tier) change, for the same cap/narrowness reasoning as above.
Things to Look At During PR Review
STATE_IGNORE_RULE/THREAD_KEEP_RULE single-sourcing (gitignore.ts:16-37): these were originally duplicated as separate literals inside auditStateFileIgnore's warning strings and in CODEV_GITIGNORE_ENTRIES. Refactored during dev-approval review to define them once and have CODEV_GITIGNORE_ENTRIES interpolate them, removing the duplicate declaration. Worth a second look that the constants are exported cleanly and nothing else in the file still hardcodes the literal strings.
Why git check-ignore over string-matching (gitignore.ts:181-232): discussed at length at the dev-approval gate — string-matching each line of CODEV_GITIGNORE_ENTRIES for presence in .gitignore would miss the shadowed-negation ordering bug (the warns when a later rule shadows the thread-file negation test case) and false-positive on a user's differently-worded-but-equivalent rule. Kept as probing real git behavior; the reasoning is captured as a lessons-learned entry above.
Scope boundary: the audit only checks the two rules this issue introduces, not the other five entries in CODEV_GITIGNORE_ENTRIES (.agent-farm/, .consult/, etc.) — those already self-heal silently via codev update/adopt and have a materially lower failure cost (clutter, not a per-person collision hazard). A general "verify all Codev gitignore entries" audit was intentionally left as a possible separate follow-up, not folded into this PR.
Run dev: afx dev pir-1192 (not applicable here — this is a CLI-only change with no dev server)
What to verify:
cd packages/codev && pnpm build && pnpm test — build and full suite green
In a scratch dir, run the built codev init, then git init and confirm git check-ignore codev/state/main.md succeeds while git check-ignore codev/state/x_thread.md fails
Run the built codev update against a .gitignore missing the rule pair — confirm it backfills both lines under a dated header
Run the built codev doctor in a repo missing the rule — confirm the new warning appears; force-add a fake codev/state/main.md and confirm doctor flags it as tracked
Low-risk change, reviewed directly (2-way consult already clean: claude + codex both APPROVE).
Actual production footprint is small and isolated despite the file count: gitignore.ts gains auditStateFileIgnore(), a well-designed audit that probes git check-ignore on phantom paths (catches real gitignore behavior, including a shadowed negation rule, rather than string-matching .gitignore text) and separately flags any architect state file already tracked from before this rule existed — exactly the pre-existing-install case the issue's doctor requirement called for. The STATE_IGNORE_RULE/THREAD_KEEP_RULE constants are shared between the gitignore template and the doctor warning text so the two can't drift apart. doctor.ts integration is a 3-line hook. Both trees updated (repo .gitignore, skeleton, this repo's own), plus the /arch-init skill doc gained a note on the per-person/thread-file split. Tests cover the new audit and the doctor warning.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PIR Review: Gitignore Architect State Files Across init/adopt/update/doctor
Fixes #1192
Summary
Architect state files (
codev/state/<name>.md, read/written by/arch-initfrom PR #1136) are per-person and were neither tracked nor gitignored, risking cross-team collisions if ever committed. This PR adds the ignore rule paircodev/state/*.md/!codev/state/*_thread.mdto the single constant all three scaffold commands (init,adopt,update) already share, so the fix lands in all three at once, and adds a newcodev doctoraudit (auditStateFileIgnore) that verifies the split is actually in effect by probing realgit check-ignorebehavior rather than string-matching.gitignoretext — which also catches an already-tracked architect state file and a shadowed-negation ordering bug that string matching would miss.Files Changed
packages/codev/src/lib/gitignore.ts(+88) — rule pair added toCODEV_GITIGNORE_ENTRIESvia two named constants (STATE_IGNORE_RULE,THREAD_KEEP_RULE), newauditStateFileIgnore()functionpackages/codev/src/commands/doctor.ts(+4) — wires the audit intocheckCodevStructure's existing warnings listpackages/codev/src/__tests__/gitignore.test.ts(+128) — new suites for the rule pair, an end-to-endgit check-ignorevalidity test, and 5auditStateFileIgnorecasespackages/codev/src/__tests__/doctor.test.ts(+24) — extended the "properly migrated" mock to answer the newgit check-ignore/ls-filescalls realisticallypackages/codev/src/__tests__/update.test.ts(+4) — updated two pre-existing scaffold: .architect-role.md missing from CODEV_GITIGNORE_ENTRIES — every fresh codev init/adopt leaves a dirty git status after first architect spawn #880 regression tests whosegitignoreAddedexpectations were exact-array-equality and needed the two new entries appended.gitignore(+4) — this repo's own gitignore gained the rule pair.claude/skills/arch-init/SKILL.md/codev-skeleton/.claude/skills/arch-init/SKILL.md(+3 each, byte-identical) — one-line versioning-stance notecodev/plans/1192-gitignore-architect-state-file.md,codev/state/pir-1192_thread.md— plan + builder thread logCommits
573b2e79[PIR Gitignore architect state files (codev/state/<name>.md) across init/adopt/update/doctor #1192] Plan draft5fde36cf[PIR Gitignore architect state files (codev/state/<name>.md) across init/adopt/update/doctor #1192] Gitignore architect state files across init/adopt/update, audit in doctorc867ce14[PIR Gitignore architect state files (codev/state/<name>.md) across init/adopt/update/doctor #1192] Repo gitignore rule pair and arch-init versioning note (both trees)7638b065[PIR Gitignore architect state files (codev/state/<name>.md) across init/adopt/update/doctor #1192] Single-source the state-file gitignore rule pairTest Results
pnpm --filter @cluesmith/codev build: ✓ passpnpm --filter @cluesmith/codev test: ✓ pass (3528 passed, 48 skipped, 0 failed; 8 new tests)npx tsc --noEmit: ✓ passcodev initin a scratch dir →.gitignorecontains the rule pair;git check-ignore codev/state/main.mdignored,git check-ignore codev/state/x_thread.mdnot ignored.codev updateagainst a pre-Gitignore architect state files (codev/state/<name>.md) across init/adopt/update/doctor #1192.gitignore→ appends exactly the two lines under a dated header.auditStateFileIgnore()exercised directly against scratch git repos: emits the "not gitignored" warning when the rule is absent, and the "tracked by git" warning (naming the file, recommendinggit rm --cached) when an architect state file was force-added.git check-ignore codev/state/main.mdsucceeds;git check-ignore codev/state/pir-1192_thread.mddoes not — confirming the split is live here too.Architecture Updates
Added to
codev/resources/arch.md, appended to the existing/arch-initparagraph in Agent Farm Internals (the section already describedcodev/state/<name>.mdstate recovery, so the versioning fact belongs right next to it): the per-person/gitignored vs. builder-thread/versioned split, which constant sources the rule pair, and which function audits it.No
arch-critical.md(HOT tier) change — the file is at its 10-fact cap, and this fact is narrow enough (specific to thecodev/statedirectory and/arch-init) that it doesn't warrant displacing an existing cross-cutting fact. The hot-tier map already points readers to "Agent Farm Internals" for state/terminal/messaging topics, which now covers this detail too.Lessons Learned Updates
Added to
codev/resources/lessons-learned.mdunder Testing: probe the tool's actual resolved behavior (git check-ignoreon a phantom path) rather than string-matching config text when auditing config-driven behavior — string matching misses rule-ordering bugs (a negation shadowed by a later conflicting rule) and false-positives on a user's equivalent-but-differently-worded rule. This generalizes beyond gitignore to any "is this configuration actually in effect" check, so it's cold-tier reference rather than a hot-tier behavior-changer.No
lessons-critical.md(HOT tier) change, for the same cap/narrowness reasoning as above.Things to Look At During PR Review
STATE_IGNORE_RULE/THREAD_KEEP_RULEsingle-sourcing (gitignore.ts:16-37): these were originally duplicated as separate literals insideauditStateFileIgnore's warning strings and inCODEV_GITIGNORE_ENTRIES. Refactored during dev-approval review to define them once and haveCODEV_GITIGNORE_ENTRIESinterpolate them, removing the duplicate declaration. Worth a second look that the constants are exported cleanly and nothing else in the file still hardcodes the literal strings.git check-ignoreover string-matching (gitignore.ts:181-232): discussed at length at the dev-approval gate — string-matching each line ofCODEV_GITIGNORE_ENTRIESfor presence in.gitignorewould miss the shadowed-negation ordering bug (thewarns when a later rule shadows the thread-file negationtest case) and false-positive on a user's differently-worded-but-equivalent rule. Kept as probing real git behavior; the reasoning is captured as a lessons-learned entry above.CODEV_GITIGNORE_ENTRIES(.agent-farm/,.consult/, etc.) — those already self-heal silently viacodev update/adoptand have a materially lower failure cost (clutter, not a per-person collision hazard). A general "verify all Codev gitignore entries" audit was intentionally left as a possible separate follow-up, not folded into this PR.How to Test Locally
pir-1192→ Review Diffafx dev pir-1192(not applicable here — this is a CLI-only change with no dev server)cd packages/codev && pnpm build && pnpm test— build and full suite greencodev init, thengit initand confirmgit check-ignore codev/state/main.mdsucceeds whilegit check-ignore codev/state/x_thread.mdfailscodev updateagainst a.gitignoremissing the rule pair — confirm it backfills both lines under a dated headercodev doctorin a repo missing the rule — confirm the new warning appears; force-add a fakecodev/state/main.mdand confirm doctor flags it as trackedFlaky Tests
None encountered.