Public record
Software health reportschema 0.27.0 · metrics 1.13.0 · 2026-07-28 07:44 UTC

cardinalhq / lakerunner-cloudformation

Python · ShellAGPL-3.0★ 1 star⑂ 0 forkssince Jul 2025View on GitHub ↗

cardinalhq/lakerunner-cloudformation holds a health index of 55 out of 100, placing it in the Moderate band. It scores highest on Vitality (84/100) and lowest on Community & Adoption (24/100). It was last updated 27 days ago. A single contributor accounts for most of its recent work.

55
overall / 100
Moderate

Software health index

Metrics are grouped into weighted categories on one standardized 1–100 scale. Overall starts as their weighted mean; when public evidence triggers the High-Risk Jurisdiction Policy, the rating is adjusted and receives an At risk ceiling of 49. AI Readiness sits outside the overall score.

55
Excellent85-100Exemplary; meets essentially all checked criteria
Good70-84Healthy; minor gaps
Moderate50-69Acceptable with notable gaps; review recommended
At risk30-49Significant weaknesses; adoption warrants caution
Critical1-29Severe problems (abandoned, single-maintainer, no hygiene)
VitalityCommunity &AdoptionSustainability &GovernanceEngineeringQualitySecurityAI Readiness

Score profile

Each axis is a category. The shape matters more than the average — a healthy subject fills the whole shape, while a spike-and-crater profile means strength in one dimension is masking risk in another.

Ownership

Cardinal HQOrganization
7 followers30 public repossince Mar 2023

This repository is backed by an organization — shared, accountable stewardship that can outlive any single maintainer.

Metrics by category

Vitality

Is the project alive — is code being written and are releases shipping?

84Good · 22% of overall
How it's scored
28.8/36Push recency — last push 27 days ago
22.8/36Commit cadence — 33/52 weeks with commits
18/18Commit volume — 423 commits in the last year
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Inputs used
commits_last_year423
human_commit_share1
days_since_last_push27
active_weeks_last_year33
How it's scored
27/27Ships releases — 100 releases published
36/36Release recency — latest release 27 days ago
27/27Release cadence — a release every ~0.8 days
0/10OpenSSF Scorecard: Signed-Releases — Project has not signed or included provenance with any releases.
Inputs used
releases_count100
latest_release_tagv1.6.5
releases_from_tagsno
days_since_latest_release27
mean_days_between_releases0.8

Community & Adoption

Does the project have users, downloads, attention, and a welcoming setup for contributors?

24Critical · 18% of overall
How it's scored
0/60Stars — 1 stars
0/25Forks — 0 forks
0/15Watchers — 0 watchers
Inputs used
forks0
stars1
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
How it's scored
22.5/22.5README
22.5/22.5License — recognized license (AGPL-3.0)
0/18CONTRIBUTING guide
0/13.5Code of conduct
0/7.2Issue template
0/6.3PR template
Inputs used
has_readmeyes
has_licenseyes
has_contributingno
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno

Sustainability & Governance

Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?

44At risk · 24% of overall
How it's scored
9/54Bus factor — 1 contributor(s) cover half of all commits
0/22.5Commit distribution — top contributor authored 100% of commits
2.7/13.5Contributor breadth — 2 contributors
3/10OpenSSF Scorecard: Contributors — project has 1 contributing companies or organizations -- score normalized to 3
Inputs used
bus_factor1
contributors_sampled2
top_contributor_share0.998
How it's scored
31.2/46.8Issue resolution — 67% of issues closed
37.6/38.3PR acceptance — 230/234 decided PRs merged
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Inputs used
merged_prs230
open_issues3
closed_issues6
issue_closed_ratio0.667
closed_unmerged_prs4
How it's scored
30/30Ownership backing — organization-owned
0/20Verified domain
6.5/25Owner reach — 7 followers of cardinalhq
17.6/25Track record — 30 public repos, account ~3 yr old
Inputs used
followers7
owner_typeOrganization
is_verified
owner_logincardinalhq
public_repos30
account_age_days1,224

Engineering Quality

Are baseline engineering and documentation practices in place?

67Moderate · 20% of overall
How it's scored
24/24CI workflows — 2 workflow(s)
24/24Tests present
0/16Linter config
0/9.6Pre-commit hooks
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 30 out of 30 merged PRs checked by a CI test -- score normalized to 10
Inputs used
has_ciyes
has_testsyes
has_editorconfigno
has_linter_configno
has_precommit_configno

Documentation

65Moderate
How it's scored
30/30README
25/25Documentation directory
0/15Documentation / homepage site
0/10Repository description
0/10Topics
10/10Wiki
Inputs used
topics
has_wikiyes
homepage
has_readmeyes
has_docs_diryes
has_descriptionno

Security

Are visible security and supply-chain practices strong, without unresolved high-risk jurisdiction exposure?

52Moderate · 16% of overall
How it's scored
7.5/7.5Binary-Artifacts — no binaries found in the repo
2.2/7.5Branch-Protection — branch protection is not maximal on development and all release branches
2.5/2.5CI-Tests — 30 out of 30 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
0.8/2.5Contributors — project has 1 contributing companies or organizations -- score normalized to 3
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5License — license file detected
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — no data
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — Project has not signed or included provenance with any releases.
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Inputs used
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate4
Excluded from scoring (no data or not applicable): packaging. Remaining weights renormalized.
How it's scored
35/35Direct dependencies free of known advisories — no direct dependency carries a known advisory
0/25Indirect dependencies free of known advisories — transitive set not separable from development and test dependencies in this scope
0/40No advisories left outstanding — no advisory carries a publication date
Inputs used
sourceosv
advisories0
affected_packages0
assessed_packages5
unassessed_packages0
affected_by_severitynone
direct_affected_packages0
Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories, No advisories left outstanding. Remaining weights renormalized. Matched 5 resolved dependencies against OSV. This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.

AI Readiness

How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score.

68Moderate · 0% of overall
How it's scored
45/45Agent instructions — CLAUDE.md
0/15Machine-readable docs (llms.txt)
40/40Legible commit history — 92 of 100 human commits state their intent (structured subject or explanatory body)
Inputs used
has_llms_txtno
legible_history_share0.92
agent_instruction_filesCLAUDE.md
agent_instruction_max_bytes15,275
How it's scored
18/18One-command bootstrap — Makefile
22/22Automated tests
0/11Lint / format config
11/11Static type checking — pyrightconfig.json
0/10Reproducible environment
0/10Demonstrated agent practice — no agent-authored commits among the last 100
0/8Automated maintenance — no automated dependency updates observed
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Inputs used
has_nixno
has_testsyes
lockfiles
has_dockerfileno
typed_languageno
bootstrap_filesMakefile
has_devcontainerno
has_linter_configno
typecheck_configspyrightconfig.json
agent_commit_share0
toolchain_manifests
dependency_bot_commit_share0
How it's scored
27/45Type-checkable code — Python with type-check config (pyrightconfig.json)
55/55Manageable file sizes — 0/69 source files over 60KB
Inputs used
primary_languagePython
largest_source_bytes33,578
source_files_sampled69
oversized_source_files0

Key facts

1GitHub stars
2contributors
423commits, last 12 months
27days since last push
100releases
1bus factor
3open issues
PyPIpackage ecosystems

Data collection warnings

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token

More detail

OpenSSF Scorecard 4.0 / 10
4.0aggregate

Independent, tool-agnostic security assessment from the open-source OpenSSF Scorecard. Each check rewards a security practice, not a specific vendor's tool. Checks Scorecard could not determine are marked n/a and excluded from the security score (never counted as zero).Scorecard v5.5.0 · 2026-07-28 07:44 UTC

10Binary-Artifactsno binaries found in the repo
3Branch-Protectionbranch protection is not maximal on development and all release branches
10CI-Tests30 out of 30 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
3Contributorsproject has 1 contributing companies or organizations -- score normalized to 3
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
n/aPackagingpackaging workflow not detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
0Signed-ReleasesProject has not signed or included provenance with any releases.
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
All dependencies 5

Full resolved dependency set from the GitHub dependency graph: 0 direct and 5 indirect (transitive) packages. The transitive closure is complete when the repository commits a lockfile.

RegistryPackageVersionRelation
PyPIcfn-lint1.49.3indirect
PyPIcloud-radar0.16.0indirect
PyPIpytest9.0.3indirect
PyPIpyyaml6.0.3indirect
PyPItroposphere4.10.1indirect
Dependency advisories 0

This repository publishes no package the index resolves, so its own dependency graph was assessed — 5 packages, which also include development and test pins that never ship: 0 carry known advisories, of which 0 are direct.

No known advisories affect the assessed dependencies.

An advisory means the version recorded in the dependency graph falls inside an advisory’s affected range. Reachability is not analysed, and the graph includes development and test pins — a finding may concern tooling rather than shipped software.

Raw JSON report machine-readable
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 2403,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Shell": 389901,
        "Python": 533704,
        "Makefile": 1829
      },
      "pushed_at": "2026-06-30T18:47:29Z",
      "created_at": "2025-07-27T22:01:51Z",
      "owner_type": "Organization",
      "updated_at": "2026-06-30T18:47:30Z",
      "description": null,
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "AGPL-3.0",
      "default_branch": "main",
      "license_spdx_raw": "AGPL-3.0",
      "primary_language": "Python",
      "significant_languages": [
        "Python",
        "Shell"
      ]
    },
    "owner": {
      "blog": "https://cardinalhq.io",
      "name": "Cardinal HQ",
      "type": "Organization",
      "login": "cardinalhq",
      "company": null,
      "location": "United States of America",
      "followers": 7,
      "avatar_url": "https://avatars.githubusercontent.com/u/128514020?v=4",
      "created_at": "2023-03-21T17:17:55Z",
      "is_verified": null,
      "public_repos": 30,
      "account_age_days": 1224
    },
    "license": {
      "state": "standard",
      "spdx_id": "AGPL-3.0",
      "raw_spdx": "AGPL-3.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v1.6.5",
          "kind": "patch",
          "published_at": "2026-06-30T18:48:13Z"
        },
        {
          "tag": "v1.6.4",
          "kind": "patch",
          "published_at": "2026-06-30T17:14:42Z"
        },
        {
          "tag": "v1.6.3",
          "kind": "patch",
          "published_at": "2026-06-30T16:09:54Z"
        },
        {
          "tag": "v1.6.2",
          "kind": "patch",
          "published_at": "2026-06-29T19:40:41Z"
        },
        {
          "tag": "v1.6.1",
          "kind": "patch",
          "published_at": "2026-06-29T16:51:24Z"
        },
        {
          "tag": "v1.6.0",
          "kind": "minor",
          "published_at": "2026-06-26T22:23:59Z"
        },
        {
          "tag": "v1.5.1",
          "kind": "patch",
          "published_at": "2026-06-24T05:28:26Z"
        },
        {
          "tag": "v1.5.0",
          "kind": "minor",
          "published_at": "2026-06-24T05:08:56Z"
        },
        {
          "tag": "v1.4.4",
          "kind": "patch",
          "published_at": "2026-06-23T20:04:20Z"
        },
        {
          "tag": "v1.4.3",
          "kind": "patch",
          "published_at": "2026-06-23T19:22:02Z"
        },
        {
          "tag": "v1.4.2",
          "kind": "patch",
          "published_at": "2026-06-22T20:44:42Z"
        },
        {
          "tag": "v1.4.1",
          "kind": "patch",
          "published_at": "2026-06-22T17:38:20Z"
        },
        {
          "tag": "v1.4.0",
          "kind": "minor",
          "published_at": "2026-06-22T05:22:46Z"
        },
        {
          "tag": "v1.3.0",
          "kind": "minor",
          "published_at": "2026-06-21T07:34:40Z"
        },
        {
          "tag": "v1.2.2",
          "kind": "patch",
          "published_at": "2026-06-19T13:40:54Z"
        },
        {
          "tag": "v1.2.1",
          "kind": "patch",
          "published_at": "2026-06-17T11:29:02Z"
        },
        {
          "tag": "v1.2.0",
          "kind": "minor",
          "published_at": "2026-06-17T11:11:57Z"
        },
        {
          "tag": "v1.1.9",
          "kind": "patch",
          "published_at": "2026-06-17T09:36:06Z"
        },
        {
          "tag": "v1.1.8",
          "kind": "patch",
          "published_at": "2026-06-16T20:58:03Z"
        },
        {
          "tag": "v1.1.7",
          "kind": "patch",
          "published_at": "2026-06-16T16:46:53Z"
        },
        {
          "tag": "v1.1.6",
          "kind": "patch",
          "published_at": "2026-06-16T08:44:49Z"
        },
        {
          "tag": "v1.1.5",
          "kind": "patch",
          "published_at": "2026-06-16T07:59:37Z"
        },
        {
          "tag": "v1.1.4",
          "kind": "patch",
          "published_at": "2026-06-11T18:32:13Z"
        },
        {
          "tag": "v1.1.3",
          "kind": "patch",
          "published_at": "2026-06-11T15:21:53Z"
        },
        {
          "tag": "v1.1.2",
          "kind": "patch",
          "published_at": "2026-06-10T17:43:02Z"
        },
        {
          "tag": "v1.1.1",
          "kind": "patch",
          "published_at": "2026-06-10T16:23:08Z"
        },
        {
          "tag": "v1.1.0",
          "kind": "minor",
          "published_at": "2026-06-10T00:15:06Z"
        },
        {
          "tag": "v1.0.1",
          "kind": "patch",
          "published_at": "2026-06-07T22:12:22Z"
        },
        {
          "tag": "v1.0.0",
          "kind": "major",
          "published_at": "2026-06-07T05:52:34Z"
        },
        {
          "tag": "v0.0.136",
          "kind": "patch",
          "published_at": "2026-06-07T04:33:09Z"
        },
        {
          "tag": "v0.0.135",
          "kind": "patch",
          "published_at": "2026-06-06T23:03:49Z"
        },
        {
          "tag": "v0.0.134",
          "kind": "patch",
          "published_at": "2026-06-06T22:49:35Z"
        },
        {
          "tag": "v0.0.133",
          "kind": "patch",
          "published_at": "2026-06-06T22:37:01Z"
        },
        {
          "tag": "v0.0.132",
          "kind": "patch",
          "published_at": "2026-06-06T22:13:15Z"
        },
        {
          "tag": "v0.0.131",
          "kind": "patch",
          "published_at": "2026-06-05T16:35:51Z"
        },
        {
          "tag": "v0.0.130",
          "kind": "patch",
          "published_at": "2026-06-05T14:46:11Z"
        },
        {
          "tag": "v0.0.129",
          "kind": "patch",
          "published_at": "2026-06-05T09:19:18Z"
        },
        {
          "tag": "v0.0.128",
          "kind": "patch",
          "published_at": "2026-06-04T22:32:27Z"
        },
        {
          "tag": "v0.0.127",
          "kind": "patch",
          "published_at": "2026-06-04T21:49:19Z"
        },
        {
          "tag": "v0.0.126",
          "kind": "patch",
          "published_at": "2026-06-04T21:26:39Z"
        },
        {
          "tag": "v0.0.125",
          "kind": "patch",
          "published_at": "2026-06-04T20:44:23Z"
        },
        {
          "tag": "v0.0.124",
          "kind": "patch",
          "published_at": "2026-06-04T16:32:12Z"
        },
        {
          "tag": "v0.0.123-rc9",
          "kind": "prerelease",
          "published_at": "2026-06-03T19:26:14Z"
        },
        {
          "tag": "v0.0.123",
          "kind": "patch",
          "published_at": "2026-06-03T16:14:51Z"
        },
        {
          "tag": "v0.0.122",
          "kind": "patch",
          "published_at": "2026-06-03T16:09:37Z"
        },
        {
          "tag": "v0.0.121",
          "kind": "patch",
          "published_at": "2026-06-03T15:55:32Z"
        },
        {
          "tag": "v0.0.120",
          "kind": "patch",
          "published_at": "2026-06-03T15:27:17Z"
        },
        {
          "tag": "v0.0.119",
          "kind": "patch",
          "published_at": "2026-06-03T03:58:17Z"
        },
        {
          "tag": "v0.0.118",
          "kind": "patch",
          "published_at": "2026-06-02T23:09:36Z"
        },
        {
          "tag": "v0.0.117",
          "kind": "patch",
          "published_at": "2026-06-02T22:28:42Z"
        },
        {
          "tag": "v0.0.116",
          "kind": "patch",
          "published_at": "2026-06-02T21:29:08Z"
        },
        {
          "tag": "v0.0.115",
          "kind": "patch",
          "published_at": "2026-06-02T20:46:33Z"
        },
        {
          "tag": "v0.0.114",
          "kind": "patch",
          "published_at": "2026-06-02T20:06:23Z"
        },
        {
          "tag": "v0.0.113",
          "kind": "patch",
          "published_at": "2026-06-02T17:17:21Z"
        },
        {
          "tag": "v0.0.112",
          "kind": "patch",
          "published_at": "2026-06-02T16:05:00Z"
        },
        {
          "tag": "v0.0.111",
          "kind": "patch",
          "published_at": "2026-06-02T15:47:16Z"
        },
        {
          "tag": "v0.0.110",
          "kind": "patch",
          "published_at": "2026-06-02T09:48:47Z"
        },
        {
          "tag": "v0.0.109",
          "kind": "patch",
          "published_at": "2026-06-02T09:07:57Z"
        },
        {
          "tag": "v0.0.108",
          "kind": "patch",
          "published_at": "2026-06-01T20:58:50Z"
        },
        {
          "tag": "v0.0.107",
          "kind": "patch",
          "published_at": "2026-06-01T17:48:30Z"
        },
        {
          "tag": "v0.0.106",
          "kind": "patch",
          "published_at": "2026-06-01T17:19:26Z"
        },
        {
          "tag": "v0.0.105",
          "kind": "patch",
          "published_at": "2026-06-01T14:06:07Z"
        },
        {
          "tag": "v0.0.104",
          "kind": "patch",
          "published_at": "2026-06-01T12:29:58Z"
        },
        {
          "tag": "v0.0.103",
          "kind": "patch",
          "published_at": "2026-06-01T11:55:41Z"
        },
        {
          "tag": "v0.0.102",
          "kind": "patch",
          "published_at": "2026-06-01T11:00:22Z"
        },
        {
          "tag": "v0.0.101",
          "kind": "patch",
          "published_at": "2026-06-01T07:06:01Z"
        },
        {
          "tag": "v0.0.100",
          "kind": "patch",
          "published_at": "2026-06-01T06:17:27Z"
        },
        {
          "tag": "v0.0.99",
          "kind": "patch",
          "published_at": "2026-06-01T05:02:36Z"
        },
        {
          "tag": "v0.0.98",
          "kind": "patch",
          "published_at": "2026-06-01T04:43:16Z"
        },
        {
          "tag": "v0.0.97",
          "kind": "patch",
          "published_at": "2026-06-01T03:18:15Z"
        },
        {
          "tag": "v0.0.96",
          "kind": "patch",
          "published_at": "2026-05-30T16:23:47Z"
        },
        {
          "tag": "v0.0.95",
          "kind": "patch",
          "published_at": "2026-05-30T16:21:04Z"
        },
        {
          "tag": "v0.0.94",
          "kind": "patch",
          "published_at": "2026-05-30T15:15:58Z"
        },
        {
          "tag": "v0.0.93",
          "kind": "patch",
          "published_at": "2026-05-29T14:50:35Z"
        },
        {
          "tag": "v0.0.92",
          "kind": "patch",
          "published_at": "2026-05-29T05:26:41Z"
        },
        {
          "tag": "v0.0.91",
          "kind": "patch",
          "published_at": "2026-05-28T23:41:19Z"
        },
        {
          "tag": "v0.0.90",
          "kind": "patch",
          "published_at": "2026-05-28T21:44:20Z"
        },
        {
          "tag": "v0.0.89",
          "kind": "patch",
          "published_at": "2026-05-28T21:11:00Z"
        },
        {
          "tag": "v0.0.88",
          "kind": "patch",
          "published_at": "2026-05-28T20:35:50Z"
        },
        {
          "tag": "v0.0.87",
          "kind": "patch",
          "published_at": "2026-05-28T20:25:08Z"
        },
        {
          "tag": "v0.0.86",
          "kind": "patch",
          "published_at": "2026-05-28T20:19:29Z"
        },
        {
          "tag": "v0.0.85",
          "kind": "patch",
          "published_at": "2026-05-28T19:17:15Z"
        },
        {
          "tag": "v0.0.84",
          "kind": "patch",
          "published_at": "2026-05-28T17:01:10Z"
        },
        {
          "tag": "v0.0.83",
          "kind": "patch",
          "published_at": "2026-05-28T16:51:25Z"
        },
        {
          "tag": "v0.0.82",
          "kind": "patch",
          "published_at": "2026-05-28T15:30:21Z"
        },
        {
          "tag": "v0.0.81",
          "kind": "patch",
          "published_at": "2026-05-28T14:35:47Z"
        },
        {
          "tag": "v0.0.80",
          "kind": "patch",
          "published_at": "2026-05-28T08:01:26Z"
        },
        {
          "tag": "v0.0.79",
          "kind": "patch",
          "published_at": "2026-05-28T07:43:02Z"
        },
        {
          "tag": "v0.0.78",
          "kind": "patch",
          "published_at": "2026-05-28T07:22:33Z"
        },
        {
          "tag": "v0.0.77",
          "kind": "patch",
          "published_at": "2026-05-26T16:47:48Z"
        },
        {
          "tag": "v0.0.76",
          "kind": "patch",
          "published_at": "2026-05-26T16:39:05Z"
        },
        {
          "tag": "v0.0.75",
          "kind": "patch",
          "published_at": "2026-05-26T15:43:16Z"
        },
        {
          "tag": "v0.0.74",
          "kind": "patch",
          "published_at": "2026-05-25T19:10:12Z"
        },
        {
          "tag": "v0.0.73",
          "kind": "patch",
          "published_at": "2026-05-25T18:08:43Z"
        },
        {
          "tag": "v0.0.72",
          "kind": "patch",
          "published_at": "2026-05-25T16:01:13Z"
        },
        {
          "tag": "v0.0.71",
          "kind": "patch",
          "published_at": "2026-05-22T14:41:00Z"
        },
        {
          "tag": "v0.0.70",
          "kind": "patch",
          "published_at": "2026-05-21T19:24:39Z"
        },
        {
          "tag": "v0.0.69",
          "kind": "patch",
          "published_at": "2026-05-21T19:03:55Z"
        },
        {
          "tag": "v0.0.68",
          "kind": "patch",
          "published_at": "2026-05-20T21:36:54Z"
        },
        {
          "tag": "v0.0.67",
          "kind": "patch",
          "published_at": "2026-05-20T16:36:04Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "7fc5c3530ae0d14eb15c6134c444f78056a892d1",
          "body": null,
          "is_bot": false,
          "headline": "bump lakerunner v1.69.1; release v1.6.5 (#243)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-30T18:47:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f0ae82380a09ed6a21e76dc5f433e3b6243dfcd2",
          "body": null,
          "is_bot": false,
          "headline": "bump lakerunner v1.69.0, maestro v1.74.0; release v1.6.4 (#242)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-30T17:13:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "68c2746521c84d8ca55faf908fd051f79a773175",
          "body": null,
          "is_bot": false,
          "headline": "bump lakerunner v1.68.0, maestro v1.73.1; release v1.6.3 (#241)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-30T16:09:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3062b26539feb2ff7a9eab287ff155e34c68ef9d",
          "body": null,
          "is_bot": false,
          "headline": "bump lakerunner to v1.67.1; release v1.6.2 (#240)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-29T19:39:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8df656007a73d86ba08c038dc3a07593d3dfb402",
          "body": "* bump lakerunner v1.67.0, maestro v1.72.1; release v1.6.1\n\n* bump image pins in deploy-lakerunner-services.sh to match",
          "is_bot": false,
          "headline": "bump lakerunner v1.67.0, maestro v1.72.1; release v1.6.1 (#239)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-29T16:50:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8a0276ec910454a634b85965612cffbf006867a1",
          "body": "…queue (v1.6.0) (#238)\n\n* back out satellite mapping; restore single bootstrap bucket + ingest queue\n\n* bump lakerunner v1.65.0, maestro v1.71.0",
          "is_bot": false,
          "headline": "Back out satellite mapping; restore single bootstrap bucket + ingest …",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-26T22:22:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dda25fc758a06f199dda210b8a48cbf67966efd2",
          "body": null,
          "is_bot": false,
          "headline": "bump lakerunner to v1.63.1, maestro to v1.68.0; release v1.5.1 (#237)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-24T05:27:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "95b458470202c8ae76ee0dba033ca28ed72c6e90",
          "body": "…ivery; remove numbered-queue + autoregister) (#236)\n\n* design: satellite mapping as Maestro-synced JSON\n\n* design: group-0 primary = org writable collector\n\n* design: collector mode (normal/read-only/satellite) replaces readonly bool\n\n* plan: lakerunner foundation for satellite mapping\n\n* plan: mae\n[…]\nx: grant ExecutionRole ssm:GetParameters on /cardinal/satellites\n\n* fix: widen ExecutionRole SSM grant to /cardinal/* for param override\n\n* docs: drop stale ensure-storage-profile from db-secret table",
          "is_bot": false,
          "headline": "Satellite mapping — CFN driver (synthesize central collector, SSM del…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-24T05:06:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1ec91472576c78efd65d4991177213b68cb2a7e8",
          "body": "…; release v1.4.4 (#235)",
          "is_bot": false,
          "headline": "default lakerunner workers to on-demand; add lakerunner_capacity knob…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-23T20:03:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "40a8eb77771cbf73889061f2bd6e8a029f62eff8",
          "body": null,
          "is_bot": false,
          "headline": "lower process-tier CPU autoscale target to 50%; release v1.4.3 (#234)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-23T19:21:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1fa75913b38948475d703679847edd74dde90796",
          "body": null,
          "is_bot": false,
          "headline": "bump lakerunner to v1.61.2; release v1.4.2 (#233)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-22T20:43:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "07bcfdc205cd25ed211a0e536e4f76ff2f427211",
          "body": "release v1.4.1",
          "is_bot": false,
          "headline": "process workers: 2M compact target; metrics mem to 4G (#232)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-22T17:37:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3a0e98484015967d0c47b65da67dcdf736feebc0",
          "body": "* bump lakerunner to v1.61.1, maestro to v1.66.5; release v1.4.0\n\n* regen deploy driver for v1.61.1/v1.66.5 image bump",
          "is_bot": false,
          "headline": "bump lakerunner to v1.61.1, maestro to v1.66.5; release v1.4.0 (#231)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-22T05:21:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "77e9b6e9b508c378656305b51688622660845e33",
          "body": null,
          "is_bot": false,
          "headline": "bump lakerunner to v1.60.0, maestro to v1.66.0; release v1.3.0 (#230)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-21T07:33:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e66ecbf25034971647e1d8c88b43d4bcbde3644a",
          "body": null,
          "is_bot": false,
          "headline": "bump lakerunner to v1.57.1; release v1.2.2 (#229)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-19T13:40:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "011a5c9231120f284a6fd6959ae63fa564637ec4",
          "body": null,
          "is_bot": false,
          "headline": "bump maestro to v1.62.10; release v1.2.1 (#228)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-17T11:28:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fffde3c28b96f375ffadaf1fa5f26937245d734a",
          "body": null,
          "is_bot": false,
          "headline": "bump lakerunner to v1.54.0; release v1.2.0 (#227)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-17T11:10:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "02e5f585b0be3e4c80cffda15f9ac5848e34e1c9",
          "body": "…monitoring scaler (#226)",
          "is_bot": false,
          "headline": "process tier: native ECS CPU target-tracking autoscaling (90%), drop …",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-17T09:34:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b0f65cc73d8cc648d0fe8fbbd03f329f267007c7",
          "body": "Make process-tier Fargate task memory settable through\ndeploy-lakerunner-services.sh, mirroring how the image params are passed.\nEach is forwarded to the stack only when set, so an existing install's\nvalue carries forward on update unless explicitly overridden -- the lever\nto apply a bumped memory default (e.g. v1.1.7 process-logs 4096) to an\nexisting install in place. Regenerated scripts/ via make scripts;\nchangelog v1.1.8.",
          "is_bot": false,
          "headline": "services driver: PROCESS_{LOGS,METRICS,TRACES}_MEMORY env vars (#225)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-16T20:57:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5f133488754e3ff542c7d29dc35bf6f6b1b1b1bc",
          "body": "…#224)\n\n- ProcessLogsMemory default 2048 -> 4096 MiB (still 1 vCPU; valid Fargate combo)\n- LakerunnerImage v1.51.3 -> v1.51.5, MaestroImage v1.60.3 -> v1.62.4\n  (digest-pinned multi-arch manifests)\n- regenerated scripts/ via make scripts; changelog v1.1.7\n\nNo release/redeploy here; bundling with a further change before tagging.",
          "is_bot": false,
          "headline": "bump process-logs memory to 4G; lakerunner v1.51.5, maestro v1.62.4 (…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-16T16:45:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7b5acfdc61e60d09f721b2281b460d94b7742504",
          "body": "…#223)\n\n* services-process: set LAKERUNNER_LOG_TRACKED_FIELDS on process-logs\n\nHardcode the log tracked-field set\nservice_name,environment_type,installation,proc_name,partition_id on the\nprocess-logs task, overriding lakerunner's compiled-in default. These are\nthe fields whose distinct values are ro\n[…]\nnors LAKERUNNER_LOG_TRACKED_FIELDS\n(the env var process-logs now sets). Digest-pinned multi-arch manifest;\nregenerated scripts/deploy-lakerunner-services.sh via make scripts.\nChangelog v1.1.6 updated.",
          "is_bot": false,
          "headline": "services-process: set LAKERUNNER_LOG_TRACKED_FIELDS on process-logs (…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-16T08:43:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d09184b1b617fc356f2b431660090426d5a7109d",
          "body": "Default LakerunnerImage v1.41.6 -> v1.51.1 and MaestroImage v1.53.1 ->\nv1.60.3 (digest-pinned multi-arch manifests). Default QueryWorkerReplicas\nlowered from 8 to 4. Changelog entry added for v1.1.5.",
          "is_bot": false,
          "headline": "bump images + lower query-worker replicas (#222)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-16T07:58:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "645e21a5ad148038b639f0cb27bcac94823a4062",
          "body": "Operator-supplied values (env vars / flags and input-file contents) that\ncontain smart quotes, no-break spaces, or other non-ASCII or control\ncharacters used to ride silently into the CloudFormation parameter JSON\nand fail much later with inscrutable template or service errors.\n\nThe shared engine no\n[…]\nd input files the same way. A violation exits 2 naming the\nparameter, the offending character (e.g. left double curly quote U+201C),\nits line and byte position, and the plain-ASCII replacement to use.",
          "is_bot": false,
          "headline": "deploy drivers: reject non-ASCII input with a precise error (#221)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-11T18:31:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6ae6906486121e21f6e856341709575f5f11eeed",
          "body": "…#220)\n\nNew optional PublicDnsName parameter (default empty) on the\nlakerunner-services root. When set, the Maestro/Dex OIDC issuer and\nredirect URLs and the QueryApiUrl output derive from it instead of the\nraw ALB DNS name, so browser logins work through a customer CNAME\npointing at the ALB. Empty preserves the existing ALB-DNS-name\nbehavior. The deploy driver accepts it as PUBLIC_DNS_NAME.",
          "is_bot": false,
          "headline": "services stack: optional PublicDnsName for vanity-hostname installs (…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-11T15:20:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c7042f991c857f4da7763db33f8eb04ea3532362",
          "body": null,
          "is_bot": false,
          "headline": "satellite stacks: optional NameSuffix for multi-install accounts (#219)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-10T17:42:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e62edaead763eef2abb996476be1f348d9f06134",
          "body": null,
          "is_bot": false,
          "headline": "changelog for v1.1.1 (#218)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-10T16:21:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cb0882144ae9c316c4195f4f37b5b3fc67cf0971",
          "body": "…(#217)",
          "is_bot": false,
          "headline": "deploy driver: accept multi-line DEX_EXTRA_USERS, flatten for PARAMS …",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-10T16:19:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8395e55edd6efa79a395782a152b36f7bdd6fec2",
          "body": "* spec: multiple dex login accounts\n\n* lakerunner-services: optional DexExtraUsers for extra DEX login accounts\n\n* dex image pin v0.3.0 -> v0.4.0; changelog v1.1.0",
          "is_bot": false,
          "headline": "Multiple DEX login accounts via DexExtraUsers (#216)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-10T00:14:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "184e7b405c32d7f7c4c327197c63f73f540b2ab6",
          "body": null,
          "is_bot": false,
          "headline": "README: use markdown lists instead of code blocks for stack order (#215)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-08T15:49:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4fa0cefeb0a09aa17b8eb1aac98ce8feda75ea4d",
          "body": null,
          "is_bot": false,
          "headline": "README: per-stack descriptions + base/satellite apply orders (#214)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-08T15:47:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "365a74df072e9946514cace177036340578e1a50",
          "body": null,
          "is_bot": false,
          "headline": "lakerunner v1.40.4 -> v1.41.6 (#213)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-07T22:11:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "06929314ef22e5a2b2e7bf44839a5fbebd72c9b4",
          "body": "Delete the Jenkinsfile and its test, drop the dead test-jenkins Make\ntarget, and scrub Jenkins wording/doc links from deploy scripts and\ndocs. Also fix certificates.md: cert is an IAM ServerCertificate, not\na Lambda custom resource.",
          "is_bot": false,
          "headline": "remove jenkins support (#212)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-07T21:23:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "53d574ea1e1111183a73961bedc6fbca38c72955",
          "body": "…(#211)\n\nEmptying both buckets once upfront raced the collector: it kept writing to\notel-raw for the ~20 min the earlier stacks took to delete, so satellite-infra-\nbase's Delete-policy bucket refilled and its delete failed. Empty each owning\nstack's bucket immediately before deleting that stack (otel-raw before\nsatellite-infra-base, cooked before lakerunner-infra-base) — by then the writer\nstack is already gone, so it stays empty. Makes the burn a clean one-shot.",
          "is_bot": false,
          "headline": "teardown-cardinal: empty each bucket right before deleting its stack …",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-07T07:17:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3a66544dcadf65983fcbc3433bc60187d86024e2",
          "body": null,
          "is_bot": false,
          "headline": "changelog: v1.0.0 (#210)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-07T05:51:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "25a4f55690c101e8bd952625dea695e110f92c16",
          "body": "* dev-scripts: add per-stack teardown-cardinal.sh\n\nSelf-contained, env-driven, CONFIRM-gated teardown for the per-stack model:\ndeletes the 5 cardinal-* stacks in reverse order, empties+removes the data\nbuckets, and force-deletes the retained cardinal-* secrets, leaving the VPC and\nECS cluster intact\n[…]\n\nagainst a live teardown (incl. a clean resume after a creds expiry). Adds a\nshellcheck/usage/gate lint test; wires the docs to it.\n\n* teardown-cardinal: avoid SC2015 (A && B || C) on account-id check",
          "is_bot": false,
          "headline": "dev-scripts: per-stack teardown-cardinal.sh (#209)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-07T05:46:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "df9bf37ae6a653be9eccd7fc47bfbabe9440c62d",
          "body": "…#208)\n\nAdd docs/operations/production-deploy.md (admin install via version-pinned\nrelease artifacts), docs/operations/dev-environment.md (reproduce test env,\nself-telemetry validation, clean per-stack teardown), and scripts/README.md\n(dev vs release-pinned drivers). Retire the legacy monolithic-mod\n[…]\ntalling/install-*/jenkins-*/end-to-end-test-plan/tearing-down/cleanup).\nRewrite README.md + dev-scripts/README.md for the per-stack model; repoint\nsurviving reference docs. All markdown links resolve.",
          "is_bot": false,
          "headline": "docs: consolidate to one production path + one dev-environment path (…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-07T05:00:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1adb75d20fabd35ad9dd2bd20647f4ff40c3f208",
          "body": "… (#207)\n\nThe repo's scripts/*.sh bake STACK_VERSION=dev (and the byte-identical test\nenforces that, since a commit pre-dates its own tag). release.yml already\nrebuilds the drivers with the tag version baked and syncs them to S3; also\nattach that same baked set to the GitHub release, so a script downloaded from\nthe release has the real version baked, not dev. Published to github + S3 as a unit.",
          "is_bot": false,
          "headline": "release: attach version-baked deploy drivers as GitHub release assets…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-07T04:36:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "58c020fc93f64917a229b4739c6baa52b198856c",
          "body": "* maestro v1.53.1: provisioning cold-start retry fix (conductor #998)\n\n* regenerate drivers for maestro v1.53.1 suffix",
          "is_bot": false,
          "headline": "maestro v1.53.1 (provisioning cold-start retry fix) (#206)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-07T04:32:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b86277bbe86486f607bf0b83d5d82ef473419086",
          "body": "Source the cardinal-cleanup task's aws-cli image from cardinal-defaults.yaml\n(images.aws_cli), digest-pinned to 2.34.63, exposed as AwsCliImage param like\nthe other images. Update the sweep-stranded-resources default and add a\ncleanup-images.txt manifest. Every project image is now a pinned public.ecr.aws ref.",
          "is_bot": false,
          "headline": "cleanup: pin aws-cli image via cardinal-defaults, sha-locked (#205)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-06T23:03:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3df65d75033932c25002a36569d85dd132f2f374",
          "body": "DbInitImage was only passed when DB_INIT_IMAGE was set, so on a stack update\nit carried UsePreviousValue and never picked up a bumped default. Bake the\ndb_init suffix and always pass it (composed with IMAGE_REGISTRY) like the other\nimages, so a plain redeploy keeps db-init current. DB_INIT_IMAGE still overrides.",
          "is_bot": false,
          "headline": "deploy driver: always set DbInitImage from baked default (#204)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-06T22:48:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1822839bf244324d9c97a0102ece556162764f88",
          "body": "…image (#203)\n\ndb-init only runs 'psql CREATE DATABASE maestro' (overrides entrypoint, uses\nnone of the grafana tooling). Switch to the digest-pinned official Postgres\nimage on public ECR (psql 18 matches RDS); removes the only ghcr.io pull.",
          "is_bot": false,
          "headline": "db-init: use official postgres:18-alpine for psql, drop ghcr grafana …",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-06T22:36:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "38496c903396dbb946d26e86159ff2de3c658da0",
          "body": "…) (#202)",
          "is_bot": false,
          "headline": "changelog: my dex change is v0.0.132 (v0.0.131 was service_graph #200…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-06T22:12:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cb746b5e7f0a62c414d6ca9c1074f95bdbe319cb",
          "body": "dex v0.3.0 renders its own config from env vars, so remove the busybox\ndex-init container, the DexInitImage parameter, the dex-config/dex-tmp\nvolumes, and the /etc/dex mount. dex runs nonroot (uid 1001) with a\nwritable rootfs and writes rendered config to the image's /tmp. Bump\nmaestro v1.50.0->v1.53.0.",
          "is_bot": false,
          "headline": "dex v0.3.0: drop dex-init sidecar; bump maestro v1.53.0 (#201)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-06T22:09:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "746c652182cd9d45fc09ffb834dedfb3433331a2",
          "body": null,
          "is_bot": false,
          "headline": "add the service_graph connector (#200)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-05T16:34:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5c12ddec54dab6d04764f0f5be10493ff32f3ce9",
          "body": "…ng; ingest pipeline fix) (#199)",
          "is_bot": false,
          "headline": "changelog: v0.0.130 (collector ALB opens 0.0.0.0/0 when internet-faci…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-05T14:45:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "abb3139582876c17ae6d88a8395be5ab30c882eb",
          "body": "…rnet-facing (#198)\n\nThe satellite collector ALB SG only ever allowed `IngestSourceCidr` (default\n10.0.0.0/8) on 4318, regardless of AlbScheme. So an `internet-facing` collector\nwas placed in public subnets but its SG still rejected everything outside\nRFC1918 -- it was not actually reachable as inte\n[…]\nix: when AlbScheme=internet-facing, layer a 0.0.0.0/0 ingress on the OTLP port,\nmatching the app ALB in lakerunner-infra-base. Internal ALBs are unchanged:\ntheir only ingress remains IngestSourceCidr.",
          "is_bot": false,
          "headline": "satellite-services: open collector ALB ingress to 0.0.0.0/0 when inte…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-05T14:42:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bcb3c3b74f9c6d195ef88331e5e941628456751e",
          "body": "… rollback recreate) (#197)",
          "is_bot": false,
          "headline": "changelog: v0.0.129 (maestro dex theme fix; services cert auto-gen on…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-05T09:18:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "83454536e35db688ff4ffd46c8231adfaac2c6dd",
          "body": "…create, not just when absent (#196)\n\nThe lakerunner-services driver auto-generates a self-signed cert (when no\nCERTIFICATE_ARN/PEM is supplied) only on a fresh create. It detected \"fresh\ncreate\" with a bare existence check: if `describe-stacks` succeeded at all, it\nskipped generation and let the en\n[…]\ne engine's recreate states. Generate\nwhen the stack is absent, REVIEW_IN_PROGRESS, or ROLLBACK_COMPLETE; keep the\nexisting cert (no regeneration, no ALB listener churn) only on a true in-place\nupdate.",
          "is_bot": false,
          "headline": "services driver: auto-generate self-signed cert on rollback/review re…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-05T09:16:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0a46f3543aa9490817ccecfee0a467f74c16a289",
          "body": "* bump(dex): v0.1.0 -> v0.2.0 (embedded theme, drop frontend.dir)\n\ndex-customization v0.2.0 embeds the Cardinal theme in the binary, so the\ndex-init config no longer needs frontend.dir: /srv/dex-cardinal/web (that\npath is gone in v0.2.0 — a stale frontend.dir would fail dex boot). Keep\nfrontend.issu\n[…]\nte deploy-lakerunner-services.sh for dex v0.2.0\n\nmake scripts — bakes the new DEX_IMAGE_SUFFIX (v0.2.0@sha256:4a3aed43)\ninto the generated driver. Keeps test_committed_drivers_match_fresh_build\ngreen.",
          "is_bot": false,
          "headline": "bump(dex): v0.1.0 -> v0.2.0 (embedded theme, drop frontend.dir) (#195)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-05T00:15:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dc66d22af00db540378b1a0d4fae3729006c4716",
          "body": "…JSON) (#194)\n\nThe execution role in lakerunner-infra-base and the collector execution role in\nsatellite-services gain an ExecutionRoleExtraPolicyArns param (CSV) appended to\nManagedPolicyArns alongside AmazonECSTaskExecutionRolePolicy, for air-gapped ECR\npull-through first-pull, cross-account ECR, \n[…]\nolicy\n<STACK_NAME>-exec-extra, attached by ARN -- CFN can't inline a string policy\nwithout Lambda). Both optional; default behavior unchanged.\n\nDocs (air-gapped-images.md), spec, changelog (v0.0.128).",
          "is_bot": false,
          "headline": "execution role: customer-supplied extra IAM policies (ARNs or pasted …",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-04T22:31:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d2dd476249556eee4f920aa8c470b6c41e388e38",
          "body": "Rolls the v0.0.126 satellite pattern to the rest:\n- lakerunner-services driver bakes lakerunner/maestro/dex (digest-pinned, repo\n  path locked) behind a single IMAGE_REGISTRY prefix; drops the per-image\n  full-URI overrides and the dead OTEL_IMAGE passthrough. busybox (DEX_INIT_IMAGE)\n  and the ghcr\n[…]\ner/maestro/dex multi-arch index digests;\n  scripts-src/build.sh bakes their suffixes; image_manifest gains a lakerunner\n  stack manifest (lakerunner-images.txt). Docs, changelog (v0.0.127), spec/plan.",
          "is_bot": false,
          "headline": "lock images + STACK_VERSION across all deploy drivers (#193)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-04T21:48:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2385014f99d9c7b8f7e972c14d89e247e3b86a6d",
          "body": "…tional STACK_VERSION (#192)\n\nThe deploy driver now bakes the collector's registry-relative path + pinned\ntag/digest at publish time (single-sourced from cardinal-defaults.yaml); the\noperator supplies only IMAGE_REGISTRY (default public.ecr.aws), suited to ECR\npull-through caches. Replaces the v0.0.\n[…]\nthe template default and the manifest.\n\nscripts-src/build.sh gains the substitution mechanism; image_manifest.py gains\n'suffix'/'manifest' subcommands. Docs, changelog (v0.0.126), spec + plan updated.",
          "is_bot": false,
          "headline": "satellite: lock collector image in driver (IMAGE_REGISTRY prefix), op…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-04T21:25:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "905efac9700740c3148d4b4e68ce19f905ea5656",
          "body": "… (#191)\n\n* docs: spec for air-gapped image registry override (Phase 1: satellite)\n\n* docs: implementation plan for satellite ImageRegistry override (Phase 1)\n\n* feat(satellite): air-gapped image mirroring via OTEL_IMAGE + image manifest\n\nThe deploy script selects the collector image (OTEL_IMAGE -> \n[…]\nnerated-templates/satellite-images.txt listing the upstream image to mirror.\nAdds docs/air-gapped-images.md and a changelog entry.\n\n* docs: reconcile spec + plan with script-driven OTEL_IMAGE approach",
          "is_bot": false,
          "headline": "satellite: air-gapped image mirroring via OTEL_IMAGE + image manifest…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-04T20:42:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7f19ef547948554070ed629c2184b99d0047874e",
          "body": "…1.40.4 (#190)\n\nlakerunner v1.40.4 fixes the trace ingest worklane to honor the\nread/write storage-profile split, so cooked traces now redirect to the\ncooked bucket via writes_to_instance_num (like logs/metrics) instead of\nbeing written back to the satellite source/raw bucket\n(cardinalhq/lakerunner#\n[…]\ns cleanup). Bump the default LakerunnerImage v1.40.0 ->\nv1.40.4 so the default install carries the fix; the grant requires\nlakerunner >= v1.40.4. Folded into the unreleased v0.0.124 CHANGELOG\nsection.",
          "is_bot": false,
          "headline": "satellite: drop raw-bucket PutObject grant; bump LakerunnerImage to v…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-04T16:31:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1b86a39555aa6b20ad0cad7097e4273430870264",
          "body": "…install) (#189)\n\n* docs: design — Maestro as sole owner of Lakerunner org provisioning\n\n* docs: implementation plan — Maestro sole owner of org provisioning\n\n* infra-base: stop seeding org content (no OrganizationId/SSM); Maestro owns it\n\n* migration: drop SSM import + ensure-storage-profile sideca\n[…]\nver keeps ORGANIZATION_ID)\n\n* docs: changelog v0.0.124 + CLAUDE.md for admin-key-only install / Maestro-owned org content\n\n* maestro: refresh stale comments referencing removed CFN org-content writers",
          "is_bot": false,
          "headline": "Maestro as sole owner of Lakerunner org provisioning (admin-key-only …",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-03T19:24:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5b82634c022f43fcf20e234fc763e1f3ddcefd44",
          "body": "…ID) (#188)\n\nRemove the canonical 12340000 default from OrganizationId on infra-base,\nservices, maestro, and OrgId on migration; each is now required and\nUUID-validated. This makes the bootstrap org predictable by choice so it\ncan match a satellite deployed before the central install.\n\n- Drivers dep\n[…]\n (storageProfiles.source:\n  config, no other source supported), not redundant with the migration\n  sidecar's configdb seed.\n\nTests, jenkins-chained-deploy.md, changelog v0.0.122. make test 480 passed.",
          "is_bot": false,
          "headline": "org: make OrganizationId required with no default (operator-chosen UU…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-03T16:13:59Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7989ab226ab275e70509271e45e18d3dc4016883",
          "body": "A \"missing required\" failure is most often caused by a value set as a plain\nshell variable but not exported, so the driver -- a separate process -- never\nreceives it. Print every required and optional input the process can actually\nsee (value, or <unset>) to stderr before the missing-required check, so the\ncause is obvious from the output. No behavior or parameter change.\n\nEdited the source part and regenerated the committed copy via make scripts.",
          "is_bot": false,
          "headline": "deploy-satellite-services: echo visible inputs before validating (#187)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-03T16:07:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fc6c14d195a1e93331caa98da2148217c91f2ea6",
          "body": "…queues (#186)\n\n- PubsubAutoRegister now defaults to true (root + process child): new deploys\n  auto-register unseen satellite raw-bucket orgs and route cooked output to\n  PubsubAutoRegisterWritesToInstance without an extra flag.\n- Add numbered queue groups 1..MAX_ADDITIONAL_QUEUES (=10): QueueUrl<n\n[…]\nand assume-role for cross-account/region queues.\n- Driver: QUEUE_URL_<n> / QUEUE_REGION_<n> / QUEUE_ROLE_ARN_<n> env loop.\n- Tests, jenkins-chained-deploy.md, changelog v0.0.121. make test 477 passed.",
          "is_bot": false,
          "headline": "pubsub-sqs: default autoregister on + support multiple satellite SQS …",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-03T15:54:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e37e9eff399ae96464bc2f92b38fb32c1528ee0f",
          "body": "…k pull) (#185)\n\nA satellite (satellite-infra-base + satellite-services) may live in the same\nor a DIFFERENT account than the central lakerunner install. describe-stacks is\naccount+region scoped, so the satellite drivers can no longer read the central\nlakerunner-infra-base stack.\n\n- satellite-servic\n[…]\n from its own paired satellite-infra-base.\n- The collector task/exec roles were already self-contained; unchanged.\n\nTests + jenkins-chained-deploy.md updated; changelog v0.0.120. make test 475 passed.",
          "is_bot": false,
          "headline": "satellite: decouple from central account (no license, no central-stac…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-03T15:26:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ec794d03acfee50e5357048e964230404530296e",
          "body": "…h tag (#184)\n\nCHANGELOG.md captures operational/system upgrade notes from v0.0.114\nthrough v0.0.119 (current) for operators updating an existing install:\nnew/changed parameters, image bumps, IAM and SG changes, and resource\nreplacements (notably the v0.0.113 Aurora -> v0.0.114 RDS-instance\nreplacement). CLAUDE.md's Publishing section now requires a matching\nchangelog entry before every v* release tag; since the tag is cut from\nthat commit, tag+push carries the changelog automatically.",
          "is_bot": false,
          "headline": "docs: add operational CHANGELOG (v0.0.114+) and require it before eac…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-03T14:56:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7290b93ae1dd9e004a62a4993d38dab169491e10",
          "body": "…tellite-access (#183)\n\nThe lakerunner trace ingest worklane does not yet split read vs write\nstorage profiles the way the logs and metric worklanes do, so it writes\ncooked trace segments back to the source (raw) bucket instead of\nredirecting to the cooked bucket via writes_to_instance_num. Without\n\n[…]\n to the RawBucket statement (renamed Sid to\nRawBucketReadWriteDelete) so satellite self-telemetry traces process.\nRemove once trace_ingest_worklane.go mirrors the logs/metric read/write\nprofile split.",
          "is_bot": false,
          "headline": "satellite-infra-base: grant s3:PutObject on raw bucket to cardinal-sa…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-03T03:57:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a596a698f95f2cd427658726ee970f6ef4c14dce",
          "body": "PR #162 merged sweeper/monitoring/admin-api/alert-evaluator into one ECS\ntask. That task hardcodes CONTROL_TASK_CPU/CONTROL_TASK_MEMORY (256/512)\nand desired_count=1, so the per-service cpu/memory_mib/replicas on those\nfour entries were no longer read — and the 256/512 values misleadingly\nread as per-container. monitoring.ingress (9090) was also dead; only\nadmin-api's ingress is consumed. Remove them.\n\nGenerated services-control template is byte-identical; no functional change.",
          "is_bot": false,
          "headline": "defaults: drop dead per-service sizing from merged control tier (#182)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-02T23:08:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3da0af192ecfebbe5ecedb92c9e3138244ecce25",
          "body": "…(#181)\n\notel (v1.8.0) and dex (v0.1.0) are already at their latest releases.",
          "is_bot": false,
          "headline": "defaults: bump lakerunner v1.33.0->v1.40.0, maestro v1.46.4->v1.50.0 …",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-02T22:27:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7986412cd825277dce3209cf69be0d610ee24c77",
          "body": "…GroupEgress deny (#180)\n\nCustomer SCPs (CFCT-Clearpool-Deny-VPC-Destructive in acct 167872550306)\nexplicitly deny ec2:RevokeSecurityGroupEgress. Specifying an inline\nSecurityGroupEgress on AWS::EC2::SecurityGroup makes CloudFormation revoke\nthe AWS-auto-created default all-allow egress rule before \n[…]\nS keep its default rule. Identical behavior, no\nrevoke call.\n\nAffected: lakerunner_infra_base (ALB + task SGs), lakerunner_infra_rds (RDS\nSG), satellite_services (ALB + task SGs), lrdev_vpc (VPCE SG).",
          "is_bot": false,
          "headline": "sg: omit inline all-allow SecurityGroupEgress to avoid RevokeSecurity…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-02T21:28:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "78423a559aa91941539f188710d5ba106bc4298c",
          "body": "… resources via a privileged ECS task (#179)",
          "is_bot": false,
          "headline": "dev-scripts: add sweep-stranded-resources.sh to delete stranded stack…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-02T21:06:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "58b94b7cebfe269a8c5d3e554769e8bbacdc9e5a",
          "body": "Setting a bucket's PublicAccessBlockConfiguration requires\ns3:PutBucketPublicAccessBlock, which some deployer roles lack -- and AWS already\napplies account/bucket default Block Public Access to new buckets, so the\nexplicit config is redundant for safety.\n\nAdd a ConfigureBucketPublicAccessBlock param\n[…]\n an optional CONFIGURE_BUCKET_PUBLIC_ACCESS_BLOCK passthrough\n(regenerated via make scripts); template tests assert the opt-in Fn::If + the\ndefault-off param; jenkins-chained-deploy.md documents both.",
          "is_bot": false,
          "headline": "s3: make bucket PublicAccessBlock opt-in, default off (#178)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-02T20:45:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5f01dc348261f8d22c254e20c624c6e517f5cf60",
          "body": "…now optional) (#177)\n\nFiles are friction for operators, so the deploy drivers now take the license\ntoken and the cert PEMs as plain string env vars; the *_FILE variants stay as\nfallbacks (additive, non-breaking).\n\n- infra-base: LICENSE_DATA (z64 token string) primary; LICENSE_DATA_FILE fallback.\n  \n[…]\nts; added driver tests (string satisfies the\nlicense requirement; cert string -> temp file, *_FILE fallback kept) and updated\njenkins-chained-deploy.md. The monolith deploy-lakerunner.sh is untouched.",
          "is_bot": false,
          "headline": "drivers: accept license + cert PEMs as direct string env vars (files …",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-02T20:04:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9f1239ca33d6088307fb4947c749327120f32202",
          "body": "…/dev tooling to dev-scripts/ (#176)\n\nscripts/ should be a 1:1 mapping from a published top-level stack to a driver.\nRename deploy-scripts/ -> dev-scripts/ (internal/dev tooling, not published) and\nmove the lifecycle drivers out of scripts/ into it:\n\n- scripts/cleanup-lakerunner.sh -> dev-scripts/cl\n[…]\n operator docs (cleanup.md, end-to-end-test-plan.md)\nare repointed. scripts/ now holds the five chained per-stack drivers (plus the\ndeploy-lakerunner.sh monolith driver, left for a separate decision).",
          "is_bot": false,
          "headline": "scripts/: keep only customer-facing per-stack drivers; move lifecycle…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-02T20:02:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9516717e8c55823da445f09a6436f8aff72f0526",
          "body": "…#175)\n\nUndo the Aurora PostgreSQL change (#174): cardinal-lakerunner-infra-rds goes\nback to a single AWS::RDS::DBInstance (Postgres 18.4, db.r7g.large, gp3, with\nthe DBAllocatedStorage parameter). Driver part/generated driver, template\ntests, and the jenkins-chained-deploy DB rows are restored to their pre-Aurora\nstate; the Aurora design spec is removed.\n\nThe unrelated release.yml change from #174 (publish the deploy drivers to the\nversioned S3 prefix) is intentionally kept.",
          "is_bot": false,
          "headline": "Revert infra-rds Aurora conversion; restore RDS PostgreSQL instance (…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-02T20:02:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dc26fea84d1a691d5cd22135944573e0e4c68c6f",
          "body": "…#174)\n\nReplace the single AWS::RDS::DBInstance (Postgres 18.4, db.r7g.large) in the\ncardinal-lakerunner-infra-rds stack with a provisioned Aurora PostgreSQL\ncluster plus one writer instance:\n\n- DBCluster (aurora-postgresql, EngineVersion 17.9) holds the data and all\n  cluster-level settings; Deleti\n[…]\n.\n\nAlso: the release workflow now publishes the regenerated single-file deploy\ndrivers to s3://.../lakerunner/<version>/scripts/ alongside the templates, so\neach version's drivers match its templates.",
          "is_bot": false,
          "headline": "infra-rds: convert to Aurora PostgreSQL (provisioned, db.r8g.large) (…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-02T17:14:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e2f92f65241756c0c4c0354e55fc1a08273991a2",
          "body": "…#173)\n\ncardinal-alb-sg is customer-supplied and owned by neither the\ncardinal-lakerunner nor the cardinal-infrastructure stack, so neither\nstack-delete reaches it and the cleanup task left it behind. Add an\noptional AlbSecurityGroupId parameter (driver --alb-sg-id) threaded to an\nALB_SG_ID env var \n[…]\n cardinal-alb-sg as an ingress source (v1.39 health-port\nrules), in which case AWS returns DependencyViolation. The cleanup task\nrole already holds ec2:DeleteSecurityGroup, so no IAM change is needed.",
          "is_bot": false,
          "headline": "cleanup: optional --alb-sg-id to sweep the customer-supplied ALB SG (…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-02T16:03:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fdf9d07e829e64c14d20919cd508d147c36b4049",
          "body": "The five chained install/update drivers in scripts/ were thin wrappers that\nexec'd a shared scripts/deploy-stack.sh engine -- two files per deploy, a\ngitops hazard for customers who copy scripts into their own environment.\n\nEach driver is now a single self-contained file, generated by\nscripts-src/bu\n[…]\nasserts byte-identical committed drivers.\njenkins-chained-deploy.md is reframed; design spec added.\n\nScope is install/update only; teardown/cleanup and the deploy-lakerunner.sh\nmonolith are untouched.",
          "is_bot": false,
          "headline": "deploy: single-file per-stack drivers generated from scripts-src/ (#172)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-02T15:45:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cb78b1300c57b463a276ce9f6232c881c9d10a4c",
          "body": "….39 health checks) (#171)",
          "is_bot": false,
          "headline": "infra-base: open health port 8090 from ALB to query + control SGs (v1…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-02T09:48:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "160aa129f8e19a59be8b7c960ab79b5ef38ebea5",
          "body": "…(admin-api/query-api); distinct health ports per merged control container; add 60s grace (#170)",
          "is_bot": false,
          "headline": "services: ALB health checks target lakerunner v1.39 health port 8090 …",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-02T09:07:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2ccad71fea3e71c3f9835a3047eafaaa96b42ce6",
          "body": "…a-prefixed collector name (avoid storage-profile identity collision) (#169)",
          "is_bot": false,
          "headline": "satellite-services: require OrganizationId, auto-generate unique alph…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T20:58:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "adc0d3cade4ce7df3f35b7ca855c604f8855921c",
          "body": "… for autoscaled workers (#168)\n\n* ECS: on-demand FARGATE for all services (spot can't place reliably during rolling deploys)\n\n* ECS capacity: on-demand for singletons+collector, spot+on-demand-base for autoscaled workers",
          "is_bot": false,
          "headline": "ECS capacity: on-demand for singletons+collector, spot+on-demand-base…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T17:47:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cb22f267e96fd70839419a58b81d4a6ee6d3debf",
          "body": "…tivetodelta) (#167)",
          "is_bot": false,
          "headline": "otel collector: convert cumulative metrics to delta before S3 (cumula…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T17:18:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d929c27d6790557256253447c4a3476dbeff4c9a",
          "body": "…able upgrades (#166)\n\nWeight-only capacity-provider strategies do not fail over for a desired=1\nservice. ECS weights only distribute MULTIPLE tasks across providers; for a\nsingle task ECS picks one provider by weight, and if FARGATE_SPOT has no\ncapacity the task fails to place, tripping the deploym\n[…]\napi /\nquery-worker (explicit). The \"spot\" branch is kept for possible future use but\nis now unreferenced.\n\nNet effect: every service's first replica is on-demand; scale-out replicas stay\n~85-90% spot.",
          "is_bot": false,
          "headline": "Fix capacity-provider fallback: add Base=1 on-demand FARGATE for reli…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T14:05:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9f079bb4f3f80e8afbb2e20227792eff544c280a",
          "body": "… (us-east-1, us-east-2) (#165)",
          "is_bot": false,
          "headline": "docs: correct publish bucket to region-suffixed cardinal-cfn-<region>…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T14:05:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ff21abdda1847352b785f16ef41ca9cf39124e2e",
          "body": "…inal-cfn -> cardinal-cfn-us-east-1) (#164)",
          "is_bot": false,
          "headline": "Fix stale template base URL default in deploy scripts (us-east-2 card…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T12:53:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d50e9e2ea3d8731f777c1925f9bcfa79f7bc19b0",
          "body": "sweeper, monitoring, admin-api, and alert-evaluator are tiny (~1-3 millicores,\n~20-25 MiB each). As four separate Fargate tasks they each paid the 0.25 vCPU /\n0.5 GB per-task floor; co-locating them in one task (256 CPU / 512 MiB) cuts\nthat ~4x and leaves one task to place instead of four (a real wi\n[…]\n/200.\n- Outputs collapse to a single ControlServiceName; the root consumed none of the\n  removed per-service-name outputs. Declared parameters unchanged.\n\nTests updated to assert the merged structure.",
          "is_bot": false,
          "headline": "Merge four control-tier singletons into one ECS service/task (#162)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T12:28:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8d1fdfdf9a50951796991881091bb583b6b95482",
          "body": "… (#163)\n\nAdds PublicSubnet3/PrivateSubnet3 in Select(2, GetAZs()); re-indexes the\nCidr split from (4, 8) to (6, 8) with public=0,1,2 and private=3,4,5;\nupdates PublicSubnetsCsv/PrivateSubnetsCsv outputs to Join all 3; updates\nthe interface-endpoint SubnetIds list; updates tests accordingly.",
          "is_bot": false,
          "headline": "lrdev-vpc: widen from 2 to 3 AZs for more Fargate-Spot capacity pools…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T12:28:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7399045e83b3751fad60d898d68e6c715fd3dbf0",
          "body": "A transient FARGATE_SPOT capacity shortage (Capacity is unavailable at\nthis time) can prevent a singleton service from placing its one new task\nduring a rolling deploy, tripping the deployment circuit breaker and\nrolling back the whole stack on an image bump.\n\nAdd a capacity_provider_strategy helper\n[…]\npot).\n\nSingletons switched to fallback: migration, pubsub-sqs, sweeper,\nmonitoring, admin-api, alert-evaluator, maestro. Workers stay pure spot:\nquery-api, query-worker, process-{logs,metrics,traces}.",
          "is_bot": false,
          "headline": "Add FARGATE on-demand fallback to singleton ECS services (#161)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T11:54:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7daa9dad70eb62b6a16b18ab687593fd6b4ce01f",
          "body": "Add PubsubAutoRegister (default false) and PubsubAutoRegisterWritesToInstance\n(default 1) to the pubsub-sqs container only; wire them through the\nlakerunner-services root; expose PUBSUB_AUTOREGISTER /\nPUBSUB_AUTOREGISTER_WRITES_TO_INSTANCE as optional env vars in\ndeploy-lakerunner-services.sh.",
          "is_bot": false,
          "headline": "Add opt-in pubsub-sqs auto-registration env vars (#160)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T10:59:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c4b7e4529578ddcb00846d5021fc0fb8a041cd87",
          "body": "* self-telemetry: configurable OTLP/HTTP endpoint to (satellite) collector\n\nReplace the locked SelfTelemetry=[No] toggle with a real SelfTelemetryEndpoint\nparameter (String, default ). When set, the query/process/control tiers export\nself-telemetry to it via OTEL_EXPORTER_OTLP_ENDPOINT, with ENABLE_\n[…]\nlution is graceful: a missing stack or absent\nCollectorEndpoint output warns to stderr and leaves self-telemetry off rather\nthan failing the app deploy. A non-empty SELF_TELEMETRY_ENDPOINT still wins.",
          "is_bot": false,
          "headline": "Self-telemetry to the collector, on by default (#159)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T07:05:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "62a882b1f0245497235bb267159db97c34e4d9db",
          "body": "…ME; drop unused otel artifacts (#158)\n\n- deploy-lakerunner-services.sh: cleanup_cert now captures $? first, cleans\n  up, clears the EXIT trap, and re-exits with the captured status, so a FAILED\n  child deploy no longer false-greens via rm's success.\n- Make DEX_ADMIN_PASSWORD_HASH a REQUIRED env var\n[…]\n Otel task SG, otel-only\n  inter-tier ingress rules, dead OTLP/health port constants, and the\n  OtelSecurityGroupId / OtelRoleArn outputs (satellite collector has its own).\n- Update tests accordingly.",
          "is_bot": false,
          "headline": "Deploy-services fixes: exit-code masking, required DEX hash, ALB_SCHE…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T06:16:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "32212786d396296f7c32179057e4b65fba242af6",
          "body": "…(#157)\n\nThe lakerunner image is distroless (no /bin/sh), so the prior\nPubsubSqsEnv blob wrapped in sh -c 'set -a; eval \"$PUBSUB_SQS_ENV\"; ...'\ncrash-looped with exec: \"sh\": executable file not found.\n\nReplace the blob with plain SQS_QUEUE_URL / SQS_REGION / SQS_ROLE_ARN\ncontainer env vars for the s\n[…]\n RawQueueUrl /\nLakerunnerAccessRoleArn from the satellite-infra-base stack and passes\nthem as plain params. Multi-account fan-out (numbered SQS_*_N groups) will\nlater use ECS environmentFiles from S3.",
          "is_bot": false,
          "headline": "fix pubsub-sqs SQS env: plain ECS env vars, not a sh -c eval wrapper …",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T05:01:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "31ca7823ff66140b746538bba5739989234555e3",
          "body": "The satellite collector handles all ingest now; the in-stack otel child\nis redundant and its /cardinal/otel-grpc log group collides with the\nsatellite collector's. Drop the Otel nested child, its otel-only\nparameters (OtelReplicas/Cpu/Memory/ConfigYaml/Image, OtelSecurityGroupId,\nOtelRoleArn), the o\n[…]\nl generator and its test, and the otel entry in the\nbuild/test wiring. Self-telemetry to the in-stack collector is gone, so\ntier children deploy with telemetry disabled (endpoint \"\", enabled\n\"false\").",
          "is_bot": false,
          "headline": "remove otel collector from lakerunner-services (#156)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T04:42:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "13f1b0a99288388e8ccf544e11ce657bcdd2c7f5",
          "body": "* deploy scripts: convert from flags to pure env-var interface\n\nConvert deploy-stack.sh and its five wrappers to a pure\nenvironment-variable interface (SCREAMING_SNAKE_CASE); no command-line\nflags remain. REGION is required in every script and never defaulted.\n\nEach script collects all missing requi\n[…]\nution, unreadable-file\nfailure, PARAMS-wins precedence) via a new --internal-build-upstream hook,\nand document FILE_PARAMS + the create-only cert behavior in\ndocs/operations/jenkins-chained-deploy.md.",
          "is_bot": false,
          "headline": "Deploy scripts: env-var driven (required-first, REGION required) (#155)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T03:53:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1be9fb7e5064ba159a8daf681e0bda1871220d45",
          "body": "* design: multi-account satellite ingest\n\n* design: make pull model an explicit invariant\n\n* design: stack topology, team isolation, driver wiring, VPC as input\n\n* design: symmetric satellite-infra-base/satellite-services naming + cardinal- prefix and nested-name note\n\n* design: Cloud Map namespaces\n[…]\n PubsubSqsEnv from satellite outputs).\n\nAdds tests/unit/test_deploy_stack_lint.py and docs/operations/jenkins-chained-deploy.md.\n\n* fix(deploy): shellcheck SC2002 — drop useless cat in deploy-stack.sh",
          "is_bot": false,
          "headline": "Multi-account satellite ingest: full 5-stack topology (#154)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-06-01T03:15:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "051543fe51aa5eca9834c53d50c806b12c737897",
          "body": null,
          "is_bot": false,
          "headline": "default RDS Postgres to 18.4 (#153)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-05-30T16:23:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "56b22cb8a8172c6b0bb9de34812d2e7d9f2cc117",
          "body": null,
          "is_bot": false,
          "headline": "default RDS to db.r7g.large for prod-like sizing (#152)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-05-30T16:20:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "70c8f58e71c79bf50af6938ff5defe7f9edb7b63",
          "body": null,
          "is_bot": false,
          "headline": "run all ECS tasks on FARGATE_SPOT + arm64 (#151)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-05-30T15:15:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c1cd8dbc0469fce4cfae4fb1582b088b789838de",
          "body": "…(#150)",
          "is_bot": false,
          "headline": "chore: bump lakerunner v1.32.0->v1.33.0 and maestro v1.46.1->v1.46.4 …",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-05-29T14:49:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "87f8ff09957860ea1c199a3c25be863718ad3132",
          "body": "The v1.46.1 maestro image consumes the MAESTRO_BOOTSTRAP_BUCKET_*\nenv vars added in PR #147 to repopulate the\nconfigdb.organization_buckets join row inside the in-process\nLakerunner provisioning worker. Previously (v1.45.9) the worker\ndeleted the row without re-creating it on every provision_org cycle,\nbreaking Explore until ensure-storage-profile re-ran from the\nmigration ECS task -- which only fires when the migration task\ndefinition changes.",
          "is_bot": false,
          "headline": "bump: maestro v1.45.9 -> v1.46.1 (#148)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-05-29T05:25:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a7c050ed4acdd7134386252f4bba82dcde6def86",
          "body": "A future maestro version (post-v1.45.9) will use these env vars to\nre-insert the configdb.organization_buckets join row that the\nv1.45.9 in-process provision_org sync currently deletes without\nre-creating. Observed live: every maestro reprovision / restart wipes\norganization_buckets and Explore retu\n[…]\nur env vars are wired.\n- test_root: assert root forwards IngestBucketName -> BucketName.\n\nNo behavior change yet on the current maestro image; takes effect\nonce a build that honors the new vars lands.",
          "is_bot": false,
          "headline": "maestro: pass bucket coordinates as MAESTRO_BOOTSTRAP_BUCKET_* (#147)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-05-28T23:40:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7f1f4f48ff9ec98836c1b159c41f5940ee5fb0dd",
          "body": "…82) (#146)\n\nPR #144 moved QueryWorkerFromQuery from 8081 to 8082 to track the\ngRPC control-stream port the v1.32.0 lakerunner image uses. That fixed\n\"no available workers\" on dispatch. But the worker still serves a\nplain-HTTP artifact endpoint at 8081 -- query-api fetches Parquet\nresults via GET /a\n[…]\nrkerArtifactFromQuery on 8081 alongside the existing\nQueryWorkerFromQuery on 8082. Split the port constants so the intent\nis documented and a future image migration can update each rule\nindependently.",
          "is_bot": false,
          "headline": "fix: reopen 8081 for query-worker artifact fetch (need both 8081 + 80…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-05-28T21:43:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7b80510089370a2b636ffa73b7f60964c4e6831f",
          "body": "\"INSERT 0 0\" is opaque when ensure-storage-profile runs but the storage\nprofile join still doesn't exist -- there's no signal whether the input\nvalues were wrong, whether the bucket_configurations row was missing\nat SELECT time, whether ON CONFLICT fired, or whether something later\ndeleted the rows.\n[…]\ne observability. Drove by query-worker\n\"storage profile not found\" errors against an install where\nensure-storage-profile logged \"INSERT 0 0\" and we could not tell why\nwithout re-running with psql -e.",
          "is_bot": false,
          "headline": "migration: verbose logging in ensure-storage-profile (#145)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-05-28T21:10:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "02b860d901f088362a2cb1c01cc2c2ec216cb77a",
          "body": "The v1.32.0 lakerunner image moved query-worker's gRPC control-stream\nport from 8081 to 8082. The QueryWorkerFromQuery SG ingress rule and\nthe cardinal-defaults.yaml ingress.port both still said 8081, so\nquery-api's Discovery bridge kept logging:\n\n  Discovery bridge: failed to connect worker ... dia\n[…]\nies returned empty rather than failing -- the\n\"list of services\" comes from RDS index and survives, but actual\ntime-series fetch needs the query-worker fan-out which was silently\nproducing no results.",
          "is_bot": false,
          "headline": "fix: query-worker port 8081 -> 8082 (lakerunner v1.32.0 moved it) (#144)",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-05-28T20:35:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2c16fbee2a5367c5d2e7cc65ac18bfc02a7d8743",
          "body": "…143)\n\nMaestro reaches the lakerunner query-api (8080) and admin-api (9091)\nvia Cloud Map at cardinal.local DNS names, bypassing the ALB. There\nwere no SG rules between MaestroSecurityGroup and either\nQuerySecurityGroup or ControlSecurityGroup on those ports, so every\nmaestro-side Cloud Map call hun\n[…]\ntyGroupIngress rules:\n- QueryFromMaestro: MaestroSG -> QuerySG on 8080\n- ControlAdminApiFromMaestro: MaestroSG -> ControlSG on 9091\n\nPlus a regression assertion in test_security.py pinning both rules.",
          "is_bot": false,
          "headline": "security: open Maestro -> query-api / admin-api cross-tier ingress (#…",
          "author_name": "Michael Graff",
          "author_login": "skandragon",
          "committed_at": "2026-05-28T20:24:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 100,
      "commits_last_year": 423,
      "latest_release_at": "2026-06-30T18:48:13Z",
      "latest_release_tag": "v1.6.5",
      "releases_from_tags": false,
      "days_since_last_push": 27,
      "active_weeks_last_year": 33,
      "days_since_latest_release": 27,
      "mean_days_between_releases": 0.8
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": false,
      "has_contributing": false,
      "health_percentage": 25,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 0,
      "stars": 1,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": null,
      "open_issues_and_prs": 3
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [
        "Makefile"
      ],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "pyrightconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 33578,
      "source_files_sampled": 69,
      "oversized_source_files": 0,
      "agent_instruction_files": [
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 15275
    },
    "dependencies": {
      "manifests": [
        "requirements.txt"
      ],
      "advisories": {
        "error": null,
        "scope": "repository_graph",
        "source": "osv",
        "findings": [],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 5,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "pypi"
      ],
      "dependencies": [],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "cfn-lint",
            "direct": false,
            "version": "1.49.3",
            "ecosystem": "pypi"
          },
          {
            "name": "cloud-radar",
            "direct": false,
            "version": "0.16.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest",
            "direct": false,
            "version": "9.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "pyyaml",
            "direct": false,
            "version": "6.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "troposphere",
            "direct": false,
            "version": "4.10.1",
            "ecosystem": "pypi"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 5,
        "direct_count": 0,
        "indirect_count": 5
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 230,
        "open_issues": 3,
        "closed_ratio": 0.667,
        "closed_issues": 6,
        "closed_unmerged_prs": 4
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "skandragon",
          "commits": 425,
          "avatar_url": "https://avatars.githubusercontent.com/u/43517?v=4"
        },
        {
          "type": "User",
          "login": "kunalkundaje",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/552415?v=4"
        }
      ],
      "contributors_sampled": 2,
      "top_contributor_share": 0.998
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "release.yml",
        "test.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 3,
            "reason": "branch protection is not maximal on development and all release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 3,
            "reason": "project has 1 contributing companies or organizations -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 0,
            "reason": "Project has not signed or included provenance with any releases.",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "7fc5c3530ae0d14eb15c6134c444f78056a892d1",
        "ran_at": "2026-07-28T07:44:36Z",
        "aggregate_score": 4,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-06-30T18:48:18Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-06-30T18:47:24Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 72,
          "created_at": "2026-05-03T14:28:10Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 73,
          "created_at": "2026-05-03T14:28:18Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 74,
          "created_at": "2026-05-03T14:28:26Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/cardinalhq/lakerunner-cloudformation",
    "host": "github.com",
    "name": "lakerunner-cloudformation",
    "owner": "cardinalhq"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 55,
      "inputs": {
        "security": 52,
        "vitality": 84,
        "community": 24,
        "governance": 44,
        "engineering": 67
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 84,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 80,
            "inputs": {
              "commits_last_year": 423,
              "human_commit_share": 1,
              "days_since_last_push": 27,
              "active_weeks_last_year": 33
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 27 days ago",
                "points": 28.8,
                "status": "partial",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 27
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "33/52 weeks with commits",
                "points": 22.8,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 33
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "423 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 423
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "releases_count": 100,
              "latest_release_tag": "v1.6.5",
              "releases_from_tags": false,
              "days_since_latest_release": 27,
              "mean_days_between_releases": 0.8
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "100 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 100
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 27 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 27
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0.8 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0.8
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 27,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 27 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 27
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "critical",
        "name": "Community & Adoption",
        "value": 24,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 1,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "1 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (AGPL-3.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "AGPL-3.0"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 44,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 15,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 2,
              "top_contributor_share": 0.998
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "2 contributors",
                "points": 2.7,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "moderate",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 69,
            "inputs": {
              "merged_prs": 230,
              "open_issues": 3,
              "closed_issues": 6,
              "issue_closed_ratio": 0.667,
              "closed_unmerged_prs": 4
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "67% of issues closed",
                "points": 31.2,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 67
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "230/234 decided PRs merged",
                "points": 37.6,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 230,
                      "decided": 234
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 54,
            "inputs": {
              "followers": 7,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "cardinalhq",
              "public_repos": 30,
              "account_age_days": 1224
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "7 followers of cardinalhq",
                "points": 6.5,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 7,
                      "login": "cardinalhq"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "30 public repos, account ~3 yr old",
                "points": 17.6,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 30
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 3
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 67,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "2 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 52,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Packaging. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "packaging"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 40,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 4
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection is not maximal on development and all release branches",
                "points": 2.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 0.8,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories, No advisories left outstanding. Remaining weights renormalized. Matched 5 resolved dependencies against OSV. This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "indirect_dependencies_free_of_known_advisories",
                    "no_advisories_left_outstanding"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_repository",
                "params": {
                  "assessed": 5
                }
              },
              {
                "code": "advisories_repo_graph_caveat",
                "params": {}
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 0,
              "affected_packages": 0,
              "assessed_packages": 5,
              "unassessed_packages": 0,
              "affected_by_severity": "none",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "transitive set not separable from development and test dependencies in this scope",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_scope_not_separable",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory carries a publication date",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_no_publication_date",
                    "params": {}
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 5,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 3
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 68,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.92,
              "agent_instruction_files": [
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 15275
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "92 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 92,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 51,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [
                "Makefile"
              ],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "pyrightconfig.json"
              ],
              "agent_commit_share": 0,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "Makefile",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Makefile"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "pyrightconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "pyrightconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "no agent-authored commits among the last 100",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "good",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 82,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 33578,
              "source_files_sampled": 69,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python with type-check config (pyrightconfig.json)",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "typecheck_config_language",
                    "params": {
                      "files": "pyrightconfig.json",
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/69 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 69,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-28T07:44:52.795807Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/c/cardinalhq/lakerunner-cloudformation.svg",
  "full_name": "cardinalhq/lakerunner-cloudformation",
  "license_state": "standard",
  "license_spdx": "AGPL-3.0"
}

Scores are signals, not warranties. They reflect publicly visible practices on GitHub — not a code audit, and not a security guarantee.

Missing data is excluded and weights renormalized, never scored as zero. Methodology is versioned and open: metrics v1.13.0, schema v0.27.0 — full methodology · metrics wiki.

How one result sits in the wider record: aggregate statistics.