BOHICA-LABS / BOHICA-LABS/vsdd-factory

bug(factory-health + repo-initialization): factory artifact tracked on product branch — .gitignore added without git rm --cached leaves split-brain copy, undetected

Open
#341 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
2
Forks
1
Avg merge
6h 43m
Merged PRs (30d)
29

Description

## Summary

A factory artifact (`.factory/cycles/v1.0.0-greenfield/implementation/red-gate-log.md`) is tracked on the PRODUCT branch (`develop`) even though `.factory/` is listed in `.gitignore`. This produces a split-brain: the same path is tracked on BOTH `develop` (stale, 182 lines) and `factory-artifacts` (live, 317 lines — the copy agents actually write to). The `develop`-tracked copy shows as perpetually "modified" in the main worktree, blocked a clean fast-forward merge, and was accidentally swept (+74 lines) into an unrelated product PR merge.

`.gitignore` rules never untrack an already-tracked path. So adding `.factory/` to `.gitignore` without a paired `git rm --cached` is a silent no-op for any file already committed — and there is no health check that detects the leak.

## Environment

vsdd-factory plugin 1.0.0-rc.21, Claude Code, greenfield+wave mode. `.factory/` mounted as a git worktree on the `factory-artifacts` orphan branch; product code on `develop` (gitflow). Repo: private.

## Root cause (reconstructed from git history)

1. An early feature PR (commit `aeb442d`, "feat(S-W3.04): full daemon assembly") committed `red-gate-log.md` into `.factory/cycles/...` on `develop` — BEFORE any ignore rule existed for `.factory/`. A factory artifact entered product history through a normal feature commit. (This also points to a gap: code-delivery PRs should never include `.factory/` paths; a pre-PR guard could have caught it.)
2. A later cleanup PR (commit `36c5e98`, "chore: remove leftover kos process scaffolding") ADDED `.factory/` (and `.factory`) to `.gitignore` — but did NOT run `git rm --cached` on the already-tracked file. Git ignore rules do not untrack already-tracked paths, so it remained tracked.
3. Subsequent factory writes updated the `factory-artifacts` copy; the `develop` copy stayed frozen and divergent → split-brain + perpetual dirty status.

## Evidence

- `git ls-files '.factory/*'` on `develop` returns exactly one path: `.factory/cycles/v1.0.0-greenfield/implementation/red-gate-log.md`
- Same path is tracked on `factory-artifacts` too; contents differ (`develop` 182 lines vs `factory-artifacts` 317 lines).
- `git check-ignore -v .factory/STATE.md` → matches the `.gitignore` `.factory/` rule (rule IS present, but post-dates the tracked file).
- The stale `develop` copy received +74 lines in a product-PR merge diff (factory content leaking into a product PR).

## Impact

- (a) Perpetual "modified" noise in main worktree `git status`
- (b) Blocks clean FF merges
- (c) Factory content silently rides along in product PR diffs
- (d) Split-brain content divergence between the two branches for the same path
- (e) Sets up the data-loss landmine documented in the companion issue (nested-worktree silent delete)

## Proposed fix (defense in depth)

1. **`factory-health` / `factory-worktree-health` skill:** add a check that runs `git ls-files '.factory/*'` on the PRODUCT branch and flags/offers `git rm --cached` for each leaked path. Today `factory-health` checks worktree mount/branch/structure but NOT whether factory paths leaked into product tracking.
2. **Whatever step adds `.factory/` to `.gitignore`** (`repo-initialization` or a cleanup skill) must ALSO run `git rm --cached -r --ignore-unmatch .factory` so already-tracked files are untracked at the same time the ignore rule lands. Adding an ignore rule without `rm --cached` is a no-op for existing tracked files.
3. **(Optional, smaller)** A `code-delivery` pre-PR guard that rejects any staged `.factory/*` path on a product feature branch.

## Related issues (distinct, cross-referenced)

- **#263** — PO agent introduced `.factory` as a tracked GITLINK (mode 160000), scope-overreach. Different mechanism (gitlink vs a normal tracked file leaked pre-ignore); same theme of "missing parent-repo `.gitignore` guard". The #263 family fix is a one-shot bootstrap; this issue shows the protection is not durable and a pre-existing tracked file goes undetected.
- **#313** — Phase-1 CI/CD artifacts never committed, orphaned on disk. Opposite problem (artifacts NOT tracked); related theme of code-branch vs factory-branch artifact routing.
- **#250 / #240** — agents commit but don't push / drop commit step; adjacent artifact-routing hygiene.

## Acceptance criteria

- [ ] `factory-health` detects and offers to untrack any `.factory/*` path tracked on the product branch.
- [ ] The skill that adds `.factory/` to `.gitignore` also runs `git rm --cached` for already-tracked factory paths.
- [ ] Cross-link to #263 (parent-repo guard family) and the companion nested-worktree data-loss issue.

---

_Plugin `vsdd-factory 1.0.0-rc.21`, Claude Code. Filed from a private downstream project; no private content included._

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.