Skip to content

WIP: feat(authoring): Skill 创作与验证平台(三层验证 / Docker 隔离 / MCP 真实探测) - #886

Open
zjncs wants to merge 13 commits into
iflytek:mainfrom
zjncs:feat/skill-authoring-validation
Open

zjncs wants to merge 13 commits into
iflytek:mainfrom
zjncs:feat/skill-authoring-validation

Conversation

@zjncs

@zjncs zjncs commented Sep 19, 2026 •

Copy link
Copy Markdown

状态:草稿(WIP) — 功能开发与验证已完成,作者正在做提交前的最终审查(描述措辞、提交拆分、与导师的沟通)。请维护者暂勿 review / merge;如需提前给方向性意见,非常欢迎。

概述

面向 SkillHub 的 Agent Skill 创作与验证平台(开源之夏 26d8e0076)。作者在浏览器工作台里完成 Skill 的创建、文件编辑、运行时绑定与三层验证,验证通过的修订号过闸后一键进入既有发布管线 —— 把"写一个 Skill"从盲写 zip 包变成带真实反馈的闭环。

分层提交

提交 内容
feat(authoring) domain + persistence 草稿 / 文件(内容寻址存储、乐观修订号)/ 运行时绑定 / 验证运行领域模型,Flyway V60(JSONB 列)
feat(authoring) validation pipeline 三层验证编排(STRUCTURE / CONFIG / BEHAVIOR)、事件与发现流、脚本运行时(inline / Docker 隔离:无网络、内存/CPU/pids 上限、只读 rootfs、全能力剥离)、OpenAI-compatible LLM agent 循环(MCP 工具真实执行)、MCP 服务器运行时真实探测(连接 + initialize 握手 + tools/list,死端点即失败发现)、崩溃运行清扫
feat(authoring) REST API 草稿/文件/绑定/运行 CRUD,SSE 事件流 + 轮询降级,发现修复应用,验证过闸提交
feat(web) workbench 草稿列表与详情、文件编辑器(文本/二进制、sha256 面板)、绑定表单、运行详情(实时事件控制台、发现卡片 + diff 预览 + 两步确认修复)、提交门禁
test(authoring) Playwright E2E(3 用例真实 UI 闭环)+ 活体冒烟脚本(35 检查 / 4 场景)
docs(authoring) 平台设计/部署/测试文档、覆盖全部断言类型的示例 Skill、RISC-V64 验证记录

核心闭环

  1. 结构层:frontmatter / 路径 / 包结构规则,发现带可应用修复建议;
  2. 配置层:validation.yaml 防御式解析、绑定校验(禁内嵌凭据、解释器白名单)、声明的 MCP 服务器逐台真实探测(连不上 → MCP_CONNECT_FAILED;toolFilters 引用未知工具 → 告警);
  3. 行为层:在一次性隔离工作区执行脚本 / LLM 任务并跑断言(exit_code、stdout_contains/matches/json、tool_call_count 等);
  4. 修复闭环:失败发现 → diff 预览 → 两步确认应用 → 修订号推进自动失效旧结论 → 一键复验;
  5. 提交过闸:只有"当前修订号验证通过"的草稿可提交,复用既有发布管线与安全扫描。

验证记录

  • 后端:mvnw test 全量 1039 tests, 0 failures(Testcontainers 真实 PostgreSQL,含 AuthoringFlowIntegrationTest 全流程与死 MCP 服务器回归用例)
  • 前端:lint / typecheck 0 错误;unit 870/876(6 个为主线既有的 theme env 失败,pristine HEAD 同现);Playwright E2E 3/3
  • 活体冒烟:scripts/authoring-smoke-test.sh 35/35(含 MCP 死服务器失败、假服务器工具发现、未知 toolFilters 告警三连)
  • RISC-V64:本分支构建 linux/riscv64 镜像(293MB,eclipse-temurin:21-jre-noble),QEMU 下 91.9s 启动、Flyway 全量迁移,REST API 走完 建草稿 → 编辑 → 绑定 → 验证 SUCCEEDED(0 错 0 警,12 事件),脚本子进程真实运行在 riscv64 用户态 —— 详见 docs/26-skill-authoring-platform.md 的验证记录章节

E2E 与冒烟共暴露并修复了 5 个真实缺陷(脚手架内容未持久化、无绑定时表单默认值被清空、文件编辑器陈旧列表劫持选中导致内容存错文件、终态运行事件不回填、MCP 探针被配置层提前返回跳过)。

部署

Flyway V60 自动建表;SKILLHUB_AUTHORING_LOCAL_SCRIPT_MODE=docker 启用容器隔离(生产建议);LLM 运行时默认关闭。配置项详见 docs/26-skill-authoring-platform.md。

Copilot AI lite review requested due to automatic review settings September 19, 2026 18:43
@CLAassistant

CLAassistant commented Sep 19, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@zjncs
zjncs marked this pull request as draft September 20, 2026 01:39
@zjncs zjncs changed the title feat(authoring): Skill 创作与验证平台(三层验证 / Docker 隔离 / MCP 真实探测) WIP: feat(authoring): Skill 创作与验证平台(三层验证 / Docker 隔离 / MCP 真实探测) Sep 20, 2026
@XiaoSeS XiaoSeS self-assigned this Sep 21, 2026
@zjncs
zjncs force-pushed the feat/skill-authoring-validation branch 2 times, most recently from dd9482c to 1389a77 Compare September 22, 2026 16:17
zjncs added 9 commits October 1, 2026 10:57
…istence

Skill drafts with per-file content-addressed storage, runtime bindings
(agent type, adapter config, tool allowlist, MCP server declarations),
validation runs with ordered events and findings, plus the Flyway V60
schema (JSONB columns) and JPA repositories. Domain services cover draft
lifecycle, file save/read with optimistic revision checks, binding
validation, fix application, submit gating, and the structure/spec/
assertion rules with fix suggestions.

Signed-off-by: zjncs <18910855655@163.com>
…d MCP probe

ValidationRunOrchestrator materializes a draft into a one-shot
workspace and runs structure, configuration and behavior layers,
streaming ordered events and findings. The local-script runtime
executes inline for dev or in a locked-down Docker container (no
network, resource caps, read-only rootfs, dropped capabilities); the
OpenAI-compatible runtime drives an agent loop with real MCP tool
execution. Declared MCP servers are probed for real at run time —
connect, initialize handshake, tools/list — and unreachable servers
or unknown toolFilters become CONFIG-layer findings even when
validation.yaml is absent. A maintenance task sweeps crashed runs.

Signed-off-by: zjncs <18910855655@163.com>
Endpoints for the authoring workbench: draft CRUD and file management
(text + binary upload, content-addressed storage), runtime binding,
validation run lifecycle with SSE event streaming and polling
fallback, findings with fix application and dismissal, and validated
draft submission into the publish pipeline. The integration test runs
the full create → edit → bind → validate → fix → revalidate → submit
loop on real PostgreSQL, including the dead-MCP-server regression.

Signed-off-by: zjncs <18910855655@163.com>
Draft list and detail pages with a file editor (create/edit/upload,
binary files render metadata + sha256, delete with explicit
reselection), runtime binding form (local-script, docker mode,
OpenAI-compatible, MCP server declarations), validation run pages
with a live event console (SSE with polling fallback, terminal-run
backfill), findings with diff previews and two-step fix confirmation,
and submit gating on the validated revision. Dev proxy target is
configurable via VITE_API_PROXY_TARGET.

Signed-off-by: zjncs <18910855655@163.com>
Playwright E2E drives the real UI against the real API: draft creation
with scaffold regression guard, file editing across create/upload
(selection integrity), runtime binding, validation to SUCCEEDED with
live events, frontmatter failure → fix preview → revalidate, and
binary upload verification. The smoke script exercises the live API
surface (35 checks): full validation loop, fixable findings, guards,
and real MCP probes against dead and fake MCP servers. Makefile dev
targets gain configurable ports and proxy target.

Signed-off-by: zjncs <18910855655@163.com>
…rification

Design/deploy/test doc for the authoring platform (domain model,
three-layer pipeline, fix loop, API, workbench, config table), a
self-contained example skill exercising every assertion type, and a
dated RISC-V64 verification record: linux/riscv64 image booted under
QEMU, Flyway V60 applied on fresh PostgreSQL, full authoring flow
driven over the API with the validation script executing inside the
emulated riscv64 container (SUCCEEDED, 0 errors).

Signed-off-by: zjncs <18910855655@163.com>
Server-side validation and runtime clients now share a fail-closed
AuthoringSecurityPolicy:

- OpenAI-compatible and http/sse MCP endpoints are resolved and
  checked against SSRF rules at save time and again at connect time:
  any-local, link-local (cloud metadata) and multicast addresses are
  always rejected; loopback, RFC1918, unique-local IPv6 and CGNAT are
  rejected unless the per-surface allow-private-endpoints flag is set;
  unresolvable hosts are rejected. HTTP redirects are never followed
  and response bodies are capped at 2 MiB on both surfaces.
- stdio MCP transport is disabled by default (mcp.stdio-enabled) and,
  in docker execution mode, its command is wrapped in a hardened
  container (no network, dropped capabilities, read-only root, tmpfs,
  pid/memory/cpu limits) that is torn down when the client closes;
  stdio lines are capped at 2 MiB with force-kill on overflow.
- envRefs may only name variables in mcp.env-allowlist (empty by
  default, so every reference is rejected until an operator opts in).
- local-script execution-mode now defaults to docker; running inline
  outside the local/dev/test profiles fails startup.

Also renumbers the authoring migration V60 -> V66 to clear the slot
taken by upstream organization migrations.

Signed-off-by: zjncs <18910855655@163.com>
- ConfiguredAuthoringSecurityPolicyTest: public/private classification
  per surface, always-blocked ranges, unresolvable hosts, no-host URIs.
- AuthoringStartupGuardTest: inline mode only boots with a
  non-production profile; docker mode always passes.
- McpClientFactoryTest: rejected endpoints never connect, disabled
  stdio refuses, envRefs are filtered by the allowlist, docker-wrapped
  commands carry the full hardening argument set.
- HttpMcpClientTest/StdioMcpClientTest: redirects to the cloud metadata
  range are not followed, 3 MiB bodies and unterminated 5 MiB lines are
  rejected (the latter with the process killed), teardown commands run
  on close.
- AuthoringFlowIntegrationTest: metadata endpoints and envRefs outside
  the allowlist are rejected at save time with actionable reasons.
- Smoke case 5 asserts the same three rejections over HTTP.

Signed-off-by: zjncs <18910855655@163.com>
- Record the 2026-09-21 end-to-end publish run: author -> validate ->
  submit PUBLIC -> async scan (SKILL_SCANNER:SAFE) -> admin review ->
  PUBLISHED, publicly retrievable, driven by the new
  scripts/authoring-publish-e2e.sh (16 checks, kept for re-runs).
- Document the security configuration keys and baseline, the docker
  default for local-script execution, and the migration renumber to
  V66.
- Add scripts/riscv64-verify.sh (native vs QEMU auto-detect) plus the
  native-hardware checklist; native runs remain an open item with no
  RISC-V hardware available to the project.

Signed-off-by: zjncs <18910855655@163.com>
@zjncs
zjncs force-pushed the feat/skill-authoring-validation branch from 1389a77 to 3c0b2e1 Compare October 1, 2026 02:58
A fake-IP VPN resolver on the dev machine answered every lookup inside
198.18.0.0/15, and the policy let that reserved range through — a real
SSRF classification gap, since the range is never a legitimate endpoint
and is the synthetic pool used by fake-IP proxies. It now follows the
same conditional block as loopback/RFC1918/ULA/CGNAT.

The unresolvable-host test now stubs resolution through an injectable
HostResolver seam instead of relying on the live network (static mocks
are unavailable: the build pins the subclass mock maker), covering both
a hard lookup failure and a synthetic fake-IP answer. The Spring-wired
constructor is annotated @Autowired so the extra test seam constructor
does not break bean creation.

Signed-off-by: zjncs <18910855655@163.com>
zjncs added 3 commits October 3, 2026 00:35
Native riscv64 hosts could not build the server image: the Alpine JDK
build stage has no riscv64 variant. The build stage base is now a
BUILD_IMAGE build arg (default unchanged), with the Noble JDK variant
passed on native hosts.

scripts/riscv64-native-setup.sh runs on the RVLab board itself: installs
Docker/PostgreSQL/Redis (apt or dnf), creates the empty database the
run migrates from zero, exposes PG and Redis to the docker bridge,
builds the image natively (no QEMU) and drives scripts/riscv64-verify.sh,
teeing everything into a dated evidence log. The doc checklist now
points at the script and records the pending RVLab access requests.

Signed-off-by: zjncs <18910855655@163.com>
Adds .github/workflows/riscv64-native.yml targeting the free Cloud-V /
10xEngineers board runners: on a physical VisionFive 2 it records the
board identity, installs JDK 21 (apt, with a Temurin riscv64 tarball
fallback) plus PostgreSQL and Redis, builds the project with Maven on
the board, and drives the full authoring flow via the verification
script. The workflow is guarded to the fork — upstream has no such
runner, an unguarded job would queue there forever.

scripts/riscv64-verify.sh gains a jar boot mode
(SKILLHUB_RISCV_BOOT_MODE=jar) that runs an already-built jar directly
instead of a Docker image, which is what the board CI uses; docker mode
is unchanged. Jar mode verified end-to-end locally (boot, health, full
flow, 12 events, cleanup) with only the arch assertion failing on the
arm64 host as designed.

Signed-off-by: zjncs <18910855655@163.com>
The Cloud-V runner workflow passed on a physical VisionFive 2 (Ubuntu
24.04 riscv64, no qemu markers): native Maven build, server boot, and
the full authoring flow 7/7 in ~14 minutes total. Checklist items 1 and
3 are now covered by repeatable native CI; items 4-5 (docker
execution-mode rerun, browser E2E) remain for a dedicated machine, with
the RVLab applications pending.

Signed-off-by: zjncs <18910855655@163.com>
@zjncs
zjncs marked this pull request as ready for review October 2, 2026 17:25

This branch has not been deployed

No deployments
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.

4 participants