v1.14.0
New Collectors
- ticket-coverage (experimental) — records what share of a component's recent pull requests referenced an issue-tracker ticket. Runs on the default branch over Lunar's own history, so change-management coverage reads as a trend on the component rather than only as a verdict on each individual pull request (#288).
- codeql / monorepo-fanout (new sub-collector on the existing
codeqlcollector) — redistributes a monorepo's repo-wide CodeQL findings to its subdirectory components, attributing each finding to the components whose paths claim it. Without it, every subcomponent of a monorepo reads as unscanned even though CodeQL scanned the whole repo; a finding no component claims stays on the root. Target it at the repository root component and enable it alongsidecodeql.cicd, which writes the findings it fans out (#293).
New Policies
- ticket-coverage (experimental) — scores a component on the share of its recent pull requests that referenced a ticket. Evaluated on the default branch, so change-management coverage counts toward initiative and domain scores instead of only appearing on individual pull requests (#288).
Improvements
- backstage collector:
auth_mode: sigv4for Backstage APIs fronted by AWS IAM auth (e.g. Amazon API Gateway) that reject Bearer tokens — setaws_region(andaws_service, defaultexecute-api); credentials resolve at runtime from the standard AWS chain, so they self-refresh with nothing to rotate. Adds anapi_path_prefixinput (default/api) for catalogs mounted at the root behind a gateway that strips the/apihop. Brings the collector to parity with thebackstagecataloger; an auth failure never discards the parse and lint results (#294). - sca and container-scan policies: new
ignore_unfixableinput (defaultfalse) onmax-severity, narrowing the failure to findings that carry an upgrade target so an unfixable base-image or upstream advisory can't hold a release gate closed indefinitely. It can only turn a FAIL into a PASS, unfixable findings are still collected and still visible, and summary-only scans fail as if the option were off and say why. Also collapses findings double-written when two scanners write the same path, so a CVE is enumerated once rather than once per scanner (#289). - sca and container-scan
max-severitynow emits one failing assertion per offending finding (severity headline first, then most severe finding first) instead of a truncated list ending in a "see component JSON" pointer that meant nothing to the developer reading the PR comment. Also wires both policies into the root+testtarget — they had test suites CI was never running (#252). - Manifest snippet allow-list now accepts the
metaandfailureTextsnippet fields, which the hub has decoded since 2026-08-25 but the validator rejected as unknown keys. The unknown-key error no longer asserts that the hub ignores the key, and the allow-list records the upstream commit it was derived from so the next drift is auditable (#292).
Fixes
- backstage cataloger: components whose git repository doesn't exist are now skipped instead of catalogued, via the new
verify_reposinput (defaulttrue). A Backstage id annotation is a claim about a repo, not a fact, so a renamed, deleted or typo'd slug used to create a component with nothing behind it. This stays inert until the new optionalGH_TOKENsecret is set. Lookups are batched ~100 repos per GraphQL request, each host in a multi-host catalog is verified independently, and a component is dropped only on an explicitNOT_FOUND— never on a nulldatafield alone, which GitHub also returns forFORBIDDENand partialSERVICE_UNAVAILABLE. Also fixes an explicit emptycomponent_id_prefixbeing clobbered back togithub.com/, which made a multi-host catalog impossible to express (#295). - gitleaks collector: the raw scanner report is no longer stored with detected secrets in plaintext. Both sub-collectors shipped gitleaks'
SecretandMatchfields verbatim into.secrets.native.gitleaks.*.report, so a secret scan produced a stored copy of the secrets it found. The normalized.secrets.issues/.secrets.cicdprojections were always safe.scan.shnow passes--redactand verifies the report really is redacted before writing it;cicd.shstrips.Secretand.Matchwithjq. Both paths degrade to losing raw detail, never to leaking (#290). - Manifests:
runs_onnested underhook:was silently dropped — it's a field of the snippet, not the hook, and nothing decodes manifests withKnownFields(true), so five sub-collectors that looked scoped were running in both CI and non-CI contexts. Behaviour change:claude(code-reviewer,run-code-review) andcoderabbit(code-reviewer) now correctly stop running on default-branch commits — they read PR review data, and a default-branch commit has no PR.codeql(github-app,running-in-prs) is unchanged; the key was deleted because both should run in both contexts. Addsscripts/validate_manifest_schema.pyso the next one fails CI instead of shipping (#291).
Pin this release in your lunar-config.yml:
- uses: github://earthly/lunar-lib/collectors/<name>@v1.14.0