Skip to content

fix(tasks): require executable commands for governed operations in task bodies#2264

Open
ayeshakhalid192007-dev wants to merge 6 commits intogithub:mainfrom
ayeshakhalid192007-dev:fix/tasks-embed-governed-commands
Open

fix(tasks): require executable commands for governed operations in task bodies#2264
ayeshakhalid192007-dev wants to merge 6 commits intogithub:mainfrom
ayeshakhalid192007-dev:fix/tasks-embed-governed-commands

Conversation

@ayeshakhalid192007-dev
Copy link
Copy Markdown
Contributor

@ayeshakhalid192007-dev ayeshakhalid192007-dev commented Apr 17, 2026

Fixes #2219

Description

Tasks generated by /speckit.tasks describe governed operations in prose.
When the constitution is compacted out of context, the agent guesses the
command, gets flags wrong, and the operation fails (e.g. 403 on NuGet push).

Root Cause

Task Generation Rules had no requirement to embed the exact command for
operations the constitution defines with specific syntax, flags, or env vars.
Tasks are always in agent context — prose descriptions throw that away.

Solution

Require that any task covering a governed operation includes the exact
executable command, parameterized with env var names, directly in the task body.

Changes

  • templates/commands/tasks.md — new ### Governed Operations (REQUIRED) rule + examples; fix inline-code nesting in governed example (double-backtick outer span)
  • templates/commands/implement.md — adds task-level re-read instruction; fixes four bare fenced code blocks (MD040 info strings)
  • templates/commands/taskstoissues.md, tests/hooks/TESTING.md,
    workflows/ARCHITECTURE.md, workflows/README.md — pre-existing MD031/MD032/MD040 lint fixes

Why This Is Safe

Pure documentation change — no Python code, no CLI arguments, no new files.
Adds an instruction to an existing rule section; all existing task formats remain valid.

Testing

  • Run /speckit.tasks on a project with a governed push/deploy in the constitution — verify generated task body contains the exact command
  • ruff check src/ passes
  • markdownlint on changed files: 0 errors

@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 20, 2026

How does this solve the issue if the tasks.md itself gets truncated out of context?

@ayeshakhalid192007-dev
Copy link
Copy Markdown
Contributor Author

Good question — this is the key distinction: templates/commands/tasks.md is only read during /speckit.tasks generation, not during task execution.

The fix targets the generated output, not the template.

Here's the flow:

  1. Agent runs /speckit.tasks → constitution is in active context → template instructs the agent to read the constitution and embed exact governed commands into each task body.
  2. Later, when the agent executes a task, it reads the task body — which now contains the exact command (e.g., dotnet nuget push "*.nupkg" --api-key $NUGET_API_KEY --source $NUGET_FEED_URL).
  3. At execution time, the constitution and the template may both be gone — but the command is already embedded in the task itself, so the agent runs it correctly.

The template being truncated is irrelevant to execution: its job is done the moment the tasks are generated. The task body is what persists across sessions and late-context compression — and that's exactly where the command now lives.

@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 20, 2026

You misunderstood me. When you execute the implement command it will read the tasks.md file at the beginning and during the execution it can also lose the context of that. It is the nature of how the original SDD process as defined by Spec Kit operates. All implementation is done by the implement command and so if the tasks.md has a large number of tasks whatever was in context at the beginning can disappear just the same

@ayeshakhalid192007-dev
Copy link
Copy Markdown
Contributor Author

You're right that tasks.md can be compacted out during a long implement session. The distinction is: when the implement command re-reads a task from disk to execute it, the exact command is already in that task body — no cross-reference to the constitution is needed. Each task is now self-contained, so context compression of tasks.md doesn't cascade into a command-guessing failure at execution time.

- **Mandatory hook** (`optional: false`):
```

```text
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you adding this in multiple places?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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.

…nd fix context-loss gap

Remove governed-operation hint from tasks-template.md Format Legend; the
generation rule in tasks.md is the single authoritative source, so the legend
entry was redundant duplication.

Add Task-level re-read instruction to implement.md step 6: before executing
each task the agent re-reads that task's entry from tasks.md on disk. This
closes the gap the reviewer identified — the initial tasks.md load can be
compacted out of context during a long session, but a per-task re-read ensures
embedded governed commands are always in active context at execution time.
@ayeshakhalid192007-dev
Copy link
Copy Markdown
Contributor Author

Two changes in commit 498251f:

  1. Duplicate note removed — the governed-operation line in tasks-template.md Format Legend is gone. tasks.md is the single authoritative source for how tasks are generated.

  2. Context-loss gap closed — you are right that the initial read of tasks.md in implement.md can be compacted out during a long session. Added a Task-level re-read bullet to step 6 of implement.md: before executing each individual task, the agent re-reads that task's entry from tasks.md on disk. This means the embedded command is always fresh in active context at execution time, regardless of what got compressed earlier in the session.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the /speckit.tasks (and related) documentation/templates to require that tasks for constitution-governed operations include the exact executable command (with env var placeholders), reducing agent “guessing” when constitution context is no longer present.

Changes:

  • Add a new Governed Operations (REQUIRED) rule to the tasks command template, including examples.
  • Update the implement command template to encourage re-reading each task entry before execution (to keep embedded commands in context).
  • Apply markdownlint-driven formatting fixes across several markdown docs (e.g., fenced code block info strings and spacing).
Show a summary per file
File Description
workflows/README.md Adds fenced code language (text) for markdownlint compliance.
workflows/ARCHITECTURE.md Adds fenced code language (text) for markdownlint compliance.
tests/hooks/TESTING.md Removes trailing whitespace in expected behavior header.
templates/commands/taskstoissues.md Adds blank lines + text info strings to fenced blocks; normalizes list formatting.
templates/commands/tasks.md Introduces governed-operations requirement; normalizes fenced block formatting.
templates/commands/implement.md Adds task-level re-read instruction; minor whitespace normalization.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 5/6 changed files
  • Comments generated: 3

Comment thread templates/commands/tasks.md Outdated
Comment thread templates/commands/implement.md
Comment thread templates/commands/tasks.md
@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 21, 2026

Please address Copilot feedback

- Fix escaped-backtick rendering bug in governed example (tasks.md:175):
  use double-backtick outer span so inner backtick displays correctly
- Add missing info strings (text) to four bare fenced code blocks in
  implement.md (MD040 compliance) - pre-hook and post-hook sections
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 5/6 changed files
  • Comments generated: 2

Comment on lines +186 to +189
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>`
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new governed-operations guidance conflicts with the earlier "Description with file path" requirement: both the governed example and the governed format snippet omit a file path entirely. Either update the governed examples/snippet to include a file path (while still embedding the exact executable command), or explicitly document that certain governed-operation tasks are exempt from the file-path requirement so agents don’t get contradictory instructions.

Suggested change
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>`

Copilot uses AI. Check for mistakes.
Comment on lines +39 to 42
```text
## Extension Hooks

**Automatic Pre-Hook**: {extension}
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this fenced text example, there is a whitespace-only line after EXECUTE_COMMAND: {command} (within the same block) that contains trailing spaces. With markdownlint default rules (MD009) enabled, that can cause a lint failure; make the line truly empty (no spaces) or remove it.

See below for a potential fix:


Copilot uses AI. Check for mistakes.
@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 21, 2026

Please address Copilot feedback. If not applicable, please explain why

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Agent loses constitution context mid-execution and falls back to guessing

3 participants