| name | bootstrap-monorepo |
| description | Autonomous polyglot monorepo bootstrap meta-prompt on the moon + proto + Bun stack (Nx-convergent). TRIGGERS - new monorepo, new repository, polyglot setup, scaffold repo, moon proto bootstrap, monorepo from scratch. |
| allowed-tools | Read |
| disable-model-invocation | false |
Bootstrap Polyglot Monorepo (moon + proto + Bun, Nx-convergent)
Canonical reference lives in THIS skill:
→ See: references/bootstrap-monorepo.md
→ Cross-language boundaries: references/cross-language-interop.md — boundary decision ladder + verified tool status (research-verified 2026-06)
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
When to Use This Skill
Use this skill when:
- Starting ANY new repository — single-language or polyglot (the structure scales down)
- Setting up a moon-orchestrated, proto-pinned, Bun/TypeScript-wired monorepo
- Wiring engines (Rust/Python/Go) behind contracts under a TS control plane
- You want the repo Nx-convergent from day one (later
nx init is mechanical, not a restructure)
Stack
| Tool | Responsibility |
|---|
| proto | Toolchain versions (bun, python, rust, node, …) pinned in repo-local .prototools |
| moon | Project graph + task orchestration + caching + affected detection (moon ci) |
| Bun | TS runtime for every script, CLI, glue tool, and test; root workspaces |
| uv / cargo | Python / Rust engines invoked natively from moon script: tasks |
TypeScript is the control plane; other languages are engines behind language-neutral contracts (JSON Schema 2020-12 / proto) with drift gates and parity tests.
Language-Selection Default (greenfield tiebreaker)
Choose which language owns the code before choosing how to cross between them. This is a tiebreaker, not a mandate — a SOTA-native ecosystem and existing repo convention override it.
- TypeScript by default for the control plane: app logic, orchestration, CLIs, APIs, config, validation, agent/workflow automation, and anything future agents must refactor. (TS is structurally typed by default — the most agent-navigable surface.)
- An engine language only where its ecosystem is SOTA-native: Python for ML/data/science/quant or Python-only libraries; Rust/Go for hot kernels and systems work (Go > Rust as the tiebreaker).
- Never let an engine language leak across the repo. A Python-only library does NOT make the project Python — wrap it behind ONE typed boundary (ladder below) and keep TS as the public interface. Validate at the boundary: TS types are compile-time only and Python hints are not runtime-enforced.
Crossing a Language Boundary (decision ladder)
When work must cross languages, climb from cheapest to most coupled — stop at the first rung that satisfies the need (full doctrine + verified tool status: references/cross-language-interop.md):
- Process boundary — CLI + JSON/NDJSON on stdio (moon
script: task). Default.
- Schema-typed RPC — protobuf + buf / ConnectRPC, when a long-lived service or stream exists.
- Data-plane — Apache Arrow IPC/Flight/ADBC, the moment two languages exchange tables.
- In-process FFI — PyO3/maturin, napi-rs, Bun FFI, when call frequency makes 1–3 too slow.
- One WASM component core — WIT + Component Model, ONLY if the kernel needs no threads (WASI threading still unshipped as of mid-2026).
Pattern B gate amendment: after the 8-float-op test selects Pattern B, ask "does the kernel need threads?" → if yes, native core (cdylib/PyO3), not WASM.
TypeScript ↔ Python (the most common pair) verified picks, June 2026: rung 1 = Bun.spawn/child_process running Python via uv run --python 3.14 (NOT bun:ffi — C-ABI only); rung 2 = FastAPI + @hey-api/openapi-ts (HTTP) or buf-generated protobuf-es + protocolbuffers/python stubs (RPC); schema SSoT = Pydantic v2 → JSON Schema 2020-12 → TS, with a CI drift gate. Full table in the reference.
Quick Commands
moon ci
moon run <project>:check
moon query projects
moon query tasks
proto use
Legacy Path
Pre-2026-06 repos on Pants + mise: the old reference remains at
../mise-tasks/references/bootstrap-monorepo.md.
Migrate per-repo (parity-first, cut tasks over one at a time), never big-bang.
Related Skills
itp:semantic-release - Release automation (local-first; Actions only for release/CodeQL/Dependabot/deploy)
itp:mise-tasks / itp:mise-configuration - legacy mise-era orchestration (still valid for unmigrated repos)
Troubleshooting
| Issue | Cause | Solution |
|---|
proto::detect::failed for moon | tool installed but no version pinned | proto pin --to global moon <version> (or add to .prototools) |
moon not found over ssh | shims not on non-interactive PATH | export PROTO_HOME + shims PATH in ~/.zshenv (NOT only .zshrc) |
| Python tests "No module named pytest" | uv run prunes dev extras | uv run --extra dev -p <version> pytest <path> from repo root |
PyO3 crate cargo test link errors (_PyBool_Type) | tests reference #[pyfunction] under extension-module | keep logic in pure-Rust core fns; tests call the core, wrapper stays thin |
| Task runs in wrong cwd | script assumes repo root | options: { runFromWorkspaceRoot: true } in the task |
| Guard task wrongly cached | moon caches by default | options: { cache: false } on guards/parity/network tasks |
| Commit "passed" but didn't land | a hook auto-fixed files and aborted | re-stage and retry; ALWAYS verify git log --oneline -1 after commit |
Post-Execution Reflection
After this skill completes, check before closing:
- Did the command succeed? — If not, fix the instruction or error table that caused the failure.
- Did parameters or output change? — If the underlying tool's interface drifted, update Usage examples and Parameters table to match.
- Was a workaround needed? — If you had to improvise (different flags, extra steps), update this SKILL.md so the next invocation doesn't need the same workaround.
Only update if the issue is real and reproducible — not speculative.