Compare commits

...
Author SHA1 Message Date
Matt PocockandClaude Opus 5 50777fcc09 feat: graduate wait-what into the productivity bucket
Moves the skill out of in-progress/ and ships it: bucket README,
top-level README, plugin.json, an ask-matt router entry, and a docs
page at docs/productivity/wait-what.md.

Productivity rather than engineering — it fires in any conversation
with an agent, code or not. The CONTEXT.md clause is an opportunistic
hook, not a prerequisite.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 11:11:54 +01:00
Matt PocockandClaude Opus 5 006ca0546b refactor: loosen wait-what's re-pitch scope to a bare demonstrative
"Re-pitch that last message" pinned the correction to one message.
"Re-pitch that" leaves the agent to judge how much of what it said
failed to land — and is shorter.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 11:07:06 +01:00
Matt PocockandClaude Opus 5 355fa7420b feat: add wait-what, the verbosity fire extinguisher
A three-line, user-invoked skill in in-progress/. Fire it when the
agent's last message doesn't land; it re-pitches that message with
the missing context, in ASD-STE100 Simplified Technical English,
using the ubiquitous language from CONTEXT.md.

The name is the mechanism. Concision skills fail by growing, so this
one is a single precise leading word and nothing else.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 10:57:02 +01:00
Matt Pocock f958fa17c1 Merge pull request #749 from mattpocock/worktree-t1-install-story
docs: tell one true install story (official marketplace)
2026-08-05 10:19:06 +01:00
Matt Pocock 3e18e04260 Merge pull request #750 from mattpocock/worktree-phase-boundaries
feat: give ask-matt the phase boundary decision tree
2026-08-05 10:18:12 +01:00
Matt PocockandClaude Opus 5 4f6e25d91e docs: shrink the CLAUDE.md change to the pointer that earns it
CLAUDE.md is always-loaded, so every word costs on every turn. The
edit had grown it by ~65 words, nearly all of which paid load without
changing behaviour:

- The official-marketplace sentence was exposition — a fact the
  pointer target already carries.
- "Never reword an install command" steered by prohibition, which
  makes the banned behaviour more available, not less.
- The fallback rationale was a third copy of what install-block.md
  owns.
- The paragraph split doubled the surface with no branch behind it.

What remains is the one line that does work — the context pointer,
front-loaded on its trigger — leaving CLAUDE.md 10 words longer than
before rather than 65.

Refs mattpocock/personal-wiki#250

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 10:15:18 +01:00
Matt PocockandClaude Opus 5 ad98b80dbd docs: sharpen the canonical install block after review
- install-block.md: state the invariant as a requirement rather than
  as already-true (docs/ is brought into line downstream); mark all
  three canonical snippets, not just the Claude Code one; pin the
  `skills@latest` spelling; restore the `setup-matt-pocock-skills`
  instruction the whole-set form carries; cite the docs source for
  the auto-update claim.
- writing-docs.md: say plainly that the template's Quickstart is the
  older wording, so the file no longer contradicts itself.
- CLAUDE.md: split the paragraph, stop restating the fallback rationale.
- ADR 0002: record what was actually verified, on which version, and
  the two things that were not — the pinned sha in the official
  listing, and the in-session slash command.

Refs mattpocock/personal-wiki#250

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 10:00:45 +01:00
Matt PocockandClaude Opus 5 c474642895 docs: tell one true install story (official marketplace)
mattpocock-skills is now listed in Claude Code's official marketplace,
so the own-marketplace route is superseded. The queued changeset still
documented it, and changeset bodies ship verbatim into CHANGELOG.md —
the release would have published a superseded install route as its
headline.

- Rewrite .changeset/ship-as-claude-plugin.md around
  `claude plugins install mattpocock-skills`.
- Add .agents/install-block.md as the single source for install
  wording, so the docs pass has one true thing to copy.
- Point .agents/writing-docs.md and CLAUDE.md at it.
- Note the official listing in ADR 0002, and record that it reads
  plugin.json directly and does not depend on marketplace.json.

.claude-plugin/marketplace.json is kept as a fallback for direct-repo
installs; nothing in CI or scripts references it.

Refs mattpocock/personal-wiki#250

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 09:57:57 +01:00
13 changed files with 162 additions and 6 deletions
@@ -26,3 +26,16 @@ The only robust ways to give Codex a single promoted-only path are (a) **restruc
- Every promoted skill has an entry in `.claude-plugin/plugin.json`'s `skills` array (this already stood as a `CLAUDE.md` rule; it now also gates the plugin's contents). - Every promoted skill has an entry in `.claude-plugin/plugin.json`'s `skills` array (this already stood as a `CLAUDE.md` rule; it now also gates the plugin's contents).
- `.claude-plugin/plugin.json`'s `version` tracks `package.json`'s version — bump both together on release. Claude uses the plugin `version` to decide when installed users see an update. - `.claude-plugin/plugin.json`'s `version` tracks `package.json`'s version — bump both together on release. Claude uses the plugin `version` to decide when installed users see an update.
## Update, 2026-08-05
`mattpocock-skills` was accepted into **Claude Code's official marketplace** — configured name `claude-plugins-official`, source repo `anthropics/claude-plugins-official` — which every Claude Code install has by default. `claude plugins install mattpocock-skills` is now the documented route, and the `marketplace add``install` path above is superseded. The install wording lives in [.agents/install-block.md](../install-block.md).
The official listing points at this repo's git URL and reads `.claude-plugin/plugin.json` directly, so it does not depend on `.claude-plugin/marketplace.json`. That file is retained only as a fallback for installing the repo directly (an unreleased commit, or a fork).
Verified 2026-08-05, on Claude Code 2.1.222, against the live listing:
- `claude plugins install mattpocock-skills` resolves with no marketplace added first, and reports `mattpocock-skills@claude-plugins-official`.
- `claude plugin details mattpocock-skills` then reports version 1.2.0 and loads the promoted skills.
- The listing's `source` is `{"source": "url", "url": "https://github.com/mattpocock/skills.git", "sha": …}` — the **sha is pinned**, so a release reaches installed users when that pin moves, not the moment we tag. At the time of writing the pin sits two commits behind `main`, which is why it lists 22 skills rather than the 24 in `plugin.json`.
- The in-session `/plugin install mattpocock-skills` was **not** exercised — `/plugin` is unavailable in headless (`claude -p`) sessions. It runs the same resolver as the CLI, and the documented example form is `/plugin install <name>@claude-plugins-official`.
+61
View File
@@ -0,0 +1,61 @@
# The canonical install block
One install story, one wording. `README.md`, `.changeset/*`, and every page under `docs/` must say **this** and nothing else. Change it here first, then propagate.
`mattpocock-skills` is listed in **Claude Code's official marketplace** — configured name `claude-plugins-official`, source repo `anthropics/claude-plugins-official` — which every Claude Code install has out of the box. There is no marketplace to add first. Official Anthropic marketplaces have auto-update enabled by default ([discover-plugins](https://code.claude.com/docs/en/discover-plugins)), so "updates arrive automatically" is a true claim, not a hope.
## Claude Code — the plugin
<canonical-block name="claude-code">
```bash
claude plugins install mattpocock-skills
```
Or, from inside a session:
```
/plugin install mattpocock-skills
```
It's in Claude Code's official marketplace, so there's nothing to add first, and updates arrive automatically.
</canonical-block>
## Codex, and other agents — skills.sh
The plugin is Claude Code only. Everywhere else, [skills.sh](https://skills.sh/mattpocock/skills) copies editable skill files into the project. Use the whole-set form on `README.md`:
<canonical-block name="skills-sh-whole-set">
```bash
npx skills@latest add mattpocock/skills
```
Pick the skills you want, and which coding agents to install them on. **The installer lets you choose which skills to take — make sure `setup-matt-pocock-skills` is one of them.**
</canonical-block>
…and the single-skill form on a `docs/` page, where the page already names one skill:
<canonical-block name="skills-sh-one-skill">
```bash
npx skills@latest add mattpocock/skills --skill=<name>
```
```bash
npx skills@latest update <name>
```
</canonical-block>
`skills@latest` is the pinned spelling in all three. The Quickstart template in [writing-docs.md](./writing-docs.md), and the 24 pages under `docs/`, still carry the older bare `npx skills …`; the docs pass brings them into line.
## The two routes are exclusive
The plugin is a managed, read-only bundle you subscribe to. skills.sh writes files you own and edit. Installing both leaves the user with every skill twice — always say "pick one".
## Not the install story
`.claude-plugin/marketplace.json` makes the repo its own single-plugin marketplace (`/plugin marketplace add mattpocock/skills`, then `/plugin install mattpocock-skills@mattpocock`). The official listing supersedes it. It is kept as a fallback for installing the repo directly — an unreleased commit, or a fork — and is **not** documented to users.
+2
View File
@@ -14,6 +14,8 @@ There is no H1 — the published page takes its title from the slug.
Fill the template below. The **fixed frame** (Quickstart block, source link, `## What it does`, `## When to reach for it`, `## Where it fits`) appears on every page. The **adaptable middle**`## Prerequisites` and the free-form substance sections — carries only what this particular skill earns; delete the rest. Fill the template below. The **fixed frame** (Quickstart block, source link, `## What it does`, `## When to reach for it`, `## Where it fits`) appears on every page. The **adaptable middle**`## Prerequisites` and the free-form substance sections — carries only what this particular skill earns; delete the rest.
Install commands are not written per page. Copy them verbatim from [the canonical install block](./install-block.md) — it is the single source for how anyone installs these skills, and a page that words it differently is a page that tells a second story. The Quickstart block in the template below is the older wording and does not yet match; the docs pass replaces it from the canonical block.
<page-template> <page-template>
Quickstart: Quickstart:
+12 -5
View File
@@ -2,11 +2,18 @@
"mattpocock-skills": minor "mattpocock-skills": minor
--- ---
Ship the skill set as a native **Claude Code plugin**. The repo is now its own single-plugin marketplace, so you can subscribe to the promoted skills as a managed, read-only bundle instead of copying editable files: Ship the skill set as a native **Claude Code plugin**, listed in Claude Code's official marketplace. You can now subscribe to the promoted skills as a managed, read-only bundle instead of copying editable files:
``` ```bash
/plugin marketplace add mattpocock/skills claude plugins install mattpocock-skills
/plugin install mattpocock-skills@mattpocock
``` ```
`.claude-plugin/plugin.json` gains full marketplace metadata (version, description, author, license, keywords) and a sibling `.claude-plugin/marketplace.json` lists the plugin. `skills.sh` remains the universal installer (and the path for Codex and other harnesses today); a native Codex plugin is deferred — see `.agents/adr/0002-ship-as-a-claude-code-plugin.md` for why. Or, from inside a session:
```
/plugin install mattpocock-skills
```
There is no marketplace to add first — the official marketplace is configured by default.
`.claude-plugin/plugin.json` carries the full plugin metadata (version, description, author, license, keywords) and the explicit list of promoted skills. `skills.sh` remains the universal installer (and the path for Codex and other harnesses today); a native Codex plugin is deferred — see `.agents/adr/0002-ship-as-a-claude-code-plugin.md` for why.
+9
View File
@@ -0,0 +1,9 @@
---
"mattpocock-skills": minor
---
Add **`wait-what`** — a fire extinguisher for model verbosity. Fire it the moment a message doesn't land, and the agent re-pitches it: a little context, ASD-STE100 Simplified Technical English, and the ubiquitous language from your `CONTEXT.md`. User-invoked, three lines long.
The mechanism is the name. Concision skills fail by growing — a 400-line skill still leaves the model verbose — so this one is a single precise leading word and nothing else. Names that describe the *output* (`/tldr`, `/no-fluff`) make the model clip words and lose you further; naming the *listener's* state asks for both halves at once, fewer words **and** the context you were missing. It also reuses the leading words already in your global `CLAUDE.md`, so the skill, `CLAUDE.md` and every `CONTEXT.md` reach for the same tokens.
It's the extinguisher, not the sprinkler. The cure for jargon is a shared language built upfront with `/grill-with-docs`; this is the in-the-moment corrective for when you don't have one yet.
+1
View File
@@ -42,6 +42,7 @@
"./skills/productivity/handoff", "./skills/productivity/handoff",
"./skills/productivity/teach", "./skills/productivity/teach",
"./skills/productivity/to-questionnaire", "./skills/productivity/to-questionnaire",
"./skills/productivity/wait-what",
"./skills/productivity/writing-for-agents" "./skills/productivity/writing-for-agents"
] ]
} }
+1 -1
View File
@@ -9,7 +9,7 @@ Skills are organized into bucket folders under `skills/`:
Every skill in `engineering/` or `productivity/` (the **promoted** buckets) must have a reference in the top-level `README.md` and an entry in `.claude-plugin/plugin.json`'s `skills` array (the Claude Code plugin ships exactly the promoted set). Skills in `misc/`, `personal/`, `in-progress/`, and `deprecated/` must not appear in either. Every skill in `engineering/` or `productivity/` (the **promoted** buckets) must have a reference in the top-level `README.md` and an entry in `.claude-plugin/plugin.json`'s `skills` array (the Claude Code plugin ships exactly the promoted set). Skills in `misc/`, `personal/`, `in-progress/`, and `deprecated/` must not appear in either.
The repo is also its own single-plugin Claude Code marketplace: `.claude-plugin/marketplace.json` lists the one `mattpocock-skills` plugin. When bumping the release version, keep `.claude-plugin/plugin.json`'s `version` in sync with `package.json`'s — Claude uses the plugin `version` to decide when installed users see an update. Run `claude plugin validate . --strict` after touching either manifest. Why a Claude plugin but not (yet) a Codex one lives in [.agents/adr/0002-ship-as-a-claude-code-plugin.md](./.agents/adr/0002-ship-as-a-claude-code-plugin.md). Install commands are copied verbatim from [.agents/install-block.md](./.agents/install-block.md). `.claude-plugin/marketplace.json` makes the repo its own single-plugin marketplace — a fallback the install block explains, not the documented route. When bumping the release version, keep `.claude-plugin/plugin.json`'s `version` in sync with `package.json`'s — Claude uses the plugin `version` to decide when installed users see an update. Run `claude plugin validate . --strict` after touching either manifest. Why a Claude plugin but not (yet) a Codex one lives in [.agents/adr/0002-ship-as-a-claude-code-plugin.md](./.agents/adr/0002-ship-as-a-claude-code-plugin.md).
Each skill entry in the top-level `README.md` must link the skill name to its `SKILL.md`. Each skill entry in the top-level `README.md` must link the skill name to its `SKILL.md`.
+1
View File
@@ -223,6 +223,7 @@ General workflow tools, not code-specific.
- **[handoff](./skills/productivity/handoff/SKILL.md)** — Compact the current conversation into a handoff document so another agent can continue the work. - **[handoff](./skills/productivity/handoff/SKILL.md)** — Compact the current conversation into a handoff document so another agent can continue the work.
- **[teach](./skills/productivity/teach/SKILL.md)** — Teach the user a new skill or concept over multiple sessions, using the current directory as a stateful teaching workspace. - **[teach](./skills/productivity/teach/SKILL.md)** — Teach the user a new skill or concept over multiple sessions, using the current directory as a stateful teaching workspace.
- **[to-questionnaire](./skills/productivity/to-questionnaire/SKILL.md)** — Turn a decision you can't answer alone into a Markdown questionnaire for the one person who can — filled in async, or together over a meeting. It grills you about the send (who it's for, what you need back), not the subject. - **[to-questionnaire](./skills/productivity/to-questionnaire/SKILL.md)** — Turn a decision you can't answer alone into a Markdown questionnaire for the one person who can — filled in async, or together over a meeting. It grills you about the send (who it's for, what you need back), not the subject.
- **[wait-what](./skills/productivity/wait-what/SKILL.md)** — Fire this the moment a message doesn't land. The agent re-pitches it with the context you're missing, in plain English, using your `CONTEXT.md` vocabulary.
- **[writing-for-agents](./skills/productivity/writing-for-agents/SKILL.md)** — Writing documents for agents: skills, AGENTS.md/CLAUDE.md, and any doc an agent reaches by a pointer. - **[writing-for-agents](./skills/productivity/writing-for-agents/SKILL.md)** — Writing documents for agents: skills, AGENTS.md/CLAUDE.md, and any doc an agent reaches by a pointer.
**Model-invoked** **Model-invoked**
+48
View File
@@ -0,0 +1,48 @@
Quickstart:
```bash
npx skills@latest add mattpocock/skills --skill=wait-what
```
```bash
npx skills@latest update wait-what
```
[Source](https://github.com/mattpocock/skills/tree/main/skills/productivity/wait-what)
## What it does
`wait-what` is the fire extinguisher for a message that didn't land. You fire it the moment you lose the thread, and the agent re-pitches what it just said: a little of the context you were missing, plain English, and the vocabulary from your project's `CONTEXT.md`.
It is three lines long, and that is the design rather than an unfinished draft. Skills that fight verbosity fail by growing — a four-hundred-line concision skill still leaves the model verbose, because the model reads the volume, not the plea. This one carries a single precise leading word and nothing else.
## When to reach for it
You invoke this by typing `/wait-what` — the agent won't reach for it on its own, and it shouldn't: only you know when you stopped following.
Reach for it the second you notice you're skimming — the agent has drifted into jargon it invented, stacked five acronyms, or explained a decision whose premise you never saw. It's a one-shot corrective on the conversation you're already in. To stop the jargon arriving in the first place, use [grill-with-docs](https://aihero.dev/skills-grill-with-docs) instead, which builds the shared language upfront.
## The name is the mechanism
The leading word is **wait**. Not "be concise" — an instruction about the agent's output, which the model satisfies by clipping words and losing you further. **Wait** is about *your* state: it says comprehension failed here. An agent that hears "be brief" writes telegrams. An agent that hears "wait, you lost me" backs up and explains.
That distinction is the whole skill. Every popular fix for verbosity — `/tldr`, `/no-fluff`, `/talk-normal` — names the *output*, so the model over-corrects into a caveman register that's shorter and no clearer. Naming the *listener* asks for both halves at once: fewer words **and** the context you were missing.
The re-pitch is deliberately vague about its own scope. It says re-pitch **that**, not "that last message", because what lost you is usually bigger than one paragraph — the agent decides how far back to go.
## It plugs into the language you already have
The body reuses the leading words already sitting in your global `CLAUDE.md` and your project's `CONTEXT.md`: ASD-STE100 Simplified Technical English for the register, ubiquitous language for the nouns. Skill, `CLAUDE.md` and `CONTEXT.md` reach for the same tokens, so firing it isn't a new instruction — it's a reminder of one the agent already agreed to.
If you have no `CONTEXT.md`, it still works; you just lose the domain-vocabulary half.
## It's working if
- The re-pitch is **shorter and clearer**, not shorter and blunter.
- It adds the premise you were missing rather than just deleting words.
- Project nouns replace invented ones — the terms in your `CONTEXT.md` come back.
- You can fire it twice in a row without it degrading into terseness.
## Where it fits
`wait-what` is a reach-for-it-anytime standalone — it sits inside whatever conversation you're already having, in any skill, at any point. It's the extinguisher; [grill-with-docs](https://aihero.dev/skills-grill-with-docs) is the sprinkler system, because a shared language agreed upfront is the real cure for jargon, and [domain-modeling](https://aihero.dev/skills-domain-modeling) is what you reach for when the *words themselves* are the problem rather than one bad message. When you're unsure which skill fits the moment, [ask-matt](https://aihero.dev/skills-ask-matt) routes you.
+1
View File
@@ -79,6 +79,7 @@ Off the main flow entirely.
- **`/research`** — delegate reading legwork to a **background agent**: it investigates a question against **primary sources**, then leaves a cited Markdown file in the repo. Keep working while it reads. The file it produces is something to take *into* the main flow at `/grill-with-docs` — research feeds the thinking, it doesn't replace it. - **`/research`** — delegate reading legwork to a **background agent**: it investigates a question against **primary sources**, then leaves a cited Markdown file in the repo. Keep working while it reads. The file it produces is something to take *into* the main flow at `/grill-with-docs` — research feeds the thinking, it doesn't replace it.
- **`/to-questionnaire`** — when the thing blocking you isn't in your head or the codebase but in **someone else's**, this writes them a questionnaire to fill in. It's the inverse of `/grill-me`: instead of interviewing you about the subject, it interviews you about the **send** — who it's going to, what you need back — and aims the questions at the gap. What comes back is material for `/grill-with-docs` or `/to-spec`. - **`/to-questionnaire`** — when the thing blocking you isn't in your head or the codebase but in **someone else's**, this writes them a questionnaire to fill in. It's the inverse of `/grill-me`: instead of interviewing you about the subject, it interviews you about the **send** — who it's going to, what you need back — and aims the questions at the gap. What comes back is material for `/grill-with-docs` or `/to-spec`.
- **`/wizard`** — for the steps only a **human** can take: clicking through a third-party dashboard, running a one-off migration, moving the project from state A to state B. It generates an interactive bash script that opens each URL, captures each value, and writes it into `.env` and GitHub secrets — so the procedure stops being something you re-explain to an agent every time. If the agent could just do it itself, it should; reach for this only where a human is genuinely in the loop. - **`/wizard`** — for the steps only a **human** can take: clicking through a third-party dashboard, running a one-off migration, moving the project from state A to state B. It generates an interactive bash script that opens each URL, captures each value, and writes it into `.env` and GitHub secrets — so the procedure stops being something you re-explain to an agent every time. If the agent could just do it itself, it should; reach for this only where a human is genuinely in the loop.
- **`/wait-what`** — the fire extinguisher for a message that didn't land. Fire it mid-conversation, inside any other skill, and the agent re-pitches what it just said with the context you were missing, in plain English, using the `CONTEXT.md` vocabulary. It's the in-the-moment corrective; `/grill-with-docs` and `/domain-modeling` are the upfront cure, because a shared language agreed early is what stops the jargon arriving at all.
- **`/teach`** — learn a concept over multiple sessions, using the current directory as a stateful workspace. - **`/teach`** — learn a concept over multiple sessions, using the current directory as a stateful workspace.
- **`/writing-for-agents`** — reference for writing documents agents consume: skills, AGENTS.md, pointed-at docs. - **`/writing-for-agents`** — reference for writing documents agents consume: skills, AGENTS.md, pointed-at docs.
+1
View File
@@ -10,6 +10,7 @@ Reachable only when you type them (Claude Code: `disable-model-invocation: true`
- **[handoff](./handoff/SKILL.md)** — Compact the current conversation into a handoff document so another agent can continue the work. - **[handoff](./handoff/SKILL.md)** — Compact the current conversation into a handoff document so another agent can continue the work.
- **[teach](./teach/SKILL.md)** — Teach the user a new skill or concept over multiple sessions, using the current directory as a stateful teaching workspace. - **[teach](./teach/SKILL.md)** — Teach the user a new skill or concept over multiple sessions, using the current directory as a stateful teaching workspace.
- **[to-questionnaire](./to-questionnaire/SKILL.md)** — Turn a decision you can't answer alone into a Markdown questionnaire for the one person who can — filled in async, or together over a meeting. - **[to-questionnaire](./to-questionnaire/SKILL.md)** — Turn a decision you can't answer alone into a Markdown questionnaire for the one person who can — filled in async, or together over a meeting.
- **[wait-what](./wait-what/SKILL.md)** — Fire this the moment a message doesn't land. The agent re-pitches it with the context you're missing, in plain English, using your `CONTEXT.md` vocabulary.
- **[writing-for-agents](./writing-for-agents/SKILL.md)** — Writing documents for agents: skills, AGENTS.md/CLAUDE.md, and any doc an agent reaches by a pointer. - **[writing-for-agents](./writing-for-agents/SKILL.md)** — Writing documents for agents: skills, AGENTS.md/CLAUDE.md, and any doc an agent reaches by a pointer.
## Model-invoked ## Model-invoked
+7
View File
@@ -0,0 +1,7 @@
---
name: wait-what
description: Stop. That last message did not land — re-pitch it.
disable-model-invocation: true
---
Wait — I don't understand where you've got to here. Re-pitch that: give me a little bit of context, talk in ASD-STE100 Simplified Technical English, and use the ubiquitous language from `CONTEXT.md`.
@@ -0,0 +1,5 @@
interface:
display_name: "Wait What"
short_description: "Re-pitch that — simpler, with the context I'm missing"
policy:
allow_implicit_invocation: false