feat(bootstrap): publish starter skills in runtime manifest

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
This commit is contained in:
XiaoSeS 2026-07-31 18:25:27 +08:00
parent b20ad397ad
commit 5f7c48b7a4
6 changed files with 125 additions and 5 deletions

View file

@ -25,6 +25,9 @@ added to the runtime manifest only after its immutable CDN URL is available; the
the matching SHA-256 so the backend can reject changed or incorrectly uploaded bytes before
extraction.
The first batch of 15 packages is pinned in the runtime manifest. A clean deployment initializes
these packages alongside the existing built-in Skills in the public `@global` namespace.
## Share a Skill with the Community
A Skill shared with the community may be considered for the curated starter collection.

View file

@ -122,7 +122,7 @@ Catalog 按单个 Skill 的许可证筛选。Anthropic 的 `docx`、`pdf`、`ppt
- 跑通批量检查、打包、上传和 manifest 更新流程。
- 已从 70 个候选中选定 A05、A07A15、B06、B07、B10、B11、B24共 15 个。
- 15 个候选均已完成必要适配、来源与许可证登记、生产包校验和静态安全复测。
- 待完成不可变制品上传、manifest 哈希登记和干净实例同步验证。
- 已完成不可变制品上传和 manifest 哈希登记,待完成干净实例同步验证。
- 不要求第一批为了形式上覆盖全部类别而降低门槛;旅行规划等缺少合格候选的场景留到第二批。
### 第二批:扩充到 30 个

View file

@ -209,6 +209,5 @@ B25 的核心行程生成实测失败,并会把敏感旅行画像写入宿主
7. 将不可变 URL 和制品 SHA-256 写入
`server/skillhub-app/src/main/resources/builtin-skills/manifest.json`,在干净部署中验证同步、下载和安装。
第一批 15 个适配包已经完成内容、安全和确定性构建检查;在官方不可变 CDN URL 可用前,暂不把
它们写入运行时 manifest。把 GitHub 分支下载地址直接写进 manifest会导致内容变化后无法审计
和复现。
第一批 15 个适配包已经完成内容、安全和确定性构建检查,并已通过官方不可变 CDN URL 和
SHA-256 写入运行时 manifest。后续更新必须发布新版本和新制品不得覆盖当前 URL 对应的字节。

View file

@ -18,6 +18,34 @@ python3 "$BUILDER" --output "$second"
cmp "$first/artifacts.json" "$second/artifacts.json"
runtime_manifest="$REPO_ROOT/server/skillhub-app/src/main/resources/builtin-skills/manifest.json"
python3 - "$first/artifacts.json" "$runtime_manifest" <<'PY'
import json
import sys
from pathlib import Path
from urllib.parse import urlsplit
artifacts = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))["artifacts"]
runtime_items = json.loads(Path(sys.argv[2]).read_text(encoding="utf-8"))["skills"]
runtime_by_coordinate = {}
for item in runtime_items:
coordinate = (item["slug"], item["version"])
assert coordinate not in runtime_by_coordinate, coordinate
runtime_by_coordinate[coordinate] = item
assert len(runtime_items) == 17, len(runtime_items)
for artifact in artifacts:
coordinate = (artifact["slug"], artifact["version"])
assert coordinate in runtime_by_coordinate, coordinate
runtime_item = runtime_by_coordinate[coordinate]
assert runtime_item["sha256"] == artifact["sha256"], coordinate
parsed_url = urlsplit(runtime_item["url"])
assert parsed_url.scheme == "https", coordinate
assert parsed_url.hostname == "bjcdn.openstorage.cn", coordinate
assert not parsed_url.query and not parsed_url.fragment, coordinate
assert parsed_url.path.endswith(f'/{artifact["sha256"]}.zip'), coordinate
PY
python3 - "$first" <<'PY'
import json
import sys

View file

@ -11,6 +11,96 @@
"version": "1.1",
"url": "https://bjcdn.openstorage.cn/aicontest/2026-06-12/9d063bc7-223a-4762-adeb-305c268aa29e.zip",
"sha256": "77b16d62c1adaf8c1d5ca06b9bff26005bc77da345e6036cc5f1f91bdee1a149"
},
{
"slug": "ai-claim-checker",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/9d8a9ef1-6c63-483a-a54d-b593180572a2/skillhub-builtin-skills/ai-claim-checker/1.0.0/19fd699fc5e67469bb764d5f695894c1a39e49055060152aa6168629ca0f0ea5.zip",
"sha256": "19fd699fc5e67469bb764d5f695894c1a39e49055060152aa6168629ca0f0ea5"
},
{
"slug": "daily-standup-journal",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/c6dc807b-5255-4aa9-8bdd-a708b9d159a6/skillhub-builtin-skills/daily-standup-journal/1.0.0/fd365dd3e1a4302044839bf3317c262c4bad650e0a677b7a1ca1d1ad5b8ab1bd.zip",
"sha256": "fd365dd3e1a4302044839bf3317c262c4bad650e0a677b7a1ca1d1ad5b8ab1bd"
},
{
"slug": "decision-matrix",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/73347ade-b71d-42e0-ad14-a63ac761d7ab/skillhub-builtin-skills/decision-matrix/1.0.0/1f284d78ebd8530b10d11a801237c11a0b24a08fe1798587df99ade7686b827a.zip",
"sha256": "1f284d78ebd8530b10d11a801237c11a0b24a08fe1798587df99ade7686b827a"
},
{
"slug": "diagram-maker",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/3d36219f-d700-4623-b482-39a39691ec22/skillhub-builtin-skills/diagram-maker/1.0.0/4c2fd87851f7a2a6dfca712887f8135f1696e23e8dc24cbb48f82303029eed17.zip",
"sha256": "4c2fd87851f7a2a6dfca712887f8135f1696e23e8dc24cbb48f82303029eed17"
},
{
"slug": "documentation-writer",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/e7e7b3ce-4923-4528-b7b4-e89de10802fa/skillhub-builtin-skills/documentation-writer/1.0.0/6a2cff6c0248c9a01c2475f2467606f06312ffc093c4ac0637ad50ba13b421aa.zip",
"sha256": "6a2cff6c0248c9a01c2475f2467606f06312ffc093c4ac0637ad50ba13b421aa"
},
{
"slug": "exam-ready",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/2a4ff8f9-7f57-435f-8eb1-69fe33afa99e/skillhub-builtin-skills/exam-ready/1.0.0/aea81a497157a19e4b136f2cfe3ba0764ebb52e520e4a87fa0446e5465f97663.zip",
"sha256": "aea81a497157a19e4b136f2cfe3ba0764ebb52e520e4a87fa0446e5465f97663"
},
{
"slug": "frontend-design",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/fae63ded-f222-4583-a723-d6d9529360e0/skillhub-builtin-skills/frontend-design/1.0.0/67b2f34163874e56ba43a0a9ed3d1012d752615a1a80f0c26608a702d9fe394e.zip",
"sha256": "67b2f34163874e56ba43a0a9ed3d1012d752615a1a80f0c26608a702d9fe394e"
},
{
"slug": "linkedin-post-formatter",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/4e19c89f-7fa2-44fa-a3bf-90ec959258c0/skillhub-builtin-skills/linkedin-post-formatter/1.0.0/171acf2d0574265b1ececa53759658aeb582aae4c859d4199b1ff322d65f8642.zip",
"sha256": "171acf2d0574265b1ececa53759658aeb582aae4c859d4199b1ff322d65f8642"
},
{
"slug": "meeting-note-summarizer",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/6cf347a7-ccc5-4016-b4ca-6263959a1b08/skillhub-builtin-skills/meeting-note-summarizer/1.0.0/5add401203f323bc1cbb350f306d3a5d3f3b16c2ad6578e7cab55d2c196152ca.zip",
"sha256": "5add401203f323bc1cbb350f306d3a5d3f3b16c2ad6578e7cab55d2c196152ca"
},
{
"slug": "retrieval-practice-generator",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/ac9086e8-ee32-4baa-bf42-0bc3f5c59558/skillhub-builtin-skills/retrieval-practice-generator/1.0.0/8e1b21f9c02312378da4d5493297d98a2ce40ba03f83a51e24c97ad53f144dc1.zip",
"sha256": "8e1b21f9c02312378da4d5493297d98a2ce40ba03f83a51e24c97ad53f144dc1"
},
{
"slug": "storytelling-advisor",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/12e1eaea-cffc-4d67-b452-5383868475d2/skillhub-builtin-skills/storytelling-advisor/1.0.0/c44427e0a45e3a63dc47fb2a58e9b40f9db7a6d29715fc38a2d6162e89cd4be3.zip",
"sha256": "c44427e0a45e3a63dc47fb2a58e9b40f9db7a6d29715fc38a2d6162e89cd4be3"
},
{
"slug": "study-strategy-selector",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/ac7017cf-7d83-46e0-a467-7e2d199cbd03/skillhub-builtin-skills/study-strategy-selector/1.0.0/ea5ef41b449b823cd996be18c4f6af2d9944a0571aa7c65091327cc1893657f1.zip",
"sha256": "ea5ef41b449b823cd996be18c4f6af2d9944a0571aa7c65091327cc1893657f1"
},
{
"slug": "time-blocking-scheduler",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/9b032189-7bba-407e-adb2-bcda2c0c2765/skillhub-builtin-skills/time-blocking-scheduler/1.0.0/005b0d9afda5bb8f4dd8b8d43b2201e26f2f2792a1d7b57dc7667367d543e76e.zip",
"sha256": "005b0d9afda5bb8f4dd8b8d43b2201e26f2f2792a1d7b57dc7667367d543e76e"
},
{
"slug": "video-frames",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/4136bddd-868a-44e3-a16e-16321433733c/skillhub-builtin-skills/video-frames/1.0.0/7b4e9f1fb30b5f8318b061e1c5aeda0249d73746acc548ee4d7ff13b3d999966.zip",
"sha256": "7b4e9f1fb30b5f8318b061e1c5aeda0249d73746acc548ee4d7ff13b3d999966"
},
{
"slug": "weather",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-07-31/0170ce8f-ad41-4819-bc50-9b572b1c6510/skillhub-builtin-skills/weather/1.0.0/181e36c0fd6ca5f6cdf224276dd12e0fd203f83456a988a6bcf15cc4f3c20dd6.zip",
"sha256": "181e36c0fd6ca5f6cdf224276dd12e0fd203f83456a988a6bcf15cc4f3c20dd6"
}
]
}

View file

@ -56,7 +56,7 @@ class BuiltinSkillManifestLoaderTest {
List<BuiltinSkillManifestLoader.ManifestItem> items = loader.load();
assertThat(items).isNotEmpty();
assertThat(items).hasSize(17);
assertThat(items).allSatisfy(item ->
assertThat(item.sha256()).matches("[0-9a-f]{64}")
);