Files
discussions/.brainstorm/factory-bootstrap.md
vitya 8ddcf0dd27 Brainstorm Q8: greenfield-mode (fresh-enterprise bootstrap)
Surfaced 2026-05-06 during factory-bootstrap field-test on Win11 laptop.
Decision: factory MUST support installing a fresh empty enterprise
(no existing gitea content) — not just cloning the existing one.

Three of five setup-* skills already cover greenfield (setup-wiki,
setup-tasks, project-bootstrap). Two need init-mode (projects-meta,
interns). Six root meta-repos have no templates anywhere — must add
templates/enterprise/<repo>/ skeletons. Anti-rec: do NOT bootstrap
the git-host itself — that's L0a infra, not L1 (factory).

Implementation deferred to post-v0; not blocking clone-mode v0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 15:52:43 +03:00

211 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
topic: factory-bootstrap
started: 2026-05-06
participants: [user, claude-cso]
status: in-progress
problem: >
Установка/обновление инфраструктуры software factory (точечные папки в ~/projects/,
shared MCP-сервера, скилы) для нового сотрудника должна быть "одной кнопкой" —
кросс-платформенной, идемпотентной, нечувствительной к расположению/имени projects-папки,
поддерживающей несколько папок проектов на одной машине, частичные/устаревшие установки
и разные AI-клиенты (Claude Code / Copilot CLI / Gemini CLI).
---
# Software factory bootstrap — design buffer
## Контекст и диагноз (как это выглядит сейчас)
В `~/projects/` есть 6 точечных папок-модулей будущей "ERP":
| Модуль | Артефакт | Состояние |
|---|---|---|
| HR / org chart | `.organization/` (roster.md + personas) | частично (CSO/Dev/Analyst в roster, personas/permissions упомянуты но не наполнены) |
| Inventory / templates | `.templates/` | `project/` — частично (`python-package`, `with-wiki-tasks`); `agent/`, `report/` — пустые |
| Knowledge | `.wiki/` (local Karpathy) | живой |
| Knowledge (shared) | `projects-wiki` через `mcp__projects-meta__*` | живой, 13 страниц |
| Tasks / PMO | `.tasks/` (local) + `mcp__projects-meta__tasks_*` (shared) | живой, 13 проектов в кэше |
| Shared services | `.common/` (lib/scripts/secrets/prompts/config) | живой |
| Tooling registry | `claude-skills/` (~20 скилов: 5 setup-*, project-bootstrap, using-*, caveman-*) | живой |
| Bus services | `.common/lib/projects-meta-mcp/`, `.common/lib/interns-mcp/` | живые |
| Communications | `.meeting-room/` | живой (cwd) |
**Что не работает для онбординга нового сотрудника:**
1. Нет orchestrator'а`setup-*` дёргаются по одному вручную из живого Claude.
2. Нет L0 entry point — пока Claude не запущен, ни один setup-* не доступен (chicken-and-egg).
3. Нет manifest'а компонентов — версий, зависимостей, health-check'ов нет нигде; `factory.yaml` отсутствует.
4. Hardcoded `~/projects/` в путях (например `.common/lib/projects-meta-mcp/dist/sync.js`) — переезд / переименование = ручная починка.
5. Multi-vendor (Cursor / Copilot CLI / Gemini CLI): `using-superpowers` уже это учитывает, но `setup-*` пишут только в `~/.claude.json`.
6. `meeting-room` / `meeting-room2` — дубликаты, фабрика сама не убрана.
7. В кросс-проектных задачах ничего нет про factory bootstrap (релевантные находки: только `web4-phase0-bootstrap` в stostayer.new и `active-platform-eval` в claude-skills). В shared wiki — пусто (`knowledge_search "factory bootstrap onboarding new machine"` → 0 hits).
## Рекомендация (decided)
**Создать новую дот-папку `~/projects/.factory/` — отдельный репо, сиблинг `.common/`. Manifest-driven cross-platform installer/updater всей мета-инфраструктуры.**
Размещение **(a)** выбрано потому, что factory должна работать **до того**, как `.common` склонирован. L0 кладёт `.factory/` первым, дальше уже он ставит всё остальное. Альтернативы (b) `.common/lib/factory/` и (c) `claude-skills/skills/factory/` отвергнуты: обе создают cycle dependency на свои родительские модули.
### Архитектура — три слоя
**L0 — Pre-Claude bootstrap** (нативный shell, без runtime-зависимостей). Разбит на два под-слоя:
**L0a — System bootstrap (toolchain).** Голая машина → готовая к работе.
- Системный пакет-менеджер: `winget` (Win11, встроен), `brew` (Mac, `curl … | bash`), `apt`/`dnf`/`pacman` (Linux native).
- `git` + `curl` через системный pkg-mgr.
- `mise` (бывш. rtx) — single-binary unified runtime manager. Через него `node@lts`, `python@latest`, `go@latest`, `rust` по требованию. Кросс-платформенно, без root, один `mise.toml` на проект. Закрывает nvm/pyenv/goenv одной зависимостью.
- Опционально, с интерактивным диалогом (yes/no/skip): Claude Code, Cursor, VS Code, Ollama, Docker Desktop.
**L0b — Factory bootstrap.** Запускается после L0a.
- `bootstrap.ps1` + `bootstrap.sh` — запуск через `iwr … | iex` / `curl … | bash`
- Делает только: detect platform → спросить `$PROJECTS_DIR` → clone `.factory/` (gitea) → передать управление в L1
- Единое состояние машины: `~/.config/factory/home.toml` со схемой:
```toml
projects_dir = "C:/Users/vitya/projects"
client = "claude-code" # | "copilot-cli" | "gemini-cli"
installed_at = "2026-05-06T..."
```
- Если на машине несколько `projects_dir` — `home.toml` хранит активный, флаг `--projects-dir <path>` переключает.
**L1 — `factory.yaml` + `factory` CLI** (один скомпилированный бинарь — Go или deno-single-file)
- Manifest-схема (черновик):
```yaml
components:
- name: dot-common
source: { type: git, url: "{gitea}/.common" }
target: "{projects_dir}/.common"
health_check: "test -f {target}/scripts/claude-switch.ps1"
- name: projects-meta-mcp
source: { type: git, url: "{gitea}/projects-meta-mcp" }
target: "{projects_dir}/.common/lib/projects-meta-mcp"
deps: [dot-common]
setup_skill: setup-projects-meta # делегируется в L2
health_check: "mcp_tool_available mcp__projects-meta__meta_status"
- name: dot-wiki
target: "{projects_dir}/.wiki"
deps: [projects-meta-mcp]
setup_skill: setup-wiki
health_check: "test -f {target}/CLAUDE.md && test -f {target}/index.md"
- name: claude-skills
source: { type: git, url: "{gitea}/claude-skills" }
target: "{projects_dir}/claude-skills"
post_install: "bash {target}/scripts/install.sh"
health_check: "test -d ~/.claude/skills/project-bootstrap"
# ... .organization, .templates, .meeting-room, dot-tasks, interns-mcp
```
- Команды:
- `factory install` — пройти DAG зависимостей, поставить всё что не прошло health-check
- `factory update` — git pull + re-run health-checks
- `factory status` — таблица: `name | version | health | deps`
- `factory diagnose <name>` — verbose run health-check, печать stderr
- Идемпотентность по health-check'у — re-run = no-op.
**L2 — `setup-*` skills остаются как есть.** `factory` их триггерит через печать инструкции пользователю ("запусти `/setup-projects-meta`") до тех пор, пока не появится программный slash-command-bridge. Когда появится — `setup_skill: <name>` будет вызываться напрямую.
### Что закрывает каждое требование
| Требование | Решение |
|---|---|
| Папка `~/projects` в произвольном месте | `{projects_dir}` substitution в manifest, источник — `~/.config/factory/home.toml` |
| Произвольное имя папки | То же; manifest нигде не хардкодит "projects" |
| Несколько папок на одной машине | Несколько профилей в `home.toml` (`[profiles.work]`, `[profiles.personal]`); флаг `--profile` |
| Cross-platform | L0 — два нативных скрипта; L1 — single-file бинарь под Win/Mac/Linux; L2 — уже работает |
| Частичные / устаревшие установки | health_check на каждый компонент; `factory status` показывает дельту; `factory update` чинит |
| Multi-vendor (не только Anthropic) | `client` в `home.toml`; manifest-компоненты помечены `clients: [claude-code, copilot-cli]`; не-совместимые скипаются |
### Anti-recommendations (чего не делать)
- Один монолитный bash/ps скрипт без manifest'а — за год превратится в legacy.
- Python-orchestrator с pip-зависимостями — сам требует bootstrap'а python (тот же chicken-and-egg).
- Повторять логику установки в L0 и L2. health_check — single source of truth.
- Складывать `factory` в `claude-skills/` — фабрика > tooling; claude-skills должен быть **компонентом** manifest'а, не корнем.
## Quick wins (параллельные, не блокируют дизайн)
- Заполнить пустые `.templates/agent/`, `.templates/report/`.
- Разобрать duplicate `meeting-room` / `meeting-room2`.
- После promotion — заингестить итог в shared wiki как `concepts/factory-bootstrap` (через `knowledge_ingest`).
- Завести в `claude-skills/.tasks/` задачу `factory-bootstrap-design` со ссылкой на promoted concept.
## Открытые вопросы
### Решённые
- **Q1 — runtime для L1**: ✅ **Go**. Решено 2026-05-06.
- Главные аргументы: размер бинаря (510 МБ vs 80100 МБ Deno), старт ~5 мс, тривиальная кросс-компиляция (включая Win/macOS ARM), `go-git/go-git` снимает зависимость от системного git, cobra даёт shell-completion из коробки.
- Стек: Go 1.23+, `go-git/go-git`, `goccy/go-yaml`, `spf13/cobra`, опционально `charmbracelet/lipgloss`. Поставка — pre-built бинари в `.factory/dist/`, скачиваются L0b.
- Контраргументы (Deno/Rust/Bun) отброшены: Deno слишком жирный для curl-pipe, Rust learning curve не оправдывает экономию 5 МБ, Bun на Windows ARM ещё не дозрел.
- **Q6 — toolchain layer в L0**: ✅ **`mise` поверх системного pkg-mgr**. Решено 2026-05-06.
- L0a: системный pkg-mgr (winget/brew/apt) → ставит git + curl + mise → mise ставит node/python/go/rust.
- Опциональный интерактивный слой: Claude Code, Cursor, VS Code, Ollama, Docker Desktop.
- Не отдельные nvm + pyenv + goenv — у каждого свой bootstrap, mise унифицирует.
- Не свой пакет-менеджер — winget/brew/apt уже стоят на любой целевой ОС.
### Открытые
- **Q2 — где живёт каноничный manifest в production**: в `.factory/factory.yaml` (один на машину) или в shared Gitea с per-machine override? Склоняюсь к "default в `.factory/` репе, override через `~/.config/factory/home.toml#overrides`".
- **Q3 — slash-command-bridge для L2**: ждать пока Anthropic / другие вендоры дадут программное API, или поднять свой через MCP-сервер `factory-mcp` (тулы: `factory_install`, `factory_status`)? Второе — независимее, но стоит ещё одного сервера.
- **Q4 — версионирование manifest'а**: semver на `factory.yaml` сам? Или per-component версии в pinned-формате `name@v1.2.3`? Last вероятно правильнее, повторяет npm/cargo.
- **Q5 — secrets**: где хранятся токены (gitea, ollama, anthropic) в multi-machine setup? Сейчас ad-hoc в `.common/secrets/` и `~/.config/projects-mcp/auth.toml`. factory должен это унифицировать.
- **Q7 — access control / discoverability** (deferred to v2): иерархия видимости компонентов фабрики (`public` / `internal` / `secret`) с фильтром при `factory install`. В v0 — все компоненты `public`, secrets живут только в `.common/secrets/` с `.gitignore`. Не блокирует v0.
- **Q8 — fresh-enterprise bootstrap (greenfield-mode дистрибутива)**: должен ли `factory` уметь поднимать **пустое предприятие** — не клонировать существующие гитеа-репы (clone-mode), а **скаффолдить шесть мета-репо из встроенных templates**?
- **Use case:** новый юзер хочет повторить эту ERP-архитектуру у себя — у него есть свой gitea/github namespace, но нет ни `.common/`, ни `.meeting-room/`, ни `.organization/`, ни `.templates/`, ни `claude-skills`-форка, ни `projects-meta-mcp` source-tree. Должен иметь возможность сделать `factory init my-enterprise --git-host https://my-gitea.example.com/myorg` — фабрика создаёт пустые репы, пушит скелеты, потом идёт обычный `factory install`.
- **Status:** ✅ нужно поддерживать. Решение принято на field-test'е 2026-05-06; реализация отложена в production-фазу.
- **Что уже покрыто greenfield'ом** (повторно использовать как есть): `setup-wiki` (пустая Karpathy-вики), `setup-tasks` (пустой STATUS.md с легендой), `project-bootstrap` (CLAUDE.md/.gitignore/README в любой папке).
- **Что не покрыто** (нужны новые скаффолды):
1. **Корневые мета-репо** — `.common/`, `.meeting-room/`, `.organization/`, `.templates/` сам, claude-skills-fork. У них нет templates ни в одном из существующих скилов. Сейчас они выросли органически, готовые лежат в `git.kzntsv.site/OpeItcLoc03/`. Для нового предприятия их надо родить.
2. `setup-projects-meta` и `setup-interns` ждут готовый source-tree в gitea — нужен **`init`-mode** (форкать из template-репа `factory/templates/...` либо inline-scaffold).
- **Архитектурное предложение** — добавить в `factory.yaml` per-component `clone-or-init`-источник:
```yaml
components:
- name: dot-common
source:
type: clone-or-init
url: "{gitea}/common" # сперва пробуем clone
template: "{factory}/templates/enterprise/common" # fallback — scaffold + init+push
```
И команда `factory init <enterprise-name> --git-host <url>` — создаёт пустые репы в namespace юзера, пушит scaffolded skeletons, далее обычный `factory install`.
- **Anti-recommendation:** **не** пытаться bootstrap'ить сам git-host (gitea/forgejo/github). Factory ожидает, что писательский git-сервер уже существует и юзер имеет туда write-access. Подъём гитеа — это L0a infra-задача (winget/docker-compose), не L1 (factory).
- **Цена:** +1 папка `templates/enterprise/<repo>/` (6 скелетов: `common`, `meeting-room`, `organization`, `templates`, `projects-meta-mcp-skeleton`, `interns-mcp-skeleton`) + per-component поле `source.template:` в manifest. Оценка: ~неделя на скелеты + ~3 дня на `clone-or-init` логику в Go-биноре.
- **Зависимости:** не блокирует v0 (clone-mode достаточно для текущего fleet'а из 1 юзера + новой машины). Реализуется параллельно после v0 production-deploy.
## v0 plan — live bootstrap нового ноута как field-test
Stop-condition этого подхода: **не сидеть в чистом дизайне до победного — у пользователя есть свежая машина, на ней проверяем дизайн руками**.
Алгоритм:
1. Узнать ОС нового ноута (Q6 ответ — определяет первую команду L0a).
2. Бутстрапить машину пошагово, я директирую каждую команду.
3. Каждая выполненная команда логгируется в `.factory/L0/install-log.md` — это сырьё для будущих `bootstrap.ps1` / `bootstrap.sh`.
4. После того как factory поднимется на новом ноуте end-to-end (включая `setup-projects-meta`, `setup-interns`, claude-skills install, `.wiki`/`.tasks`/`.organization` clone), формализуем log в скрипты.
5. Только после успешного field-test'а садимся за L1 (Go-бинарь и `factory.yaml`).
**Артефакты этого этапа:**
- `.factory/L0/install-log.md` — пошаговый лог команд (на новом ноуте).
- Diff между "что я сделал руками" и "что должен делать L0 скрипт" — readme-черновик `.factory/L0/README.md`.
- Список найденных gaps (что не получилось / что было неочевидно) — кандидаты в Q-список.
## Действия после промоушена
1. `meeting-room-promote-brainstorm factory-bootstrap` →
- shared wiki: `concepts/factory-bootstrap` (целевой проект — `_meta` или новый `factory`)
- `claude-skills/.tasks/`: `factory-bootstrap-design` (status=ready, next_action="ответить на Q1Q5, прототипировать L0")
- `.archive/2026-05-06-factory-bootstrap.md`
## Resume point — 2026-05-06 (перерыв)
Field-test на новом Win11 ноуте идёт. Полный пошаговый лог + текущее состояние шагов — в `.factory/L0/install-log.md` (запушено в `git.kzntsv.site/OpeItcLoc03/factory`).
Краткий summary: L0a (toolchain) ✅, L0b (factory clone + home.toml) ✅, 11a (claude-skills + 21 skill) ✅. Юзер в перерыв сам прогоняет 11b (claude login + плагины superpowers/context7). После возвращения — 11c (setup-* скилы по очереди).
Основной артефакт field-test'а: список **gap'ов для bootstrap.ps1**, накапливающийся в install-log.md в секции "Gaps / questions surfaced during field-test". Когда field-test завершится — этот список напрямую конвертируется в скрипт.
## Stop-condition этого буфера
Дизайн доводится до состояния, где открытые вопросы Q1Q5 закрыты. После — promote и переход в плановую фазу (L0 → L1 → manifest → миграция существующих setup-* в L2-делегирование).