fix(001): ecosystem-scope SDK watchlist + drop contradictory unknown-posture notice (spec 210 verify)#13
Conversation
…unknown-posture notice (spec 210) Two verify-verdict fixes surfaced by review of PR #12: - purl_matches gates on the watchlist entry's ecosystem: a same-named dependency from another ecosystem (pkg:pypi/openai, pkg:cargo/ai) no longer false-matches the npm openai/ai entries on a mixed-language BOM. The ecosystem field (previously dead_code) is now load-bearing; a purl-less component keeps the name-only fallback. - append_posture_binding_findings skips the SBOM cross-check when the binding is internally inconsistent (e.g. an unknown posture string), so a "maybe" posture no longer emits BOTH an error AND a reassuring "DECLARED" notice. Also depth-bounds the recursive BOM component walk (untrusted --sbom-dir input) at MAX_BOM_DEPTH so a pathologically nested BOM stops instead of overflowing the stack. Tests: purl_matcher_gates_on_ecosystem + posture_findings_unknown_posture_errors_without_declared_notice; 108 lib tests pass. spec 001 §3 documents the ecosystem-scoping + the inconsistency short-circuit.
AI Code ReviewReviewBugs and Logic ErrorsName-only fallback is ecosystem-agnostic ( None => name == Some(entry.name.as_str()),When a BOM component carries no
const MAX_BOM_DEPTH: usize = 64;
if depth > MAX_BOM_DEPTH { return None; }
SecurityNo new OWASP-class vulnerabilities introduced. The depth-bound on the recursive BOM walk is the right fix for the untrusted-input concern and is correctly placed. Spec-Spine Compliance
PerformanceNone of the changes introduce a performance regression. SummaryTwo actionable items before merge:
Automated review by Claude. Diff size: 100 lines. |
AI Code ReviewCode ReviewBugs and Logic ErrorsPurl-present suppresses name fallback (intentional but undocumented edge case) In the refactored let matched = match purl {
Some(p) => purl_matches(p, &entry.name, &entry.ecosystem),
None => name == Some(entry.name.as_str()),
};When a component carries a purl from a different ecosystem (e.g. Inconsistency early return skips The early return is correct for the stated goal (no contradictory notice). However, Security
Rust's No file-size guard before Test Coverage Gaps
Spec-Spine ComplianceBoth behavioral changes (ecosystem-gating on purl type and skip-on-inconsistency) are reflected in PerformanceNo concerns. The depth guard improves worst-case behavior for adversarial input. Automated review by Claude. Diff size: 104 lines. |
First release since v0.3.0, bundling PRs #12 and #13 (OAP spec 210 verify half). Additive feature, so this is a minor bump under 0.x. - Added (#12, spec 001): verify-certificate carries and adjudicates the agenticPostureBinding: round-trips it through the typed cert struct so the self-hash and signature hold, then adjudicates internal consistency, an SBOM cross-check of a declared none under --sbom-dir, and the spec 210 FR-004 governance-envelope shape check. - Added (#13, spec 001): ecosystem-scoped the agentic-SDK watchlist (npm openai no longer matches pkg:pypi/openai; purl match anchors on the name segment) and skipped the cross-check when internal consistency already failed, dropping the contradictory unknown-posture notice. Version bumped in lockstep across Cargo.toml, npm/package.json (main + five platform pins), and py/pyproject.toml; Cargo.lock and the codebase-index shard regenerated.
What
Two verify-verdict fixes + one robustness fix for the spec 210 agentic-posture
verifier, surfaced by AI review of PR #12.
HIGH: ecosystem-scope the SDK watchlist match
purl_matchesstrippedpkg:<type>/but ignored the type, so apkg:pypi/openai@1.0.0orpkg:cargo/ai@0.1.0matched the npmopenai/aiwatchlist entries: a cross-ecosystem false positive that would
Contradictanoneposture on a mixed-language BOM. The match now requires the purl<type>to equal the entry's
ecosystem(the field was present butdead_code). When acomponent has a purl, the match gates on it; only a purl-less component falls
back to a name-only match.
MEDIUM: drop the contradictory unknown-posture notice
An unknown posture string (e.g.
"maybe") is an internal-consistency error, butadjudicate_agentic_postureshort-circuited onposture != "none"and returnedDeclared, so the same binding got BOTH the error and a reassuring "agenticposture: DECLARED (agency acknowledged)" notice.
append_posture_binding_findingsnow skips the cross-check when the binding is internally inconsistent: the error
is authoritative.
LOW: depth-bound the BOM component walk
--sbom-diris caller-supplied (untrusted), so the recursivecomponents[]walkis now bounded at
MAX_BOM_DEPTH = 64. Real CycloneDX nesting is shallow, so nolegitimate BOM is truncated; a pathologically nested one stops instead of
overflowing the stack.
Verification
purl_matcher_gates_on_ecosystem(pypi/cargoopenai/aido notmatch npm entries; case-insensitive type),
posture_findings_unknown_posture_errors_without_declared_notice.purl_matcher_anchors_on_the_name_segmentupdated to the 3-arg signature.
spec-spine compile/lint --fail-on-warn/index checkclean; spec 001§3 documents the ecosystem-scoping + the inconsistency short-circuit.
Not changed (reviewed, deliberately out of scope)
load_agentic_sdk_watchlistexpectpanic on a malformed embedded file: abuild-time invariant (committed + tested), consistent with an embedded-asset
contract; left as-is.
_commentkey tolerance and the per-call re-parse (aOnceLockmicro-opt):cosmetic / immaterial for a one-shot CLI.