-
Notifications
You must be signed in to change notification settings - Fork 7.8k
fix(tasks): require executable commands for governed operations in task bodies #2264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 6 commits
82e19e4
f677974
eecdec1
b957ccc
498251f
786ed21
6a4294f
b0db74f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,7 +25,7 @@ You **MUST** consider the user input before proceeding (if not empty). | |
| - If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation | ||
| - For each executable hook, output the following based on its `optional` flag: | ||
| - **Optional hook** (`optional: true`): | ||
| ``` | ||
| ```text | ||
| ## Extension Hooks | ||
|
|
||
| **Optional Pre-Hook**: {extension} | ||
|
|
@@ -36,7 +36,7 @@ You **MUST** consider the user input before proceeding (if not empty). | |
| To execute: `/{command}` | ||
| ``` | ||
| - **Mandatory hook** (`optional: false`): | ||
| ``` | ||
| ```text | ||
| ## Extension Hooks | ||
|
|
||
| **Automatic Pre-Hook**: {extension} | ||
|
Comment on lines
+41
to
44
|
||
|
|
@@ -142,10 +142,11 @@ You **MUST** consider the user input before proceeding (if not empty). | |
|
|
||
| 6. Execute implementation following the task plan: | ||
| - **Phase-by-phase execution**: Complete each phase before moving to the next | ||
| - **Respect dependencies**: Run sequential tasks in order, parallel tasks [P] can run together | ||
| - **Respect dependencies**: Run sequential tasks in order, parallel tasks [P] can run together | ||
| - **Follow TDD approach**: Execute test tasks before their corresponding implementation tasks | ||
| - **File-based coordination**: Tasks affecting the same files must run sequentially | ||
| - **Validation checkpoints**: Verify each phase completion before proceeding | ||
| - **Task-level re-read**: Before executing each individual task, re-read that task's entry from tasks.md to get its complete body. This ensures any embedded commands (e.g., governed operations with exact flags and env vars) are in active context even if the initial tasks.md load was compressed out during a long session. | ||
|
mnriem marked this conversation as resolved.
|
||
|
|
||
| 7. Implementation execution rules: | ||
| - **Setup first**: Initialize project structure, dependencies, configuration | ||
|
|
@@ -180,7 +181,7 @@ Note: This command assumes a complete task breakdown exists in tasks.md. If task | |
| - If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation | ||
| - For each executable hook, output the following based on its `optional` flag: | ||
| - **Optional hook** (`optional: true`): | ||
| ``` | ||
| ```text | ||
| ## Extension Hooks | ||
|
|
||
| **Optional Hook**: {extension} | ||
|
|
@@ -191,7 +192,7 @@ Note: This command assumes a complete task breakdown exists in tasks.md. If task | |
| To execute: `/{command}` | ||
| ``` | ||
| - **Mandatory hook** (`optional: false`): | ||
| ``` | ||
| ```text | ||
| ## Extension Hooks | ||
|
|
||
| **Automatic Hook**: {extension} | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -25,6 +25,7 @@ You **MUST** consider the user input before proceeding (if not empty). | |||||||||||||||||
| ## Pre-Execution Checks | ||||||||||||||||||
|
|
||||||||||||||||||
| **Check for extension hooks (before tasks generation)**: | ||||||||||||||||||
|
|
||||||||||||||||||
| - Check if `.specify/extensions.yml` exists in the project root. | ||||||||||||||||||
| - If it exists, read it and look for entries under the `hooks.before_tasks` key | ||||||||||||||||||
| - If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally | ||||||||||||||||||
|
|
@@ -34,7 +35,8 @@ You **MUST** consider the user input before proceeding (if not empty). | |||||||||||||||||
| - If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation | ||||||||||||||||||
| - For each executable hook, output the following based on its `optional` flag: | ||||||||||||||||||
| - **Optional hook** (`optional: true`): | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| ```text | ||||||||||||||||||
| ## Extension Hooks | ||||||||||||||||||
|
|
||||||||||||||||||
| **Optional Pre-Hook**: {extension} | ||||||||||||||||||
|
|
@@ -44,16 +46,19 @@ You **MUST** consider the user input before proceeding (if not empty). | |||||||||||||||||
| Prompt: {prompt} | ||||||||||||||||||
| To execute: `/{command}` | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| - **Mandatory hook** (`optional: false`): | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| ```text | ||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are you adding this in multiple places?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch — removed the duplicate from tasks-template.md Format Legend (commit 498251f). The generation rule in tasks.md is the single authoritative source; the legend entry was redundant. |
||||||||||||||||||
| ## Extension Hooks | ||||||||||||||||||
|
|
||||||||||||||||||
| **Automatic Pre-Hook**: {extension} | ||||||||||||||||||
| Executing: `/{command}` | ||||||||||||||||||
| EXECUTE_COMMAND: {command} | ||||||||||||||||||
|
|
||||||||||||||||||
| Wait for the result of the hook command before proceeding to the Outline. | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Outline | ||||||||||||||||||
|
|
@@ -106,7 +111,8 @@ You **MUST** consider the user input before proceeding (if not empty). | |||||||||||||||||
| - If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation | ||||||||||||||||||
| - For each executable hook, output the following based on its `optional` flag: | ||||||||||||||||||
| - **Optional hook** (`optional: true`): | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| ```text | ||||||||||||||||||
| ## Extension Hooks | ||||||||||||||||||
|
|
||||||||||||||||||
| **Optional Hook**: {extension} | ||||||||||||||||||
|
|
@@ -116,14 +122,17 @@ You **MUST** consider the user input before proceeding (if not empty). | |||||||||||||||||
| Prompt: {prompt} | ||||||||||||||||||
| To execute: `/{command}` | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| - **Mandatory hook** (`optional: false`): | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| ```text | ||||||||||||||||||
| ## Extension Hooks | ||||||||||||||||||
|
|
||||||||||||||||||
| **Automatic Hook**: {extension} | ||||||||||||||||||
| Executing: `/{command}` | ||||||||||||||||||
| EXECUTE_COMMAND: {command} | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently | ||||||||||||||||||
|
|
||||||||||||||||||
| Context for task generation: {ARGS} | ||||||||||||||||||
|
|
@@ -163,10 +172,31 @@ Every task MUST strictly follow this format: | |||||||||||||||||
| - ✅ CORRECT: `- [ ] T005 [P] Implement authentication middleware in src/middleware/auth.py` | ||||||||||||||||||
| - ✅ CORRECT: `- [ ] T012 [P] [US1] Create User model in src/models/user.py` | ||||||||||||||||||
| - ✅ CORRECT: `- [ ] T014 [US1] Implement UserService in src/services/user_service.py` | ||||||||||||||||||
| - ✅ CORRECT (governed): ``- [ ] T008 Push packages to NuGet feed: `dotnet nuget push "*.nupkg" --api-key $NUGET_API_KEY --source $NUGET_FEED_URL```` | ||||||||||||||||||
| - ❌ WRONG: `- [ ] Create User model` (missing ID and Story label) | ||||||||||||||||||
| - ❌ WRONG: `T001 [US1] Create model` (missing checkbox) | ||||||||||||||||||
| - ❌ WRONG: `- [ ] [US1] Create User model` (missing Task ID) | ||||||||||||||||||
| - ❌ WRONG: `- [ ] T001 [US1] Create model` (missing file path) | ||||||||||||||||||
| - ❌ WRONG (governed): `- [ ] T008 Push packages to NuGet feed` (prose only — omits executable command for a governed operation) | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Governed Operations (REQUIRED) | ||||||||||||||||||
|
|
||||||||||||||||||
| A **governed operation** is any operation the project constitution defines with specific command syntax, required flags, or environment variable references (for example: a package publish step, a deployment command, a signed git tag). | ||||||||||||||||||
|
|
||||||||||||||||||
| When a task covers a governed operation, its description MUST include the exact executable command from the constitution, parameterized with environment variable names rather than literal credential values. Do not paraphrase the command. | ||||||||||||||||||
|
|
||||||||||||||||||
| ```text | ||||||||||||||||||
| - [ ] [TaskID] [P?] [Story?] Description: `<exact-command --flag $ENV_VAR>` | ||||||||||||||||||
|
||||||||||||||||||
| When a task covers a governed operation, its description MUST include the exact executable command from the constitution, parameterized with environment variable names rather than literal credential values. Do not paraphrase the command. | |
| ```text | |
| - [ ] [TaskID] [P?] [Story?] Description: `<exact-command --flag $ENV_VAR>` | |
| When a task covers a governed operation, it MUST still include the required file path from the standard task format, and its description MUST include the exact executable command from the constitution, parameterized with environment variable names rather than literal credential values. Do not paraphrase the command. | |
| ```text | |
| - [ ] [TaskID] [P?] [Story?] path/to/file.ext Description: `<exact-command --flag $ENV_VAR>` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Markdownlint MD031 is enabled (default rules) and requires fenced code blocks to be surrounded by blank lines. This optional-hook fence is immediately after the list item line; add a blank line before the fence (and keep indentation) to satisfy MD031 consistently with the other command templates.
This issue also appears in the following locations of the same file: