Result model
5 minutes read
Every check(purlOrName, version, asOf?) call and fromLookupProduct conversion returns a Result conforming to schemas/result.v1.schema.json (JSON Schema draft 2020-12). Types live in src/result.ts, src/check.ts, and src/domain.ts.
Stability tags on Result and ResultMatch match the JSDoc annotations in src/result.ts:
@stable: additive-only contract through 1.0; field name and meaning will not change incompatibly.@experimental: evolving behavior; field name, optionality, or semantics are not promised and may change before 1.0.
check → Result (CheckResult)
| Field | Type | Stability | Meaning |
|---|---|---|---|
schemaVersion |
1 |
@stable |
Fixed version number of this result model (RESULT_SCHEMA_VERSION). |
status |
"ok" | "deprecated" | "unsupported" | "end-of-life" | "removed" | "scheduled" |
@stable |
Primary verdict. "ok" when no rule matches; otherwise the most serious matching event (short names; see mapping below). |
matches |
ResultMatch[] |
@stable |
Every matching rule, ordered by event seriousness then earliest date. Empty when status is "ok". |
version |
string |
@stable |
The version argument exactly as passed to check (not normalised). |
asOf |
string (optional) |
@experimental |
The day daysLeft is measured from (YYYY-MM-DD), when supplied. Omitted for the two-argument call. |
ResultMatch (CheckMatch)
| Field | Type | Stability | Meaning |
|---|---|---|---|
ruleId |
string |
@stable |
Id of the matching registry rule. |
event |
"deprecated" | "unsupported" | "end-of-life" | "removed" | "scheduled" |
@stable |
Lifecycle event on that rule, in check's short form. |
date |
string | null |
@stable |
Deadline from the rule (YYYY-MM-DD), or null when the rule has no deadline. |
daysLeft |
number | null |
@experimental |
Whole UTC days from asOf until date; null when past, undated, or asOf is omitted. |
replacement |
string | null |
@stable |
Suggested replacement from the rule, or null when none. |
sources |
EvidenceSource[] |
@stable |
Authoritative evidence pages the rule cites. |
reviewedAt |
string |
@stable |
Date (YYYY-MM-DD) a maintainer last reviewed the rule against its sources. |
Shared: EvidenceSource
Defined in src/domain.ts and used by both ResultMatch.sources and LookupFinding.sources.
| Field | Type | Meaning |
|---|---|---|
title |
string |
Name of the evidence page. |
url |
string |
URL of that page (https://). |
accessedAt |
string (optional) |
Day the page was reviewed (YYYY-MM-DD). |
Complete examples
Scheduled release line with an explicit asOf day (check("node", "22.12.0", "2026-04-01")):
{
"schemaVersion": 1,
"status": "scheduled",
"matches": [
{
"ruleId": "nodejs.runtime.eol-22",
"event": "scheduled",
"date": "2027-04-30",
"daysLeft": 394,
"replacement": "Node.js 24 LTS or later",
"sources": [
{
"title": "Node.js Release Working Group schedule",
"url": "https://github.com/nodejs/Release/blob/main/schedule.json",
"accessedAt": "2026-10-24"
}
],
"reviewedAt": "2026-10-24"
}
],
"version": "22.12.0",
"asOf": "2026-04-01"
}
Supported or unknown package with no matching rule (check("pkg:generic/nodejs", "24.0.0")):
{
"schemaVersion": 1,
"status": "ok",
"matches": [],
"version": "24.0.0"
}
Field reference: Result
schemaVersion
- Stability:
@stable - Type: integer constant
1(RESULT_SCHEMA_VERSION, required) - Meaning: Identifies schema
v1of the result payload. New fields inv1are additive only;schemaVersionis never bumped without an accepted decision record.
Example:
1
status
- Stability:
@stable - Type:
"ok" | "deprecated" | "unsupported" | "end-of-life" | "removed" | "scheduled"(required) - Meaning: Primary verdict for the checked version. Always
"ok"if and only ifmatchesis empty; otherwise equals theeventof the first element inmatches(most serious event according tolifecycleEventPrecedence:end-of-life,removed,unsupported,deprecated,scheduled).
Example:
"scheduled"
matches
- Stability:
@stable - Type:
ResultMatch[](required) - Meaning: Every active rule whose version range contains the input
version, ordered by event seriousness first and earliestdatesecond (undated rules sort after dated ones; ties preserve registry rule order). Empty ([]) whenstatusis"ok".
Example:
[
{
"ruleId": "osv.npm.request",
"event": "deprecated",
"date": null,
"daysLeft": null,
"replacement": null,
"sources": [
{
"title": "GHSA-p8p7-x288-28g6",
"url": "https://osv.dev/vulnerability/GHSA-p8p7-x288-28g6",
"accessedAt": "2026-10-27"
}
],
"reviewedAt": "2026-10-27"
}
]
version
- Stability:
@stable - Type: non-empty
stringcontaining non-whitespace characters (required) - Meaning: The
versionstring exactly as supplied by the caller, without stripping whitespace, leadingv, or build metadata (+...), even though matching normalises those before testingversranges.
Example:
"22.12.0"
asOf
- Stability:
@experimental(do not rely on this field name or shape as frozen before 1.0) - Type:
YYYY-MM-DDstring(optional) - Meaning: Present today when the caller passes an explicit
asOfdate string tocheckorfromLookupProduct, and omitted in the two-argument call. Never read from a system clock. BecauseasOfis@experimental, whether it remains optional onResult, changes name, or moves into another structure is not guaranteed across pre-1.0 releases.
Example:
"2026-04-01"
Field reference: ResultMatch
ruleId
- Stability:
@stable - Type:
stringmatching^[a-z0-9]+(?:[.-][a-z0-9]+)*$(required) - Meaning: Identifier of the matched rule in
registry/*.json(for example"nodejs.runtime.eol-22"or"npm.package.request.deprecated").
Example:
"nodejs.runtime.eol-22"
event
- Stability:
@stable - Type:
"deprecated" | "unsupported" | "end-of-life" | "removed" | "scheduled"(required) - Meaning: Lifecycle event recorded on the matching rule, expressed in the result model's short enum (mapping
"end-of-support"to"unsupported"and"scheduled-end-of-life"to"scheduled"). Status and event values are never renamed.
Example:
"deprecated"
date
- Stability:
@stable - Type:
YYYY-MM-DDstring | null(required) - Meaning: Announced lifecycle deadline from the rule, or
nullwhen the rule carries no deadline date.
Example:
"2027-04-30"
daysLeft
- Stability:
@experimental(do not treat this behavior as promised before 1.0) - Type: positive
integer(>= 1) ornull(required in v1 JSON, value semantics are experimental) - Meaning: Currently reports whole UTC calendar days from
asOfuntildatewhenasOfis provided anddateis strictly afterasOf, andnullotherwise (past, same-day, undated, or two-argument no-asOfcalls). BecausedaysLeftis@experimental, its name, nullability, whether past deadlines report negative counts, and which events populate it are not promised before 1.0.
Example:
394
replacement
- Stability:
@stable - Type: non-empty
string | null(required) - Meaning: Maintainer-reviewed replacement guidance from the rule when present, or
nullwhen the rule does not specify a replacement.
Example:
"Node.js 24 LTS or later"
sources
- Stability:
@stable - Type: non-empty array of
EvidenceSourceobjects (minItems: 1, required) - Meaning: Authoritative external pages (release schedules, package deprecations, official advisories) backing the rule's lifecycle claim.
Example:
[
{
"title": "request package deprecation notice",
"url": "https://www.npmjs.com/package/request",
"accessedAt": "2026-10-13"
}
]
reviewedAt
- Stability:
@stable - Type:
YYYY-MM-DDstring(required) - Meaning: Date a maintainer last reviewed the matched rule against its cited sources (
rule.provenance.reviewedAt). Carried directly on each match so callers can check evidence freshness without consulting separate files.
Example:
"2026-10-24"
Field reference: EvidenceSource
Each entry in ResultMatch.sources matches $defs.source in schemas/result.v1.schema.json.
title
- Type: non-empty
string(required) - Meaning: Human-readable title of the authoritative source document or notice.
Example:
"Node.js Release Working Group schedule"
url
- Type:
https://URLstring(required) - Meaning: HTTPS link to the authoritative source page.
Example:
"https://github.com/nodejs/Release/blob/main/schedule.json"
accessedAt
- Type:
YYYY-MM-DDstring(optional) - Meaning: Calendar day that source page was fetched or checked when recording provenance, when supplied by the registry rule. Distinct from
reviewedAton the rule/match.
Example:
"2026-10-24"
Status name mapping
check shortens two registry events; lookupProduct keeps the registry names and uses "supported" / "ok" differently for "nothing matched":
Registry / lookupProduct status |
check / Result status |
|---|---|
"supported" (no match) |
"ok" (no match) |
"deprecated" |
"deprecated" |
"end-of-support" |
"unsupported" |
"end-of-life" |
"end-of-life" |
"removed" |
"removed" |
"scheduled-end-of-life" |
"scheduled" |
Legacy: lookupProduct → LookupResult
lookupProduct stays available for existing callers (schemaVersion: "ebb.lookup.v1"). Use fromLookupProduct(old, asOf?) to convert a versioned LookupResult into the v1 Result model above.
| Field | Type | Meaning |
|---|---|---|
schemaVersion |
"ebb.lookup.v1" |
Fixed schema id for this legacy result shape. |
query |
{ name: string; version?: string } |
Echo of the caller's arguments. version is omitted when the caller did not pass one. |
query.name |
string |
Product name or package URL as given. |
query.version |
string (optional) |
Version as given, when present. |
product |
{ id: string; purl: string; name: string; ecosystems: string[] } |
The resolved product record. |
product.id |
string |
Stable product id. |
product.purl |
string |
Canonical package URL for the product. |
product.name |
string |
Display name. |
product.ecosystems |
string[] |
Ecosystems that product appears in. |
version |
string (optional) |
Version as given; omitted when the caller did not pass one. |
status |
LifecycleEvent | "supported" |
Primary verdict from findings, or "supported" when none match. Uses registry event names (not Result's short forms). |
deadline |
string (optional) |
Earliest deadline among findings that have one; omitted when none do. |
replacement |
string (optional) |
Replacement from the primary finding; omitted when that finding has none. |
findings |
LookupFinding[] |
Matching rules (all product rules when no version; version-filtered otherwise), sorted by deadline then rule id. |
LifecycleEvent is "deprecated" \| "end-of-support" \| "end-of-life" \| "removed" \| "scheduled-end-of-life".
LookupFinding
| Field | Type | Meaning |
|---|---|---|
ruleId |
string |
Id of the matching registry rule. |
ecosystem |
string |
Ecosystem the rule belongs to. |
event |
LifecycleEvent |
Lifecycle event on that rule (registry names). |
severity |
"info" | "low" | "medium" | "high" | "critical" |
How much attention the rule assigns. |
title |
string |
Short rule title. |
summary |
string |
Longer rule summary. |
deadline |
string (optional) |
Rule deadline when present. |
replacement |
string (optional) |
Suggested replacement when present. |
affectedVersions |
string |
The rule's vers range string. |
sources |
EvidenceSource[] |
Authoritative evidence pages the rule cites. |