Skip to content

feat(registry): write SKILL.md bodies to R2 by content hash - #693

Merged
harlan-zw merged 2 commits into
mainfrom
feat/skill-source-r2
Nov 12, 2026
Merged

harlan-zw merged 2 commits into
mainfrom
feat/skill-source-r2

Conversation

@harlan-zw

Copy link
Copy Markdown
Collaborator

🔗 Linked issue

Related to #126 (daily check-in: database capacity incident). Step 3 and 4 of ADR-0019 (#692).

❓ Type of change

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

📚 Description

skills.rendered_raw holds every SKILL.md body in D1: about 9 KB a row, 117 KB at the largest, 25,145 rows on 2026-11-12. D1 is a 10 GB store and reached that limit on 2026-11-04. ADR-0019 moves the body to R2 under its SHA-256, which the row already records in rendered_raw_sha256.

Architecture: the sync and the backfill task put bodies through the new skill-source store into R2, while the D1 skills row keeps its copy for now

This is the dual-write step. Nothing reads from R2 yet and no column changes.

  • skill-source-store.ts: key v1/skill-source/sha256/<2>/<sha>.md in PUBLIC_ARTIFACTS. A put is conditional on the key not existing, R2 checks the bytes against the hash, and a failure is a value, not a throw. readSkillSource serves R2 first and falls back to the D1 column; a later step moves each reader onto it.
  • syncRepo collects each changed body and puts it to R2 before the D1 batch, so a row that names a hash never points at a missing object. A failed put leaves the row's own copy and counts in stats.sourceStoreFailures. The repo-maintenance job passes the bucket; scripts and older tests that omit it write D1 only.
  • backfill-skill-sources (*/5) copies rows that predate the change, 200 a run by rowid, about ten hours for the current table. The cursor lives in the new registry_cursors table (migration 0159) and only advances past rows whose put succeeded.

Data flow: the R2 put happens before the D1 upsert for one changed body

Cost: 25 K Class A puts for the backfill, about $0.11, and 225 MB of R2 storage.

Rollback: delete the task and the sourceBucket option. The objects are inert and the readers never left D1.

docs/arch/cron.md is regenerated and pnpm cron:parity passes.

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

🤖 Generated with Claude Code

`skills.rendered_raw` holds every body in D1, about 9 KB a row and
117 KB at the largest, and D1 reached its 10 GB limit on 2026-11-04.
ADR-0019 moves the body to R2 under its SHA-256, which the row already
records in `rendered_raw_sha256`.

This is the dual-write step. The sync puts each changed body to R2
before the D1 batch, so a row that names a hash never points at a
missing object, and a failed put leaves the row's own copy in place. A
five-minute task copies the rows that predate the change, 200 a run,
with a cursor in the new `registry_cursors` table. `readSkillSource`
serves R2 first and falls back to the column, for the readers a later
step moves over.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@harlan-github-agent harlan-github-agent Bot added the harlan-agent-running An Agent holds a Task on this issue or pull request right now. label Nov 12, 2026
@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. and removed harlan-agent-running An Agent holds a Task on this issue or pull request right now. labels Nov 12, 2026
@harlan-github-agent

harlan-github-agent Bot commented Nov 12, 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-11-12 02:15 UTC.

GitHub merged this pull request.

  • Logged (78/100): Failed dual writes behind the cursor are never retried. View code Optional follow-up: Optional follow-up: persist failed source writes for retry independently of the forward-only backfill cursor.
    • Ask an agent to verify and fix this finding
  • Logged (55/100): R2 read errors bypass the available D1 fallback. View code Optional follow-up: Optional follow-up: handle R2 read failures and return the stored D1 body when available before adopting this helper.
    • Ask an agent to verify and fix this finding

edd72e85-d5f4-42bd-86e0-ed6d6514c4a5

Selected findings run after merge and open separate pull requests.

@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-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 Nov 12, 2026

@harlan-github-agent harlan-github-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Harlan Agent Kit posted this automated review. AI open source policy.

Automated Review: READY.

Read the Review results

@harlan-zw
harlan-zw merged commit 58a188f into main Nov 12, 2026
8 checks passed
@harlan-zw
harlan-zw deleted the feat/skill-source-r2 branch November 12, 2026 02:12
@harlan-github-agent harlan-github-agent Bot removed the harlan-agent-ready The automated Review passed every gate on this head commit. label Nov 12, 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