Skip to content

feat(artifact-delivery): reuse a ready build of the same commit - #348

Merged
harlan-zw merged 1 commit into
mainfrom
feat/reuse-ready-artifact-build
Oct 1, 2026
Merged

harlan-zw merged 1 commit into
mainfrom
feat/reuse-ready-artifact-build

Conversation

@harlan-zw

Copy link
Copy Markdown
Collaborator

❓ Type of change

  • 📖 Documentation
  • 🐞 Bug fix
  • 👌 Enhancement
  • ✨ New feature
  • 🧹 Chore
  • ⚠️ Breaking change

📚 Description

Over 14 days, 264 public Artifact builds covered only 89 distinct (Repository, commit, Skill path) builds, and each one made about 9 GitHub reads. On 2026-09-30 those reads hung, and builds failed for commits we had already built and signed. This is PR 2 of the GitHub mitigation plan.

A build now reuses a ready public build of the same source instead of loading it again:

  • Pinned to a commit that was built before: no GitHub read at all.
  • Unpinned: GitHub still resolves the branch or tag, and only the load is skipped. If GitHub is down, the build fails as it does today. It never falls back to an older commit; the owner said not yet.

The reuse key is the whole resolved source (Repository ID, owner, name, commit, tree, Skill path), a ready Resolution, and an available Artifact. The earlier attestation must still verify under the current trusted root, with the current policy version and check versions, and R2 must still hold the bytes. No earlier signature is copied. The build stages a new statement with this Resolution's time, and the signer signs it on the same path as a fresh build, after it hashes the R2 object again. The CLI sees the same response shape and the same Skilld-Page-Url header. Private delivery stays out; it is off, and its access rules need their own review.

Architecture: the build asks findReusableBuild before GitHub, which reads D1 through index 0131 and checks R2; the signer path is unchanged

Data flow: a Resolution pinned to a built commit reaches ready with no GitHub call

Each decision emits artifact-build-reuse with outcome hit or miss, a reason on a miss, and the new artifact.resolutionId, artifact.reuseLookup and artifact.reusedFrom fields, so the check-in can count hits.

Loose ends I would like a view on:

  • The deploy smoke asks for find-skill on the default branch. Unless that branch moved, it now takes the reuse path, so a green smoke no longer proves the GitHub load and packaging path. I left scripts/smoke-artifact-resolution.mjs alone because fix(artifact): retry GitHub reads once and time out page fetches #345 edits it. Pin a commit nobody has built? Or a scheduled fresh build?
  • A pinned hit trusts the owner and name to Repository mapping from the earlier build. If the Repository was renamed, deleted or made private since, a fresh build would fail or name another Repository, while a reused one still names the old identity. The bytes are the same commit either way.
  • Two builds of one commit in flight at the same time still both load (queue concurrency is 2). A later message in the same batch does reuse. Both land on the same R2 object and artifacts row.
  • ARTIFACT_POLICY_VERSION is now also the switch that forces fresh builds: bump it when loading or packaging changes what one commit produces. I skipped a separate build version column so that the decision reads only signed fields.
  • The migration is 0131: 0129 is claimed by feat(indexnow): re-enable submission for the curated set #320 and 0130 is on main. The lookup still works without the index, only slower.
  • nuxt.config.ts will need a small rebase against fix(artifact): retry GitHub reads once and time out page fetches #345 and fix(registry): serve skills-raw and skill-files from D1 #347.

🤖 AI disclosure: Harlan Agent Kit modified this description. My AI open-source policy.

Over 14 days, 264 public builds covered only 89 distinct builds, and each
build makes about 9 GitHub reads. On 2026-09-30 those reads hung and
builds failed for commits that were already built and signed.

A public build now reuses a ready build of the same source when its
attestation still verifies under the current trusted root, its policy
and check versions are current, and R2 still holds the bytes. A request
pinned to a built commit makes no GitHub read. An unpinned request still
resolves on GitHub, so it never gets an older commit. The signer signs a
fresh statement through the normal path.
@harlan-github-agent harlan-github-agent Bot added harlan-agent-running An Agent holds a Task on this issue or pull request right now. harlan-agent-review-required Pull request triage requires an adversarial Review for this head commit. labels Sep 30, 2026
@harlan-github-agent

harlan-github-agent Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

🤖 MERGED

Harlan Agent Kit posted this automated review. It is not Harlan's personal review or approval. AI open source policy. Last updated: 2026-10-01 02:18 UTC.

GitHub merged this pull request.

  • Logged (20/100): The two architecture diagrams the description cites as evidence of the design are gone from GitHub's media host, so reviewers cannot verify the depicted build/data flow against the implementation. View code
    • Ask an agent to verify and fix this finding
  • Logged (35/100): A pinned reuse can attest content under a repository identity that GitHub no longer maps to those bytes. View code
    • Ask an agent to verify and fix this finding
  • Logged (30/100): The deploy smoke stops proving the load and packaging path once reuse covers its default-branch request. View code
    • Ask an agent to verify and fix this finding

d02033e9-543f-4b5d-8dd9-8811be9e712b

Selected findings run after merge and open separate pull requests.

@harlan-zw harlan-zw added the harlan-agent-review Pull request triage requires an adversarial Review. Adding this label manually always forces one. label Sep 30, 2026
@harlan-github-agent harlan-github-agent Bot added harlan-agent-ready The automated Review passed every gate on this head commit. and removed harlan-agent-review Pull request triage requires an adversarial Review. Adding this label manually always forces one. harlan-agent-running An Agent holds a Task on this issue or pull request right now. harlan-agent-review-required Pull request triage requires an adversarial Review for this head commit. labels Sep 30, 2026
@harlan-zw
harlan-zw merged commit dc84444 into main Oct 1, 2026
6 checks passed
@harlan-github-agent harlan-github-agent Bot removed the harlan-agent-ready The automated Review passed every gate on this head commit. label Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant