From 549fe2ea24103b9cf8813af051a156c773453a2b Mon Sep 17 00:00:00 2001 From: OpeItcLoc03 Date: Wed, 6 May 2026 18:22:47 +0000 Subject: [PATCH] meta(wiki): ingest concepts/factory-bootstrap in factory --- .wiki/concepts/factory-bootstrap.md | 211 ++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 .wiki/concepts/factory-bootstrap.md diff --git a/.wiki/concepts/factory-bootstrap.md b/.wiki/concepts/factory-bootstrap.md new file mode 100644 index 0000000..eba1d2a --- /dev/null +++ b/.wiki/concepts/factory-bootstrap.md @@ -0,0 +1,211 @@ +--- +date: '2026-05-06' +source: .meeting-room/.archive/2026-05-06-factory-bootstrap.md +status: promoted +type: concept +title: factory-bootstrap +ingested_at: '2026-05-06T18:22:46.484Z' +ingested_by: OpeItcLoc03@DESKTOP-NSEF0UK +source_project: .meeting-room +--- +# Software factory bootstrap — design + +## Контекст и диагноз + +В `~/projects/` есть точечные папки-модули будущей "ERP": + +| Модуль | Артефакт | Состояние (на 2026-05-06) | +|---|---|---| +| HR / org chart | `.organization/` (roster.md + personas) | частично | +| Inventory / templates | `.templates/` | частично (`project/` есть, `agent/`/`report/` пусты) | +| Knowledge (local) | `.wiki/` (Karpathy) | живой | +| Knowledge (shared) | `projects-wiki` через `mcp__projects-meta__*` | живой, 13–14 страниц | +| Tasks / PMO | `.tasks/` (local) + `mcp__projects-meta__tasks_*` (shared) | живой, 14 проектов в кэше | +| Shared services | `.common/` (lib/scripts/secrets/prompts/config) | живой | +| Tooling registry | `claude-skills/` (~21 скил) | живой | +| Bus services | `.common/lib/projects-meta-mcp/`, `.common/lib/interns-mcp/` | живые | +| Communications | `.meeting-room/` | живой | + +**Что не работало для онбординга нового сотрудника:** + +1. Нет orchestrator'а — `setup-*` дёргаются по одному вручную. +2. Нет L0 entry point — пока Claude не запущен, ни один setup-* не доступен. +3. Нет manifest'а компонентов — версий, зависимостей, health-check'ов нет нигде. +4. Hardcoded `~/projects/` в путях — переезд = ручная починка. +5. Multi-vendor (Cursor / Copilot CLI / Gemini CLI): `setup-*` пишут только в `~/.claude.json`. +6. Фабрика сама не убрана. + +## Решение + +**Создать новую дот-папку `~/projects/.factory/` — отдельный репо, сиблинг `.common/`. Manifest-driven cross-platform installer/updater всей мета-инфраструктуры.** + +Размещение выбрано потому, что factory должна работать **до того**, как `.common` склонирован. L0 кладёт `.factory/` первым, дальше уже он ставит всё остальное. Альтернативы (`.common/lib/factory/`, `claude-skills/skills/factory/`) отвергнуты — обе создают cycle dependency. + +### Архитектура — три слоя + +**L0 — Pre-Claude bootstrap** (нативный shell, без runtime-зависимостей). Два под-слоя: + +**L0a — System bootstrap (toolchain).** Голая машина → готовая к работе. +- Системный пакет-менеджер: `winget` (Win11), `brew` (Mac), `apt`/`dnf`/`pacman` (Linux). +- `git` + `curl` через системный pkg-mgr. +- `mise` (бывш. rtx) — single-binary unified runtime manager. Через него `node@lts`, `python@latest`, `go@latest`, `rust` по требованию. Закрывает 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 ` переключает. + +**L1 — `factory.yaml` + `factory` CLI** (один скомпилированный Go-бинарь — см. Q1). +- 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 + 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" + ``` +- Команды: `factory install`, `factory update`, `factory status`, `factory diagnose `. +- Идемпотентность по health-check'у — re-run = no-op. + +**L2 — `setup-*` skills остаются.** Factory триггерит через печать инструкции пользователю до тех пор, пока не появится программный slash-command-bridge (см. Q3). + +### Что закрывает каждое требование + +| Требование | Решение | +|---|---| +| `~/projects` в произвольном месте | `{projects_dir}` substitution в manifest, источник — `home.toml` | +| Произвольное имя папки | То же; manifest нигде не хардкодит "projects" | +| Несколько папок на одной машине | Профили в `home.toml`; флаг `--profile` | +| Cross-platform | L0 — два нативных скрипта; L1 — single-file бинарь под Win/Mac/Linux; L2 — уже работает | +| Частичные / устаревшие установки | health_check на каждый компонент; `factory status` показывает дельту; `factory update` чинит | +| Multi-vendor | `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'а. + +## Решённые вопросы + +### Q1 — runtime для L1: Go + +Главные аргументы: размер бинаря (5–10 МБ vs 80–100 МБ 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 + +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 уже стоят на любой целевой ОС. + +### Q8 — fresh-enterprise bootstrap (greenfield-mode) + +`factory` должен уметь поднимать **пустое предприятие** — не только клонировать существующие гитеа-репы (clone-mode), но и **скаффолдить шесть мета-репо из встроенных templates**. Use case: новый юзер хочет повторить эту ERP-архитектуру в своём gitea/github namespace. + +Что уже покрыто greenfield'ом (повторно использовать): `setup-wiki`, `setup-tasks`, `project-bootstrap`. + +Что не покрыто (нужны новые скаффолды): +1. **Корневые мета-репо** — `.common/`, `.meeting-room/`, `.organization/`, `.templates/`, claude-skills-fork. +2. `setup-projects-meta` и `setup-interns` ждут готовый source-tree в gitea — нужен **`init`-mode**. + +Архитектурное предложение — добавить в `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 --git-host `. + +**Anti-recommendation:** не пытаться bootstrap'ить сам git-host (gitea/forgejo/github). Factory ожидает, что писательский git-сервер уже существует. + +Цена: +1 папка `templates/enterprise//` (6 скелетов) + per-component поле `source.template:`. ~неделя на скелеты + ~3 дня на `clone-or-init` логику. + +Не блокирует v0; реализуется параллельно после v0 production-deploy. + +## Открытые вопросы (deferred за v0) + +- **Q2 — где живёт каноничный manifest в production:** в `.factory/factory.yaml` (один на машину) или в shared Gitea с per-machine override? Склонение: "default в `.factory/` репе, override через `~/.config/factory/home.toml#overrides`". +- **Q3 — slash-command-bridge для L2:** ждать программное API от вендоров, или поднять свой через MCP-сервер `factory-mcp` (`factory_install`, `factory_status`)? +- **Q4 — версионирование manifest'а:** semver на `factory.yaml` сам? Или per-component pinned `name@v1.2.3` (npm/cargo style)? +- **Q5 — secrets:** где хранятся токены в multi-machine setup? Сейчас ad-hoc в `.common/secrets/` и `~/.config/projects-mcp/auth.toml`. +- **Q7 — access control / discoverability** (deferred to v2): иерархия видимости компонентов (`public` / `internal` / `secret`). В v0 — все `public`, secrets живут только в `.common/secrets/` с `.gitignore`. +- **Q9 — переименование `claude-skills` → `.skills`** (deferred): репо стилистически выпадает из dotfile-конвенции флота. Scope: только git-имя репо в gitea + cloned dir name. Local runtime path `~/.claude/skills/` остаётся (hardcoded в Claude Code). Когда поднимать: при дизайне `factory.yaml` v0.2 / `templates/enterprise//`. + +## v0 plan — live bootstrap нового ноута как field-test (выполнено 2026-05-06) + +Stop-condition: не сидеть в чистом дизайне до победного — у пользователя есть свежая машина, на ней проверяем дизайн руками. + +Алгоритм: +1. Узнать ОС нового ноута. +2. Бутстрапить пошагово, я директирую каждую команду. +3. Каждая команда логгируется в `.factory/L0/install-log.md` — сырьё для будущих `bootstrap.ps1` / `bootstrap.sh`. +4. После end-to-end успеха — формализуем log в скрипты. +5. Только после field-test'а — за L1 (Go-бинарь и `factory.yaml`). + +## Field-test results — 2026-05-06 + +End-to-end на новом Win11 ноуте отработал. Полный лог — `.factory/L0/install-log.md` (этот же репо). + +| Шаг | Что | Статус | +|---|---|---| +| L0a | mise + системный pkg-mgr (winget) | ✅ first-pass | +| L0b | clone `factory`, инициализация `~/.config/factory/home.toml` | ✅ | +| 11a | clone `claude-skills`, 21 скил доступен через `Skill` тул | ✅ | +| 11b | `claude login` + плагины `superpowers@claude-plugins-official` + `context7@claude-plugins-official` | ✅ (manual, browser-redirect) | +| 11c.1 | `setup-interns` — MCP-сервер, секреты в `.common/secrets/interns.env` | ✅ | +| 11c.2 | `setup-projects-meta` — repo + wiki clone + MCP entry + initial sync | ✅ idempotent re-run (всё уже было — скил детектил наличие и пошёл по path «update + verify») | +| 11c.3 | context7 sanity (`resolve-library-id "react"` → 5 matches) | ✅ | +| Фикстуры | `.organization/`, `.templates/`, `.meeting-room/` склонированы | ✅ | + +**Что подтвердилось:** + +1. **Q1 (Go для L1) валидно** — текущий L0 на mise+winget хорошо ложится в манифест, runtime-зависимостей сверху не нужно. +2. **Q6 (mise поверх системного pkg-mgr)** — отработало без сюрпризов. Mise успешно поставил node/python. +3. **`setup-projects-meta` idempotency-логика** — корректно различил «fresh install» vs «update+verify». В bootstrap.ps1 повторить. +4. **Plugin-route для context7** — правильное решение (legacy `setup-context7` скил не запускался, конфликта нет). + +**Gap'ы / кандидаты для bootstrap-скрипта** (полный список — в `install-log.md`): + +- 11b принципиально не автоматизируется (требует браузер-redirect / device-code) — bootstrap.ps1 должен **парковаться** здесь и ждать пользователя. +- Порядок 11c-скилов критичен: `interns` → `projects-meta` → плагины (или их sanity) → фикстуры. Это контракт скрипта, не выбор пользователя. +- Каждый setup-* скил уже идемпотентен — bootstrap может звать их без проверки «надо ли». Но pre-check блок самого скрипта (есть ли git, mise, claude, плагины) обязан быть. + +## Источник + +Промоушн брейнсторма из `.meeting-room/.archive/2026-05-06-factory-bootstrap.md`. Участники: user, claude-cso. Старт: 2026-05-06.