From f1a21f8d14fda722b5da30712325a31e2f7fd32c Mon Sep 17 00:00:00 2001 From: Louis Choquel Date: Sat, 26 Sep 2026 19:35:58 +0200 Subject: [PATCH 1/2] Design and run point at the method graph page pipelex-design now gives the path of the flowchart page the workshop writes beside a bundle validated by path when it hands over a finished method, replacing a host-rendered graph the view-less workshop never gave, and pipelex-run gives it on a dry run. The sentence explain already carried moves into one include the three skills share. Both skills sat at the size ceiling, so the reason for the runs/ exclusion leaves the shared submission partial (docs/decisions.md records it) and a few sentences are tightened; no guard moved. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 2 +- CLAUDE.md | 3 ++- docs/build-targets.md | 1 + docs/decisions.md | 5 +++-- docs/skills.md | 6 +++--- pipelex-codex/skills/pipelex-catalog/SKILL.md | 2 +- pipelex-codex/skills/pipelex-design/SKILL.md | 6 +++--- pipelex-codex/skills/pipelex-edit/SKILL.md | 2 +- pipelex-codex/skills/pipelex-explain/SKILL.md | 4 ++-- pipelex-codex/skills/pipelex-inputs/SKILL.md | 2 +- pipelex-codex/skills/pipelex-organize/SKILL.md | 2 +- pipelex-codex/skills/pipelex-run/SKILL.md | 10 +++++----- pipelex-vibe/skills/pipelex-catalog/SKILL.md | 2 +- pipelex-vibe/skills/pipelex-design/SKILL.md | 6 +++--- pipelex-vibe/skills/pipelex-edit/SKILL.md | 2 +- pipelex-vibe/skills/pipelex-explain/SKILL.md | 4 ++-- pipelex-vibe/skills/pipelex-inputs/SKILL.md | 2 +- pipelex-vibe/skills/pipelex-organize/SKILL.md | 2 +- pipelex-vibe/skills/pipelex-run/SKILL.md | 10 +++++----- pipelex/skills/pipelex-catalog/SKILL.md | 2 +- pipelex/skills/pipelex-design/SKILL.md | 6 +++--- pipelex/skills/pipelex-edit/SKILL.md | 2 +- pipelex/skills/pipelex-explain/SKILL.md | 4 ++-- pipelex/skills/pipelex-inputs/SKILL.md | 2 +- pipelex/skills/pipelex-organize/SKILL.md | 2 +- pipelex/skills/pipelex-run/SKILL.md | 10 +++++----- templates/skills/pipelex-design/SKILL.md.j2 | 4 ++-- templates/skills/pipelex-explain/SKILL.md.j2 | 2 +- templates/skills/pipelex-run/SKILL.md.j2 | 10 +++++----- templates/skills/shared/graph-page.md.j2 | 16 ++++++++++++++++ templates/skills/shared/validate-call.md.j2 | 6 ++++-- tests/unit/test_gen_skill_docs.py | 14 ++++++++++++++ tests/unit/test_pipelex_design_skill.py | 10 ++++++++++ tests/unit/test_pipelex_run_skill.py | 12 ++++++++++++ tests/unit/test_skill_guards.py | 2 ++ 35 files changed, 118 insertions(+), 59 deletions(-) create mode 100644 templates/skills/shared/graph-page.md.j2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 382c5f23..e0537232 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ ### Changed -- **`pipelex-explain` points at the method graph page**: the Pipelex tools are about to write a method's flowchart, `method-graph.html`, beside the files a validation reads by path, and `pipelex-explain` now gives that page's path before its text flow, so the whole method can be opened in a browser. The skill still writes nothing of its own, and the page is the one file an explanation of a bundle on disk leaves. `pipelex-catalog`'s check of whether a bundle would save asks the tools not to write the page, since that check is a question and writes no file. +- **`pipelex-explain`, `pipelex-design` and `pipelex-run` point at the method graph page**: the Pipelex tools are about to write a method's flowchart, `method-graph.html`, beside the files a validation reads by path, and these skills now give that page's path before their text flow — `pipelex-explain` in every explanation of a bundle on disk, `pipelex-design` when it hands over a method, and `pipelex-run` on a dry run — so the whole method can be opened in a browser. `pipelex-explain` still writes nothing of its own, and the page is the one file it leaves. `pipelex-catalog`'s check of whether a bundle would save asks the tools not to write the page, since that check is a question and writes no file. ### Fixed diff --git a/CLAUDE.md b/CLAUDE.md index ef1dfbb7..7a1b3631 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -55,7 +55,8 @@ templates/ # SOURCE OF TRUTH — all .j2 templates live here │ ├── saved-copy-notice.md.j2 # The linked saved method does not have this change; `/pipelex-catalog` compares the two and updates it (include-only) │ ├── catalog-id-pointer.md.j2 # The pointer design, edit and organize place at a catalog id, with the bridge's two guards (include-only) │ ├── catalog-id-bridge.md.j2 # How a file-based skill reaches a catalog id: the linked directory, or the pull (include-only; included by shared/catalog-id.md alone) -│ └── pipefunc-warning.md.j2 # PipeFunc is experimental on the hosted plane (include-only) +│ ├── pipefunc-warning.md.j2 # PipeFunc is experimental on the hosted plane (include-only) +│ └── graph-page.md.j2 # The method graph page's path, before the text flow: explain, design's delivery and run's dry run (include-only) ├── hooks/ │ ├── hooks.json.j2 # Claude PostToolUse hook config │ ├── codex-hooks.json.j2 # Codex PostToolUse hook config (plugin-bundled) diff --git a/docs/build-targets.md b/docs/build-targets.md index c45d99a2..6c499f54 100644 --- a/docs/build-targets.md +++ b/docs/build-targets.md @@ -284,6 +284,7 @@ So the bump procedure is: edit `[vars.floors]`, run `make build`, run `make chec | `catalog-id-pointer.md.j2` | the pointer a file-based skill places where it meets a catalog id or a published address, sending the model to `shared/catalog-id.md` before any file is read, with the bridge's two guards beside it — for design, edit and organize | none | | `catalog-id-bridge.md.j2` | how a file-based skill reaches a catalog id: the search over the link files, the several-hits question, the pull, and the refusal of a published address. Included by the rendered shared reference `catalog-id.md.j2` alone, which `pipelex-design`, `pipelex-edit` and `pipelex-organize` point at | `catalog_id_bridge_resume` (the step the skill resumes at, interpolated mid-sentence; the shared reference sets `the skill that sent you here, just after its pointer to this file`) | | `pipefunc-warning.md.j2` | that `PipeFunc` is experimental on the hosted plane and runs its Python in a network-blocked sandbox | none | +| `graph-page.md.j2` | the path of the method graph page `mthds_validate` writes beside a bundle validated by path, given before the text flow, with the page's first-write note and its error in one line — for explain, design's delivery and run's dry run, the three places a skill presents a method's flow | none | | `project-root.md.j2` | where a project starts — the nearest directory holding one of the project markers — for design, integrate and catalog | none | | `git-ignore.md.j2` | how a path that holds the user's data is kept out of version control before it is written: `git check-ignore -q`, an entry in the nearest `.gitignore` relative to that file's directory, the check again, and the guard that a path git still does not ignore, which a tracked one never is, waits for the user. Included after each skill's own bold subject, by `pipelex-inputs` for the copies of the user's files, `pipelex-lab` for a case of them and `pipelex-run` for the `runs/` folder a save writes into | `git_ignore_paths` (what is checked and when, following `git check-ignore -q`), `git_ignore_entry` (the entry written); neither has a default | | `skill-dir.md.j2` | on Codex and Vibe, the sentence defining the `` placeholder as the directory of the `SKILL.md` the harness loaded; nothing on Claude, where `${CLAUDE_SKILL_DIR}` is substituted. Included just before the first sentence that uses `{{ skill_dir }}` | none | diff --git a/docs/decisions.md b/docs/decisions.md index 869d4468..5ab6d32b 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -682,7 +682,7 @@ Until the console's own release, the hosted console and the local workshop regis - **What the skills said of the console is corrected.** The shared submission include no longer calls the inline form "the only form the hosted console accepts", since the console takes no files at all, and `pipelex-explain`'s not-on-disk reference names one cause of an absent `mthds_get_method` where it named two: a workshop older than the release that brought it. The connection reference a skill reads when its tools are absent now tells the user that the plugin's MCP server is the one not connected, which a user who can see a connected Pipelex connector would otherwise doubt, and both references say that the connector's `pipelex_*` tools do not stand in for the workshop's. - **The README's quick-start paragraph is not changed here.** It lives in the onboarding region, which is generated from the workspace's onboarding source (the Claude Code sync block) and is replaced from there, so it moves when that block does. -## The workshop's method graph page: `pipelex-explain` shows it, the catalog's check turns it off (2026-09-26) +## The workshop's method graph page: the skills that present a flow show it, the catalog's check turns it off (2026-09-26) `pipelex-mcp` made `mthds_validate` write the method's flowchart as a standalone page, `method-graph.html`, beside the files whenever every file is given as `{ path }`, whatever the verdict, and rewrite it on each validation; a caller turns it off with `graph_page: false` (`pipelex-mcp/SPEC.md`, "The method graph page"). The default is the workshop's to keep, because it is what gives a builder in a host with no views the graph at all, so a skill that must not leave a file behind is the one that opts out. @@ -690,7 +690,8 @@ Until the console's own release, the hosted console and the local workshop regis - **`pipelex-catalog`'s check of whether a bundle would save passes `graph_page: false`.** The skill writes no file itself and names the two the workshop writes for it, the pulled sources and the link; a page written by a question would have been a third. `mthds_save_method`'s own validation writes no page, so a save needs nothing. - **"Wherever the tool lists that argument."** A workshop older than the page lists no `graph_page` and writes no page. `@pipelex/mcp` 0.20.0, the release before the page, ignored the argument when it was sent from Claude Code on 2026-09-26 and answered the verdict as usual, but Codex and Mistral Vibe were not tried, and a host may hold the model to the advertised schema; so the check names the argument only where the tool offers it rather than sending it blind. - **`pipelex-organize` is left as it is.** Its baseline validation writes the page before the layout changes, and its confirmation after the swap rewrites it from the new layout, so the page it leaves matches the files. Its promises are about the bundle's `.mthds` files, which the page is not, and it deletes only `.mthds` files. Where the confirmation fails and the original layout is restored, the page shows the rejected candidate until the next validation rewrites it; that is not worth another validation call. -- **The writing skills keep the page.** `pipelex-design`, `pipelex-edit`, `pipelex-inputs`, `pipelex-run` and `pipelex-integrate` validate by path and let the workshop write it. Pointing the user at it from those skills is a change of its own. +- **`pipelex-design` and `pipelex-run` show the page where they present the flow**, ruled by Louis on 2026-09-26, the same day as explain. Design gives it at delivery, replacing "the interactive method graph where the host rendered it", which the plugin's workshop, having no views, never gave. Run gives it on a dry run alone: a real run's reply is the run, and a user who wants the flow asks for a dry run or for `pipelex-explain`. The three skills say it in one sentence, the include `templates/skills/shared/graph-page.md.j2`, which speaks of "a summary" calling the page new because design's page is new at the construction loop's first validation, long before delivery. Both skills sat at the size ceiling, so the room came from wording: the reason `runs/` is excluded left the shared submission partial, since the artifacts bullet above records it, run's opening stopped restating where a dry run lives, and a few sentences were tightened; no guard moved. The skills name a path that opens in a browser and assume no host preview, so whether Codex's HTML preview runs the page's CDN scripts was not checked, and nothing depends on it. +- **The other skills that validate by path leave the page without a word.** `pipelex-edit`, `pipelex-inputs`, `pipelex-integrate`, `pipelex-organize` and a real run let the workshop write it and present no flow. `TestSharedSkillIncludes` pins which skills include the sentence, so a skill that starts or stops naming the page changes this ruling on purpose. ## A local workshop is one make target, and touches no tracked file (2026-09-26) diff --git a/docs/skills.md b/docs/skills.md index e5e369ca..83f447d0 100644 --- a/docs/skills.md +++ b/docs/skills.md @@ -4,7 +4,7 @@ What each skill of the Pipelex plugin does, what it needs, and the tools it call ## Build a method -**`pipelex-design`** designs a method contract-first and writes it as `.mthds` files. A method whose whole graph is understood and shallow is written directly as a coherent, runnable bundle; deep, uncertain, staged or resumable work goes through signature-driven refinement, validated at each step. A structural or contract change to an existing method, such as a new step or a new input, comes back here too, and the skill re-enters the affected region directly or through signatures according to its complexity. +**`pipelex-design`** designs a method contract-first and writes it as `.mthds` files. A method whose whole graph is understood and shallow is written directly as a coherent, runnable bundle; deep, uncertain, staged or resumable work goes through signature-driven refinement, validated at each step. A structural or contract change to an existing method, such as a new step or a new input, comes back here too, and the skill re-enters the affected region directly or through signatures according to its complexity. When the method is ready, the skill presents its flow, giving first the path of the flowchart page the Pipelex tools write beside the bundle. **`pipelex-edit`** makes the edits that keep a method's contract: a prompt, a model reference, a mechanical rename. It proves each one with a validation before and after, and sends a structural or contract change to `/pipelex-design`. @@ -22,7 +22,7 @@ Those three work on files, and each also takes a saved method's catalog id (`mt_ ## Run and save -**`pipelex-run`** runs a method and follows a run, and does nothing else. It starts a run from a bundle directory, a catalog id or a published method's address, with inputs that are already run-ready, and prints the run id the moment the run starts. A pipe other than the main one is named by its qualified reference, its code prefixed by the domain of the file that defines it, as `domain.pipe_code`. Every completed run is saved into `runs//`, under the directory the agent was started in: its whole output as `main_stuff.json`, beside each file it produced, named after the field it fills. That output carries what the run read in your files, so in a git repository the skill makes sure `runs/` is ignored before it saves there, adding it to the nearest `.gitignore` when it is not and saying so; a path git still does not ignore waits for your say-so, and outside a repository nothing is done. It follows a run by its id alone, to its status, its results or a save of it, which works days later. A run of a directory linked to a saved method is filed under that method, so it appears in the method's history. A failure goes back to the skill that owns the repair. The skill never starts a run nobody asked for, and a dry run shows the method's flow and spends nothing. +**`pipelex-run`** runs a method and follows a run, and does nothing else. It starts a run from a bundle directory, a catalog id or a published method's address, with inputs that are already run-ready, and prints the run id the moment the run starts. A pipe other than the main one is named by its qualified reference, its code prefixed by the domain of the file that defines it, as `domain.pipe_code`. Every completed run is saved into `runs//`, under the directory the agent was started in: its whole output as `main_stuff.json`, beside each file it produced, named after the field it fills. That output carries what the run read in your files, so in a git repository the skill makes sure `runs/` is ignored before it saves there, adding it to the nearest `.gitignore` when it is not and saying so; a path git still does not ignore waits for your say-so, and outside a repository nothing is done. It follows a run by its id alone, to its status, its results or a save of it, which works days later. A run of a directory linked to a saved method is filed under that method, so it appears in the method's history. A failure goes back to the skill that owns the repair. The skill never starts a run nobody asked for, and a dry run shows the method's flow, with the path of its flowchart page when the tools wrote one, and spends nothing. **`pipelex-catalog`** carries a method between a bundle directory and your organization's Pipelex catalog: it lists what is saved, saves a directory as a new method or updates the one its `pipelex-method.json` link names, and pulls a saved method's files back to disk. A save validates and stores the bundle in a single call. It sends the bundle's files by path, because the tools write the `pipelex-method.json` link only beside files they read from disk, and that link is what makes the next save an update rather than a second method; for a bundle outside the directory the agent was started in, which the tools cannot read by path, the skill says the link cannot be written and saves without it only if you say yes. On an update, that leaves the link behind the catalog, so the directory's next save is refused as a conflict with that save, which the skill recognises as its own; a pull into the same directory, once the tools can write there, brings the link up to date. Before an update, the skill says that the update reaches every caller of that id. It refuses to overwrite a change it has not seen, and it never deletes. @@ -44,7 +44,7 @@ The skills share one reference for MTHDS, the language a method is written in: ` ## The Pipelex tools -The tools reach the Pipelex API with your key, the same one the hook uses. Each tool that takes a method takes the files themselves, a saved method's catalog id as `method_id`, or a published method's address as `method_ref`; a call by id needs an API key, because the catalog belongs to an organization. The tools read a file by path only inside the directory the agent was started in, an absolute path included; for a bundle outside it, start the agent from a directory that holds the bundle, or the skills send the files' contents instead. A version of the tools that draws the method graph also writes the method's flowchart, `method-graph.html`, beside files it validates by path, and rewrites it on each validation; `pipelex-explain` tells you where the page is, and `pipelex-catalog`'s check of whether a bundle would save turns it off, since a question writes no file. +The tools reach the Pipelex API with your key, the same one the hook uses. Each tool that takes a method takes the files themselves, a saved method's catalog id as `method_id`, or a published method's address as `method_ref`; a call by id needs an API key, because the catalog belongs to an organization. The tools read a file by path only inside the directory the agent was started in, an absolute path included; for a bundle outside it, start the agent from a directory that holds the bundle, or the skills send the files' contents instead. A version of the tools that draws the method graph also writes the method's flowchart, `method-graph.html`, beside files it validates by path, and rewrites it on each validation; `pipelex-explain`, `pipelex-design` when it hands over a method and `pipelex-run` on a dry run tell you where the page is, the other skills leave it without a word, and `pipelex-catalog`'s check of whether a bundle would save turns it off, since a question writes no file. - **`mthds_validate`** validates a method. Its verdict carries the main pipe's signature, from which `/pipelex-integrate` types a call site. - **`mthds_inputs_template`** returns the input template of a pipe. diff --git a/pipelex-codex/skills/pipelex-catalog/SKILL.md b/pipelex-codex/skills/pipelex-catalog/SKILL.md index bea6dfac..5a2d307b 100644 --- a/pipelex-codex/skills/pipelex-catalog/SKILL.md +++ b/pipelex-codex/skills/pipelex-catalog/SKILL.md @@ -28,7 +28,7 @@ Every gesture between a bundle directory and the organization's method catalog: The target is a bundle directory. -1. **Gather the bundle's files** as the convention below says, and submit them as `files` with the **root file first** — the one carrying the bundle's `domain` header, usually `main.mthds` — because the platform derives the method's listed description from the first file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` gets no link file: a method created that way stays unlinked, so the next save from here makes a second one, and a method updated that way keeps the link's old sync time, so the next save from here is refused as a conflict with this session's own save. So **a save takes the path form**. When the workshop refuses a path, say that this session cannot write the link and which of the two that costs, and save inline only on the user's yes. +1. **Gather the bundle's files** as the convention below says, and submit them as `files` with the **root file first** — the one carrying the bundle's `domain` header, usually `main.mthds` — because the platform derives the method's listed description from the first file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` gets no link file: a method created that way stays unlinked, so the next save from here makes a second one, and a method updated that way keeps the link's old sync time, so the next save from here is refused as a conflict with this session's own save. So **a save takes the path form**. When the workshop refuses a path, say that this session cannot write the link and which of the two that costs, and save inline only on the user's yes. 2. **Decide the arm from `pipelex-method.json` beside the root file.** When it is there, this is an **update**: pass its `method_id`, pass its `synced_updated_at` as `expected_updated_at`, and keep the `name` it records unless the user is renaming. When it is not, this is a **creation**: ask the user for the name, proposing the bundle's `description` in a few words or its `domain` in plain words (`summarize_pdf` → *Summarize PDF*). `name` is required on both arms, since the save rewrites the whole catalog row. Never pass `link_dir`: omitted, the link goes beside the root file. 3. **Decide `python`.** It replaces the stored Python as a set: omitting it preserves the stored set, sending files replaces them all, and sending `[]` clears them. **A bundle with no `PipeFunc` sends no `python` at all**, and `[]` goes only when the user has asked for the stored Python to be cleared. With a `PipeFunc`, read [python.md](references/python.md) before choosing any file: **which `.py` files are the method's is this skill's judgement, not the tool's**, and a file sent by mistake is uploaded to the catalog, where nothing validates it. When it is unclear, ask; do not sweep the directory. 4. **Say what is about to happen, in one line**, then call `mthds_save_method`; there is no second confirmation, since the user's request is the consent. A create says what is made: *Creating a new method **Summarize PDF** on Pipelex from `methods/summarize_pdf/`.* An update says what an update is, in a line that is never optional: diff --git a/pipelex-codex/skills/pipelex-design/SKILL.md b/pipelex-codex/skills/pipelex-design/SKILL.md index fe4ed992..95320614 100644 --- a/pipelex-codex/skills/pipelex-design/SKILL.md +++ b/pipelex-codex/skills/pipelex-design/SKILL.md @@ -27,7 +27,7 @@ Read [writing-mthds.md](../shared/writing-mthds.md) **before writing**: it is th Fix the **input concept(s)**, the **output concept** and the **description**, precise enough to implement against, and specify every boundary concept fully now. Shape each concept from all its known consumers: it must be structured if any consumer field-reads it (`$x.field`, a construct `from = "x.field"`), and can stay simple otherwise. Declare each concept exactly once, complete, owned by the root boundary or by the controller that introduces it. -**Announce the captured contract in one line** (inputs → output, one-sentence semantics), with the bundle home resolved below in the same line, before writing, so the user can interject without blocking progress. **If the design will emit a `PipeFunc`, say so in that same line**, warning rather than refusing: **`PipeFunc` is experimental on the hosted plane.** Its Python runs in a sandbox with no network access, and the feature is still in development, so a method that validates can still fail when it runs. Discuss only genuine ambiguity, or when the user asks to collaborate. +**Announce the captured contract in one line** (inputs → output, one-sentence semantics), with the bundle home resolved below in the same line, before writing, without waiting for a reply. **If the design will emit a `PipeFunc`, say so in that same line**, warning rather than refusing: **`PipeFunc` is experimental on the hosted plane.** Its Python runs in a sandbox with no network access, and the feature is still in development, so a method that validates can still fail when it runs. Discuss only genuine ambiguity, or when the user asks to collaborate. ### 2. Resolve the bundle home before writing @@ -48,7 +48,7 @@ Design the whole graph in memory, then write `main.mthds` in the bundle home, to ### 5. Validate -Gather the bundle's files as the convention below says, the whole library, and call `mthds_validate` with `files` for every file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. +Gather the bundle's files as the convention below says, the whole library, and call `mthds_validate` with `files` for every file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. Branch on the **structured verdict** from its Markdown summary, never on transport: `is_valid: true` is complete with `is_runnable: true` and nothing pending, and otherwise a scaffold whose backlog is the summary's `## Pending signatures`; on `is_valid: false`, fix from `validation_errors[]` and the summary's locators, which name the offending file, then re-validate. @@ -58,7 +58,7 @@ For a completed method, re-gather the whole bundle and confirm **`is_valid: true 1. **Organize only when the layout needs it.** A converged stepwise construction or signature-driven re-entry normally invokes `/pipelex-organize`; a result already coherent in either mode skips it. 2. **Project the input schema**: `mthds_inputs_template` with the final whole-bundle `files` and `explicit: false`; show the compact template. -3. **Present the flow**: the interactive method graph where the host rendered it, else a concise text flow. +3. **Present the flow** as concise text. **When the verdict carries `graph_page.written: true`, give the page's `path` before the text flow**: it opens in a browser and draws the whole method. When a summary called the page new, pass on its note that a project under git may want to ignore it. A `graph_page.error` gets one line, and the verdict stands. 4. **Warn again for a `PipeFunc`**, naming its pipes: **`PipeFunc` is experimental on the hosted plane.** Its Python runs in a sandbox with no network access, and the feature is still in development, so a method that validates can still fail when it runs. 5. **Hand off**: `/pipelex-inputs` prepares the user's files, or test files with planted facts, then `/pipelex-run` runs the method, and `/pipelex-lab` writes answer keys and scores the runs; `/pipelex-catalog` saves it under an `mt_…` id anything can call; `/pipelex-integrate` wires it into a codebase (a `package.json` or a `pyproject.toml`), and with none, `/pipelex-scaffold` creates an application around it if the user wants one. 6. Search the whole project for `sources.json` files carrying `"generator": "pipelex-integrate"` — `grep -rl '"pipelex-integrate"' --include=sources.json .` — which sit beside each generated tree (`src/generated//`, `/generated//`), never beside the bundle, so looking only next to the `.mthds` files finds nothing. Keep each one whose `sources` name a `.mthds` file this change rewrote, moved or removed, **or whose `bundle_dir` holds a `.mthds` file this change created** — a new file is in no `sources` map, yet the call site loads every `.mthds` file under that directory. For each, say the generated types in that directory are now stale and offer `/pipelex-integrate` to refresh them: it regenerates in place and touches the call site only if the types no longer fit it. diff --git a/pipelex-codex/skills/pipelex-edit/SKILL.md b/pipelex-codex/skills/pipelex-edit/SKILL.md index d7c7b22b..3f15e797 100644 --- a/pipelex-codex/skills/pipelex-edit/SKILL.md +++ b/pipelex-codex/skills/pipelex-edit/SKILL.md @@ -43,7 +43,7 @@ Check the requested change against the scope split at the top. Structural or con ### Step 3: Baseline verdict -Validate the whole bundle **before editing**: call `mthds_validate` with `files` for every file, and branch on the structured verdict, never on transport. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. +Validate the whole bundle **before editing**: call `mthds_validate` with `files` for every file, and branch on the structured verdict, never on transport. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. - `is_valid: true` → record whether it is runnable or a scaffold (non-empty `pending_signatures`). That same state must hold after your edits. - `is_valid: false` → the bundle is broken **before** your change: surface the `validation_errors[]` and the Markdown summary, and offer to repair first. **Never edit on a broken baseline.** diff --git a/pipelex-codex/skills/pipelex-explain/SKILL.md b/pipelex-codex/skills/pipelex-explain/SKILL.md index 8acbd7e7..82df81b1 100644 --- a/pipelex-codex/skills/pipelex-explain/SKILL.md +++ b/pipelex-codex/skills/pipelex-explain/SKILL.md @@ -36,7 +36,7 @@ A `PipeSignature` is **pending only when no concrete pipe of the same code exist ### 3. The verdict, when the workshop is there -One `mthds_validate` call over the same files. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. The call adds two things to the explanation: the **verdict line** (whether it is valid, whether it is runnable, what is still pending) and, when the verdict carries a `main_pipe`, the **main pipe's typed signature**: its namespaced ref, each declared input with its concept and whether it is required, and the concept it produces. On `{path}` files the workshop also writes the method's flowchart beside them as `method-graph.html`, rewritten on every validation, and reports it as `graph_page`. +One `mthds_validate` call over the same files. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. The call adds two things to the explanation: the **verdict line** (whether it is valid, whether it is runnable, what is still pending) and, when the verdict carries a `main_pipe`, the **main pipe's typed signature**: its namespaced ref, each declared input with its concept and whether it is required, and the concept it produces. On `{path}` files the workshop also writes the method's flowchart beside them as `method-graph.html`, rewritten on every validation, and reports it as `graph_page`. Without the tool, explain from the source and **say the verdict was not checked**. Your own reading of the source is not a guess: the pipe types, the concepts and step 2's backlog are yours to state, saying whose reading it is. But do not present a validation verdict, a typed signature or a pending list as the workshop's when the workshop did not answer, and do not guess at validity. **On a target that is not on disk there is no such fallback.** @@ -46,7 +46,7 @@ Say first whether it is **complete** or a **scaffold with a backlog**, from step ### 5. The flow: the root first, then one passage per module -**When the verdict carries `graph_page.written: true`, give the page's `path` before the text flow**: it opens in a browser and draws the whole method. When the summary says the page is new, pass on its note that a project under git may want to ignore it. A `graph_page.error` gets one line, and the verdict stands. +**When the verdict carries `graph_page.written: true`, give the page's `path` before the text flow**: it opens in a browser and draws the whole method. When a summary called the page new, pass on its note that a project under git may want to ignore it. A `graph_page.error` gets one line, and the verdict stands. **The root file gives the contract and the top-level flow**, then **one passage per module file**, each named by its file; a one-file method gets one passage, the simple case and not a missing structure. Trace the flow from the main pipe, reading the controllers in their own terms: diff --git a/pipelex-codex/skills/pipelex-inputs/SKILL.md b/pipelex-codex/skills/pipelex-inputs/SKILL.md index afb12fcf..00de3f74 100644 --- a/pipelex-codex/skills/pipelex-inputs/SKILL.md +++ b/pipelex-codex/skills/pipelex-inputs/SKILL.md @@ -31,7 +31,7 @@ The one entry point for a method's inputs — placeholders, synthetic data, the The target takes three forms, and every call takes exactly one selector. -- **A local bundle**, the usual case, as `files`: `` is its directory, usually the one holding `main.mthds`, unless the caller names another. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. +- **A local bundle**, the usual case, as `files`: `` is its directory, usually the one holding `main.mthds`, unless the caller names another. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. - **A registered method**, an `mt_…` id with no local bundle in play, as `method_id`: its current stored content, which needs the API key. `` is a directory the user names, by default a new `.//`. - **A published method**, as `method_ref: "github.com//[/][@]"`: read [references/published-address.md](references/published-address.md) before the first call. **An address with no tag is accepted, and it floats**: say so in one line, recommend the tag, and carry on. diff --git a/pipelex-codex/skills/pipelex-organize/SKILL.md b/pipelex-codex/skills/pipelex-organize/SKILL.md index cef50e8d..5dea995c 100644 --- a/pipelex-codex/skills/pipelex-organize/SKILL.md +++ b/pipelex-codex/skills/pipelex-organize/SKILL.md @@ -27,7 +27,7 @@ It is a **content-preserving transformation**: the method's semantics never chan **For a catalog id (`mt_…`) or a published address**, read [the catalog-id reference](../shared/catalog-id.md) before reading any file. **When several directories are linked to the method, ask which is the work; never choose.** **Never present a linked directory as the saved method's current content.** -Gather the bundle's files as the convention below says, read each, and call `mthds_validate` with `files` for every file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. Record the **baseline**: `is_valid`, `is_runnable`, and the exact `pending_signatures` set. `is_valid: true` proceeds, runnable or scaffold. +Gather the bundle's files as the convention below says, read each, and call `mthds_validate` with `files` for every file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. Record the **baseline**: `is_valid`, `is_runnable`, and the exact `pending_signatures` set. `is_valid: true` proceeds, runnable or scaffold. ### Step 2 — Plan the layout, compose the files diff --git a/pipelex-codex/skills/pipelex-run/SKILL.md b/pipelex-codex/skills/pipelex-run/SKILL.md index 5d0bd295..edfcc0a4 100644 --- a/pipelex-codex/skills/pipelex-run/SKILL.md +++ b/pipelex-codex/skills/pipelex-run/SKILL.md @@ -5,7 +5,7 @@ description: Run an MTHDS method on the hosted Pipelex API, and follow a run tha # Run an MTHDS method -This skill owns the run lifecycle, and only that, through two entries and no third: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which stays good long after the session that started it. A dry run is not a third entry: it is Start a run's step 3, shown to the user as a numbered flow. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). +This skill owns the run lifecycle through two entries: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which stays good long after the session that started it; a dry run is Start a run's step 3, shown. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). ## Requirements @@ -18,7 +18,7 @@ This skill owns the run lifecycle, and only that, through two entries and no thi ### 1. The target and the pipe -The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing or disambiguating by name and description, then carrying the returned id; without that tool, ask for the id. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. +The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing by name and description, then carrying the returned id; without that tool, ask for it. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. The pipe is the declared main pipe unless the user named another: **carry its `pipe_ref` through every call**, the code qualified by its own file's domain. @@ -39,11 +39,11 @@ Anything else — a placeholder, a local path, a `data:` URL, inline bytes, a re ### 3. Prove the target before spending credit -For a **bundle directory**, one `mthds_validate` call over the bundle, with the same file set step 5 submits. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. For an **`mt_…` id**, the same call with `method_id` in place of `files`, and for an address with `method_ref`. Step 2's template call does not stand in for it: it answers `is_valid` alone, and a scaffold is a *valid* bundle. +For a **bundle directory**, one `mthds_validate` call over the file set step 5 submits. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. For an **`mt_…` id**, the same call with `method_id` in place of `files`, and for an address with `method_ref`. Step 2's template call does not stand in for it: it answers `is_valid` alone, and a scaffold is a *valid* bundle. The bar is `is_valid: true`, `is_runnable: true` and an empty `pending_signatures`. Short of it, report the verdict and route to `/pipelex-design`, or to `/pipelex-edit` when the fix is contract-preserving; an address's verdict is reported as [its reference](references/published-address.md) says. Never run a method that did not pass. -**A dry run is this step, shown.** The workshop has no mock-inference mode, so when the user asks for a dry run or anything "before spending credit", this call is it (a test run on test files is a real run), and the graph it builds never reaches you. Show the flow as numbered text: each step, what it reads and makes, where it batches or branches, and which steps call a model. For an id or an address, give the contract from the verdict's `main_pipe` instead. Say that no model ran and nothing was spent, and what the inputs still need. **Then end the turn there, even when the same request asked for the real run too**: the flow is the reply, and the paid run waits for the user's go. +**A dry run is this step, shown.** The workshop has no mock-inference mode, so when the user asks for a dry run or anything "before spending credit", this call is it (a test run on test files is a real run). **When the verdict carries `graph_page.written: true`, give the page's `path` before the text flow**: it opens in a browser and draws the whole method. When a summary called the page new, pass on its note that a project under git may want to ignore it. A `graph_page.error` gets one line, and the verdict stands. Show the flow as numbered text: each step, what it reads and makes, where it batches or branches, and which steps call a model. For an id or an address, give the contract from the verdict's `main_pipe` instead. Say that no model ran and nothing was spent, and what the inputs still need. **Then end the turn there, even when the same request asked for the real run too**: the flow is the reply, and the paid run waits for the user's go. ### 4. Say what is about to run @@ -83,7 +83,7 @@ Give `failure_message` **verbatim** first, then read [failed-run.md](references/ A run id alone, with no method and no inputs: nothing is validated or prepared. -- **"how is run X going"** → `mthds_run_status`. Report the state and, while it is running, the retry hint rather than a guess at how long it will take. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. +- **"how is run X going"** → `mthds_run_status`. Report the state and, while it runs, the retry hint, never a guess at how long it will take. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. - **"get the results of run X"** → `mthds_run_results`. A run that is not terminal has no results: report the state instead. - **"save run X"**, or its files → `mthds_download_artifacts`, as step 7 says; it works days after the run. Saving a run twice adds copies. diff --git a/pipelex-vibe/skills/pipelex-catalog/SKILL.md b/pipelex-vibe/skills/pipelex-catalog/SKILL.md index b2b2085d..11b750c1 100644 --- a/pipelex-vibe/skills/pipelex-catalog/SKILL.md +++ b/pipelex-vibe/skills/pipelex-catalog/SKILL.md @@ -28,7 +28,7 @@ Every gesture between a bundle directory and the organization's method catalog: The target is a bundle directory. -1. **Gather the bundle's files** as the convention below says, and submit them as `files` with the **root file first** — the one carrying the bundle's `domain` header, usually `main.mthds` — because the platform derives the method's listed description from the first file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` gets no link file: a method created that way stays unlinked, so the next save from here makes a second one, and a method updated that way keeps the link's old sync time, so the next save from here is refused as a conflict with this session's own save. So **a save takes the path form**. When the workshop refuses a path, say that this session cannot write the link and which of the two that costs, and save inline only on the user's yes. +1. **Gather the bundle's files** as the convention below says, and submit them as `files` with the **root file first** — the one carrying the bundle's `domain` header, usually `main.mthds` — because the platform derives the method's listed description from the first file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` gets no link file: a method created that way stays unlinked, so the next save from here makes a second one, and a method updated that way keeps the link's old sync time, so the next save from here is refused as a conflict with this session's own save. So **a save takes the path form**. When the workshop refuses a path, say that this session cannot write the link and which of the two that costs, and save inline only on the user's yes. 2. **Decide the arm from `pipelex-method.json` beside the root file.** When it is there, this is an **update**: pass its `method_id`, pass its `synced_updated_at` as `expected_updated_at`, and keep the `name` it records unless the user is renaming. When it is not, this is a **creation**: ask the user for the name, proposing the bundle's `description` in a few words or its `domain` in plain words (`summarize_pdf` → *Summarize PDF*). `name` is required on both arms, since the save rewrites the whole catalog row. Never pass `link_dir`: omitted, the link goes beside the root file. 3. **Decide `python`.** It replaces the stored Python as a set: omitting it preserves the stored set, sending files replaces them all, and sending `[]` clears them. **A bundle with no `PipeFunc` sends no `python` at all**, and `[]` goes only when the user has asked for the stored Python to be cleared. With a `PipeFunc`, read [python.md](references/python.md) before choosing any file: **which `.py` files are the method's is this skill's judgement, not the tool's**, and a file sent by mistake is uploaded to the catalog, where nothing validates it. When it is unclear, ask; do not sweep the directory. 4. **Say what is about to happen, in one line**, then call `mthds_save_method`; there is no second confirmation, since the user's request is the consent. A create says what is made: *Creating a new method **Summarize PDF** on Pipelex from `methods/summarize_pdf/`.* An update says what an update is, in a line that is never optional: diff --git a/pipelex-vibe/skills/pipelex-design/SKILL.md b/pipelex-vibe/skills/pipelex-design/SKILL.md index d2c1bb60..c11f5ba5 100644 --- a/pipelex-vibe/skills/pipelex-design/SKILL.md +++ b/pipelex-vibe/skills/pipelex-design/SKILL.md @@ -27,7 +27,7 @@ Read [writing-mthds.md](../shared/writing-mthds.md) **before writing**: it is th Fix the **input concept(s)**, the **output concept** and the **description**, precise enough to implement against, and specify every boundary concept fully now. Shape each concept from all its known consumers: it must be structured if any consumer field-reads it (`$x.field`, a construct `from = "x.field"`), and can stay simple otherwise. Declare each concept exactly once, complete, owned by the root boundary or by the controller that introduces it. -**Announce the captured contract in one line** (inputs → output, one-sentence semantics), with the bundle home resolved below in the same line, before writing, so the user can interject without blocking progress. **If the design will emit a `PipeFunc`, say so in that same line**, warning rather than refusing: **`PipeFunc` is experimental on the hosted plane.** Its Python runs in a sandbox with no network access, and the feature is still in development, so a method that validates can still fail when it runs. Discuss only genuine ambiguity, or when the user asks to collaborate. +**Announce the captured contract in one line** (inputs → output, one-sentence semantics), with the bundle home resolved below in the same line, before writing, without waiting for a reply. **If the design will emit a `PipeFunc`, say so in that same line**, warning rather than refusing: **`PipeFunc` is experimental on the hosted plane.** Its Python runs in a sandbox with no network access, and the feature is still in development, so a method that validates can still fail when it runs. Discuss only genuine ambiguity, or when the user asks to collaborate. ### 2. Resolve the bundle home before writing @@ -48,7 +48,7 @@ Design the whole graph in memory, then write `main.mthds` in the bundle home, to ### 5. Validate -Gather the bundle's files as the convention below says, the whole library, and call `mthds_validate` with `files` for every file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. +Gather the bundle's files as the convention below says, the whole library, and call `mthds_validate` with `files` for every file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. Branch on the **structured verdict** from its Markdown summary, never on transport: `is_valid: true` is complete with `is_runnable: true` and nothing pending, and otherwise a scaffold whose backlog is the summary's `## Pending signatures`; on `is_valid: false`, fix from `validation_errors[]` and the summary's locators, which name the offending file, then re-validate. @@ -58,7 +58,7 @@ For a completed method, re-gather the whole bundle and confirm **`is_valid: true 1. **Organize only when the layout needs it.** A converged stepwise construction or signature-driven re-entry normally invokes `/pipelex-organize`; a result already coherent in either mode skips it. 2. **Project the input schema**: `mthds_inputs_template` with the final whole-bundle `files` and `explicit: false`; show the compact template. -3. **Present the flow**: the interactive method graph where the host rendered it, else a concise text flow. +3. **Present the flow** as concise text. **When the verdict carries `graph_page.written: true`, give the page's `path` before the text flow**: it opens in a browser and draws the whole method. When a summary called the page new, pass on its note that a project under git may want to ignore it. A `graph_page.error` gets one line, and the verdict stands. 4. **Warn again for a `PipeFunc`**, naming its pipes: **`PipeFunc` is experimental on the hosted plane.** Its Python runs in a sandbox with no network access, and the feature is still in development, so a method that validates can still fail when it runs. 5. **Hand off**: `/pipelex-inputs` prepares the user's files, or test files with planted facts, then `/pipelex-run` runs the method, and `/pipelex-lab` writes answer keys and scores the runs; `/pipelex-catalog` saves it under an `mt_…` id anything can call; `/pipelex-integrate` wires it into a codebase (a `package.json` or a `pyproject.toml`), and with none, `/pipelex-scaffold` creates an application around it if the user wants one. 6. Search the whole project for `sources.json` files carrying `"generator": "pipelex-integrate"` — `grep -rl '"pipelex-integrate"' --include=sources.json .` — which sit beside each generated tree (`src/generated//`, `/generated//`), never beside the bundle, so looking only next to the `.mthds` files finds nothing. Keep each one whose `sources` name a `.mthds` file this change rewrote, moved or removed, **or whose `bundle_dir` holds a `.mthds` file this change created** — a new file is in no `sources` map, yet the call site loads every `.mthds` file under that directory. For each, say the generated types in that directory are now stale and offer `/pipelex-integrate` to refresh them: it regenerates in place and touches the call site only if the types no longer fit it. diff --git a/pipelex-vibe/skills/pipelex-edit/SKILL.md b/pipelex-vibe/skills/pipelex-edit/SKILL.md index 53a6195c..5de9ea90 100644 --- a/pipelex-vibe/skills/pipelex-edit/SKILL.md +++ b/pipelex-vibe/skills/pipelex-edit/SKILL.md @@ -43,7 +43,7 @@ Check the requested change against the scope split at the top. Structural or con ### Step 3: Baseline verdict -Validate the whole bundle **before editing**: call `mthds_validate` with `files` for every file, and branch on the structured verdict, never on transport. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. +Validate the whole bundle **before editing**: call `mthds_validate` with `files` for every file, and branch on the structured verdict, never on transport. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. - `is_valid: true` → record whether it is runnable or a scaffold (non-empty `pending_signatures`). That same state must hold after your edits. - `is_valid: false` → the bundle is broken **before** your change: surface the `validation_errors[]` and the Markdown summary, and offer to repair first. **Never edit on a broken baseline.** diff --git a/pipelex-vibe/skills/pipelex-explain/SKILL.md b/pipelex-vibe/skills/pipelex-explain/SKILL.md index 4830bcb9..0cd450f2 100644 --- a/pipelex-vibe/skills/pipelex-explain/SKILL.md +++ b/pipelex-vibe/skills/pipelex-explain/SKILL.md @@ -36,7 +36,7 @@ A `PipeSignature` is **pending only when no concrete pipe of the same code exist ### 3. The verdict, when the workshop is there -One `mthds_validate` call over the same files. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. The call adds two things to the explanation: the **verdict line** (whether it is valid, whether it is runnable, what is still pending) and, when the verdict carries a `main_pipe`, the **main pipe's typed signature**: its namespaced ref, each declared input with its concept and whether it is required, and the concept it produces. On `{path}` files the workshop also writes the method's flowchart beside them as `method-graph.html`, rewritten on every validation, and reports it as `graph_page`. +One `mthds_validate` call over the same files. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. The call adds two things to the explanation: the **verdict line** (whether it is valid, whether it is runnable, what is still pending) and, when the verdict carries a `main_pipe`, the **main pipe's typed signature**: its namespaced ref, each declared input with its concept and whether it is required, and the concept it produces. On `{path}` files the workshop also writes the method's flowchart beside them as `method-graph.html`, rewritten on every validation, and reports it as `graph_page`. Without the tool, explain from the source and **say the verdict was not checked**. Your own reading of the source is not a guess: the pipe types, the concepts and step 2's backlog are yours to state, saying whose reading it is. But do not present a validation verdict, a typed signature or a pending list as the workshop's when the workshop did not answer, and do not guess at validity. **On a target that is not on disk there is no such fallback.** @@ -46,7 +46,7 @@ Say first whether it is **complete** or a **scaffold with a backlog**, from step ### 5. The flow: the root first, then one passage per module -**When the verdict carries `graph_page.written: true`, give the page's `path` before the text flow**: it opens in a browser and draws the whole method. When the summary says the page is new, pass on its note that a project under git may want to ignore it. A `graph_page.error` gets one line, and the verdict stands. +**When the verdict carries `graph_page.written: true`, give the page's `path` before the text flow**: it opens in a browser and draws the whole method. When a summary called the page new, pass on its note that a project under git may want to ignore it. A `graph_page.error` gets one line, and the verdict stands. **The root file gives the contract and the top-level flow**, then **one passage per module file**, each named by its file; a one-file method gets one passage, the simple case and not a missing structure. Trace the flow from the main pipe, reading the controllers in their own terms: diff --git a/pipelex-vibe/skills/pipelex-inputs/SKILL.md b/pipelex-vibe/skills/pipelex-inputs/SKILL.md index 881cfc0b..a79f53cc 100644 --- a/pipelex-vibe/skills/pipelex-inputs/SKILL.md +++ b/pipelex-vibe/skills/pipelex-inputs/SKILL.md @@ -31,7 +31,7 @@ The one entry point for a method's inputs — placeholders, synthetic data, the The target takes three forms, and every call takes exactly one selector. -- **A local bundle**, the usual case, as `files`: `` is its directory, usually the one holding `main.mthds`, unless the caller names another. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. +- **A local bundle**, the usual case, as `files`: `` is its directory, usually the one holding `main.mthds`, unless the caller names another. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. - **A registered method**, an `mt_…` id with no local bundle in play, as `method_id`: its current stored content, which needs the API key. `` is a directory the user names, by default a new `.//`. - **A published method**, as `method_ref: "github.com//[/][@]"`: read [references/published-address.md](references/published-address.md) before the first call. **An address with no tag is accepted, and it floats**: say so in one line, recommend the tag, and carry on. diff --git a/pipelex-vibe/skills/pipelex-organize/SKILL.md b/pipelex-vibe/skills/pipelex-organize/SKILL.md index 8c8e87ab..cde3ba9a 100644 --- a/pipelex-vibe/skills/pipelex-organize/SKILL.md +++ b/pipelex-vibe/skills/pipelex-organize/SKILL.md @@ -27,7 +27,7 @@ It is a **content-preserving transformation**: the method's semantics never chan **For a catalog id (`mt_…`) or a published address**, read [the catalog-id reference](../shared/catalog-id.md) before reading any file. **When several directories are linked to the method, ask which is the work; never choose.** **Never present a linked directory as the saved method's current content.** -Gather the bundle's files as the convention below says, read each, and call `mthds_validate` with `files` for every file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. Record the **baseline**: `is_valid`, `is_runnable`, and the exact `pending_signatures` set. `is_valid: true` proceeds, runnable or scaffold. +Gather the bundle's files as the convention below says, read each, and call `mthds_validate` with `files` for every file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. Record the **baseline**: `is_valid`, `is_runnable`, and the exact `pending_signatures` set. `is_valid: true` proceeds, runnable or scaffold. ### Step 2 — Plan the layout, compose the files diff --git a/pipelex-vibe/skills/pipelex-run/SKILL.md b/pipelex-vibe/skills/pipelex-run/SKILL.md index 48517c3d..effe5cb6 100644 --- a/pipelex-vibe/skills/pipelex-run/SKILL.md +++ b/pipelex-vibe/skills/pipelex-run/SKILL.md @@ -5,7 +5,7 @@ description: Run an MTHDS method on the hosted Pipelex API, and follow a run tha # Run an MTHDS method -This skill owns the run lifecycle, and only that, through two entries and no third: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which stays good long after the session that started it. A dry run is not a third entry: it is Start a run's step 3, shown to the user as a numbered flow. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). +This skill owns the run lifecycle through two entries: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which stays good long after the session that started it; a dry run is Start a run's step 3, shown. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). ## Requirements @@ -18,7 +18,7 @@ This skill owns the run lifecycle, and only that, through two entries and no thi ### 1. The target and the pipe -The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing or disambiguating by name and description, then carrying the returned id; without that tool, ask for the id. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. +The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing by name and description, then carrying the returned id; without that tool, ask for it. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. The pipe is the declared main pipe unless the user named another: **carry its `pipe_ref` through every call**, the code qualified by its own file's domain. @@ -39,11 +39,11 @@ Anything else — a placeholder, a local path, a `data:` URL, inline bytes, a re ### 3. Prove the target before spending credit -For a **bundle directory**, one `mthds_validate` call over the bundle, with the same file set step 5 submits. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. For an **`mt_…` id**, the same call with `method_id` in place of `files`, and for an address with `method_ref`. Step 2's template call does not stand in for it: it answers `is_valid` alone, and a scaffold is a *valid* bundle. +For a **bundle directory**, one `mthds_validate` call over the file set step 5 submits. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. For an **`mt_…` id**, the same call with `method_id` in place of `files`, and for an address with `method_ref`. Step 2's template call does not stand in for it: it answers `is_valid` alone, and a scaffold is a *valid* bundle. The bar is `is_valid: true`, `is_runnable: true` and an empty `pending_signatures`. Short of it, report the verdict and route to `/pipelex-design`, or to `/pipelex-edit` when the fix is contract-preserving; an address's verdict is reported as [its reference](references/published-address.md) says. Never run a method that did not pass. -**A dry run is this step, shown.** The workshop has no mock-inference mode, so when the user asks for a dry run or anything "before spending credit", this call is it (a test run on test files is a real run), and the graph it builds never reaches you. Show the flow as numbered text: each step, what it reads and makes, where it batches or branches, and which steps call a model. For an id or an address, give the contract from the verdict's `main_pipe` instead. Say that no model ran and nothing was spent, and what the inputs still need. **Then end the turn there, even when the same request asked for the real run too**: the flow is the reply, and the paid run waits for the user's go. +**A dry run is this step, shown.** The workshop has no mock-inference mode, so when the user asks for a dry run or anything "before spending credit", this call is it (a test run on test files is a real run). **When the verdict carries `graph_page.written: true`, give the page's `path` before the text flow**: it opens in a browser and draws the whole method. When a summary called the page new, pass on its note that a project under git may want to ignore it. A `graph_page.error` gets one line, and the verdict stands. Show the flow as numbered text: each step, what it reads and makes, where it batches or branches, and which steps call a model. For an id or an address, give the contract from the verdict's `main_pipe` instead. Say that no model ran and nothing was spent, and what the inputs still need. **Then end the turn there, even when the same request asked for the real run too**: the flow is the reply, and the paid run waits for the user's go. ### 4. Say what is about to run @@ -83,7 +83,7 @@ Give `failure_message` **verbatim** first, then read [failed-run.md](references/ A run id alone, with no method and no inputs: nothing is validated or prepared. -- **"how is run X going"** → `mthds_run_status`. Report the state and, while it is running, the retry hint rather than a guess at how long it will take. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. +- **"how is run X going"** → `mthds_run_status`. Report the state and, while it runs, the retry hint, never a guess at how long it will take. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. - **"get the results of run X"** → `mthds_run_results`. A run that is not terminal has no results: report the state instead. - **"save run X"**, or its files → `mthds_download_artifacts`, as step 7 says; it works days after the run. Saving a run twice adds copies. diff --git a/pipelex/skills/pipelex-catalog/SKILL.md b/pipelex/skills/pipelex-catalog/SKILL.md index de4d1069..55b2e3bf 100644 --- a/pipelex/skills/pipelex-catalog/SKILL.md +++ b/pipelex/skills/pipelex-catalog/SKILL.md @@ -37,7 +37,7 @@ Every gesture between a bundle directory and the organization's method catalog: The target is a bundle directory. -1. **Gather the bundle's files** as the convention below says, and submit them as `files` with the **root file first** — the one carrying the bundle's `domain` header, usually `main.mthds` — because the platform derives the method's listed description from the first file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` gets no link file: a method created that way stays unlinked, so the next save from here makes a second one, and a method updated that way keeps the link's old sync time, so the next save from here is refused as a conflict with this session's own save. So **a save takes the path form**. When the workshop refuses a path, say that this session cannot write the link and which of the two that costs, and save inline only on the user's yes. +1. **Gather the bundle's files** as the convention below says, and submit them as `files` with the **root file first** — the one carrying the bundle's `domain` header, usually `main.mthds` — because the platform derives the method's listed description from the first file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` gets no link file: a method created that way stays unlinked, so the next save from here makes a second one, and a method updated that way keeps the link's old sync time, so the next save from here is refused as a conflict with this session's own save. So **a save takes the path form**. When the workshop refuses a path, say that this session cannot write the link and which of the two that costs, and save inline only on the user's yes. 2. **Decide the arm from `pipelex-method.json` beside the root file.** When it is there, this is an **update**: pass its `method_id`, pass its `synced_updated_at` as `expected_updated_at`, and keep the `name` it records unless the user is renaming. When it is not, this is a **creation**: ask the user for the name, proposing the bundle's `description` in a few words or its `domain` in plain words (`summarize_pdf` → *Summarize PDF*). `name` is required on both arms, since the save rewrites the whole catalog row. Never pass `link_dir`: omitted, the link goes beside the root file. 3. **Decide `python`.** It replaces the stored Python as a set: omitting it preserves the stored set, sending files replaces them all, and sending `[]` clears them. **A bundle with no `PipeFunc` sends no `python` at all**, and `[]` goes only when the user has asked for the stored Python to be cleared. With a `PipeFunc`, read [python.md](references/python.md) before choosing any file: **which `.py` files are the method's is this skill's judgement, not the tool's**, and a file sent by mistake is uploaded to the catalog, where nothing validates it. When it is unclear, ask; do not sweep the directory. 4. **Say what is about to happen, in one line**, then call `mthds_save_method`; there is no second confirmation, since the user's request is the consent. A create says what is made: *Creating a new method **Summarize PDF** on Pipelex from `methods/summarize_pdf/`.* An update says what an update is, in a line that is never optional: diff --git a/pipelex/skills/pipelex-design/SKILL.md b/pipelex/skills/pipelex-design/SKILL.md index 95c01ede..f5ae1ff4 100644 --- a/pipelex/skills/pipelex-design/SKILL.md +++ b/pipelex/skills/pipelex-design/SKILL.md @@ -36,7 +36,7 @@ Read [writing-mthds.md](../shared/writing-mthds.md) **before writing**: it is th Fix the **input concept(s)**, the **output concept** and the **description**, precise enough to implement against, and specify every boundary concept fully now. Shape each concept from all its known consumers: it must be structured if any consumer field-reads it (`$x.field`, a construct `from = "x.field"`), and can stay simple otherwise. Declare each concept exactly once, complete, owned by the root boundary or by the controller that introduces it. -**Announce the captured contract in one line** (inputs → output, one-sentence semantics), with the bundle home resolved below in the same line, before writing, so the user can interject without blocking progress. **If the design will emit a `PipeFunc`, say so in that same line**, warning rather than refusing: **`PipeFunc` is experimental on the hosted plane.** Its Python runs in a sandbox with no network access, and the feature is still in development, so a method that validates can still fail when it runs. Discuss only genuine ambiguity, or when the user asks to collaborate. +**Announce the captured contract in one line** (inputs → output, one-sentence semantics), with the bundle home resolved below in the same line, before writing, without waiting for a reply. **If the design will emit a `PipeFunc`, say so in that same line**, warning rather than refusing: **`PipeFunc` is experimental on the hosted plane.** Its Python runs in a sandbox with no network access, and the feature is still in development, so a method that validates can still fail when it runs. Discuss only genuine ambiguity, or when the user asks to collaborate. ### 2. Resolve the bundle home before writing @@ -57,7 +57,7 @@ Design the whole graph in memory, then write `main.mthds` in the bundle home, to ### 5. Validate -Gather the bundle's files as the convention below says, the whole library, and call `mthds_validate` with `files` for every file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. +Gather the bundle's files as the convention below says, the whole library, and call `mthds_validate` with `files` for every file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. Branch on the **structured verdict** from its Markdown summary, never on transport: `is_valid: true` is complete with `is_runnable: true` and nothing pending, and otherwise a scaffold whose backlog is the summary's `## Pending signatures`; on `is_valid: false`, fix from `validation_errors[]` and the summary's locators, which name the offending file, then re-validate. @@ -67,7 +67,7 @@ For a completed method, re-gather the whole bundle and confirm **`is_valid: true 1. **Organize only when the layout needs it.** A converged stepwise construction or signature-driven re-entry normally invokes `/pipelex-organize`; a result already coherent in either mode skips it. 2. **Project the input schema**: `mthds_inputs_template` with the final whole-bundle `files` and `explicit: false`; show the compact template. -3. **Present the flow**: the interactive method graph where the host rendered it, else a concise text flow. +3. **Present the flow** as concise text. **When the verdict carries `graph_page.written: true`, give the page's `path` before the text flow**: it opens in a browser and draws the whole method. When a summary called the page new, pass on its note that a project under git may want to ignore it. A `graph_page.error` gets one line, and the verdict stands. 4. **Warn again for a `PipeFunc`**, naming its pipes: **`PipeFunc` is experimental on the hosted plane.** Its Python runs in a sandbox with no network access, and the feature is still in development, so a method that validates can still fail when it runs. 5. **Hand off**: `/pipelex-inputs` prepares the user's files, or test files with planted facts, then `/pipelex-run` runs the method, and `/pipelex-lab` writes answer keys and scores the runs; `/pipelex-catalog` saves it under an `mt_…` id anything can call; `/pipelex-integrate` wires it into a codebase (a `package.json` or a `pyproject.toml`), and with none, `/pipelex-scaffold` creates an application around it if the user wants one. 6. Search the whole project for `sources.json` files carrying `"generator": "pipelex-integrate"` — `grep -rl '"pipelex-integrate"' --include=sources.json .` — which sit beside each generated tree (`src/generated//`, `/generated//`), never beside the bundle, so looking only next to the `.mthds` files finds nothing. Keep each one whose `sources` name a `.mthds` file this change rewrote, moved or removed, **or whose `bundle_dir` holds a `.mthds` file this change created** — a new file is in no `sources` map, yet the call site loads every `.mthds` file under that directory. For each, say the generated types in that directory are now stale and offer `/pipelex-integrate` to refresh them: it regenerates in place and touches the call site only if the types no longer fit it. diff --git a/pipelex/skills/pipelex-edit/SKILL.md b/pipelex/skills/pipelex-edit/SKILL.md index a8fee043..14f68cfe 100644 --- a/pipelex/skills/pipelex-edit/SKILL.md +++ b/pipelex/skills/pipelex-edit/SKILL.md @@ -52,7 +52,7 @@ Check the requested change against the scope split at the top. Structural or con ### Step 3: Baseline verdict -Validate the whole bundle **before editing**: call `mthds_validate` with `files` for every file, and branch on the structured verdict, never on transport. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. +Validate the whole bundle **before editing**: call `mthds_validate` with `files` for every file, and branch on the structured verdict, never on transport. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. - `is_valid: true` → record whether it is runnable or a scaffold (non-empty `pending_signatures`). That same state must hold after your edits. - `is_valid: false` → the bundle is broken **before** your change: surface the `validation_errors[]` and the Markdown summary, and offer to repair first. **Never edit on a broken baseline.** diff --git a/pipelex/skills/pipelex-explain/SKILL.md b/pipelex/skills/pipelex-explain/SKILL.md index ee8ea761..a98134c3 100644 --- a/pipelex/skills/pipelex-explain/SKILL.md +++ b/pipelex/skills/pipelex-explain/SKILL.md @@ -43,7 +43,7 @@ A `PipeSignature` is **pending only when no concrete pipe of the same code exist ### 3. The verdict, when the workshop is there -One `mthds_validate` call over the same files. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. The call adds two things to the explanation: the **verdict line** (whether it is valid, whether it is runnable, what is still pending) and, when the verdict carries a `main_pipe`, the **main pipe's typed signature**: its namespaced ref, each declared input with its concept and whether it is required, and the concept it produces. On `{path}` files the workshop also writes the method's flowchart beside them as `method-graph.html`, rewritten on every validation, and reports it as `graph_page`. +One `mthds_validate` call over the same files. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. The call adds two things to the explanation: the **verdict line** (whether it is valid, whether it is runnable, what is still pending) and, when the verdict carries a `main_pipe`, the **main pipe's typed signature**: its namespaced ref, each declared input with its concept and whether it is required, and the concept it produces. On `{path}` files the workshop also writes the method's flowchart beside them as `method-graph.html`, rewritten on every validation, and reports it as `graph_page`. Without the tool, explain from the source and **say the verdict was not checked**. Your own reading of the source is not a guess: the pipe types, the concepts and step 2's backlog are yours to state, saying whose reading it is. But do not present a validation verdict, a typed signature or a pending list as the workshop's when the workshop did not answer, and do not guess at validity. **On a target that is not on disk there is no such fallback.** @@ -53,7 +53,7 @@ Say first whether it is **complete** or a **scaffold with a backlog**, from step ### 5. The flow: the root first, then one passage per module -**When the verdict carries `graph_page.written: true`, give the page's `path` before the text flow**: it opens in a browser and draws the whole method. When the summary says the page is new, pass on its note that a project under git may want to ignore it. A `graph_page.error` gets one line, and the verdict stands. +**When the verdict carries `graph_page.written: true`, give the page's `path` before the text flow**: it opens in a browser and draws the whole method. When a summary called the page new, pass on its note that a project under git may want to ignore it. A `graph_page.error` gets one line, and the verdict stands. **The root file gives the contract and the top-level flow**, then **one passage per module file**, each named by its file; a one-file method gets one passage, the simple case and not a missing structure. Trace the flow from the main pipe, reading the controllers in their own terms: diff --git a/pipelex/skills/pipelex-inputs/SKILL.md b/pipelex/skills/pipelex-inputs/SKILL.md index bf5b20e3..21eb4e63 100644 --- a/pipelex/skills/pipelex-inputs/SKILL.md +++ b/pipelex/skills/pipelex-inputs/SKILL.md @@ -41,7 +41,7 @@ The one entry point for a method's inputs — placeholders, synthetic data, the The target takes three forms, and every call takes exactly one selector. -- **A local bundle**, the usual case, as `files`: `` is its directory, usually the one holding `main.mthds`, unless the caller names another. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. +- **A local bundle**, the usual case, as `files`: `` is its directory, usually the one holding `main.mthds`, unless the caller names another. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. - **A registered method**, an `mt_…` id with no local bundle in play, as `method_id`: its current stored content, which needs the API key. `` is a directory the user names, by default a new `.//`. - **A published method**, as `method_ref: "github.com//[/][@]"`: read [references/published-address.md](references/published-address.md) before the first call. **An address with no tag is accepted, and it floats**: say so in one line, recommend the tag, and carry on. diff --git a/pipelex/skills/pipelex-organize/SKILL.md b/pipelex/skills/pipelex-organize/SKILL.md index 8b9e73f0..07cae009 100644 --- a/pipelex/skills/pipelex-organize/SKILL.md +++ b/pipelex/skills/pipelex-organize/SKILL.md @@ -35,7 +35,7 @@ It is a **content-preserving transformation**: the method's semantics never chan **For a catalog id (`mt_…`) or a published address**, read [the catalog-id reference](../shared/catalog-id.md) before reading any file. **When several directories are linked to the method, ask which is the work; never choose.** **Never present a linked directory as the saved method's current content.** -Gather the bundle's files as the convention below says, read each, and call `mthds_validate` with `files` for every file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. Record the **baseline**: `is_valid`, `is_runnable`, and the exact `pending_signatures` set. `is_valid: true` proceeds, runnable or scaffold. +Gather the bundle's files as the convention below says, read each, and call `mthds_validate` with `files` for every file. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. Record the **baseline**: `is_valid`, `is_runnable`, and the exact `pending_signatures` set. `is_valid: true` proceeds, runnable or scaffold. ### Step 2 — Plan the layout, compose the files diff --git a/pipelex/skills/pipelex-run/SKILL.md b/pipelex/skills/pipelex-run/SKILL.md index 25b837ae..b1b624fd 100644 --- a/pipelex/skills/pipelex-run/SKILL.md +++ b/pipelex/skills/pipelex-run/SKILL.md @@ -19,7 +19,7 @@ allowed-tools: # Run an MTHDS method -This skill owns the run lifecycle, and only that, through two entries and no third: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which stays good long after the session that started it. A dry run is not a third entry: it is Start a run's step 3, shown to the user as a numbered flow. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). +This skill owns the run lifecycle through two entries: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which stays good long after the session that started it; a dry run is Start a run's step 3, shown. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). ## Requirements @@ -32,7 +32,7 @@ This skill owns the run lifecycle, and only that, through two entries and no thi ### 1. The target and the pipe -The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing or disambiguating by name and description, then carrying the returned id; without that tool, ask for the id. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. +The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing by name and description, then carrying the returned id; without that tool, ask for it. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. The pipe is the declared main pipe unless the user named another: **carry its `pipe_ref` through every call**, the code qualified by its own file's domain. @@ -53,11 +53,11 @@ Anything else — a placeholder, a local path, a `data:` URL, inline bytes, a re ### 3. Prove the target before spending credit -For a **bundle directory**, one `mthds_validate` call over the bundle, with the same file set step 5 submits. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. For an **`mt_…` id**, the same call with `method_id` in place of `files`, and for an address with `method_ref`. Step 2's template call does not stand in for it: it answers `is_valid` alone, and a scaffold is a *valid* bundle. +For a **bundle directory**, one `mthds_validate` call over the file set step 5 submits. Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` is the fallback. For an **`mt_…` id**, the same call with `method_id` in place of `files`, and for an address with `method_ref`. Step 2's template call does not stand in for it: it answers `is_valid` alone, and a scaffold is a *valid* bundle. The bar is `is_valid: true`, `is_runnable: true` and an empty `pending_signatures`. Short of it, report the verdict and route to `/pipelex-design`, or to `/pipelex-edit` when the fix is contract-preserving; an address's verdict is reported as [its reference](references/published-address.md) says. Never run a method that did not pass. -**A dry run is this step, shown.** The workshop has no mock-inference mode, so when the user asks for a dry run or anything "before spending credit", this call is it (a test run on test files is a real run), and the graph it builds never reaches you. Show the flow as numbered text: each step, what it reads and makes, where it batches or branches, and which steps call a model. For an id or an address, give the contract from the verdict's `main_pipe` instead. Say that no model ran and nothing was spent, and what the inputs still need. **Then end the turn there, even when the same request asked for the real run too**: the flow is the reply, and the paid run waits for the user's go. +**A dry run is this step, shown.** The workshop has no mock-inference mode, so when the user asks for a dry run or anything "before spending credit", this call is it (a test run on test files is a real run). **When the verdict carries `graph_page.written: true`, give the page's `path` before the text flow**: it opens in a browser and draws the whole method. When a summary called the page new, pass on its note that a project under git may want to ignore it. A `graph_page.error` gets one line, and the verdict stands. Show the flow as numbered text: each step, what it reads and makes, where it batches or branches, and which steps call a model. For an id or an address, give the contract from the verdict's `main_pipe` instead. Say that no model ran and nothing was spent, and what the inputs still need. **Then end the turn there, even when the same request asked for the real run too**: the flow is the reply, and the paid run waits for the user's go. ### 4. Say what is about to run @@ -97,7 +97,7 @@ Give `failure_message` **verbatim** first, then read [failed-run.md](references/ A run id alone, with no method and no inputs: nothing is validated or prepared. -- **"how is run X going"** → `mthds_run_status`. Report the state and, while it is running, the retry hint rather than a guess at how long it will take. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. +- **"how is run X going"** → `mthds_run_status`. Report the state and, while it runs, the retry hint, never a guess at how long it will take. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. - **"get the results of run X"** → `mthds_run_results`. A run that is not terminal has no results: report the state instead. - **"save run X"**, or its files → `mthds_download_artifacts`, as step 7 says; it works days after the run. Saving a run twice adds copies. diff --git a/templates/skills/pipelex-design/SKILL.md.j2 b/templates/skills/pipelex-design/SKILL.md.j2 index 49673d4a..b3b8c954 100644 --- a/templates/skills/pipelex-design/SKILL.md.j2 +++ b/templates/skills/pipelex-design/SKILL.md.j2 @@ -34,7 +34,7 @@ Read [writing-mthds.md](../shared/writing-mthds.md) **before writing**: it is th Fix the **input concept(s)**, the **output concept** and the **description**, precise enough to implement against, and specify every boundary concept fully now. Shape each concept from all its known consumers: it must be structured if any consumer field-reads it (`$x.field`, a construct `from = "x.field"`), and can stay simple otherwise. Declare each concept exactly once, complete, owned by the root boundary or by the controller that introduces it. -**Announce the captured contract in one line** (inputs → output, one-sentence semantics), with the bundle home resolved below in the same line, before writing, so the user can interject without blocking progress. **If the design will emit a `PipeFunc`, say so in that same line**, warning rather than refusing: {% include "skills/shared/pipefunc-warning.md.j2" %} Discuss only genuine ambiguity, or when the user asks to collaborate. +**Announce the captured contract in one line** (inputs → output, one-sentence semantics), with the bundle home resolved below in the same line, before writing, without waiting for a reply. **If the design will emit a `PipeFunc`, say so in that same line**, warning rather than refusing: {% include "skills/shared/pipefunc-warning.md.j2" %} Discuss only genuine ambiguity, or when the user asks to collaborate. ### 2. Resolve the bundle home before writing @@ -65,7 +65,7 @@ For a completed method, re-gather the whole bundle and confirm **`is_valid: true 1. **Organize only when the layout needs it.** A converged stepwise construction or signature-driven re-entry normally invokes `/pipelex-organize`; a result already coherent in either mode skips it. 2. **Project the input schema**: `mthds_inputs_template` with the final whole-bundle `files` and `explicit: false`; show the compact template. -3. **Present the flow**: the interactive method graph where the host rendered it, else a concise text flow. +3. **Present the flow** as concise text. {% include "skills/shared/graph-page.md.j2" %} 4. **Warn again for a `PipeFunc`**, naming its pipes: {% include "skills/shared/pipefunc-warning.md.j2" %} 5. **Hand off**: `/pipelex-inputs` prepares the user's files, or test files with planted facts, then `/pipelex-run` runs the method, and `/pipelex-lab` writes answer keys and scores the runs; `/pipelex-catalog` saves it under an `mt_…` id anything can call; `/pipelex-integrate` wires it into a codebase (a `package.json` or a `pyproject.toml`), and with none, `/pipelex-scaffold` creates an application around it if the user wants one. 6. {% include "skills/shared/stale-types-notice.md.j2" %} diff --git a/templates/skills/pipelex-explain/SKILL.md.j2 b/templates/skills/pipelex-explain/SKILL.md.j2 index ae47c0cf..11e4c37c 100644 --- a/templates/skills/pipelex-explain/SKILL.md.j2 +++ b/templates/skills/pipelex-explain/SKILL.md.j2 @@ -55,7 +55,7 @@ Say first whether it is **complete** or a **scaffold with a backlog**, from step ### 5. The flow: the root first, then one passage per module -**When the verdict carries `graph_page.written: true`, give the page's `path` before the text flow**: it opens in a browser and draws the whole method. When the summary says the page is new, pass on its note that a project under git may want to ignore it. A `graph_page.error` gets one line, and the verdict stands. +{% include "skills/shared/graph-page.md.j2" %} **The root file gives the contract and the top-level flow**, then **one passage per module file**, each named by its file; a one-file method gets one passage, the simple case and not a missing structure. Trace the flow from the main pipe, reading the controllers in their own terms: diff --git a/templates/skills/pipelex-run/SKILL.md.j2 b/templates/skills/pipelex-run/SKILL.md.j2 index db9725b9..db0f633c 100644 --- a/templates/skills/pipelex-run/SKILL.md.j2 +++ b/templates/skills/pipelex-run/SKILL.md.j2 @@ -15,7 +15,7 @@ description: Run an MTHDS method on the hosted Pipelex API, and follow a run tha # Run an MTHDS method -This skill owns the run lifecycle, and only that, through two entries and no third: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which stays good long after the session that started it. A dry run is not a third entry: it is Start a run's step 3, shown to the user as a numbered flow. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). +This skill owns the run lifecycle through two entries: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which stays good long after the session that started it; a dry run is Start a run's step 3, shown. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). ## Requirements @@ -29,7 +29,7 @@ This skill owns the run lifecycle, and only that, through two entries and no thi ### 1. The target and the pipe -The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing or disambiguating by name and description, then carrying the returned id; without that tool, ask for the id. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. +The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing by name and description, then carrying the returned id; without that tool, ask for it. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. The pipe is the declared main pipe unless the user named another: **carry its `pipe_ref` through every call**, the code qualified by its own file's domain. @@ -50,11 +50,11 @@ Anything else — a placeholder, a local path, a `data:` URL, inline bytes, a re ### 3. Prove the target before spending credit -For a **bundle directory**, one `mthds_validate` call over the bundle, with the same file set step 5 submits. {% include "skills/shared/validate-call.md.j2" %} For an **`mt_…` id**, the same call with `method_id` in place of `files`, and for an address with `method_ref`. Step 2's template call does not stand in for it: it answers `is_valid` alone, and a scaffold is a *valid* bundle. +For a **bundle directory**, one `mthds_validate` call over the file set step 5 submits. {% include "skills/shared/validate-call.md.j2" %} For an **`mt_…` id**, the same call with `method_id` in place of `files`, and for an address with `method_ref`. Step 2's template call does not stand in for it: it answers `is_valid` alone, and a scaffold is a *valid* bundle. The bar is `is_valid: true`, `is_runnable: true` and an empty `pending_signatures`. Short of it, report the verdict and route to `/pipelex-design`, or to `/pipelex-edit` when the fix is contract-preserving; an address's verdict is reported as [its reference](references/published-address.md) says. Never run a method that did not pass. -**A dry run is this step, shown.** The workshop has no mock-inference mode, so when the user asks for a dry run or anything "before spending credit", this call is it (a test run on test files is a real run), and the graph it builds never reaches you. Show the flow as numbered text: each step, what it reads and makes, where it batches or branches, and which steps call a model. For an id or an address, give the contract from the verdict's `main_pipe` instead. Say that no model ran and nothing was spent, and what the inputs still need. **Then end the turn there, even when the same request asked for the real run too**: the flow is the reply, and the paid run waits for the user's go. +**A dry run is this step, shown.** The workshop has no mock-inference mode, so when the user asks for a dry run or anything "before spending credit", this call is it (a test run on test files is a real run). {% include "skills/shared/graph-page.md.j2" %} Show the flow as numbered text: each step, what it reads and makes, where it batches or branches, and which steps call a model. For an id or an address, give the contract from the verdict's `main_pipe` instead. Say that no model ran and nothing was spent, and what the inputs still need. **Then end the turn there, even when the same request asked for the real run too**: the flow is the reply, and the paid run waits for the user's go. ### 4. Say what is about to run @@ -96,7 +96,7 @@ Give `failure_message` **verbatim** first, then read [failed-run.md](references/ A run id alone, with no method and no inputs: nothing is validated or prepared. -- **"how is run X going"** → `mthds_run_status`. Report the state and, while it is running, the retry hint rather than a guess at how long it will take. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. +- **"how is run X going"** → `mthds_run_status`. Report the state and, while it runs, the retry hint, never a guess at how long it will take. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. - **"get the results of run X"** → `mthds_run_results`. A run that is not terminal has no results: report the state instead. - **"save run X"**, or its files → `mthds_download_artifacts`, as step 7 says; it works days after the run. Saving a run twice adds copies. diff --git a/templates/skills/shared/graph-page.md.j2 b/templates/skills/shared/graph-page.md.j2 new file mode 100644 index 00000000..52b931d6 --- /dev/null +++ b/templates/skills/shared/graph-page.md.j2 @@ -0,0 +1,16 @@ +{#- The method graph page. When every file of an `mthds_validate` call is a + `{ path }`, the workshop writes the method's flowchart as `method-graph.html` + beside them and reports it as `graph_page: { path, written, error? }` + (`pipelex-mcp/SPEC.md`, "The method graph page (`graph_page`)"). One + sentence, included where a skill presents a method's flow: explain's step 5, + design's delivery and run's dry run. The other skills that validate by path + leave the page without a word; `docs/decisions.md` says why. + + "A summary" and not "the summary": the workshop's note that the page is new + comes with its first write, which for design is the first validation of the + construction loop, long before the flow is presented. + + Strips its own trailing newline (the closing comment below), so it can be + included mid-paragraph. -#} +**When the verdict carries `graph_page.written: true`, give the page's `path` before the text flow**: it opens in a browser and draws the whole method. When a summary called the page new, pass on its note that a project under git may want to ignore it. A `graph_page.error` gets one line, and the verdict stands. +{#- -#} diff --git a/templates/skills/shared/validate-call.md.j2 b/templates/skills/shared/validate-call.md.j2 index bc609a14..c7be1d46 100644 --- a/templates/skills/shared/validate-call.md.j2 +++ b/templates/skills/shared/validate-call.md.j2 @@ -7,7 +7,9 @@ `/pipelex-run` saves a completed run's artifacts. `pipelex-integrate` sets `validate_call_file_set = false` and states its own set, because the set it submits is the set its generated call site loads at runtime, and that is - the call site's to define. + the call site's to define. Why `runs/` is excluded — a method that emits or + echoes a `.mthds` file would otherwise submit its own output as source — is + rationale, and lives in `docs/decisions.md` beside the artifact `dir`. The local workshop resolves a `{ path }` item against its own working directory and refuses one that resolves outside it (`pipelex-mcp`, @@ -21,5 +23,5 @@ only beside a `{ path }` root file: for a save, the inline form is the one that leaves a new method unlinked, or an updated one's link behind the catalog. -#} -{% if validate_call_file_set | default(true) %}Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts: a method that emits or echoes a `.mthds` file would otherwise have its own output submitted as part of its source. {% endif %}Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` {{ validate_call_inline | default("is the fallback.") }} +{% if validate_call_file_set | default(true) %}Submit every `.mthds` file beneath the bundle directory **except anything under a `runs/` directory**, where `/pipelex-run` saves a completed run's artifacts. {% endif %}Prefer the path form `{path: }`. The workshop refuses a path outside **its own** working directory, where the harness launched it; relaunching the harness from a directory holding the bundle cures that. Inline `{content: , uri: }` {{ validate_call_inline | default("is the fallback.") }} {#- -#} diff --git a/tests/unit/test_gen_skill_docs.py b/tests/unit/test_gen_skill_docs.py index 60d343c9..154ffbd0 100644 --- a/tests/unit/test_gen_skill_docs.py +++ b/tests/unit/test_gen_skill_docs.py @@ -957,6 +957,7 @@ class TestSharedSkillIncludes: "stands for the directory holding this `SKILL.md`": "skills/shared/skill-dir.md.j2", "relative to that file's directory, say so, and check again": "skills/shared/git-ignore.md.j2", "so one still not ignored is not written until the user says so": "skills/shared/git-ignore.md.j2", + "give the page's `path` before the text flow": "skills/shared/graph-page.md.j2", } @pytest.mark.parametrize("sentence, owner", sorted(SHARED_BLOCK_OWNERS.items())) @@ -986,6 +987,19 @@ def test_the_pipefunc_warning_reaches_the_skills_that_ship_it(self) -> None: assert include in explain assert include in run + def test_the_graph_page_is_given_where_a_skill_presents_the_flow_and_nowhere_else(self) -> None: + """`mthds_validate` writes `method-graph.html` beside `{ path }` files, whichever skill + called it. Explain, design's delivery and run's dry run present a method's flow, so each + gives the page's path before its text flow (L-260926-d89a39, then L-260926-14cb83); every + other skill that validates by path leaves the page without a word, as `docs/decisions.md` + records. A skill that starts naming the page, or stops, changes that ruling, so the roster + is pinned here.""" + include = "skills/shared/graph-page.md.j2" + carriers = sorted( + path.parent.name for path in (self.REPO_TEMPLATES / "skills").glob("*/SKILL.md.j2") if include in path.read_text(encoding="utf-8") + ) + assert carriers == ["pipelex-design", "pipelex-explain", "pipelex-run"] + @pytest.mark.parametrize("target_name", ["prod", "codex", "mistral-vibe"]) def test_the_language_reference_carries_the_same_warning(self, target_name: str) -> None: """The language reference is where a designer reads what a PipeFunc is; a diff --git a/tests/unit/test_pipelex_design_skill.py b/tests/unit/test_pipelex_design_skill.py index 9ac5560a..abba9499 100644 --- a/tests/unit/test_pipelex_design_skill.py +++ b/tests/unit/test_pipelex_design_skill.py @@ -172,6 +172,16 @@ def test_the_skill_fits_what_a_compaction_keeps(self, target_name: str) -> None: size = len(self.render(target_name)) assert size <= SKILL_CEILING_CHARS, f"{target_name}: pipelex-design renders {size} characters, over the {SKILL_CEILING_CHARS} ceiling" + @pytest.mark.parametrize("target_name", TARGETS) + def test_delivery_gives_the_graph_page_before_the_text_flow(self, target_name: str) -> None: + """The plugin's workshop has no views, so no host ever rendered the "interactive method graph" + step 6 used to offer first. What reaches the user is the page `mthds_validate` writes beside a + bundle validated by path, so delivery gives its path and then the text flow (L-260926-14cb83).""" + flow = self.the_line(self.render(target_name), "**Present the flow**") + assert "give the page's `path` before the text flow" in flow + assert "as concise text" in flow + assert "where the host rendered it" not in self.render(target_name) + @pytest.mark.parametrize("target_name", TARGETS) def test_the_formatting_note_is_not_a_design_step(self, target_name: str) -> None: """The formatting-hook note is a stop by the read-before-act test — the hook's block names the syntax diff --git a/tests/unit/test_pipelex_run_skill.py b/tests/unit/test_pipelex_run_skill.py index df097a1e..09ef6587 100644 --- a/tests/unit/test_pipelex_run_skill.py +++ b/tests/unit/test_pipelex_run_skill.py @@ -209,6 +209,18 @@ def test_the_skill_fits_what_a_compaction_keeps(self, target_name: str) -> None: size = len(self.render(target_name)) assert size <= SKILL_CEILING_CHARS, f"{target_name}: pipelex-run renders {size} characters, over the {SKILL_CEILING_CHARS} ceiling" + @pytest.mark.parametrize("target_name", TARGETS) + def test_a_dry_run_gives_the_graph_page_before_the_numbered_flow(self, target_name: str) -> None: + """A dry run is step 3 shown, and on a bundle validated by path that call writes the method's + flowchart beside it, so the dry run gives the page's path and then the numbered flow. The skill used + to say the graph never reaches the model, which stopped being the whole truth once the page reached + the user (L-260926-14cb83). A real run says nothing of the page: its reply is the run.""" + body = self.render(target_name) + dry_run = self.the_line(body, "**A dry run is this step, shown.**") + assert dry_run.index("give the page's `path` before the text flow") < dry_run.index("Show the flow as numbered text") + assert "never reaches you" not in body + assert body.count("graph_page") == 2, "the page is named in the dry run alone" + @pytest.mark.parametrize("target_name", TARGETS) def test_every_platform_renders_the_skill(self, target_name: str) -> None: body = self.render(target_name) diff --git a/tests/unit/test_skill_guards.py b/tests/unit/test_skill_guards.py index 4e578424..8a0f383a 100644 --- a/tests/unit/test_skill_guards.py +++ b/tests/unit/test_skill_guards.py @@ -50,6 +50,7 @@ "**Never redesign on a broken baseline**", "**Retain the original contents until the final verdict is restored.**", "restore the retained baseline contents and report the failure", + "give the page's `path` before the text flow", ), "pipelex-explain": ( "Accept it, and say so in one line.", @@ -195,6 +196,7 @@ ), "pipelex-run": ( "**A dry run is this step, shown.**", + "give the page's `path` before the text flow", "**A dry-run request goes to step 3 first.**", "Then end the turn there, even when the same request asked for the real run too", "a paid run never starts on a dry-run request whose flow the user has not been shown", From 3d35ff99abd92b8ad7cf52452d371ba876e37624 Mon Sep 17 00:00:00 2001 From: Louis Choquel Date: Sat, 26 Sep 2026 19:40:17 +0200 Subject: [PATCH 2/2] Run asks when several saved methods fit a name The size trim had cut "choosing or disambiguating" to "choosing", which let the model pick among several saved methods matching a name on its own and spend credit on the wrong one. The sentence now says to ask when several fit, registered as a guard; the room comes from three shorter phrasings. Co-Authored-By: Claude Opus 5.5 --- pipelex-codex/skills/pipelex-run/SKILL.md | 8 ++++---- pipelex-vibe/skills/pipelex-run/SKILL.md | 8 ++++---- pipelex/skills/pipelex-run/SKILL.md | 8 ++++---- templates/skills/pipelex-run/SKILL.md.j2 | 8 ++++---- tests/unit/test_skill_guards.py | 1 + 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/pipelex-codex/skills/pipelex-run/SKILL.md b/pipelex-codex/skills/pipelex-run/SKILL.md index edfcc0a4..f18563ee 100644 --- a/pipelex-codex/skills/pipelex-run/SKILL.md +++ b/pipelex-codex/skills/pipelex-run/SKILL.md @@ -5,7 +5,7 @@ description: Run an MTHDS method on the hosted Pipelex API, and follow a run tha # Run an MTHDS method -This skill owns the run lifecycle through two entries: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which stays good long after the session that started it; a dry run is Start a run's step 3, shown. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). +This skill owns the run lifecycle through two entries: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which outlives the session that started it; a dry run is Start a run's step 3, shown. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). ## Requirements @@ -18,7 +18,7 @@ This skill owns the run lifecycle through two entries: [Start a run](#start-a-ru ### 1. The target and the pipe -The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing by name and description, then carrying the returned id; without that tool, ask for it. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. +The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing by name and description and asking when several fit, then carrying the returned id; without that tool, ask for it. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. The pipe is the declared main pipe unless the user named another: **carry its `pipe_ref` through every call**, the code qualified by its own file's domain. @@ -61,7 +61,7 @@ Call `mthds_run` with the same target — the whole-bundle `files` submission, ` When `pipelex-method.json` sits beside the root `.mthds` file, send its `method_id` beside the `files`: the files are what run, and the run is filed under that method in the webapp's history. **Say which method it was filed under, and do not let the filing read as the saved method having run.** -The tool returns a durable `run_id` immediately and never blocks. **Report that id the moment it returns, before anything else.** **For an address, give `method_provenance` beside it**: the address, the tag and the resolved commit SHA. +The tool returns a durable `run_id` at once and never blocks. **Report that id the moment it returns, before anything else.** **For an address, give `method_provenance` beside it**: the address, the tag and the resolved commit SHA. ### 6. Follow it to terminal @@ -83,7 +83,7 @@ Give `failure_message` **verbatim** first, then read [failed-run.md](references/ A run id alone, with no method and no inputs: nothing is validated or prepared. -- **"how is run X going"** → `mthds_run_status`. Report the state and, while it runs, the retry hint, never a guess at how long it will take. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. +- **"how is run X going"** → `mthds_run_status`. Report the state and, while it runs, the retry hint, never a guessed duration. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. - **"get the results of run X"** → `mthds_run_results`. A run that is not terminal has no results: report the state instead. - **"save run X"**, or its files → `mthds_download_artifacts`, as step 7 says; it works days after the run. Saving a run twice adds copies. diff --git a/pipelex-vibe/skills/pipelex-run/SKILL.md b/pipelex-vibe/skills/pipelex-run/SKILL.md index effe5cb6..823f9edd 100644 --- a/pipelex-vibe/skills/pipelex-run/SKILL.md +++ b/pipelex-vibe/skills/pipelex-run/SKILL.md @@ -5,7 +5,7 @@ description: Run an MTHDS method on the hosted Pipelex API, and follow a run tha # Run an MTHDS method -This skill owns the run lifecycle through two entries: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which stays good long after the session that started it; a dry run is Start a run's step 3, shown. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). +This skill owns the run lifecycle through two entries: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which outlives the session that started it; a dry run is Start a run's step 3, shown. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). ## Requirements @@ -18,7 +18,7 @@ This skill owns the run lifecycle through two entries: [Start a run](#start-a-ru ### 1. The target and the pipe -The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing by name and description, then carrying the returned id; without that tool, ask for it. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. +The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing by name and description and asking when several fit, then carrying the returned id; without that tool, ask for it. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. The pipe is the declared main pipe unless the user named another: **carry its `pipe_ref` through every call**, the code qualified by its own file's domain. @@ -61,7 +61,7 @@ Call `mthds_run` with the same target — the whole-bundle `files` submission, ` When `pipelex-method.json` sits beside the root `.mthds` file, send its `method_id` beside the `files`: the files are what run, and the run is filed under that method in the webapp's history. **Say which method it was filed under, and do not let the filing read as the saved method having run.** -The tool returns a durable `run_id` immediately and never blocks. **Report that id the moment it returns, before anything else.** **For an address, give `method_provenance` beside it**: the address, the tag and the resolved commit SHA. +The tool returns a durable `run_id` at once and never blocks. **Report that id the moment it returns, before anything else.** **For an address, give `method_provenance` beside it**: the address, the tag and the resolved commit SHA. ### 6. Follow it to terminal @@ -83,7 +83,7 @@ Give `failure_message` **verbatim** first, then read [failed-run.md](references/ A run id alone, with no method and no inputs: nothing is validated or prepared. -- **"how is run X going"** → `mthds_run_status`. Report the state and, while it runs, the retry hint, never a guess at how long it will take. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. +- **"how is run X going"** → `mthds_run_status`. Report the state and, while it runs, the retry hint, never a guessed duration. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. - **"get the results of run X"** → `mthds_run_results`. A run that is not terminal has no results: report the state instead. - **"save run X"**, or its files → `mthds_download_artifacts`, as step 7 says; it works days after the run. Saving a run twice adds copies. diff --git a/pipelex/skills/pipelex-run/SKILL.md b/pipelex/skills/pipelex-run/SKILL.md index b1b624fd..f277c05b 100644 --- a/pipelex/skills/pipelex-run/SKILL.md +++ b/pipelex/skills/pipelex-run/SKILL.md @@ -19,7 +19,7 @@ allowed-tools: # Run an MTHDS method -This skill owns the run lifecycle through two entries: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which stays good long after the session that started it; a dry run is Start a run's step 3, shown. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). +This skill owns the run lifecycle through two entries: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which outlives the session that started it; a dry run is Start a run's step 3, shown. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). ## Requirements @@ -32,7 +32,7 @@ This skill owns the run lifecycle through two entries: [Start a run](#start-a-ru ### 1. The target and the pipe -The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing by name and description, then carrying the returned id; without that tool, ask for it. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. +The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing by name and description and asking when several fit, then carrying the returned id; without that tool, ask for it. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. The pipe is the declared main pipe unless the user named another: **carry its `pipe_ref` through every call**, the code qualified by its own file's domain. @@ -75,7 +75,7 @@ Call `mthds_run` with the same target — the whole-bundle `files` submission, ` When `pipelex-method.json` sits beside the root `.mthds` file, send its `method_id` beside the `files`: the files are what run, and the run is filed under that method in the webapp's history. **Say which method it was filed under, and do not let the filing read as the saved method having run.** -The tool returns a durable `run_id` immediately and never blocks. **Report that id the moment it returns, before anything else.** **For an address, give `method_provenance` beside it**: the address, the tag and the resolved commit SHA. +The tool returns a durable `run_id` at once and never blocks. **Report that id the moment it returns, before anything else.** **For an address, give `method_provenance` beside it**: the address, the tag and the resolved commit SHA. ### 6. Follow it to terminal @@ -97,7 +97,7 @@ Give `failure_message` **verbatim** first, then read [failed-run.md](references/ A run id alone, with no method and no inputs: nothing is validated or prepared. -- **"how is run X going"** → `mthds_run_status`. Report the state and, while it runs, the retry hint, never a guess at how long it will take. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. +- **"how is run X going"** → `mthds_run_status`. Report the state and, while it runs, the retry hint, never a guessed duration. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. - **"get the results of run X"** → `mthds_run_results`. A run that is not terminal has no results: report the state instead. - **"save run X"**, or its files → `mthds_download_artifacts`, as step 7 says; it works days after the run. Saving a run twice adds copies. diff --git a/templates/skills/pipelex-run/SKILL.md.j2 b/templates/skills/pipelex-run/SKILL.md.j2 index db0f633c..aafd9782 100644 --- a/templates/skills/pipelex-run/SKILL.md.j2 +++ b/templates/skills/pipelex-run/SKILL.md.j2 @@ -15,7 +15,7 @@ description: Run an MTHDS method on the hosted Pipelex API, and follow a run tha # Run an MTHDS method -This skill owns the run lifecycle through two entries: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which stays good long after the session that started it; a dry run is Start a run's step 3, shown. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). +This skill owns the run lifecycle through two entries: [Start a run](#start-a-run) from a target and its inputs, and [Follow a run](#follow-a-run) from a run id alone, which outlives the session that started it; a dry run is Start a run's step 3, shown. It does not prepare inputs (`/pipelex-inputs`) or repair a method (`/pipelex-edit`, `/pipelex-design`). ## Requirements @@ -29,7 +29,7 @@ This skill owns the run lifecycle through two entries: [Start a run](#start-a-ru ### 1. The target and the pipe -The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing by name and description, then carrying the returned id; without that tool, ask for it. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. +The target is a **bundle directory**, submitted as `files`; a registered method's **`mt_…` id**, as `method_id`; or a **published method's address**, `github.com//[/][@]`, as `method_ref`: read [published-address.md](references/published-address.md) before the first call. A saved method named without its id is resolved through `mthds_list_methods`, choosing by name and description and asking when several fit, then carrying the returned id; without that tool, ask for it. Every call in this skill takes the form settled here, and **an address pairs with nothing**, being a complete run source: `files` or a `method_id` beside it is refused before anything runs. **When an address and another target are both in hand, ask which one is meant; never pick one yourself**: a run is paid. The pipe is the declared main pipe unless the user named another: **carry its `pipe_ref` through every call**, the code qualified by its own file's domain. @@ -72,7 +72,7 @@ Call `mthds_run` with the same target — the whole-bundle `files` submission, ` When `pipelex-method.json` sits beside the root `.mthds` file, send its `method_id` beside the `files`: the files are what run, and the run is filed under that method in the webapp's history. **Say which method it was filed under, and do not let the filing read as the saved method having run.** -The tool returns a durable `run_id` immediately and never blocks. **Report that id the moment it returns, before anything else.** **For an address, give `method_provenance` beside it**: the address, the tag and the resolved commit SHA. +The tool returns a durable `run_id` at once and never blocks. **Report that id the moment it returns, before anything else.** **For an address, give `method_provenance` beside it**: the address, the tag and the resolved commit SHA. ### 6. Follow it to terminal @@ -96,7 +96,7 @@ Give `failure_message` **verbatim** first, then read [failed-run.md](references/ A run id alone, with no method and no inputs: nothing is validated or prepared. -- **"how is run X going"** → `mthds_run_status`. Report the state and, while it runs, the retry hint, never a guess at how long it will take. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. +- **"how is run X going"** → `mthds_run_status`. Report the state and, while it runs, the retry hint, never a guessed duration. Step 6's readings of `degraded` and of a long `RUNNING` hold here as well. - **"get the results of run X"** → `mthds_run_results`. A run that is not terminal has no results: report the state instead. - **"save run X"**, or its files → `mthds_download_artifacts`, as step 7 says; it works days after the run. Saving a run twice adds copies. diff --git a/tests/unit/test_skill_guards.py b/tests/unit/test_skill_guards.py index 8a0f383a..2453c9f0 100644 --- a/tests/unit/test_skill_guards.py +++ b/tests/unit/test_skill_guards.py @@ -205,6 +205,7 @@ "keep polling on its hint, and never call the run stuck or failed from it.", "**When an address and another target are both in hand, ask which one is meant; never pick one yourself**", "**carry its `pipe_ref` through every call**", + "choosing by name and description and asking when several fit", "Not current is not run-ready", "Do not prepare inputs here.", "Never run a method that did not pass.",