Skip to content

feat(reqstool): dogfood OpenSpec <-> reqstool traceability#84

Merged
jimisola merged 3 commits into
mainfrom
feat/openspec-dogfooding
Jun 24, 2026
Merged

feat(reqstool): dogfood OpenSpec <-> reqstool traceability#84
jimisola merged 3 commits into
mainfrom
feat/openspec-dogfooding

Conversation

@jimisola

Copy link
Copy Markdown
Member

Summary

  • Bootstraps the OpenSpec spec layer and derives the reqstool SSOT for this repo, mirroring reqstool-client#407.
  • 3 capability specs (decorator-definitions, decorator-processing, yaml-export) backing DECORATORS_001-003 / SVC_DECORATORS_001-003.
  • Re-tags src/ with @Requirements/@SVCs, including genuine self-application: SVCs is tagged with DECORATORS_001 via the Requirements decorator it's implemented alongside (no chicken-and-egg compiled-processor problem here, unlike the Java annotation-processor repos — confirms the assumption noted in the rollout plan).
  • Wires the previously dead tests/resources/test_decorators/* fixture files (never referenced by any test) into a new tests/e2e/reqstool_decorators/test_process_e2e.py test exercising the full pipeline against real decorator syntax.
  • Converts the decorator-mechanics unit tests in test_decorators.py from @Requirements(...)/@SVCs(...) decorator syntax to direct calls (Requirements(...)(func)). The decorator-syntax form made the nested, intentionally-fake REQ_*/SVC_* IDs in those tests show up as real AST-discoverable annotations once this repo's own processor self-applies to its own tests — reqstool validate --strict correctly rejected those as references to non-existent requirement/SVC IDs. New scripts/generate_annotations.py self-apply step also excludes tests/resources for the same reason.
  • CI (build.yml) now runs the self-apply step and gates on reqstool status/validate via a [pypi, main] matrix calling the shared reqstool/.github actions, plus the reusable validate-openspec workflow.
  • .claude/settings.json, .mcp.json, CONTRIBUTING.md prerequisites, and .gitignore carve-out added from the start, matching the pattern now established across the rollout.

Validation

  • hatch run dev:pytest — 36/36 pass
  • hatch run dev:black --check / hatch run dev:flake8 — clean
  • openspec validate --specs --strict — 3/3 passed
  • reqstool validate --strict local -p docs/reqstool — all checks passed (no warnings)
  • reqstool status --check-all-reqs-met local -p docs/reqstool — 3/3 complete, PASS
  • CLI vs MCP server (reqstool mcp local -p docs/reqstool, get_status tool) — outputs agree exactly (3/3 complete, identical test counts)

Test plan

  • CI green on both pypi and main matrix legs
  • validate-openspec job green

https://claude.ai/code/session_015rzqRsXwmTz2rR9hjwYU3Q

Bootstrap the OpenSpec spec layer and derive the reqstool SSOT for this
repo, mirroring reqstool-client#407. Adds 3 capability specs
(decorator-definitions, decorator-processing, yaml-export) backing
DECORATORS_001-003 / SVC_DECORATORS_001-003, re-tags src with
@Requirements/@svcs (including genuine self-application: SVCs is
tagged with DECORATORS_001 via the Requirements decorator it
implements alongside), and wires tests/resources' previously-unused
fixture files into a new e2e test instead of leaving them dead.

Converts the decorator-mechanics unit tests in test_decorators.py from
`@Requirements(...)`/`@SVCs(...)` decorator syntax to direct calls
(`Requirements(...)(func)`) -- the decorator syntax form made the
nested, intentionally-fake REQ_*/SVC_* IDs in those tests show up as
real AST-discoverable annotations once this repo's own processor
self-applies to its own tests, which `reqstool validate --strict`
correctly rejected as references to non-existent requirement/SVC IDs.

CI matrix on [pypi, main] via shared reqstool/.github actions, with a
new scripts/generate_annotations.py self-apply step (excluding
tests/resources for the same fake-ID reason above) feeding
`reqstool status`/`validate`.

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>

@jimisola jimisola left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Full PR Review — Consolidated Findings

Ran 7 parallel checks (review, code-review, smells, advanced-smells, security, cruft, testing) scoped to this PR's diff. No correctness bugs found. Findings below, ordered by severity — all will be addressed in a follow-up commit.

# Prio Location Finding
1 Medium .github/workflows/build.yml:50-57 validate-reqstool only runs on the main matrix leg; reqstool-status --fail-if-incomplete runs on both legs. Clarifying which check is the actual required gate on the pypi leg.
2 Low scripts/generate_annotations.py:11 tests/integration is scanned but only contains empty __init__.py stubs — a no-op, easy to mistake for real coverage.
3 Low scripts/generate_annotations.py:1 Missing the # Copyright © LFV header used by every other .py file in this repo.
4 Low src/reqstool_python_decorators/decorators/decorators.py:14 @Requirements("DECORATORS_001") is applied only to SVCs (not Requirements, which can't self-tag — its own name isn't bound yet at definition time) with no comment explaining the asymmetry.
5 Low tests/unit/reqstool_decorators/test_decorators.py 10 near-identical 3-line test blocks with no shared helper.
6 Low tests/e2e/reqstool_decorators/test_process_e2e.py:31-37 e2e test never asserts fullyQualifiedName or the YAML schema-header line — the parts of the pipeline most exposed to real filesystem behavior.
7 Info .github/workflows/build.yml build/reqstool/annotations.yml and hatch build's output coexist in build/ only because hatch build doesn't clean it — fragile if that ever changes.

Non-issues (flagged by an agent but already correct): pinning reqstool/.github's shared actions to a main-branch SHA (the established convention across this rollout — that repo has no release/tag scheme); the 3 near-identical openspec/specs/*/spec.md files (intentional thin-pointer pattern, content lives in docs/reqstool/*.yml).


Automated — /x:full-pr-review

jimisola added 2 commits June 24, 2026 09:02
- Drop tests/integration from the self-apply scan (empty stub dirs,
  was a misleading no-op)
- Add missing copyright header to scripts/generate_annotations.py
- Document why @requirements("DECORATORS_001") is tagged on SVCs
  rather than Requirements (self-reference ordering constraint)
- Clarify in build.yml which step is the actual required gate
  (reqstool status) vs. supplementary (validate-reqstool, main-only)
  and note the build/ directory ordering dependency
- Strengthen the e2e test with assertions on fullyQualifiedName and
  the YAML schema header, the parts of the pipeline most exposed to
  real filesystem behavior
- Collapse the 10 near-identical decorator-mechanics unit tests into
  3 parametrized tests, removing repeated boilerplate

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
@jimisola jimisola merged commit 8baa93f into main Jun 24, 2026
10 checks passed
@jimisola jimisola deleted the feat/openspec-dogfooding branch June 24, 2026 08:13
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.

1 participant