Skip to content

fix(resolver,api): apply qualifier filters across cross-source searches and REST query params - #56

Merged
kurtseifried merged 2 commits into
mainfrom
fix/qualifier-filtering-cross-source-and-api
Nov 3, 2026
Merged

kurtseifried merged 2 commits into
mainfrom
fix/qualifier-filtering-cross-source-and-api

Conversation

@kurtseifried

Copy link
Copy Markdown
Contributor

Agent: Gemini (SecID governing agent)

Summary

Fixes qualifier filtering (?parsability=, ?content_type=, ?lang=) across all resolution paths and REST API query parameters:

  1. typeScopedSearch and namespaceScopedSearch (src/resolver.ts):
    • Applies applyQualifierFilters(results, parsed.qualifiers) and returns qualifierNotFoundResponse when qualifiers filter out all results (e.g., secid:advisory/CVE-2026-0019?parsability=structured).
    • Validates child.data.lang against parsed.qualifiers.lang, sets res.lang on child matches, and surfaces buildLangNotFoundMessage when an identifier matched children whose available languages exclude the requested language.
  2. applyQualifierFilters (src/resolver.ts):
    • Filters out URL-less RegistryResult guidance notes (!("url" in r)) when ?parsability= or ?content_type= is requested, and signals not_found when filtered.length === 0 && results.length > 0.
  3. qualifierNotFoundResponse (src/resolver.ts):
    • Reports available parsability values when ?parsability= removes all results, and reports combined qualifier mismatches when each qualifier value exists on different results.
  4. Top-level REST query parameters (src/api.ts):
    • Merges top-level &parsability=, &content_type=, and &lang= query parameters on /api/v1/resolve into the query when not already present inside secid=, matching the documented examples in API-RESPONSE-FORMAT.md and handling unencoded & after a SecID qualifier.
  5. Bare identifier & type-only qualifiers (src/kv-resolve.ts, src/parser.ts):
    • Strips and forwards ?qualifiers on bare identifier searches (e.g., CVE-2026-0019?parsability=structured) in searchBareIdentifier, and strips inline ?qualifiers from type-only SecID strings (e.g., secid:control?country=DE) in extractSecIDType and parseSecID.

Verification

  • npm run typecheck (0 errors)
  • npm test (all 17 test files / 899 tests pass)

Closes #55
Closes #10

…es and REST query params

- Apply applyQualifierFilters (?parsability, ?content_type, ?lang) and lang validation/metadata in typeScopedSearch and namespaceScopedSearch
- Filter out URL-less RegistryResult note entries when ?parsability or ?content_type is requested, returning qualifierNotFoundResponse if no URL results remain
- Report available parsability values and combined qualifier mismatches in qualifierNotFoundResponse
- Support ?parsability, ?content_type, and ?lang as top-level /api/v1/resolve query parameters (and merge unencoded '&' qualifiers)
- Strip and forward qualifiers on bare identifier searches in searchBareIdentifier and on type-only SecID strings in parser.ts
- Add regression tests across resolver, KV resolver, and REST API test suites

Closes #55
Closes #10

AI-Agent: Gemini
…alifiers before slash

Address all 4 P2 findings from fresh-context OpenAI Codex review:
1. Pass top-level HTTP query qualifiers (?parsability, ?content_type, ?lang)
   structurally into resolveQuery via capture.qualifiers instead of
   string-splicing onto decoded SecID, avoiding subpath corruption when
   source-level qualifiers precede '#'.
2. Merge extraQualifiers with parsed.qualifiers inside resolveFromKV and
   searchBareIdentifier ({ ...extra, ...inline }) so inline SecID qualifiers
   always take precedence regardless of position or key casing.
3. Prevent parameter pollution when decoded top-level query param values
   contain '&' or '='.
4. Strip source-level ?qualifiers from head before splitting on '/' in
   extractSecIDType and parseSecID so MIME-type slashes (e.g.
   secid:advisory?content_type=application/json) are not treated as path
   separators.

AI-Agent: Gemini
@kurtseifried

Copy link
Copy Markdown
Contributor Author

Agent: Gemini (SecID governing agent)

Independent Two-Review Summary

Review 1: Self-Review (Gemini)

  • Verified that ?parsability=, ?content_type=, and ?lang= qualifiers are applied across subpath resolution, namespace-scoped search, type-scoped cross-source search, bare identifier search, and top-level /api/v1/resolve HTTP query parameters.
  • Confirmed URL-less RegistryResult notes are excluded when parsability or content_type filters are active, and qualifierNotFoundResponse surfaces available parsability values and combined qualifier mismatches.

Review 2: Fresh-Context Cross-Vendor Review (OpenAI Codex gpt-6-astra)

Codex ran 24 in-memory assertions against the snapshot-seeded KV harness and identified 4 P2 issues in the initial commit (82397d1):

  1. Top-level filters corrupted subpaths when qualifiers preceded # (src/api.ts): string-appending &lang=de when ? appeared before # produced #art-32&lang=de.
  2. Inline qualifier precedence could be bypassed (src/api.ts): qualifierFromSecID did not split on # or normalize uppercase keys (?PARSABILITY=structured).
  3. Decoded parameter values allowed qualifier injection (src/api.ts): a top-level content_type=text/html%26parsability%3Dscraped interpolated &parsability=scraped into the SecID string.
  4. Type-only queries misinterpreted MIME-type slashes as path separators (src/parser.ts): secid:advisory?content_type=application/json split on the / inside application/json before stripping ? qualifiers.

Resolution (2344311)

  • Updated src/api.ts and src/kv-resolve.ts to pass top-level HTTP query qualifiers structurally via capture.qualifiers (mergeQualifiers(parsed.qualifiers, capture?.qualifiers)), eliminating string splicing and parameter pollution while guaranteeing inline qualifier precedence.
  • Updated src/parser.ts (extractSecIDType and parseSecID) to strip source-level ?qualifiers from head before splitting on /.
  • Updated qualifierFromSecID in src/api.ts to respect # boundaries and case-insensitive keys.
  • Added 4 regression tests in test/api.test.ts covering each finding (all 649 tests across 4 files pass).

@kurtseifried
kurtseifried merged commit 749be62 into main Nov 3, 2026
1 check passed
@kurtseifried
kurtseifried deleted the fix/qualifier-filtering-cross-source-and-api branch November 3, 2026 14:03
kurtseifried added a commit to CloudSecurityAlliance/SecID-Server-API that referenced this pull request Nov 3, 2026
…ort HTTP qualifier params (#3) (#30)

* fix(resolver,api): filter qualifiers across all search paths and support HTTP qualifier params (#3)

- Apply _apply_qualifier_filters (?parsability=, ?content_type=, ?lang=) in
  namespace_scoped_search, type_scoped_search, and _search_bare_identifier
  to match CloudSecurityAlliance/SecID-Service#56.
- Exclude URL-less RegistryResult entries when parsability or content_type
  qualifiers are requested.
- Strip source-level ?qualifiers from head before splitting on '/' in
  extract_secid_type and parse_secid so MIME slashes do not split head.
- Accept top-level parsability, content_type, and lang query parameters on
  GET /api/v1/resolve and merge them structurally with inline qualifiers.

Closes #3

AI-Agent: Gemini

* fix(resolver): address Codex review findings on lang weight and diagnostics (#3)

- Preserve declared weight in _child_hit (do not add +1 default-lang bonus
  during cross-source and bare searches).
- Use node_matches(..., scoped=scoped) and skip version_required sources in
  _lang_not_found_message callers so open patterns without known_values do
  not suppress the related fallback.
- Check availability of all active qualifiers in _qualifier_not_found before
  blaming lang on combined qualifier misses.

AI-Agent: Gemini
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant