Repository navigation
fix(severity): one grade per advisory, inherited from GHSA aliases when unrated; one tier for unknown - #986
Merged
Merged
Conversation
runyourempire
added a commit
that referenced
this pull request
Oct 18, 2026
… malware Critical; notices never worded as vulnerabilities (#986 review) B1. One mirror-row grader. osv::severity::cluster_grade runs over a SeverityRecord (MatchedAdvisory or StoredAdvisory): the most severe own grade in the alias group, else the highest GHSA alias grade from AliasGrades. The matcher's surfaces (Upgrade Plan, Preemption, Brief, stack_change) and the mirror-row surfaces now use the same code: - Knowledge Gaps: advisory_tier_for groups the affecting rows by alias (rows_grade); AliasGrades is loaded once per GapScan. - Signal: matcher_verdict grades its checked / exposed rows as one group; mirror_severity_tier reads every row of the item's alias group for the package, not get_osv_advisory_by_id's single GHSA-first row (GHSA-76w9 gave medium for the nix group whose GHSA-wgrg is high). - The scorer reads the alias grades from a copy the Database keeps (Database::alias_grades: one query, dropped on every osv_advisories write, with a write counter so a load that raced a write is not kept), never per item. A five-surface test pins the nix shape and the GO-2024-3333 shape (graded alias stored for another package): high on the plan, Preemption, Brief, Knowledge Gaps, the matcher verdict and the mirror lookup. B2. fourda_depengine::severity::ghsa_aliases used a byte slice (a[..5]) on untrusted alias text and panicked on a multi-byte boundary; it uses get(..5) now, with a test (a 2-byte char across index 5, a 3-byte char at 4). The other slices in this diff index Vecs by construction. Installed malware (recovery-lead decision). A MAL- record on the installed version is Critical in cluster_urgency, and the plan and alert path skip the AD-046 scope rule for it: a dev-only or transitive malicious package still runs its code on the developer's machine. sv-010 -> critical, sv-020 new. S2 and the notice wording. One maintenance predicate (osv::severity::maintenance_text: no fix, no CVSS, unmaintained/deprecated words over summary + details) decides both "may take an alias grade" and "is a notice"; the MCP-style summary-only check is gone. A notice is never counted or worded as a vulnerability: "unmaintained: zvariant (RUSTSEC-2026-0370), no exploitable vulnerability" on the Preemption alert (title and explanation; mixed groups count only vulnerabilities and add the notice sentence), the Upgrade Plan's Watch fold, the Brief (advisory_count 0, no severity in the deterministic line or the prompt), stack_change, Knowledge Gaps (only_maintenance_notices: not a security gap) and Signal (SecurityVerdict.maintenance_only or the item's own text: Watch priority, the notice as the action line and the necessity reason, no applicability). Nits. One tier rank (fourda_depengine::severity::tier_rank, re-exported by osv::severity); brief_facts_build and security_verdict lost their inverted copies, and security_verdict::normalize_tier gave way to canonical_tier. osv_get_matches always serializes severity_from (null for an own grade), and the frontend command type names severity_label / severity_from. PIPELINE_VERSION stays as rebased (the security-lane changes ride the same cve/osv-scoped bump). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KSXWNneouUjTiVV3Rc3FH
runyourempire
force-pushed
the
fix/severity-parity
branch
from
October 18, 2026 12:35
c95d405 to
0ffc64d
Compare
runyourempire
added a commit
that referenced
this pull request
Oct 18, 2026
… malware Critical; notices never worded as vulnerabilities (#986 review) B1. One mirror-row grader. osv::severity::cluster_grade runs over a SeverityRecord (MatchedAdvisory or StoredAdvisory): the most severe own grade in the alias group, else the highest GHSA alias grade from AliasGrades. The matcher's surfaces (Upgrade Plan, Preemption, Brief, stack_change) and the mirror-row surfaces now use the same code: - Knowledge Gaps: advisory_tier_for groups the affecting rows by alias (rows_grade); AliasGrades is loaded once per GapScan. - Signal: matcher_verdict grades its checked / exposed rows as one group; mirror_severity_tier reads every row of the item's alias group for the package, not get_osv_advisory_by_id's single GHSA-first row (GHSA-76w9 gave medium for the nix group whose GHSA-wgrg is high). - The scorer reads the alias grades from a copy the Database keeps (Database::alias_grades: one query, dropped on every osv_advisories write, with a write counter so a load that raced a write is not kept), never per item. A five-surface test pins the nix shape and the GO-2024-3333 shape (graded alias stored for another package): high on the plan, Preemption, Brief, Knowledge Gaps, the matcher verdict and the mirror lookup. B2. fourda_depengine::severity::ghsa_aliases used a byte slice (a[..5]) on untrusted alias text and panicked on a multi-byte boundary; it uses get(..5) now, with a test (a 2-byte char across index 5, a 3-byte char at 4). The other slices in this diff index Vecs by construction. Installed malware (recovery-lead decision). A MAL- record on the installed version is Critical in cluster_urgency, and the plan and alert path skip the AD-046 scope rule for it: a dev-only or transitive malicious package still runs its code on the developer's machine. sv-010 -> critical, sv-020 new. S2 and the notice wording. One maintenance predicate (osv::severity::maintenance_text: no fix, no CVSS, unmaintained/deprecated words over summary + details) decides both "may take an alias grade" and "is a notice"; the MCP-style summary-only check is gone. A notice is never counted or worded as a vulnerability: "unmaintained: zvariant (RUSTSEC-2026-0370), no exploitable vulnerability" on the Preemption alert (title and explanation; mixed groups count only vulnerabilities and add the notice sentence), the Upgrade Plan's Watch fold, the Brief (advisory_count 0, no severity in the deterministic line or the prompt), stack_change, Knowledge Gaps (only_maintenance_notices: not a security gap) and Signal (SecurityVerdict.maintenance_only or the item's own text: Watch priority, the notice as the action line and the necessity reason, no applicability). Nits. One tier rank (fourda_depengine::severity::tier_rank, re-exported by osv::severity); brief_facts_build and security_verdict lost their inverted copies, and security_verdict::normalize_tier gave way to canonical_tier. osv_get_matches always serializes severity_from (null for an own grade), and the frontend command type names severity_label / severity_from. PIPELINE_VERSION stays as rebased (the security-lane changes ride the same cve/osv-scoped bump). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KSXWNneouUjTiVV3Rc3FH
runyourempire
force-pushed
the
fix/severity-parity
branch
from
October 18, 2026 13:01
0ffc64d to
6f13fe5
Compare
runyourempire
added a commit
that referenced
this pull request
Oct 18, 2026
… malware Critical; notices never worded as vulnerabilities (#986 review) B1. One mirror-row grader. osv::severity::cluster_grade runs over a SeverityRecord (MatchedAdvisory or StoredAdvisory): the most severe own grade in the alias group, else the highest GHSA alias grade from AliasGrades. The matcher's surfaces (Upgrade Plan, Preemption, Brief, stack_change) and the mirror-row surfaces now use the same code: - Knowledge Gaps: advisory_tier_for groups the affecting rows by alias (rows_grade); AliasGrades is loaded once per GapScan. - Signal: matcher_verdict grades its checked / exposed rows as one group; mirror_severity_tier reads every row of the item's alias group for the package, not get_osv_advisory_by_id's single GHSA-first row (GHSA-76w9 gave medium for the nix group whose GHSA-wgrg is high). - The scorer reads the alias grades from a copy the Database keeps (Database::alias_grades: one query, dropped on every osv_advisories write, with a write counter so a load that raced a write is not kept), never per item. A five-surface test pins the nix shape and the GO-2024-3333 shape (graded alias stored for another package): high on the plan, Preemption, Brief, Knowledge Gaps, the matcher verdict and the mirror lookup. B2. fourda_depengine::severity::ghsa_aliases used a byte slice (a[..5]) on untrusted alias text and panicked on a multi-byte boundary; it uses get(..5) now, with a test (a 2-byte char across index 5, a 3-byte char at 4). The other slices in this diff index Vecs by construction. Installed malware (recovery-lead decision). A MAL- record on the installed version is Critical in cluster_urgency, and the plan and alert path skip the AD-046 scope rule for it: a dev-only or transitive malicious package still runs its code on the developer's machine. sv-010 -> critical, sv-020 new. S2 and the notice wording. One maintenance predicate (osv::severity::maintenance_text: no fix, no CVSS, unmaintained/deprecated words over summary + details) decides both "may take an alias grade" and "is a notice"; the MCP-style summary-only check is gone. A notice is never counted or worded as a vulnerability: "unmaintained: zvariant (RUSTSEC-2026-0370), no exploitable vulnerability" on the Preemption alert (title and explanation; mixed groups count only vulnerabilities and add the notice sentence), the Upgrade Plan's Watch fold, the Brief (advisory_count 0, no severity in the deterministic line or the prompt), stack_change, Knowledge Gaps (only_maintenance_notices: not a security gap) and Signal (SecurityVerdict.maintenance_only or the item's own text: Watch priority, the notice as the action line and the necessity reason, no applicability). Nits. One tier rank (fourda_depengine::severity::tier_rank, re-exported by osv::severity); brief_facts_build and security_verdict lost their inverted copies, and security_verdict::normalize_tier gave way to canonical_tier. osv_get_matches always serializes severity_from (null for an own grade), and the frontend command type names severity_label / severity_from. PIPELINE_VERSION stays as rebased (the security-lane changes ride the same cve/osv-scoped bump). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KSXWNneouUjTiVV3Rc3FH
runyourempire
force-pushed
the
fix/severity-parity
branch
from
October 18, 2026 13:29
6f13fe5 to
65891fc
Compare
runyourempire
added a commit
that referenced
this pull request
Oct 18, 2026
…WE ids stored `fourda_depengine::is_malware(id, aliases, cwe_ids)`: a malicious-package record is an OSV `MAL-` id or alias, or carries CWE-506 in database_specific.cwe_ids. GitHub's malware advisories often have no `MAL-` alias: crossenv GHSA-c2m4-w5hm-vqjw ("crossenv is malware") has aliases ["CVE-2017-16074"] and cwe_ids ["CWE-506"] (live 2026-10-18), so the parent-release predicate read it as an unfixed ordinary advisory. No summary keyword is read (the release gate's "Malicious code in" prefix check is replaced by the shared rule). Phase 128 adds osv_advisories.cwe_ids (additive; schema 128, so a 127 binary refuses the database through the existing too-new guard) and makes every ecosystem's advisory sync due, so rows stored before it are re-upserted with their CWE ids on the next cycle instead of staying NULL. The sync stores database_specific.cwe_ids; StoredAdvisory and MatchedAdvisory carry them. Wired where MAL- was matched: the parent-release Advisory (osv/parent_release.rs) and the release gate (osv/release_advisories.rs). Severity is left to #986. No new egress. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018hjX3pEMmC7CHfG41PiPj7
runyourempire
added a commit
that referenced
this pull request
Oct 18, 2026
…WE ids stored `fourda_depengine::is_malware(id, aliases, cwe_ids)`: a malicious-package record is an OSV `MAL-` id or alias, or carries CWE-506 in database_specific.cwe_ids. GitHub's malware advisories often have no `MAL-` alias: crossenv GHSA-c2m4-w5hm-vqjw ("crossenv is malware") has aliases ["CVE-2017-16074"] and cwe_ids ["CWE-506"] (live 2026-10-18), so the parent-release predicate read it as an unfixed ordinary advisory. No summary keyword is read (the release gate's "Malicious code in" prefix check is replaced by the shared rule). Phase 128 adds osv_advisories.cwe_ids (additive; schema 128, so a 127 binary refuses the database through the existing too-new guard) and makes every ecosystem's advisory sync due, so rows stored before it are re-upserted with their CWE ids on the next cycle instead of staying NULL. The sync stores database_specific.cwe_ids; StoredAdvisory and MatchedAdvisory carry them. Wired where MAL- was matched: the parent-release Advisory (osv/parent_release.rs) and the release gate (osv/release_advisories.rs). Severity is left to #986. No new egress. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018hjX3pEMmC7CHfG41PiPj7
…en unrated; one tier for unknown Severity parity with @4da/mcp-server, pinned by a new shared vector file (src-tauri/tests/conformance/vectors/severity.jsonl, sv-001..sv-019). Unrated records. A record with no curated label and no scorable CVSS takes the HIGHEST grade among all of its GHSA aliases readable in the local mirror (osv_advisories, any package or ecosystem), named by the smallest GHSA id on a tie; an unreadable alias never lowers it; none readable leaves it unknown. Maintenance notices are never graded from an alias (the MCP's isMaintenanceNotice). The rule is the pure fourda_depengine::severity (twin of the MCP's gradeFromAliases); osv::severity::grade_unrated applies it once per matching pass over the mirror rows get_matched_advisories already reads: no network, no extra query, nothing per advisory. Provenance. MatchedAdvisory carries severity_from (the GHSA id); an inherited grade is always shown with it: "high (from GHSA-w32m-9786-jp63)" in the Upgrade Plan explanation and citation notes, the Preemption alert explanation, the Brief (SecurityFact.worst_tier_from, rendered by the deterministic brief, the LLM prompt and the stack-change stream item). EvidenceItem's ConfidenceProvenance is a closed enum (Heuristic / OsvVerified / ...) naming how the confidence number was derived; adding a variant for a severity source would extend the canonical type (doctrine rule 1, needs an ADR), so the alias goes in the explanation and the citation note instead. Cluster grade. A vulnerability cluster (one alias group) takes the MOST SEVERE OWN grade among its records; an inherited grade applies only when no record has one. Before, cluster_severity_tier took the highest CVSS band whenever any record was scored and ignored labels: crates.io nix (GHSA-76w9 CVSS 6.7, GHSA-wgrg label HIGH, RUSTSEC-2021-0119) read medium on the plan, alerts and Brief and high on Knowledge Gaps. Knowledge Gaps, the plan, the alert path, the Brief and the scorer's security lane now grade each record by one function, osv::severity::row_grade. Per-record order. The curated label first, the CVSS band second (the mirror's stored severity_label order). Every grader used to read CVSS first. On the 3,923 pinned conformance records the two orders disagree on 123, all GHSA, 113 of them beside a CVSS v4 vector neither engine scores, which GitHub's label follows (GHSA-23hp-3jrh-7fpw: v3 7.5, label CRITICAL). Pinned: sv-015..sv-017. Unknown tier. One rule for a cluster nothing grades, on the plan and the alerts (osv::severity::cluster_urgency): Medium; Watch for maintenance notices only (no fix, no CVSS, unmaintained/deprecated text, the plan's informational fold); High for a malicious-package record (MAL-). The alert path used to guess from the first record's summary words (infer_urgency_from_summary, deleted): Watch unless it said "rce" / "xss" etc. Accuracy first: a version-confirmed vulnerability with a fix is not dismissed to Watch on a keyword miss, nor raised to High on a keyword hit; Medium says what is known. The AD-046 scope rule (scope_adjusted_urgency) still applies on top, so a dev-only unknown reads Watch on both surfaces. Scoring. PIPELINE_VERSION 42 -> 43, registered in SCOPED_EPOCHS on source_type IN ('cve','osv'): the security lane's tier (advisory_tier, mirror_severity_tier, content_severity_tier) moves to the label-first order, which can change a persisted signal_priority / critical-alert flag (the v39 precedent). The tier is computed only for is_security_source. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KSXWNneouUjTiVV3Rc3FH
… malware Critical; notices never worded as vulnerabilities (#986 review) B1. One mirror-row grader. osv::severity::cluster_grade runs over a SeverityRecord (MatchedAdvisory or StoredAdvisory): the most severe own grade in the alias group, else the highest GHSA alias grade from AliasGrades. The matcher's surfaces (Upgrade Plan, Preemption, Brief, stack_change) and the mirror-row surfaces now use the same code: - Knowledge Gaps: advisory_tier_for groups the affecting rows by alias (rows_grade); AliasGrades is loaded once per GapScan. - Signal: matcher_verdict grades its checked / exposed rows as one group; mirror_severity_tier reads every row of the item's alias group for the package, not get_osv_advisory_by_id's single GHSA-first row (GHSA-76w9 gave medium for the nix group whose GHSA-wgrg is high). - The scorer reads the alias grades from a copy the Database keeps (Database::alias_grades: one query, dropped on every osv_advisories write, with a write counter so a load that raced a write is not kept), never per item. A five-surface test pins the nix shape and the GO-2024-3333 shape (graded alias stored for another package): high on the plan, Preemption, Brief, Knowledge Gaps, the matcher verdict and the mirror lookup. B2. fourda_depengine::severity::ghsa_aliases used a byte slice (a[..5]) on untrusted alias text and panicked on a multi-byte boundary; it uses get(..5) now, with a test (a 2-byte char across index 5, a 3-byte char at 4). The other slices in this diff index Vecs by construction. Installed malware (recovery-lead decision). A MAL- record on the installed version is Critical in cluster_urgency, and the plan and alert path skip the AD-046 scope rule for it: a dev-only or transitive malicious package still runs its code on the developer's machine. sv-010 -> critical, sv-020 new. S2 and the notice wording. One maintenance predicate (osv::severity::maintenance_text: no fix, no CVSS, unmaintained/deprecated words over summary + details) decides both "may take an alias grade" and "is a notice"; the MCP-style summary-only check is gone. A notice is never counted or worded as a vulnerability: "unmaintained: zvariant (RUSTSEC-2026-0370), no exploitable vulnerability" on the Preemption alert (title and explanation; mixed groups count only vulnerabilities and add the notice sentence), the Upgrade Plan's Watch fold, the Brief (advisory_count 0, no severity in the deterministic line or the prompt), stack_change, Knowledge Gaps (only_maintenance_notices: not a security gap) and Signal (SecurityVerdict.maintenance_only or the item's own text: Watch priority, the notice as the action line and the necessity reason, no applicability). Nits. One tier rank (fourda_depengine::severity::tier_rank, re-exported by osv::severity); brief_facts_build and security_verdict lost their inverted copies, and security_verdict::normalize_tier gave way to canonical_tier. osv_get_matches always serializes severity_from (null for an own grade), and the frontend command type names severity_label / severity_from. PIPELINE_VERSION stays as rebased (the security-lane changes ride the same cve/osv-scoped bump). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KSXWNneouUjTiVV3Rc3FH
…until fix/malware-cwe) contains_malware now reads a MAL- id OR a MAL- alias (a GHSA malware advisory listing its OpenSSF record). The shared fourda_depengine malware predicate, with database_specific.cwe_ids CWE-506 (GHSA-c2m4-w5hm-vqjw, crossenv, has no MAL alias), lands with fix/malware-cwe and replaces it; the crossenv vector waits for that. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KSXWNneouUjTiVV3Rc3FH
…depengine::is_malware); crossenv vector on contains_malware now calls fourda_depengine::is_malware over each match's (advisory_id, aliases, cwe_ids): a MAL- id or alias, or CWE-506 in database_specific.cwe_ids. The local MAL-only predicate is deleted. Stacked on fix/malware-cwe (#992), which stores cwe_ids; this lands after it. sv-021: crossenv GHSA-c2m4-w5hm-vqjw (live OSV 2026-10-18: aliases [CVE-2017-16074], cwe_ids [CWE-506], own label HIGH) on the installed 1.0.1 is Critical, its severity its own high. The vector checker reads database_specific.cwe_ids as osv::sync stores it. Knowledge Gaps reads the cwe_ids column with the rows it grades. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KSXWNneouUjTiVV3Rc3FH
…edAdvisory::is_malware); sv-022 title-only malware contains_malware calls MatchedAdvisory::is_malware, the merged fourda_depengine::is_malware(id, aliases, cwe_ids, summary): a MAL- id or alias, CWE-506, or GitHub's "Malicious Package in" / "Malicious code in" title. #992's unrated-malware test now pins Critical on the alert path (most_urgent_tier) instead of the deleted summary heuristic. sv-022: GHSA-28f8-hqmc-7ph8 "Malicious Package in ember-power-timepicker" (live OSV 2026-10-19: no aliases, cwe_ids [], own label CRITICAL, versions [1.0.8]) installed is Critical; a unit test pins the title arm beside a low own grade. Restores a closing brace the rebase dropped in briefing_deterministic_tests.rs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KSXWNneouUjTiVV3Rc3FH
runyourempire
force-pushed
the
fix/severity-parity
branch
from
October 18, 2026 16:47
65891fc to
4e63d7c
Compare
runyourempire
enabled auto-merge
October 18, 2026 16:51
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
This PR gives each advisory one severity in every engine and on every surface. It covers the app half of the parity rule agreed with recovery-lead, which the
@4da/mcp-server6.2.5 integration also adopts.MatchedAdvisory.severity_fromnames the alias, and every surface prints it as "high (from GHSA-…)": the Upgrade Plan explanation and citations, the Preemption explanation, the Brief (deterministic and prompt), and stack-change.cluster_severity_tiertook the highest CVSS band whenever any record had a score, and ignored labels.nixread medium on the plan, Preemption and Brief, but high on Knowledge Gaps.knowledge_decay, the plan, alerts, the Brief and the scorer's security lane now all grade through one function (osv::severity::row_grade/cluster_severity).osv::severity::cluster_urgency). Before, the plan said Medium and alerts guessed from keywords in the first record's summary (infer_urgency_from_summary, now deleted).MAL-record: High. This is unchanged from the old heuristic's id check, which is the source's own statement.Review round (2026-10-19)
This is stacked on #992 (
fourda_depengine::is_malwareplus thecwe_idscolumn), so it must land after #992.osv::severity::cluster_grade, over matched advisories and raw mirror rows. The mirror lookup reads the whole alias group, so nix is high, not medium. A five-surface test pins the nix and GO-2024-3333 shapes.MAL-id or alias, or CWE-506) is Critical and exempt from the AD-046 scope discount. The crossenv GHSA-c2m4 record is pinned as sv-021.Tier changes on a read-only copy of the live database
cwe_ids.Parity status: the MCP half is NOT merged yet
This is the app half. The
@4da/mcp-serverhalf (label-first per record, worst own grade per cluster, alias inheritance, the unknown tier, installedMAL-Critical, andseverityin the TS vector runner) exists only on unmerged MCP branches today. Until it merges and the MCP corpus pin moves to a 4DA commit that containsseverity.jsonl, the two engines can still disagree on unrated advisories. That is a hard gate before any MCP publish.Scoring version
PIPELINE_VERSIONgoes 42 → 43 and is registered inSCOPED_EPOCHSforsource_type IN ('cve','osv').signal_priorityand the critical-alert flag. The v39 precedent treats that kind of change as needing a bump.Shared vectors
src-tauri/tests/conformance/vectors/severity.jsonlhas 19 lines. They are documented in the vectors README, run by the Rust gate through the real code path, and mirrored in the MCP runner. They cover:MAL-, a maintenance notice, and thenixgroup;Live effect, on a read-only copy of the operator database
Not here
ConfidenceProvenancegets no new variant. It is a closed list describing how the confidence number was computed, and extending it is a canonical-type change that needs an ADR (doctrine rule 1). Provenance goes in the explanation and the citation note instead.fix/h1-parent-release(fix(upgrade-plan): name the parent release that fixes a nested advisory (audit H1) #981) inupgrade_plan.rs,osv/mod.rs,vectors_tests.rsand the vectors README, so whichever lands second rebases.Checks
cargo clippy --locked -- -D warnings: clean.cargo test --libacross osv, evidence, preemption, brief_facts, scoring, knowledge_decay, briefing, stack_change and morning: 1,847 passed, including the vector gate.check-file-sizes: no errors.🤖 Generated with Claude Code
https://claude.ai/code/session_015KSXWNneouUjTiVV3Rc3FH