Wiki: factory/.wiki/concepts/factory-bootstrap.md (full design + Q1/Q6/Q8 decisions + Q2-Q5/Q7/Q9 deferred + 2026-05-06 field-test results). Tasks: factory#factory-bootstrap-script (ready), factory#factory-l1-design (blocked-by script). Side-task: claude-skills#project-creation-lifecycle-skill (gap surfaced — ad-hoc project creation strands repos outside projects-meta indexing until manual seed). Buffer moved to .archive/2026-05-06-factory-bootstrap.md.
23 KiB
topic, started, participants, status, problem
| topic | started | participants | status | problem | ||
|---|---|---|---|---|---|---|
| factory-bootstrap | 2026-05-06 |
|
ready-to-promote | Установка/обновление инфраструктуры 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) |
Что не работает для онбординга нового сотрудника:
- Нет orchestrator'а —
setup-*дёргаются по одному вручную из живого Claude. - Нет L0 entry point — пока Claude не запущен, ни один setup-* не доступен (chicken-and-egg).
- Нет manifest'а компонентов — версий, зависимостей, health-check'ов нет нигде;
factory.yamlотсутствует. - Hardcoded
~/projects/в путях (например.common/lib/projects-meta-mcp/dist/sync.js) — переезд / переименование = ручная починка. - Multi-vendor (Cursor / Copilot CLI / Gemini CLI):
using-superpowersуже это учитывает, ноsetup-*пишут только в~/.claude.json. meeting-room/meeting-room2— дубликаты, фабрика сама не убрана.- В кросс-проектных задачах ничего нет про 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со схемой: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-схема (черновик):
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-checkfactory update— git pull + re-run health-checksfactory status— таблица:name | version | health | depsfactory 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.
- Главные аргументы: размер бинаря (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 ещё не дозрел.
- Главные аргументы: размер бинаря (5–10 МБ vs 80–100 МБ Deno), старт ~5 мс, тривиальная кросс-компиляция (включая Win/macOS 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-mcpsource-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 в любой папке). - Что не покрыто (нужны новые скаффолды):
- Корневые мета-репо —
.common/,.meeting-room/,.organization/,.templates/сам, claude-skills-fork. У них нет templates ни в одном из существующих скилов. Сейчас они выросли органически, готовые лежат вgit.kzntsv.site/OpeItcLoc03/. Для нового предприятия их надо родить. setup-projects-metaиsetup-internsждут готовый source-tree в gitea — нуженinit-mode (форкать из template-репаfactory/templates/...либо inline-scaffold).
- Корневые мета-репо —
- Архитектурное предложение — добавить в
factory.yamlper-componentclone-or-init-источник:И командаcomponents: - name: dot-common source: type: clone-or-init url: "{gitea}/common" # сперва пробуем clone template: "{factory}/templates/enterprise/common" # fallback — scaffold + init+pushfactory 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.
- Use case: новый юзер хочет повторить эту ERP-архитектуру у себя — у него есть свой gitea/github namespace, но нет ни
-
Q9 — переименование
claude-skills→.skills(deferred): репоclaude-skillsстилистически выпадает из dotfile-конвенции флота (.common/,.organization/,.meeting-room/,.templates/,.wiki/,.tasks/) и фиксирует в имени один движок, хотяsuperpowers:using-superpowersуже ссылается на Copilot CLI / Codex / Gemini tool mappings. Озвучено пользователем 2026-05-06 во время field-test'а, явно «но позже».- Scope переименования: только git-имя репо в gitea + cloned dir name. Local runtime path
~/.claude/skills/остаётся (hardcoded в Claude Code). Frontmatter скилов с Claude-specific tool names не трогается —references/copilot-tools.md/codex-tools.mdуже покрывают cross-platform. - Когда поднимать: (a) при дизайне
factory.yamlv0.2 /templates/enterprise/<repo>/— естественный момент менять имена; (b) при общем рефакторинге фикстур-репо. Не блокирует v0.
- Scope переименования: только git-имя репо в gitea + cloned dir name. Local runtime path
v0 plan — live bootstrap нового ноута как field-test
Stop-condition этого подхода: не сидеть в чистом дизайне до победного — у пользователя есть свежая машина, на ней проверяем дизайн руками.
Алгоритм:
- Узнать ОС нового ноута (Q6 ответ — определяет первую команду L0a).
- Бутстрапить машину пошагово, я директирую каждую команду.
- Каждая выполненная команда логгируется в
.factory/L0/install-log.md— это сырьё для будущихbootstrap.ps1/bootstrap.sh. - После того как factory поднимется на новом ноуте end-to-end (включая
setup-projects-meta,setup-interns, claude-skills install,.wiki/.tasks/.organizationclone), формализуем log в скрипты. - Только после успешного field-test'а садимся за L1 (Go-бинарь и
factory.yaml).
Артефакты этого этапа:
.factory/L0/install-log.md— пошаговый лог команд (на новом ноуте).- Diff между "что я сделал руками" и "что должен делать L0 скрипт" — readme-черновик
.factory/L0/README.md. - Список найденных gaps (что не получилось / что было неочевидно) — кандидаты в Q-список.
Field-test results — 2026-05-06
End-to-end на новом Win11 ноуте отработал. Полный лог — .factory/L0/install-log.md (git.kzntsv.site/OpeItcLoc03/factory).
| Шаг | Что | Статус |
|---|---|---|
| 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/ склонированы |
✅ |
Что подтвердилось:
- Q1 решение (Go для L1) валидно — текущий L0 на mise+winget хорошо ложится в манифест, runtime-зависимостей сверху не нужно.
- Q6 решение (mise поверх системного pkg-mgr) — отработало без сюрпризов. Mise успешно поставил node/python.
setup-projects-metaidempotency-логика — корректно различил «fresh install» vs «update+verify». В bootstrap.ps1 повторить эту же pre-check логику.- Plugin-route для context7 — правильное решение (legacy
setup-context7скил не запускался, конфликта нет).
Gap'ы / кандидаты для bootstrap-скрипта (полный список — в install-log.md секция «Gaps / questions surfaced during field-test»):
- 11b принципиально не автоматизируется (требует браузер-redirect / device-code) — bootstrap.ps1 должен парковаться здесь и ждать пользователя.
- Порядок 11c-скилов критичен:
interns→projects-meta→ плагины (или их sanity) → фикстуры. Это контракт скрипта, не выбор пользователя. - Каждый setup-* скил уже идемпотентен — bootstrap может звать их без проверки «надо ли». Но pre-check блок самого скрипта (есть ли git, mise, claude, плагины) обязан быть.
Действия после промоушена (план)
meeting-room-promote-brainstorm factory-bootstrap→- shared wiki в проекте
factory:concepts/factory-bootstrap(полный дизайн + Q1/Q6/Q8 решения + Q9 deferred + field-test results). - tasks в
factory/.tasks/:factory-bootstrap-script— status=ready, next_action: «извлечь шаги из install-log.md вbootstrap.ps1+bootstrap.sh, переиспользовать idempotency-pattern из setup-projects-meta».factory-l1-design— status=blocked-byfactory-bootstrap-script, next_action: «после успешного скрипта — Go-бинарь + factory.yaml schema (см. Q2/Q4)».
- архив:
.archive/2026-05-06-factory-bootstrap.md.
- shared wiki в проекте
Stop-condition этого буфера
✅ Достигнут 2026-05-06. Q1, Q6, Q8 закрыты; Q2–Q5 явно отложены за v0 (живут в shared wiki после промоушена); Q7, Q9 deferred. Field-test end-to-end успешен. Готов к промоушену.