feat(skills): project-bootstrap@1.11.0 — .gitignore meta-isolation block
Step 1 now ships agent meta-paths inversions (`!.claude/`, `!.tasks/`, `!.wiki/`, `!.brainstorm/`, `!.archive/`, `!.mcp/`, `!.mcp.json`, `!MEMORY.md`) so own greenfield/upgrade projects re-enable visibility against the global `core.excludesFile` cutter (`~/.config/git/ignore`) that hides obvyaska from forks of upstream open-source. Without it any fresh bootstrap landed an empty first commit on machines with the global configured: setup-wiki/setup-tasks/Step 5 created .wiki/.tasks/CLAUDE.md but git ignored them. Two cases handled in Step 1: - no .gitignore → write template (block included unconditionally) - existing .gitignore → marker-based (`# AI обвеска — слой 2:`) append-if-missing; idempotent on re-run Smoke-tested in %TEMP%\test-bootstrap-meta-iso: all 3 acceptance criteria pass + negative control (strip block → global hides) + idempotency (re-run with marker present skips). Source concept: workshop wiki concepts/meta-out-of-repo.md. Closes board task [meta-isolation-bootstrap-skill-update]. MINOR bump (1.10.1 → 1.11.0) — new feature, backward-compat. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -724,7 +724,7 @@ Pattern для починки уже отработан в `setup-projects-meta`
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ⚪ [meta-isolation-bootstrap-skill-update] — Обновить `project-bootstrap` skill чтобы для своих новых проектов он создавал локальный `.gitignore` с `!`-инверсиями мета-путей. Без обновления любой новый bootstrap'нутый проект ломается сразу: `.tasks/`, `.wiki/`, `.claude/` создаются, но git их не видит из-за глобального `core.excludesFile`, и в первый коммит они не попадают.
|
## 🟢 [meta-isolation-bootstrap-skill-update] — Обновить `project-bootstrap` skill чтобы для своих новых проектов он создавал локальный `.gitignore` с `!`-инверсиями мета-путей. Без обновления любой новый bootstrap'нутый проект ломается сразу: `.tasks/`, `.wiki/`, `.claude/` создаются, но git их не видит из-за глобального `core.excludesFile`, и в первый коммит они не попадают.
|
||||||
|
|
||||||
**Источник:** `.workshop/.wiki/concepts/meta-out-of-repo.md` — секции «Слой 2» и «Новые проекты».
|
**Источник:** `.workshop/.wiki/concepts/meta-out-of-repo.md` — секции «Слой 2» и «Новые проекты».
|
||||||
|
|
||||||
@@ -761,10 +761,11 @@ Pattern для починки уже отработан в `setup-projects-meta`
|
|||||||
|
|
||||||
**Не делать:** не клади инверсии безусловно, без проверки что цель — свой репо. В чужих форках это потенциально создаст расхождение с upstream'ом (новый файл в `.gitignore`). Если bootstrap отрабатывает только для своих новых проектов — этот edge-case не релевантен; уточнить в коде скила.
|
**Не делать:** не клади инверсии безусловно, без проверки что цель — свой репо. В чужих форках это потенциально создаст расхождение с upstream'ом (новый файл в `.gitignore`). Если bootstrap отрабатывает только для своих новых проектов — этот edge-case не релевантен; уточнить в коде скила.
|
||||||
|
|
||||||
**Status:** ready
|
**Status:** done
|
||||||
**Where I stopped:** (not started)
|
**Where I stopped:** v1.11.0 shipped + installed. Template carries meta-isolation block; SKILL.md Step 1 documents greenfield (template) + upgrade-case marker-append. Smoke test on `%TEMP%\test-bootstrap-meta-iso` passed all 3 acceptance + negative control + idempotency. Wiki: `concepts/project-bootstrap-meta-isolation.md` + index + log entries.
|
||||||
**Next action:** Прочитать текущий `project-bootstrap` SKILL.md (`~/projects/claude-skills/skills/project-bootstrap/SKILL.md`) чтобы понять структуру шагов и где встроить запись `.gitignore`. Добавить шаг после `git init`. MINOR-bump в frontmatter version. Тестовый run на greenfield: `mkdir /tmp/test-bootstrap && cd /tmp/test-bootstrap && /project-bootstrap` (или эквивалент через агента) → проверить acceptance. Коммит: `feat(skills): project-bootstrap adds local meta-paths inversions for own projects`.
|
**Next action:** (closed)
|
||||||
**Branch:** n/a
|
**Branch:** master
|
||||||
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-10T11:04:56.068Z -->
|
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-10T11:04:56.068Z -->
|
||||||
|
<!-- closed-by: OpeItcLoc03@DESKTOP-NSEF0UK / 2026-05-10 / note: project-bootstrap v1.11.0 — .gitignore meta-isolation block (template + upgrade-case marker append); 3/3 acceptance proven via greenfield smoke + negative control + idempotency check -->
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
36
.wiki/concepts/project-bootstrap-meta-isolation.md
Normal file
36
.wiki/concepts/project-bootstrap-meta-isolation.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
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.
|
||||||
@@ -36,6 +36,7 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever
|
|||||||
- [interns-repo-read-design](concepts/interns-repo-read-design.md) — interns-repo-read-design
|
- [interns-repo-read-design](concepts/interns-repo-read-design.md) — interns-repo-read-design
|
||||||
- [hermes-skills-rollout-design](concepts/hermes-skills-rollout-design.md) — hermes-skills-rollout-design
|
- [hermes-skills-rollout-design](concepts/hermes-skills-rollout-design.md) — hermes-skills-rollout-design
|
||||||
- [tdd-criteria-design](concepts/tdd-criteria-design.md) — tdd-criteria-design
|
- [tdd-criteria-design](concepts/tdd-criteria-design.md) — tdd-criteria-design
|
||||||
|
- [project-bootstrap-meta-isolation.md](concepts/project-bootstrap-meta-isolation.md) — project-bootstrap@1.11.0 — Step 1 ships meta-isolation block in `.gitignore` (`!.claude/`, `!.tasks/`, `!.wiki/`, ...) so own greenfield/upgrade projects re-enable agent meta-paths against global `core.excludesFile` cutter. Marker-based append-only on existing files; smoke-tested with negative control
|
||||||
|
|
||||||
## Packages
|
## Packages
|
||||||
|
|
||||||
|
|||||||
@@ -55,3 +55,5 @@ Parseable: `grep "^## \[" .wiki/log.md | tail -20`.
|
|||||||
## [2026-05-07] ingest | concepts/tdd-criteria-design
|
## [2026-05-07] ingest | concepts/tdd-criteria-design
|
||||||
|
|
||||||
## [2026-05-07] review | tdd-criteria v0.2.0 — 4 findings applied: trigger-loophole fix (removed session-authorship clause), composite-tasks + refactoring sections, expanded file-extension list, clarified wrapper line-count + spike-survivor fallback + foreign-schema fix; design doc synced
|
## [2026-05-07] review | tdd-criteria v0.2.0 — 4 findings applied: trigger-loophole fix (removed session-authorship clause), composite-tasks + refactoring sections, expanded file-extension list, clarified wrapper line-count + spike-survivor fallback + foreign-schema fix; design doc synced
|
||||||
|
|
||||||
|
## [2026-05-10] decision | project-bootstrap-meta-isolation — v1.11.0 ships meta-isolation block in `.gitignore` template + Step 1 upgrade-case append; restores agent meta-paths visibility against global `core.excludesFile`; smoke-tested greenfield + negative control + idempotency
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: project-bootstrap
|
name: project-bootstrap
|
||||||
version: 1.10.1
|
version: 1.11.0
|
||||||
description: >
|
description: >
|
||||||
Initializes or upgrades a project in the current folder: git, .gitignore, README.md,
|
Initializes or upgrades a project in the current folder: git, .gitignore, README.md,
|
||||||
.wiki/ using Karpathy's method, .tasks/ for task tracking, CLAUDE.md with skill triggers.
|
.wiki/ using Karpathy's method, .tasks/ for task tracking, CLAUDE.md with skill triggers.
|
||||||
@@ -61,8 +61,37 @@ If git is not initialized:
|
|||||||
git init
|
git init
|
||||||
```
|
```
|
||||||
|
|
||||||
If `.gitignore` does not exist — create from template `assets/.gitignore.template`.
|
### `.gitignore`
|
||||||
If it exists — leave it untouched.
|
|
||||||
|
The template `assets/.gitignore.template` contains two parts:
|
||||||
|
|
||||||
|
1. Standard ignore rules (deps, build, env, IDE, OS, logs).
|
||||||
|
2. **Meta-isolation block** — `!`-inversions for `.claude/`, `.tasks/`, `.wiki/`,
|
||||||
|
`.brainstorm/`, `.archive/`, `.mcp/`, `.mcp.json`, `MEMORY.md`. This block
|
||||||
|
re-enables tracking of agent meta-paths in **own** repos against the
|
||||||
|
global `core.excludesFile` rule (`~/.config/git/ignore`) that hides them
|
||||||
|
from forks of upstream open-source. Without it, the `.tasks/`, `.wiki/`,
|
||||||
|
and `.claude/` directories created by Steps 3-5 would be invisible to git
|
||||||
|
on machines where the global excludesFile is configured, and the first
|
||||||
|
commit would be empty of agent obvyaska. Full design: workshop wiki
|
||||||
|
`concepts/meta-out-of-repo.md` (sections "Слой 2" and "Новые проекты").
|
||||||
|
|
||||||
|
Two cases:
|
||||||
|
|
||||||
|
- **`.gitignore` does not exist** — create from `assets/.gitignore.template`
|
||||||
|
(block included unconditionally).
|
||||||
|
- **`.gitignore` exists** — check for the marker line
|
||||||
|
`# AI обвеска — слой 2:` (substring match, case-sensitive). If absent →
|
||||||
|
append the meta-isolation block (with the marker comment) to the end of
|
||||||
|
the file, prefixed by a blank line if the file does not already end with
|
||||||
|
one. If present → leave the file untouched.
|
||||||
|
|
||||||
|
The block is **scoped to own projects**. The bootstrap skill currently has no
|
||||||
|
fork-of-upstream mode (greenfield-full creates a brand-new Gitea repo;
|
||||||
|
add-remote and upgrade operate on the user's own repos), so the block is
|
||||||
|
applied unconditionally in all current modes. If a fork-bootstrap mode is
|
||||||
|
ever added, the block must be **omitted** there — putting `!.claude/` etc.
|
||||||
|
into a fork's `.gitignore` would diverge from upstream's ignore rules.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -27,3 +27,14 @@ Thumbs.db
|
|||||||
# Logs
|
# Logs
|
||||||
*.log
|
*.log
|
||||||
logs/
|
logs/
|
||||||
|
|
||||||
|
# AI обвеска — слой 2: переопределяем глобальный ~/.config/git/ignore
|
||||||
|
# для своих репо (см. global wiki concept meta-out-of-repo)
|
||||||
|
!.claude/
|
||||||
|
!.tasks/
|
||||||
|
!.wiki/
|
||||||
|
!.brainstorm/
|
||||||
|
!.archive/
|
||||||
|
!.mcp/
|
||||||
|
!.mcp.json
|
||||||
|
!MEMORY.md
|
||||||
|
|||||||
Reference in New Issue
Block a user