Files
discussions/.archive/2026-05-06-factory-bootstrap.md
vitya f3cad514db Promote factory-bootstrap → factory wiki + 2 tasks; archive buffer
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.
2026-05-06 21:23:42 +03:00

23 KiB
Raw Blame History

topic, started, participants, status, problem
topic started participants status problem
factory-bootstrap 2026-05-06
user
claude-cso
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)

Что не работает для онбординга нового сотрудника:

  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 со схемой:
    projects_dir = "C:/Users/vitya/projects"
    client = "claude-code"  # | "copilot-cli" | "gemini-cli"
    installed_at = "2026-05-06T..."
    
  • Если на машине несколько projects_dirhome.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-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-источник:
      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.
  • 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.yaml v0.2 / templates/enterprise/<repo>/ — естественный момент менять имена; (b) при общем рефакторинге фикстур-репо. Не блокирует v0.

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-список.

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/ склонированы

Что подтвердилось:

  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 повторить эту же pre-check логику.
  4. Plugin-route для context7 — правильное решение (legacy setup-context7 скил не запускался, конфликта нет).

Gap'ы / кандидаты для bootstrap-скрипта (полный список — в install-log.md секция «Gaps / questions surfaced during field-test»):

  • 11b принципиально не автоматизируется (требует браузер-redirect / device-code) — bootstrap.ps1 должен парковаться здесь и ждать пользователя.
  • Порядок 11c-скилов критичен: internsprojects-meta → плагины (или их sanity) → фикстуры. Это контракт скрипта, не выбор пользователя.
  • Каждый setup-* скил уже идемпотентен — bootstrap может звать их без проверки «надо ли». Но pre-check блок самого скрипта (есть ли git, mise, claude, плагины) обязан быть.

Действия после промоушена (план)

  1. 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-by factory-bootstrap-script, next_action: «после успешного скрипта — Go-бинарь + factory.yaml schema (см. Q2/Q4)».
    • архив: .archive/2026-05-06-factory-bootstrap.md.

Stop-condition этого буфера

Достигнут 2026-05-06. Q1, Q6, Q8 закрыты; Q2Q5 явно отложены за v0 (живут в shared wiki после промоушена); Q7, Q9 deferred. Field-test end-to-end успешен. Готов к промоушену.