Skip to content

feat(extensions): add EARS requirements syntax extension#3324

Open
dhruv-15-03 wants to merge 3 commits into
github:mainfrom
dhruv-15-03:feat/1356-ears-extension
Open

feat(extensions): add EARS requirements syntax extension#3324
dhruv-15-03 wants to merge 3 commits into
github:mainfrom
dhruv-15-03:feat/1356-ears-extension

Conversation

@dhruv-15-03

@dhruv-15-03 dhruv-15-03 commented Jul 3, 2026

Copy link
Copy Markdown

Summary

Adds a bundled first-party extension that brings EARS (Easy Approach to Requirements Syntax) to Spec Kit, addressing #1356 (the most-requested open feature by reactions, with no existing implementation).

EARS constrains every requirement to one of five sentence patterns built around the mandatory modal shall, producing unambiguous, testable requirements. It originated at Rolls-Royce and is widely used in aerospace, automotive, and other safety-critical domains.

What it adds

Three explicit commands, mirroring the structure of the bundled bug extension and writing artifacts under .specify/ears/<slug>/:

Command Purpose Output
speckit.ears.author Draft requirements for a feature directly in EARS, classified by pattern requirements.md
speckit.ears.lint Read-only audit of existing requirements for EARS conformance and ambiguity, with suggested rewrites lint-report.md
speckit.ears.convert Rewrite free-form requirements into EARS and emit an original-to-EARS traceability matrix requirements.md

Registered as a bundled catalog entry alongside agent-context, bug, and git.

Design notes

  • Optional and additive. It changes no core templates and no default behavior. This directly addresses the design discussion on Feature Request: EARS (Easy Approach to Requirements Syntax) Integration #1356 (a commenter noted EARS should not be forced as the default without evidence it is universally superior) - EARS here is an opt-in tool, never a mandated format.
  • Consistent with existing extensions. Command file format, slug conventions, guardrails, and tests all mirror the bug extension.
  • lint is strictly read-only - it never edits source; all rewrites are suggestions.

Open question for maintainers

#1356 explicitly asks whether EARS should be a core/first-party capability or a community-contributed template. I implemented it as a bundled first-party extension because that is the lowest-friction, non-invasive vehicle, but I am happy to relocate it to the community catalog instead if you prefer - your call. The structure is identical either way.

Testing

  • tests/extensions/ears/ covers bundled layout, catalog registration, bundle resolution, and install via ExtensionManager (8 tests, all passing).
  • Full tests/extensions suite passes. The one intermittent failure in test_extension_agent_context.py (bundled-script yaml import) is a pre-existing Windows test-ordering flake unrelated to this change: it passes in isolation and when this PR's tests are excluded.

AI disclosure

This change was prepared by @dhruv-15-03, who reviewed and directed the work.

Refs #1356

Add a bundled first-party extension that brings EARS (Easy Approach to
Requirements Syntax) to Spec Kit. EARS constrains each requirement to one
of five sentence patterns built around the mandatory modal "shall",
producing unambiguous, testable requirements.

The extension provides three explicit commands, mirroring the structure of
the bundled bug extension and writing artifacts under .specify/ears/<slug>/:

- speckit.ears.author  - draft requirements for a feature directly in EARS
- speckit.ears.lint    - read-only audit of existing requirements for EARS
                         conformance and ambiguity, with suggested rewrites
- speckit.ears.convert - rewrite free-form requirements into EARS and emit
                         an original-to-EARS traceability matrix

The extension is optional and additive: it changes no core templates and no
default behavior, and is registered as a bundled catalog entry alongside the
existing agent-context, bug, and git extensions.

Adds tests/extensions/ears covering the bundled layout, catalog
registration, bundle resolution, and install via ExtensionManager.

Refs github#1356

Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a new first-party, bundled ears extension to Spec Kit that provides EARS (Easy Approach to Requirements Syntax) workflows for authoring, linting, and converting requirements, along with catalog registration and basic installation/layout tests.

Changes:

  • Added a bundled extensions/ears/ extension (manifest, README, and three command prompts: author/lint/convert).
  • Registered the extension in extensions/catalog.json as a bundled extension.
  • Added a new tests/extensions/ears/ suite to validate the bundled layout, catalog entry, bundle resolution, and install behavior.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/extensions/ears/test_ears_extension.py Adds tests for ears bundled layout, catalog registration, locator behavior, and install copying/manifest.
tests/extensions/ears/init.py Marks the new test package for the ears extension.
extensions/ears/README.md Documents the EARS extension purpose, commands, slug conventions, and guardrails.
extensions/ears/extension.yml Declares the ears extension manifest and its provided commands.
extensions/ears/commands/speckit.ears.lint.md Adds the lint command prompt spec (read-only audit + report output).
extensions/ears/commands/speckit.ears.convert.md Adds the convert command prompt spec (rewrite + traceability matrix output).
extensions/ears/commands/speckit.ears.author.md Adds the author command prompt spec (net-new EARS requirements authoring).
extensions/catalog.json Registers ears as a bundled extension in the extensions catalog.

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

Comment thread extensions/catalog.json
Comment thread tests/extensions/ears/test_ears_extension.py
Comment thread extensions/ears/commands/speckit.ears.lint.md Outdated
Comment thread extensions/ears/commands/speckit.ears.author.md Outdated
Comment thread extensions/ears/commands/speckit.ears.convert.md Outdated
Comment thread extensions/ears/commands/speckit.ears.convert.md Outdated
…ord wording

- Add extensions/ears to pyproject.toml wheel force-include so
  specify extension add ears works on wheel installs, matching the
  other bundled extensions (git, agent-context, bug).
- Add a regression test asserting pyproject.toml force-includes
  extensions/ears.
- Fix a wording contradiction in the author/lint/convert command prompts:
  the EARS reference said requirements use exactly one pattern keyword
  while also describing complex requirements that combine multiple
  keywords (e.g. While + When). Reworded to allow complex combinations
  while still requiring the shall modal.

Addresses automated review feedback on PR github#3324.

Assisted-by: GitHub Copilot (model: claude-sonnet-5, autonomous)
@dhruv-15-03

dhruv-15-03 commented Jul 5, 2026

Copy link
Copy Markdown
Author

Posted by GitHub Copilot as per direction on behalf of @dhruv-15-03.

Pushed 700d717 addressing the automated review feedback:

  • Added extensions/ears to the wheel force-include list in pyproject.toml (it was missing, so specify extension add ears would have failed on wheel installs) + a regression test asserting the force-include entry exists.
  • Fixed the "exactly one pattern keyword" wording in the author/lint/convert command prompts, which contradicted the documented support for complex (multi-keyword) EARS requirements.

Full test suite (tests/test_extensions.py, 329 tests) passes locally.

…r guardrails

The author command's Guardrails section still said "exactly one EARS
pattern keyword; no compound requirements", contradicting the EARS
Reference section above it (which allows complex requirements that
combine multiple pattern keywords). Reworded to match lint.md/convert.md
and clarify that "compound" (multiple behaviors joined by and/commas)
is a different concept from "complex" (one behavior expressed with
combined pattern keywords).

Found while verifying commit 700d717 fully resolves all review threads
on PR github#3324.

Assisted-by: GitHub Copilot (model: claude-sonnet-5, autonomous)
Copilot AI review requested due to automatic review settings July 5, 2026 12:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@dhruv-15-03

dhruv-15-03 commented Jul 5, 2026

Copy link
Copy Markdown
Author

Posted by GitHub Copilot as per direction on behalf of @dhruv-15-03.

All 6 automated review threads reviewed, verified against the fix, replied to individually, and resolved:

  1. extensions/catalog.json:42 (wheel force-include gap) — fixed in 700d717.
  2. tests/extensions/ears/test_ears_extension.py:83 (missing regression test) — fixed in 700d717.
  3. speckit.ears.lint.md (keyword wording) — fixed in 700d717.
  4. speckit.ears.author.md (keyword wording, reference section) — fixed in 700d717.
  5. speckit.ears.convert.md (keyword wording, reference section) — fixed in 700d717.
  6. speckit.ears.convert.md (keyword wording, self-check) — fixed in 700d717.

While verifying, found one residual instance of the same contradiction in speckit.ears.author.md's Guardrails section ("exactly one ... no compound requirements") that the review didn't catch — fixed in 2f6c7b1.

Full suite: tests/test_extensions.py + tests/extensions/ears/ = 335 passed, 3 skipped, 0 failed. No repo CI is configured on this PR (no checks reported). PR remains MERGEABLE with no merge conflicts.

Ready for maintainer review/merge.

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.

2 participants