Skip to content

feat(openspec): bootstrap OpenSpec spec layer for the demo's status showcase - #104

Merged
jimisola merged 10 commits into
mainfrom
feat/openspec-dogfooding
Jun 21, 2026
Merged

feat(openspec): bootstrap OpenSpec spec layer for the demo's status showcase#104
jimisola merged 10 commits into
mainfrom
feat/openspec-dogfooding

Conversation

@jimisola

Copy link
Copy Markdown
Member

What

Applies the OpenSpec ↔ reqstool dogfooding pattern from reqstool-client#407 to this repo — the first in the org-wide rollout (see PLAN_dog_fooding.md).

reqstool-demo's purpose is different from reqstool-client's: it's a small fixture app that intentionally showcases every reqstool status outcome (pass, manual-fail, not-implemented, failing-test, skipped-test, missing-test), not a fully-passing production codebase. The OpenSpec layer here reflects that — six capability specs, one per status outcome, in thin ID-reference form against the existing requirement/SVC IDs (REQ_PASS, REQ_MANUAL_FAIL, ...). IDs were kept as-is rather than renamed to a capability prefix, since they're already domain-named and intentionally non-uniform (unlike reqstool-client's fully-passing, renamed set).

Changes

  • openspec/specs/{greeting,billing,reporting,validation,notifications,audit-logging}/spec.md — one capability per status outcome
  • openspec/openspecui.hooks.ts — reqstool-ai's openspecui enrichment hook (/reqstool-openspec:init)
  • .reqstool-ai.yaml — single demo module, domain-specific (no) ID prefix (/reqstool:init)
  • .mcp.json — project-scoped reqstool MCP server entry

The existing docs/reqstool/requirements.yml/software_verification_cases.yml SSOT was already fully consistent with source/tests — no changes needed there.

Validation

  • openspec validate --specs --strict → 6/6 passed
  • reqstool validate --strict local -p docs/reqstool → all checks passed
  • reqstool status local -p docs/reqstool → 1/6 complete (by design — this repo showcases incomplete states)
  • mvn clean verify → BUILD SUCCESS (one intentionally failing test, by design)
  • CLI vs MCP: compared reqstool status against the reqstool mcp server's get_requirements_status tool — found a real discrepancy on REQ_SKIPPED_TEST/REQ_MISSING_TEST (MCP reported meets_requirements: true, contradicting both the CLI and the MCP server's own get_status tool). Root-caused and fixed upstream in reqstool-client#411 (merged), with a follow-up tracked in reqstool-client#412 to consolidate the two implementations. Re-verified after #411 merged: CLI and MCP now agree exactly across all 6 requirements.

🤖 Generated with Claude Code

…howcase

Adds an OpenSpec layer mirroring reqstool-client#407's dogfooding pattern,
scoped to this repo's actual purpose: showcasing every reqstool status
outcome (pass, manual-fail, not-implemented, failing-test, skipped-test,
missing-test) across six small feature capabilities.

- openspec/specs/{greeting,billing,reporting,validation,notifications,
  audit-logging}/spec.md — one capability per status outcome, in thin
  ID-reference form against the existing requirements.yml/SVC IDs
  (REQ_PASS, REQ_MANUAL_FAIL, ...). IDs are kept as-is (no capability
  prefix) since they're already domain-named and intentionally demonstrate
  non-passing states, unlike reqstool-client's renamed/100%-passing set.
- openspec/openspecui.hooks.ts — reqstool-ai's openspecui enrichment hook.
- .reqstool-ai.yaml — single "demo" module, domain-specific (no) prefix.
- .mcp.json — project-scoped reqstool MCP server entry.

Validated: openspec validate --specs --strict (6/6 pass), reqstool
validate --strict (pass), reqstool status (1/6 complete, by design),
mvn clean verify (build succeeds; one intentionally failing test, by
design), and CLI vs MCP get_requirements_status now agree exactly across
all 6 requirements (confirmed after reqstool-client#411's fix).

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 (code-review, smells, advanced-smells, security, cruft, testing, general review) scoped to this PR's diff.

# Prio Location Finding Fix
1 High .github/workflows/build.yml No CI step ran openspec validate --specs --strict — the PR's validation claims weren't backed by a regression gate; build-docs.yml's paths: ["docs/**"] filter wouldn't even catch openspec/** changes. Added an openspec validate --specs --strict step to build.yml
2 Low .reqstool-ai.yaml:28-29 req_prefix: "" vs svc_prefix: "SVC_" asymmetry could confuse a future reader. Expanded the comment
3 Low PR title/commit Commit scope openspec isn't in the org's enumerated CONTRIBUTING.md scope list, though it matches reqstool-client#407's precedent exactly. No action — consistent with established precedent
4 Info .mcp.json vs openspec/openspecui.hooks.ts reqstool mcp invocation duplicated in two places. Not actionable here — hooks.ts is vendored verbatim from the reqstool-ai plugin template
5 Info openspec/openspecui.hooks.ts:33 Malformed JSON-RPC line from the subprocess is silently dropped, could hang a pending promise. Not actionable here — pre-existing in the vendored file, same as reqstool-client#407
6 Info README/CONTRIBUTING Neither mentions the new OpenSpec/MCP tooling. Optional discoverability nice-to-have

Security and cruft checks: clean, no findings. All 6 spec.md files' requirement/SVC ID references were independently verified correct against the SSOT by 2 separate checks.

Note: didn't add reqstool validate --strict to CI alongside openspec validate — that command isn't in the currently-published PyPI release (0.11.0) yet, only on reqstool-client's unreleased main. Worth revisiting once a release ships it.


Automated — /x:full-pr-review

jimisola added 3 commits June 21, 2026 18:21
- Add an openspec validate --specs --strict step to build.yml so spec/SSOT
  drift fails CI instead of relying on the manual run documented in #104's
  PR description; build-docs.yml's docs/** path filter doesn't cover
  openspec/**, so nothing else was catching this.
- Expand the .reqstool-ai.yaml comment explaining why req_prefix is empty
  while svc_prefix isn't.

Found by /x:full-pr-review on #104. reqstool validate --strict was
intentionally not added yet — not in the currently published PyPI release.

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
Adds an openspec validate --specs --strict step to build.yml so spec/SSOT
drift fails CI instead of relying on the manual run documented in #104's
PR description.

Runs reqstool status/validate against both the latest PyPI release and
reqstool-client's main branch in a matrix, since reqstool-client is
deliberately holding off its next release until the org-wide OpenSpec
dogfooding rollout is complete, and main already has fixes (#411) and
commands (validate) not yet published. reqstool validate --strict only
runs on the main leg since that subcommand isn't on PyPI yet. CI continues
to run the latest PyPI release as its baseline; see reqstool-demo#105 for
tracking divergence between the two legs and collapsing back to PyPI-only
once reqstool-client cuts its next release.

Also expands the .reqstool-ai.yaml comment explaining why req_prefix is
empty while svc_prefix isn't.

Found by /x:full-pr-review on #104.

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
build (main) failed: the runner's default Python (3.12) doesn't satisfy
reqstool-client@main's reqstool-python-decorators>=0.1.0 dependency, which
requires Python >=3.13. Add actions/setup-python@v6 pinned to 3.13,
matching reqstool-client's own CI convention (build.yml, lint.yml).

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
Replaces the inline reqstool install/status/validate steps and the
inline openspec install/validate step with the reusable building blocks
just added to reqstool/.github for this rollout:

- reqstool/.github/.github/actions/validate-reqstool (reqstool-client#412
  follow-up notwithstanding, runs reqstool validate --strict; only called
  for the main matrix leg since that subcommand isn't on PyPI yet)
- reqstool/.github/.github/actions/reqstool-status (runs reqstool status,
  fail-if-incomplete left false since this repo intentionally has
  incomplete requirements)
- reqstool/.github/.github/workflows/common-validate-openspec.yml (now a
  separate job, since it's a reusable *workflow* rather than a composite
  action)

Pinned to reqstool/.github@cd3b5e8 (main, 2026-06-21) per
reqstool/.github#40 and #41.

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
Comment thread .github/workflows/build.yml Fixed
validate-reqstool/reqstool-status no longer install reqstool themselves
(reqstool/.github#48 removed their broken nested
./.github/actions/install-reqstool reference, which only resolved when
called from within reqstool/.github itself, not from a consuming repo
like this one). Call install-reqstool explicitly as its own step first.

Pinned to reqstool/.github@11a00fc (main, 2026-06-21).

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
Comment thread .github/workflows/build.yml Fixed
Picks up reqstool/.github#59 (drop --verbosity compact from
reqstool-status, also not yet on PyPI — same situation as the validate
subcommand fixed in #48), found via this PR's pypi matrix leg failing
with "invalid choice: 'compact'".

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
Comment thread .github/workflows/build.yml Fixed
@jimisola jimisola self-assigned this Jun 21, 2026
jimisola added 3 commits June 22, 2026 00:15
requirements.yml and software_verification_cases.yml used 0.0.1 for every
requirement/SVC. Per semver, 0.0.x is reserved for pre-release/unstable
work before any real first version — the first published revision of a
thing should be 0.1.0, which also matches reqstool-ai's own
.reqstool-ai.yaml.template default ("Revision string for new requirements
and SVCs. Default: 0.1.0"). My earlier .reqstool-ai.yaml matched the
existing (non-conventional) 0.0.1 instead of fixing it forward.

manual_verification_results.yml has no revision field in its schema, so
nothing to change there.

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
CodeQL flagged this 3 times across commits: the workflow didn't limit
GITHUB_TOKEN permissions. Add permissions: contents: read at the
workflow root, matching the existing convention in this repo
(build-docs.yml, check-semantic-pr.yml).

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

Copy link
Copy Markdown
Member Author

Addressed CodeQL findings and two of your review comments since the last update:

  • CodeQL (3x, recurring across commits as the file evolved): `build.yml` had no explicit `permissions` block for `GITHUB_TOKEN`. Added `permissions: contents: read` at the workflow root, matching this repo's existing convention (`build-docs.yml`, `check-semantic-pr.yml`). All 3 threads auto-resolved once CodeQL re-scanned.
  • Revision convention: bumped `revision: 0.0.1` → `0.1.0` across `requirements.yml`, `software_verification_cases.yml`, and `.reqstool-ai.yaml` — per semver, 0.0.x is pre-release territory; the first published revision should be 0.1.0, which also matches reqstool-ai's own template default. `manual_verification_results.yml` has no `revision` field in its schema, so nothing to change there.
  • CI now fully green on both the `pypi` and `main` matrix legs, after working through two more PyPI-vs-main gaps found along the way (`fix(ci): drop broken nested local action reference in reqstool actions .github#48`, `chore(deps): update dependency org.junit.jupiter:junit-jupiter-api to v5.14.3 - autoclosed #59`) and a broken nested composite-action reference.

All checks pass; no open threads remain on this branch.

@jimisola
jimisola merged commit 75d829d into main Jun 21, 2026
9 checks passed
@jimisola
jimisola deleted the feat/openspec-dogfooding branch June 21, 2026 22:30
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