Public record
Software health reportschema 0.27.0 · metrics 1.13.0 · 2026-07-24 01:26 UTC

wmetcalf / blastbox

Reusable detonation framework: run untrusted documents through disposable, hardened workers

PythonMIT★ 0 stars⑂ 0 forkssince Jun 2026View on GitHub ↗

wmetcalf/blastbox holds a health index of 54 out of 100, placing it in the Moderate band. It scores highest on Vitality (76/100) and lowest on Community & Adoption (31/100). It was last updated today. A single contributor accounts for most of its recent work.

54
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.

54
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

William MetcalfPersonal account
102 followers73 public repossince Sep 2010

This repository is owned by a personal account. A single-owner project carries more continuity risk than an organization-backed one.

Package ecosystems

RegistryPackageVersionDownloads / moVersionsLast publishTags
PyPIblastbox0.1.261,346270 days agosandboxmalwaredetonationuntrusteddocumentisolation

Metrics by category

Vitality

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

76Good · 22% of overall
How it's scored
36/36Push recency — last push 0 days ago
5.5/36Commit cadence — 8/52 weeks with commits
18/18Commit volume — 383 commits in the last year
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Inputs used
commits_last_year383
human_commit_share1
days_since_last_push0
active_weeks_last_year8

Release discipline

100Excellent
How it's scored
27/27Ships releases — 27 releases published
36/36Release recency — latest release 0 days ago
27/27Release cadence — a release every ~2.8 days
0/10OpenSSF Scorecard: Signed-Releases — no data
Inputs used
releases_count27
latest_release_tagv0.1.26
releases_from_tagsno
days_since_latest_release0
mean_days_between_releases2.8
Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.

Community & Adoption

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

31At risk · 18% of overall
How it's scored
0/60Stars — 0 stars
0/25Forks — 0 forks
0/15Watchers — 0 watchers
Inputs used
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
How it's scored
22.5/22.5README
22.5/22.5License — recognized license (MIT)
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
How it's scored
41.7/80Monthly downloads — 1,346 downloads/month across pypi
0/20Registry dependents — not reported by this ecosystem
Inputs used
packagesblastbox
dependents
ecosystemspypi
total_downloads
monthly_downloads1,346
Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.

Sustainability & Governance

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

55Moderate · 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
1.4/13.5Contributor breadth — 1 contributors
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Inputs used
bus_factor1
contributors_sampled1
top_contributor_share1
How it's scored
0/46.8Issue resolution — no issues or no data
34.7/38.3PR acceptance — 59/65 decided PRs merged
0/15OpenSSF Scorecard: Code-Review — Found 0/3 approved changesets -- score normalized to 0
Inputs used
merged_prs59
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs6
Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.
How it's scored
10/30Ownership backing — personal (user) account
0/20Verified domain — not applicable to user accounts
14.5/25Owner reach — 102 followers of wmetcalf
25/25Track record — 73 public repos, account ~15 yr old
Inputs used
followers102
owner_typeUser
is_verified
owner_loginwmetcalf
public_repos73
account_age_days5,784
Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.
How it's scored
25/25Published & resolvable — 1 package(s) on pypi
35/35Publish recency — latest publish 0 days ago
20/20Version history — 27 published versions
20/20Not deprecated — active, not deprecated or yanked
Inputs used
packagesblastbox
ecosystemspypi
any_deprecatedno
min_days_since_publish0

Engineering Quality

Are baseline engineering and documentation practices in place?

65Moderate · 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
10/20OpenSSF Scorecard: CI-Tests — 1 out of 2 merged PRs checked by a CI test -- score normalized to 5
Inputs used
has_ciyes
has_testsyes
has_editorconfigno
has_linter_configno
has_precommit_configno
How it's scored
30/30README
25/25Documentation directory
0/15Documentation / homepage site
10/10Repository description
0/10Topics
10/10Wiki
Inputs used
topics
has_wikiyes
homepage
has_readmeyes
has_docs_diryes
has_descriptionyes

Security

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

35At risk · 16% of overall
How it's scored
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
1.2/2.5CI-Tests — 1 out of 2 merged PRs checked by a CI test -- score normalized to 5
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/3 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
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
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
5/5Packaging — packaging workflow detected
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 — no data
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_aggregate3.5
Excluded from scoring (no data or not applicable): signed_releases. Remaining weights renormalized.

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.

65Moderate · 0% of overall
How it's scored
45/45Agent instructions — AGENTS.md
0/15Machine-readable docs (llms.txt)
40/40Legible commit history — 100 of 100 human commits state their intent (structured subject or explanatory body)
Inputs used
has_llms_txtno
legible_history_share1
agent_instruction_filesAGENTS.md
agent_instruction_max_bytes2,942
How it's scored
0/18One-command bootstrap
22/22Automated tests
0/11Lint / format config
11/11Static type checking — src/blastbox/py.typed
10/10Reproducible environment — Dockerfile
10/10Demonstrated agent practice — 24 of the last 100 commits agent-authored or agent-credited
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_dockerfileyes
typed_languageno
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configssrc/blastbox/py.typed
agent_commit_share0.24
toolchain_manifests
dependency_bot_commit_share0
How it's scored
27/45Type-checkable code — Python with type-check config (src/blastbox/py.typed)
53.7/55Manageable file sizes — 6/249 source files over 60KB
Inputs used
primary_languagePython
largest_source_bytes138,065
source_files_sampled249
oversized_source_files6
How it's scored
0/40API schema (OpenAPI/GraphQL/proto)
0/20MCP server
40/40Runnable examples — examples
Inputs used
example_dirsexamples
has_mcp_signalno
api_schema_files

Key facts

0GitHub stars
1contributors
383commits, last 12 months
0days since last push
27releases
1bus factor
0open issues
PyPIpackage ecosystems

Data collection warnings

  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository
  • deps.dev does not index pypi:blastbox@0.1.26; advisories assessed against the repository dependency graph instead

More detail

OpenSSF Scorecard 3.5 / 10
3.5aggregate

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-24 01:26 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
5CI-Tests1 out of 2 merged PRs checked by a CI test -- score normalized to 5
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/3 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
10Packagingpackaging workflow 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
n/aSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
Direct dependencies 1
RegistryPackageVersion constraintManifest
PyPIpydantic>=2.6.0pyproject.toml
All dependencies not collected

The resolved dependency set could not be collected for this report: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Raw JSON report machine-readable
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 4291,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "C": 4524,
        "Shell": 23260,
        "Python": 2956335,
        "Dockerfile": 1520
      },
      "pushed_at": "2026-07-24T01:22:12Z",
      "created_at": "2026-06-01T22:15:24Z",
      "owner_type": "User",
      "updated_at": "2026-07-24T01:21:59Z",
      "description": "Reusable detonation framework: run untrusted documents through disposable, hardened workers",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Python",
      "significant_languages": [
        "Python"
      ]
    },
    "owner": {
      "blog": null,
      "name": "William Metcalf",
      "type": "User",
      "login": "wmetcalf",
      "company": null,
      "location": null,
      "followers": 102,
      "avatar_url": "https://avatars.githubusercontent.com/u/409768?v=4",
      "created_at": "2010-09-21T12:36:45Z",
      "is_verified": null,
      "public_repos": 73,
      "account_age_days": 5784
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.1.26",
          "kind": "patch",
          "published_at": "2026-07-24T01:22:12Z"
        },
        {
          "tag": "v0.1.25",
          "kind": "patch",
          "published_at": "2026-07-23T16:01:26Z"
        },
        {
          "tag": "v0.1.24",
          "kind": "patch",
          "published_at": "2026-07-20T15:33:07Z"
        },
        {
          "tag": "v0.1.23",
          "kind": "patch",
          "published_at": "2026-07-20T14:47:17Z"
        },
        {
          "tag": "v0.1.22",
          "kind": "patch",
          "published_at": "2026-07-13T14:31:55Z"
        },
        {
          "tag": "v0.1.21",
          "kind": "patch",
          "published_at": "2026-07-12T23:15:23Z"
        },
        {
          "tag": "v0.1.20",
          "kind": "patch",
          "published_at": "2026-07-12T18:37:41Z"
        },
        {
          "tag": "v0.1.19",
          "kind": "patch",
          "published_at": "2026-06-29T15:38:17Z"
        },
        {
          "tag": "v0.1.18",
          "kind": "patch",
          "published_at": "2026-06-29T14:30:35Z"
        },
        {
          "tag": "v0.1.17",
          "kind": "patch",
          "published_at": "2026-06-28T14:16:21Z"
        },
        {
          "tag": "v0.1.16",
          "kind": "patch",
          "published_at": "2026-06-20T03:33:26Z"
        },
        {
          "tag": "v0.1.15",
          "kind": "patch",
          "published_at": "2026-06-14T16:58:17Z"
        },
        {
          "tag": "v0.1.14",
          "kind": "patch",
          "published_at": "2026-06-14T02:30:22Z"
        },
        {
          "tag": "v0.1.13",
          "kind": "patch",
          "published_at": "2026-06-13T14:01:53Z"
        },
        {
          "tag": "v0.1.12",
          "kind": "patch",
          "published_at": "2026-06-13T03:31:05Z"
        },
        {
          "tag": "v0.1.11",
          "kind": "patch",
          "published_at": "2026-06-12T17:21:27Z"
        },
        {
          "tag": "v0.1.10",
          "kind": "patch",
          "published_at": "2026-06-12T15:19:28Z"
        },
        {
          "tag": "v0.1.9",
          "kind": "patch",
          "published_at": "2026-06-12T14:09:35Z"
        },
        {
          "tag": "v0.1.8",
          "kind": "patch",
          "published_at": "2026-06-12T13:53:46Z"
        },
        {
          "tag": "v0.1.7",
          "kind": "patch",
          "published_at": "2026-06-08T18:29:24Z"
        },
        {
          "tag": "v0.1.6",
          "kind": "patch",
          "published_at": "2026-06-08T14:08:20Z"
        },
        {
          "tag": "v0.1.5",
          "kind": "patch",
          "published_at": "2026-06-08T06:04:18Z"
        },
        {
          "tag": "v0.1.4",
          "kind": "patch",
          "published_at": "2026-06-08T04:47:22Z"
        },
        {
          "tag": "v0.1.3",
          "kind": "patch",
          "published_at": "2026-06-07T18:02:25Z"
        },
        {
          "tag": "v0.1.2",
          "kind": "patch",
          "published_at": "2026-06-02T02:09:21Z"
        },
        {
          "tag": "v0.1.1",
          "kind": "patch",
          "published_at": "2026-06-02T00:06:40Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2026-06-01T22:41:10Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "047a4148a766e73cc85311db2d9c4b196a3bbf47",
          "body": "The ingress ran a single uvicorn worker (`uvicorn.run(app, workers=1)`), and its\nblob-store I/O is synchronous, so under load all submit/status/result requests\nserialize behind one event loop (submits measured 7-44s with ~150 concurrent\nclients). On a shared-queue fleet this caps ingest throughput a\n[…]\n-loop serialization bottleneck.\n\nBumps 0.1.25 -> 0.1.26.\n\n\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(serve): add `serve --workers N` for a multi-worker ingress (#66)",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-24T01:21:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "31546843ee7d8df0acf364dc86dcd62ea02bd942",
          "body": "Host-side distributed blob storage (BlobStore: LocalBlobStore default /\nS3BlobStore opt-in) landed in #65. Patch bump, not minor: the engine contract\n(the validate callable / worker interface) is unchanged, so it stays within the\nengines' >=0.1.x,<0.2 compatibility cap — RedTusk needs only a build-arg bump and\nClippyShot needs no constraint change.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "release: blastbox 0.1.25 (distributed blob storage)",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-23T16:01:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9c7c879e634c211f106ca815c02db4337337530f",
          "body": "Distributed blob storage (samples + results via BlobStore)",
          "is_bot": false,
          "headline": "Merge pull request #65 from wmetcalf/feat/distributed-blob-storage",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-23T15:58:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "33fe251cdc0b1a6ed079ebf9524b7ca0cd1d3842",
          "body": "… residual\n\nC1 (upgrade migration): a job that completed before this feature has its output at the\nlegacy <job_root>/<id>/output and was never uploaded to the store, so the store-only\nread path 404s it after an in-place upgrade. LocalBlobStore.open_output now falls back\nto that legacy on-disk locati\n[…]\n-links to it.\n\nGates green: ruff, mypy, pytest (0 failed).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix(blobs): C1 legacy-output fallback for local upgrades; document C2…",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-23T02:24:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b3295fbfcd7a87ee7ca34870da2207339b87aeb1",
          "body": "…ap) + bug_003 (non-dict metadata)\n\nIndependent cloud review of the branch found two issues on top of the two marla loops:\n\nbug_001 — the upload-exhaustion partial-blob reap (Finding S1) was unconditional. The\npre-upload _claim_is_still_ours check runs BEFORE the retry loop, so the whole backoff\nwin\n[…]\n\n\nGates green: ruff, mypy, pytest (2121 passed, 0 failed).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix(dispatch,ingress): ultrareview bug_001 (claim-fence exhaustion re…",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-23T01:39:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8f6a733ca49a3a0ce4f4acd66c04ccc03aa22694",
          "body": "…etry\n\nC4: S3BlobStore.delete_job now inspects delete_objects' Errors field and\nraises on a partial delete, instead of treating S3's always-200 response\nas unconditional success -- mirrors the already-correct LocalBlobStore.\n\nS1: both dispatchers (classic Dispatcher's shared _upload_output, and\nVmJo\n[…]\nepend on the same bytes with no refcount to check against.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix(blobs,dispatch,ingress): C4/S1/E2/C3 -- blob-lifecycle error symm…",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T20:52:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bba82ad683a5cfdd432e23e8a45a4327ecbebe7a",
          "body": "…es on demand; E3 — consecutive-not-lifetime materialise_attempts\n\nThe classic Dispatcher (cold + warm paths) had zero get_sample calls, so a\njob whose sample lived only in the blob store (a shared-queue deployment,\nuploaded by another node's ingress) ran with a missing/garbage input\ninstead of fetc\n[…]\n consecutive failures as documented, not a lifetime total.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix(dispatch,vm_dispatch): E1 — classic Dispatcher materialises sampl…",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T20:32:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "10a366331a54ed8fa599eec0bf7ca93135a32f31",
          "body": "…ore result upload\n\nThe P1 fix added self._upload_output() to both the cold (_dispatch_inner) and\nwarm (_dispatch_warm) success paths, but put_output is a per-job-key overwrite,\nnot a claim-fenced CAS — unlike VmJobDispatcher._process, which already\nrechecks _claim_is_still_ours() immediately before\n[…]\nlaim. Confirmed red against the\npre-fix code, green after.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix(dispatch): R2-1 — classic Dispatcher rechecks claim ownership bef…",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T19:03:39Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d81bd86faf0023e488be8700ec39da78069dc768",
          "body": "…E, propagate real local-delete errors, strip materialise_attempts, fix job_root/blob_root doc contradiction\n\n- ingress/app.py: DELETE /v1/jobs/{id} now calls _blob_store.delete_job(job_id)\n  (best-effort, logged not fatal) so durable result artifacts under blob_root\n  (outside job_root) are actuall\n[…]\nASTBOX_BLOB_LOCAL_ROOT or s3://), never a shared job_root.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix(blobs,ingress,jobs,docs): P2/D2/L1 + doc F2 — reap blobs on DELET…",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T18:31:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "923357a4c5bb9973cb80cf62b25c40462ebe7966",
          "body": "… blob store\n\ncli.py builds Dispatcher (the \"file\" dispatch-style path) for every local\nruntime (cold, docker, firecracker, gvisor) — the standard local deployment.\nIt finished jobs at job_root/<id>/output and marked them DONE but never called\nput_output. The API's result routes (ingress/app.py) rea\n[…]\nand upload-failure policy\non both the cold and warm paths.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix(dispatch): P1 — the classic Dispatcher now uploads results to the…",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T18:19:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5ce0226c84d736e75ea08c448854a90a375ab509",
          "body": "…l \"preserve for retry\"\n\nVmJobDispatcher._process left a put_output failure RUNNING with\npreserve_result_for_retry=True, on the theory that \"the sweeper / a retry can\nstill find it.\" No such consumer exists: nothing re-runs a RUNNING job. In\npractice orphan recovery eventually FAILs the job but unli\n[…]\nsted-retries case (FAILED, job dir purged, not preserved).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix(vm_dispatch,blobs): D1 — bounded retry replaces the non-functiona…",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T18:19:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0ba1bffdaaf150c247d8867d277aee010cc0a491",
          "body": "The net_policy-rejection block in _process gated _purge_job_dir inside the\nFAILED CAS's `if`, so a peer reclaim between claim_next() and the CAS (which\nmakes the CAS lose) skipped the purge entirely, leaving spooled malware bytes\non this worker's disk. Mirror the already-correct reclaim-before-valid\n[…]\n. The FAILED-status write itself is unchanged.\n\nAdds a regression test simulating the lost-CAS race (peer flips claim_id\nbetween claim and the net_policy CAS) and confirms the job dir is still\npurged.",
          "is_bot": false,
          "headline": "fix(vm_dispatch): purge job dir unconditionally on net_policy rejection",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T16:37:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c57cd8f0b9fc67a90f0309718c8ce78bc0ef5fa1",
          "body": "F1 (SECURITY): make the worker job-dir purge genuinely unconditional. The\n`finally` in VmJobDispatcher._process gated on `owned` (the terminal-CAS\nreturn), so a peer reclaiming in the CAS window — or a NoWarmSlot requeue that\nforces owned=False — left the materialised sample + output on this worker'\n[…]\nr every path; all gates green (ruff, mypy, pytest tests/).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix(blobs,dispatch,retention): close final-review F1/F3/F4 findings",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T16:20:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9a927eba39ce9b20cd9b120d7c64fdc7c5b3d691",
          "body": "Task 8 wired blob_store into VmJobDispatcher's JobRetentionSweeper but left\nDispatcher._run_maintenance's sweeper construction unwired. In a mixed-tier\nfleet sharing one JobStore (FC-warm nodes on Dispatcher + AWS Lambda burst on\nVmJobDispatcher/network dispatch_style, always blob-backed), expire_du\n[…]\n_run_maintenance passes it\nthrough to JobRetentionSweeper.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix(retention): wire blob_store into the dispatch.py sweeper too",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T15:51:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3e16c87a999533eb095039f76c93ba32345104b5",
          "body": "RetentionSweeper (JobRetentionSweeper) gains an optional blob_store param.\nWhen set, expiring a job also calls BlobStore.delete_job(job_id) after the\non-disk rmtree, so result bytes uploaded via put_output don't outlive the\nlocal copy. delete_job is scoped to results/<job_id> only (backends already\n\n[…]\nhe blob\nstore via put_output) now passes its self._blobs through to the sweeper.\nblob_store defaults to None, so every other construction site and mode-1\n(no BLASTBOX_BLOB_URL) behaviour is unchanged.",
          "is_bot": false,
          "headline": "feat(retention): reap result blobs; never delete shared sample blobs",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T15:33:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "86255ceb0ed656640fd015c39621cacd84e8c1ee",
          "body": "…tes through the blob store\n\nCloses two gaps a security review found in the result-serving path, both\nrequired for correctness on a multi-node deployment (workers purge the job\ndir after upload; result routes must serve from the blob store):\n\n- LocalBlobStore/S3BlobStore.put_output walked out_dir wi\n[…]\naps, including a fail-red-first check for the symlink fix.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix(blobs,ingress): reject symlinks in put_output; route artifact rou…",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T15:23:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9356cc36f7ca141e2f8a996d65edc11570fbfad5",
          "body": "/v1/jobs/{id}/metadata and /result now read exclusively through\nBlobStore.open_output instead of the local job_root output/ dir. After the\nworker purge (Task 5/6), the local output dir is gone by the time these\nroutes run on a real deployment, so the filesystem-coupled reads 404'd every\ncompleted jo\n[…]\ne docs/superpowers/sdd/task-7-report.md for the full\nbefore/after, gate output, and a flagged latent finding (put_output follows\nsymlinks when uploading, in local.py/s3.py, outside this task's scope).",
          "is_bot": false,
          "headline": "feat(ingress): serve result artifacts through the blob store",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T14:54:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e8d258a972b32774c3b78647a7aaec88bc722834",
          "body": "put_output writes to a deterministic per-job key as a per-file\noverwrite/union, not a claim-fenced atomic swap. The nearest ownership\ncheck ran before _ensure_metadata, several lines before the upload, so\na claim reclaimed in that gap could let this worker clobber a peer's\nalready-uploaded, already-\n[…]\n proves\nthe fence gates the call, not just that it exists.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix(dispatch): re-check ownership immediately before result upload",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T14:38:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8bf207f49ff8974584807077ec782ed4361aa749",
          "body": "…work\n\nput_output(job_id, output/) now runs on the terminal SUCCESS path, after\nmetadata.json is written and before the terminal DONE CAS -- so the output\ndir still exists when the upload happens, well before the `finally` purge\ndeletes it.\n\nput_output failure is the mirror image of a get_sample fet\n[…]\n terminal CAS, so a failure just\nreturns without ever flipping the job out of RUNNING -- the reclaim sweeper\n(or a peer) picks it up for another attempt instead of the result being\nsilently discarded.",
          "is_bot": false,
          "headline": "feat(dispatch): upload results before purge; never discard completed …",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T14:26:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9ddcbb4cf825e688a68a248d2bc10822a79fb617",
          "body": "… verify\n\n- LocalBlobStore._atomic_copy: name the temp file per-call (uuid4 + thread\n  id), not just PID, so two threads racing put_sample for byte-identical\n  content in the same process can no longer share a temp path and\n  interleave/truncate each other's writes before os.replace.\n- LocalBlobStor\n[…]\nly worked because get_sample previously skipped\n  verification.\n- test_local_roundtrip.py: add a test that a corrupted stored blob raises\n  BlobIntegrityError on get_sample and leaves no file at dest.",
          "is_bot": false,
          "headline": "fix(blobs): unique temp names, scoped test blob_root, local integrity…",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T14:17:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "78fe7b5d93186d2049ae409ea8f175d9c8e5bd11",
          "body": "LocalBlobStore now stores bytes for real under a blob_root outside job_root\n(BLASTBOX_BLOB_LOCAL_ROOT, default sibling 'blobs' dir), so re-materialisation\nalways works and mode 1 / mode 3 share one code path. The two reclaim early-returns\nin vm_dispatch now purge unconditionally: a worker that loses\n[…]\nicit job_root= caller gets a correctly-rooted local store.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "feat(blobs): real local store; purge unconditionally on reclaim",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-22T14:03:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f35a09692bd7d829f1ffa8b464de1f549bdc327b",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "plan: add Task 9 (real LocalBlobStore + unconditional purge)",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-21T20:09:32Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4bf38933ee6bbea7130d4e7e14b129a5260a79bc",
          "body": "The no-op LocalBlobStore was incompatible with the worker purge invariant (a store\nwhose only copy IS the job dir has nothing left to serve once the job dir is\ndestroyed) and it made the abstraction dishonest -- its get_sample could only ever\nfail. That forced a mode-specific branch into the dispatc\n[…]\nde 1 and mode 3 share one code path with no\nbranch to rot.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "docs(design): LocalBlobStore is a real store; purge is unconditional",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-21T20:08:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f3a4d804a17f25f7d6637e3d307439093234d789",
          "body": "Review findings on Task 5's _purge_job_dir security invariant:\n\n- The net_policy-rejection terminal path used a bare input.unlink()\n  instead of _purge_job_dir(job), leaving the job dir (currently empty,\n  but not guaranteed to stay that way) behind on a terminal write.\n  Switched it to _purge_job_d\n[…]\n(containment refusal,\n  rmtree OSError) had zero test coverage. Added direct-call tests for\n  both, plus a residue test proving the net_policy-rejected path leaves\n  no sample bytes or job dir behind.",
          "is_bot": false,
          "headline": "fix(dispatch): purge job dir on net_policy rejection; add backstop tests",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-21T19:53:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3e7a9ac8df61694a6b5f32ca8a96a3472432ac81",
          "body": "…variant)\n\nWorkers are frequently spare hardware, not hardened sample repositories, so\nnothing may survive a terminal state on their local disk. Add\nVmJobDispatcher._purge_job_dir(job), a containment-guarded shutil.rmtree of\nthe job's whole dir (input AND output) mirroring JobRetentionSweeper's\ndefe\n[…]\nte time, before the purge)\ninstead of weakening the purge.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "feat(dispatch): purge the job dir on every terminal path (security in…",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-21T19:36:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "91ed753e257903ac2e68719f887ca642e6e7154e",
          "body": "missing blob reaches FAILED instead of looping forever\n\nBlobFetchError release-to-QUEUED (Task 4) never gave up: a permanently\nmissing sample (deleted/never-written blob, or LocalBlobStore's always-raise\nin single-node mode) looped release -> reclaim -> release every 30s with no\nterminal state. Add \n[…]\nTEMPTS bound in\nVmJobDispatcher: below the bound, release exactly as before but also persist\nthe incremented counter; at the bound, CAS the job to FAILED with a clear\nerror instead of releasing again.",
          "is_bot": false,
          "headline": "fix(dispatch): bound sample-materialise release retries so a permanently",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-21T19:15:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e6f049958b58e1267d4639da2209b8bbebdc4c3d",
          "body": "… failure\n\nVmJobDispatcher now accepts blob_store (defaults to build_blob_store_from_env(),\nmatching ingress/app.py) and blob_retry_backoff_s. When a claimed job's spooled\ninput is missing, it fetches via BlobStore.get_sample() instead of failing\noutright. A BlobFetchError releases the claim (RUNNIN\n[…]\n CAS'd on expect_claim_id) with claimable_after backoff instead of\nfailing the job -- an unreachable object store is this worker's connectivity\nproblem, not the sample's. created_at is left untouched.",
          "is_bot": false,
          "headline": "feat(dispatch): materialise samples on demand; release claim on fetch…",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-21T18:57:29Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "be68cd57f26b7b9177860d22bc98b59a55df9f04",
          "body": "- app.py: import BlobStore at module level (was referenced only in a\n  quoted annotation with no import, breaking both ruff F821 and mypy)\n- s3.py: widen S3BlobStore.__init__'s env param to Mapping[str, str] |\n  None (os.environ is a Mapping, not a dict) and silence the\n  missing-stubs error on the \n[…]\ntyped] pattern already used\n  for redis in jobs/factory.py\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix: restore ruff+mypy gates broken by distributed blob storage work",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-21T18:47:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0b638ce420de88b239d8ed0d71bcb19607324e79",
          "body": "A job row is claimable the instant it exists, so put_sample() must succeed\nbefore _job_store.create(job) -- otherwise a worker can claim a job whose\nsample it can't fetch and gets pushed down the release-and-retry path for\na sample that was never actually missing.\n\nbuild_app() now accepts an optiona\n[…]\n03 without reflecting internal exception text if it fails.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "feat(ingress): store the sample blob before creating the job row",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-21T18:40:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bbae553e761cd65423f9efff365e6998db73d1e6",
          "body": "The dedupe check in put_sample caught all exceptions with 'except Exception: pass',\nsilently masking throttling, permissions errors, or malformed calls. This permanently\nhides issues when HeadObject fails but PutObject succeeds — every put_sample re-uploads\ninstead of no-op'ing.\n\nNarrowed exception \n[…]\nssert put_sample re-raises instead of silently\nsucceeding.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix(blobs): narrow head_object exception handling in S3BlobStore",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-21T18:29:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "054323db4e770778e79e033bfb81c88a813281f4",
          "body": "S3BlobStore stores samples at samples/<sha256> (content-addressed, dedup'd\nvia head_object) and job results at results/<job_id>/<name> (gzip'd by\ndefault, transparent on read). get_sample rehashes fetched bytes and raises\nBlobIntegrityError on mismatch so a substituted object never reaches an\nengine\n[…]\nddfinalizer(ctx.stop) to close it at the end of each test.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "feat(blobs): add S3BlobStore behind the blastbox[s3] extra",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-21T18:21:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ec83d55e3b963a37f1a6ba3d71e3990ae197e324",
          "body": null,
          "is_bot": false,
          "headline": "feat(blobs): add BlobStore protocol, LocalBlobStore, and env factory",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-21T17:58:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8df4b438202c4b85ab53c9cfa27e7ae0d9611e77",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "docs: add distributed blob storage design + implementation plan",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-21T17:54:37Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b5b120bf1180b9779a931db77f35cc2243070dd5",
          "body": "The pool was hardcoded min_size=1/max_size=8. Every job submit and status poll\nborrows a connection, so max_size is the real ingress concurrency ceiling --\nfar below postgres' own max_connections (100) and unrelated to CPU. Measured:\n~256 concurrent pollers livelocked while /healthz still answered i\n[…]\nng --\npool sizing must never be why a node fails to start.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VNs5Ay38aQdizqij3W37tD",
          "is_bot": false,
          "headline": "fix(jobs): make the postgres pool size configurable",
          "author_name": "Will Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-21T17:54:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "728986e4a32af3e9acfb6010fe0439e941ab3916",
          "body": "chore(release): bump version to 0.1.24",
          "is_bot": false,
          "headline": "Merge pull request #64 from wmetcalf/chore/release-0.1.24",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T15:32:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8811bc7dc95077b509328d54d2d8eb774d8dba50",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): bump version to 0.1.24",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T15:10:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d0c1a47d5aa4c178c05037342c35072b3a01a5ce",
          "body": "docs(node-sizer): address #62 review feedback",
          "is_bot": false,
          "headline": "Merge pull request #63 from wmetcalf/docs/node-autosizer-modes-fixups",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T15:01:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "88b4113b8bfdda5a909d0a1c964201e2ed707e1a",
          "body": "…usage\n\nSecond round of #63 review nits:\n- separate BLASTBOX_NODE_BALANCING onto its own optional line (the inline \"+\"\n  read as if RESOURCE_MANAGEMENT toggled balancing).\n- correct the demo instructions: node_sizer_exercise.py uses its own temp dirs\n  (never touches the share dir); node_sizer_xnode_demo.py takes the share dir as\n  its first positional arg (default /tmp/bb-xnode), not BLASTBOX_NODE_SHARE_DIR.",
          "is_bot": false,
          "headline": "docs(node-sizer): clarify balancing comment + correct demo share-dir …",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T14:59:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "322a23d95897810153e92be2aa671dd55530be85",
          "body": "…ples\n\nPR #62 bot review follow-ups:\n- Do not tell operators to drop the static ceiling: it is the fallback if the\n  sizer setup fails (_start_node_sizer -> None restores the configured pool).\n- Qualify the cold no-headroom behavior: the gate keeps ONE cold permit always\n  (liveness floor); only job\n[…]\ncleans up -> would pollute a live node view).\n- Use full var names (BLASTBOX_NODE_BALANCING, BLASTBOX_NODE_ENGINE_<NAME>_RAM_MIB)\n  and relative cross-links between DEPLOYMENT.md and CONFIGURATION.md.",
          "is_bot": false,
          "headline": "docs(node-sizer): address review feedback on the autosizer-modes exam…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T14:54:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "de1c057291d2b86d480c45abd55d933531b64ed5",
          "body": "docs(node-sizer): worked examples for the multi-worker/multi-tier modes",
          "is_bot": false,
          "headline": "Merge pull request #62 from wmetcalf/docs/node-autosizer-modes",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T14:46:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "90f3755ebcf177041a3bc4e68f7fff172d102763",
          "body": "Document the autosizer modes shipped with the node-pool-autosizer epic that had\nno usage examples: same engine on two tiers (shared budget + untargeted dedup),\nthe budgeted cold-only sidecar dispatcher (claimable_after deferral), and the\nall-local cascade budgeted as one pool. Adds DEPLOYMENT.md shape 4 (\"Auto-sizing\na multi-worker host\") with env examples, and widens the CONFIGURATION.md\nautosizer intro beyond \"firecracker/gvisor only\" to cover cold-only + cascade.",
          "is_bot": false,
          "headline": "docs(node-sizer): worked examples for the multi-worker/multi-tier modes",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T14:44:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "61154a30252e1cd243d990f2bb24b0b363ab451d",
          "body": "chore(release): bump version to 0.1.23",
          "is_bot": false,
          "headline": "Merge pull request #61 from wmetcalf/chore/release-0.1.23",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T14:41:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cd2194ca7cfe5b8247d3ea59ca71407b095bf62f",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): bump version to 0.1.23",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T14:39:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "40f49377653ed975744651cae151aaf987131573",
          "body": "feat(host): optional node pool autosizer (right-size warm pools from live demand under a node budget)",
          "is_bot": false,
          "headline": "Merge pull request #60 from wmetcalf/feat/node-pool-autosizer",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T14:27:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aeb1a022737577f82be4c77a97136b2e4c8fa273",
          "body": "A `cascade` runtime composes ordered member tiers into one warm pool; its\nceiling is the SUM of member capacities. `manages(\"cascade\")` is False, so an\nall-local cascade (fc/gvisor members) ran OUTSIDE the water-fill — its slots\nconsumed node RAM but weren't budgeted, oversubscribing the node agains\n[…]\n(above);\nOpus-max LOW documented (footprint note); qwen non-string-crash HIGH refuted\n(manages() guards non-strings) — all three locked with regression tests.\n1624 host tests green, mypy + ruff clean.",
          "is_bot": false,
          "headline": "feat(node-sizer): enroll an all-local cascade in node management",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T08:01:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "eb254f339a5d41a369bfbbb9d27d18f1f2ca7986",
          "body": "Untargeted jobs (target_tier IS NULL) are claimable by EVERY tier of an\nengine, so the pre-dedup per-tier backlog counted them once PER TIER and\ndoubled a multi-tier engine's demand. Split the backlog into targeted (tier-\nscoped, per same-(engine,tier) replica) and untargeted (engine-wide, per pool)\n[…]\ne; the node budget water-fill stays the hard bound.\n\n1616 host tests green (+ field-order + untargeted-dedup + count-untargeted_only\nregressions), mypy + ruff clean, untargeted_only count PG-verified.",
          "is_bot": false,
          "headline": "feat(node-sizer): dedup untargeted backlog across an engine's tier-pools",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T07:17:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a4fb149834dbbb02dad944ed365c622080d6cfd2",
          "body": "…rrent starters\n\ncodex P2: the instance RLock only serializes threads, not separate PROCESSES. During a rolling\ndeploy two dispatchers can both read the pre-upgrade column set and both run the claimable_after\nALTER; the loser raised duplicate-column and crashed __init__. Postgres now uses ADD COLUMN\n[…]\nher driver swallows a concurrent duplicate rather than fail store\nconstruction (best-effort index migration). Verified: 6 concurrent starters against a\npre-upgrade table on real Postgres -> no errors.",
          "is_bot": false,
          "headline": "fix(jobs): make the claimable_after migration idempotent across concu…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T06:46:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cdd3368cfc4022d0cd2647ece82c1db63f8ccfcb",
          "body": "…nting for the cold tier)\n\nFollow-on from the codex review (JaW5/J90I): in the warm-sidecar deployment a SEPARATE cold\ndispatcher (tier=\"cold\") runs docker cold workers with no warm pool, so it was neither\nadmitted against nor published into the node budget — warm fc/gvisor peers could allocate the\n\n[…]\nTests: cold-only dispatcher gets a budgeted gate + publishes a cold-tier reservation;\ncold-only gate floored to 1 on fail-closed; _node_manages_tier(\"cold\") true. 2008 green;\nexercisers 12/12 + 14/14.",
          "is_bot": false,
          "headline": "feat(node-sizer): budget a pool-less cold-only dispatcher (node accou…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T06:40:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3dd769ac05b7f0b6dd6e26b0b1ffa25989990eff",
          "body": "…nt, shutdown-fence cold admission\n\nFourteenth codex batch (4 P1/P2 fixed; the cold-only-dispatcher P1 is being BUILT as a\nfollow-on feature, not deferred).\n\nP1 — split cap must not clip the incumbent's reservation (dispatcher_sizer). When a replica\njoins, splitting max_ceiling could drop it BELOW t\n[…]\nency (ceiling>=8 not clipped to 4); local warm floor\nsplits (2/2=1); cold dispatch fenced (requeued, no permit) once shutting down. count() verified\nlock-free on real Postgres (23 passed). 2006 green.",
          "is_bot": false,
          "headline": "fix(node-sizer): cap>=reserved, split local warm floor, lock-free cou…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T06:25:17Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b285f1ce9422cfae15f058daff162943fa615e58",
          "body": "…replaces created_at bump)\n\nFollow-on from the codex review (JvXY): the capacity-requeue of a cold job with no\nnode-budget headroom used to bump created_at so the job sorted behind claimable work. But\ncreated_at is the submission time driving public ordering AND max_queued_age expiry, so the\nbump br\n[…]\nble_after eligibility / doesn't-block-claimable-work / round-trip across all 3\nstores; public-dict strip; dispatch defer preserves created_at + sets claimable_after. 2003\ngreen, pg-search suite green.",
          "is_bot": false,
          "headline": "feat(jobs): claimable_after eligibility field for capacity deferral (…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T06:18:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1b9b5487ed32983bfd7dcaf751532df0ee578bc2",
          "body": "… ceiling, split floor/cap across replicas\n\nThirteenth codex batch (1 P1 + 3 P2 fixed; 2 deferred with rationale on-thread).\n\nP1 — consume a completed backlog sample before replacing it (dispatcher_sizer). The\none-outstanding-count guard discarded a count that finished AFTER its deadline but before\n\n[…]\n all-local + derive the aggregate footprint).\n\nTests: split cap capped at 4 not 8; late-finishing count consumed; summed ceiling clamped\n+ own snapshot validates. 1993 green; exercisers 12/12 + 14/14.",
          "is_bot": false,
          "headline": "fix(node-sizer): consume late count, don't zero on count error, clamp…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T05:55:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "10a6641dc10c00bdf51d9e4501dfffc543ed4cd7",
          "body": "…counts, defer capacity-requeued cold jobs\n\nTwelfth codex batch (2 P1, 1 P2) — edge cases of the prior fixes.\n\nP1 — do not finalize without the publish lock (dispatcher_sizer._locked_final). It still\nran fn() on a timed-acquire timeout, so shutdown could remove the snapshot / write the\norphan lease \n[…]\nd's result is picked up when it finishes.\n\nTests: final cleanup skipped when a publish holds the lock; count not respawned while a\nprior thread is alive; capacity requeue bumps created_at. 1990 green.",
          "is_bot": false,
          "headline": "fix(node-sizer): skip final cleanup on lock timeout, cap outstanding …",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T05:29:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "402da5d5a39da25a86235f439b76c941e361a5b7",
          "body": "…split static weight\n\nEleventh codex batch — three of the four trace the replica-dedup work.\n\nP1 — distribute the backlog remainder across replicas (dispatcher_sizer). Flooring the\ndivisor gave every replica warm target 0 when backlog < replica count, stranding the job\nin warm-only mode. Shares now \n[…]\ng\npool-less sizing; answered on the thread as a tracked follow-on with the current manual\nmitigation.)\n\nTest: backlog=1 across 2 replicas → the low-ranked one gets the slot, not 0-for-all.\n1988 green.",
          "is_bot": false,
          "headline": "fix(node-sizer): distribute backlog remainder, bound the count wait, …",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T05:04:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2ffc781f2b57892099bc8a4a8f2c07c8980fedc3",
          "body": "…replicas\n\nTenth codex batch (3 P2, shared-capacity accounting).\n\nP2 — sum multi-engine pool ceilings bounded by concurrency (cli). max(caps) undercounted\nSIMULTANEOUS multi-engine work (two engines capped 8, concurrency 16 → only 8). Now\nsum(caps) bounded by concurrency; the node budget still bound\n[…]\nross-node non-dedup is a deliberate failover choice; the same-tier-replica overcount it\nsupersedes is already fixed.)\n\nTests updated: combined ceiling = sum(8,8) bounded by concurrency 16. 1987 green.",
          "is_bot": false,
          "headline": "fix(node-sizer): sum multi-engine ceilings; split warm target across …",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T04:43:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1ad0a58cd2577d6094d73590292b449745e059d6",
          "body": "…ts, byte-parse mem, cap+serialize leases\n\nNinth codex batch (2 P1, 3 P2).\n\nP1 — keep heartbeats alive during an unexpectedly slow count (dispatcher_sizer). A count\nslower than the staleness window let peers expire the dispatcher mid-count and reallocate\nits live pool. The count now runs in a thread\n[…]\n the retained reservation.\n\nTests: bare-bytes parse; retained permit reclaimed on confirmed-gone / kept while\nunreadable; orphan lease max_ceiling == reservation. 1987 green; exercisers 12/12 + 14/14.",
          "is_bot": false,
          "headline": "fix(node-sizer): heartbeat during slow counts, reclaim retained permi…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T04:38:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fe31b1c04c224479f85ac64c893246e60c23bd7d",
          "body": "…n a daemon thread\n\nThe backgrounded CREATE INDEX CONCURRENTLY (prior batch, for the startup-latency P2)\nregressed the pg-search CI with a DeadlockDetected: a per-store daemon thread building\nthe jobs index takes system-catalog locks and races other concurrent index DDL (the\npage-hash index, or anot\n[…]\nnly (no lock\nheld) — pre-create the index in ops if that matters.\n\nVerified against the CI pg_bktree Postgres image locally: pg-search suite 48 passed, 3x,\nno deadlock (was DeadlockDetected at setup).",
          "is_bot": false,
          "headline": "fix(sql_store): run jobs-index build synchronously (lock-free), not i…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T04:29:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1b85a1fada1118eb07ca3d6968edfa7af7e2dd98",
          "body": "…orphan safety, replica backlog dedup\n\nEighth codex batch (5 P1, 3 P2) — security + race implications of the prior fixes.\n\nP1 — restrict the auto-created share dir (node_share). The world-writable 0o1777 I added\nfor cross-UID publish let ANY local UID publish a poisoned (unauthenticated) snapshot\n(t\n[…]\ne-not-world dir; fail-close on read failure; stop() orphan count;\ncold permit retained on failed kill / released on confirmed kill; replica backlog split.\n1985 green; exercisers 12/12 + xnode + 14/14.",
          "is_bot": false,
          "headline": "fix(node-sizer): tighten trust, read-failure fail-close, cold-permit/…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T04:21:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "840cbcf2d83df4a859b1ddf7171a3a023b476110",
          "body": "…rphan+stale pricing, background index build\n\nSeventh codex batch (2 P1, 3 P2), several tracing the implications of prior fixes.\n\nP1 — fail-closed floor bounded by budget (dispatcher_sizer._size_to_floor). The\nmixed-node-id fallback resized each pool to its full min_warm; two pools @ min_warm=8\non a\n[…]\nn thread.\n\nTests: fail-closed floors to 1 even at min_warm=8; a slow count does not fail-close;\norphan lease prices cold; stale_after clamps to 300 and validates. 1981 green;\nexercisers 12/12 + 14/14.",
          "is_bot": false,
          "headline": "fix(node-sizer): fail-closed floor bound, slow-count publish timer, o…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T03:46:17Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d6e7b99fe2697889c20f6b4ec96b7b06e87b5854",
          "body": "…-long snapshot keys\n\nSixth codex batch on the conservation work (1 P1, 1 P2).\n\nP1 — publish cold work in WARM-SLOT EQUIVALENTS (dispatcher_sizer). The cold GATE\nalready prices permits by the cold worker footprint, but the published RESERVATION\nstill counted each cold worker as one warm slot. The pl\n[…]\ncommon short case.\n\nTests: reservation prices 2 double-footprint cold workers as 4 units; a 250-char node id\npublishes + round-trips through a bounded hashed key. 1978 green; exercisers 12/12 + 14/14.",
          "is_bot": false,
          "headline": "fix(node-sizer): price cold reservation in warm-slot units; hash over…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T02:28:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "241c5842a0d66a92ef1f8b5927bee81a4bbfc696",
          "body": "…, schema-scoped index repair\n\nFifth codex batch on the conservation work (2 P1, 2 P2).\n\nP1 — reserved is a HARD ceiling floor (node_sizer.plan_sizes). The prior fix fed the\nreservation into water-fill DEMAND only; plan_sizes still starts every pool at 1 and\ncould allocate a pool FEWER slots than it\n[…]\nreserved floor preserved under a greedy peer; orphan lease outlives 20s and ages\nout by the GC floor; interval clamps to <=150; index-repair drop+rebuild. 1976 green;\nexercisers 12/12 + xnode + 14/14.",
          "is_bot": false,
          "headline": "fix(node-sizer): reserved ceiling floor, orphan lease, interval<=GC/2…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-20T01:51:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1a60fffed25dc9bc51232411e7264c50dc41ca0c",
          "body": "…isher-declared window)\n\nAudit P1 (proactive): the effective staleness window was computed per-READER from\nlocal cadence/config (max(own stale_after, (interval+tick)*2)), so two co-located\ndispatchers could disagree about a slow-but-live peer — fast readers age it out and\nreallocate its share while \n[…]\nstays visible to a reader whose own window is\n20 and ages out at 50 for readers with window 20 AND 90 — i.e. the publisher window\ngoverns, not the reader. 1974 green; exercisers 12/12 + xnode + 14/14.",
          "is_bot": false,
          "headline": "fix(node-sizer): reconcile the staleness horizon across readers (publ…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T22:56:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c1688befff78f35e48ff5838af7e5a90ddb00263",
          "body": "…losed publish/orphans, reservation sum/re-sample\n\nBoth the 3 latest codex P1s AND a proactive multi-agent budget-conservation audit\n(which found MORE, including a bug in a prior fix). The invariant: every RAM-consuming\nentity must have a live reservation that exists before it starts and persists un\n[…]\ned).\n\nTests: pool.stop orphan count; cold priced by footprint; fail-closed on publish loss;\nreservation sums warm+cold; phantom snapshot cleaned on aborted setup. 1973 green;\nexercisers 12/12 + 14/14.",
          "is_bot": false,
          "headline": "fix(node-sizer): budget-conservation hardening — cold pricing, fail-c…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T22:50:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "04a07ffd9f6b3d1ae1900e05a1fd3133e1fc1311",
          "body": "codex P2: batch 2 fixed NodeConfig.active and from_env to fold adaptive into\nresource_management, but the sizer's OWN gate _active() still checked only\nresource_management/balancing. A directly-constructed NodeConfig(adaptive=True,\nresource_management=False) therefore reported active=True yet tick()\n[…]\nr ran for callers using the construction API instead of\nfrom_env. _active() now includes cfg.adaptive, mirroring the property. Test: an\nadaptive-only direct config sizes the pool instead of no-opping.",
          "is_bot": false,
          "headline": "fix(node-sizer): _active() honors an adaptive-only direct config",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T22:26:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f46e29a26ff929239e087ac9d434561067627c58",
          "body": "… ceiling; reservation holds resident slots\n\nFifth codex batch (1 P1, 2 P2) — refining the batch-3 consensus work.\n\nP1 — reserve resident slots in the PUBLISHED allocation (dispatcher_sizer.py).\nBatch 4 based the COLD GATE on max(warm target, resident), but the published demand\nstill dropped the ins\n[…]\natters.\n\nTests: poisoned budget field dropped by read_all; combined ceiling = max(1,32)=32 not\n1; reservation reflects 8 resident slots at zero demand. Full suite 1967 green;\nexercisers 12/12 + 14/14.",
          "is_bot": false,
          "headline": "fix(node-sizer): validate consensus fields; largest-not-smallest pool…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T19:25:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b90b1682a83e1954dd35279b3bf7e4db228da021",
          "body": "…rves resident slots; heal invalid PG index\n\nFourth codex batch (2 P1, 1 P2) — refining the batch-2 cold-path work.\n\nP1 — exclude cold-only demand from the warm target (dispatcher_sizer.py). Batch 2\nadded cold in-flight into `assigned` to keep the ceiling RESERVATION up; but that\nvalue also fed the \n[…]\nid one before rebuilding.\n\nTests: cold gate reserves resident slots (8 resident + target 1 -> floor 1, not 7);\ninvalid-index probe drops-then-rebuilds. Full suite 1964 green; exercisers 12/12 + 14/14.",
          "is_bot": false,
          "headline": "fix(node-sizer): warm target excludes cold demand; cold headroom rese…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T18:45:59Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1a6fa967a6761f90d1c3e89db639575ab78da423",
          "body": "…cument node-wide participation\n\nThird codex batch (3 P1s) — all the config-divergence-across-co-located-dispatchers\nclass the mode consensus already addressed. Extended the same published-consensus\npattern to the remaining detectable dimensions and documented the one that can't be\ndetected.\n\nP1 — r\n[…]\n nets that DO catch the detectable divergences.\n\nTests: mixed node ids fail to the floor; budget reconciles to the min across the view.\nFull suite 1962 green; exercisers 12/12 + xnode + 14/14 locally.",
          "is_bot": false,
          "headline": "fix(node-sizer): reconcile budget + fail-closed on mixed node ids; do…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T18:38:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "21ca1546693d2415519a5e1745f10aeb38c4b568",
          "body": "… demand; adaptive/min-warm fixes\n\nSecond codex batch (from the gate-epic review — 2 P1, 2 P2). The gate as first\nwritten wrapped ALL dispatch and claimed a hard \"active ≤ ceiling ≤ budget\" cap.\nThat was wrong: warm slots stay RESIDENT even when idle, and cold workers spawn\nOUTSIDE the warm pool, so\n[…]\n gate == cold headroom and floors at 1 when warm saturates (sizer); plus\nthe dispatch harness updated to assert warm + cold headroom ≤ ceiling (+1 floor).\nFull suite 1960 green; harness 14/14 locally.",
          "is_bot": false,
          "headline": "fix(node-sizer): gate cold-only against budget headroom; persist cold…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T18:29:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1cc858cf7dc2957f2be1d2f8f75b778f6d0792d0",
          "body": "…onal resize, interval cap, dedicated DDL conn, cross-uid share dir\n\nFive findings from the post-push codex review (1 P1, 4 P2), each with a\ndiscriminating regression test:\n\nP1 — mixed allocation modes oversubscribe the node (dispatcher_sizer.py).\n  Each dispatcher applied its OWN balancing mode to \n[…]\nitself and took the whole budget. When WE\n  auto-create the dir, make it sticky world-writable (0o1777, /tmp semantics) so\n  any peer UID can publish; a pre-provisioned dir's perms are left untouched.",
          "is_bot": false,
          "headline": "fix(node-sizer): address codex review batch — mode consensus, provisi…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T18:13:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c45d7aefaa53dea0aafa44cc209f527489f3285f",
          "body": "…ler-owned removal\n\nCheck 9 still asserted run() auto-removes the snapshot on exit — the OLD\ncontract. Removal is caller-owned now (run() holds the reservation so peers see\nthe pool drain before it vanishes; the caller removes it after reaping the pool,\nas cli.py and the dispatch harness do). Split into two checks: run() KEEPS the\nsnapshot, then remove_own_snapshot() clears it. Caught by running the exerciser\non a fresh node (toolz3).",
          "is_bot": false,
          "headline": "fix(examples): node_sizer_exercise graceful-cleanup check matches cal…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T17:54:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "da23f7fd314a7a43d2654b75261484b3f0d2d3f9",
          "body": "…-path cap\n\nUpdate CONFIGURATION.md budget-bounding + the cli.py comment now that the\nsizer->gate control is implemented (no longer a follow-on), and extend the\ndispatch-startup harness to exercise it: the sizer drives the gate to the pool\nceiling and the gate admits exactly that many concurrent jobs, blocking the\nover-limit one. 13/13 checks.",
          "is_bot": false,
          "headline": "docs(node-sizer): document the concurrency gate as the automatic cold…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T17:48:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dc3e1f198d86eb1f887d1cb0a421f5c8bfc5d9db",
          "body": "…p over the cold path too\n\nThe autosizer bounded the WARM pool (warm slots + ceiling) to the node RAM budget,\nbut cold-fallback / egress-bypass jobs bypass the warm pool, so the budget was only\na soft cap: a burst of cold detonations could exceed Σ(footprint) and oversubscribe\nthe node's RAM. Cappin\n[…]\nhe\n    Dispatcher and the sizer.\n\nAll off unless resource_management/balancing is configured. Tests: gate bounds/\nshrink-without-interrupt/grow-wakes-waiter/timeout, plus sizer-drives-gate-to-ceiling.",
          "is_bot": false,
          "headline": "feat(node-sizer): dynamic concurrency gate — node budget is a hard ca…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T17:47:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a6c2e7e9e70fe1e62ad64f1e6286d8db6c952d1e",
          "body": "… CONCURRENTLY, more guards\n\nPR #60 codex batch — reworked the hard-cap after codex showed warm_only is wrong:\n\n- Do NOT force warm_only (P1): it breaks jobs that resolve to an egress network\n  personality (they deliberately bypass the warm pool) and doesn't bound cold RAM\n  anyway. Removed the forc\n[…]\nrrency, return-None-on-publish-fail, env-prefix\ncollision. Docs updated (concurrency-based bounding). Dispatch harness updated + re-run\n(11/11). ruff + mypy clean; full host suite green (1550 passed).",
          "is_bot": false,
          "headline": "fix(node-sizer): concurrency-bounded budget (not warm_only), PG index…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T17:14:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2f78391ebbcf6fd147c47f099203030e1b581d70",
          "body": "…dening\n\nnode_sizer_dispatch_harness.py drives the ACTUAL cli dispatch-startup wiring\n(_node_manages_tier gating, warm_only forcing, unspawned start, synchronous first\nsizing, restore-on-skip, reservation-until-reaped) against a REAL SQLite store\n(exercising idx_jobs_status_engine_tier + the count-c\n[…]\n with a WarmPool-shaped fake pool (no microVM runtime needed).\nExercised live on toolz3: 11/11 PASS. Also the earlier demo-assertion hardening\n(undersized baseline; direct cross-node isolation proof).",
          "is_bot": false,
          "headline": "examples(node-sizer): dispatch-startup integration harness + demo har…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T16:48:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "957afc981dea7362ae6f6bb141513cf86d85004a",
          "body": "…lection, hardening\n\nPR #60 codex batch on the hard-cap wiring:\n\n- P1 restore pool when sizing skipped: the unspawned-start (warm=0) left the pool\n  DEAD if _start_node_sizer returned None (incomplete inventory / unwritable share).\n  Capture the configured warm/ceiling before pre-shrinking and resto\n[…]\nnapshots are filtered out of the planning view (not just budget-bounded).\n\nRegression tests for restore/reservation/count-collection/bool/dedup. ruff + mypy\nclean; full host suite green (1547 passed).",
          "is_bot": false,
          "headline": "fix(node-sizer): restore-on-skip, reservation-until-reaped, count-col…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T16:43:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bb46983d726f0e9ded9a29a9c1e5958cf75aa80e",
          "body": "…ventory, SQL index\n\nAddresses the remaining PR #60 codex feedback, including the two architectural\nquestions (decided toward the enterprise hard-guarantee behavior):\n\nARCHITECTURE — the node budget is now a HARD cap when the autosizer manages a pool:\n- Cold fallback (SDoR7): resource management now\n[…]\n of\n  the slow-count concern).\n\nRegression tests for the tier gating, incomplete-inventory skip, synchronous first\ntick, heartbeat fence. Docs updated. ruff + mypy clean; full host suite green (1544).",
          "is_bot": false,
          "headline": "feat(node-sizer): hard-cap enforcement + fence heartbeat, complete in…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T15:49:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e0f1d1e8ff3c6d8619f60d26ba4dc1429ef42194",
          "body": "… refresh hint\n\nPR #60 codex feedback on the r12 design changes:\n\n- Resource-share now normalizes by the BINDING resource (max of RAM-frac and\n  vCPU-frac vs the budget), not RAM alone. So on a vCPU-bound node two equal-weight\n  pools with different slot_vcpus get an equal CPU share, not equal slots\n[…]\nlocated share. The\n  effective window is capped at the GC floor so a spoofed refresh_s can't keep a\n  phantom in view.\n\nRegression tests for all three; ruff + mypy clean; full host suite green (1541).",
          "is_bot": false,
          "headline": "fix(node-sizer): binding-resource share, weight clamp, slow-publisher…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T15:28:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7bb078abbef0fcce4645dff1909904f4a02512ee",
          "body": "…avior\n\nSelf-contained live exerciser (fake pools, no production container) that asserts\nall node-sizer behaviors against the real /proc/meminfo + cpu_count budget: real\nbudget, tier identity, no-oversubscription, min_warm reservation, resource-share\nweights, adaptive shedding under pressure, heartb\n[…]\nibility + stop-fence,\ncross-node isolation, and graceful cleanup. Exercised live on toolz2 + toolz3\n(128 GiB / 32-core / KVM): 11/11 PASS on both, plus a real cross-host file-crossing\nisolation check.",
          "is_bot": false,
          "headline": "examples(node-sizer): end-to-end exercise driving every autosizer beh…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T14:54:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a1a32b0476fa8ac3f2f7a8d55696a8a2dd3fb860",
          "body": "The two remaining PR #60 design questions, resolved toward the more robust option:\n\n- weight = RESOURCE share, not slot count (SC_TF). The water-fill score is now\n  demand/(slots·footprint), so demand/weight buys a share of the node RAM budget:\n  two equal-weight pools with different footprints get \n[…]\n-engine baseline keeps pools viable. Best-\n  effort host protection -- a HARD OOM guarantee is cgroup memory limits.\n\nRegression tests for both; ruff + mypy clean; full host suite green (1538 passed).",
          "is_bot": false,
          "headline": "feat(node-sizer): resource-share weights + lower adaptive floor",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T14:51:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f96c9eba000dc2d2125247485a851ea616d0d908",
          "body": "…n stop\n\nPR #60 codex batch (2 P1 + P2s), closed by restructuring tick()'s publish:\n\n- Slow-count aging (P1): tick() counted the backlog FIRST, then published, so a\n  dispatcher whose count exceeds the staleness window (a huge shared-store scan)\n  published nothing during it and peers aged out its s\n[…]\neights for the shared pool (was using only the first engine's weight).\n\nRegression test for the fence (stop + remove mid-count -> no republish). ruff +\nmypy clean; full host suite green (1536 passed).",
          "is_bot": false,
          "headline": "fix(node-sizer): heartbeat before slow count + fence update-publish o…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T06:16:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "20358aa6eb6374ae2552903b494e66163e0016f4",
          "body": "…ootprint\n\nPR #60 codex P1: a dispatcher serving several engines on ONE pool used whichever\nmatching EngineNode appeared first for the pool's per-slot footprint. If the first\ndeclared 512 MiB slots and a co-served engine declared 2048 MiB, the sizer\nunder-counted RAM/vCPU and could set a ceiling tha\n[…]\nhe MAX slot_ram_mib/slot_vcpus (a slot must fit the biggest served engine) and the\nMIN max_ceiling / max min_warm across the served engines. Regression test.\n\nruff + mypy clean; full host suite green.",
          "is_bot": false,
          "headline": "fix(cli): size a multi-engine pool with the conservative (max) slot f…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T04:02:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ff04f9154982af9aadf4a9e947c3fe3ce35d24c6",
          "body": "…node warning\n\nThree of the six open PR #60 design questions, resolved toward the cleaner behavior:\n\n- min_warm is now a RESERVED floor, not soft. plan_sizes seats each pool's min_warm\n  before demand-filling, so an idle latency-critical pool keeps its floor hot even\n  when a busy neighbour wants th\n[…]\nR threads (static-ceiling\nfallback, untargeted per-pool over-provision, weight=0 spare-capacity).\n\nRegression test for the min_warm reservation; ruff + mypy clean; full host suite green\n(1534 passed).",
          "is_bot": false,
          "headline": "feat(node-sizer): reserve min_warm floor, direct stop cleanup, mixed-…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T03:56:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7522e87915d15ccc84e74bb0a1c772da8fb74180",
          "body": "…rface\n\nPR #60 review: AGENTS.md requires new env vars documented near the feature, but\ndocs/CONFIGURATION.md had no BLASTBOX_NODE_* entries. Add a 'Node pool autosizer'\nsection covering the three opt-in switches, the engine inventory + per-engine\nfootprint/cap/weight knobs, headroom/oversubscription/adaptive, interval/staleness,\nthe share dir, and the node id (with the cross-host-sharing invariant).",
          "is_bot": false,
          "headline": "docs(config): document the BLASTBOX_NODE_* autosizer configuration su…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T02:12:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "580a4fa5e73b6f4910d39593efb1940d0e41811c",
          "body": "PR #60 codex-connector follow-ups:\n\n- P1: mkstemp created snapshots 0600 and os.replace preserved that mode, so peer\n  dispatchers running under a DIFFERENT uid (each engine container can) would get\n  PermissionError reading the node view, drop that pool, and oversubscribe. chmod\n  the file to 0644 \n[…]\ntract\n  the guard into _safe_path() and use it in BOTH publish and remove, so neither can\n  be steered outside the share dir by an unsafe identity component.\n\nruff + mypy clean; full host suite green.",
          "is_bot": false,
          "headline": "fix(node-share): world-readable snapshots + traversal guard on remove",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T02:10:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f45343a59a173c00b84bae45b00cd1755b10473b",
          "body": "Marla round-2 finding (glm-nim HIGH): _start_node_sizer started the sizer daemon\nthread and THEN printed a status line. If that print raised (broken pipe / closed\nstderr), the except returned None while the thread was already running -- a leaked\ndaemon the caller could never stop or join (and it nev\n[…]\nound-2 Claude lenses (fix-verification + holistic) both returned CLEAN on the\nround-1 fixes. Regression test: a failing status print leaves no thread running.\nruff + mypy clean; full host suite green.",
          "is_bot": false,
          "headline": "fix(cli): start sizer thread after the status print to avoid a leak",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T01:58:17Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9e431ea628ce54122d80e9861e00c6d3e4df117a",
          "body": "…ode-id guards\n\nMarla round-1 findings on the current branch (2 HIGH + 1 MEDIUM + 4 LOW):\n\n- HIGH (container pid collision): the instance token was os.getpid(), but each\n  dispatcher runs in its own container where pid is almost always 1 -- two\n  replicas would collide and each size to the full budg\n[…]\nor a single host, or each host a\ndistinct id; mixing a tagged and an untagged host on one shared dir conflates\nthem.\n\nRegression tests for each; ruff + mypy clean; full host suite green (1532 passed).",
          "is_bot": false,
          "headline": "fix(node-sizer): random instance token, reliable stop, mtime GC, ts/n…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-19T01:45:12Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0271d4a982ab340eeb2f7f954655b3ef2fe572b6",
          "body": "…t-tick staleness\n\nThree more PR #60 review findings (chatgpt-codex-connector):\n\n- P1 symlink-follow on publish: the old predictable <pool>.json.tmp could be\n  pre-created by a peer as a symlink so write_text() followed it and truncated a\n  file outside the share dir. publish() now writes via tempfi\n[…]\nsion tests for all three (planted-symlink not followed, traversal rejected,\nunsafe engine name rejected, slow-count keeps the peer). ruff + mypy clean; full\nhost suite green (1528 passed, 29 skipped).",
          "is_bot": false,
          "headline": "harden(node-sizer): symlink-safe writes, path-traversal guard, curren…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T21:00:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "66467fe4d764426516a5395e595fc2aab88dab07",
          "body": "Resolves the two open PR #60 review threads with the cleanest long-term design.\n\nRollout overlap (per-instance identity): a warm pool belongs to a PROCESS, so the\npublishing-unit identity is now (engine, tier, node, instance=pid). Two replicas\nof one engine/tier/node — a rolling deploy stopping the \n[…]\nt the budget (no 2x); graceful stop\nremoves own file; read_all GCs a long-abandoned file. Live demos updated for the\nnew filenames.\n\nruff + mypy clean; full host suite green (1524 passed, 29 skipped).",
          "is_bot": false,
          "headline": "feat(node-sizer): per-process instance identity + trust-model doc",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T20:53:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9863e304ba10d5c6e8cfee8a6916c256f6f39454",
          "body": "Standalone demos used to validate the autosizer on real hardware (toolz2/toolz3,\n128 GiB / 32-core / KVM):\n\n- node_sizer_live_demo.py: simulates the real production topology (redtusk +\n  titanarum, each on firecracker AND gvisor = 4 pools on one host) coordinating\n  via a shared node dir under the b\n[…]\nngines and\n  ignores the foreign node (no double-budgeting).\n\nValidated live: toolz2 + toolz3 both PASS; cross-node isolation PASS (toolz3\nignored 4 foreign toolz2 snapshots and sized only its own 4).",
          "is_bot": false,
          "headline": "examples(node-sizer): live real-hardware + cross-node isolation demos",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T20:28:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0e174f579f1c3e18d2c3b393ea5c8508c5f26e15",
          "body": "…finite intervals\n\nTwo more PR #60 review findings (chatgpt-codex-connector):\n\n- pool.py: the pre-spawn ceiling recheck could not catch a resize() that lowered\n  the ceiling WHILE runtime.spawn() was blocked (a slow AWS/microVM spawn) --\n  the check passed against the old ceiling and the completed s\n[…]\nd. from_env now rejects non-finite floats (and unparseable ints) and falls\n  back to the finite default.\n\nRegression tests for both; ruff + mypy clean; full host suite green\n(1521 passed, 29 skipped).",
          "is_bot": false,
          "headline": "fix(pool,node-config): reap over-ceiling slot at publish; reject non-…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T20:20:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9a33141db1259497875f2d2ae78b510dd68894c7",
          "body": "…ver-commit\n\nAddresses PR #60 review thread (pool.py spawn recheck). _spawn_to_deficit\ncomputed to_spawn once, then spawned the whole batch checking only the stop\nevent per slot. A concurrent resize() lowering this pool ceiling mid-batch (the\nnode autosizer downsizing) would let the loop over-commit\n[…]\nssion test simulates a resize() firing mid-batch via the runtime spawn hook\nand asserts the pool never exceeds the lowered ceiling.\n\nruff + mypy clean; full host suite green (1519 passed, 29 skipped).",
          "is_bot": false,
          "headline": "fix(pool): recheck ceiling per-spawn so a mid-batch downsize cannot o…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T19:10:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d16a532da653adac049d39b8a66de5e139652141",
          "body": "…span tiers\n\nWill confirmed the architecture should be forgiving/elastic: one host can run the\nSAME engine on TWO node-managed tiers (firecracker AND gvisor) as separate warm\npools. The snapshot identity was (engine, node) — both pools keyed as the same\n'clip', so they collided on <engine>.json AND \n[…]\n. New tests: two tiers on one node share the budget (Σ==8,\nno 2x); same engine across two physical nodes still sizes independently.\n\nruff + mypy clean; full host suite green (1518 passed, 29 skipped).",
          "is_bot": false,
          "headline": "fix(node-sizer): key pools by (engine, tier, node) so one engine can …",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T19:02:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ade0b0350cd40aefced6ae32dbeeaf47969f633e",
          "body": "…dently\n\nValidates the multi-node model (one engine on several physical nodes sharing a\nqueue for load-balancing/failover): the per-node sizer keys snapshots by\n(engine, node), so clip on toolz2 and clip on toolz3 publish\nclip@toolz2.json / clip@toolz3.json on a shared dir without colliding, each\nnode's view filters to its own node, and each sizes its own clip pool to its own\nbudget independently — no cross-node contamination.\n\nFull host suite green (1517 passed, 29 skipped).",
          "is_bot": false,
          "headline": "test(node-sizer): same engine across two physical nodes sizes indepen…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T17:25:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6950433e418ed7c8ec1bb32821ac88c318ca016e",
          "body": "… future-ts bound\n\nAddresses PR #60 review (chatgpt-codex-connector), three real correctness issues:\n\n- Backlog now scopes to the claimant's tier. local_backlog_fn / count() gained a\n  claimant_tier filter mirroring claim_next's target_tier routing (untargeted OR\n  matching tier). Without it a firec\n[…]\ntherwise read as fresh\n  forever and kept a stopped engine consuming node budget. Modest skew tolerated.\n\nRegression tests for each; ruff + mypy clean; full host suite green\n(1516 passed, 29 skipped).",
          "is_bot": false,
          "headline": "fix(node-sizer): tier-scoped backlog, node-namespaced snapshot files,…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T16:12:08Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ada9d5ba91564e6d090f40aa36a9cf4eb85e3676",
          "body": "…nfo parse\n\nAddresses PR #60 review (gemini-code-assist):\n\n- read_all now filters unknown keys before constructing DemandSnapshot. During\n  a rolling upgrade a newer peer may add a snapshot field; an older reader\n  passing it to the constructor raised TypeError → the file was skipped → that\n  peer s\n[…]\n/mocked file (missing column,\n  non-numeric) degrades to a 0 budget / None instead of crashing the tick.\n\nRegression tests for both; ruff + mypy clean; full host suite green\n(1511 passed, 29 skipped).",
          "is_bot": false,
          "headline": "fix(node-sizer): tolerate unknown snapshot fields + harden /proc/memi…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T16:01:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "68904418374bd30a9b6502465ffda5354437b736",
          "body": "Round-9 adversarial-review hardening (allocation-math lens, defense-in-depth):\nplan_sizes computed warm = min(ceiling, max(min_warm, ceil(demand))); with an\nout-of-contract negative min_warm/demand this could emit a negative warm target,\nwhich WarmPool.resize(warm_size<0) rejects with ValueError. Un\n[…]\n1-ULP multiplicative-recompute overshoot was rejected as physically\nmeaningless (the incremental accumulator never oversubscribes).\n\nruff + mypy clean; full host suite green (1509 passed, 29 skipped).",
          "is_bot": false,
          "headline": "harden(node-sizer): clamp warm target at 0 for out-of-contract input",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T15:41:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9cfbc650730b53dde726b46b3cc62f18eec58fd7",
          "body": "Round-8 adversarial-review fix (whole-feature holistic lens, command-backed):\nfrom_env is the WRITER of a dispatcher's own demand snapshot, but it left\nmin_warm and weight unbounded above, while the READER (node_share._valid) caps\nthem at _MAX_CEILING_SANE (4096) and _MAX_WEIGHT (1<<20). A plausible\n[…]\no writer and reader can't drift. Regression test asserts from_env's output\nalways round-trips through _valid even at absurd config.\n\nruff + mypy clean; full host suite green (1508 passed, 29 skipped).",
          "is_bot": false,
          "headline": "fix(node-config): clamp min_warm/weight to the reader's _valid caps",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T15:31:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fadc81ea56c401833824e807ed58c38f62c582f0",
          "body": "Round-7 adversarial-review fix (holistic lens): _reap_surplus() ran\nunconditionally in WarmPool.tick(), so it changed burst-drain behavior for\nEVERY pool — including ones that never enable the node autosizer. Concretely:\nafter a burst deactivated (effective target drops back to warm_size), the idle\n\n[…]\ns\nexact prior lazy burst-drain; an autosized pool still converges downsizes\npromptly per-tick. Regression test pins both behaviors.\n\nruff + mypy clean; full host suite green (1507 passed, 29 skipped).",
          "is_bot": false,
          "headline": "fix(pool): gate eager surplus reaping on autosizer opt-in",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T15:24:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "51be3d77d9fc337b188822f03bce382f4a0e10e4",
          "body": "Accidentally committed in an earlier review-fix commit; it's a transient\noutput of the local adversarial-review harness, not part of the feature.",
          "is_bot": false,
          "headline": "chore: untrack .marla-mechanical.json review scratch artifact",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T15:13:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f22bdaf68811387177d2a32bdaafabab789e7382",
          "body": "…aptive at physical RAM\n\nRound-6 adversarial-review fixes to the dispatcher self-sizer:\n\n- Symmetric node filter: a partial config (some engines set BLASTBOX_NODE_ID,\n  some not, on one host) now still coordinates. The old asymmetric\n  `s.node in (\"\", self._node)` hid a tagged peer from an untagged \n[…]\nOOM. Scale now caps\n  at min(1.25, 1/headroom); also re-clamped each tick in case headroom changed.\n\nRegression tests for all three; ruff + mypy clean; full host suite green\n(1506 passed, 29 skipped).",
          "is_bot": false,
          "headline": "fix(node-sizer): symmetric node filter, warm from real demand, cap ad…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T15:12:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a554419e7dc63cc4301a6df6f7aa95a012020e24",
          "body": "…eness vs tick time\n\nFifth pass. cli/config lens clean; the remaining findings (correctness + holistic +\ncodex) were three real issues, one a regression this branch's own round-3 fix introduced:\n\n- HIGH (regression): node identity defaulted to socket.gethostname(), but inside a\n  container that's th\n[…]\ngistered-snapshots-reserve-budget (by design — share_dir\ndefines the node's engine set), reap-race re-raise (fixed run-2, audited clean). +3\nregression tests. mypy + ruff clean; full host suite green.",
          "is_bot": false,
          "headline": "fix(host): round-5 review — node-id regression, snapshot bounds, stal…",
          "author_name": "William Metcalf",
          "author_login": "wmetcalf",
          "committed_at": "2026-07-18T14:56:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 27,
      "commits_last_year": 383,
      "latest_release_at": "2026-07-24T01:22:12Z",
      "latest_release_tag": "v0.1.26",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 8,
      "days_since_latest_release": 0,
      "mean_days_between_releases": 2.8
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 42,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "blastbox",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "sandbox",
            "malware",
            "detonation",
            "untrusted",
            "document",
            "isolation",
            "Development Status :: 4 - Beta",
            "Intended Audience :: Developers",
            "License :: OSI Approved :: MIT License",
            "Operating System :: POSIX :: Linux",
            "Programming Language :: Python :: 3",
            "Programming Language :: Python :: 3.12",
            "Topic :: Security",
            "Topic :: Software Development :: Libraries :: Application Frameworks"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/blastbox/",
          "is_deprecated": false,
          "latest_version": "0.1.26",
          "repository_url": "https://github.com/wmetcalf/blastbox",
          "versions_count": 27,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": 1346,
          "first_published_at": "2026-06-01T22:15:58.646196Z",
          "latest_published_at": "2026-07-24T01:22:55.569868Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 0
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 1
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "src/blastbox/py.typed"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 138065,
      "source_files_sampled": 249,
      "oversized_source_files": 6,
      "agent_instruction_files": [
        "AGENTS.md"
      ],
      "agent_instruction_max_bytes": 2942
    },
    "dependencies": {
      "manifests": [
        "pyproject.toml"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "pypi"
      ],
      "dependencies": [
        {
          "name": "pydantic",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.6.0"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 1,
        "merged_prs": 59,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 6
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "wmetcalf",
          "commits": 384,
          "avatar_url": "https://avatars.githubusercontent.com/u/409768?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "publish.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": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 5,
            "reason": "1 out of 2 merged PRs checked by a CI test -- score normalized to 5",
            "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/3 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "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": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow 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": null,
            "reason": "no releases found",
            "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": "047a4148a766e73cc85311db2d9c4b196a3bbf47",
        "ran_at": "2026-07-24T01:26:05Z",
        "aggregate_score": 3.5,
        "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-07-24T01:23:01Z",
      "oldest_open_prs": [
        {
          "number": 59,
          "created_at": "2026-07-13T20:58:43Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-24T01:21:55Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/wmetcalf/blastbox",
    "host": "github.com",
    "name": "blastbox",
    "owner": "wmetcalf"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 54,
      "inputs": {
        "security": 35,
        "vitality": 76,
        "community": 31,
        "governance": 55,
        "engineering": 65
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 76,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 60,
            "inputs": {
              "commits_last_year": 383,
              "human_commit_share": 1,
              "days_since_last_push": 0,
              "active_weeks_last_year": 8
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "8/52 weeks with commits",
                "points": 5.5,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 8
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "383 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 383
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 27,
              "latest_release_tag": "v0.1.26",
              "releases_from_tags": false,
              "days_since_latest_release": 0,
              "mean_days_between_releases": 2.8
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "27 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 27
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~2.8 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 2.8
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 31,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "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 (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "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
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 52,
            "inputs": {
              "packages": [
                "blastbox"
              ],
              "dependents": null,
              "ecosystems": "pypi",
              "total_downloads": null,
              "monthly_downloads": 1346
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "1,346 downloads/month across pypi",
                "points": 41.7,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 1346,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 55,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "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": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "moderate",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 65,
            "inputs": {
              "merged_prs": 59,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 6
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "59/65 decided PRs merged",
                "points": 34.7,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 59,
                      "decided": 65
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/3 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 62,
            "inputs": {
              "followers": 102,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "wmetcalf",
              "public_repos": 73,
              "account_age_days": 5784
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "102 followers of wmetcalf",
                "points": 14.5,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 102,
                      "login": "wmetcalf"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "73 public repos, account ~15 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 73
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 15
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "blastbox"
              ],
              "ecosystems": "pypi",
              "any_deprecated": false,
              "min_days_since_publish": 0
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on pypi",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 0 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "27 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 27
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 65,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 58,
            "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": "1 out of 2 merged PRs checked by a CI test -- score normalized to 5",
                "points": 10,
                "status": "partial",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "good",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "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": 10,
                "status": "met",
                "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": "at_risk",
        "name": "Security",
        "value": 35,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 35,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 3.5
            },
            "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 not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "1 out of 2 merged PRs checked by a CI test -- score normalized to 5",
                "points": 1.2,
                "status": "partial",
                "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/3 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "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": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "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": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "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
              }
            ]
          }
        ],
        "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": 65,
        "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": 1,
              "agent_instruction_files": [
                "AGENTS.md"
              ],
              "agent_instruction_max_bytes": 2942
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "AGENTS.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "AGENTS.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": "100 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 100,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 53,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": true,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "src/blastbox/py.typed"
              ],
              "agent_commit_share": 0.24,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "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": "src/blastbox/py.typed",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "src/blastbox/py.typed"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "24 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 24,
                      "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": 81,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 138065,
              "source_files_sampled": 249,
              "oversized_source_files": 6
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python with type-check config (src/blastbox/py.typed)",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "typecheck_config_language",
                    "params": {
                      "files": "src/blastbox/py.typed",
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "6/249 source files over 60KB",
                "points": 53.7,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 249,
                      "oversized": 6
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "has_mcp_signal": false,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "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": [
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
    "deps.dev does not index pypi:blastbox@0.1.26; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-24T01:26:20.984508Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/w/wmetcalf/blastbox.svg",
  "full_name": "wmetcalf/blastbox",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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 statisticsPyPI.