diff --git a/dist/mappa-brainstorm-promote.skill b/dist/mappa-brainstorm-promote.skill deleted file mode 100644 index a7db543..0000000 Binary files a/dist/mappa-brainstorm-promote.skill and /dev/null differ diff --git a/dist/mappa-closing-ritual.skill b/dist/mappa-closing-ritual.skill deleted file mode 100644 index 4ba667f..0000000 Binary files a/dist/mappa-closing-ritual.skill and /dev/null differ diff --git a/dist/mappa-delegation.skill b/dist/mappa-delegation.skill deleted file mode 100644 index 86597e4..0000000 Binary files a/dist/mappa-delegation.skill and /dev/null differ diff --git a/dist/mappa-knowledge.skill b/dist/mappa-knowledge.skill deleted file mode 100644 index 7a57ae8..0000000 Binary files a/dist/mappa-knowledge.skill and /dev/null differ diff --git a/dist/mappa-messaging.skill b/dist/mappa-messaging.skill deleted file mode 100644 index e2b657f..0000000 Binary files a/dist/mappa-messaging.skill and /dev/null differ diff --git a/dist/mappa-session-orient.skill b/dist/mappa-session-orient.skill deleted file mode 100644 index f359972..0000000 Binary files a/dist/mappa-session-orient.skill and /dev/null differ diff --git a/dist/mappa-task-work.skill b/dist/mappa-task-work.skill deleted file mode 100644 index 398d553..0000000 Binary files a/dist/mappa-task-work.skill and /dev/null differ diff --git a/dist/report-mappa-issue.skill b/dist/report-mappa-issue.skill deleted file mode 100644 index 0b50c1e..0000000 Binary files a/dist/report-mappa-issue.skill and /dev/null differ diff --git a/skills/mappa-brainstorm-promote/SKILL.md b/skills/mappa-brainstorm-promote/SKILL.md deleted file mode 100644 index c181df6..0000000 --- a/skills/mappa-brainstorm-promote/SKILL.md +++ /dev/null @@ -1,322 +0,0 @@ ---- -name: mappa-brainstorm-promote -author: ours -version: 1.10.0 -description: > - Finalize a brainstorm buffer (mappa type=brainstorm, status=buffer): two - paths. (1) Promote a matured buffer — read → target → brainstorm_promote - (atomic buffer → wiki-page + archive, decision 7) → action-items as tasks - (task_create, bodies carry [[brainstorm:N]]) → review umbrella → covering - letter → final entry. (2) Close an already-completed buffer (work done, no - wiki needed) — verify linked tasks done → final entry + status=archive. - Buffer done ⇔ all action-items created AND all tasks done (incl. - review-umbrella) — wiki concepts/buffer-completion-criteria. General mappa - mechanism. Old name — trigger-synonym: workshop-promote-brainstorm. - Triggers (bilingual): «промоутни брейнсторм», «выкати в вики», "promote - the brainstorm", "finalize ", "publish to wiki"; «закрой буфер», - «архивируй буфер», "close the buffer", "archive the buffer". ---- - -# mappa-brainstorm-promote - -Finalizing a matured brainstorm buffer that lives **as a mappa entity of type -`brainstorm`** (status=buffer). This is a general mappa mechanism — exactly -like `task.create` or `wiki.create`: the buffer exists in mappa, the skill -takes it to the end (promote the content into the wiki + action-items as -tasks). No workshop specifics: the skill triggers from any folder, works with -brainstorm entities of any project. - -The procedure is linear (from reading the buffer to promotion and tasks), not -a loop: it's launched explicitly on the final buffer and takes it to the end. -In the forkflow it sits between work (`mappa-task-work`) and finish -(`mappa-closing-ritual`). - -**Completion criteria** (wiki `concepts/buffer-completion-criteria`, .workshop): -a buffer is done ⇔ (all action-items are created as tasks) ∧ (all created -tasks are done, including the review-umbrella). Two entry paths to `archive`: - -- **Promote** (steps 5–9): a maturing buffer whose content must land in a - wiki — `brainstorm_promote` (wiki page + archive atomically). -- **Close** (step 5b): an already-completed buffer — work done long ago - (tasks done / resolved / legacy-promoted in the file era), no wiki page - needed. Verify the chain — in the graph for same-project links, via - direct `task_get` for cross-project tasks — write the final entry, - `brainstorm_update(status='archive')`. This is how done-but-not-closed - buffers are swept (case: entity-uuid brainstorm:109, tasks 1067/1068/1093 - done, buffer still `buffer` with zero edges — audit 2026-08-25). - -**Content promotion — always via `mcp__mappa__brainstorm_promote`:** -atomically creates a wiki page (slug from the buffer, body preserved) in the -project from the call and moves the buffer to `archive` (number/slug stable, -decision 20; parent_of edges, `brainstorm.promoted` event). No file channels. -Action-items go as tasks to the target project via `mcp__mappa__task_create` -(carve-out without a lease, #1054; sequentially, not batched). - -## When to use - -- «промоутни брейнсторм», «выкати в вики», "promote the brainstorm", - "finalize ", "publish to wiki". -- The user references a brainstorm entity (brainstorm:N) or a buffer topic - that matured and is ready for promotion. - -## Inputs - -- Brainstorm ref `brainstorm:N` or `` (buffer slug/topic) + project (if - the buffer is not in the current project — ask). -- For the skill branch additionally: `` of the new skill (if not - specified — ask, propose a derivation from the topic). - -## Decision flow - -``` -brainstorm entity in mappa (type=brainstorm, status=buffer) - │ - ▼ - find + read (entity_search type=brainstorm → entity_get full body) - │ - ▼ - ask: target project (where to promote) - │ - ├── close (no promotion): work already done, no wiki page needed - │ → step 5b (graph check + final entry + status=archive) - │ - ├── ordinary project → brainstorm_promote(project=) - │ → wiki page (spec) in the target wiki - │ - └── skill → dialog: description (trigger contract) - → preview + confirm - → mkdir + Write SKILL.md (skeleton) in ~/projects/skills/ - → git add + commit (local, no push/install) - │ - ▼ - parse action-items from the buffer body - │ - ▼ - for each: mcp__mappa__task_create (SEQUENTIALLY, not batched) - │ - ▼ - review-umbrella: mcp__mappa__task_create (blocked, blocker=impl#) - │ - ▼ - covering letter: mcp__mappa__inbox_send (mappa-delegation canon) - │ - ▼ - final report (wiki:NNNN — spec, brainstorm:N — archive, tasks) -``` - -## Steps - -1. **Find the buffer in mappa.** `mcp__mappa__entity_search(type='brainstorm', - project=, q=)` → in the results brainstorm:N (ref). Read the - full buffer: `mcp__mappa__entity_get(key)` — key = uuid, full ref - `brainstorm:N`, or bare num (канон адресации task:1221: голое число = num; - этап A задеплоен) — body = running record (frontmatter + rounds). - Адресация буфера — по num/ref/uuid, internal id наружу не используем - (выпилится в этапе B, task:1221). - - If the buffer is not in mappa — create a brainstorm entity via - `mcp__mappa__brainstorm_create` (or HTTP `POST /entities` type=brainstorm, - contract decision 7/#1054). Don't invent file buffers. - -2. **Show the buffer summary (≤2 paragraphs).** - -3. **Ask the target project** — where to promote the content. Default — the - project where the buffer lives (brainstorms are run where the topic is - relevant). Verify the project exists in mappa: - `mcp__mappa__entity_search` type=project (or `mcp__mappa__entity_search` - with q=). If not — abort with a message. - -4. **If target = skill (the user wants it as a skill):** - - Ask `` of the new skill (if not specified) — a valid slug - (`[a-z0-9-]+`). - - Validation (order matters): first check that `~/projects/skills/` itself - is a repository. If not — **abort** with the message "clone skills via - update-skills or manually". - - Then: `~/projects/skills/skills//` must NOT exist. If it exists — - **abort** with the message "skill `` already exists, update through - the normal route in `~/projects/skills/`, this skill is not for updates". - - Two-pass skeleton: dialog on `description` (activation trigger contract: - minimum 2-3 phrases, Russian/English pairs; what it does; antipatterns) → - preview + confirm → `Write` of the skeleton (header + 6 empty sections) → - local `git commit` in `~/projects/skills/`. **Without** install.sh, push, - build-hermes — those are in the baseline tasks of step 7. The body of the - skeleton is written in a second pass by eye (outside this skill's scope). - -5. **Content promotion (always via `brainstorm_promote`, decision 7):** - - `mcp__mappa__brainstorm_promote(project=, brainstorm_id=)` - - - Atomically: buffer → wiki page (slug from the buffer, body preserved, - parent_of buffer→wiki edges and refs→buffer) + buffer → `archive` + - significant `brainstorm.promoted` event. - - **Frontmatter-summary (wiki:2661):** make sure the buffer body has - `summary:` as one line in the frontmatter — `wiki.search` cards read it. - If missing — append via `mcp__mappa__brainstorm_update` (PATCH - /brainstorm/:id, title/body/status, optimistic version+409; id = num | - ref | uuid) before the promotion. - - Re-promoting an archived buffer → error (one-shot, idempotent via - status). Cross-check `brainstorm_id` (num/ref) from step 1. - - If `brainstorm_promote` failed (version conflict, 409) → retry with the - fresh num/ref; on a stable failure — abort before creating tasks. - -5b. **Closing an already-completed buffer (no promotion).** When the work is - already done and no wiki page is needed (legacy-promoted, resolved by the - human, tasks all done, or the decision was reversed): - - - Verify the chain: `mcp__mappa__graph_neighbors`/`graph_backlinks` on - the buffer for same-project links (edges resolve in the owner's project - scope, finding #1014); for cross-project tasks (workshop → target, the - normal case) resolve the refs from the body/final entry via direct - `mcp__mappa__task_get(task:N)` — every linked task must be status=done - (or the buffer is closed by content: «решено»/«отменено»). - If tasks are done but nothing is written — the chain was never recorded; - the final entry below fixes it (backward text refs). - - Append the final entry to the body via `mcp__mappa__brainstorm_update` - (body, expected version; 409 → re-GET → retry): - «Закрытие (дата) — цепочка завершена: [[task:N]]… done / решено / - промоутнуто (легаси). Критерий: [[concepts/buffer-completion-criteria]]». - The `[[task:N]]` and `[[wiki:…]]` links create the closing edges on - write (decision 4). - - Set `status='archive'` in the same `brainstorm_update`. Buffer archived - without a wiki page — the knowledge is already where it belongs or is - historical (review reports, legacy plans). - - Report: `brainstorm:N` → archive, with the reason. - -6. **Action-items parsing:** regex over lines like `- [ ] ...` in the buffer - body, sections after `## Следующие шаги`/`## TODO`/`## Next steps`/ - `## Action items`. Show the list, allow editing/removing/adding. If 0 - action-items — continue, don't block. - -7. **Task creation:** - - > **NB:** create tasks **SEQUENTIALLY**, not batched. One `task_create` → - > wait for the response → the next one. - - - **Ordinary target:** for each action-item — - `mcp__mappa__task_create(project=, slug=, title, description, - status='ready')`. Create — carve-out, no lease needed (wiki:2660/#1054). - The impl task description references the spec (wiki:NNNN from step 5) and - MUST start with the buffer wikilink `[[brainstorm:N]]` — a ref edge is - created on write (decision 4) when the buffer is in the same project as - the task; cross-project it stays a searchable text ref - (`entity_search "brainstorm:N"` finds the task). - - **Skill:** three baseline tasks in `project='skills'`: - - `[-install]` — run `install.sh` in `~/projects/skills/`, - verify activation in a new session. - - `[-hermes-mapping]` — a record in - `~/projects/skills/hermes/mapping.yaml` (mode `auto` for style ones, - `pending` if it touches tools/environment). - - `[-test-trigger]` — run the trigger phrases from the description: - activates on its own, doesn't activate on 2-3 close foreign ones. - Plus content tasks from the buffer (if any) — also in `project='skills'`, - slug-prefix `-`. - - If the N-th task failed — continue the rest, report at the end which were - created / which weren't. Remember the slugs for the review-umbrella. - -8. **Review-umbrella (for a target with impl tasks, and for skill — always):** - - `mcp__mappa__task_create(project=, slug=-review, - status='blocked', blocker=, description=)` - - - **Who does it:** not the implementer. The next session in this project (a - different model / different day / different agent) with a clean context. - The "I just wrote this" bias is the main risk. - - Checklist: read the spec (wiki:NNNN from step 5), `git log` of the - shipped commits, for each impl task run the tests and cross-check with - acceptance criteria, findings → follow-up tasks via `task_create`. - - Closing: all findings filed OR the reviewer confirmed "no findings" in - the close-note. - - If the review task failed — report, **continue** to step 9 (the promotion - is already done, the buffer is in archive). - -8b. **Final entry in the buffer (closing the chain).** After tasks are - created, append to the buffer body via `mcp__mappa__brainstorm_update` - (body + expected version; 409 → re-GET → retry): «Промоут → wiki:NNNN · - таски [[task:N]]… · review-зонт [[task:M]]». This writes the backward - refs — the completion record per `concepts/buffer-completion-criteria` - (cross-project: text refs, verified by `task_get`; same-project: edges). - If the body PATCH on an archived entity is rejected — report to the user - (the chain stays visible through the tasks' [[brainstorm:N]] forward refs). - -9. **Covering letter to the target's inbox (mappa-delegation canon).** A task - on the board doesn't ping a live session, a letter = ping + context: - - `mcp__mappa__inbox_send(project=, from=, subject='Promotion - : tasks <#N…>', body=)` - -10. **Final report to the user:** - - Where it was promoted: `wiki:NNNN` (spec in the target wiki). - - Archive: `brainstorm:N` (status=archive, number stable). - - Which tasks were created (ref, title, project). - - **For skill:** remind about the second pass "let's flesh out ``". - -## Failure modes - -- Buffer not found in mappa (no brainstorm entity) → abort, report: create via - `brainstorm_create` (step 1) or HTTP POST /entities. -- `entity_search`/`entity_get` failed (API error, not an empty result) → abort - with the error text; don't create a buffer by guess. -- Target project doesn't exist in mappa → abort before promotion. -- `brainstorm_promote` failed (409 version / stable refusal) → retry with the - fresh num/ref; on a repeated failure — abort before creating tasks. The - buffer stays in buffer — retried later. -- Buffer already `archive` (repeated call) → abort: promotion is one-shot, - idempotence via status (decision 7). -- Closing (step 5b): buffer still has open linked tasks → abort, don't close; - report which tasks are open. Buffer is a living storm → abort (close only - completed or reversed buffers). -- Closing: `brainstorm_update` 409 (version) → re-GET → retry; repeated - failure → report, buffer stays in `buffer`. -- `task_create` failed on the N-th content task → continue the rest, report - partial. The promotion is already done — the buffer is not rolled back. -- `task_create` review-umbrella failed → don't block, report to the user - (create manually from step 8). -- `inbox_send` (covering letter) failed → promotion and tasks are not rolled - back; report to the user, the letter can be sent later (the promotion is - already visible in the graph/inbox of the target). -- **Skill:** `~/projects/skills/` doesn't exist → abort. -- **Skill:** `~/projects/skills/skills//` already exists → abort. -- **Skill:** user didn't confirm the preview → abort, state unchanged. -- **Skill:** local `git commit` in `~/projects/skills/` failed → the file - stays, report that the commit needs to be done by hand; the buffer promotion - is not blocked. - -## Side effects - -- **Always:** `brainstorm_promote` — atomically wiki page in the target + - buffer → `archive` + parent_of edges (wiki→buffer, refs→buffer) + - `brainstorm.promoted` event. -- **Closing (5b):** `brainstorm_update` — final entry with `[[task:N]]`/ - `[[wiki:…]]` refs + status → `archive`; closing edges on write. -- **Ordinary target:** spec page in the target project's wiki (with - frontmatter-summary, wiki:2661) + impl tasks + review-umbrella + covering letter. -- **Skill:** skeleton `~/projects/skills/skills//SKILL.md` (only header + - empty 6-section skeleton) + local commit in `~/projects/skills/`. - **Without** install.sh, push, build-hermes — those are in the baseline tasks. -- Creates N tasks in the target via `mcp__mappa__task_create` (carve-out). -- Creates a review-umbrella task (status=blocked, blocker=impl#). -- Sends a covering letter to the target's inbox. - -## What NOT to do - -- **Don't use file channels** — the buffer lives in a mappa brainstorm entity, - no `.brainstorm/`/`.archive/` records. -- **Don't use `mcp__projects-meta__tasks_create` / `knowledge_ingest` / - `knowledge_promote`** — file channels are removed. Tasks — - `mcp__mappa__task_create`, wiki — `brainstorm_promote` (content) + - `wiki_create`/`wiki_update` (extra pages). -- Don't `git mv` the buffer into the archive — the promotion archives it itself. -- Don't delete the buffer instead of promoting — the graph history is lost - (parent_of, refs). -- Don't close a living buffer (5b) — closing is only for completed/reversed - work; verify linked tasks via the graph first. -- Don't close without the final entry — the backward refs are the chain. -- Don't invent wiki pages when closing (5b) — closing ≠ promotion. -- Don't batch `task_create` (race; incident 2026-08-24: 6/7 failed) — only - sequentially. -- Don't forget the covering letter — a task on the board doesn't ping a live session. -- **Skill:** don't automatically reformat the buffer body into the skeleton — - the body is written in a second pass by eye. -- **Skill:** don't run `install.sh`, don't push, don't edit - `hermes/mapping.yaml` — those are baseline tasks. -- **Skill:** don't promote into an existing skill (abort). diff --git a/skills/mappa-closing-ritual/SKILL.md b/skills/mappa-closing-ritual/SKILL.md deleted file mode 100644 index 571c3ed..0000000 --- a/skills/mappa-closing-ritual/SKILL.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -name: mappa-closing-ritual -author: ours -version: 1.3.0 -description: > - Finish phase of the forkflow: handoff write (mcp__mappa__handoff_write, - version h:N) + PROPOSE wiki-ingest + PROPOSE task closes. Mutations — only - after user confirmation. Ad-hoc: mode=light — an explicit question "Write - handoff?" at the end of the session (NOT an automatic sweep), the decision - is the human's. Old name — trigger-synonym: session-handoff (write part). - Reading at start — mappa-session-orient. Triggers (bilingual): «завершаем - сессию», «сворачиваемся», «закругляемся», "wrap up session", "end session", - "we're done for now". Anti-triggers (task-zone, not session-end): - «закрываем эту таску», «pause», «отбой», «разбегаемся». ---- - -# mappa-closing-ritual - -Finish phase of the agent cycle: **write handoff → propose wiki-ingest → -propose task closes**. Start ≠ finish: reading the handoff at start — -`mappa-session-orient`; here — the write path with procedure and confirmation. - -Channel — the **Mappa handoff entity** (`mcp__mappa__handoff_write`, type -`h:`, per-project): fields `session_id`/`date`/`status`/`summary`/ -`open_treks[]`/`ask_user[]`/`guards[]`/`recent_commits[]`. Each write = a **new -version** (append-only, versioned history). The file-based -`.tasks/NEXT_SESSION.md` no longer exists. - -## When to use - -- Session-end phrases: «завершаем сессию», «сворачиваемся», «закругляемся», - "wrap up session", "end session", "we're done for now". -- Ad-hoc session without a track/task at the end: **mode=light** — an explicit - question "Write handoff?" (not an automatic sweep), the human decides. -- The project's AGENTS.md contains the trigger line - `session handoff: read on start, write on end`. - -**Skip (task-zone, not session-end):** «закрываем эту таску» (task close → -`mappa-task-work`), «pause», «приостанови» (task-pause), «отбой», «разбегаемся» -(too broad), "let me finish one task first, then we'll talk" (partial finish). -On ambiguity — **ASK**: "are we closing the session or a task?" - -## Steps - -### 1. Scope check - -This is the current project (cwd). No global mutations, no other projects. - -### 2. Mid-task capture - -If there is a 🔴 active task of the project (mappa board / `.tasks/`) — capture -into summary: -``` -left mid-task: -where_stopped: -``` -No board — write the handoff without the mid-task section, don't block. - -### 3. Compose content (handoff fields) - -- `session_id` — `` or session identifier; -- `status` — `active` (work continues) / `paused` (frozen) / `done` (finished); -- `summary` — the link: where we stopped, mid-task, key decisions; -- `open_treks` — array of open tracks (readiness + entry-point); -- `ask_user` — pending decisions / expected resolutions; -- `guards` — "don't do" (preemptive guards); -- `recent_commits` — 3–5 latest commits (`: `). - -Forward-looking, not a timeline: handoff = a link of new things specifically -for the next turn, not an overview of the whole project. The mappa board / wiki -remain authoritative for their own scope — don't duplicate them in the handoff. - -### 4. Append - -`mcp__mappa__handoff_write(project=, session_id, status, summary, open_treks?, ask_user?, guards?, recent_commits?)` — the service creates a new `h:N` version (previous ones remain; reading the latest — `entity_search(type='handoff', project, limit=1)`). Pass array fields as `[]` when empty (the next agent sees: empty, not forgotten). Written without a lease (like inbox). - -> **Confirm gate:** handoff write is a mutation. In mode=light (ad-hoc) and on -> ambiguity — first an explicit question "Write handoff?", only after "yes" — -> write. - -### 5. Propose wiki-ingest (don't write!) - -If durable knowledge appeared during the session — **PROPOSE** the ingest -(`mappa-knowledge`: mappa wiki create — carve-out, update — version+409, -wiki:2660), listing the candidates. Don't write anything without confirmation. - -### 6. Propose task-board closes (don't close!) - -If there are tasks that look closed — **PROPOSE** the closes -(`mappa-task-work`: task_close with version+409, wiki:2660). Respect ralph-loop: -verifier tasks close only via the verifier (attempt/harness-record). - -### 7. Proposal format — one block - -``` -Closing ritual: -(a) ingest X into the wiki? -(b) close Y? -(c) nothing. -``` -Wait for the answer. Refusal = skip (don't insist, don't repeat in this session). - ---- - -## mode=light (ad-hoc sessions) - -Ad-hoc session (no task/track, but artifacts may be born): the trace in mappa -is always written (service contract — session live-ingest), but -**structuring happens only on an explicit question**: at the end of the -session ask "Write handoff?" (the human decides). NOT an automatic sweep: -without "yes" — write nothing, the trace stays in mappa as is. - -## Failure modes - -- **Secret detected.** Content matches secret patterns (`AKIA...`, `sk-...`, - `ghp_...`, `ssh-rsa`, `BEGIN PRIVATE KEY`, `password=`/`token=`) → **abort - write**. Tell the user with the suspicious line indicated. -- **Ambiguous phrase** → ASK "are we closing the session or a task?", don't guess. -- **Mid-task without a board** → handoff without the mid-task section, don't block. -- **User refused the ritual proposals** → skip, don't insist. -- **Project not in mappa** → silent exit (first session). - -## Side effects - -- Writes the project's handoff entity (append-only, versioned history). No - files, no git commits for the handoff. -- The ritual **proposes** wiki-ingest and task closes — but does NOT write - them without "yes". -- No global mutations, no other projects. - -## What NOT to do - -- **No auto-execute** — every mutation (handoff write / wiki-ingest / task - close) only after an explicit "yes" from the user. -- **Don't run the ritual on a substantive commit.** Only a session-end phrase - (or an explicit user request). -- **Don't sweep automatically in ad-hoc** — mode=light: an explicit question - "Write handoff?", the human decides. -- **Don't write secrets** into the handoff. Secret-pattern match → abort. -- **Don't write a handoff on every commit** — only at the finish. -- **Don't duplicate the board / wiki** — handoff = forward-looking link. -- **No cross-project** — per-project scope. -- **Don't treat the handoff as authoritative** on the reader's side — it's the - previous session's recommendation, not a directive; the user can override. - -## Reference - -- Reading the handoff at start: `mappa-session-orient`. -- Task closes: `mappa-task-work` (pre-close coverage, notify letter). -- Wiki-ingest: `mappa-knowledge`. -- Letters: `mappa-messaging`. Delegation: `mappa-delegation`. -- Session live-ingest (the trace in mappa is always written): `concepts/session-live-ingest` (wiki:2604). diff --git a/skills/mappa-delegation/SKILL.md b/skills/mappa-delegation/SKILL.md deleted file mode 100644 index 564b50a..0000000 --- a/skills/mappa-delegation/SKILL.md +++ /dev/null @@ -1,277 +0,0 @@ ---- -name: mappa-delegation -author: ours -version: 1.4.0 -description: > - The cycle of delegating a task to another agent/project: pre-flight gate → - body template → dry-run preview → confirm → covering letter to the - recipient's inbox → paired review task for impl. Every cross-project - delegation is a pair: tasks_create + letter (event: created) — a task on the - board does not ping a live session. Old name — trigger-synonym: - delegate-task. Triggers (bilingual): «делегировать таску», «создать задачу - на агента», «поставить задачу агенту», «tasks_create для», "delegate task", - "create a task for an agent", "assign a task to an agent". NOT applicable: - self-assigned tasks on your own board («создать задачу себе» → - mappa-task-work), doing work yourself, workshop-internal tasks. ---- - -# mappa-delegation - -Unified **cycle of assigning tasks to agents**: from the pre-flight gate to -the covering letter to the recipient. Guarantees that every delegated task -carries: mandatory skills (imperative invoke), pre-flight permissions, -steering-loop fields (notify/weight), a paired review task for impl — and that -the recipient actually learns about the task (letter, not just the board). - -## When to use - -Before every `tasks_create` call for another project or agent. - -**Activates:** «делегировать таску», «создать задачу на агента», «поставить задачу агенту», «tasks_create для», "delegate task", "create a task for an agent". - -**Not applicable:** -- Work you do yourself in the current session. -- Self-assigned tasks on your own board («создать задачу себе», "task for myself") → `mappa-task-work`, not delegation. Disambiguator: «на агента»/«агенту»/«в проект X» = delegation; «себе»/"myself" = your own board. -- Workshop-internal tasks (`.workshop/.tasks/` — workshop-meta, not delegation). -- `tasks_create` with `target=agenda` (cross-project agenda — not delegation to an agent). - -## Inputs - -- `target_project` — qualified `/` (required) -- `slug` — kebab-case latin -- Short task description (goal + acceptance criteria) -- `weight` — `cheap-ok | needs-claude | needs-human` -- `notify` — commissioning project slug (who gets the inbox letter on close/park) - -The task number is assigned by the server (`tasks_create` from the -agenda/task-counter) — the assigner neither invents nor reserves it. The -returned `#n` from preview/confirm is the task's machine key: blockers, -letters, and the decision trail reference it. - -> **Contract (interactive, wiki:2660).** `task_create` — **carve-out without a -> lease** (create-without-lease as a principle); update/close — version+409 -> (409 → re-GET → retry). file channel — sha-CAS via Gitea. No claim/TTL — -> "take a task" = conditional update by version (poller outside mappa). - -## Steps (the cycle) - -### 1. Pre-flight gate (6 questions to the user) - -Ask **before** composing the task body: - -0. **Critical infrastructure?** — the task changes: poller/agent-runner, MCP - servers (projects-meta, interns), claim/close/heartbeat mechanics, deploy - infra (traefik, docker, systemd), CI/CD pipelines, git hooks. - - If **yes** → force `weight: needs-human`, no discussion. Explain to the - user why. - - If **no** → continue. -1. **Interns — allowed?** (yes/no, per task) -2. **Auto-push — allowed?** (yes/no, per task) -3. **Contextual skills beyond defaults?** — propose per task content (e.g. - `claude-api` for Anthropic SDK work, `frontend-design` for UI, - `using-interns` if interns are allowed); the user approves. -4. **notify — who gets the completion/block report?** (project slug; usually - `.workshop` or `OpeItcLoc03/workshop`) -5. **Session-break after this task?** — is a session break needed after it - closes (domain-switch, milestone, heavy infra)? - - If **yes** → set `session_break` in the task body (see template): `true` - or a string-hint with the next track's name. `mappa-task-work` will stop - after close and propose ending the session, without claiming the next task. - - If **no** → don't add the field (default — the agent continues the cycle). - -### 2. Compose the task body per template - -Sections strictly in order: - -``` - -**Spec:** — mandatory for tasks -from design/decision: the impl reads the design, doesn't guess - -## Mandatory skills — invoke before starting work - -- invoke `tdd-criteria` — before writing code -- invoke `mappa-task-work` — for task status management -- invoke `project-discipline` — commit/push discipline -- invoke `mappa-knowledge` after closing — ingest .wiki/concepts/.md -[if cross-project: - invoke `using-projects-meta` — cross-project tasks/wiki] -[contextual skills from step 1.3] - -**TDD:** yes | no — -**Permissions:** interns: yes/no | auto-push: yes/no -**weight:** cheap-ok | needs-claude | needs-human -**notify:** -[**allow_upgrade:** true/false] -[**session_break:** true | ""] # optional — mappa-task-work stops after close, doesn't claim the next task -``` - -**When to set `session_break`** (optional; by default DON'T set it — it marks -a real boundary, not a default). Three cases: - -1. **Domain / repo switch** — the task finishes one track before moving to an - unrelated one. -2. **Milestone task** — the last in a group of sub-tasks of one feature. -3. **Heavy infra task** — shared checkout, migrations, deploy — where it's - reasonable to stop and check the state. - -Value: `true` (next track = "see STATUS.md") or a string-hint with the next -track's name. Consumer — `mappa-task-work`: after close it prints -`🔚 SESSION BOUNDARY …` and stops, without claiming the next task. Design: -`.wiki/concepts/delegate-task-session-break.md`. - -**Staged breakdown:** if the solution splits into stages (1 → 1b → 3), create -each stage as a separate task with `status: blocked` + `blocker: - (#n1, #n2 — numbers, not slugs; the number = machine -key)`. The board shows the order, the poller won't take dependent work early. -Create tasks in one repo sequentially, not in parallel (otherwise sha-lock -conflict — see Failure modes). - -**Why `invoke` and not a trigger phrase:** AGENTS.md is unreliable (drifts -under compression, weak models ignore it). The task body is read actively — -the imperative `invoke` is a direct command, not passive matching. - -### 3. Dry-run preview - -`tasks_create(confirm=false)` — show the user the preview before the real commit. - -### 4. Confirmation and creation - -After the user's OK: `tasks_create(confirm=true)`. - -### 5. Covering letter — mandatory for cross-project delegation - -After creation, **every cross-project delegation** is duplicated by a letter to -the recipient's inbox (canon — `mappa-messaging`: Mappa channel, address from -the address book `~/projects/.wiki/concepts/projects-address-book.md`): - -``` -mcp__mappa__inbox_send( - project: , # folder name, from the address book - from: , - subject: "[event: created] #n slug", - body: "1-2 lines — what the task is, why, slug; «sort it out and take it»" -) -``` - -(«sort it out and take it» — intentionally bilingual placeholder: the covering -letter body may be written in the recipient's language (Russian for -Russian-speaking projects, English otherwise). Not a trigger phrase.) -``` - -(update/close mutations — version-based (409 → retry); letter delivery — -carve-out, requires no lease.) - -Reason: a task on the board **does not ping the recipient's live session**. -The poller will pick it up by `Weight`/`Notify`, but a live interactive -session learns only through the inbox monitor — i.e. through the letter. The -rule "task + letter, not just task" — is the general case (step 7 is its -particular case for downstream tasks). - -Skip: self-assigned tasks on your own board; `target=agenda` (shared board, -no concrete recipient — steering-loop via `Notify`). - -### 6. Paired review task (impl tasks only) - -If the task is implementation — create the paired `-review` -(status=blocked, blocker=`#n` — the impl task number). Skip for: pointer -tasks, ops tasks, research tasks, any non-impl. - -**Deploy gate (operator rule 2026-08-26):** if the task requires deploy — its -target is `.admin` (secrets/runbooks are service-use, other agents must NOT -look into them), not the app repo. Deploy is possible ONLY after: impl close → -paired review done → all follow-up tasks closed. Admin gets the task + a -covering letter. - -**Notifying affected projects (operator rule 2026-08-26):** every delegation / -promotion notifies the project agents — the covering letter goes to ALL -affected projects, except yourself (self-copy doesn't count as notifying -others). Task on a board doesn't ping a live session; the letter is the ping. - -**`weight` of the review task — inherit from the impl task, but never below -`needs-claude`** (set explicitly at `tasks_create`): - -- impl `needs-human` → review `needs-human` (a critical-infra change cannot - be reviewed by a weak tier — the review inherits the impl's strictness). -- impl `needs-claude` → review `needs-claude`. -- impl `cheap-ok` → review `needs-claude` (floor: review is - discipline-critical, see What NOT to do — don't drop to cheap-ok). - -Without an explicit `weight` the poller won't route the review task (the -reconciler skips it) — so always set it, even when impl and review are at the -same tier. - -### 7. Downstream task for a LIVE session → require task + inbox letter - -If the task body **instructs the agent to create a downstream task itself** for -another project where a **live interactive session** is working (e.g. the -programmer sets a deploy task for the admin) — in the spec **explicitly require -BOTH `tasks_create` AND the inbox letter** to that project -(`mcp__mappa__inbox_send(project=, from=, subject="[event: created] #n slug", ...)`). - -Reason: a task on the board does **NOT** ping the live session. The poller -will pick it up by `Weight`/`Notify`, but a live interactive session learns -only through the inbox monitor / Stop-hook — i.e. through the letter. A spec -that requires only `tasks_create` leaves the downstream task hanging unnoticed, -and someone finishes the ping by hand. - -Rule: poller-driven target → `Weight`/`Notify` mandatory; live session → inbox -letter mandatory; **not sure poller or live — require BOTH.** Apply the same -rule when you ping a peer yourself: task + letter, not just task. - -## Failure modes - -- **User refuses the pre-flight** → abort, don't create the task. -- **User rejects the dry-run preview** → abort. -- **notify not specified** → re-ask, don't skip silently. Without notify the - steering-loop doesn't close. -- **weight not specified** → re-ask. Without weight the poller doesn't know who - to give the task to. -- **tasks_create failed** → distinguish: **PushRejected** (sha-lock conflict — - the repo moved between preview and confirm; happens on parallel creation into - one repo) → **retry**: repeat the confirm — the server re-reads the actual - base_sha. Other errors → tell the user, don't retry without an explicit request. - -## Side effects - -- Creates a task in the target project via `tasks_create` (file channel — - Gitea commit; service channel — mappa entity, create = carve-out without a - lease wiki:2660). -- Optionally creates the paired review task (status=blocked). -- Covering letter to the recipient's inbox (cross-project delegation). - -## What NOT to do - -- Don't skip the pre-flight gate — even if everything seems obvious. -- Don't use passive trigger phrases instead of `invoke` — "tdd-criteria" in - text is weaker than "invoke `tdd-criteria`". -- Don't skip `notify` — without it the boss won't learn about completion. -- Don't skip `weight` — without it fleet routing is blind. -- Don't create a review task for pointer/ops/research tasks — impl only. -- Don't create a review task without `weight` — the reconciler/poller will - skip it. Inherit from impl, floor `needs-claude` (see Step 6). -- Don't assign `weight: cheap-ok` where discipline is critical (review, - security, schema migration) — weak models may ignore invoke instructions. -- Don't assign `weight: needs-claude` or `cheap-ok` to tasks changing critical - infrastructure (poller, MCP servers, deploy, CI/CD) — only `needs-human`. -- Don't set `session_break` routinely on every task — it marks a real - boundary (domain-switch / milestone / heavy infra), not a default; otherwise - `mappa-task-work` breaks the session after every close. -- **Don't create tasks from design/decision without a `**Spec:**` reference** - — the impl agent guesses thresholds/scope instead of reading the design. -- **Don't create several tasks in one repo in parallel** — sha-lock conflicts - (PushRejected); serialize the confirms. -- **Don't delegate a cross-project task without the covering letter** to the - recipient's inbox (step 5, Mappa `inbox_send`). `tasks_create` into a foreign - board doesn't ping the live session — a task without a letter stays unnoticed - until the poller/hand. -- **Don't instruct the agent to create a downstream task for a live session - without the paired inbox letter** (see Step 7). `tasks_create` into a foreign - board doesn't ping the live session — the spec must require BOTH the task - and the letter, otherwise the downstream task hangs unnoticed. - -## Reference - -- Letters: `mappa-messaging` (inbox_send canon, address book). -- Tasks/board: `mappa-task-work`. -- Knowledge: `mappa-knowledge` (wiki after closing). -- Promotion: `mappa-brainstorm-promote` (review-umbrella through it too). diff --git a/skills/mappa-knowledge/SKILL.md b/skills/mappa-knowledge/SKILL.md deleted file mode 100644 index 85f6f99..0000000 --- a/skills/mappa-knowledge/SKILL.md +++ /dev/null @@ -1,279 +0,0 @@ ---- -name: mappa-knowledge -author: ours -version: 1.5.3 -description: > - The cycle of working with a project's knowledge in Mappa (Karpathy LLM Wiki, - channel = mappa entities): ingest → query → lint + a graph layer for - relational/structural questions. Absorbs using-wiki + using-wiki-graph (old - names — trigger-synonyms). Triggers (bilingual): «заингесть», «обнови вики», - «запроси вики», «проверь вики», "use project wiki", "query the wiki", - «что связывает X и Y», «как связаны», «путь между X и Y», "what connects - X and Y", «что ссылается на X», «backlinks of X», «сироты», «битые ссылки», - "orphan pages". Wiki = entities type=wiki (read — carve-out; create — - carve-out, update — version+409; contract wiki:2660). Relational questions — - via graph_* (BFS server-side), guarded failure-mode: one page and stop, - no multi-hop chains by reading. Skip for single-page content questions. ---- - -# mappa-knowledge - -The single cycle of working with a project's knowledge in **Mappa**: three -operations (ingest / query / lint) + a **graph layer** for relational and -structural questions. The skill is a cycle, not a tool: knowledge is -**compiled once and kept current** (ingest), queried (query), checked (lint), -and the links between entities are read through the graph (graph_*). - -Channel — Mappa (`mcp__mappa__*`), NOT files. A page is an entity `type=wiki` -(`wiki:N`); read — carve-out; **create — carve-out without a lease; update — -optimistic concurrency (version+409 → retry)** (contract wiki:2660, v0.12.0). -The file-based `.wiki/` no longer exists; `setup-wiki` is dead (nothing to set up). - -## When to use - -- Ingest a document/source into the wiki («заингесть X», «обнови вики»). -- Answer from the wiki / check the wiki («запроси вики», «проверь вики», lint). -- Relational/structural question («что связывает X и Y», «backlinks», «сироты») — the graph layer. -- Modify any page — formats below are mandatory; project conventions live in - the `AGENTS` entity (legacy — `CLAUDE` pointer). - -**NOT for:** one-off code questions (normal file reading), single-file -README/ADR (not a persistent knowledge base), a project without a wiki in mappa. - -## Three layers (don't mix) - -1. **Raw sources** — `summaries/` pages. Immutable: read, don't edit - (the only exception — the `> Status` blockquote on an explicit user request). -2. **Wiki** — the other pages (entities/concepts/packages/contradictions/open-questions/overview). -3. **Schema** — the `AGENTS` entity (canon, slug `AGENTS`) + `CLAUDE` (legacy - pointer "Canon is AGENTS"). Read `AGENTS` first; it overrides this skill on - conflict. - -## First step of any operation - -1. `mcp__mappa__wiki_get(project, 'AGENTS')` — if present, read it (canon; if - not — `wiki_get(project, 'CLAUDE')`, the legacy pointer). -2. `mcp__mappa__wiki_get(project, 'index')` — the catalog; find the needed - pages. (Default catalog — `entity_search`, decision 1; `index` is an - orientation aid.) -3. Only then act. - -If `AGENTS`/`CLAUDE` is missing — the wiki is either new or unmaintained: -don't improvise the structure, the first ingest creates `AGENTS` -(+ `CLAUDE` pointer). - -## MCP surface - -| Operation | Tool | Note | -|---|---|---| -| Read a page | `mcp__mappa__wiki_get(project?, slug)` | read — carve-out | -| Search pages | `mcp__mappa__entity_search(q, type='wiki', project?, scope?, limit)` | ILIKE over body/title (full bodies) | -| Card search | `mcp__mappa__wiki.search(q, scope?, project?, projects?, limit?)` | cards {ref, project, slug, title, summary, snippet, related} — without bodies (wiki:2661) | -| Create a page | `mcp__mappa__wiki_create(project, slug, body)` | **carve-out without a lease** | -| Update a page | `mcp__mappa__wiki_update(project, id, title?, body?, version)` | id = num \| ref wiki:N \| uuid (канон task:1221); **version-based**: conflict → 409 → retry with the fresh version from wiki_get | -| Path between entities | `mcp__mappa__graph_path({from, to})` | shortest chain, BFS | -| Neighbors / outgoing | `mcp__mappa__graph_neighbors({id})` | node edges with target resolution | -| Incoming links | `mcp__mappa__graph_backlinks({id})` | who references the node | -| Graph health | `mcp__mappa__graph_stats()` | nodes/edges/components | - -**Writing — carve-out (create) / version-based (update), no lease (interactive -contract, wiki:2660).** `wiki_create` requires no claim_token; `wiki_update` -takes the expected `version` (fresh from `wiki_get`) — conflict → 409 → -re-GET → retry. - -**Frontmatter-summary (wiki:2661, card search).** On create/update/promote -write `summary:` — ONE essence line in the page frontmatter (`---\ntitle: …\nsummary: one line\n---`). The `wiki.search` cards read it (without summary the -card is poorer — snippet fallback only). Don't insert duplicate info into the -body: the summary is compiled once, in the frontmatter. - -**Refs and ids (#1037/#1028, канон task:1221).** The public surface carries the per-type ref by -full name as the first field: `ref: "wiki:3"` (decision 20, convention #1028), -`num` next, the global `id` — internal (last). `wiki_update` takes the -`num` | `ref wiki:N` | uuid (этап A task:1221 задеплоен: голое число = num; -internal id наружу не используем — выпилится в этапе B). In prose — -slug/name first, ref as anchor: "the spec `concepts/session-live-ingest` -(wiki:2604)". In page bodies — wikilinks by slug (`[[concepts/foo]]`, -decision 4) or per-type refs by full names (`[[task:N]]`/`[[inbox:N]]`). - ---- - -## The cycle: three operations - -### Ingest — «заингесть X» - -1. Read the source completely. -2. Extract: entities, concepts, packages, cross-results. -3. Create `summaries/` — one summary page per source (~50–150 lines; - put the raw link in frontmatter `raw_path` + `ingested:`). -4. For every affected page: - - exists → update (`wiki_update(project, id, body, version)` — version - fresh from `wiki_get`; 409 → re-GET → retry). **Mark contradictions - explicitly** with a `> **Contradiction:** source A says X, source B — Y` - block. Don't overwrite silently. - - missing → create (`wiki_create`, carve-out). -5. Update `index` (catalog: one line per page) — optional; the default catalog - is `entity_search` (decision 1). -6. Report to the user: what was created, what updated, which contradictions. - First ingest of a new wiki: create `AGENTS` (canon) + `CLAUDE` (pointer). - -**Op-log — automatic.** Every write operation is already logged by the service -into the `logs` table (component=entity type, message=slug+operation; to view — -`mcp__mappa__admin_logs`). Don't maintain a manual `log` page — it's a -duplicate, the audit trail lives in the service (decision 12, ratified -2026-08-24). - -**One ingest can touch 10–15 pages. That's normal — that's what LLMs are for.** - -Write order: all wiki mutations in one cycle; create — carve-out, update — with -version (fresh from `wiki_get`); 409 → re-GET → retry. No lease/claim needed -for writing (wiki:2660). - -### Query — a question to the wiki - -1. Read `index` first, then dig into pages (`wiki_get` by slug). -2. Answer with quote-wikilinks: `[[concepts/foo]]` (edges are created on - write, decision 4). -3. **Compounding the wiki.** If the answer is a real synthesis (comparison, - analysis, new link) — ask the user: "Save as a wiki page?" Good questions - become pages in `concepts/`. - -**Relational/structural questions — don't read, call the graph** (next -section): links form a graph that an LLM doesn't traverse reliably by reading. - -### Lint — «проверь вики» - -Look for: -- **Contradictions** between pages. -- **Orphans** — pages without incoming links: `graph_backlinks(id)` (id from - `wiki_get`) → no incoming edges = orphan. -- **Stale-claims** — a page's `updated_at` older than the source it summarizes. -- **Lost entities** — concepts from the text without their own page - (`entity_search` by name → empty). -- **Empty/TODO sections.** - -Report — a punch list. Don't delete anything automatically. - ---- - -## Graph layer (relational/structural questions) - -**Stop and call the graph.** On a relational/structural question about the wiki -or any mappa entities (tasks, letters, sessions) **don't answer after reading -one page** — that's the 0%-recall failure the graph layer exists for. The -service walks the edges deterministically (BFS) and returns the answer in a few -lines; context doesn't get polluted. - -Question form → tool: - -| Question | Tool | -|---|---| -| relational — «что связывает X и Y», «путь между», "what connects", "shortest path" | `graph_path({from, to})` | -| neighbourhood — «соседи X», "neighbours of X" | `graph_neighbors({id})` | -| incoming — «кто ссылается на X», «backlinks», "what links to X" | `graph_backlinks({id})` | -| health — «сироты», «битые ссылки», «здоровье вики», "orphan pages" | `graph_stats()` + `graph_backlinks(id)` | - -**Addressing: slug → num/ref/uuid.** Resolve the key via `wiki_get`/`entity_search` -(ref/num/uuid — публичная адресация, канон task:1221; internal id не используем). Graph -responses carry per-type refs by full names (`task:N`/`inbox:N`/`wiki:N`, convention #1028) — -reference them, not internal ids. An empty `path` = the link genuinely doesn't exist — -say so; don't invent a chain from textual proximity. - -**Precondition — the graph is actually connected.** If unsure — first -`graph_stats()`: `edges` ≈ 0 ⇒ empty graph, answer by reading. (Slugs without -[[links]] create no edges; orphans are normal for sparse wikis.) - ---- - -## Page formats (MANDATORY) - -### Frontmatter - -```yaml ---- -title: Human-readable name -type: entity | concept | package | summary | contradiction | open-question | overview -tags: [short, tokens] -sources: [concepts/mappa.md] -updated: 2026-08-24 ---- -``` - -`summaries/` pages additionally carry `ingested: YYYY-MM-DD` and `raw_path: …`. -`contradictions/` — `status: open | resolved | accepted-divergence` and -`affects:`. `open-questions/` — `status: open | answered | obsolete` and -`touches:`. - -### Slugs - -- `kebab-case`, **Latin only**. Transliterate Cyrillic/other scripts - («план переписывания» → `ozon-client-rewrite`). The original title — in H1 - and frontmatter. -- `entities/`, `concepts/`, `packages/`, `summaries/`, - `contradictions/`, `open-questions/`. - -### Op-log — the `logs` table, not a page - -File-based `log.md` is dead (decision 12/15, ratified 2026-08-24). The service -writes the op-log itself on every write operation: `mcp__mappa__admin_logs` -(filters level/since/component/entity, retention 14d). Don't create, append, -or parse a manual `log` page. - -### `index` — catalog via search - -Catalog = `entity_search(q, type='wiki', project)` (decision 1). The `index` -page — optional orientation aid: one line per page -`- [Title](concepts/foo.md) — hook.`, sections by type. Update only if the -page already exists; don't proliferate catalog duplicates. - -## Quick reference - -| Situation | What we touch | -|---|---| -| Ingest one document | `summaries/` (new) + 3–15 entities/concepts/packages (+ optional `index`) | -| Query | (read) + possibly a new page | -| Query relational | graph_* (BFS), not reading | -| Lint | (read) + graph_backlinks/stats for orphans | -| New project wiki | the first ingest creates `AGENTS` + `CLAUDE` pointer; op-log — automatic | - -## Common mistakes - -- **Editing `summaries/`.** Not allowed. Only a status block on an explicit request. -- **Dumping raw content into `summaries/`.** A summary is a summary. Reference - the raw, don't copy it. -- **Silent overwrites.** A new source contradicts a page — mark with a - `> **Contradiction:**` block; don't wipe it. -- **Narrative op-log.** Don't maintain it by hand: the service writes logs - itself (admin.logs). -- **Non-ASCII slugs.** Break grep and cross-platform compatibility. Transliterate. -- **Missed contradictions in lint.** The wiki's value is in exposed tensions, - not in false consensus. -- **Writing without version (update).** `wiki_update` without a fresh version → - last-write-wins, risk of wiping someone else's work; take the version from - `wiki_get`, 409 → retry. -- **Holding a claim for reading/thinking.** A claim is for the duration of - work; reading — carve-out. -- **Answering a relational question by reading one page.** That's the exact - 0%-recall failure — call graph_*. -- **Slugs/paths into graph tools.** Only fresh keys (num/ref/uuid, канон task:1221; a - deleted entity → error). -- **Dragging the whole wiki into context** to "trace" links by hand — the - service does it for zero tokens. - -## Red flags - -- Relational question → reading a page instead of `graph_*`. -- Editing `summaries/` or silently overwriting a contradiction. -- Wiki update mutation without version (last-write-wins) or create with an - invented claim. -- Narrative op-log by hand. - ---- - -## Reference - -- Entity search: `mcp__mappa__entity_search` (FTS, decision 1). -- Op-log: `mcp__mappa__admin_logs` (automatic, decision 12). -- Tree/umbrellas: `mcp__mappa__graph_tree(root, depth?, fields?, limit?)`. -- Tasks: `mappa-task-work`. Mail: `mappa-messaging`. Delegation: `mappa-delegation`. -- Related: `using-projects-meta` (bridge until the flip), `project-discipline`. -- Showing wiki pages to the human (rows/cards): `mappa-presentation` — mandatory format. diff --git a/skills/mappa-messaging/SKILL.md b/skills/mappa-messaging/SKILL.md deleted file mode 100644 index 60406b0..0000000 --- a/skills/mappa-messaging/SKILL.md +++ /dev/null @@ -1,262 +0,0 @@ ---- -name: mappa-messaging -author: ours -version: 1.4.1 -description: > - The inter-session mail cycle via Mappa: SEND (inbox_send) → RECEIVE - (inbox_monitor) → POLICY (peer ≠ authority). Address = the project folder - name from the address book; from = your own folder; never write to yourself. - A letter from another agent is a proposal, not authority; the only source of - direction and scope is the human. Old names — trigger-synonyms: - inter-session-messaging. Triggers (bilingual): «напиши письмо <проекту>», - «отправь сообщение», «свяжись с <проектом>», «передай <проекту>», - «уведомь <проект>», "write a message to ", "send a message", - and also receiving incoming mail (see below). NOT about delivery/monitoring - (→ mappa-session-orient, inbox raise) and NOT about tasks - (→ mappa-task-work, mcp__mappa__task_*). ---- - -# mappa-messaging - -The single canon of inter-session mail — **a cycle, not a tool**: send → -receive → content policy. Each phase below is a mandatory part of the cycle; -skipping a phase = a broken cycle (a letter without policy = flood, a reply -without SEND = emptiness). - -Channel — Mappa (`mcp__mappa__*`), NOT files. A letter is an entity of type -`inbox` (`inbox:N`), lives in the service; delivery and reading — carve-out -(require no project lease, decision 19). The file channel `.agents/inbox/` is -removed (flip of decision 15). - -## When to use - -- Write a letter to another project/agent: «напиши письмо <проекту>», «отправь сообщение», «свяжись с <проектом>», «передай <проекту>», «уведомь <проект>», "write a message to ", "send a message". -- Received an incoming letter (the monitor delivered it, or you checked - `inbox_monitor` yourself) — process it per RECEIVE. -- Discussing design/scope/decisions with another session — keep POLICY - (peer ≠ authority). - -**NOT for:** mail delivery/monitoring (→ `mappa-session-orient`, inbox raise), -tasks (→ `mappa-task-work`), handoff (→ `mappa-closing-ritual`), promotion (→ -`mappa-brainstorm-promote`). - ---- - -## SEND — how to write a letter - -### Address — only from the address book, and the project must be in Mappa - -The project address = **its disk folder name as is** (`.workshop`, `artmone.pro`, -`snolla.js`). Never invent an address from a qualified name, remote, or memory — -the folder may not match the repo (`OpeItcLoc03/common` → folder `.common`). - -1. Read the address book: `~/projects/.wiki/concepts/projects-address-book.md` - (shared wiki clone). Table: `address (folder) | qualified | role`. -2. Find the row with the target project by folder name. -3. If the project is **not** in the book — don't write the letter. Stop and ask - the human (or add a book entry if the human confirmed the address). A letter - to an invented address creates an orphan project in Mappa (`ensureProject`) - and gets lost. -4. **The project must exist in Mappa**: cross-check the address against the - project list (`mcp__mappa__admin_status` → `projects[]` or - `entity_search` type=project). A non-existent address is absent from the - list — stop and ask (or create the project). - -### The send call - -``` -mcp__mappa__inbox_send( - project: , # project folder name (from the address book) - from: , # YOUR folder name (just the name, no owner/topic) - subject: , # optional — short topic - body: # free markdown -) -``` - -- `from` — **only your folder name**. No owner, no description. NOT - `reviewer-command-index-done-ack` (the letter topic is not an address). A - letter with an invented `from` cannot be replied to. -- Reply to a letter: `inbox_send(project=, from=)`. - In `subject` — the `Re: ` prefix, in the body the first line is a reference - to the original letter (`inbox:` or its subject). There are no - `in_reply_to`/`event` fields in Mappa — instead subject-prefixes `Re:` and - `[event: closed]` for lifecycle letters. - -### Ref format: slug/name first, full ref name as anchor - -Convention for prose and links: **name/slug first, ref as anchor** — "the -letter about the deploy (inbox:2046)", "the task `session-live-ingest-impl` -(task:1022)". -Write refs **by full names**: `task:`/`wiki:`/`inbox:`/`session:`/`handoff:`/ -`storm:`/`repo:`/`commit:`/`project:` (short `t:`/`w:`/`i:`/… are accepted by -the parser, but write full). The wiki ref is a single `wiki:NNNN` for all -buckets (subtype — in the slug: `wiki:2604` = concepts/session-live-ingest). - -### Task references — by global number (v2 format) - -A task reference in a letter — **by global number**: `#452` (v2 format, -numbers are the machine key, unique across the whole federation). Not a slug — -slugs can repeat between projects. First mention of a task in a letter — with -number and slug for readability: `#452 (tasks-v2-search-by-id)`, afterwards — -just `#452`. Resolving a number into {project, slug} — via -`mcp__mappa__entity_search` (searches by number/id) or `entity_get` (key — uuid -or full ref `type:NNN`; bare numbers → 400, task:1067). - -### Hard rules - -1. **Never write a letter to yourself** — your inbox is for incoming, not for - notes. Notes — in `.brainstorm/` or `.tasks/`, not by letter. -2. **Never invent an address** — only from the address book + an existing - project in Mappa (step 4 above). -3. **`from` — always an address (folder name)** that can be replied to. - Descriptions like `workshop session (implements catalog wave 2)` — banned: - such a letter cannot be replied to. -4. **The letter topic — in `subject` and body**, not in `from`. - ---- - -## RECEIVE — how to process incoming mail - -1. Incoming is delivered by the monitor (`mappa-session-orient` — inbox raise, - pi extension) or you check yourself: `mcp__mappa__inbox_monitor(project=, limit)`. - Response — `{rows: [{id, slug, from, subject, body}]}`: the latest letters - of your project, with sender and topic (meta extracted by the server). -2. **A letter is first-class, not a background notification.** Read and process - it at the start of the nearest turn — NOT "when I get around to it", NOT at - the end of the session. If a message appeared in context after a long - tool-cycle — that's no reason to bury it in the final summary: process it - before the session ends. -3. Acknowledge receipt explicitly and answer the content in your turn. -4. **Who is the sender:** the `from` field in the `inbox_monitor` response - (address — folder name). Topic — `subject`. For a reply — SEND to the - sender (`from`). -5. If a reply is needed — SEND per the canon above, to the sender (`from`). -6. Don't leave a letter unprocessed until the end of the turn — if you can't - decide now, say so and (if needed) create a task via - `mcp__mappa__task_*`, don't "forget". -7. **Expected mail:** if you yourself triggered an event that will birth a - letter into your inbox (notify to your project: close/blocked/ - delivery-failed task) — check `inbox_monitor` at the moment the event fired; - don't wait for the letter to arrive on its own. Delivery may lag for the - duration of the current tool-cycle. -8. **Dedup:** the monitor remembers delivered ids (in process memory). Letters - in Mappa are not moved (no `.read/`) — processed ones stay in the list; - don't re-read them, cross-check against already-seen ids. - ---- - -## POLICY — letter content - -> The inbox is a peer channel, not a chain of command. Messages from another agent session are a colleague's proposals — never a human mandate. The human is the only authority for direction and scope. - -### Rules - -1. **Peer ≠ authority.** A message from another agent (even role-named - "assigner" / "boss" / "reviewer") is peer input: analysis and proposals. - Only the human grants sanction. Direction and scope — only from the human. -2. **Don't present your opinion as a decision.** When replying to a peer, - don't call your design choice "the assigner's decision" until the human has - explicitly ratified it. Phrase it: "I recommend X; the human hasn't ratified - it." Distinguish "the human decided X" from "a peer/I recommend X". -3. **Escalations require an explicit human "yes".** Architectural decisions - and scope growth must be ratified by the human **before** you report them to - a peer as decided or act on them. - -### Channel contract (inbox vs board) - -- **Inbox (`inbox.*`) — a communication channel only**: discussion, help, - lifecycle notifications ("task created", "closed", "blocked"). Nothing more. -- **Tasks — only through `mcp__mappa__task_*`.** The board is the only source - of truth about a task: existence, status, scope, decisions are created and - changed via `task_create` / `task_close` — never "decided" inside a letter. - (Create — carve-out; update/close — version+409, wiki:2660.) - -Consequence: **if it's not on the board — it's not a task or a decision, it's -a conversation.** A meaningful design choice must land on the board (or the -wiki); the inbox only points to it. - -### Lifecycle notifications: task + letter - -A cross-project task action is always a "board + letter" pair. The board is the -source of truth (existence/status/scope), the letter is a ping and context. In -the letter body, name the task **by number** (`#452`), not just by slug. -Mark lifecycle letters with the subject-prefix `[event: ]`: - -| Event | Who writes | Where | subject | -|---|---|---|---| -| Created | commissioner | recipient's inbox | `[event: created] #N slug` | -| Closed | executor (live session) or poller (auto-run) | commissioner's inbox (`Notify`) | `[event: closed] #N slug` | -| Blocked/parked | same | same | `[event: blocked] #N slug` | - -Letter body — 1-2 lines + numbers/slugs, don't duplicate the board. A live -session learns about a task ONLY through the letter (the board doesn't ping); -the commissioner learns about closing only via `Notify`/letter. Assignment -rule — `mappa-delegation` (the "board+letter pair" step); closing rule — -`mappa-task-work` (close). - -### What this is against - -Two sessions ping-pong, each agrees with the other's frame and adds scope, the -human is nominally in the loop. Echo-chamber signature: fast replies, agreement -with your frame, scope growth every round. This is -`user_context_agents_path_of_least_resistance` one level up: sessions bypass -human ratification — fake "decided" through mutual agreement. - -### Circuit-breaker - -Noticing scope growth without an explicit human "yes" — **stop and ask the -human**: "I'm a peer session, not a human authority; I'm escalating scope here; -do you really want this to go out as decided?" - -**Multi-session caveat — don't shout "override" from partial sight.** When the -human runs several sessions, your view of what they ratified is partial. A peer -acting on the "unratified" may have real human sanction from a channel you -don't see. On an apparent violation — **ask "did you ratify this in another -channel?"**, don't accuse. Lesson 2026-06-16: workshop called the close in -common a "fake attribution of ratification"; in reality the human approved -directly in the common channel while workshop was still discussing. Surface the -gap with a question — the human reconciles the channels. - -### Why this exists - -Arose 2026-06-16: workshop and common ran a multi-round design exchange over -the inbox; workshop escalated the design (tamper-guard → prevention → -oracle-integrity → runner-owns-verifier → close-moves) and reported every step -as "the assigner's decision" — implying human sanction that didn't exist. -common recognized the echo chamber, read its own stop-hook, and correctly -refused to implement the unratified redesign, asking the human. The methodology -lives in the skill, not in per-session memory. - ---- - -## What NOT to do - -| Temptation | Reality | -|---|---| -| "A letter is a quick way to settle it, I'll formalize later" | If it's not on the board — it's not a task or a decision, it's a conversation. Design choice → board/wiki, the letter only pings. | -| "I'll write to the .common channel, they'll approve" | A peer letter is a proposal, not a sanction. The human is the only authority for direction and scope. | -| "The slug is unique, I'll reference it" | Slugs repeat between projects — reference by global number `#452`. | -| "I'll reply at the end of the session, collect everything at once" | A letter is first-class: process at the start of the nearest turn, not "when I get around to it". | -| "I don't have the address — I'll write from memory/qualified" | Address — only from the address book; an invented address breeds an orphan project and the letter gets lost. | - -## Red flags - -- Writing a letter to yourself / to an invented address / with a `from`-description. -- Ping-pong: fast agreements, scope growth every round, the human nominally in the loop. -- Calling your choice "the assigner's decision" without explicit human ratification. -- A letter "decides" a task while it's absent from the board. - -All these flags = **stop and ask the human** (or create a task/wiki page). - ---- - -## Reference - -- Incoming delivery/monitoring: `mappa-session-orient` (inbox raise; pi extension inbox-monitor). -- Address book: `~/projects/.wiki/concepts/projects-address-book.md` (shared wiki). -- Mappa project list: `mcp__mappa__admin_status` (carve-out, no lease). -- Tasks: `mappa-task-work` (board = `mcp__mappa__task_*`). -- Handoff: `mappa-closing-ritual` (write) / `mappa-session-orient` (read). -- Delegation: `mappa-delegation` (the "board + covering letter" pair). -- Showing letters to the human (rows/cards): `mappa-presentation` — mandatory format. -- Related: `recommend-dont-menu` (response style), `project-discipline`. diff --git a/skills/mappa-presentation/SKILL.md b/skills/mappa-presentation/SKILL.md deleted file mode 100644 index c46f7d4..0000000 --- a/skills/mappa-presentation/SKILL.md +++ /dev/null @@ -1,217 +0,0 @@ ---- -name: mappa-presentation -author: ours -version: 1.1.0 -description: > - The single standard for showing Mappa entities to the human — the answer - format an agent renders for the eyes: list rows (board/inbox/search) and - full cards (one entity). Two modes, fixed field order; server display/card - fields copied verbatim (row → display, card → card, dates UTC+Z); - fallback templates render local time; never raw JSON. Mandatory - for ANY display of mappa entities - (task/inbox/wiki/brainstorm/session/handoff/repo/commit/operator/project) — - «покажи таски», «что на досках», «письма», «какой статус», «дай - подробнее», any answer carrying entities. Old name — trigger-synonym: - mappa-display. Complements (does not replace) convention #1028 (ref - format), task status emoji (mappa-task-work), search cards (wiki:2661); - server-side display/card fields (task:1176/1177) copied verbatim — - the templates here are the canon fallback until the deploy (v0.20.0). ---- - -# mappa-presentation - -The single standard for **what the human sees** when an agent shows Mappa -entities. Problem it solves: agents rendered entities "as it happened" (raw -JSON dumps, random field sets, slug without number), the human guessed and -re-asked "give me more details". Here — the mandatory format. - -Channel — output to the human in chat. NOT about tools and NOT about data — -about presentation. - -## Hard principles - -1. **Never show raw JSON** of a tool result. Any answer about an entity is - rendered per the templates below. Dumping JSON into chat = bug. -2. **Two modes:** `row` (lists: board, inbox, search results — one line per - entity) and `card` (a single entity on request or when detailing — a full - block). -3. **The card carries ALL fields** of the template. Do not trim "to avoid - clutter": the human re-asks precisely because a field was dropped. -4. **Field order is fixed** (per template), do not rearrange. -5. **Dates — server fields: UTC+Z verbatim; fallback: local and human.** - Mappa stores and returns UTC (canonical machine truth — the server never - converts). If the entity carries server `display`/`card` — copy the date - verbatim as rendered (UTC + `Z`: row `YYYY-MM-DD`, card `YYYY-MM-DDTHH:MMZ`), - no conversion. Fallback (agent-rendered): show local (operator's machine): - row `YYYY-MM-DD`, card `YYYY-MM-DD HH:MM` — no seconds, no `T`/`Z`; if the - local timezone is unknown to the agent — show UTC with an explicit `Z`. - Never invent a zone. -6. **Refs always full-name** (`task:N`, `inbox:N`, `wiki:N`, … — convention - #1028), never `#`, never short aliases. - -## Server-side display/card fields (priority) - -Серверные `display` (row) и `card` (markdown) поля реализованы (task:1176/1177, -репо 0bf09c6; каналы: /entities/:id, /wiki/:project/:slug, /wiki/:slug, -/search/full, /task/:id, /task/list) — **копировать verbatim** в -соответствующем режиме (row → display, карточка → card). Даты в серверных -полях — UTC с суффиксом Z (row YYYY-MM-DD / card YYYY-MM-DDTHH:MMZ), не -конвертировать. Шаблоны ниже — fallback-канон ДО деплоя (деплой: v0.20.0, -проверять /health) и для составления списков. Если серверное поле есть, но -выглядит битым — рендерить по шаблону и упомянуть расхождение. - ---- - -## Task - -### Row (board/list) - -``` -🔴 task:1062 mappa-task-work — P1 · due 2026-08-30 · созд. 2026-08-24 -``` - -Order: status emoji, ref, slug (title only if shorter than ~50 chars), -project (only in cross-project lists: ` · ` after the slug), -priority, due (if any), created date. Dependencies — suffix `· ← task:1060` -(parent, if present). Overdue — mark `(просрочена)`. - -### Card - -``` -🔴 task:1062 mappa-task-work -Проект: .workshop -Название: -Статус: active · Приоритет: P1 · Дедлайн: 2026-08-30 (просрочена) -Владелец: <owner> -Создана: 2026-08-24 18:25 · Обновлена: 2026-08-25 19:18 -Родитель: task:1060 <parent-slug> -Блокер: <only when status=blocked — what blocks> -Описание: -<first ~15 lines of markdown; end — «… ещё N строк»> -``` - -## Inbox (letter) - -### Row (inbox/list) - -``` -inbox:2257 · от mappa · 2026-08-25 · «1169 — дубль (закрыта), 1171 — done» — обе P2 закрыты… -``` - -Order: ref, `от <from>`, date, subject in quotes, then body teaser (first -~80 chars). If subject is empty — the body teaser replaces it. - -### Card - -``` -📬 inbox:2257 · от mappa -Тема: «<subject>» -Дата: 2026-08-25 17:54 -Отправитель: <sender_display> ---- -<body — first ~20 lines of markdown; end — «… ещё N строк»> -``` - -## Wiki - -### Row - -``` -wiki:2656 AGENTS (.workshop) — обновл. 2026-08-25 -``` - -### Card - -``` -wiki:2656 AGENTS (.workshop) -Заголовок: <title> -Summary: <frontmatter summary, one line> -Обновлена: 2026-08-25 19:18 ---- -<body — first ~20 lines; «… ещё N строк»> -``` - -## Brainstorm (buffer) - -### Row - -``` -brainstorm:14 mappa-presentation (.workshop) — buffer · обновл. 2026-08-25 -``` - -### Card — like wiki, plus `Статус: buffer | archive`. - -## Session - -### Row - -``` -session:742 (vitya) — deepseek-v4-flash · clean · 2026-08-25 -``` - -Order: ref, project, model, end_state (clean | active | stale), date. - -## Handoff - -### Row - -``` -handoff:12 (.workshop) — active · «<summary up to ~100 chars>» -``` - -## Repo / Commit - -### Row - -``` -commit:0e3c55a (pi-extensions) — «README переписан» · 2026-08-25 -``` - -## Operator / Project - -### Row - -``` -operator:vitya — owner · DESKTOP-NSEF0UK -project:83 mappa — role: app -``` - ---- - -## List rules - -- **Tasks:** sort 🔴 → 🟡 → ⚪ → 🔵 → 🟢; inside — by due (overdue first), - then by created. Cross-project — grouped by project, project mandatory. -- **Inbox:** newest first (latest first). -- **Search/cross-project:** project mandatory in every row. - -## Prose rules - -- First mention in text — «slug/name (task:N)» (convention #1028). -- In letters between agents — global number `#N` (format v2, mappa-messaging); - in chat with the human — per-type refs `task:N`. - -## What NOT to do - -- Dump JSON into chat. -- Card with dropped fields "for brevity". -- List row without ref / without status / without date. -- Invented timezones or "yesterday/today" instead of dates. -- ISO `…T…Z` timestamps with seconds in chat — show local `YYYY-MM-DD HH:MM`. -- Internal id instead of ref, short aliases (`t:`/`w:`) instead of full names. -- Trimming body without the «… ещё N строк» marker. - -## Red flags - -- About to paste a tool's output into chat as-is → stop, render per template. -- Human re-asked "give more details" about an entity → a field was dropped - from the card; return the full template. - ---- - -## Reference - -- Ref format: convention #1028 (mappa), full names `task:`/`wiki:`/`inbox:`/… -- Task status emoji: `mappa-task-work`. -- Search cards: `mcp__mappa__search` / `wiki_search` (wiki:2661). -- Task work: `mappa-task-work`. Mail: `mappa-messaging`. Wiki: `mappa-knowledge`. diff --git a/skills/mappa-session-orient/SKILL.md b/skills/mappa-session-orient/SKILL.md deleted file mode 100644 index 14c54b8..0000000 --- a/skills/mappa-session-orient/SKILL.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -name: mappa-session-orient -author: ours -version: 1.1.0 -description: > - Start phase of the forkflow: contract + reading (pull --ff-only → handoff - read → inbox raise → liveness summary "alive/dead" → live-ingest query). - Also needed for ad-hoc sessions without an AGENTS.md contract. Absorbs - pulling-before-work, session-handoff(read), session-inbox-monitor(raise), - using-system-snapshot (liveness) + live-ingest query (old names are - trigger-synonyms). Boundary: orient answers "alive/dead" in one line; deep - diagnosis is outside the suite (escalate to a human / a diagnostic session). - Triggers (bilingual): «что на сессии», «кто последним работал», «продолжи с - места», «orient me», "what's on the session", "who worked last", "continue - from where I stopped", "orient me", session-start ritual, «pull remote before - work», "pull remote before work". ---- - -# mappa-session-orient - -Start phase of the agent cycle: **contract + reading**, a thin layer — answers -the question "alive/dead" (one line per section), does not go deep. Also needed -for ad-hoc sessions (where there is no AGENTS.md contract — orientation is -still mandatory). - -> **Boundary session-orient / ops (w:2605, round 3):** orient = "alive/dead"; -> ops = "why and what's next". A problem at start → **do not dig deeper**: -> hand it to the human or to a diagnostic session (outside the suite). - -## When to use - -- Session start (ritual, order strictly per Steps). -- «что на сессии», «кто последним работал», «продолжи с места», «orient me», - "what's on the session", "who worked last", "continue from where I stopped". -- Ad-hoc session without a track/task — orientation anyway (contract + reading). - -## Steps (order — the ritual) - -### 1. Contract - -Read the project's `AGENTS.md` (canon; `CLAUDE.md` — legacy pointer). If there -is no AGENTS.md — ad-hoc: no contract, but orientation continues (steps 2–6 -don't depend on it). - -### 2. Pull (pulling-before-work, full cycle) - -`git pull --ff-only` — once at start. Checks in order: git work-tree? (no → -silent exit), pull policy (`pull.rebase=true` + `pull.ff=only`, set-if-absent), -origin remote? (no → skip), clean tree? (dirty → skip, no stash), HEAD -attached? (no → skip), upstream? (no → skip), `git pull --ff-only`. -**Never auto-merge/rebase, never stash.** Repeat pull — only on explicit -"sync". - -### 3. Handoff read (session-handoff read part) - -1. `mcp__mappa__entity_search(q='', type='handoff', project=<name>, limit=1)` — - if empty, silent exit (project's first session). -2. **Staleness:** `meta.date` > 7 days → ask the user "the handoff is stale, - override or continue?". -3. **Summarize + Orient:** retell in one block (summary / open_treks / - ask_user / guards / recent_commits): "the previous session proposed X. Do we do it?" -4. **Wait.** No actions until the user confirms. Default = orient + ask, no - auto-execute. - -### 4. Inbox raise + sweep (session-inbox-monitor) - -Raise the persistent monitor on the project's inbox (pi: the inbox-monitor -extension polls `GET /inbox?project=<cwd>`; opt-in — the string -`inbox monitor: raise on start` in AGENTS.md, live re-check every tick). Sweep: -`mcp__mappa__inbox_monitor(project=<name>)` — unread letters may change the -plan; handle each per `mappa-messaging` (a letter is first-class, at the start -of the nearest turn). - -### 5. Liveness summary (using-system-snapshot) — "alive/dead" - -One or two probes in the current turn, compress into 3–4 lines, no raw dumps: - -``` -mcp__mappa__meta_health → 🟢/🔴 Mappa alive (header on outage) -mcp__mappa__admin_status → counters by type/project (load) -mcp__projects-meta__meta_system_snapshot → poller (running? + projects) / docker (N/N up, - else the problematic ones) / tasks (Σ active/blocked, - cache — may be stale) -``` - -**Never assert liveness from memory** — only a tool call in this same turn. If -the snapshot shows a problem → **escalate, don't dig**: "problem at start, not -investigating — handing to the human / a diagnostic session" (ops outside the -suite). - -### 6. Live-ingest query (consumer of session-live-ingest, #1022/#1024) - -Dependency: server #1022 (v0.8.0) + client part #1024 (pi session-sync, -.session written by the client). Contract — w:2604. - -1. `mcp__mappa__session_list(project=<name>, stale_minutes?)` — the project's - latest sessions, latest-first (`updated_at DESC`), with - end-state/ts/meta-triple {project, runtime, machine, folder}. -2. **Stale-active detect:** end-state≠clean AND updated_at < now−X → - "<runtime>@<machine> was running, not finished" (crash-detect). -3. **"Different triple + not finished"** → propose (peer canon, human's - decision): ignore / nudge by letter (`mappa-messaging`: letter to that - triple) / continue yourself. -4. **Same-triple (`/resume`):** same triple {runtime, machine, folder} → load - the remainder (pi-native resume or a brief from mappa). - -**Note (2026-08-24):** the `/session` routes are not yet deployed to prod -(server #1022 in repo, deploy awaits #1055) — on 404/"no route" the live-ingest -query is skipped without failing: orient continues (steps 1–5), the query part -— per actual availability. - -## Failure modes - -- **Problem at start** (service down, red snapshot, pull conflict) → don't dig: - escalate to the human / a diagnostic session (ops outside the suite). -- **Pull diverged** → "⚠️ diverged — resolve manually"; no auto-merge/rebase. -- **Handoff stale (>7 days)** → ask the user, don't silently override. -- **Live-ingest unavailable** (404 no route / no client #1024) → skip step 6, - don't block orientation. -- **Project not in mappa** (no handoff/session entities) → silent exit on the - corresponding steps; the project's first session — normal. - -## Side effects - -- Writes nothing, mutates nothing (orientation read-only: pull — local ff, - inbox-raise — monitor, liveness — probes, live-ingest — read). -- Raises the persistent inbox monitor (lives until the end of the session). - -## What NOT to do - -- **No auto-execute** from the handoff — orient + ask, no auto-action. -- **Don't dig into diagnosis** — orient = "alive/dead"; "why" is outside the suite. -- **Don't assert liveness from memory** — only a probe in this same turn. -- **No stash / no auto-merge / no auto-rebase** on pull — only `--ff-only`. -- **No repeated pull** in the session without an explicit "sync". -- **No multi-hop live-ingest chains** — one line "who worked last", the - proposal goes to the human. -- **Don't write** (handoff/wiki/tasks) at orientation — that's the finish phase - (`mappa-closing-ritual`). - -## Reference - -- Finish phase: `mappa-closing-ritual` (handoff write + PROPOSE). -- Tasks: `mappa-task-work` (board after orientation). -- Mail: `mappa-messaging` (letter replies, nudge a triple). -- Knowledge: `mappa-knowledge`. Delegation: `mappa-delegation`. -- Live-ingest spec: `concepts/session-live-ingest` (wiki:2604). -- **CC hook + operator (task:1061):** in a single-user setup CC sessions carry - `operator:vitya` even headless (`claude -p`) — there is no reliable hook - signal (detect via CLAUDE_INTERACTIVE if CC sets it). Do not treat operator - as a sign "a human is at the wheel"; source of truth — end-state + liveness. -- Deep diagnosis (outside the suite): `using-vds-ops` (VDS containers). diff --git a/skills/mappa-task-work/SKILL.md b/skills/mappa-task-work/SKILL.md deleted file mode 100644 index bd22003..0000000 --- a/skills/mappa-task-work/SKILL.md +++ /dev/null @@ -1,344 +0,0 @@ ---- -name: mappa-task-work -author: ours -version: 1.5.1 -description: > - The central cycle of working with tasks in Mappa: orientation → work - selection (priority/due) → execution → handover (close + review-umbrella) + - loop-mode "work the queue". Board = mappa entities (decisions 14/15/19/20); - create — carve-out, update/close — optimistic concurrency (version+409), - owner = persistent assignee, liveness — from the owner's session (interactive - contract, wiki:2660). Absorbs using-tasks + task-format + task-loop (loop-mode - INSIDE) + priority-due section (old names — trigger-synonyms). - Triggers (bilingual): «что на досках», «возьми таску», «какой статус», - «update status», «pause», «switch to X», «где мы остановились», "work the - queue", «поработай очередь», «прогони доску», "what's on the boards", "take - a task". Priority = the human's territory: agents set P0-P2/deadline only at - creation, default P1; overdue → notify, no auto-bump. NOT about delegation - (→ mappa-delegation), NOT about board overview (→ ops/using-system-snapshot). ---- - -# mappa-task-work - -The central cycle of working with tasks: **orientation → work selection → -execution → handover**. Board — mappa entities (`type=task`, `task:N`): read — -carve-out; **create — carve-out without a lease; update/close — optimistic -concurrency (version+409 → retry)**; **owner = persistent assignee; task -liveness — from the owner's session** (interactive contract, wiki:2660; poller -outside mappa). The skill is a cycle, not a tool: one mechanics for -selection/execution/handover, plus **loop-mode** («поработай очередь») inside — -no separate skill is created. - -> **Transitional (file channel).** While the poller/cache reads file boards -> (`.tasks/STATUS.md`), the legacy channel lives: file blocks must obey a -> strict format (see "Task format" below), mutations — via -> `mcp__projects-meta__tasks_*` (Gitea commits). New tasks — via -> `mcp__mappa__task_create`. Don't mix. - -## When to use - -- «что на досках», «возьми таску», «какой статус», «update status», «pause», «switch to X», «где мы остановились», "what's on the boards", "take a task". -- "work the queue", «поработай очередь», «прогони доску» → **loop-mode**. -- Task switch / pause / session end — keep the board consistent. - -**NOT for:** delegating to another agent/project (→ `mappa-delegation`), -promotion (→ `mappa-brainstorm-promote`), infra diagnosis (→ `using-vds-ops`), -cross-project overview (→ `using-system-snapshot`). - -## MCP surface - -| Operation | Tool | Note | -|---|---|---| -| Take the next ready task | `mcp__mappa__task_update(project, id, owner=<yours>, status=active…, version)` | **conditional update**: status→active, owner=X, version+409 (whoever is first with the right version — takes it) | -| Create a task | `mcp__mappa__task_create(project, slug, title?, description?, status?, priority?, due?)` | **carve-out without a lease**; per-type number (decision 20) | -| Close a task | `mcp__mappa__task_close(project, id, version)` | **version-based**: conflict → 409 → retry with the fresh version from task_get | -| Update a task | `mcp__mappa__task_update(project, id, parent?, owner?, status?, reason?, version)` | version-based; 409 → retry | -| Read a task | `mcp__mappa__entity_get(id)` | key: uuid, full ref `task:NNN`, or bare num (канон task:1221: голое число = num) | -| Read a task compact | `mcp__mappa__task_get(id)` | key: uuid, `task:NNN`, or bare num | -| Board list | `mcp__mappa__entity_search(q, type='task', project=<name>, limit)` | all statuses | -| parent_of tree | `mcp__mappa__graph_tree(root, depth?, fields?, limit?)` | umbrellas/hierarchy | -| Related entities | `mcp__mappa__graph_neighbors/backlinks(id)` | refs to the task | -| Overdue | `mcp__mappa__admin_overdue_scan(project?)` | P2 job: notify to inbox, no mutations | -| Owner liveness | `mcp__mappa__session_list(project, stale_minutes?)` | owner's session alive/stale → task active or not | -| Close notification | `mcp__mappa__inbox_send(project=<notify>, from=<yours>, subject, body)` | letter to the commissioner | - -**Owner = persistent assignee; liveness — from the session (interactive -contract, wiki:2660).** No TTL/claim/timer on the task: "took a task" = -conditional update (`status→active, owner=X` + version, 409 on conflict — -whoever is first takes it). Owner liveness — the session: a task with owner=X -is active while session X is alive (end-state≠clean, not stale; -`session_list(project)`); crash = stale → the human/orchestrator decides -(poller outside mappa, works on projects-meta file boards). Write paths -(create/update/close) require no leases/claims — only version on update/close -(409 on conflict). - -**Refs and ids (#1037/#1028, канон task:1221).** Tasks carry `ref: "t:N"` by full name as the -first field (`task:N`, convention #1028), `num` next, the global `id` — internal -(last; наружу не используем — адресация по num/ref/uuid, канон task:1221). Reference a task as -`[[task:N]]`/`task:N` in prose (slug/name first, ref as anchor: "the task -`mappa-task-work` (task:1062)"), never `#<global id>`. - -## Statuses (emojis for presentation) - -| Emoji | Status | Meaning | -|---|---|---| -| ⚪ | `ready` | not started, fully defined | -| 🔴 | `active` | in progress (usually one) | -| 🟡 | `paused` | in progress, resumable | -| 🔵 | `blocked` | waiting on external input | -| 🟢 | `done` | closed | - -Don't confuse: 🟢 — *done*, not "ready". Ready is ⚪. - ---- - -## The cycle - -### Phase 0 — Orientation - -1. **Inbox sweep** — `mcp__mappa__inbox_monitor(project=<name>)`: unread - letters may change the plan. Handle each per `mappa-messaging`. -2. **Board** — `entity_search(q, type='task', project=<name>, limit=50)`: sort - by status (🔴 → 🟡 → ⚪), one line per task — row format from - `mappa-presentation` (never raw JSON). -3. If the user named a task — `entity_get(key)` by its ref/num/uuid (`task:NNN` / bare num / uuid; канон task:1221 — голое число = num). -4. Confirm in one sentence: "We're in the middle of X, next step — Y". -5. Ask whether the plan is right before acting. - -### Phase 1 — Work selection (priority/due) - -1. **Task selection — from the board list** (`entity_search(q, type='task', project)`): - order — **P0 pool first, within it by deadline (overdue first), - then P1, then P2**; missing priority = P1 (task-priority-due). - "Take a task" = `task_update(project, id, owner=<yours>, status='active', - version)` — conditional update: status→active, owner=X, version+409; - whoever is first with the right version takes it (interactive contract, - wiki:2660). `owner` = `<machine>:<runtime>:<session>`. -2. **Local-first recommendation** — cwd board first; cross-project — a footnote - (`Cross-project: N 🔴 active — see tasks_aggregate`) only if N>0 and there's - no active 🔴 in cwd. Cross-project urgencies are information, not a driver - for "what to do here". -3. **Priority/Due — the human's territory (task-priority-due section):** - - An agent sets `priority`/`due` **only at task creation** (explicit - parameters or `**Priority:** P0|P1|P2` / `**Due:** yyyy-mm-dd` lines in - the description). Absent → default P1, no deadline. - - **After creation an agent doesn't change** priority/deadline — the - human's precedent is structural (agent updates are rejected by the - server). If you discover the task is actually P0 → park the question to - the human, don't bump it yourself. - - **Overdue:** due < today with ready/active → `admin_overdue_scan` - notifies the inbox **once, without mutations** — no auto-bump/auto-priority - change. - -### Phase 2 — Execution - -- **One active task** 🔴 per project. No parallelism. -- Read description + per-task file (`<slug>.md`, where present) before starting. -- Liveness — from the owner's session (`session_list(project)`), not a timer; - long tasks need no heartbeat (interactive contract, wiki:2660). -- **`session_break` gate** (from task-loop): if the task description has the - `session_break` marker — after close DON'T claim the next one: print - `🔚 SESSION BOUNDARY …` and stop (domain-switch / milestone / heavy infra). - -### Phase 3 — Handover (close + review-umbrella) - -1. **Pre-close coverage check.** Collect acceptance criteria from the - description. For each — evidence: a test in the diff, an artifact, a design - reference. No evidence for a criterion → ask the user "close or wait for - coverage". -2. Resolve/drop open questions. -3. `task_close(project, id, version)` → status `done`. `version` — fresh from - `entity_get(key)`/`task_get(key)` (key = uuid or `task:NNN`); conflict (409) → re-GET → retry. -4. **Notify letter (cross-project tasks).** If the task came from another - project (there's `from:`/`notify:` in description/meta) — `inbox_send` to - the commissioner: `project=<notify>`, `subject="[event: closed] <slug>"`, - body = the outcome (done, acceptance, references). A live session writes it - itself. Task 🟢 ≠ commissioner learned. -5. **Review for impl tasks (paired, canon rule 4 AGENTS .workshop).** - Every impl task gets a paired review — regardless of the assignment channel: - - **Assigned/delegated task** (`mappa-delegation`): the paired `<slug>-review` - was created at assignment (status=blocked, blocker=impl#); closing the impl - unblocks it — the next session in the target reviews. - - **Self-assigned task (your own board, mappa-task-work)**: YOU create the - paired `<slug>-review` (status=blocked, blocker=impl#) at the same moment - you create the impl task. **Do not review your own work** — run the review - through a subagent (`review_subagent` / `review-kit-pi-method`: clean - context, non-implementer) after close, then close the review with the - findings (or file them as follow-up tasks). If the subagent is unavailable - — leave the review task for the next session (blocked until then). - - If the impl is already closed — the review is created ready (not blocked). -6. **Deploy gate (impl requiring deploy).** Deploy is possible ONLY after: - close → review (paired, done) → all follow-up tasks closed. Order - irreversible. All deploys go strictly through `.admin` (secrets and - runbooks are service-use; other agents must NOT look into them — only - `secret:<path>` refs). The .admin task + covering letter are created via - `mappa-delegation` (canon task + letter) — for self-assigned deploys you - create them yourself (target `.admin`, not your own board). Never deploy - yourself. -7. Add a summary line to the handoff/wiki if present. - -### Pause / switch / session end - -1. Current 🔴 → `task_close` if finished (see Phase 3), otherwise mark - `status=paused` (owner stays; "where stopped" — in the description or handoff). -2. **Inbox sweep** at the task boundary (`inbox_monitor`). -3. Take the next one: `task_update(owner, status='active', version)` — the - previous stays 🟡. -4. Confirm the orientation before starting. - -> **Never lose Where I stopped** — critical field: in the description (last -> paragraph) or in the handoff entity (`mappa-closing-ritual`). Before the end -> of the session, definitely write the handoff. - ---- - -## Loop-mode — «поработай очередь» - -One trigger surface: «поработай очередь» / "work the queue" / «прогони доску» -→ this mode. Work the board **in this session**: take → work → close → take, -until the queue is empty or the user said stop. **Interactive cycle, not a daemon.** - -``` -task_update(owner, status=active, version) → 409? re-GET → retry → empty? → STOP "board is empty" - ↓ task -work in this session (read description + <slug>.md) - ↓ -finished? no → park: blocked (external) | paused (resumable) → next - ↓ yes -consult_policy: human-only/strict-human → STOP before close/commit, ask the user - ↓ auto -pre-close coverage check → task_close - ↓ -session_break on the task? → yes: print 🔚 SESSION BOUNDARY, STOP - ↓ no -next … -``` - -- **An empty queue is a natural stop, not a wait-loop.** No `CronCreate`, no - subagent spawn, no short pollers — that's the work of a separate poller. - Long watch ("keep working until I say stop" + explicit "keep checking") — - only one `ScheduleWakeup` with an interval ≥1200s, never `CronCreate`. -- **Non-finishable task:** external blocker → `status=blocked` + blocker - (concrete fact + what's needed); you interrupted (budget/stop) → - `status=paused` + where_stopped. One fallen task doesn't stop the cycle — - park and continue. -- **No heartbeat needed** — owner liveness from the session (wiki:2660); a - long task with a live session doesn't "expire". -- **Consult gate:** `auto` → autopilot up to close; `human-only`/`strict-human` - → work, then **STOP before close/commit** and ask the user. Push is never - automatic (project-discipline Rule 4: commit freely, push on explicit grant). - ---- - -## Task format (from task-format) - -### Primary: mappa task_create - -Task creation — **via the tool, not by hand** (decision 20): carve-out, no -lease/claim needed for create (wiki:2660). The number `task:N` is assigned by -the server — don't invent it. - -``` -mcp__mappa__task_create( - project: <project name>, // required - slug: <kebab-case>, // required, latin - title: <one line>, // optional - description: <markdown>, // body; [[refs]] → edges (decision 4) - status: ready | active | paused | blocked | done, // default ready - priority: P0 | P1 | P2, // only at creation; absent → P1 - due: yyyy-mm-dd // only at creation; absent = none -) -``` - -Slug rules: short, lowercase, kebab-case, latin. Description — markdown, -`[[refs]]` to related. Priority/Due — at creation OR as lines in the -description (`**Priority:** P0|P1|P2`, `**Due:** yyyy-mm-dd`; explicit -parameters override). - -### Legacy: .tasks/STATUS.md block (interim until the poller flips) - -While the file poller is not switched to mappa (#984), blocks in -`.tasks/STATUS.md` must obey a strict format — otherwise the poller silently -skips: - -```markdown -## ⚪ [#1234 my-task-slug] — One-line description. - -**Status:** ready -**Created:** 2026-08-23 -**Where I stopped:** (not started) -**Next action:** First concrete step the claiming agent runs. -**Branch:** master -**Weight:** needs-claude -**Notify:** OpeItcLoc03/workshop -<!-- created-by: you@machine / from: OpeItcLoc03/workshop / 2026-08-23 --> - ---- -``` - -Three load-bearing rules: **(1)** the header is exactly `## <emoji> [#<n> -<slug>] — <desc>` (h2, one emoji, `[#<n> <slug>]`, separator ` — `); **(2)** -fields are `**Label:** value` lines, bullets are ignored; **(3)** -`**Created:**` is mandatory. - -Fields the poller parses: `**Weight:**` (cheap-ok | needs-claude | -needs-human — **mandatory** for auto-claim), `**Notify:**` (<owner>/<repo>), -`**Requirements:**`, `**Runtime allowed:**`, `**Consult policy:**`, -`**Blocker:**` (only on 🔵), `**Priority:**`/`**Due:**` (as above). -`**Owner:**/`**Claim token:**/`**Claim expires at:**` — claim stamp, written -and cleared by the poller; a stuck stamp on ⚪ blocks the poller. - -**Weight — the field that decides the take:** without `**Weight:**` the poller -parks to 🔵 (`no backend for weight_tier: unknown`). Ordinary code → -`needs-claude`; critical infra (poller, MCP servers, deploy, CI, git hooks) → -`needs-human`. - ---- - -## Failure modes - -- **version conflict** on update/close → version is stale; re-GET the fresh - version, retry. Don't "resolve the conflict" by overwriting without version - (last-write-wins). -- **task_close on an unfinished task** → never. Park (blocked/paused). -- **owner on a task without a live session** → the task is formally active but - the owner is stale; ask the human (advisory, not a lock). -- **notify not specified (legacy)** → without it the boss won't learn about completion. -- **weight not specified (legacy)** → the poller parks (no backend for weight_tier). -- **update Priority/Due after creation** → the server rejects; park the - question to the human, don't bump yourself. - -## What NOT to do - -- **Don't invent numbers** — `task:N` is assigned by the server (decision 20). -- **Version discipline:** update/close — always with version (409 on conflict → - re-GET → retry). Create — carve-out without a lease (wiki:2660). -- **One active task** — only one 🔴 per project. -- **Never close without a coverage check** — evidence for every acceptance criterion. -- **Don't close unfinished work** — park, not close. -- **Don't bump priority/due after creation** — the human's territory. -- **Don't "settle" tasks by letter/in chat** — the board is the only source of - truth (mappa-messaging canon: "if it's not on the board — it's not a task"). -- **Don't poll an empty queue** — empty = stop and report; no daemon/CronCreate. -- **Don't autopilot human-only/strict-human** through close/commit; push — only on grant. -- **Don't batch tasks_create into one repo** — sha-lock conflicts; serialize. - -## Red flags — STOP - -- "I'll set a timer to check for new tasks" → no. Stop on an empty queue. -- "I'll spawn a background worker to run the board" → no. One cycle, this session. -- "The task isn't ready, but I'll close and mark it" → never. Park. -- "The task is clearly P0, I'll bump it myself" → no. Ask the human. - ---- - -## Reference - -- Delegation (assigning to agents): `mappa-delegation`. -- Mail (covering letters, notify): `mappa-messaging`. -- Knowledge (wiki-ingest after closing): `mappa-knowledge`. -- Session finish (handoff write): `mappa-closing-ritual`. -- Session start (pull/handoff/inbox/snapshot): `mappa-session-orient`. -- Promotion: `mappa-brainstorm-promote` (review-umbrella for promotions). -- Showing tasks to the human (rows/cards): `mappa-presentation` — mandatory format. -- Cross-project overview: `using-system-snapshot` (liveness) / `mcp__projects-meta__tasks_aggregate`. diff --git a/skills/report-mappa-issue/SKILL.md b/skills/report-mappa-issue/SKILL.md deleted file mode 100644 index c157164..0000000 --- a/skills/report-mappa-issue/SKILL.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -name: report-mappa-issue -author: ours -version: 0.2.0 -description: > - Use when working with mappa (MCP tools `mcp__mappa__*`, HTTP routes, mappa - skills) and anything deviates from the expected workflow: 500/5xx, "entity - not found" for an id that must exist, unexpected response shape, timeouts, - silent failures, wrong status, instability. Report it by mail to `mappa` AND - `.workshop` — never swallow, never only-local-log, never only in-chat. - TEMPORARY skill: active while mappa is unstable; retire when stabilized. - Triggers (bilingual): «маппа отдала 500», «entity not found», «неожиданный - ответ от mappa», «mappa вернула», "mappa returned 500", "entity not found", - "unexpected mappa response". ---- - -# report-mappa-issue - -Any deviation from the expected mappa workflow is reported **by mail to `mappa` -and `.workshop`** — immediately, with evidence. Never swallow, never hide it in -a local log, never postpone "until a digest". - -> ⚠️ **TEMPORARY skill:** active while mappa is unstable. It is a stopgap for -> collecting signals toward stabilization. When mappa stabilizes (a week -> without reports) — this skill is retired: reports become ordinary bug tasks. -> The owner of the retirement decision is workshop. - -## When to use - -Report when, during work with mappa, **any** of the following happens: - -- **5xx / 500 / 502** on any call (`task_*`, `wiki_*`, `inbox_*`, `entity_*`, - `admin_*`, `graph_*`, HTTP routes). -- **"Entity not found" / 404** for an id/ref that **must** exist (you know you - created it; you see it in a fresh response; another letter/task references it). -- **Unexpected response shape** — fields don't match the documented ones, - empty `rows` where data was expected, a new/unexpected type in the response. -- **Timeouts / hangs** on a call. -- **Silent failure** — the call "succeeded" but had no effect (task not - created, letter not delivered, status unchanged). -- **Retry worked** — even if the repeated call succeeded: the instability - itself is a signal for stabilization (mark `retry: resolved`). -- **Wrong/unexpected entity status**, board vs reality desync. - -**Retries are allowed** (1–2 with a pause), but the report happens regardless -of the retry outcome: case 500 → report; case 500 → retry → ok → report with -`retry: resolved`. - -## When NOT to use - -- **Expected 404** — the entity genuinely does not exist and should not - (never created; deleted by design). Before reporting, check that the entity - was required to exist. -- **Documented known limitations** (e.g. "verify on prod is impossible by - design", "prod is stale until redeploy" — if documented and known to the - mappa team). -- **Deviations NOT from mappa** — VDS/docker (→ using-vds-ops), projects-meta - cache (documented staleness), model providers. Only mappa. -- **The same incident already reported** — don't duplicate (see Dedup). - -## Core pattern — the report - -Each call: `mcp__mappa__inbox_send` to **both** addresses (`mappa` and -`.workshop`, addresses from the address book -`~/projects/.wiki/concepts/projects-address-book.md`), `from` = your own -folder name. Letter format: - -``` -Subject: [mappa-issue] <symptom> @ <tool/endpoint> (<date>) - -Body: -- Expected: <what should have happened per workflow/docs> -- Actual: <error/status/response — message text or a short snippet> -- Call: <tool + key parameters / endpoint + project> -- Retry: <did the retry work, how many attempts> -- Recurrence: <first time / repeats — how many times this session> -- Context: <project, session, which flow was running> -``` - -One letter = **one incident** (symptom × endpoint). Recurrence goes in the same -letter (`recurrence: 5 times in 2 hours`), not a new report per call. - -## Common mistakes / rationalizations - -| Rationalization | Reality | -|---|---| -| "Mappa is down — the letter won't arrive, why write" | A letter is an entity in Mappa (carve-out, no lease). When the service revives, it will be in the recipient's inbox. Always write. | -| "I'll tell the human in chat" | The human is not always in session; the mappa team doesn't see chat. A letter is durable and cross-session. | -| "I'll write it in the local log" | The local log is invisible to the mappa team. The goal of the report is visibility for recipients. (Local recording is extra, not instead.) | -| "The retry worked — so it's fine" | The instability itself is a signal. Report with `retry: resolved`. | -| "It's a small thing, I won't spam" | While mappa is unstable — any signal is material for stabilization. Dedup protects against spam, silence does not. | -| "I'll collect several and report at once" | First occurrence — immediately. Recurrence gets appended to the same letter. | -| "Mappa surely already knows this" | Unknown until reported. The report is exactly how it becomes known. | - -## Red flags — STOP - -- Caught a mappa error and silently continued (no report). -- Recorded only locally / said only in chat — no letter. -- Skipped "entity not found" without checking whether the id must exist. -- Postponed the report "for later" without a letter and without a task. -- Reported but not to both addresses (`mappa` and `.workshop`). - -## Cross-agent - -Channel — mappa inbox (`inbox_send` / `inbox.monitor`), shared by all agents -(pi: `mcp__mappa__inbox_send`; Claude Code: the same MCP tools; headless — the -same). Addressing strictly from the address book (`inter-session-messaging` -canon). - -## Out of scope - -- **Does not fix mappa** — service diagnosis/repair is separate; this skill - only reports. (Deep diagnosis — `diagnosing-bugs` / `using-vds-ops` for - infra.) -- **Does not report other services** — only deviations from the mappa workflow. -- **Does not replace** `inter-session-messaging` (the send mechanics live - there; this skill defines the policy "what counts as an incident").