Skip to content

Personal-kit API gaps for AgentKit kit publish/sync #88

Closed

Description

@mrgoonie

M0 AgentKit v3 release blocker (owner decision, 2026-10-19): Personal kits are no longer a post-v3 optional milestone. AgentKit #2524 and #2589 require production-compatible first-run flows after ak update --ssot: create/edit foundation-derived skills and personal kits, rebase/resolve, explicit private publish, locked second-device sync, and approved session-evolution proposal; local/offline use requires no SkillX login, cloud calls require scoped auth. At audit, SKILLX_PERSONAL_KITS_API=0 in apps/web/wrangler.jsonc. PR #94 delivered composition metadata and If-Match on 2026-10-16, so re-check gaps 1–2 rather than reimplement, and evaluate 3–7 against current schema. Release must pass real staging→production-compatible E2E including signed @agentkit/* foundation publishing, pinned older base handling, CAS conflict, private permissions, no secret leakage and rollback; no fake-only GO. Own exact API enablement, rollback flag and smoke receipts. AgentKit #2282 owns independent acceptance. No automatic user-session upload, public publish or execution of remote scripts. Server-side work should not duplicate AgentKit's Go installer.


Context

AgentKit G2 adds ak skills kit publish and ak skills kit sync --locked for personal kits. The work is tracked in bestagentkits/agentkit#2278 under the epic bestagentkits/agentkit#2274.

Building them against the current personal-kit API surfaced gaps that limit what a synced kit can do. AgentKit works around each one by failing safe and does not depend on any undocumented endpoint.

Gaps

  1. A revision document has no composition metadata. There is no field for the manifest's extends and include, or for the resolution records (keep-old, fork and overlay decisions). As a result, a kit synced from SkillX cannot be rebased or edited from that copy.
    • Ask: optional, schema-validated composition fields on a revision document, and include them in the document digest.
  2. No If-Match or ETag precondition on kit writes. AgentKit sends the expected generation in the request body.
    • Ask: honor If-Match: <generation> and return 412 on a mismatch, keeping the body field for compatibility.
  3. Only forks of ak- skills can be published. An in-place overlay on a foundation skill is refused, so AgentKit exits 6 for it today.
  4. Bases are verified against SkillX releases only. The @agentkit/* foundation releases must exist on SkillX before any AgentKit kit can publish or sync.
    • Ask: publish or mirror the @agentkit/* releases, or accept a signed AgentKit release manifest as a base.
  5. Session proposals are not offered through the personal-kit API that AgentKit uses. This relates to feat(evolution): private reviewed overlay revisions from local session-derived skill improvements #56.
  6. Every pinned base must be the current release. A skill pinned to an older foundation release cannot be published until it is rebased.
    • Ask: allow a revision to pin any published, non-yanked base release.
  7. extends: skillx:<kit> is not supported. A manifest cannot extend another SkillX kit yet; AgentKit keeps it marked unsupported.

Acceptance

Each item is either done or explicitly declined, with the reason. AgentKit then updates its contract and the G2 acceptance rows.

Refs #31

Activity

  1. self-assigned this
    on Oct 15, 2026
  2. mrgoonie commented on Oct 16, 2026

    @mrgoonie
    ContributorAuthor

    Status of every item, from the code on main plus #94. #94 references this issue but does not close it.

    # Item Decision
    1 Composition metadata Done in #94
    2 If-Match / 412 Done in #94
    3 Overlay on a foundation (shared) skill Deferred
    4 @agentkit/* bases Owner/ops decision, options below
    5 Session proposals Already exposed by #83, nothing to add
    6 Pin any published, non-yanked base Already supported, now tested and documented in #94
    7 extends: skillx:<kit> Declined as a new server feature: parent already covers a kit, and a release base depends on item 4

    1. Composition (done). A revision document may carry an optional composition: {extends, include?, resolutions?}. It mirrors the AgentKit manifest extends/include and the agentkit.skill-overlay-resolution/v1 records.

    • Validation is strict and nothing is reordered.
    • It is part of the revision digest. A document without it keeps its old digest, and the existing golden vector is unchanged. The new vector is packages/contracts/src/fixtures/personal-kit-composition-golden.json.
    • SkillX stores it verbatim and never interprets it.
    • Rebase and conflict-resolution revisions drop it, because they move the pins it describes.

    2. If-Match (done). Every generation-guarded write accepts If-Match: "g<n>" (the kit ETag) or a bare <n>.

    • A stale value gives 412 kit.generation_conflict.
    • The body expectedGeneration still works and keeps its 409.
    • If both are sent, they must agree; otherwise the request gets a 400.

    3. Overlay on a foundation skill (deferred). The refusal does not come from lineage. It is the shared-alias guard, overlay.shared_alias.

    • The guard always treats ak-/ak: skills as shared, plus the identities in SKILLX_SHARED_SKILL_ALIASES. Every other @agentkit/* skill can already be overlaid in place (see kit-revisions.test.ts).
    • feat(personal-kits): immutable lineage, structured overlays and conflict-safe foundation rebase #55 lineage is a kit-to-kit parent chain. It has no notion of several foundation owners of one alias, so it can't decide precedence for a shared skill cheaply.
    • The guard mirrors AgentKit's own rule (its contract section 7.4: "fork it instead"). Relaxing it needs AgentKit to define precedence for a shared alias first.
    • Revisit once AgentKit specifies that. Until then, the fork path is the supported answer.

    4. @agentkit/* bases (owner/ops decision). Bases resolve only through SkillX releases. Options:

    • (a) Mirror the releases on SkillX (recommended).

      • An operator provisions the @agentkit publisher with POST /api/v1/publishers (admin secret).
      • AgentKit CI publishes each foundation with a scoped releases:publish:@agentkit key.
      • This needs SKILLX_RELEASES_API on in production, migration 0012 applied, and a D1 backup before any apply.
      • No code change is needed.
    • (b) Accept a signed AgentKit release manifest as a base.

      • This adds a second trust root, with key distribution and rotation, and either byte storage or fetch-on-verify for composition digests.
      • Large, and duplicates (a).
    • (c) Status quo. AgentKit keeps failing safe.

      No action was taken here.

    5. Session proposals. #83 serves them on the same personal-kit API AgentKit already uses: POST /api/v1/kits/@h/k/proposals/validate, POST .../proposals, GET .../revisions/:id/proposal and POST .../revisions/:id/review (web session only), behind SKILLX_PERSONAL_KITS_API. The envelope is skillx.kit-proposal/v1, and the policy is shared via #87. Consuming it is AgentKit G4 slice 4.

    6. Pins on older releases. loadPinnedBase already resolves any release the owner can read, by package, version and digest. It never compared against the newest release.

    7. extends: skillx:<kit> (declined as a new server feature).

    • For a SkillX personal kit, the document's parent: {kit, revisionDigest} already expresses it: one parent, depth 4, and a foreign parent must be public and activated.
    • For a SkillX release foundation (the AgentKit skillx: + releaseDigest form), the entries already pin releases. What is missing is a published foundation, which is item 4.
    • composition.extends now accepts the skillx form as metadata, so AgentKit can record it.

    AgentKit follow-ups (bestagentkits/agentkit#2278):

    • Send If-Match: "g<n>" and map 412 like 409 (exit 6).
    • Emit and read composition, and compare against the new golden vector.
    • Map extends: skillx:<kit> to parent.
    • Keep the fork path for shared skills.
    • Take up proposals in G4.
  3. mrgoonie commented on Oct 19, 2026

    @mrgoonie
    ContributorAuthor

    #100 (in progress) implements the kit provenance part of gap 4, option (a).

    skillx.release/v2 carries provenance: {provider: "kit", origin}. @agentkit/* is accepted only when provenance is kit, the key is scoped releases:publish:@agentkit, and the publisher is the active, admin-provisioned agentkit. Trust stays local-unverified.

    The AgentKit client side is tracked in bestagentkits/agentkit#2623.


    Generated by Claude Code

  4. zuey-cloud-harness commented on Oct 19, 2026

    @zuey-cloud-harness

    Bổ sung issue tích hợp/private-library và DoD theo yêu cầu người dùng ngày 19/10/2026: #107, đối ứng https://github.com/bestagentkits/agentkit/issues/2640.

    #107 phân biệt private standalone skill packages với personal-kit overlays, bổ sung owner access, auth/scopes, thư viện riêng API/CLI/dashboard, giữ review policy cho session-derived proposals, và yêu cầu chứng minh vòng A publish → B sync → B sửa/publish → A nhận phiên bản mới.

    #88 tiếp tục sở hữu API gaps/enablement; #107 tái sử dụng #55/#56/#83/#94 và provenance #100, không yêu cầu triển khai lại phần đã có. Mỗi DoD phải dẫn test, build/deployment ID và receipts thật; bật feature flag hoặc fake-only tests không đủ GO.

  5. mrgoonie commented on Oct 19, 2026

    @mrgoonie
    ContributorAuthor

    Enablement signal, rollback runbook and the smoke script are in draft #109. The staging smoke receipt is still BLOCKED: there is no SkillX staging Worker and no SKILLX_STAGING_TOKEN. #109 has only a local in-memory receipt. The production flag is unchanged and nothing was deployed. AgentKit side: bestagentkits/agentkit#2647.

  6. added and removed on Oct 19, 2026
  7. mrgoonie commented on Oct 20, 2026

    @mrgoonie
    ContributorAuthor

    Production receipt (2026-10-20)

    Enablement

    • SKILLX_PERSONAL_KITS_API was set to "1" by feat(web): enable personal kits and collections APIs in production #112 (5c1f879).
      • Rollback: set it to "0" and redeploy; every kit route then answers 404 and stored kits stay untouched.
      • The procedure is documented in docs/deployment-guide.md and docs/personal-kits-api.md.
    • Production D1 has migrations 0015, 0016, 0018, 0019 and 0020 applied. A Time Travel bookmark was taken before each migration batch.
    • Current worker version is 7d29ff0a at main 79f98fb.

    Foundation publisher and release (gap 4)

    • Publisher bestagentkits is active and admin-provisioned. It has a key scoped to releases:publish:@bestagentkits and a GitHub OIDC trusted publisher for .github/workflows/publish-agentkit-foundation.yml (environment skillx-publish, refs/heads/main).
    • Released @bestagentkits/plan@0.1.0 (beta, published). Source: kits/core/skills/ak-plan at AgentKit f8e2da556c1e19dd5e53934304d7fcce4c0974a0.
      • releaseDigest is sha256:08b0fce1b56819e0e85f9edcc479432f4f3e56c0a79c9f91c95e58fe84cbac65, identical to AgentKit's own digest of that skill directory.
    • Gap 4 is resolved without a contract change. Foundations publish as @bestagentkits/<slug>, because the skillx.release/v1 contract and every shipped verifier reject @agentkit/*. AgentKit consumes bases as skillx:bestagentkits/<slug>. The @agentkit key was revoked and the agentkit publisher row stays reserved.
    • release/v2 provenance (skillx.release/v2: kit provenance (provider/origin) to allow @agentkit foundation releases #100) is not needed for this path.

    Smoke (production, kit @skillx-smoke/smoke-pk-2610200943)

    • CAS
      • A stale If-Match returns 412 kit.generation_conflict, and a stale body expectedGeneration returns 409. In both cases nothing is written.
      • The correct generation returns 201.
      • Cloudflare weakens the kit ETag to W/"g<n>", which made an echoed If-Match fail with 400. fix(web): accept the weak kit ETag in If-Match #116 now accepts the weak form.
      • Re-smoke at 09:53 +07: If-Match: W/"g5" returned 200; the same stale tag sent again returned 412.
    • Private access
      • Anonymous read: 401.
      • A read with only the admin secret: 401. An admin-secret write: 404.
      • The owner's scoped key releases:publish:@bestagentkits: 401 on both the kit and its lock.
      • MCP get_kit: anonymous gets not_found, the owner gets found.
    • Rollback
      • Activating rev 1, then rev 2, then rolling back to rev 1 each returned 200.
      • GET /lock showed the effective revision changing at each step (generation 3, 4, 5).
    • Full receipts are in plans/reports/smoke-261020-prod-personal-kits-install.md in the delivery workspace. Secrets were redacted.

    Gaps

    # Status
    1, 2 Done in #94; If-Match hardened for weak ETags in #116
    3 Deferred: an in-place overlay on a shared foundation skill stays refused; AgentKit keeps exit 6 for it
    4 Done via @bestagentkits (above)
    5 Already exposed by #83
    6 Supported and tested since #94
    7 Declined as a new server feature (parent covers a kit)

    The private-library scope in #107 and the staging receipt in draft #109 remain open on their own.

  8. added
    shippedMerged/deployed
    and removed on Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

shippedMerged/deployed

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions