Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude/skills/board/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Read-only. `BIN=scripts/pipeline` (relative to the engine root, every session's
Nothing runs before a refusal except `mp-task scope`, `mp-task project` and
`project list`.
1. `$BIN/mp-task board <P>` (with `all` when typed) — JSON lines with `key`,
`status`, `title`, `dir`, `worktreePath`. The project's `checkoutPath` and
`status`, `title`, `parent`, `dir`, `worktreePath`. The project's `checkoutPath` and
`home` come from the `mp-task project <P>` output of step 0.
2. For each row, the files in `dir`, only those that exist: `derive.json` (plan
URL), `pr.md` (PR), `progress.md` (stage). For each task with a `derive.json`
Expand All @@ -40,7 +40,7 @@ Read-only. `BIN=scripts/pipeline` (relative to the engine root, every session's
`checkoutPath` is not `null`, the entry of `git -C <checkoutPath> worktree list`
whose path equals `<checkoutPath>--<basename dir>`; otherwise —. Run
`git worktree list` once per project.
4. Print one table: key, title, status, plan (URL or —), open threads, PR,
4. Print one table: key, title, parent (key or —), status, plan (URL or —), open threads, PR,
worktree, next. The next column, for any project: `/plan` for `new`; `/do` for
`planning` with no open threads; `/plan` again when threads are open;
«ручная проверка → /ship» for `review`; — for `merged`/`done`; the reason for
Expand Down
3 changes: 2 additions & 1 deletion .claude/skills/do/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ teammate.

`$BIN/mp-task scope`, then apply the «Session scope» rule of `docs/PIPELINE.md` to
`/do <KEY>`: `global` — any key; `P` — continue only when the key has the code `P`;
`P-N` — continue only for `/do P-N`; anything else (an argument that is not a key, a
`P-N` — continue only when the key is `P-N` or its subtask by
`$BIN/mp-task subtasks P-N`; anything else (an argument that is not a key, a
malformed session key, a non-zero exit) — print the refusal text from
`docs/PIPELINE.md` and stop. This step runs before «Preconditions»: no
`$BIN/mp-task show`, no `catch_up`, no `mp-worktree` before it.
Expand Down
41 changes: 29 additions & 12 deletions .claude/skills/flow/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ reads.
`$BIN/mp-task scope`, then apply the «Session scope» rule of `docs/PIPELINE.md` to
`/flow`: `global` — continue when every key has the same code (keys of several
projects get the «mixes projects» text); `P` — continue when every key has the code
`P`; `P-N` — refused; an argument that is not a key (other than the run name), a
malformed session key or a non-zero exit — refused. A refusal prints its text from
`P`; `P-N` — continue when every key is `P-N` or its subtask by
`$BIN/mp-task subtasks P-N`; an argument that is not a key (other than the run
name), a malformed session key or a non-zero exit — refused. A refusal prints its text from
`docs/PIPELINE.md` and stops. This step runs before «Preconditions», before
`git fetch`, before the flow branch is created or pushed and before the flow score
is written. The nested plan and do runs go in this same session and pass their
own Step 0 with the same key.
own Step 0 with the same key; the subtasks of `P-N` pass it by the same rule.

## Preconditions

Expand All @@ -41,14 +42,29 @@ own Step 0 with the same key.
- `$BIN/mp-task flow <first KEY>` gives the project's `integration` and `prTarget`;
a non-zero exit → print its error and stop before any write.

## Subtasks

Before the flow score is written, run `$BIN/mp-task subtasks <KEY>` for every typed
key. The run list: for each typed key, in the typed order, its descendants in the
order of the `subtasks` output, then the key itself; a repeated key is dropped and
its first occurrence stays. The status of each subtask decides by «Subtasks» of
`docs/PIPELINE.md`: skipped, taken like a typed key, or one question — header
`Подзадача`, options «Пропустить (рекомендую)» and «Включить», the reason from
`$BIN/mp-task show <KEY>` in the question text. An included subtask gets
`$BIN/mp-task status <KEY> planning "в потоке <name>: включена инженером"`.

## Order

Before any write, compute the order of the keys: first the dependencies from the
«Связи» section of each `source.md` (a key goes after the keys of this run it
depends on); then the files each card names — tasks touching the same files go
one after another, the one the others build on first; otherwise the order typed.
Announce it in the chat: the keys in order, one line of reasoning per key. Then go
on without waiting for a confirmation. A dependency outside the run that is not
Before any write, compute the order of the keys. The base is the run list
(subtasks before their parent). Then the dependencies from the «Связи» section of
each `source.md` (a key goes after the keys of this run it depends on): a stable
topological reordering that never puts a parent before its subtasks. Then the files
each card names — tasks touching the same files go one after another, the one the
others build on first — where those constraints allow it. A cycle between the tree
and «Связи» is a question to the engineer. Announce it in the chat: the keys in
order, a mark `подзадача <parent>` on each subtask, one line of reasoning per key,
then on a line of its own the skipped subtasks with their status. Then go on
without waiting for a confirmation. A dependency outside the run that is not
`review`, `merged` or `done` is a question to the engineer before the start
(wait for it, or go on and record it as `/do --force` does).

Expand All @@ -63,7 +79,8 @@ on without waiting for a confirmation. A dependency outside the run that is not
(`git -C <base clone> worktree add <path> flow/<name>` when missing). Merges
happen there; never in the base clone.
3. Flow score: `<project home>/flows/<name>.md` — the branch with its base SHA, the
worktree, the announced order with a checkbox per key, later the PR URL. Commit
worktree, the announced order expanded with subtasks with a checkbox per key,
the list of skipped subtasks, later the PR URL. Commit
with `$BIN/mp-home-commit <CODE> "<message>"` (it stages `flows` too).

## Reconnaissance up front
Expand Down Expand Up @@ -113,8 +130,8 @@ key is recorded in the flow score.
<KEY> merged"`. Then shut the key's teammate down (`SendMessage` «shut down»;
`TaskStop` if it does not answer).

Re-typing the same command resumes: keys already in `review` for this flow are
skipped.
Re-typing the same command resumes: it expands the subtasks again, and keys
already in `review` for this flow are skipped.

## Questions

Expand Down
4 changes: 2 additions & 2 deletions .claude/skills/plan/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ order typed.

`$BIN/mp-task scope`, then apply the «Session scope» rule of `docs/PIPELINE.md` to
`/plan` and every typed key: `global` — any key; `P` — continue only when every
typed key has the code `P`; `P-N` — continue only when every typed key equals
`P-N`; anything else (an argument that is not a key, a malformed session key, a
typed key has the code `P`; `P-N` — continue only when every typed key is `P-N`
or its subtask by `$BIN/mp-task subtasks P-N`; anything else (an argument that is not a key, a malformed session key, a
non-zero exit) — print the refusal text from `docs/PIPELINE.md` and stop. This step
runs before the status check in «Input», before `$BIN/mp-task show` and before any
derive call or subagent, so `/plan MP-41` in a TBA chat stops on the scope, not on
Expand Down
5 changes: 4 additions & 1 deletion .claude/skills/ship/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ one entered. `BIN=scripts/pipeline` (relative to the engine root, every session'
`$BIN/mp-task scope`, then apply the «Session scope» rule of `docs/PIPELINE.md` to
`/ship` and every typed argument: `global` — any keys and `flow/<name>`; `P` —
keys with the code `P` and a flow of project `P`; `P-N` — continue only when every
typed argument equals `P-N` (`flow/<name>` in a task chat is refused); anything
typed key is `P-N` or its subtask by `$BIN/mp-task subtasks P-N`, and for
`flow/<name>` when every key of the checkboxes of the flow score
`<home of P>/flows/<name>.md` is `P-N` or its subtask (no file — the refusal text
from `docs/PIPELINE.md`); anything
else (an argument that is not a key, a malformed session key, a non-zero exit) —
print the refusal text from `docs/PIPELINE.md` and stop. This step runs before `pr.md` is read, before
`git fetch`, merge, push, `gh`, any status change and any worktree removal.
Expand Down
7 changes: 5 additions & 2 deletions .yoke/context.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@ The Session with the `global` Scope. Started from the engine root; administers a
The Session with a `project` Scope. Exactly one per Project. Works in the context of the whole Project, opens and manages its Task chats, receives their Events.

## Task chat
The Session with a `task` Scope. Bound to one Task; works only in that Task's context, in its own worktree. Manages nothing.
The Session with a `task` Scope. Bound to one Task; works only in that Task's context, in its own worktree. Manages nothing except the pipeline skills the engineer types in it, which may run its Task and its Subtasks (docs/PIPELINE.md «Session scope»).

## Task
The unit of work recorded in the database (formerly "request"). A Task belongs to a Project. A Task chat exists only for an existing Task.

## Parent task / Subtask
A Task may name one Parent task of the same Project (`parent`); Subtasks form a tree of any depth. Not the Parent of a Session: a Subtask's Task chat still has the Project chat as its Parent, and its Events and Milestones go there.

## Project / Organization
A registered Project belongs to one Organization. Organization is a grouping and a context source only; it has no Session of its own.

## Parent
The structural owner of a Session: Task chat → Project chat → Main chat. Parenthood never changes and does not depend on who opened the Session.
The structural owner of a Session: Task chat → Project chat → Main chat. Parenthood never changes and does not depend on who opened the Session. For Tasks see Parent task / Subtask.

## Event
A record created when a child Session's turn that a Parent message started stops, carrying the final message of that turn (`turn_end`), or stops mid-turn waiting for a human (`waiting`), and when a Task reaches a Milestone (`milestone`). Events flow only from a Task chat to its Project chat; the Main chat receives none. Parent messages are kept in the same table as kind `message` and go down, from a Parent to its child.
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ logging or Herdr tab is a prerequisite. Follow the user's requested scope and se
the older record moves to `<key>~<pid>.json`. A fork started by hand without
`MYPI_SCOPE` is not registered. `mypi sessions` (MCP `sessions`) shows the tree;
`mypi session forget <key>` drops a row on the user's request. Without
`XDG_RUNTIME_DIR` or an initialized schema 12 database registration fails and the
`XDG_RUNTIME_DIR` or an initialized schema 13 database registration fails and the
warmup still runs. /open (MCP open_session, CLI mypi open) focuses a live
session's Herdr tab or opens a new tab in its project's Herdr workspace (label
org/project, created when missing; a task gets its tab there without starting
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ order: the row for this native id, the live record of the same process,
the older record moves to `<key>~<pid>.json`. A fork started by hand without
`MYPI_SCOPE` is not registered. `mypi sessions` (MCP `sessions`) shows the tree;
`mypi session forget <key>` drops a row on the user's request. Without
`XDG_RUNTIME_DIR` or an initialized schema 12 database registration fails and the
`XDG_RUNTIME_DIR` or an initialized schema 13 database registration fails and the
warmup still runs.

`/open <key...>` (the Claude skill `/open`, the Pi command `/open`, CLI
Expand Down Expand Up @@ -273,6 +273,9 @@ command that opens the database, including warmup, asks for it.
Upgrading to schema 12: run `mypi db init` once after updating (back up the
database first).

Upgrading to schema 13: run `mypi db init` once after updating (back up the
database first).

### Updating without overwriting customizations

The installed engine is not a development checkout; contribute through the
Expand Down
2 changes: 1 addition & 1 deletion docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ organizations(id, slug)
projects(id, org_id, slug, code, checkout_path)
task_statuses(id, code, is_terminal)
tasks(id, project_id, number, title, status_id,
context_dir, worktree_path, created_at, updated_at)
context_dir, worktree_path, parent_id, created_at, updated_at)
sessions(key, scope_type, project_id, task_id, agent, native_id, created_at)
events(id, from_key, to_key, kind, message, created_at, delivered_at)
```
Expand Down
19 changes: 11 additions & 8 deletions docs/HTTP-API.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ A task key is `CODE-N` (`MP-12`), a project code is `CODE` (`MP`).
| `GET /v1/tasks?project&status&q&cursor&limit` | read | `task_page` | `{ items: task[], next }` |
| `GET /v1/tasks/{KEY}` | read | `task_show` | `task` |
| `POST /v1/tasks` | write | `task_create` | `task`, status 201 |
| `PATCH /v1/tasks/{KEY}` | write | `task_status`, `task_title`, `task_progress`, `task_touch`, then `task_show` | `task` |
| `PATCH /v1/tasks/{KEY}` | write | `task_status`, `task_title`, `task_parent`, `task_progress`, `task_touch`, then `task_show` | `task` |
| `GET /v1/events?to&from&kind&delivered&q&cursor&limit` | read | `event_list` | `{ items: event[], next }` |
| `GET /v1/journal?scope&from&to&type&q&cursor&limit` | read | `journal_page` | `{ items: journal[], next }` |
| `POST /v1/journal` | write | `journal_add` | `{ id }`, status 201 |
Expand Down Expand Up @@ -125,11 +125,13 @@ Bodies are JSON objects; every field is a string unless noted, unknown fields ar
refused:

- `POST /v1/tasks`: `project`, `title`, `status`, `slug`, `source` (the exact source
text). No file sources, no `adoptSource`.
- `PATCH /v1/tasks/{KEY}`: `status`, `title`, `reason`, `progress`, `touch` (only
`true`). At least one of status, title, progress, touch; `reason` is required with
status or title and refused without them; `touch` only alone. Parts apply in the
order status, title, progress, touch; progress carries no artifacts.
text), optional `parent` (the key of a parent task of the same project). No file
sources, no `adoptSource`.
- `PATCH /v1/tasks/{KEY}`: `status`, `title`, `parent` (a task key or `null` to
clear), `reason`, `progress`, `touch` (only `true`). At least one of status, title,
parent, progress, touch; `reason` is required with status, title or parent and
refused without them; `touch` only alone. Parts apply in the order status, title,
parent, progress, touch; progress carries no artifacts.
- `POST /v1/journal`: `scope`, `text` (a note). `scope` takes the same references
as the journal query (`global`, an org slug, `org/project`, `project:FX`,
`task:FX-1`).
Expand All @@ -139,7 +141,8 @@ Response shapes:

- `project`: `{ code, org, slug, identity, repository, checkoutPath }`
- `flow`: `{ project, code, source, integration, taskBranch, prTarget, mergeMethod, release }`
- `task`: `{ key, project, number, title, status, isTerminal, contextDir, worktreePath, createdAt, updatedAt }`
- `task`: `{ key, project, number, title, parent, status, isTerminal, contextDir, worktreePath, createdAt, updatedAt }`
(`parent` is the key of the parent task or `null`)
- `event`: `{ id, from, to, kind, text, createdAt, deliveredAt }`
- `journal`: `{ id, at, scope: { type, key? }, type, text, artifacts: [{ path, commit }] }`
(`commit` is `null` for historical path-only artifacts)
Expand Down Expand Up @@ -184,7 +187,7 @@ field or route needs `/v2`.

## Engine updates and migrations

The server opens a database of schema 12 and keeps its code in memory. After an
The server opens a database of schema 13 and keeps its code in memory. After an
engine update or a migration, restart it.

## Access log
Expand Down
7 changes: 5 additions & 2 deletions docs/M1-CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ and projects without a clone exit 1 with a JSON error. Over 64 KiB the oldest fa
the farthest memory zone are hidden with a marker naming the MCP `memory` show call and,
in parentheses, `memory show -s …`. `--max-chars n` (1–21845) applies the same cut at n characters instead; the Claude Code hook uses 9500. `journal read` global remains global-only.
Task cards from task show and task list include worktreePath (null until a worktree is
recorded).
recorded) and parent (the key of the parent task, or null).
`project resolve` returns `{match:"project",identity,code,scope}` or `{match:"none"}`
or `{match:"ambiguous",projects}` using the registered checkout resolver; sibling
worktrees are not inferred.
Expand All @@ -78,11 +78,14 @@ the remaining folder or null.

```text
task create --project org/project --title "Title" --status research --slug short-slug --file /path/to/source
task create --project org/project --title "Subtask" --status new --slug subtask --parent MP-1 --file /path/to/source
task list [--project org/project] [--status code]
task show MP-1
task worktree MP-1
task status MP-1 review --reason "ready for review"
task title MP-1 "Better title" --reason "clarification"
task parent MP-2 MP-1 --reason "part of the epic"
task parent MP-2 none --reason "split out"
task progress MP-1 "actual outcome" [--artifacts /path/to/artifacts.json]
status list
status add accepted --terminal
Expand All @@ -96,7 +99,7 @@ journal read --all --type status_changed
```

These are independent syntax examples, not a mandatory sequence. `task status` to `review`, `blocked`, `merged` or a terminal status also queues a `milestone` event for the project chat (inbox, warmup), unless the caller is the project chat itself (its registered key, else `MYPI_SCOPE`, as for `warmup`); milestones are never sent live. Tasks belong to a
registered project; existing standalone REQ records remain readable.
registered project; existing standalone REQ records remain readable. A parent task is a task of the same project, never the task itself and never one of its own subtasks (no cycles); `task parent` writes a `note` `Parent: <old|none> → <new|none>. <reason>` to the task's journal.

`project flow MP` (or `org/project`) prints the project's branch flow from
`home/projects/<org>/<project>/flow.json`:
Expand Down
Loading
Loading