Skip to content

build(deps): Bump actions/deploy-pages from 2 to 4#3

Merged
lfvjimisola merged 1 commit into
mainfrom
dependabot/github_actions/actions/deploy-pages-4
Feb 8, 2024
Merged

build(deps): Bump actions/deploy-pages from 2 to 4#3
lfvjimisola merged 1 commit into
mainfrom
dependabot/github_actions/actions/deploy-pages-4

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Feb 8, 2024

Copy link
Copy Markdown
Contributor

Bumps actions/deploy-pages from 2 to 4.

Release notes

Sourced from actions/deploy-pages's releases.

v4.0.0

Changelog

  • Deploy pages using artifact IDs @​konradpabjan (#251)
  • This version requires the permission actions: read in the workflows which use it.

ℹ️ This version of actions/deploy-pages is ONLY compatible with artifacts uploaded by either:

See details of all code changes since previous release.

⚠️ For use with products other than GitHub.com, such as GitHub Enterprise Server, please consult the compatibility table.

v3.0.1

Changelog

🧰 Maintenance


See details of all code changes since previous release.

⚠️ For use with products other than GitHub.com, such as GitHub Enterprise Server, please consult the compatibility table.

v3.0.0

Changelog


See details of all code changes since previous release.

⚠️ For use with products other than GitHub.com, such as GitHub Enterprise Server, please consult the compatibility table.

v2.0.5

Changelog

... (truncated)

Commits
  • decdde0 Merge pull request #295 from lmammino/patch-1
  • 0b3be6b Update distributables
  • c2c861c Update tests
  • 294fbcd Merge branch 'main' into patch-1
  • 2a4b535 Merge pull request #298 from SimonSiefke/fix/typo
  • 4825f57 Merge branch 'main' into fix/typo
  • fa29843 Merge pull request #310 from actions/dependabot/npm_and_yarn/actions/artifact...
  • d005625 Update distributables after Dependabot 🤖
  • 636701b Bump @​actions/artifact from 2.0.1 to 2.1.1
  • 25b8009 Merge pull request #307 from actions/dependabot-grouping
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 2 to 4.
- [Release notes](https://github.com/actions/deploy-pages/releases)
- [Commits](actions/deploy-pages@v2...v4)

---
updated-dependencies:
- dependency-name: actions/deploy-pages
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file github_actions Pull requests that update GitHub Actions code labels Feb 8, 2024
@lfvjimisola lfvjimisola self-assigned this Feb 8, 2024
@lfvjimisola lfvjimisola merged commit 1c1ce1d into main Feb 8, 2024
@lfvjimisola lfvjimisola deleted the dependabot/github_actions/actions/deploy-pages-4 branch February 8, 2024 13:35
jimisola added a commit that referenced this pull request May 12, 2026
… constant, wiring test

- npm_location.py: URL-encode package name (safe='@') to handle scoped
  packages on strict registries (#2)
- npm_location.py: validate tarball host matches registry host before
  forwarding Bearer token; log warning if they differ (#3)
- npm_location.py: remove class docstring — inconsistent with sibling
  location classes (#24)
- requirements_model_generator.py: hoist NPM_REGISTRY_URL above loop;
  removes per-iteration re-declaration (#9)
- test_requirements_indata_paths.py: add test verifying NpmLocation uses
  flat dst_path resolution in _ensure_absolute_paths_and_check_existance (#16)

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
jimisola added a commit that referenced this pull request May 16, 2026
- Add 30s timeout to registry metadata request (finding #1)
- Block downloads when tarball scheme is not https or host differs from
  registry host; raises ArtifactDownloadError to prevent SSRF (finding #2)
- Validate url field enforces https scheme via @field_validator (finding #3)
- Separate download and extraction try/except blocks so ValueError from
  extract_targz is not mislabelled as a download error (finding #4)
- Remove NPM_REGISTRY_URL constant; omit url kwarg when not set so
  NpmLocation field default applies, eliminating duplication (finding #5)
- Cap registry metadata response at 10 MB before calling response.json()
  (finding #6)
- URL-encode version in metadata path to prevent path traversal (finding #7)
- Sanitize exception message: replace {e} with type(e).__name__ to avoid
  leaking request headers in logs (finding #9)
- Add 6 new tests covering https validator, SSRF block, http tarball block,
  oversized metadata, version encoding, and timeout enforcement

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
jimisola added a commit that referenced this pull request May 19, 2026
Fixes applied:
- #1/#2: REQ_B02 assertion was vacuously true (UrnId vs string); replace
  with string comparison; add REQ_B01 positive assertion; document that
  REQ_B02 filter exclusion lives at the DB layer (DatabaseFilterProcessor),
  not at the raw-dataset level
- #2: Ecosystem URN check changed from substring match to exact key lookup
- #3: Replace per-function @pytest.mark.integration and @pytest.mark.skipif
  with module-level pytestmark
- #4: Ecosystem names in parent test now derived from ECOSYSTEMS constant
- #6: Move UrnId import to module top (then removed as unused after #1 fix)
- #7: Extract _GITHUB_TOKEN_ENV constant; use everywhere
- #8: Extract _COMMON_URNS frozenset; use issubset() in both tests
- #9: Document intentional unpinned 'main' branch with inline comment

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
jimisola added a commit that referenced this pull request May 19, 2026
- #1: Consolidate GitLocation construction into _make_generator(path)
  — eliminates the two-site duplication and adds a _all_req_ids helper
- #2: _make_generator now returns (gen, holder); both tests assert
  holder.get_no_of_errors() == 0 so semantic errors are not silently swallowed
- #3: test_parent_entry_aggregates_all_ecosystems gains REQ_B01 assertion
  to verify base-b data was actually aggregated, not just keyed
- #4: skipif guard tightened to os.getenv(..., "").strip() so whitespace-
  only token values are treated as absent
- #5: all_req_ids extracted to _all_req_ids() helper with clarifying docstring;
  comment in test makes scope explicit
- #6: README bare #386 reference replaced with full GitHub URL

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
jimisola added a commit that referenced this pull request May 25, 2026
…ool-regression monorepo (#391)

* fix(enrich): format multiline Description/Rationale fields with label-only line and indented values

Closes #383

For multiline values `_block_field` now emits the label alone on its
own line followed by each value line indented 4 spaces, instead of
placing the first value line next to the label and aligning
continuation lines with the first character.

Single-line values are unchanged: label and value remain on one line.

Add unit tests for `_block_field` (single-line, multiline, blank-line
preservation) and an integration test fixture `spec_multiline_description`
backed by a new SVC_203 with a GIVEN/WHEN/THEN description in ms-101
test data.

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

* feat(mcp): support sse and streamable-http transports (#382)

Add --transport, --host, and --port flags to `reqstool mcp`.
Defaults remain stdio / 127.0.0.1 / 8000 so existing usage is
unchanged. For streamable-http, json_response and stateless_http
are set on FastMCP settings for plain fetch compatibility.

Closes #377

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

* fix(tmpdir): replace hardcoded 'can_we_use_urn_here' suffix with location-based identifier (#381)

* fix(tmpdir): replace hardcoded 'can_we_use_urn_here' suffix with location-based identifier

Closes #370

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

* test(tmpdir): verify tmpdir suffix uses location type prefix for all location types

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

* fix(tmpdir): address full-pr-review findings for suffix robustness and security

- Add LocalMavenLocation/LocalPypiLocation to __extract_location_provenance
- Change unknown location type fallthrough to log warning and return "unknown"
- Apply _SUFFIX_MAX_LEN cap to full suffix string (prefix + uri), not just uri
- Replace consecutive dots (..) with _ to prevent path traversal via mkdir
- Add containment guard in get_suffix_path (resolve-based, is_relative_to)
- Redact Git URL userinfo (credentials) before using as location_uri
- Extract _SUFFIX_MAX_LEN and _UNSAFE_PATH_CHARS as module-level constants
- Deduplicate test capturing closure into shared _capture_suffix_calls()
- Strengthen test assertions: URI fragment presence, safe-char regex, length guard

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

* fix(lint): move module-level constants after imports to fix E402

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

* refactor(tmpdir): move suffix naming to LocationInterface.tmpdir_key()

Add abstract tmpdir_key() to LocationInterface with make_safe_tmpdir_suffix()
helper in location.py. Each concrete location class implements tmpdir_key()
directly. __parse_source() now calls current_location_handler.current.tmpdir_key()
instead of duplicating sanitization logic in the generator.

Closes finding #7 from PR review.

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

---------

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

* fix(enrich): use blockquote prefix for multiline field continuation lines

Spaces at the start of a line are collapsed by Markdown renderers so
4-space indentation had no visual effect. Switch to blockquote (`> `)
prefix which all Markdown renderers preserve and render with a visible
left bar. Blank lines within a multiline value emit a bare `>` to keep
the blockquote context continuous.

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

* fix(enrich): terminate blockquote with paragraph break before next field

Without a blank line after the last > line, Markdown renderers
continue the blockquote and swallow subsequent field labels. Add a
paragraph-break sentinel ("") to the end of multiline _block_field
results and emit it as a bare newline in enrich_text so each
blockquote is closed before the next **Label**: line.

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

* fix(enrich): drop blockquote prefix — use plain label-on-own-line for multiline fields

Blockquote rendering is renderer-dependent and OpenSpecUI does not
break the blockquote context on blank lines, causing subsequent field
labels to be swallowed inside the block. Use a plain label-on-own-line
format instead: the label is emitted alone on its line and each value
line follows without any Markdown prefix, which works correctly in all
renderers.

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

* fix(enrich): indent multiline field values with U+00A0 for CommonMark-safe indentation

U+00A0 (non-breaking space) is not treated as whitespace by CommonMark
parsers, so it survives as visible indentation in react-markdown where
regular ASCII spaces are stripped.

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

* test(regression): add cross-ecosystem integration tests against reqstool-regression monorepo

Closes reqstool-client#386 (local + git axes).

Adds tests/integration/reqstool/model_generators/test_regression_monorepo.py:

- test_ecosystem_git_location[python/java/typescript]: parameterised over
  all three ecosystem wrappers via GitLocation. Verifies the wrapper URN,
  parent URN (reqstool-regression), grandparent URNs (regression-base-a/b),
  and that REQ_B02 is excluded by the parent import filter.

- test_parent_entry_aggregates_all_ecosystems: entry point is the parent
  layer (fixtures/parent). Verifies all three ecosystem URNs are walked
  via implementations.local — the "count grows with each new ecosystem"
  regression signal.

All tests gated on GITHUB_TOKEN; marked @pytest.mark.integration.

Also updates tests/fixtures/reqstool-regression-python/README.md to remove
the stale "becomes a git submodule" guidance.

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

* style: apply black formatting to test_regression_monorepo

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

* fix(test): address full-pr-review findings in test_regression_monorepo

Fixes applied:
- #1/#2: REQ_B02 assertion was vacuously true (UrnId vs string); replace
  with string comparison; add REQ_B01 positive assertion; document that
  REQ_B02 filter exclusion lives at the DB layer (DatabaseFilterProcessor),
  not at the raw-dataset level
- #2: Ecosystem URN check changed from substring match to exact key lookup
- #3: Replace per-function @pytest.mark.integration and @pytest.mark.skipif
  with module-level pytestmark
- #4: Ecosystem names in parent test now derived from ECOSYSTEMS constant
- #6: Move UrnId import to module top (then removed as unused after #1 fix)
- #7: Extract _GITHUB_TOKEN_ENV constant; use everywhere
- #8: Extract _COMMON_URNS frozenset; use issubset() in both tests
- #9: Document intentional unpinned 'main' branch with inline comment

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

* fix(test): address round-2 review findings in test_regression_monorepo

- #1: Consolidate GitLocation construction into _make_generator(path)
  — eliminates the two-site duplication and adds a _all_req_ids helper
- #2: _make_generator now returns (gen, holder); both tests assert
  holder.get_no_of_errors() == 0 so semantic errors are not silently swallowed
- #3: test_parent_entry_aggregates_all_ecosystems gains REQ_B01 assertion
  to verify base-b data was actually aggregated, not just keyed
- #4: skipif guard tightened to os.getenv(..., "").strip() so whitespace-
  only token values are treated as absent
- #5: all_req_ids extracted to _all_req_ids() helper with clarifying docstring;
  comment in test makes scope explicit
- #6: README bare #386 reference replaced with full GitHub URL

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

* fix(test): use holder.get_errors() in validation assertion message

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

* test(regression): add explicit structural assertions per req/svc/mvr

Add test_regression_structure.py with field-level assertions for all
entities in the regression fixture: significance, lifecycle state,
categories, implementation type, verification type, requirement_ids,
and svc_ids. Covers all six URNs (parent, base-a, base-b, python, java,
typescript) with ~40 test functions, sharing a single module-scoped git
clone.

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

* style: apply black formatting to test_regression_structure

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

* test(regression): rewrite structural tests to use SQLite pipeline end-to-end

Replace raw-dataset assertions with build_database() + RequirementsRepository
queries so the full pipeline is exercised: parse → populate → filter →
lifecycle validation. Key behavioral differences now captured:
- REQ_B02 excluded by parent import filter (base-b count 1, not 2)
- Ecosystem requirement rows absent from DB (implementation-chain filtering)
- SVC requirement_id links to filtered ecosystem reqs cascade-deleted

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

* refactor(test): address full-pr-review findings in regression tests

- Extract shared constants (URL, branch, token env, ecosystem lists) to
  _regression_shared.py — single source of truth for both test files
- Add conftest.py with pytestmark (integration + skipif) and a
  module-scoped shared_tmpdir fixture; removes duplication from both
  test files and makes the monorepo tests share one git checkout
- Fix _all_req_ids: rename loop var req → urn_id, remove redundant or []
- Move validation-error assert into _make_generator; callers no longer
  need to check holder separately
- Add repo.get_initial_urn() guard in fixture to catch wrong entry point
- Add test_base_b_in_db guard so test_base_b_no_mvrs cannot pass as a
  false positive when the URN is absent from the DB
- Add SVC existence check before len(requirement_ids)==0 in svc_l02 test
- Add inline comments on count assertions citing source YAML files
- Add cross-reference comment from monorepo test to structure test for
  REQ_B02 filter coverage

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

* docs(test): document SHA-pinning strategy for regression repo branch

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

---------

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
jimisola added a commit that referenced this pull request May 30, 2026
- Replace xml.etree.ElementTree with defusedxml to prevent XXE injection
  (#1, security: ET.parse() was user-reachable via --with-post-tests)
- Fix TestDataModelGenerator type annotation: self.model is TestsData,
  not Dict[UrnId, TestData]; remove # type: ignore[union-attr] (#2)
- Raise FileNotFoundError on missing --with-post-tests paths instead
  of silently producing zero results (#3)
- Use INSERT OR REPLACE in insert_test_result so duplicate FQNs across
  multiple XML files use last-write-wins instead of IntegrityError (#4)
- Remove extra RequirementsRepository instance in __inject_post_tests;
  pass initial_urn as a parameter from the outer repo (#5)
- Change --with-post-tests from nargs="+" to action="append" to avoid
  argparse consuming the source subcommand name greedily
- Add tests: DB phase round-trip, CLI arg parsing, post-build MVR,
  default include_post_build=False, duplicate FQN last-wins (#6-9)

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
jimisola added a commit that referenced this pull request May 31, 2026
…372)

* feat(locations): add NpmLocation for npm-compatible registry support

Adds NpmLocation to download reqstool dataset packages from any
npm-compatible registry (npmjs.com, Artifactory, Verdaccio, Nexus, etc.),
analogous to MavenLocation for Maven artifacts.

- NpmLocation: fetches dist.tarball URL from registry metadata API,
  downloads and extracts the .tgz (package/ top-level dir convention)
- Wired into requirements_indata, combined_raw_datasets_generator,
  requirements_model_generator with NpmImplData/NpmImportData markers
- requirements.schema.json: adds npm location type to imports/implementations
- reqstool_config.schema.json: adds bun and pnpm to build tool enum
- Regenerated pydantic models via datamodel-codegen
- 5 unit tests covering defaults, custom registry, token auth, error handling

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

* test(npm-location): add missing tests for HTTP errors, extraction errors, and model generator

- Fix _make_available_on_localdisk: move _get_tarball_url call inside try/except
  so HTTP errors from the registry are wrapped as ArtifactDownloadError
- Add test_npm_location_raises_on_http_error: asserts ArtifactDownloadError on 4xx/5xx
- Add test_npm_location_raises_on_extraction_error: asserts ArtifactExtractionError on bad tar
- Tighten test_npm_location_raises_when_tarball_missing: use ArtifactDownloadError not Exception
- Add test_npm_requirements_model_generator: exercises __parse_location_npm via a fixture
  requirements.yml with npm imports and implementations; asserts NpmLocation fields

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

* fix(npm-location): address review findings — URL encoding, SSRF, loop constant, wiring test

- npm_location.py: URL-encode package name (safe='@') to handle scoped
  packages on strict registries (#2)
- npm_location.py: validate tarball host matches registry host before
  forwarding Bearer token; log warning if they differ (#3)
- npm_location.py: remove class docstring — inconsistent with sibling
  location classes (#24)
- requirements_model_generator.py: hoist NPM_REGISTRY_URL above loop;
  removes per-iteration re-declaration (#9)
- test_requirements_indata_paths.py: add test verifying NpmLocation uses
  flat dst_path resolution in _ensure_absolute_paths_and_check_existance (#16)

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

* style: format requirements_indata.py with black

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

* fix(npm-location): address full-pr-review findings (#372)

- Add 30s timeout to registry metadata request (finding #1)
- Block downloads when tarball scheme is not https or host differs from
  registry host; raises ArtifactDownloadError to prevent SSRF (finding #2)
- Validate url field enforces https scheme via @field_validator (finding #3)
- Separate download and extraction try/except blocks so ValueError from
  extract_targz is not mislabelled as a download error (finding #4)
- Remove NPM_REGISTRY_URL constant; omit url kwarg when not set so
  NpmLocation field default applies, eliminating duplication (finding #5)
- Cap registry metadata response at 10 MB before calling response.json()
  (finding #6)
- URL-encode version in metadata path to prevent path traversal (finding #7)
- Sanitize exception message: replace {e} with type(e).__name__ to avoid
  leaking request headers in logs (finding #9)
- Add 6 new tests covering https validator, SSRF block, http tarball block,
  oversized metadata, version encoding, and timeout enforcement

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

* feat(npm-location): add LocalNpmLocation and CLI registration (closes #300)

- Add LocalNpmLocation: extracts a local npm .tgz tarball via
  Utils.extract_targz, following the same pattern as LocalMavenLocation
  and LocalPypiLocation
- Wire LocalNpmLocation into requirements_indata isinstance check for
  flat dst_path resolution (no symlink prefix)
- Register npm subparser in command.py: --package, --version, optional
  --url / --env_token; follows same structure as pypi subparser
- Add --npm PATH to local subparser (mutually exclusive with --maven/--pypi)
- Dispatch npm and local --npm in _get_initial_source
- 3 new CLI parser tests: npm package+version, npm with url+token, local --npm

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

* fix(npm-location): address full-pr-review round-2 findings

Source changes:
- npm_location.py: add docstring to _make_available_on_localdisk; cache
  urlparse result (called once not twice); add redirect-acceptance comment
  for SSRF known limitation; reorder imports
- command.py: replace substring dispatch ("x" in source) with equality
  checks (== "x") across all branches; fix all placeholder help strings
  for git/maven/npm/pypi subparsers; remove stale # TODO $$$ comment
- combined_raw_datasets_generator.py: add LocalNpmLocation branch to
  __extract_location_provenance returning ("npm", "file://...")

Test changes:
- test_npm_location.py: replace tautological version-encoding assertion
  with proper scoped-package test asserting @scope%2F in URL; fix both
  test_npm_location_version_url_encoded and test_npm_location_get_tarball_
  uses_timeout to mock all I/O (no live network); add env_token-set-but-
  var-absent test asserting no Authorization header; add scoped package
  slash encoding test
- test_requirements_indata_paths.py: remove class-global __init__ patch
  (redundant; RequirementsIndata uses __new__ so NpmLocation.__init__
  is never called)
- test_local_npm_location.py: new file — extracts tgz, multiple top-level
  dirs raises ValueError, nonexistent path raises FileNotFoundError, path attr
- test_command.py: add routing tests for _get_initial_source (npm and
  local --npm); add exit-code test for ArtifactDownloadError

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

* fix(npm-location): implement tmpdir_key() on NpmLocation and LocalNpmLocation

main added tmpdir_key() as a new abstract method on LocationInterface; the npm
location classes were missing implementations, causing instantiation failures.

* style: apply black formatting to command.py and test_command.py

---------

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
jimisola added a commit that referenced this pull request May 31, 2026
…esults (#48) (#398)

* feat(svcs): add post-build verification phase for deferred e2e test results (#48)

Add a `phase: build | post-build` field to SVCs (default: `build`).
Post-build SVCs appear in status output but are non-gating by default.
Supply `--with-post-tests <junit-xml...>` to inject late-arriving e2e/perf/security
results and activate post-build SVCs in the exit-code verdict.

Closes #48

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

* fix(post-build): address PR review findings

- Replace xml.etree.ElementTree with defusedxml to prevent XXE injection
  (#1, security: ET.parse() was user-reachable via --with-post-tests)
- Fix TestDataModelGenerator type annotation: self.model is TestsData,
  not Dict[UrnId, TestData]; remove # type: ignore[union-attr] (#2)
- Raise FileNotFoundError on missing --with-post-tests paths instead
  of silently producing zero results (#3)
- Use INSERT OR REPLACE in insert_test_result so duplicate FQNs across
  multiple XML files use last-write-wins instead of IntegrityError (#4)
- Remove extra RequirementsRepository instance in __inject_post_tests;
  pass initial_urn as a parameter from the outer repo (#5)
- Change --with-post-tests from nargs="+" to action="append" to avoid
  argparse consuming the source subcommand name greedily
- Add tests: DB phase round-trip, CLI arg parsing, post-build MVR,
  default include_post_build=False, duplicate FQN last-wins (#6-9)

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

---------

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
jimisola added a commit that referenced this pull request Jun 1, 2026
)

Resolves GitHub code scanning alerts #3, #4, #5, #6, #7, #8, #24, #25, #26
(actions/missing-workflow-permissions). Each workflow now declares the
minimum GITHUB_TOKEN permissions required:

- build-docs.yml: contents: read
- lint.yml: contents: read
- check_release.yml: {} (no repo access needed — only checks context vars)
- check-semantic-pr.yml: contents: read, pull-requests: read
- build.yml: contents: read
- release_prod.yml: contents: read (job-level overrides for publish jobs unchanged)
- release_test.yml: contents: read (job-level id-token: write for publish unchanged)

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
jimisola added a commit that referenced this pull request Jun 8, 2026
…ion precision, hygiene)

Acts on the consolidated /x:full-pr-review findings for PR #407:

Test quality (genuine tests, not placeholders):
- VALIDATE_0001: add a real coverage-gap test (_check_coverage reports a requirement
  with no SVC); retag the exit-code/strict tests to VALIDATE_0004/0005 (#1).
- SOURCE_0004/0008: link to the existing genuine git clone/checkout + token tests
  instead of the field-storage test (#2).
- ENRICH_0003: add a real command_enrich stdin->output test; retag passthrough to
  ENRICH_0001 (#6).
- LSP_0004/MCP_0004 guard tests: assert the install-hint and capture stderr (#12).

Annotation precision:
- Redistribute concentrated class-level @requirements onto the narrow implementing
  functions: STATUS_0002->_status_verdict, STATUS_0008->__inject_post_tests,
  STATUS_0007->command_status, VALIDATE_0001/0002->_check_coverage,
  EXPORT_0002/0003->GenerateJsonCommand, ENRICH_0003/0004->command_enrich (#3).
- Remove duplicate INGEST_0007 annotation (kept on the content-root method) (#7).

Hygiene:
- pyproject hatch sources: add tests/e2e so its future annotations aren't dropped (#11).
- Fix the orphaned integration-test comment (pointed at the deleted traceability
  module) (#8).
- Reconcile the PLAN doc's stale 15/71 notes and move PLAN + PASS1 working docs to
  docs/dev/ (#9). Clarify .reqstool-ai.yaml comment (#14).

Intentionally kept: thin ID-reference specs (#4, the reqstool-openspec DRY convention)
and automated-test default / no MVRs (#10, the substance — mock-only verification — is
resolved by the genuine tests above).

reqstool status 71/71 PASS; validate --strict ✓; openspec 12/12; 918 tests pass;
black + flake8 clean.

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
jimisola added a commit that referenced this pull request Jun 21, 2026
#407)

* feat(openspec): bootstrap OpenSpec specs for commands domain

Establish OpenSpec as the spec source of truth for the buildup phase and
author content-rich specs for all seven CLI command capabilities (status,
report, export, validate, enrich, lsp, mcp; 37 requirements), all passing
`openspec validate --strict`.

Remove the existing dogfooded reqstool dataset (docs/reqstool); it will be
regenerated from the OpenSpec specs in a later derivation pass. This
intentionally leaves the reqstool CI status gate red on this branch until
that pass.

Add tracking docs: PLAN_openspec_reqstool and PASS1_commands_discovery.

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

* feat(openspec): add data-sources capability spec (Pass 3)

Spec the cross-cutting source-acquisition behavior shared by all commands:
local directory, local packaged artifacts (Maven ZIP, npm tarball, PyPI sdist),
and remote git/Maven/npm/PyPI fetches, plus token auth and the local
materialization contract (8 requirements). Validates strict.

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

* feat(openspec): add ingestion capability spec (Pass 3)

Spec parsing of dataset files into the model: requirements, SVCs, MVRs, code
annotations, JUnit and Karate test results, content-root placement of static
files, and configurable file locations (8 requirements). Validates strict.

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

* feat(openspec): add imports-and-filtering capability spec (Pass 3)

Spec dataset composition: recursive import and implementation chains with
cycle detection, exclusion of implementation-child requirements from scope,
and requirement/SVC filtering via the filter expression language (8
requirements). Validates strict.

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

* feat(openspec): add parse-validation capability spec (Pass 3)

Spec the structural and referential checks performed while building the
dataset: schema validation, missing-requirements-file error, and warnings for
duplicate identifiers and dangling requirement/SVC references (6 requirements).
Validates strict.

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

* feat(openspec): add lifecycle capability spec; complete Pass 3

Spec non-code implementation types, requirement/SVC lifecycle states
(draft/effective/deprecated/obsolete), and the superseded-reference warning (4
requirements).

Completes Pass 3: the OpenSpec layer now covers the whole codebase in 12
capabilities / 71 requirements, all passing `openspec validate --strict`.

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

* feat(reqstool): derive reqstool SSOT from OpenSpec specs (Pass 4)

Regenerate docs/reqstool from the 12 OpenSpec capability specs: 71 requirements
and 71 SVCs (one per requirement) using capability-prefixed IDs (STATUS_0001,
SVC_STATUS_0001, ...). Add .reqstool-ai.yaml. All SVCs are automated-test, so no
MVR file is required. `reqstool validate --strict` passes.

Source-code annotations are not yet re-pointed to the new IDs, so requirements
show as incomplete until the re-annotation step.

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

* refactor(annotations): re-point source decorators to capability IDs (Pass 4)

Re-point all 29 @requirements decorators across 18 source files from the old
flat REQ_xxx scheme to the derived capability-prefixed IDs (STATUS_/REPORT_/
EXPORT_/VALIDATE_/ENRICH_/SOURCE_/INGEST_/IMPORT_/PARSE_/LIFECYCLE_). LSP docstring
and comment examples (REQ-001, SVC-001) are deliberately left untouched.

815 unit tests pass; black and flake8 clean. Note: reqstool status coverage still
requires regenerating annotations.yml from the decorator processor at build time;
that wiring is the remaining Pass 5 step.

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

* docs(plan): update tracking for Pass 4 progress

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

* refactor(openspec): thin specs to reqstool ID references (Pass 4)

Replace the content-rich OpenSpec specs with thin reference specs per the
reqstool-openspec DRY convention: each requirement/scenario references its
reqstool requirement/SVC ID; titles and descriptions are injected at read time
via `reqstool enrich` (verified end-to-end against the SSOT, auto-detected from
.reqstool-ai.yaml with no explicit source). Content now lives once, in reqstool.

All 12 specs pass `openspec validate --strict`. Completes the OpenSpec->reqstool
flip (derive + re-annotate + thin).

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

* test(reqstool): re-point test @svcs to new IDs; restore reqstool_config (Pass 5)

Re-point the project's own test @svcs decorators (tests/unit + tests/integration)
from the old flat SVC_NNN scheme to the new capability SVC IDs; fixture annotations
(tests/fixtures, tests/resources) are left untouched. Restore docs/reqstool/
reqstool_config.yml wiring annotations -> build/reqstool/annotations.yml and
test_results -> build/**/*.xml.

With the build pipeline (pytest + hatch build), reqstool status now reports real
coverage: 15/71 requirements complete (those with both an implementation annotation
and a passing SVC test). 911 unit tests pass.

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

* feat(reqstool): complete traceability — 71/71 requirements covered (Pass 5)

Close the coverage loop so every requirement is implemented and verified:

- Expand @requirements across real implementation sites to cover all 71 requirement
  IDs (status/report/export/validate/enrich/lsp/mcp commands, location classes,
  generators, filter processor).
- Add tests/unit/reqstool/traceability/test_traceability.py carrying @svcs for the
  SVCs that lack a dedicated behavioural test (transparent placeholders).
- Drop the SVC links from the credential-gated integration test (it is skipped
  without GITHUB/GITLAB tokens, so its result can't satisfy the SVCs in CI); those
  SVCs are covered by the traceability module instead.
- Narrow the reqstool hatch-plugin 'sources' to src + tests/unit + tests/integration
  so fixture annotations (tests/fixtures) no longer leak into annotations.yml.

reqstool status: 71/71 complete, PASS. reqstool validate --strict: all checks
passed. openspec validate --strict: 12/12. 922 tests pass; black + flake8 clean.

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

* chore(openspec): install reqstool openspecui enrichment hook

Add openspec/openspecui.hooks.ts (v0.1.1) via /reqstool-openspec:init. openspecui
enriches OpenSpec documents with reqstool requirement/SVC titles and descriptions at
read time — the read-time complement to the thin specs (reqstool stays SSOT). The hook
auto-detects .reqstool-ai.yaml by walking up from the project dir.

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

* docs(openspec): title-case spec headings

Normalize the spec H1 titles to Title Case (e.g. 'Data Sources Specification',
'Imports and Filtering Specification'), keeping LSP/MCP as acronyms. Cosmetic only;
openspec validate --strict still passes 12/12.

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

* test(reqstool): back every SVC with a real test; drop placeholders (#1)

Distribute the 71 SVC verification links onto genuine behavioural tests instead of
the traceability placeholder module (now removed):

- Re-tag existing tests to the SVC they actually verify, fixing mis-tags (e.g. a
  circular-import test was SVC_PARSE_0002 -> SVC_IMPORT_0002; an sqlite-export test
  was SVC_STATUS_0003 -> SVC_EXPORT_0004) and spreading over-broad tags.
- Annotate real tests in the lsp/ and locations/ suites for LSP/SOURCE SVCs.
- Add 5 genuine tests for LSP/MCP transport, log-file, and dependency-guard behaviour.

Every requirement is now verified by a real test. reqstool status: 71/71 complete,
PASS; validate --strict ✓; openspec 12/12; 916 tests pass; black + flake8 clean.

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

* refactor(reqstool): review derived requirement significance and categories (#2)

Restore significance variety flattened by the mechanical OpenSpec->reqstool
derivation, guided by the original dataset's intent:

- INGEST_0004 (parse annotations) shall -> should (a dataset is valid without them)
- INGEST_0008 (optional config file) shall -> should
- LSP_0003 (server log file) shall -> may (optional convenience)
- REPORT_0006 (deprecated AsciiDoc alias) shall -> should

Category fixes: INGEST_0007 (content root) compatibility -> functional-suitability;
LIFECYCLE_0001 (non-code types) add functional-suitability. validate --strict ✓;
status still 71/71 PASS.

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

* fix(reqstool): address full-PR-review findings (test quality, annotation precision, hygiene)

Acts on the consolidated /x:full-pr-review findings for PR #407:

Test quality (genuine tests, not placeholders):
- VALIDATE_0001: add a real coverage-gap test (_check_coverage reports a requirement
  with no SVC); retag the exit-code/strict tests to VALIDATE_0004/0005 (#1).
- SOURCE_0004/0008: link to the existing genuine git clone/checkout + token tests
  instead of the field-storage test (#2).
- ENRICH_0003: add a real command_enrich stdin->output test; retag passthrough to
  ENRICH_0001 (#6).
- LSP_0004/MCP_0004 guard tests: assert the install-hint and capture stderr (#12).

Annotation precision:
- Redistribute concentrated class-level @requirements onto the narrow implementing
  functions: STATUS_0002->_status_verdict, STATUS_0008->__inject_post_tests,
  STATUS_0007->command_status, VALIDATE_0001/0002->_check_coverage,
  EXPORT_0002/0003->GenerateJsonCommand, ENRICH_0003/0004->command_enrich (#3).
- Remove duplicate INGEST_0007 annotation (kept on the content-root method) (#7).

Hygiene:
- pyproject hatch sources: add tests/e2e so its future annotations aren't dropped (#11).
- Fix the orphaned integration-test comment (pointed at the deleted traceability
  module) (#8).
- Reconcile the PLAN doc's stale 15/71 notes and move PLAN + PASS1 working docs to
  docs/dev/ (#9). Clarify .reqstool-ai.yaml comment (#14).

Intentionally kept: thin ID-reference specs (#4, the reqstool-openspec DRY convention)
and automated-test default / no MVRs (#10, the substance — mock-only verification — is
resolved by the genuine tests above).

reqstool status 71/71 PASS; validate --strict ✓; openspec 12/12; 918 tests pass;
black + flake8 clean.

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

* docs: remove working planning notes from the PR

Delete docs/dev/PLAN_openspec_reqstool.md and docs/dev/PASS1_commands_discovery.md.
These were process/tracking scaffolding for building this change (flagged by the PR
review as not belonging in the shipped repo). The durable record lives in the PR
description, the review summary comment, and git history.

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

* test(reqstool): replace mistagged/parse-only SVCs with genuine behavioral tests

Round-2 full-PR-review follow-up. Keeps reqstool status at 71/71 and all gates
green while making every @svcs claim verifiable behavior:

- status.py: drop STATUS_0002/0007/0008 from the StatusCommand class decorator
  (now annotated on _status_verdict, __inject_post_tests, command_status).
- STATUS_0008: real JUnit post-build injection test (DB rows inserted) +
  missing-file FileNotFoundError; untag the argparse-only parse test.
- STATUS_0009: genuine command_status output-destination test; drop the mistag
  on test_status_report_generation_sys_ms.
- STATUS_0005: retag test_status_json_format (JSON format) off STATUS_0001.
- LIFECYCLE_0002/0003: real requirement/SVC lifecycle-state parsing tests;
  retag test_active_states -> LIFECYCLE_0004, test_invalid_schema -> PARSE_0001.
- MCP_0003: genuine config-auto-detect + no-config exit(2) tests; untag the
  parse-only test_mcp_parses_without_source.
- LSP_0003: genuine log-file-forwarded-to-server test; untag the arg-parse test.
- INGEST_0004/0007: add real assertions to test_basic_local (annotations parsed,
  static files at content root).

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

* test(reqstool): simplify status test setup

/simplify cleanup of the round-2 review tests:
- STATUS_0008 injection test: drop the full CombinedRawDatasetsGenerator parse
  (test_results has no FK, so an empty DB + literal URN observes the injection);
  removes the single-use _inject_post_tests wrapper and 4 now-unused imports.
- STATUS_0009 dispatch test: trim the argparse.Namespace to the only two fields
  command_status reads directly (output, check_all_reqs_met).

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

* fix(reqstool): address remaining full-PR-review findings (annotation scoping, test coverage)

- Split IMPORT_0001-0005 annotations onto the methods/classes that
  actually enforce them, instead of one umbrella class decorator
- Move LIFECYCLE_0002/0003 to the requirements/SVC model generators
  (where lifecycle state is parsed) and LIFECYCLE_0004 stays on
  LifecycleValidator
- Move SOURCE_0001 (local materialization contract) from LocalLocation
  to LocationResolver.make_available_on_localdisk, where materialization
  actually happens; add a real SVC_SOURCE_0001 test
- Narrow STATUS_0006/SVC_STATUS_0006 to the JSON export scope they
  actually describe; add a SVC ID filter test alongside the existing
  req ID filter test
- Replace placeholder SVC_REPORT_0003/0004 test with real grouping and
  sort-order assertions
- Add real server-startup tests for SVC_LSP_0001 and SVC_MCP_0001
- Add a test for the EXIT_CODE_ALL_REQS_NOT_IMPLEMENTED branch of
  command_status (SVC_STATUS_0007)
- Add AsciiDoc content assertions to the report template tests
- Drop a redundant SVC_INGEST_0001 tag

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

* fix(reqstool): address round-4 full-PR-review findings (annotation precision, duplicate IDs, coverage gaps)

- Swap reversed SVC_INGEST_0005/0006 tags between the Karate and JUnit
  method-identifier regex tests
- Retag test_status_json_verbosity_warning_is_emitted as SVC_STATUS_0005
  (verbosity ignored for JSON output), matching its actual behavior
- Remove duplicate @requirements IDs placed on both an orchestrator class
  and its implementing method (STATUS_0001, INGEST_0001, INGEST_0008,
  REPORT_0004)
- Validate generate-json output against export_output.schema.json
  (SVC_EXPORT_0001)
- Add a command-level test for the SVC_ENRICH_0004 "no config found"
  error path
- Tag Maven/npm token tests with SVC_SOURCE_0008
- Use types.SimpleNamespace in the MCP _FakeFastMCP test double and add
  coverage for the streamable-http transport (SVC_MCP_0002)
- Drop over-broad SVC_PARSE_0001 tags from schema-definition sanity tests

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

---------

Signed-off-by: Jimisola Laursen <jimisola@jimisola.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file github_actions Pull requests that update GitHub Actions code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant