chore(project-create): relocated to mappa/skills-core (task:1595) — это mappa core-скил, канон в монорепо victor/mappa

This commit is contained in:
2026-08-30 02:04:49 +03:00
parent 74fdbe8070
commit ddcb552601

View File

@@ -1,130 +0,0 @@
---
name: project-create
author: ours
version: 0.3.0
description: >
Mappa-side cycle of creating a new project: ask the operator for the hosting
address (platform + user/org) FIRST — never derive it from neighbouring
projects — then pre-flight checks (free in mappa AND in gitea), then ASK the
operator HOW to create the repo (via .admin task+letter / server flow
projects_create_repo / manual) — the path is the operator's call, never
assumed — then create the repo and register in mappa (in the right order,
see Hard rule 2026-08-29), then ask where on
disk the project folder goes and what it's named, create the folder, write
the `.mappa` marker (wiki:3340), and hand over to project-bootstrap (general
skill). Triggers (bilingual):
«создай проект», «заведи проект», «новый проект», «создать проект на
гите», "create a project", "start a new project", "set up a project",
«куда разместить проект». NOT repo content/bootstrap (→ project-bootstrap),
NOT renaming/re-hosting an existing project.
---
# Project Create (mappa-side)
The cycle of creating a **new project** from the mappa side. Built live on the
tg-digest case (2026-08-27, brainstorm:129): the operator ran the pattern
through a real creation, the skill records it. Guarantees that the hosting
address is the operator's decision (not the agent's guess), that mappa and
gitea stay in sync (created together, not one before the other), and that the
operator picks the on-disk location.
## When to use
Before any `projects_register` / gitea repo creation for a **new** project.
**Activates:** «создай проект», «заведи проект», «новый проект», «создать проект на гите», "create a project", "start a new project", "set up a project".
**Not applicable:**
- Repo content / bootstrap (git init, README, AGENTS.md, .wiki, .tasks, remote push) → `project-bootstrap` (general skill; project-create hands over to it).
- Re-hosting / renaming an existing project → read what's there first, no creation.
- A project that already exists in mappa registry or gitea → verify with the operator, don't create a duplicate.
## Hard rules
### Hard rule 1 (original lesson)
**The hosting address (platform + user/org) is the operator's decision. ASK, never derive.** Do not copy the owner from a neighbouring project (the live failure: `victor/tg-digest` was assumed by analogy with `victor/yt-digest` — wrong, the operator had to correct it). Options to offer: platform (Gitea git.kzntsv.site / GitHub), and for Gitea — the known users/orgs from the registry (e.g. `victor` personal apps, `OpeItcLoc03` infra/meta, `cancel_music` music modules). The registry `mcp__mappa__projects_list` shows the existing `qualified` names — use it to propose options, but the choice is the operator's.
### Hard rule 2 (2026-08-29, live failure agensyn)
**The repo-creation PATH is the operator's decision — ASK, never assume the default.** Offer: (a) via `.admin` (task + letter — the legacy canon, secrets live there), (b) server flow `mcp__mappa__projects_create_repo` (creates the repo on the provider AND registers in mappa itself, `source=auto`), (c) manual. The operator overrides the default; delegating to `.admin` before they choose is not revocable (the task lands on the board, `.admin` reacts instantly — the agensyn case).
**NEVER register the project in mappa (`projects_register`) BEFORE the repo exists.** A pre-existing registry entry makes the server flow `projects_create_repo` return 409 `already registered` (resolveStrict), and there is no delete channel for registry entries. Order that works: operator picks the path → repo is created → registration (the server flow registers itself; the `.admin` path registers AFTER the repo exists, with the known qualified).
## Steps (the pattern)
1. **Ask the hosting address.** Platform (Gitea/GitHub) + user/org. One question, offer the registry-derived options, wait for the answer. Do NOT register anything yet.
2. **Ask the repo-creation path** (Hard rule 2): via `.admin` / server flow `projects_create_repo` / manual. Do NOT delegate or register yet — this is the operator's call.
3. **Pre-flight checks** — can we create:
- mappa: the project name is not in the registry (`projects_list` / `projects_resolve`) — and do NOT create it here.
- gitea: repo name is free, the user/org exists, we have rights (`.admin` path: `.admin` owns the tokens and checks on its side; server flow: the mappa server holds provider creds).
4. **Create the repo + register, per the chosen path:**
- **server flow** (`projects_create_repo`) — single call creates the repo AND registers (`source=auto`, `qualified` from the provider response). Nothing else to register.
- **via `.admin`** — `task_create` in `.admin` (**priority P0** — it blocks the project chain) + covering letter via `inbox_send` (a task on the board doesn't ping a live session). The repo task is an **ops task → NO paired review** (mappa-delegation: skip review for ops). Acceptance: repo created private, answer letter with clone URLs + which token is needed for push. AFTER the repo exists (qualified known) → `projects_register`.
- **manual** — the operator creates the repo themselves; register after they confirm.
5. **Ask the operator: where on disk the project folder goes and what it's named** (location AND folder name — both are the operator's call) — do not guess the path or the name.
6. **Create the folder** on the agent's local filesystem (the operator's workstation, not a remote host).
7. **Write the `.mappa` marker** — see Step 5.5 below. Right after the folder exists, the marker values are known from this cycle; no manual generator run.
8. **Hand over to bootstrap**`project-bootstrap` (general skill) does git init, .gitignore, README, AGENTS.md, remote connect, push. Separate step, after the repo exists.
## Step 5.5 — `.mappa` маркер (контракт wiki:3340)
Сразу после создания папки — маркер `.mappa/config.yaml` (гейт mappa-скилов:
«без маркера папка не участвует в mappa-операциях», task:1546). Значения уже
известны из этого цикла — ручной прогон генератора не нужен (task:1583):
- `project` — канон (имя папки, выбрано оператором в шаге 5);
- `tenant``MAPPA_TENANT` (по умолчанию `vitya`);
- `url``MAPPA_CORE_URL` (без trailing slash);
- `git_provider` — платформа из шага 1 (gitea/github/…);
- `git` — qualified (owner/repo) из ответа `.admin` / `projects_create_repo` (шаг 4, clone URL).
Запись — детерминированный рендер по контракту. Канон-скрипт — ассет
`project-bootstrap` (в репо: `skills/project-bootstrap/assets/dot_mappa_marker.py`;
тот же шаг в bootstrap 5.8 — повторный прогон там no-op):
```bash
python <skills-repo>/skills/project-bootstrap/assets/dot_mappa_marker.py write \
--project "$FOLDER_NAME" --tenant vitya --url "$MAPPA_CORE_URL" \
--git-provider gitea --git "$OWNER/$REPO" --dir "$FOLDER_PATH"
```
Верифицировать: `python .../dot_mappa_marker.py check --dir "$FOLDER_PATH"`
→ exit 0. Маркер без секретов, коммитится. Если project-bootstrap не
установлен — маркер всё равно появится на хэндовере (шаг 8 → bootstrap 5.8).
## Why the repo usually goes through `.admin` (and when it doesn't)
Gitea tokens are secrets — they live only with `.admin` (zone rule: secrets stay out of other agents). Precedent: yt-digest (inbox:2305) and tg-digest (inbox:2463) — `.admin` creates the repo via `POST /user/repos` → transfer to the target owner (the admin endpoint refuses without write:admin), then answers with the clone URLs and the push token (`pass show gitea/admin-token` for OpeItcLoc03, or a user token with repo:write for the target owner).
**The alternative:** `projects_create_repo` (task:1542) — the mappa server holds provider creds and creates the repo itself, registering the project in the same call. The operator chooses which path; do not hard-default to `.admin` (Hard rule 2, agensyn 2026-08-29).
## Failure modes
- The operator hasn't chosen the address → abort, don't create. The address is the operator's call.
- The operator hasn't chosen the repo-creation path → ask, don't default to `.admin` (Hard rule 2).
- mappa name taken → suggest a rename, don't overwrite.
- gitea name taken / user missing → report, suggest a rename.
- `projects_create_repo` → 409 `already registered` → you registered before the repo (Hard rule 2) — there is no delete channel; report to the operator, don't work around it by hand.
- `.admin` repo task failed → report, don't register the project alone (mappa and gitea are created as a pair).
- `task_create` in `.admin` → 422 secret-detected on the token scope string (`write:repository` is flagged) → rephrase ("токен с правами на запись в репозиторий"), don't include raw token strings.
- The operator answers the on-disk path only after the repo is created → that's the normal order, fine.
## What NOT to do
- Don't assume the hosting owner from a neighbouring project — ask (Hard rule 1).
- Don't assume the repo-creation path — ask (Hard rule 2); a `.admin` delegation already sent is not revocable.
- Don't register the project in mappa before the repo exists (breaks the server flow with 409; no delete channel).
- Don't create mappa registration alone without the repo (they're a pair).
- Don't create the repo and skip the mappa registration entirely (the pair: repo AND registration both exist, in the right order).
- Don't create the on-disk folder in a guessed location — ask.
- Don't do the bootstrap inside this skill — that's `project-bootstrap`.
- Don't create a paired review for the `.admin` repo task (ops task).
- Don't skip the covering letter to `.admin` (task + letter, not just task).
## Reference
- Mappa registry: `mcp__mappa__projects_list` / `projects_register` / `projects_resolve`.
- Repo creation: `.admin` (task + letter, mappa-delegation canon; ops → no review).
- Bootstrap: `project-bootstrap` (general skill).
- Live case: brainstorm:129 (tg-digest, .workshop) — the whole pattern was built there.