From bb37b180d636bb3875acc2080dc94da8080b8600 Mon Sep 17 00:00:00 2001 From: Quratulain-bilal Date: Thu, 25 Jun 2026 17:48:23 +0500 Subject: [PATCH] fix(extensions): tell agent to run mandatory hooks, not just emit the directive (#2901) In agent-direct invocations nothing watches agent output for the EXECUTE_COMMAND: directive, so a mandatory hook that is only emitted never runs and the failure is silent (#2730). Add one line after each mandatory-hook block instructing the agent to actually invoke the hook and wait for it before continuing. The instruction tells the agent to run the hook the way it would run the command itself in the current agent/session, and notes the invocation may differ from the literal {command} id shown in the block (e.g. skills-mode agents run it as /skill:speckit-... or $speckit-...), so it stays correct outside the default slash-command form. Fixes #2730 --- templates/commands/analyze.md | 2 ++ templates/commands/checklist.md | 2 ++ templates/commands/clarify.md | 2 ++ templates/commands/constitution.md | 2 ++ templates/commands/converge.md | 2 ++ templates/commands/implement.md | 2 ++ templates/commands/plan.md | 2 ++ templates/commands/specify.md | 2 ++ templates/commands/tasks.md | 2 ++ templates/commands/taskstoissues.md | 2 ++ 10 files changed, 20 insertions(+) diff --git a/templates/commands/analyze.md b/templates/commands/analyze.md index 5b521cf2a..e4ba8f7d8 100644 --- a/templates/commands/analyze.md +++ b/templates/commands/analyze.md @@ -45,6 +45,7 @@ You **MUST** consider the user input before proceeding (if not empty). Wait for the result of the hook command before proceeding to the Goal. ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently ## Goal @@ -228,6 +229,7 @@ After reporting, check if `.specify/extensions.yml` exists in the project root. Executing: `/{command}` EXECUTE_COMMAND: {command} ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently ## Operating Principles diff --git a/templates/commands/checklist.md b/templates/commands/checklist.md index 2e1b1040a..e202ebb66 100644 --- a/templates/commands/checklist.md +++ b/templates/commands/checklist.md @@ -66,6 +66,7 @@ You **MUST** consider the user input before proceeding (if not empty). Wait for the result of the hook command before proceeding to the Execution Steps. ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently ## Execution Steps @@ -363,4 +364,5 @@ Check if `.specify/extensions.yml` exists in the project root. Executing: `/{command}` EXECUTE_COMMAND: {command} ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently diff --git a/templates/commands/clarify.md b/templates/commands/clarify.md index a83d52f02..4948fdcfa 100644 --- a/templates/commands/clarify.md +++ b/templates/commands/clarify.md @@ -49,6 +49,7 @@ You **MUST** consider the user input before proceeding (if not empty). Wait for the result of the hook command before proceeding to the Outline. ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently ## Outline @@ -251,6 +252,7 @@ Check if `.specify/extensions.yml` exists in the project root. Executing: `/{command}` EXECUTE_COMMAND: {command} ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - **Optional hook** (`optional: true`): ``` ## Extension Hooks diff --git a/templates/commands/constitution.md b/templates/commands/constitution.md index 29ae9a09e..d003d5c9b 100644 --- a/templates/commands/constitution.md +++ b/templates/commands/constitution.md @@ -46,6 +46,7 @@ You **MUST** consider the user input before proceeding (if not empty). Wait for the result of the hook command before proceeding to the Outline. ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently ## Outline @@ -147,4 +148,5 @@ Check if `.specify/extensions.yml` exists in the project root. Executing: `/{command}` EXECUTE_COMMAND: {command} ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently diff --git a/templates/commands/converge.md b/templates/commands/converge.md index 3d366e1d3..35cf3736c 100644 --- a/templates/commands/converge.md +++ b/templates/commands/converge.md @@ -49,6 +49,7 @@ You **MUST** consider the user input before proceeding (if not empty). Wait for the result of the hook command before proceeding to the Goal. ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently @@ -266,5 +267,6 @@ After producing the result, check if `.specify/extensions.yml` exists in the pro Executing: `/{command}` EXECUTE_COMMAND: {command} ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently diff --git a/templates/commands/implement.md b/templates/commands/implement.md index c416fa738..eda580d56 100644 --- a/templates/commands/implement.md +++ b/templates/commands/implement.md @@ -45,6 +45,7 @@ You **MUST** consider the user input before proceeding (if not empty). Wait for the result of the hook command before proceeding to the Outline. ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently ## Outline @@ -192,6 +193,7 @@ Check if `.specify/extensions.yml` exists in the project root. Executing: `/{command}` EXECUTE_COMMAND: {command} ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - **Optional hook** (`optional: true`): ``` ## Extension Hooks diff --git a/templates/commands/plan.md b/templates/commands/plan.md index 44ab8403a..8e00e3ef9 100644 --- a/templates/commands/plan.md +++ b/templates/commands/plan.md @@ -53,6 +53,7 @@ You **MUST** consider the user input before proceeding (if not empty). Wait for the result of the hook command before proceeding to the Outline. ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently ## Outline @@ -91,6 +92,7 @@ Check if `.specify/extensions.yml` exists in the project root. Executing: `/{command}` EXECUTE_COMMAND: {command} ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - **Optional hook** (`optional: true`): ``` ## Extension Hooks diff --git a/templates/commands/specify.md b/templates/commands/specify.md index 4558b922a..09a584e0e 100644 --- a/templates/commands/specify.md +++ b/templates/commands/specify.md @@ -50,6 +50,7 @@ You **MUST** consider the user input before proceeding (if not empty). Wait for the result of the hook command before proceeding to the Outline. ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently ## Outline @@ -253,6 +254,7 @@ Check if `.specify/extensions.yml` exists in the project root. Executing: `/{command}` EXECUTE_COMMAND: {command} ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - **Optional hook** (`optional: true`): ``` ## Extension Hooks diff --git a/templates/commands/tasks.md b/templates/commands/tasks.md index f863e7787..4d3e45a7c 100644 --- a/templates/commands/tasks.md +++ b/templates/commands/tasks.md @@ -54,6 +54,7 @@ You **MUST** consider the user input before proceeding (if not empty). Wait for the result of the hook command before proceeding to the Outline. ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently ## Outline @@ -111,6 +112,7 @@ Check if `.specify/extensions.yml` exists in the project root. Executing: `/{command}` EXECUTE_COMMAND: {command} ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - **Optional hook** (`optional: true`): ``` ## Extension Hooks diff --git a/templates/commands/taskstoissues.md b/templates/commands/taskstoissues.md index b3093baa0..f1df10001 100644 --- a/templates/commands/taskstoissues.md +++ b/templates/commands/taskstoissues.md @@ -46,6 +46,7 @@ You **MUST** consider the user input before proceeding (if not empty). Wait for the result of the hook command before proceeding to the Outline. ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently ## Outline @@ -100,4 +101,5 @@ Check if `.specify/extensions.yml` exists in the project root. Executing: `/{command}` EXECUTE_COMMAND: {command} ``` + After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook. - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently