Skip to content

feat(web) (4/5): skill authoring workbench - #1001

Closed
zjncs wants to merge 8 commits into
iflytek:mainfrom
zjncs:feat/authoring-web
Closed

zjncs wants to merge 8 commits into
iflytek:mainfrom
zjncs:feat/authoring-web

Conversation

@zjncs

@zjncs zjncs commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Layer (d) of the authoring platform split (#934), stacking on #954 (layer b, under review) and #1000 (layer c).

Stacking note: this branch contains layers (b)+(c)'s commits, so the diff above currently shows the stack — it collapses to the layer-(d)-only changes as the lower layers merge. The incremental diff for review today is 26 files, ~+3.3k hand-written lines (the schema is generated): zjncs/skillhub#5.

What this layer adds

The web workbench under /dashboard/authoring:

  • Draft list + detail (files / runtime binding / validation runs tabs) with a file editor that tracks unsaved state and surfaces optimistic-concurrency conflicts
  • Runtime binding form switching fields by agent type (interpreter vs endpoint/model), tool allowlist, MCP server declarations with immediate validation
  • Run detail: status card, live event console (SSE with a 2s polling fallback and cursor replay), finding cards with severity, location, suggested-fix diff preview and one-click apply/dismiss
  • Submit dialog handing validated drafts to the publish pipeline
  • Copy in en/zh/ru; Playwright e2e for the full flow (e2e/authoring-flow.spec.ts)

Verification

zjncs added 8 commits October 21, 2026 16:54
Layer (b) of the authoring platform (iflytek#934), stacking on iflytek#935:

- **Runtime bindings**: agent type + config + tool allowlist + MCP server
  declarations per draft, persisted as JSONB and validated at save time;
  local-script and OpenAI-compatible agent types
- **CONFIG and BEHAVIOR validation layers**: validation.yaml spec parsing
  (defensive YAML), per-task execution through the runtime adapters
  (inline subprocesses with a cleared environment, or the docker backend
  with a locked-down container), MCP servers probed for real during
  validation with tool discovery surfaced in the event stream; assertion
  evaluation (exit codes, stdout/stderr contains, timeouts)
- **Security policies** (the layer that wants the dedicated review):
  the shared AuthoringSecurityPolicy gates OpenAI-compatible and http/sse
  MCP endpoints at save time and again at connect time — cloud-metadata
  and link-local addresses are always rejected, loopback/RFC1918/ULA/
  CGNAT/RFC2544 ranges sit behind per-surface flags; stdio MCP transport
  is disabled by default and, in docker execution mode, wraps its command
  in a hardened container (no network, dropped capabilities, read-only
  root, resource caps) that is torn down on close; envRefs may only name
  variables in the operator-configured allowlist; docker execution-mode
  is the default and inline mode fails startup outside local/dev/test;
  HTTP redirects are never followed and response/stdio line sizes are
  capped at 2 MiB.

Verified: security-policy and MCP unit tests (policy classification per
surface, redirect refusal, response caps, envRef filtering, docker-wrapped
commands), adapter tests including a real-container isolation check, and
the runtime flow integration test (three-layer validation with inline
script execution; cloud-metadata/envRefs/LLM-surface bindings rejected
at save time).

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

Rebases the runtime layer onto main, which now carries iflytek#935 plus the
follow-up hardening (FutureTask per run with duplicate-submit fencing,
a wall-clock watchdog on the timer, settle-first cancellation with
worker interrupt, appendTerminalEvent, revision-pinned
materializeSnapshot, and the PackageEntry streaming API).

The three-phase orchestrator keeps all of it: the watchdog remains the
hard deadline while the behavior layer keeps its between-task soft
deadline; the cooperative cancel signal is now the worker's interrupt
status; the config/behavior layers read the pinned snapshot and the
draft id from the run instead of a reloaded draft. The upstream
orchestrator test is adapted to the runtime-layer constructor (no
adapters registered — the lifecycle paths under test never reach the
config layer) and passes unchanged in its assertions.

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

The validation container drops every capability, including DAC_OVERRIDE,
so the mounted workspace must be world-readable on the host for the
in-container interpreter to open the script, and directories must be
traversable and writable so the script can create artifacts. Fresh JVM
temp directories are owner-only on Linux (umask 077 runners, hardened
hosts), which broke script execution with 'sh: can't open: Permission
denied' — macOS Docker Desktop masks this by remapping ownership inside
its VM, which is why the local suite passed while the hosted-runner CI
failed.

The container also runs as the host JVM's uid:gid (--user) so files the
script creates inside the mount belong to the same user that cleans the
workspace up; running as the image-default root left artifacts that the
host user (and the test harness) could not delete.

Signed-off-by: zjncs <18910855655@163.com>
The push of this rebase did not create a workflow run (GitHub-side
hiccup); an empty commit to retrigger the backend-tests check.

Signed-off-by: zjncs <18910855655@163.com>
Picks up upstream API drift (S3 storage options, github-sync, dsh 0.3.1)
on top of the authoring endpoints.

Signed-off-by: zjncs <18910855655@163.com>
Layer (c) of the authoring platform (iflytek#934), stacking on the runtime
layer:

- **Fix loop**: apply a finding's suggested patch to the draft in one
  call (sha256-guarded old content, revision bump, validation verdict
  invalidated by the new revision) or dismiss it as not applicable
- **Submission**: validated drafts submit into the existing SkillHub
  publish pipeline — the gate is strict (the draft's current revision
  must be bound to a run that succeeded with zero errors), so content
  can never be published without the exact bytes that were validated;
  reuses SkillPublishService (package re-validation, security scan,
  review flow) and records the resulting skill id on the draft

Verified by the full authoring flow integration test: create → edit →
bind runtime → three-layer validation → fix a finding → re-validate →
submit into the (mocked) publish pipeline.

Signed-off-by: zjncs <18910855655@163.com>
Adds the finding apply/dismiss and draft submit endpoints on top of the
runtime-layer schema.

Signed-off-by: zjncs <18910855655@163.com>
Layer (d) of the authoring platform (iflytek#934), stacking on the fix/publish
layer: the web workbench under /dashboard/authoring —

- draft list and draft detail (files / runtime binding / validation runs)
  with an editor that tracks unsaved state and surfaces optimistic-
  concurrency conflicts
- runtime binding form switching fields by agent type (interpreter vs
  endpoint/model), tool allowlist and MCP server declarations with
  immediate validation
- run detail: status card, live event console (SSE with a 2s polling
  fallback and cursor replay), finding cards with severity, location,
  suggested-fix diff preview and one-click apply/dismiss
- submit dialog handing validated drafts to the publish pipeline
- copy in en/zh/ru; Playwright e2e for the full authoring flow
  (e2e/authoring-flow.spec.ts)

Verified: typecheck clean; 922 web unit tests pass (the only failures
in the suite are the two pre-existing upstream theme tests, which fail
identically on plain main).

Signed-off-by: zjncs <18910855655@163.com>
Copilot AI balanced review requested due to automatic review settings October 22, 2026 03:30

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.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@zjncs

zjncs commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Closing in favor of the layer-by-layer cadence: stacked-against-main PRs show the cumulative diff (this one included everything below it), which defeats the point of the split. This layer will be resubmitted against main as soon as the layer below merges, at which point the diff collapses to this layer's own changes. The incremental diff stays reviewable today at the fork-stacked PR linked from #934. Sorry for the churn.

@zjncs zjncs closed this Oct 22, 2026
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.

2 participants