For the complete documentation index, see llms.txt. This page is also available as Markdown.

2025

v0.2.2 (2025-12-19)

Features

  • Checks can now be marked as not applicable to a component (for example, a Go-specific check on a repository with no Go code): calling the new Check.skip(reason) method reports the check with the new skipped status (CheckStatus.SKIPPED) and discards any assertions recorded before the skip.

v0.2.1 (2025-11-06)

Features

  • Check and Node gain get_value_or_default(path, default), which returns the given default when there is no value at the path — instead of raising an error or, while data collection is still in progress, marking the check pending.

v0.2.0 (2025-11-05)

Breaking changes

Node-based data access API

The SDK's data access layer is rebuilt around the new Node class, which represents a location in the component JSON and navigates relative to that location. Check.get_node(path) returns a Node; nodes expose get_value, get_all_values, exists, and get_node, with paths resolved relative to the node and data accessed lazily. Checks and nodes can also be iterated — lists yield child nodes, dicts yield keys — and items() yields key/child-node pairs.

Upgrading from 0.1.x requires policy changes:

  • ComponentData and Path are removed. Build a Node instead — Node.from_bundle_file, Node.from_bundle_json, Node.from_component_json_file, or Node.from_component_json — and pass it to Check(name, node=...). When no node is given, checks still load the component JSON automatically from LUNAR_BUNDLE_PATH.

  • check.get(path) is renamed to check.get_value(path), and check.get_all(path) to check.get_all_values(path). Both now default to ., the current node's value.

  • Paths use a strict JSON path grammar — dot segments (.foo), bracketed keys (['foo-bar']), and array indexes ([0]) — that can be concatenated for relative navigation. General JSONPath expressions such as $ roots, wildcards, and filters are no longer accepted. Because the SDK now parses paths itself, the jsonpath-ng dependency is gone and lunar-policy has no runtime dependencies.

  • CheckStatus.NO_DATA is renamed to CheckStatus.PENDING; policy code that references the old member must be updated. The status value reported in check results is still no-data.

v0.1.7 (2025-10-01)

Improvements

  • lunar-policy can now be installed on Python 3.9 and newer; earlier releases required Python 3.13.

v0.1.6 (2025-08-20)

Breaking changes

  • Component data loaded with ComponentData.from_file or ComponentData.from_json must now include a bundle_info key, which carries the workflow-completion signal; Lunar-provided data includes it automatically, but hand-written fixtures used for local policy testing need to add it, and ComponentData.from_component_json accepts a new optional bundle_info argument.

  • The get_or_default and get_all_or_default methods are removed; use exists() to probe for optional data, or catch NoDataError where a default value is genuinely wanted.

Features

  • The new assert_exists(Path(path)) assertion and exists(path) helper test whether a path is present in the component data; assert_exists requires a Path object, while exists accepts a path string. Before all CI workflows for the commit have finished, a missing path keeps the usual no-data behavior; afterward, assert_exists fails the check and exists returns False.

Improvements

Missing data becomes conclusive once collectors finish

Checks now distinguish data that has not been collected yet from data that is conclusively absent. Lunar records in the component data whether all CI workflows for the commit have completed, and the SDK reads that signal whenever a queried path has no data.

While workflows are still running, missing data behaves as before: the check ends early and reports no-data, and Lunar re-evaluates the policy as more data is collected. Once all workflows have finished, missing data is no longer treated as pending: assert_exists fails the check, exists returns False, and other assertions or get calls that hit a missing path report an error instead of leaving the check no-data indefinitely.

  • NoDataError can now be imported directly from the package root (from lunar_policy import NoDataError), for policies that handle missing data themselves.

Bug fixes

  • Result reporting is fixed for policy scripts that define more than one check: each check's results are now emitted on a separate line, so checks after the first are no longer misread.

v0.1.5 (2025-06-27)

Features

  • Policy scripts can now write ordinary log output to stdout: check results are emitted with the marker Lunar provides via LUNAR_LOG_PREFIX, so the platform can separate result reporting from anything else the script prints and capture the rest as script logs; when the marker is not set, output is unchanged.

Bug fixes

  • The missing-data check status is now reported as no-data instead of no_data, making the value consistent with the rest of Lunar; it previously surfaced as no_data in the checks SQL view.

v0.1.4 (2025-06-03)

Breaking changes

  • The submit() method on Check is removed — results are submitted automatically when the with block exits — and name is now a read-only property; the previously public description attribute is now internal.

  • The SnippetData class is renamed to ComponentData, matching what it holds — the component JSON a policy evaluates; update imports and references, the from_file, from_json, and from_component_json constructors are unchanged.

  • Check.failure_reasons now returns a list of failure messages instead of a single comma-separated string.

Features

  • New get_or_default and get_all_or_default methods on Check return a default value instead of ending the check as no_data when a path has no data.

Improvements

  • Unexpected exceptions inside a check now produce a distinct error check status instead of being recorded as an assertion failure, separating broken policy code from genuine policy violations; the new value is available as CheckStatus.ERROR.

  • When a check ends early because data is missing, the recorded result now includes a message naming the path that had no data (for example, No data found for .sbom).

v0.1.3 (2025-05-28)

Breaking changes

Explicit Path objects for component-data queries

Component-data lookups in assertions are now expressed with the new Path class, and assertions no longer guess whether a string argument is a JSON path: a plain string is always treated as a literal value.

Previously, any string beginning with . was interpreted as a path, which made it impossible to assert against literal values that merely look like paths. Path replaces the former JsonPathExpression class, and paths may now be written with an explicit $ root prefix (for example Path("$.readme.exists")); either way they are evaluated from the root of the component JSON. String arguments to get and get_all are still interpreted as paths.

  • The assert_exists and assert_missing assertions are removed; assert on the value itself instead.

  • A check now ends at the first missing-data access, recording a single no_data result and skipping the rest of the block, instead of every assertion reporting no_data individually; accordingly, get and get_all raise NoDataError when a path has no data — handled automatically by the Check context manager — instead of returning None or an empty list.

Features

  • The new fail() method on Check explicitly fails a check with an optional failure message, for conditions the built-in assertions cannot express.

  • New status and failure_reasons properties on Check expose the outcome of a check — useful for unit-testing policies; statuses are values of the CheckStatus enum, which replaces OpResult.

  • The new SnippetData.from_component_json constructor loads a plain component JSON document as both the merged view and a single delta, so a policy can be exercised against a raw component JSON.

Improvements

  • An unhandled exception inside a with Check(...) block is now recorded on the check as a failed assertion carrying the error message, so the failure shows up in the check results rather than only in the script's output; the exception still propagates after the check is submitted.

Bug fixes

  • lunar_policy.__version__ now reports the package version; it previously reported 0.0.1 regardless of the installed release.

v0.1.2 (2025-05-20)

Breaking changes

Package renamed to lunar-policy

The Policy Python SDK is now published on PyPI as lunar-policy, replacing the lunar-checks name; the package was originally published as lunar-snippets. Install it with pip install lunar-policy and import it as lunar_policy:

Aside from the name, the package contents are identical to lunar-checks 0.1.1. Update policy dependencies and imports to the new name; the older package names no longer receive updates.

Last updated