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>
20 KiB
topic, started, participants, status, problem
| topic | started | participants | status | problem | ||
|---|---|---|---|---|---|---|
| factory-bootstrap | 2026-05-06 |
|
in-progress | Установка/обновление инфраструктуры 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, но нет ни
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-список.
Действия после промоушена
meeting-room-promote-brainstorm factory-bootstrap→- shared wiki:
concepts/factory-bootstrap(целевой проект —_metaили новыйfactory) claude-skills/.tasks/:factory-bootstrap-design(status=ready, next_action="ответить на Q1–Q5, прототипировать L0").archive/2026-05-06-factory-bootstrap.md
- shared wiki:
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 этого буфера
Дизайн доводится до состояния, где открытые вопросы Q1–Q5 закрыты. После — promote и переход в плановую фазу (L0 → L1 → manifest → миграция существующих setup-* в L2-делегирование).