mirror of
https://github.com/github/spec-kit.git
synced 2026-07-03 20:36:23 +08:00
* feat(extensions): add bundled bug triage workflow extension (#2870) Add a bundled 'bug' extension providing a three-stage bug triage workflow: - speckit.bug.assess: triage a bug report (pasted text or URL), locate suspected code paths, and propose a remediation - speckit.bug.fix: apply the proposed remediation and record what changed - speckit.bug.test: validate the fix and record the verification result Each bug gets its own directory under .specify/bugs/<slug>/ with one Markdown report per stage (assessment.md, fix.md, test.md). The slug is the only handle the three commands share; existing bug directories are never overwritten. Mirrors the layout of the existing bundled extensions (git, agent-context): - extensions/bug/extension.yml, README.md, commands/ - extensions/catalog.json: register 'bug' (alphabetical, between agent-context and git) - pyproject.toml: add wheel mapping to specify_cli/core_pack/extensions/bug Closes #2870 * address Copilot review on #2871 - speckit.bug.assess.md: drop POSIX-specific 'mkdir -p' example; reword the prerequisite to describe the requirement (ensure BUG_DIR exists) without assuming a specific shell. - speckit.bug.fix.md: fix the slug-resolution fallback wording. It listed '.specify/bugs/*/assessment.md' but then keyed off whether 'exactly one bug directory' existed; now it correctly keys off whether exactly one matching 'assessment.md' was found and uses the slug from its parent directory. - tests/extensions/bug/test_bug_extension.py: add a smoke test analogous to the agent-context extension's coverage. Validates the bundled layout, catalog registration, '_locate_bundled_extension("bug")' resolution, and that 'ExtensionManager.install_from_directory' installs the three commands. All 333 tests in tests/extensions/, tests/test_extensions.py, and tests/test_extension_registration.py pass. * address Copilot review on #2871 (round 2) - Import _locate_bundled_extension from the public 'specify_cli' package (it is re-exported in __init__.py) instead of the private 'specify_cli._assets' module, so the test does not depend on internal module layout. - Clarify module docstring: install_from_directory is called with register_commands=False, so commands are copied and recorded in the installed manifest but not registered with AI agents. Wording updated to avoid implying otherwise. * address Copilot review on #2871 (round 3) - tests/extensions/bug/test_bug_extension.py: read extension.yml as UTF-8 explicitly to avoid platform-dependent default encoding (notably on Windows). Matches how the README is read in the same module. - extensions/bug/commands/speckit.bug.assess.md: add a 'Safety When Fetching URLs' section. Instructs the agent to treat fetched page content as untrusted input (no obeying embedded prompt-injection directives), forbids supplying credentials/secrets that a page asks for, scopes the fetch to the URL the user provided (no following redirects to other resources), and requires suspicious content to be quoted verbatim under an 'Unverified' heading rather than acted on. - extensions/catalog.json: bump 'updated_at' to today (2026-06-05) so consumers that cache by this field invalidate when 'bug' is added. - extensions/bug/README.md: minor grammar fix ('a reproduction that was not actually performed'). All 251 tests in tests/extensions/bug/, tests/test_extensions.py, and tests/test_extension_registration.py pass. * speckit.bug.assess: add URL Trust Policy for fetched bug-report URLs Builds on the 'Safety When Fetching URLs' section by adding a tiered classification rule the agent applies before any fetch: 1. Refuse outright (no fetch, no prompt) for non-http(s) schemes, loopback, link-local, RFC1918 private space, and known cloud instance-metadata endpoints (169.254.169.254, metadata.google.internal, 100.100.100.200, metadata.azure.com). This closes the SSRF / internal-recon vector opened by 'paste any URL'. 2. Fetch silently for an explicit allowlist of widely-used public bug-report sources (github, gitlab, bitbucket, atlassian.net, linear, stackoverflow/stackexchange, sentry). This preserves the paste-a-URL ergonomics the workflow is built for. 3. Otherwise prompt once in interactive mode (default 'no', naming the resolved host explicitly); in automated mode skip the fetch and record '[UNVERIFIED - fetch skipped: host not on safe list: <host>]' in assessment.md so a human can decide later. In every case, assessment.md records the verbatim URL, the resolved host, and which branch of the policy was taken (allowlisted / confirmed-by-user / auto-refused: <reason>) so the per-bug directory's audit trail is complete. Preflight HEAD probes are explicitly forbidden since the probe itself is the request the policy gates. Execution step 1 now defers to the policy before fetching. * speckit.bug.assess: remove 'post-redirect-resolution' inconsistency The URL Trust Policy explicitly forbids following redirects, but the audit-trail bullet asked the agent to record the host 'post-redirect-resolution', which contradicted that rule and could lead agents to follow redirects unintentionally to determine what to log. Reword both call sites to refer to the host parsed from the URL the user supplied (no resolution implied): - Tier-3 interactive prompt: '...naming the host parsed from the URL explicitly...' - Recorded fields: 'The host parsed from that URL (no redirect following - see the rule above).' No behavior change; clarification only.
3.7 KiB
3.7 KiB
Bug Triage Workflow Extension
A three-step bug triage workflow for Spec Kit: assess, fix, and validate. Each bug lives in its own directory under .specify/bugs/<slug>/, with one Markdown report per stage.
Overview
This extension delivers an opinionated, repeatable bug workflow that any AI coding agent can drive:
- Assess — read a bug report (pasted text or a URL), judge whether it is a real bug, locate suspected code paths, and propose a remediation.
- Fix — apply the proposed remediation and record exactly what changed.
- Test — re-run the reproduction and any added tests, then record the verification result.
The three stages communicate through three Markdown files in a single per-bug directory:
.specify/bugs/<slug>/
├── assessment.md # written by speckit.bug.assess
├── fix.md # written by speckit.bug.fix
└── test.md # written by speckit.bug.test
Commands
| Command | Description | Output |
|---|---|---|
speckit.bug.assess |
Triages a bug report (pasted text or URL) against the codebase. | .specify/bugs/<slug>/assessment.md |
speckit.bug.fix |
Applies the remediation from the assessment. | .specify/bugs/<slug>/fix.md |
speckit.bug.test |
Validates the fix and records the verification report. | .specify/bugs/<slug>/test.md |
Slug Conventions
A slug is the per-bug directory name under .specify/bugs/. It is the only handle the three commands share.
- User-provided: any shape the user wants, normalized to lowercase kebab-case (e.g.
login-timeout,cve-2026-001,oauth-redirect-500). The slug is preserved verbatim after normalization — no timestamps or numbers are appended automatically. - Asked for: in interactive use,
speckit.bug.assessasks for a slug when none is supplied, suggesting a kebab-case default derived from the bug summary. - Automated: when no human is available to answer, the agent generates a slug itself. The generated slug MUST produce a unique directory — if
.specify/bugs/<slug>/already exists, the agent appends the shortest disambiguating suffix needed (-2,-3, …) or a short date (-20260605). Existing bug directories are never overwritten.
Installation
# Install the bundled bug extension (no network required)
specify extension add bug
Disabling
# Disable the bug extension
specify extension disable bug
# Re-enable it
specify extension enable bug
Typical Flow
# 1. Triage a bug from a pasted stack trace
/speckit.bug.assess "TypeError: cannot read properties of undefined (reading 'token') at /auth/callback"
# 2. Triage a bug from a GitHub issue URL
/speckit.bug.assess https://github.com/example/repo/issues/1234 slug=callback-token
# 3. Apply the proposed fix
/speckit.bug.fix slug=callback-token
# 4. Validate the fix
/speckit.bug.test slug=callback-token
Guardrails
speckit.bug.assessandspeckit.bug.testnever modify source code. They read the repository and write only inside.specify/bugs/<slug>/.speckit.bug.fixis the only command that edits source code, and it stays within the files listed in the assessment unless new evidence requires expanding scope (which is logged infix.mdunder Deviations from Assessment).- None of the commands overwrite an existing report file without explicit confirmation; in automated mode they refuse and pick a new unique slug instead.
- Verdicts and verification results are never over-claimed: a reproduction that was not actually performed is reported as
partialornot-run, notverified.
Hooks
This extension registers no hooks. The three commands are always invoked explicitly by the user.