Repository navigation
Conversation
…blement smoke While SKILLX_PERSONAL_KITS_API is off every kit path still answers 404, now with the code kit.api_disabled, before any authentication or lookup. A client can then say the deployment does not offer personal kits instead of reporting a missing kit; the answer names no kit, owner or state. scripts/smoke-personal-kits.mjs stores one throwaway private kit and checks anonymous 401, idempotent replay, 412 on a stale If-Match, activation, the lock read-back and 404 for another account, then prints a JSON receipt without keys. It refuses a non-loopback base unless --allow-remote is passed and exits 2 when the deployment answers kit.api_disabled. A vitest runs it against the real route modules over the in-memory D1/R2. docs/personal-kits-api.md gains an enablement and rollback runbook. The production flag value in wrangler.jsonc is unchanged.
|
AgentKit counterpart (draft): bestagentkits/agentkit#2647 maps |
mrgoonie
left a comment
There was a problem hiding this comment.
Review độc lập cho head 69dbb139e
Kết luận: 0 blocking, 4 non-blocking. Phần flag-off trả đúng 404 kit.api_disabled trước cả auth, lookup và rate limiter. Phản hồi có Cache-Control: no-store và không nhắc tới kit, owner hay state nào. apps/web/wrangler.jsonc vẫn để "SKILLX_PERSONAL_KITS_API": "0".
Bằng chứng đã chạy
- Môi trường: worktree tạm,
pnpm install --frozen-lockfile. pnpm test: 104 files, 2130 passed và 2 skipped.apps/web:react-router typegenrồitsc -b, exit 0.- Probe
scripts/smoke-personal-kits.mjs, dùng key giả và một fake loopback, không gửi gì tới skillx.sh:--base https://example.invalidbị từ chối, không có request nào.- Các host
localhost.example.comvà127.0.0.1@evil.exampleđều bị từ chối. - Fake trên
127.0.0.1trảkit.api_disabled: exit 2, đúng 1 request GET, receipt cóenabled:false. - Không có key nào xuất hiện trong stdout hay stderr.
- Tenancy, xem trong code hiện có vì diff không đổi phần này:
serveKit: read đi quaresolveViewer+ rate limit + 401 khi anonymous.- Write đòi
actor.kind === "user", nếu không thì trả 404. - Admin secret không thấy kit nào, trừ các admin route.
- Kit của người khác trả cùng 404
not_foundnhư kit không tồn tại. Smoke harness test "other account is 404" đã chạy qua route thật.
- Rate limit: phản hồi flag-off bỏ qua limiter. Điều này chấp nhận được vì nó là hằng, không chạm D1 hay R2.
Non-blocking
- Tenancy check của smoke là tùy chọn, và chỉ kiểm tra phía đọc.
- Khi thiếu
SKILLX_SMOKE_OTHER_KEY, receipt vẫnok: truemà không có check cross-account. Với #88/#2589, "private permissions" là tiêu chí GO. - Đề xuất: bắt buộc có other key khi
--allow-remote, hoặc ghi checkskippedvà đểok:false. - Nên thêm check cross-account write: other key gọi
POST revisionslên kit của owner thì phải nhận 404 và không tạo row nào.
- Khi thiếu
- Kit smoke tồn tại vĩnh viễn trên deployment. Mỗi lần chạy lại tạo thêm một kit
@handle/smoke-<random>, mà API không có endpoint xóa. Runbook nên nói rõ điều này, và chỉ cách dọn: dùng tên cố định quaname, hoặc ghi SQL dọn kèm rollback note. - Smoke vẫn follow redirect mặc định của
fetch. Undici có stripAuthorizationkhi redirect sang origin khác, nhưng nên đặt thêmredirect: "manual"để defense-in-depth: base loopback không thể chuyển owner key đi nơi khác, và một 3xx sẽ thành check fail rõ ràng. - Doc chưa khớp code. Runbook ghi
"1"bật API, nhưngpersonalKitsApiEnabledcó sẵn từ trước và cũng nhận"true". Nên ghi đúng, hoặc thu hẹp code lại chỉ nhận"1".- Thêm một gợi ý (không bắt buộc):
packages/cli/src/lib/kit-api.tschưa mapkit.api_disabledthành thông báo thân thiện như AgentKit đã làm.
- Thêm một gợi ý (không bắt buộc):
Đối chiếu với AgentKit
- bestagentkits/agentkit#2647 map 404
kit.api_disabledthànhsource.unsupported(exit 2). Tôi đã probe bằng binary thật với fake loopback và thấy khớp. - Các 404
not_foundkhác vẫn làsource.not_found. - Contract giữa hai bên nhất quán.
Đây là COMMENT review, không approve.
…bled in the CLI
The smoke now checks cross-account writes as well as reads: a second account
gets 404 storing or activating a revision, 403 kit.publisher_not_owned creating
a kit under the owner's handle, and leaves the owner's kit unchanged. A remote
run refuses to start without SKILLX_SMOKE_OTHER_KEY, and no request follows a
redirect (a 3xx fails the check).
The API cannot delete a kit (immutable revisions and audit, ON DELETE
RESTRICT), so the smoke reuses one fixed private kit (--kit-name, default
agentkit-smoke) and appends one revision per run instead of a new kit each
time; the runbook gains the cleanup step. The docs state both accepted
enable values ("1" or "true").
The CLI kit client maps 404 kit.api_disabled to KitApiDisabledError, a clear
"this deployment does not offer personal kits yet" error, while a plain 404
stays an ordinary API error.
mrgoonie
left a comment
There was a problem hiding this comment.
Re-review các commit sửa (đến d8480db)
Kết luận: tất cả finding trước đó đã được sửa. Không có blocking. 3 điểm non-blocking ở cuối.
Từng finding
| Finding | Kết quả | Bằng chứng |
|---|---|---|
--allow-remote phải có SKILLX_SMOKE_OTHER_KEY, kiểm tra cross-account đọc và ghi |
Fixed | main() trả 1 khi remote mà thiếu key thứ hai (test kiểm tra thông báo). Khi có key: đọc 404, ghi revision 404, activate 404, tạo kit dưới handle của owner 403 kit.publisher_not_owned, và kit của owner không đổi sau đó. Key sai hoặc trùng owner thì check fail (fail closed). |
Kit smoke dùng lại, --kit-name, bước runbook (API không xóa được) |
Fixed | Kit cố định @handle/agentkit-smoke, profile theo run để revision không trùng. docs/personal-kits-api.md có bước Clean up (tài khoản smoke riêng, không trỏ vào handle người dùng thật) và nêu lý do (ON DELETE RESTRICT, migration 0015). |
redirect: "manual", 3xx là failure |
Fixed | Mọi request dùng redirect: "manual"; opaqueredirect hoặc 3xx cho code redirect và check fail. Có test (302 làm check đầu fail, mọi request mang manual). |
Flag nhận "1" hoặc "true", doc |
Fixed | personalKitsApiEnabled trim, lowercase, so với 1 hoặc true, giống releasesApiEnabled; doc ghi đúng. |
CLI map kit.api_disabled sang KitApiDisabledError |
Fixed | kit-api.ts bọc apiRequest: 404 + code kit.api_disabled thì ném KitApiDisabledError extends ApiError; 404 not_found vẫn là ApiError thường. Có test hai chiều. |
wrangler.jsonc flag vẫn "0" |
Confirmed | apps/web/wrangler.jsonc:72 là "0", và PR không sửa file này. |
Mọi đường kit (kể cả quarantine) đi qua serveKit, nên câu trả lời flag-off phủ toàn bộ và đến trước auth và lookup.
Kiểm tra đã chạy (worktree tạm tại commit d8480db, đã xóa sau khi xong)
vitest runchoapps/web/tests/personal-kits,packages/cli/src/lib,scripts: 15 file, 435 test, pass.pnpm -r run typecheck: không có lỗi.- Không gọi production skillx.sh; chỉ test trong bộ nhớ.
Non-blocking
- Smoke remote không yêu cầu
https. Với--allow-remotevàhttp://ở host remote, cả hai API key đi dạng cleartext. Nên từ chối non-loopback không phải https. - Test chưa phủ giá trị
"true"(và khoảng trắng) của flag; chỉ có"1"và"0". Một test nhỏ chopersonalKitsApiEnabledlà đủ. - Comment trong
apps/web/wrangler.jsoncvẫn ghi"0" = off (404 everywhere), chưa nhắckit.api_disabled. Dòng "stores nothing" của squat probe chỉ đúng khi server đúng; nếu server hồi quy thì kit squat không xóa được. Nên ghi điều kiện đó trong runbook.
CLEAN: 0 blocking, 3 non-blocking.
… values A remote enablement smoke now refuses a base URL that is not https, since it sends account keys. Tests pin the accepted flag values: "1" or "true", trimmed and in any case, and nothing else. The wrangler.jsonc comment and the runbook state those values (the production value stays "0"), and the runbook names the cross-account create probe precisely.
Summary
Part of #88 (the "API enablement, rollback flag and smoke receipts" part left
open after #94). It covers the server side that AgentKit needs to run personal
kits against SkillX once an operator turns the API on. It does not turn it on.
Flag-off answer. While
SKILLX_PERSONAL_KITS_APIis off, every kit pathstill answers 404. It now carries the code
kit.api_disabled, answeredbefore any authentication or lookup, and names no kit, owner or state.
AgentKit (bestagentkits/agentkit#2589) maps it to "unsupported" (exit 2) and
says the deployment does not offer personal kits yet. A plain
not_foundstays "no such kit", so it is never taken as a deleted kit. The flag accepts
"1"or"true"(trimmed, any case), likeSKILLX_RELEASES_API; tests pinthe on and off values, and the docs and the
wrangler.jsonccomment say so.CLI.
packages/clikitApimaps 404kit.api_disabledtoKitApiDisabledError("this SkillX deployment does not offer personal kitsyet ... your local kits are unaffected"). It is still an
ApiError, and aplain 404 stays an ordinary
ApiError.ApiErrorgains the raw body and acodegetter (an additive change).Enablement smoke.
scripts/smoke-personal-kits.mjschecks:If-Matchgets 412kit.generation_conflict;kit.publisher_not_owned;Behavior:
--allow-remoteis passed. A remoterun also refuses a non-https base and refuses to start without
SKILLX_SMOKE_OTHER_KEY, so thecross-account checks always run there.
redirect: "manual", and a 3xx fails the check.kit.api_disabled.Cleanup. The API cannot delete a kit: revisions and audit rows are
immutable, and kits are
ON DELETE RESTRICT(migration 0015). So, instead ofa new random kit per run, the smoke reuses one fixed private kit,
@handle/agentkit-smoke(--kit-nameto change it). Each run appends andactivates one revision there, and a per-run
profilekeeps the revisionunique. The runbook adds a cleanup step: use a dedicated smoke account, and
never point the smoke at a real user's handle. The second account's attempt
to create
@handle/smoke-squat-<random>is refused with 403 before any write, so it leaves no kit.Runbook.
docs/personal-kits-api.md"Enablement and rollback":"0"keeps every stored revision, lock and audit row.The error table lists
kit.api_disabled.Not in this PR (on purpose)
apps/web/wrangler.jsonckeeps"SKILLX_PERSONAL_KITS_API": "0". Nothingwas deployed and no deployed SkillX was contacted. Turning the flag on,
deploying and running the smoke belong to the ops workstream (Personal-kit API gaps for AgentKit kit publish/sync #88 / feat(private-library): publish skills/kits riêng tư và đồng bộ đa thiết bị, kèm DoD với AgentKit #107).
(declined) of Personal-kit API gaps for AgentKit kit publish/sync #88 are unchanged.
E2E staging receipt: BLOCKED
There is no SkillX staging Worker and no
SKILLX_STAGING_TOKEN, so this PR hasno staging smoke receipt. What exists is a local receipt, and it is not a
production-readiness claim.
apps/web/tests/personal-kits/kit-enablement-smoke.test.tsruns the smoke against the real
api.v1.kitsand release-manifest routemodules over the in-memory D1/R2 test harness:
checks; the foreign writes store nothing (1 kit, 1 revision);
redirectand is never followed;enabled: falseand writes nothing;refused before any request.
Tests
pnpm testatcc7f69a: 104 files, 2136 passed and 2 skipped.pnpm -r --if-present run typecheck(skill-tree, cli, contracts, web)exits 0.
packages/clitsupbuild succeeds.Related
AgentKit), [Phase 3] Personal kits, installer, lockfile and multi-device sync #35 (phase 3 personal kits and sync), feat(kits): If-Match preconditions and composition metadata for personal kits #94 (If-Match and
composition metadata, merged), Harden personal kit proposal scanning before enabling the API flag #86 (proposal hardening before enabling the
flag, closed), feat(releases): skillx.release/v2 kit provenance for @agentkit releases #104 (provenance).
bestagentkits/agentkit#2647.