Skip to content

Confine catalog-ID coupling to the dispatch layer #448

Description

@jmeridth

🤖 Raised during review of #446; the pattern predates that PR and now spans most recently added checks.

Background

The intended design binds catalog requirement IDs to logic in exactly one place: the dispatch map in evaluation_plans/evaluation-plans.go (ID to step function), with catalog content in data/catalogs/*.yaml and step functions staying catalog-agnostic so they can be reused by other catalogs or other checks. That structure still exists, but catalog-ID coupling has drifted into the step packages themselves in three forms.

1. Doc comments tied to requirement IDs (cosmetic, ~24 instances)

Most recently added steps are documented as implementations of one specific requirement, for example:

  • sec_assessment/steps.go:317 // HasThreatModelAnalysis implements OSPS-SA-03.02: ...
  • build_release/steps.go:140 // CicdUntrustedCodeIsolation checks OSPS-BR-01.03: ...
  • vuln_management/steps.go:578 // SastEnforcedOnChanges implements OSPS-VM-06.02: ...
  • access_control/steps.go:240 // WorkflowJobPermissionsLeastPrivilege implements OSPS-AC-04.02: ...

Older checks (legal, docs, early governance) describe behavior without IDs. Cleanup: reword step doc comments to describe the behavior being assessed; the ID linkage lives in the dispatch map, which is already keyed by ID.

2. Hardcoded catalog IDs in runtime code (substantive, ~12 instances)

Every AI-assisted step passes its own requirement ID as a string literal into shared helpers, and the ID flows into log output:

  • quality/steps.go: AIFallback(payload, "OSPS-QA-06.02", ...), recordAIAssessment(payload, "OSPS-QA-06.03", ...)
  • access_control/steps.go: AIFallback(payload, "OSPS-AC-04.02", ...)

Root cause: the TypedStep signature does not provide the invoking requirement ID at runtime, even though the dispatch layer knows it, so authors inlined it. Comment cleanup alone leaves this coupling in place. Proposed fix: thread the requirement ID from the dispatch layer into steps that need it for logging/evidence (for example a closure wrapper at registration, or SDK support in pluginkit), and remove the string literals.

3. Minor naming

  • vuln_management/vm_05_test.go is named after a requirement family rather than the behavior it tests.

Proposed cleanup pass

  • Reword step doc comments to behavior descriptions (category 1)
  • Thread the requirement ID from the dispatch layer and delete hardcoded ID literals (category 2)
  • Rename vm_05_test.go (category 3)
  • Consolidate the three release-asset companion/signature classifiers (build_release signatureAssetKind/isHashManifest/isReleaseAssetCompanion, quality compiledReleaseAssetExtensions and SBOM/signature suffixes) into reusable_steps (noted in the feat(OSPS-BR-02.02): associate release assets with release identifiers #445 review)
  • Extract a shared fence-aware markdown section helper (consumers: vuln_management documentationSections, governance escalationPolicySections; noted in the feat(OSPS-GV-04.01): require review before escalated permissions #446 review)
  • Add a CI guard so the drift does not return, e.g. fail if OSPS- appears in evaluation_plans/ outside evaluation-plans.go (allowing data/catalogs/, badgeurl, and docs)
  • Reword the 14 catalog-ID references in data/ comments (payload.go 2, graphql-binary-check.go 6, rest-data.go 5, vex.go 1, vuln_reporting.go 1), and decide whether the CI guard should cover that directory too. The payload layer gathers GitHub data and is not catalog-specific, so naming controls there is the same drift.

Sequencing

Open PRs #445, #446, and #447 originally followed the drifted style described above. Their new doc comments have since been reworded to the target convention (e922b1f, 7234d5a, ecab5d1), so merging them will not add to the cleanup surface. The remaining pass covers the pre-existing code on main (categories 1 through 3) plus the CI guard.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions