Test 600 — Public SkillHub catalog and private-to-public promotion
Date: 2026-08-08

Scope
=====

This test covers the public anet.sh SkillHub catalog and the explicit export path
from the private, network-scoped Dashboard SkillHub. It does not collapse the two
trust planes:

* Hub/Dashboard `published` means published inside one authenticated network.
* Internet publication requires a local export, a public-repository pull request,
  and a second maintainer review.
* There is no automatic private-to-public synchronization and no public write API.

Provenance
==========

Public anet.sh source commit:
  72f7afd6d6f1aa2e685808650e12f85e51696eee

Dashboard export source commits:
  0c29aed470e5b908ab10631fa8cf6a3433483824  initial export implementation
  181aecf7eee38459d93bc6cccbea295d0781a834  deferred Blob URL cleanup

The Dashboard branch is intentionally stacked on the private SkillHub branch. It
must not be rebased into an unrelated tree or merged before the private SkillHub
base is available.

Docker evidence
===============

Public catalog image:
  tag during verification: anet-test600:dev
  image digest: sha256:da0d71db435021c8a8ad41ac49bc80bf60fe07eca9abbd03b90d4dce3a302eb6
  embedded TEST600_SOURCE_COMMIT:
    72f7afd6d6f1aa2e685808650e12f85e51696eee
  result: PASS (10 checks) at source 72f7afd6; follow-up import preflight adds
    an eleventh witnessed-red gate before write

Dashboard image:
  tag during verification: anet-skillhub-dashboard:dev
  image digest: sha256:2c4f08b32bf03ff4909056b3f38c608ed8406bb9cf1f75f597206975a28e4f20
  embedded source commit:
    0c29aed470e5b908ab10631fa8cf6a3433483824
  result: contract PASS; targeted ESLint 0 errors; Next production build PASS
  routes: 52 pages, including /skillhub

The follow-up URL-lifetime delta at 181aecf7 was re-run in Docker with the
read-only worktree mounted into node:22-bookworm-slim. The SkillHub module
contract passed. This delta only defers URL.revokeObjectURL until the next event
loop and adds a contract assertion; it does not change the bundle schema,
permissions, or rendering.

Vercel project-root follow-up
============================

Source commit:
  96b70ec7deadf96da023f0012096aeeb75e11f2f

Docker image:
  tag: anet-test600-vercel-root:dev
  image digest: sha256:6347ebe1236d26bccf0554893896a379937f786a4d5dff5df046dbb20c7ed72a
  embedded TEST600_SOURCE_COMMIT:
    96b70ec7deadf96da023f0012096aeeb75e11f2f
  result: PASS (12 checks)

Witnessed red used the same filesystem boundary as the Vercel project: only
`docs-site/` was present. `npm run build` failed in prebuild with
`MODULE_NOT_FOUND` because it referenced `../scripts/build-public-skillhub.mjs`,
which is outside that project root. The failed cloud deployment did not replace
the existing anet.sh production deployment.

Witnessed green moves the single canonical validator into
`docs-site/scripts/`, keeps the repository-root command as a compatibility
wrapper, and adds a docs-site-only gate. The exact Docker source passed all 12
checks, including a real VitePress production build in 34.34 seconds. A separate
docs-site-only host probe also completed `npm run build` and emitted the public
catalog and `/skillhub` page without reading a repository parent directory.

Public-catalog checks
=====================

1. The checked-in catalog is deterministic and current.
2. Invalid licenses are rejected (witnessed red).
3. Credential-shaped content is rejected without printing the value (witnessed red).
4. A manually edited/stale catalog is rejected (witnessed red).
5. A bundle whose SHA-256 does not match its content is rejected (witnessed red).
6. A valid Dashboard-format bundle imports into the expected immutable path.
7. Symlinks and unexpected files are rejected.
8. Chinese and English public-boundary documentation is present.
9. The public catalog component is wired into both locales.
10. A real VitePress production build emits the catalog, content, and both pages.
11. The Vercel docs-site project root contains its complete catalog validator.
12. The production build remains green with the self-contained prebuild path.

Security and privacy assertions
===============================

* Metadata keys are explicit at import and catalog-build time; private/unknown
  fields are rejected before the importer creates a version directory.
* The validator accepts only regular files and rejects symlinks.
* Skill text is UTF-8, bounded to 128 KiB, and rejects NUL bytes.
* Credential-shaped strings, private keys, and host-local home paths are blocked.
* Skill content is rendered as plain text, not raw HTML.
* Dashboard export is available only to a reviewer for a network-published skill.
* The browser bundle is constructed from an allowlist and omits network_id,
  skill_id, source_alias, user/node identifiers, content_hash from the private
  record, and review notes.
* Export downloads locally. It does not send content to anet.sh or another network.

Production rollout and UAT
==========================

Authorized merge and deployment completed on 2026-08-09 (Asia/Shanghai):

* Private Hub #596 -> main `6ad202de70e5df00eb2192dfd7988bb1f848890b`;
  deployed as `runtime-v28-skillhub-6ad202de` on port 9200.
* Private Dashboard #3 -> main `525b8c41aec12a14b5f1f8d50a08083e8cec5634`;
  deployed with `/skillhub` returning HTTP 200.
* Public-export Dashboard #4 -> main
  `5ac62da04ed98989695db31071a97bbabeb3d5a9`; deployed as
  `dashboard-runtime-skillhub-5ac62da0` on port 3001.
* Public catalog #597 -> main `f4eee0dd17c7f15bcd71f55cca698016ee14d18b`.
* Vercel-root fix #599 -> main `6870d76521c8722ebedc530dd8b565b577c04aaa`.
* Independently reviewed public skill #598 -> main
  `13f324d4e304e5b1884566c88ccbe72f75a98158`.

The first Vercel cloud build failed closed on the parent-directory script path.
After #599, a normal `vercel --prod --yes` cloud build from merged main passed;
no prebuilt workaround was used for the final deployment. The deployment was
aliased to `www.anet.sh`.

Live public UAT returned HTTP 200 for all four surfaces:

* `https://www.anet.sh/skillhub/`
* `https://www.anet.sh/en/skillhub/`
* `https://www.anet.sh/skillhub/catalog.json`
* `https://www.anet.sh/skillhub/skills/public-skill-review-checklist/1.0.0/SKILL.md`

The live catalog contained exactly two reviewed entries:
`public-skill-review-checklist@1.0.0` and `skill-writing-guide@1.0.0`.
For the production-promoted checklist, the private Hub content, public catalog
`content_sha256`, and downloaded SKILL.md bytes all matched:

  a009367849bc1c8d4f808c9bf7474f87b1432b4643651c402dbff0fca5863be1

The live catalog contained zero objects with private network, skill ID, source,
review, creator, or reviewer fields. This proves the intended sequence:
private submit -> private review/readback -> local allowlisted export -> public
pull request -> independent second review -> deterministic catalog -> public
detail/download. Private `published` status never triggered automatic Internet
publication.

Known limits and future gates
=============================

* The scanner is a defense-in-depth validator, not a universal secret detector.
  Public-repository review remains mandatory.
* Public direct submission/federation is intentionally absent. Adding it requires
  publisher identity, abuse controls, central moderation, immutable storage, and
  an audit log.
* Every future public skill still requires an explicit public-repository pull
  request and independent review; network publication alone is insufficient.
* Future schema changes must preserve the allowlisted export and must be tested
  against a docs-site-only Vercel project root.

Verdict
=======

Private SkillHub, Dashboard export, public catalog, clean Vercel deployment, and
production private-to-public UAT: PASS.
