--- title: project-bootstrap meta-isolation block type: concept updated: 2026-05-10 --- # project-bootstrap meta-isolation block `project-bootstrap` v1.11.0 ships a meta-isolation block in the local `.gitignore` it creates / appends. Block contains `!`-inversions for `.claude/`, `.tasks/`, `.wiki/`, `.brainstorm/`, `.archive/`, `.mcp/`, `.mcp.json`, `MEMORY.md`. ## Why The global `core.excludesFile` (`~/.config/git/ignore`) hides agent meta-paths from forks of upstream open-source — see workshop wiki `concepts/meta-out-of-repo.md` (sections "Слой 2", "Новые проекты"). Without slой 2 in own repos, `setup-wiki` / `setup-tasks` / Step 5 produce `.wiki/`, `.tasks/`, `CLAUDE.md`, but git ignores them and the bootstrap commit lands empty of obvyaska. Empirically reproduced before the fix; smoke test in `assets/.gitignore.template` greenfield confirms. ## In-skill design choices - **Marker comment** — `# AI обвеска — слой 2:` (case-sensitive substring) used to detect the block on upgrade-case append. Comment text matches workshop wiki concept; chosen over checking for `!.tasks/` line because users may add their own ad-hoc `!`-rules unrelated to this block. - **Append-only on upgrade** — never rewrite or reorder existing `.gitignore`. Same discipline as Step 5's CLAUDE.md merge (idempotent, append missing). - **Block applied unconditionally in current modes.** Bootstrap's three modes (greenfield-full, add-remote, upgrade) all assume the user owns the repo. Greenfield-full creates a fresh Gitea repo; add-remote and upgrade operate on user repos. There is no fork-of-upstream mode today — if added, the block must be omitted there (putting `!.claude/` into a fork's `.gitignore` would diverge from upstream's ignore semantics). - **Template change is the load-bearing edit** — greenfield projects pick up the block by template copy. Upgrade-case append handles existing repos that bootstrapped before v1.11.0 (or were created without bootstrap). ## Acceptance proven Smoke test on greenfield (`%TEMP%\test-bootstrap-meta-iso`): 1. `.gitignore` from template contains the block — ✓. 2. `.tasks/_smoke.md` shows as untracked in `git status` — ✓. 3. First-commit candidate set includes `.tasks/`, `.wiki/`, `.claude/`, `.brainstorm/`, `MEMORY.md` — ✓. 4. Negative control — strip block, status hides all meta-paths (only `.gitignore` itself remains visible). Confirms global excludesFile is the cutter and slой 2 is what restores visibility — ✓. 5. Upgrade-case append idempotent — second run with marker present skips — ✓. ## Pointers - Source concept: `~/projects/.workshop/.wiki/concepts/meta-out-of-repo.md` - Sister action-item: `[meta-isolation-existing-repos-migration]` in `OpeItcLoc03/workshop` — one-off migration of existing own repos. - Long-term: `[meta-isolation-mcp-sync-extension]` in `OpeItcLoc03/common` — extend `projects-meta-mcp` to sync `.wiki/` + `.claude/skills/` so meta-paths can leave repo entirely.