Repository navigation
feat(registry): reproducible AgentKit foundation publishing and pinned whole-tree artifact API #54
Description
Parent / cross-repo
Implementation slice of SkillX #34 and #21, tracked by SkillX #31; counterpart AgentKit #2274 and design prerequisite AgentKit #2275. Keep #34 as contract owner for generic registry, not a second registry implementation.
Objective
Create a first-class, trusted AgentKit publisher integration using SkillX's generic immutable whole-directory package/release model: export one self-contained AK foundation skill from the canonical AK repo and publish it manually and through scoped CI with exactly reproducible bytes; expose safe pinned artifact resolution for AgentKit consumers. Do not port AK's installer to TypeScript.
Start with real code
- SkillX
packages/contracts/src/package-manifest.ts,packages/skill-identity,apps/web/app/lib/db/registry-schema.ts,packages/cli/src/commands/publish.ts,apps/web/app/lib/security/content-scanner.ts, Github import/scan routes. Audit existing implementation vs phase-2 roadmap [Phase 2] Immutable registry and publishing CLI/CI #34. - AK
kits/{core,engineer,marketing}/skills,kit.yaml, CLI package/release builder and exported resource closure. - Check exact upstream HEAD, doc ownership and current storage/migrations before designing migrations. Current
skillx useemitsSKILL.mdtext/metadata, not installable nested packages.
Scope / deliverables
- Define deterministic package closure: full recursive file manifest for
SKILL.md,references/,scripts/,assets/,modules/, nested arbitrary regular files plus declared runtime/deps; reject symlink, special file, hardlink, traversal, archive bombs, unsafe modes, secrets and overlimit resources with stable errors. Explicit policy for tests/build artefacts/metadata. - Reuse
skillx.package/v1package identity (@agentkit/ak-...), exact semver/release state. Separate source identity (Git repo+path+commit) from namespace ownership and immutable artifact digest. Release version cannot be overwritten with different bytes. - Stable deterministic pack process (canonical relative paths, file ordering, timestamps, modes, UTF-8/machine-independent canonical manifest; no platform-dependent hash drift). Per-file SHA-256, archive SHA-256, SBOM/dependency metadata where applicable. Publish idempotently.
- Secure R2/artifact distribution through explicit versioned metadata + entitlement aware authorization + short-lived URL/stream and integrity checks; no link construction or redirects that bypass auth. Cache-policy and revocation/yank semantics documented for offline local digests.
- Publisher auth: scoped CI credential or OIDC trusted publish (where supported), namespace ownership, minimal permissions, no secrets in build output/README. Sign/attest artifact provenance if approved contract; do not block existing skill discovery unnecessarily.
- AK mapping: publish one small truly standalone foundation skill first, manually and through CI; reject bundles missing dependencies/hooks/sidecars rather than misrepresenting them as runnable. Curated kit export only after closure verified and SkillX [Phase 4] Hook packs and AgentKit reference publishing #36.
- Stable read-only
inspect/resolve/downloadAPI contract supporting exact release+digest and compatibility metadata for Go consumer. Existingskillx useremains backwards compatible, labeled discovery-only when incomplete; no runtime execution during resolve. - Security release lifecycle: draft/quarantine/review/publish/yank, publisher key rotation, replay controls and revoked/compromised source handling.
Required negative/repro tests
- 94-file-style nested resources preserved; manifests/digests identical from clean builds; same version with changed bytes rejected; cross-runtime archive hash consistency.
- Zip-slip / tar traversal, symlink pointing out, case/Unicode collision, Windows reserved paths, oversized/duplicate entries, malicious executable bit, leaked credential fixtures, malformed metadata, dependency closure missing.
- Auth bypass on private/paid packages, forged namespace, CI publish token with overbroad permissions, partial upload, concurrent idempotent publish/retry, yanked/quarantined resolution.
- Manual vs CI publishing of same snapshot yields identical digest; install/read path has no implicit code execution.
Agent implementation prompt
Implement a vertical slice within Phase 2 with its existing schema/migrations and tests, not a parallel marketplace. Read SkillX instructions, #21/#31/#34 and AK #2275 contract first. Produce an explicit contract+threat model and repo-file references. First implement deterministic full-tree pack+verify, then immutable upload/resolve/auth, finally a scoped AgentKit example publisher. Preserve existing routes/CLI use/search. Keep backward compatibility and feature flags for incomplete public APIs. Every failed verification must fail closed; never curl | sh. Open focused PR(s) with exact tests, artifact digests, no mutable latest refs, migration and rollback notes. Coordinate the API shape with the AgentKit SourceProvider issue before finalizing.
Non-goals
SkillX universal runtime installer, AK native installer rewrite, auto-activation of hooks/scripts, user personalization, paid creator settlement.
Acceptance
- Generic [Phase 2] Immutable registry and publishing CLI/CI #34 contracts reused, no duplicate schema ownership.
- Complete standalone skill published to SkillX manually + CI reproducibly.
- Signed/attested publisher provenance decision documented and integrity verified.
- Pinned, entitled artifact metadata+bytes resolvable by AK without executing.
- Private/quarantined/yanked behavior and path/adversarial tests pass.
- Cross-link implementation PR and AgentKit consumer issue.
Activity
zuey-cloud-harness commentedon Oct 11, 2026
Consumer/direct counterparts: AK #2277 (optional pinned SkillX read/cache/locked sync), AK #2275 (shared contracts), AK #2282 (full-tree/auth/reproducibility and no-exec E2E). Depends on generic immutable registry SX #34 and complete nested resources SX #21. AK Go installer remains separate.
mrgoonie commentedon Oct 11, 2026
AgentKit contract proposal for alignment: https://github.com/bestagentkits/agentkit/pull/2283 (
docs/specs/skill-lifecycle-contract.md). Requests for this slice: (1)releaseDigestMUST equal the canonical tree digestagentkit.skill-tree/v1of the release file tree (archive/artifact_digest= transport integrity only), so manual and CI releases hash identically regardless of container; (2) the SkillX publisher/verifier should pass the shared vectorsdocs/conformance/skill-lifecycle/skill-tree-v1-vectors.json(32 cases incl. traversal, NFC, case collision, reserved names, symlink, noise exclusion); (3)@agentkit/*is reserved for signed AgentKit kits. AgentKit owns the local lock; collection revisions resolve into it. Feedback welcome on the PR before it is accepted.feat(skill-tree): add agentkit.skill-tree/v1 digest, archive readers …
feat(contracts): signed skillx.release/v1 manifest, release status an…
mrgoonie commentedon Oct 13, 2026
SX-3 merged in #59 (squash ec8e143). Evidence: CI green at head 2fc65bf; two isolated review rounds (round 2: 0 blockers, 0 majors); follow-ups in #61.
Activation is NOT done:
SKILLX_RELEASES_APIstays "0" in production; the release endpoint returns 404.fix(registry): harden release reads after review
fix(registry): bound digest lookups by the rows that can win
feat(registry): pinned whole-tree release read API (SX-4) (#64)
mrgoonie commentedon Oct 13, 2026
SX-4 merged in #64 (squash eb94997). It adds the pinned read API: release list, signed manifest by version or digest, file and artifact by digest with
?version=, and signing key IDs. Everything stays behindSKILLX_RELEASES_API(off).Evidence:
Activation checklist (not done):
RELEASE_READ_LIMITERbinding, namespace 5401.SKILLX_REGISTRY_REVOKED_KEY_IDSas a secret.SKILLX_RELEASES_API=1.Follow-ups:
last_used_atwrite in API-key auth./files/*re-validates the manifest on every request.feat(registry): audited release state transitions and full-tree E2E (…
mrgoonie commentedon Oct 13, 2026
SX-5 landed in #66 (squash 6c5557a): release/publisher state API with audited compare-and-set (migration 0013, append-only triggers), admin containment of yanked releases in one batch, rate limiting before any write, 94-file nested full-tree E2E, runbook in
docs/deployment-guide.md.Evidence: web typecheck 0; vitest 1180 pass, 1 known fail (#63); web build 0; local wrangler applied 0001-0013 and the triggers abort UPDATE/DELETE. Two independent review rounds, no open Blocker/High.
Still owner steps (not done): back up D1, apply 0012 and 0013 remotely, then follow the runbook "Enable" section. Follow-ups tracked in the new limiter/real-D1 issue.
zuey-cloud-harness commentedon Oct 13, 2026
Progress snapshot 2026-10-14 00:25 ICT
Source-code implementation slices SX-1..SX-5: 5/5 merged (100% of planned foundation registry slices), but production activation/issue acceptance NOT complete.
6c5557a2026-10-13 22:25 ICT. DefaultSKILLX_RELEASES_API="0"inapps/web/wrangler.jsonc. No verified real production publish/consume smoke or API enabled as of evidence checked.feat(releases): enable the release API in production (#70)
mrgoonie commentedon Oct 14, 2026
Release API activation (runbook in
docs/deployment-guide.md), 2026-10-14:d1 exportis refused because the DB has FTS5 virtual tables, so the tables the migrations touch (api_keys,d1_migrations) were dumped separately, outside the repo.0012_api_key_scopesand0013_release_state_auditapplied remotely; both listed ind1_migrations;release_state_audittable plusrelease_state_audit_no_update/_no_deletetriggers present.RELEASE_WRITE_LIMITER): both rate-limit bindings listed;GET /api/v1/packages/@agentkit/x/releases-> 404.SKILLX_RELEASES_API = "1"). Live: unknown package -> 404not_found,GET .../state-> 405, anonymousPOST .../state-> 401auth.required. Homepage 200.Rollback stays: set the flag to
"0"and redeploy.zuey-cloud-harness commentedon Oct 14, 2026
Release API milestone update, 2026-10-14 10:59 ICT
Important correction to 00:25 report: release API is now activated on production, but signed publish/consume acceptance remains BLOCKED.
RELEASE_WRITE_LIMITER(30/60s), admin secret attempts throttled. Release state API: dedicated write limiter and real-D1 round trip before enable #68 CLOSED.SKILLX_RELEASES_API=1. Owner reports live request responses unknown package 404, wrong method 405, unauthorized state mutation 401. Main363600cconfirms flag = 1.publisher.not_owner. No real release published. Implement safe publisher provisioning and verify creator ownership, idempotency, scoped auth and admin audit before declaring this issue accepted.mrgoonie commentedon Oct 14, 2026
Production activation smoke: passed (2026-10-14, runbook step 6)
Throwaway release
@skillx-smoke/activation-smoke@0.0.1(channel beta) published with areleases:publish:@skillx-smokescoped key.200,created: true,state: published, keyIdskillx-reg-993cd14a011f7b76, findings[]200,created: false, samereleaseDigest200, one release, newest first200, byte-identical (805 B)SKILL.md200, sha256 matches the manifest entry200, 2048 B, sha256 equalsartifactDigest/api/v1/keys[skillx-reg-993cd14a011f7b76], revoked[]ak skills resolve/inspect/read(AGENTKIT_SKILLX=1, isolated home) verified the signature with its embedded production key and recomputedreleaseDigestsha256:d345848f…1575200,published -> yanked409 state_conflictyanked; new resolution410 release_yanked; locked read by digest200applied user published->yanked,stale user published->yanked,applied admin none->active(publisher)The smoke release stays yanked. The scoped key is to be revoked by the owner.
Found on the way: #73 (built CLI bundle crashes on yaml dynamic require; smoke used a temporary createRequire shim) and #74 (Settings cannot create scoped keys; key created through the API).
zuey-cloud-harness commentedon Oct 14, 2026
Production publisher/smoke checkpoint, 2026-10-14 21:40 ICT
@skillx-smoke/activation-smoke@0.0.1: scoped-key publish/replay, by-version and by-digest signed manifest, file and artifact SHA-256, independent AgentKitak skills resolve/inspect/readEd25519 verification andreleaseDigest, successful yank/409 stale replay and audit. Smoke remains yanked. This supersedes the earlier '0 publisher, no smoke' status.feat(releases): signed release status, exec manifest validation, dige…