diff --git a/.gitattributes b/.gitattributes index 6a613a7..1bad34c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6,3 +6,6 @@ reports/sdk-standard/2026-09-15-detection-selection/*.log -text -whitespace src/data/pp-detection-comparison.json -text # 实验归档保留原始 CRLF 和文件尾空行,校验其他行尾空格。 reports/rotated-detection/2026-09-18-feasibility/** -text whitespace=blank-at-eol,space-before-tab,cr-at-eol +reports/tracking/2026-09-19-foundation/** -text whitespace=blank-at-eol,space-before-tab,cr-at-eol +# 原始构建/测试日志保留工具输出的行尾空格和尾部空行。 +reports/tracking/2026-09-19-foundation/*.log -text -whitespace diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3418682..af17c3e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -5,11 +5,9 @@ on: workflow_dispatch: permissions: contents: read - pages: write - id-token: write concurrency: group: pages - cancel-in-progress: true + cancel-in-progress: false jobs: build: runs-on: ubuntu-latest @@ -24,6 +22,10 @@ jobs: - uses: actions/upload-pages-artifact@v3 with: { path: dist } deploy: + permissions: + contents: read + pages: write + id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} diff --git a/docs/superpowers/plans/2026-08-17-web-model-sdk-portal-roadmap.md b/docs/superpowers/plans/2026-08-17-web-model-sdk-portal-roadmap.md index b3a73e8..7ec12cc 100644 --- a/docs/superpowers/plans/2026-08-17-web-model-sdk-portal-roadmap.md +++ b/docs/superpowers/plans/2026-08-17-web-model-sdk-portal-roadmap.md @@ -14,7 +14,7 @@ readiness, not by the number of models mentioned in the catalog. TinyPose 0.3.0、PP-Segmentation 0.1.0 与 PP-RotatedDetection 0.1.0 已正式发布。分割以 PP-YOLOE_seg_s 640 FP32 提供单帧图片、原图框与二值 ROI 掩码;旋转框以 PP-YOLOE-R-s 1024 FP32 提供 DOTA 15 类和原图四点框。两者均完成双源、npm、Release 和 HTTPS Demo 回读;旋转框固定发布证据见[独立 SDK 回执](https://github.com/chenmohan123/web-sdk-PP-RotatedDetection/tree/b54ae15ca124fd111cac6e683409fdbb88a14e13/reports/2026-09-18-release)。门户已登记第七个 SDK,并保留各自桌面验证边界。 -旋转框首版已按可行性结论发布,当前不扩展切片、媒体、手机或 NPU 承诺。多目标跟踪已完成[固定参考可行性评估](../../../reports/tracking/2026-09-18-feasibility/README.md):五配置60组合成实跑和多实例状态诊断,首发候选为 ByteTrack 算法机制。低分恢复有效,同时保留交叉掉头身份交换、跨类复用、全局 ID 和时间间隔边界;根 MIT/Apache 与基础来源 GPL 的追溯差异尚需处置。下一阶段先完成来源/许可、无权重算法标准扩展和独立 API/实现设计,再验证真实序列与桌面浏览器。本轮没有建立生产 SDK、发布 npm 或分发上游代码,不把合成结果当作 MOT 精度或浏览器性能。分割精度变体和媒体扩展留待后续,Workflow 继续暂缓。 +旋转框首版已按可行性结论发布,当前不扩展切片、媒体、手机或 NPU 承诺。独立 `web-sdk-pp-tracking@0.1.0` 已完成 npm、GitHub Release、HTTPS Demo 和远程治理核验:采用纯算法标准 1.2.0、ByteTrack 高低分思想的数学独立实现、Apache-2.0、实例状态与 CPU/main API,双语 Demo 及 Vanilla/React 示例保持原边界。[前期参考评估](../../../reports/tracking/2026-09-18-feasibility/README.md)中的许可疑点保留为历史,本产品不复制或分发旧参考代码;[原本地验收和七 SDK 标准回归](../../../reports/tracking/2026-09-19-foundation/README.md)也不改写。2026-09-19 固定 MOT17 七段 FRCNN 训练序列 5316 帧已评测,默认 IDF1 48.2922%、IDSW 1101、MOTA 44.4010%,消融 IDF1 48.3465%、IDSW 1066;低分续接减少漏检但增加误检和切 ID,不是测试集排行榜或官方复现。门户第八个算法条目、CPU 分类和无权重详情已准备登记;当前生产站尚未包含第八条,须在门户 PR、合并及生产回读完成后关闭。手机与跨设备兼容仍未声明。分割精度变体与媒体扩展保留后续,Workflow 继续暂缓。 ## Current Baseline @@ -155,4 +155,4 @@ APIs remain separate Labs work and are not prerequisites for the MVP. ## Next Concrete Task -PP-Segmentation 与 PP-RotatedDetection 门户登记均已上线。跟踪固定参考评估已完成,下一阶段以 ByteTrack 算法机制为候选,处理来源/许可与无权重标准,设计独立 API、实例状态和时间策略后再进入 TS/真实序列/桌面浏览器验证;当前无跟踪生产 SDK。上方各 Phase 为历史总体路线;Workflow 实施仍暂缓,不因新增目录项或跟踪评估而启动。 +PP-Segmentation 与 PP-RotatedDetection 门户登记均已上线。PP-Tracking 0.1.0 的 npm、GitHub Release、HTTPS Demo 和远程治理已核验,固定 MOT17 训练序列评测及真实身份连续性限制保持不变;门户第八条算法记录已准备登记,当前生产站尚未包含该条目,后续完成门户 PR、合并与生产回读。390px 仅为桌面布局证据。上方各 Phase 保留为历史总体路线;Workflow 实施仍暂缓。 diff --git a/docs/superpowers/plans/2026-09-13-pp-detection-multi-model-roadmap.md b/docs/superpowers/plans/2026-09-13-pp-detection-multi-model-roadmap.md index d5dbe29..e150bc6 100644 --- a/docs/superpowers/plans/2026-09-13-pp-detection-multi-model-roadmap.md +++ b/docs/superpowers/plans/2026-09-13-pp-detection-multi-model-roadmap.md @@ -18,7 +18,7 @@ - **TinyPose:0.3.0 已发布。** 三个稳定变体,单帧/人体框 API,独立 Demo 支持图片、本地视频和摄像头。物理摄像头、手机及 NPU 的验证边界保持不变。 - **PP-Segmentation:0.1.0 已发布。** PP-YOLOE_seg_s 640 FP32,单帧 Blob/RGBA、原图框和独立二值 ROI 掩码。64图四模式严格质量验收通过,最小掩码IoU为0.9987084870848708;双源八组合、npm、GitHub Release和HTTPS Demo均已核验。原始官方裁边口径失败记录保留,最终采用原图整数尺寸独立参考。[固定发布记录](https://github.com/chenmohan123/web-sdk-PP-Segmentation/tree/89b350d30305ecbc275780e455d1c115a250570f/reports/2026-09-18-release-readiness)包含许可、双源、质量和交付回执。Trusted Publishing已配置,实际OIDC发布待下一次新版本验证。门户登记为第六个SDK。 - **PP-RotatedDetection:0.1.0 已发布。** PP-YOLOE-R-s 1024 FP32,单帧 Blob/RGBA、DOTA 15 类和原图四点框。双源 × WASM/WebGPU × 主线程/Worker、npm、GitHub Release 与 HTTPS Demo 均已核验;[固定发布记录](https://github.com/chenmohan123/web-sdk-PP-RotatedDetection/tree/b54ae15ca124fd111cac6e683409fdbb88a14e13/reports/2026-09-18-release)保留模型身份、数值和交付回执。门户登记为第七个 SDK;大图切片、媒体、手机与 NPU 不在当前验证范围。 -- **多目标跟踪:固定参考可行性评估完成,生产前置待办。** [60组合成实跑证据](../../../reports/tracking/2026-09-18-feasibility/README.md)覆盖官方 ByteTrack、OC-SORT 及 Paddle 两类跟踪实现;首发候选为 ByteTrack 算法机制。低分关联、短遮挡恢复已复现,同时保留掉头交叉身份交换、跨类 ID 复用、全局计数碰撞/去重及时间间隔边界。根 MIT/Apache 与基础来源 GPL 的追溯差异尚需处置;先完成来源/许可、无权重算法标准扩展与独立 API 设计,再进入 TS 和真实序列/桌面浏览器验证。本轮未建立 SDK、发布 npm 或上游代码,合成结果不是 MOT 基准,Workflow 继续暂缓。 +- **多目标跟踪:0.1.0 已发布,门户第八条准备登记。** npm、GitHub Release、HTTPS Demo 与远程治理已完成核验;SDK 采用纯算法标准 1.2.0、ByteTrack 高低分思想的独立数学实现、CPU/main、有状态 API、双语 Demo 及 Vanilla/React 示例,代码 Apache-2.0,不复制或分发旧参考实现。[前期评估](../../../reports/tracking/2026-09-18-feasibility/README.md)和[原本地验收](../../../reports/tracking/2026-09-19-foundation/README.md)保持历史原貌。固定 MOT17 七段 FRCNN 训练序列 5316 帧:默认 IDF1 48.2922%、IDSW 1101、MOTA 44.4010%、FP 4169、FN 57166;低分消融 IDF1 48.3465%、IDSW 1066,说明低分关联不是普遍精度提升。这不是测试集、官方 ByteTrack 排名或视频端到端速度。门户第八个纯算法条目已准备登记,当前生产站尚未包含该条目,须待门户 PR、合并和生产回读完成后关闭。移动设备及其他后端仍未验证,Workflow 继续暂缓。 ### 已完成:旋转框独立 SDK 可行性 @@ -32,7 +32,7 @@ PP-YOLOE-R-s 单尺度 FP32 已建立独立 SDK,完成四点坐标、原图还原、Blob/RGBA、浏览器预处理、显式 CPU/GPU、Worker、取消/释放、缓存、完整性校验、双源分发与正式发布。极端长宽比、平分排序与大图切片边界仍需另行验证;未经验证的能力不进入当前承诺。 -旋转框任务保持独立,不加入现有轴对齐 Detection API。分割 FP16/量化和媒体能力、HRNet 等姿态扩展保留后续;跟踪依据上述证据进入来源/许可、无权重标准与独立实现设计阶段,真实视频和浏览器尚未验证。继续桌面优先、模型 SDK 的 ModelScope 默认并保留 Hugging Face,以及独立 Demo 统一风格的要求;无权重算法不得伪造模型资产/缓存或 GPU 支持。手机复核按后续发布范围安排,Workflow 仍暂缓。 +旋转框任务保持独立,不加入现有轴对齐 Detection API。分割 FP16/量化和媒体能力、HRNet 等姿态扩展保留后续;跟踪已完成独立实现及固定 MOT17 训练序列评测,现为待远程核验的首次发布候选,精度与身份连续性限制按报告保留。继续桌面优先、模型 SDK 的 ModelScope 默认并保留 Hugging Face,以及独立 Demo 统一风格的要求;无权重算法不得伪造模型资产/缓存或 GPU 支持。390px 桌面视口不等同手机验证,Workflow 仍暂缓。 后文日期更早的“下一阶段”保留为历史实施记录,当前优先级以本节为准。 diff --git a/docs/superpowers/plans/2026-09-19-pp-tracking-first-release.md b/docs/superpowers/plans/2026-09-19-pp-tracking-first-release.md new file mode 100644 index 0000000..f61c0e3 --- /dev/null +++ b/docs/superpowers/plans/2026-09-19-pp-tracking-first-release.md @@ -0,0 +1,52 @@ +# PP-Tracking 首版发布实施计划 + +> **For agentic workers:** REQUIRED SUB-SKILL: 使用superpowers:subagent-driven-development执行本轮任务及独立审查。主代理负责远程发布,子代理不得再派代理。 + +**Goal:** 以真实序列证据发布独立PP-Tracking 0.1.0并登记门户。 +**Architecture:** 本地MOT17公开检测框进入现有SDK,固定TrackEval评分;SDK原子状态及CPU/main接口保持;门户增加算法目录类型,仅发布后登记。 +**Tech Stack:** TypeScript/Node、Python/TrackEval、Playwright、Astro、GitHub Actions、npm OIDC。 +**Spec:** `docs/superpowers/specs/2026-09-19-pp-tracking-release-design.md` + +## Global Constraints + +- SDK根 `F:/git/00_chenmohan/github/web-sdk-PP-Tracking`;门户根 `C:/Users/chenm/.codex/worktrees/segmentation-portal/chenmohan123.github.io`。原门户用户工作区不动。 +- 文档、回复、注释、提交中文,公开指南保留等价英文;手动编辑apply_patch,明确文件git add,禁git add .。 +- pnpm必须附 `--config.verify-deps-before-run=false --config.manage-package-manager-versions=false`。 +- 用户已确认真实评测及首次发布/门户登记,旧AGENTS本地限定在本次明确授权内失效;子代理只做本地,远程由主代理处理。 +- 不复制来源不明Kalman/SORT实现;TrackEval只作为离线MIT评分工具,不进生产依赖。 +- 原MOT检测/GT、逐轨输出、媒体放.tmp;公开来源哈希和汇总,无数据许可扩张。保留既有历史证据。 +- 每项完成有实测证据与审查;不重复未变化的大套测试。sdk:check前后报告写各任务不同路径。 + +### Task 1: 真实检测序列评测与复现 + +**Files:** SDK `scripts/evaluation/mot17/*`、`tests/mot17-adapter.test.*`、`reports/2026-09-19-mot17/*`、`docs/zh-CN/performance.md`、`docs/en/performance.md`、compatibility双语、NOTICE评测来源说明。 +**Interfaces:** 现有createTracker的TrackingFrame与TrackingResult;输入官方MOT17Labels.zip,七段FRCNN默认与低分消融;输出summary.json和双语解读,输入/输出/评分器完整摘要。 + +- [x] 固定数据包身份、官方训练用途和引用依据、TrackEval MIT源码commit与依赖;保留来源快照于.tmp及JSON摘要,拒绝错误hash。不得读旧Kalman源码。 +- [x] 用小型原创输入验证适配:MOT帧号/fps到timestamp、越界框裁剪和空框剔除、低分保留、observed+tracked导出、GT不进入SDK。示例断言:`expect(frame.timestampMs).toBe(1000 / fps); expect(result.detections[0].box.x).toBe(0)`;无效文件不得静默截断。 +- [x] 实现下载/适配/运行/评分的可复跑CLI,默认输出新.tmp目录,固定归档禁止覆盖;用官方MotChallenge2DBox预处理+Identity/CLEAR计算标准指标。评分器用原创完美匹配/换ID/漏检小fixture核对定义。 +- [x] 跑全部5316帧默认与low=high消融,记录每段及合计IDF1/IDSW/MOTA/FP/FN、运行耗时、容量、原始输出hash;确定性复核同输入同配置非timing输出相同。 +- [x] Chromium至少一完整真实序列非耗时输出对齐,记录具体版本/CPU/main/日期;不展示未经许可的媒体。 +- [x] 写真实失败模式和发布建议,运行新增相关测试+必要类型/构建以及前后checker;中文提交,给主代理报告。不做远程发布。 + +### Task 2: 发布候选与纯算法门户支持 + +**Files:** 门户 `standards/v1/portal-contract.md`、`src/lib/registry/{schema,types,labels,query}.ts`及相关测试、`src/pages/models/[slug].astro`、目录筛选、`src/content/models/pp-tracking.yaml`、`.github/workflows/deploy.yml`;SDK `AGENTS.md`、README双语、docs双语发布/兼容/性能指南、`sdk-manifest.yaml`、CHANGELOG、`.github/workflows/*`、Demo公开链接文案。 +**Interfaces:** 消费Task1已审查summary;门户kind互斥模型与算法,CPU后端、multi-object-tracking分类、algorithm元数据;PP-Tracking条目仅本地待发布验证,远程合并由主代理控制。 + +- [x] 先扩标准:模型继续要求assets非空;算法assets=[]且algorithm必填,不接收假模型权重。schema测试覆盖旧7模型、正确算法、缺来源/算法带权重拒绝、模型缺资产拒绝。示例:`expect(modelSchema.safeParse({...tracking, assets:[modelAsset]}).success).toBe(false)`。 +- [x] 实现目录/详情/筛选算法展示,CPU/JavaScript清楚,保留现有视觉令牌。单SDK详情不导入任何runtime。支持390px布局。 +- [x] 更新发布候选双语文档与Demo远程链接、真实评测限制、版本0.1.0;旧本地验收报告保持历史原样。AGENTS远程规则改成明确授权下可执行,不给未来无限授权。 +- [x] 发布工作流统一npm环境,先验证tag版本。支持首次手工npm已存在相同版本时安全核对并跳过重复发布,不能吞掉不一致或真正发布错误;未来版本走OIDC。Pages和CI最小权限,按实际线上/离线边界写说明。门户deploy.yml的pages/id-token写权限移至deploy job,concurrency.cancel-in-progress=false,以满足现行发布契约并保持原构建命令。 +- [x] 最终候选完整SDK verify一次;门户checker/相关tests/build与浏览器目录/详情/CPU过滤/390px,保存报告;更新两份路线至待发布候选。两仓分别提交,独立审查后交主代理。 + +### Task 3: 首次发布、线上核验与门户合并 + +**Files:** SDK `reports/2026-09-19-release/*`、双语发布清单;门户路线、发布证据与最终SDK条目。 +**Interfaces:** 已通过审查的SDK候选,GitHub仓库/main/Rulesets/v0.1.0、npm web-sdk-pp-tracking@0.1.0、Pages URL、Trusted Publisher仓库/release.yml/npm。 + +- [x] 主代理核验远程不存在冲突,创建SDK仓库,建立main基线并通过PR/CI引入审查候选;绑定并API回读默认分支与标签规则、npm/github-pages环境、Pages。 +- [x] 首次npm发布使用宿主登录;遇服务端要求本人安全验证时立即给当前有效链接并继续独立准备工作。不输出token/OTP,不重复已完成的登录。 +- [x] 配置 Trusted Publishing 并逐项核对 HTTP 201 保存响应(未独立 GET);发布不可变 v0.1.0 与 GitHub Release,验证 Actions、HTTPS Demo、npm dist/tarball 实际 API 消费,保存不含凭据的回执。 +- [ ] 仅公开链接及部署回读通过后推送门户PR,包含此前未合并算法标准基础和本轮算法目录,核对main差异/CI后合并;attach_artifact挂载全部PR。 +- [ ] 生产门户第八条、筛选/详情、Demo回放与中英文、远程治理通过;报告真实评测指标与范围,关闭计划并保留工作树/历史分支。 diff --git a/docs/superpowers/plans/2026-09-19-pp-tracking-foundation.md b/docs/superpowers/plans/2026-09-19-pp-tracking-foundation.md new file mode 100644 index 0000000..4bcd09a --- /dev/null +++ b/docs/superpowers/plans/2026-09-19-pp-tracking-foundation.md @@ -0,0 +1,91 @@ +# 独立 PP-Tracking SDK 首版实施计划 + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development 或 superpowers:executing-plans,按任务执行和审查。 + +**Goal:** 交付可本地使用和验证的独立跟踪SDK及统一风格Demo。 +**Architecture:** 先增加算法类标准,再用无依赖TypeScript实现两阶段关联和状态生命周期,React Demo消费同一公开API。 +**Tech Stack:** TypeScript 5.9、Vitest、Vite、React、Playwright、Python/NumPy参考。 +**Spec:** `docs/superpowers/specs/2026-09-19-pp-tracking-design.md` + +## Global Constraints + +- 门户根 `C:/Users/chenm/.codex/worktrees/segmentation-portal/chenmohan123.github.io`;SDK根 `F:/git/00_chenmohan/github/web-sdk-PP-Tracking`。 +- 文档、注释、提交中文;公开文档有等价英文。手动编辑用apply_patch;明确文件add,禁git add .。 +- pnpm始终加 `--config.verify-deps-before-run=false --config.manage-package-manager-versions=false`。 +- 规范源是门户standards/v1;不修改原门户工作目录,不嵌入检测SDK或虚构权重/GPU/Worker。 +- 生产runtime无依赖,Apache-2.0原创实现;不读/翻译上游Kalman/SORT源码实现算法。 +- 本轮本地实现及证据,不新增远程仓库/发布,不改npm身份配置。 +- 先标准后产品。每个任务遵守设计、只修改责任文件,独立验证提交;子代理不得派生子代理。 + +### Task 1: 纯算法标准与检查器 + +**Files:** standards/v1的README双语、schema、rules、runtime/demo/performance/docs契约、算法manifest模板和checklist;tools/sdk-standard-check的manifest/discover/rules和测试;skills/web-model-sdk-standard/references/scaffold.md。 +**Interfaces:** 生产1.2.0 `kind: algorithm` 与设计定义的algorithm字段;新DEMO-006状态复位、ALGORITHM-001规则;模型与算法分支互斥,旧清单兼容。 + +- [x] 加失败用例:有效算法、缺algorithm、带model/cache、旧版kind算法、伪造kind、缺算法timing、缺复位标记、旧模型缺assets仍失败。 +```ts +expect((await scanRepository(algorithmRoot)).findings.filter(x=>x.level==='required'&&x.status==='fail')).toEqual([]); +// 将算法清单schemaVersion改为1.1.0后必须有CONFIG-001,不能获得模型规则豁免。 +``` +- [x] 运行 `pnpm ... sdk:check:test` 确认新增回归会失败,再实现schema条件、适用规则、发现器和模板。不能让无效manifest跳过必需检查;skip需证据说明。 +- [x] 更新标准双语入口及对应契约,模型要求保留;算法cold/warm指新实例/复用状态,无模型耗时。 +- [x] 运行 `pnpm ... sdk:check:test`、`pnpm ... test`、`pnpm ... build`;提交 `扩展纯算法SDK标准并保持模型契约兼容`。 + +### Task 2: 独立跟踪核心与来源证据 + +**Files:** SDK新建AGENTS.md、package.json、tsconfig/vitest、scripts/build.mjs及check-package.mjs、src/{types,errors,kalman,assignment,tracker,index}.ts、tests/*.test.ts、tests/fixtures/math-reference.json及生成脚本、LICENSE、NOTICE、docs/zh-CN/algorithm.md与docs/en/algorithm.md。 +**Interfaces:** createTracker/update/reset/dispose和全部字段/默认值严格依设计;runtime={requestedBackend:'cpu',actualBackend:'cpu',executionMode:'main',runtimeVersion:'web-sdk-pp-tracking@0.1.0'};timings五项。 + +- [x] SDK空目录先运行门户 `pnpm ... sdk:check -- --repo --format json --out reports/sdk-standard/pp-tracking-before.json`,保留预期缺失。 +- [x] 初始化 `codex/tracking-foundation` 本地Git,先写数学/匹配/生命周期失败测试;不复制其他SDK的runtime。 +```ts +const a=createTracker({minHits:1}), b=createTracker({minHits:1}); +const frame={timestampMs:0,imageSize:{width:640,height:480},detections:[{box:{x:20,y:20,width:40,height:80},score:0.9,classId:0}]}; +expect(a.update(frame).tracks[0].id).toBe(1); +expect(b.update(frame).tracks[0].id).toBe(1); +expect(()=>a.update(frame)).toThrow(); +a.reset(); expect(a.update(frame).generation).toBe(1); +``` +- [x] 实现8维Kalman,文档定义F、H、P/Q/R与dt,使用小型矩阵运算/Joseph covariance保证数值;独立Python/NumPy参考至少预测、连续更新、不同dt。 +- [x] 实现确定性门限内全局分配(匈牙利或等价),低分不新建、类别隔离、tentative/tracked/lost/removed、时间上限/数目上限;校验和计算事务性提交,dispose幂等。 +- [x] 补充非法输入/配置、引用隔离、capacity、big-gap、score边界、lost不可低分复活、贪心反例、门限反例测试。跟踪ID只在该实例,移除事件只返回一次。 +- [x] 运行 `pnpm ... test`、`typecheck`、`build`、`check:package`;记录源码基础/限制和npm pack实际内容;提交核心。 + +### Task 3: 独立Demo、双语文档、示例及发布脚本 + +**Files:** SDK demo/{index.html,vite.config.ts,ui-tokens.json,src/*}、examples/vanilla与examples/react、README双语、docs双语六组指南、sdk-manifest.yaml、CHANGELOG、.github/workflows/{ci,pages,release}.yml、tests/browser.mjs及Demo数据测试。 +**Interfaces:** 消费Task2实际公开API,不改核心契约;manifest按Task1模板。Demo输入JSON={frames:TrackingFrame[]};文件5MiB、帧数3000、每帧100框上限。 + +- [x] 阅读旋转Demo和PP-Detection样式文件作为布局参考,复用门户ui-tokens,不复制推理;实现原创合成序列与schema完整导入校验。 +```ts +// 导入失败保留现有序列与结果;回放每步使用frame.timestampMs,seek先reset再顺序推进。 +// 当前状态显示CPU / JavaScript / Main;丢失轨迹虚线,无权重/缓存/后端选择器。 +``` +- [x] 实现品牌栏、紧凑控制、SVG结果/轨迹、播放暂停单步重播、文件导入、结果JSON下载、语言切换;结果优先显示,详情折叠,390px可用。 +- [x] 从标准模板创建manifest/README/checklist,文档明确低分检测保留、seek/reset和ID非身份;全部未发布链接标记为计划地址,安装使用本地包方式,不声称npm已存在。 +- [x] Vanilla示例真正调用构建包API,React引用Demo,构建两者;CI测试类型和打包及浏览器,Pages使用官方actions和最小权限;release要求先通过验证后以OIDC发布,首次发布尚待授权。 +- [x] 浏览器自动覆盖中文/英文、单步/播放暂停/重播、低分/遮挡、导入成功失败、导出、无横向滚动、Vanilla;运行unit、typecheck:demo、build:demo、test:browser及sdk:check;提交完整Demo与文档。 + +### Task 4: 桌面验收证据与交付复核 + +**Files:** SDK scripts/evaluation/*、reports/2026-09-19-desktop/*、docs兼容/性能指南、manifest.verification;门户reports/sdk-standard/pp-tracking-after.json与计划验收记录,以及docs/superpowers/plans/2026-09-13-pp-detection-multi-model-roadmap.md、2026-08-17-web-model-sdk-portal-roadmap.md中的当前跟踪进度。 +**Interfaces:** 消费已完成SDK,不能用静态声明替代运行;证据区分机制正确性和浏览器性能,无移动端/MOT精度承诺。 + +- [x] 可复现合成序列性能测量至少10、50、100框,注明浏览器/OS/CPU/日期及样本数、p50/p95;包含cold创建与warm更新,固定输入可重跑,无绝对性能断言。 +- [x] 记录真实浏览器主线程运行、两种语言、390px、Vanilla及导入导出,保留机器可读摘要和命令。截图放忽略目录,报告只列路径。 +- [x] 校验npm pack、无runtime依赖和源码来源;运行全部SDK tests/typechecks/builds/browser与门户sdk:check/tests/build。 +- [x] 更新verification只填实际测试的浏览器版本和设备,sdk:check远程skip如实保留;记录发布尚未执行及真实视频质量未测。 +- [x] 同步两份总路线的当前状态为实际完成的本地SDK/桌面证据,保留旧阶段历史说明,不把尚未发布的Tracking登记为可用门户条目;归档主代理的7个现有SDK新旧标准检查差异报告。 +- [x] 提交证据和兼容说明,独立整分支审查后交付本地Demo及可审查代码。 + +## 本地交付记录(2026-09-19) + +四个任务及独立整分支审查已完成,SDK审查提交 `96f32f0`,门户审查提交 `72ca1e5`。 +核心与Demo的完整验证、归档保护修复及标准回归见[验收报告](../../../reports/tracking/2026-09-19-foundation/README.md); +最终审查为0项严重、0项重要、1项轻微,详见[审查记录](../../../reports/tracking/2026-09-19-foundation/final-review.md)。 +轻微项为静态DOM标记的后缀误匹配,当前真实Demo不受影响,留后续检查器修补。 + +本地Demo为 `http://127.0.0.1:4196/`,可用 `npm run dev:demo` 在SDK目录重新启动。 +保留 `codex/tracking-foundation` 和 `codex/tracking-sdk-foundation` 本地分支。 +npm、Release、在线Demo与远程治理尚未发布或核验,真实授权视频MOT质量尚未测量; +Workflow继续暂缓,不登记未发布的第8个在线SDK。 diff --git a/docs/superpowers/specs/2026-09-19-pp-tracking-design.md b/docs/superpowers/specs/2026-09-19-pp-tracking-design.md new file mode 100644 index 0000000..b7aa7ab --- /dev/null +++ b/docs/superpowers/specs/2026-09-19-pp-tracking-design.md @@ -0,0 +1,99 @@ +# 独立 PP-Tracking SDK 首版设计 + +日期:2026-09-19。依据用户已确认的独立 SDK 路线及继续推进指令。 + +## 范围与来源 + +实现 `web-sdk-pp-tracking`,仓库目录 `F:/git/00_chenmohan/github/web-sdk-PP-Tracking`。 +这是单 SDK 工作;门户仅扩展标准,不连接检测 SDK、不新增 Workflow。 +首版为 TypeScript CPU 主线程算法,无模型、无推理依赖、无下载或缓存按钮。 +Worker 留待实测有必要时增加,首版只声明 `main`,不提供空实现。 + +采用 ByteTrack 论文的高/低分两阶段关联思想,独立编写恒速 Kalman、 +带未匹配选项的最小代价分配及状态机。不得翻译或复制前次评估发现来源 +义务不清晰的 ByteTrack/DeepSORT/Paddle Kalman 或 SORT/OC-SORT 实现。 +生产代码依据数学定义、论文机制和本设计编写,Apache-2.0 仅声明本项目 +代码许可;NOTICE 记录论文、算法差异和评估来源,不声称官方移植或逐值兼容。 +来源评估见 `reports/tracking/2026-09-18-feasibility/README.md`。 + +## API 和状态 + +公开 `createTracker(options?)`,返回 `update(frame, { signal }?)`、 +`reset()`、`dispose()`;更新同步,AbortSignal 只能在计算开始前取消。 +输入 `TrackingFrame` 为 `timestampMs`、`imageSize: {width,height}` 和 +`detections: {box:{x,y,width,height},score,classId}[]`。坐标为图像像素的 +轴对齐框;类别为非负安全整数,分数在 [0,1],尺寸正且所有数值有限。 +框须在图像范围内;不自动裁剪。时间戳为非负有限数,严格递增;seek +或图像尺寸变化必须 reset。所有校验在状态修改前完成,失败不得推进时钟或 ID。 + +结果返回 `generation`、`timestampMs`、`tracks`、`removed`、`runtime`、 +`timings`。轨迹含 `id`、`classId`、`box`、`state`、`observed`、 +`score: number|null`、`ageMs`、`hits`、`missedMs`;状态为 tentative、 +tracked、lost。`removed` 为仅本次移除的轨迹,state=removed。 +预测轨迹 `observed=false, score=null`,不得把历史置信度当成本帧检测。 +ID 为实例私有安全整数,同代次内不复用;reset 后代次+1,ID从1重新开始。 +不同实例互不影响;dispose 幂等,此后 update/reset 抛稳定错误。 +返回对象和输入对象均不与内部可变状态共享。 + +默认阈值:lowScoreThreshold=0.1、highScoreThreshold=0.5、 +newTrackThreshold=0.6;high>=low且new>=high。默认 minHits=2, +matchIouThreshold=0.3、lowMatchIouThreshold=0.2、maxLostMs=1000、 +largeGapMs=2000、maxDetections=100、maxTracks=200。 +数量上限为正安全整数且不超过500;minHits为1至100的整数。 +时间限制须为有限正数,largeGapMs>=maxLostMs。 + +所有阶段严格隔离类别。先用 tracked/lost 与高分框关联,再用未匹配的 +tracked 与低分框关联;lost 不以低分框恢复。再将 tentative 与剩余高分框 +关联;未匹配 tentative 当帧移除。剩余高分框达到 new 阈值时创建 tentative, +连续命中达到 minHits 后 tracked(minHits=1立即 tracked)。 +无匹配 tracked 转 lost;lost 超过 maxLostMs 在匹配前移除。单次时间间隔 +超过 largeGapMs 时先移除旧轨迹再处理新观测;不通过补空帧循环推进。 +容量满时跳过新建,结果报告 `droppedDetections`,不得驱逐有效轨迹。 +关联必须是确定性的全局最小代价匹配,门限内才可匹配,允许双方未匹配。 +测试须覆盖贪心错误和先全局分配再过滤导致有效匹配丢失的反例。 + +运动状态为 [cx,cy,w,h,vx,vy,vw,vh],dt以秒计。独立实现标准线性 +Kalman predict/update,协方差初值、过程和观测噪声须写入算法文档。 +输出宽高保持正数,数值失败以稳定错误报告,不污染已提交状态。 +不做外观 ReID、不保证交叉或掉头时身份正确,不把轨迹 ID 当真实身份。 + +## 标准扩展 + +规范升至1.2.0,继续接受1.0.0/1.1.0模型manifest。 +新增仅1.2.0可用的 `kind: algorithm`;缺省及 `kind: model` 保持模型规则。 +算法manifest必须有 algorithm(id、version、family、source、license、 +input、output、stateful),禁止 model/cache 字段;模型禁止 algorithm。 +旧版本不得借kind逃避模型检查。runtime继续报告实际后端与执行模式。 +算法性能要求 validationMs、predictionMs、associationMs、updateMs、totalMs; +不要求模型下载或缓存耗时。Demo使用 data-sdk-algorithm-info 和 +data-sdk-state-reset,保留runtime/timing标记。规则应明确模型/算法适用性, +不适用项以skip及理由记录;无效清单不得触发算法豁免。 +算法输入、来源、许可、状态生命周期和复位为必填契约。 + +## Demo 和文档 + +延续 PP-Detection:浅色背景、紧凑品牌栏、左侧输入/参数控制、右侧可视化 +结果、耗时和运行信息折叠;中文默认、可切英文,390px无横向滚动。 +提供原创合成检测框序列(直行、低分恢复、短遮挡、交叉掉头),SVG绘制 +框和ID/轨迹,播放、暂停、单步、重新开始、JSON导入、导出本轮结果。 +导入只读本地文件,限制5MiB、3000帧、每帧100框;完整验证后原子替换。 +选择示例、重播、seek均reset。播放用记录的timestamp,与浏览器帧率分离。 +输入和预测视觉可区分,切语言不清空状态。呈现算法限制,但不塞入操作长文。 +不做模型目录、检测/摄像头前置流程;不伪装真实视频测评。 + +双语README及quick-start、API、compatibility、troubleshooting、 +privacy/deployment、performance;Vanilla可运行示例及React Demo参考。 +打包只包括构建产物、类型、README、LICENSE、NOTICE,无React运行依赖。 +提供CI、Pages与发布workflow,但本轮本地实现不声称npm或Demo已经发布。 + +## 验收 + +先扩标准再实现产品。创建空SDK目录即运行sdk:check,保留before/after报告。 +单测覆盖数学参考、全局关联、低分恢复、遮挡/超时、类别隔离、实例隔离、 +reset/dispose、无效输入原子性、输出引用隔离、阈值边界和数量上限。 +用独立 NumPy 公式参考核对数值;可用先前机制输入评估行为差异,不能把 +官方输出逐值相等设为目标。真实序列暂未有明确授权样本,首版如实只报告 +合成机制验证,不声称MOT精度。桌面Chromium验证Demo、Vanilla、导入导出、 +中英文、空态、重播和390px布局,记录版本/日期/操作/限制。 +执行typecheck、test、build、check:package、build:demo、浏览器测试及门户 +checker/tests/build。交付本地可审查版本;远程发布须有明确发布范围。 diff --git a/docs/superpowers/specs/2026-09-19-pp-tracking-release-design.md b/docs/superpowers/specs/2026-09-19-pp-tracking-release-design.md new file mode 100644 index 0000000..7b4d724 --- /dev/null +++ b/docs/superpowers/specs/2026-09-19-pp-tracking-release-design.md @@ -0,0 +1,31 @@ +# PP-Tracking 真实序列评测与首版发布设计 + +用户已确认本轮顺序:真实视频序列评测、处理影响使用的问题、发布0.1.0、门户登记第八个SDK。授权包含GitHub仓库/PR合并、npm、Release、HTTPS Demo与Trusted Publishing;服务端要求的本人验证仍由用户完成。 + +## 范围与工作区 + +SDK:`F:/git/00_chenmohan/github/web-sdk-PP-Tracking`,当前8d4a554;门户沿用隔离工作树 `C:/Users/chenm/.codex/worktrees/segmentation-portal/chenmohan123.github.io`,当前4d79c02。保留原门户用户文件和旧分支;本轮建立codex/tracking-first-release本地分支。SDK独立消费检测框,不接入Detection运行时,不创建Workflow。门户只登记元数据。 + +## 真实序列与评测口径 + +采用MOT17官方无图像压缩包 `https://motchallenge.net/data/MOT17Labels.zip`,10107022字节,SHA256 `0aa79322e91583369f42f17c4d79a0b145380d8732487bba59272048dc82b2b9`。固定七段FRCNN训练序列02/04/05/09/10/11/13,共5316帧;不按结果挑选片段,不下载或发布视频图片。 + +官方原数据页提供公开下载,FAQ明确允许在训练集比较算法设置并要求引用MOT16和相应序列论文。当前站点已静态归档,保留实际页面及可读历史FAQ的URL、检索日期与摘要。未找到覆盖全部素材的统一再分发许可时,不杜撰CC许可证或把数据归入Apache-2.0;仅在本地按公开基准用途评测,公开代码、来源/文件哈希和汇总指标,原检测框、GT及逐轨输出保留忽略目录。若此依据不足以覆盖选中数据的评测用途,先解决来源问题或替换有明确评测授权的数据。 + +固定默认参数运行,不用这些训练序列调参。另做lowScoreThreshold=highScoreThreshold的机制消融,其他参数相同;这是同实现的消融对照,不是官方ByteTrack精度排名。MOT时间按seqinfo原fps,像素坐标通过明确的MOT转SDK适配,越界检测框裁到图像内、空框剔除并统计;GT按官方评分处理,不能用GT选择输入。每帧只将observed且state=tracked的结果写MOT输出,预测lost与未确认tentative不充当检测。 + +用固定提交的MIT TrackEval官方MOTChallenge预处理和Identity/CLEAR指标,记录IDF1、IDSW、MOTA、FP/FN、每序列及合计,不用自造ID变化计数冒充IDSW。记录SDK/输入/评分器hash、固定参数、执行环境、CPU时间、最大输入/轨迹数和容量丢弃数。原始数据、输出及评分日志可本地复跑,汇总报告不得声称MOT17测试集/排行榜成绩或完整端到端速度。至少一个完整真实序列再在桌面Chromium运行,核对与Node非耗时输出相同。 + +发布门槛:全帧无异常、无非有限框/重复ID/容量丢弃,来源/评分定义明确,真实问题与限制记录完整;指标只代表固定公开检测器和这些训练序列,不设事后挑选的准确率门槛或宣称高精度。发现功能错误则定向修复并复测相关证据;真实交叉/机位运动等固有限制如实记录。 + +## 发布及门户 + +SDK保持0.1.0,更新双语指南、Demo链接、CHANGELOG、验证环境和发布清单,保留原合成测量历史。发布工作流先验证tag与包版本,再验证/构建/发布;首次npm引导发布和后续OIDC不能重复发布同版本。Trusted Publisher固定仓库 `chenmohan123/web-sdk-PP-Tracking`、`release.yml`、`npm`环境;首版是否具备provenance以实际回执为准。 + +GitHub仓库公开,默认main,PR与最新CI门禁、会话解决、防强推/删分支、v*不可变标签、无常驻管理员bypass;Pages Actions+HTTPS,部署只给必要权限、串行且绑定提交。本机gh复用APPDATA/GitHub CLI并恢复原GH_CONFIG_DIR。npm本人验证只通过安全页面,不索取验证码或密码。 + +门户先在standards/v1/portal-contract.md补充算法目录契约,再修改registry schema/UI:缺省kind保持model,算法kind=algorithm,task=multi-object-tracking,CPU/JavaScript真实后端,assets空数组且algorithm来源/版本/家族/状态字段必填;模型仍要求非空assets,不得伪造0字节ONNX。展示算法信息与无需权重状态;目录筛选/详情/比较不复制runtime。PP-Tracking公开链接核验通过后才合并正式条目。 + +## 验证与交付 + +SDK修改前后sdk:check;新的数据适配/评分边界使用有意义的定向测试,完整SDK verify在最终发布候选上执行一次。门户schema/查询/详情/列表测试及生产构建浏览器回归,保留七SDK兼容。发布前独立代码审查;发布后GitHub/npm/HTTPS Demo及治理API回读,线上Demo中英文与回放冒烟,npm tarball实际消费验证。完成后同步规划与日期化证据;仅遇到本人安全验证或真实外部阻塞才请求用户参与。 diff --git a/reports/sdk-standard/pp-tracking-2026-09-19-release-after.json b/reports/sdk-standard/pp-tracking-2026-09-19-release-after.json new file mode 100644 index 0000000..3e63971 --- /dev/null +++ b/reports/sdk-standard/pp-tracking-2026-09-19-release-after.json @@ -0,0 +1,269 @@ +{ + "standardVersion": "1.2.0", + "repositories": [ + { + "standardVersion": "1.2.0", + "repository": "web-sdk-PP-Tracking", + "summary": { + "requiredPassed": 17, + "requiredFailed": 0, + "requiredSkipped": 7, + "requiredUnknown": 0, + "requiredNotApplicable": 0, + "recommendedPassed": 3, + "recommendedFailed": 0, + "labs": 1, + "status": "locally-compliant" + }, + "findings": [ + { + "id": "ALGORITHM-001", + "level": "required", + "status": "pass", + "message": "算法清单声明身份、家族、来源、许可、输入输出与有状态语义", + "remediation": "按 sdk-manifest.algorithm.yaml 填写 algorithm 字段并记录状态生命周期。", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "skip", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 algorithm,本规则仅适用于 model;清单已通过完整校验。" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "demo/index.html", + "evidence": "demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "demo/index.html", + "evidence": "demo/index.html, demo/src/App.tsx, examples/vanilla/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "skip", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 algorithm,本规则仅适用于 model;清单已通过完整校验。" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo 展示当前模型或算法的信息、运行信息和耗时", + "remediation": "模型使用 data-sdk-model-info,算法使用 data-sdk-algorithm-info;两者保留 data-sdk-runtime-info 和 data-sdk-timing。", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx" + }, + { + "id": "DEMO-006", + "level": "required", + "status": "pass", + "message": "算法 Demo 提供状态复位操作", + "remediation": "使用 data-sdk-state-reset 标记复位控件,并按状态生命周期契约连接 reset。", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx" + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla/README.en.md", + "evidence": "examples/vanilla/README.en.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.en.md", + "evidence": "examples/react/README.en.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla/README.en.md", + "evidence": "examples/vanilla/README.en.md, examples/react/README.en.md" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + }, + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "skip", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 algorithm,本规则仅适用于 model;清单已通过完整校验。" + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "声明当前 SDK 类型所需的标准耗时字段", + "remediation": "模型保留下载、缓存、校验、会话、推理和总耗时;算法声明 validationMs、predictionMs、associationMs、updateMs、totalMs。", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + } + ] + } + ] +} diff --git a/reports/sdk-standard/pp-tracking-2026-09-19-release-before.json b/reports/sdk-standard/pp-tracking-2026-09-19-release-before.json new file mode 100644 index 0000000..3e63971 --- /dev/null +++ b/reports/sdk-standard/pp-tracking-2026-09-19-release-before.json @@ -0,0 +1,269 @@ +{ + "standardVersion": "1.2.0", + "repositories": [ + { + "standardVersion": "1.2.0", + "repository": "web-sdk-PP-Tracking", + "summary": { + "requiredPassed": 17, + "requiredFailed": 0, + "requiredSkipped": 7, + "requiredUnknown": 0, + "requiredNotApplicable": 0, + "recommendedPassed": 3, + "recommendedFailed": 0, + "labs": 1, + "status": "locally-compliant" + }, + "findings": [ + { + "id": "ALGORITHM-001", + "level": "required", + "status": "pass", + "message": "算法清单声明身份、家族、来源、许可、输入输出与有状态语义", + "remediation": "按 sdk-manifest.algorithm.yaml 填写 algorithm 字段并记录状态生命周期。", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "skip", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 algorithm,本规则仅适用于 model;清单已通过完整校验。" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "demo/index.html", + "evidence": "demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "demo/index.html", + "evidence": "demo/index.html, demo/src/App.tsx, examples/vanilla/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "skip", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 algorithm,本规则仅适用于 model;清单已通过完整校验。" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo 展示当前模型或算法的信息、运行信息和耗时", + "remediation": "模型使用 data-sdk-model-info,算法使用 data-sdk-algorithm-info;两者保留 data-sdk-runtime-info 和 data-sdk-timing。", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx" + }, + { + "id": "DEMO-006", + "level": "required", + "status": "pass", + "message": "算法 Demo 提供状态复位操作", + "remediation": "使用 data-sdk-state-reset 标记复位控件,并按状态生命周期契约连接 reset。", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx" + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla/README.en.md", + "evidence": "examples/vanilla/README.en.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.en.md", + "evidence": "examples/react/README.en.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla/README.en.md", + "evidence": "examples/vanilla/README.en.md, examples/react/README.en.md" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + }, + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "skip", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 algorithm,本规则仅适用于 model;清单已通过完整校验。" + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "声明当前 SDK 类型所需的标准耗时字段", + "remediation": "模型保留下载、缓存、校验、会话、推理和总耗时;算法声明 validationMs、predictionMs、associationMs、updateMs、totalMs。", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + } + ] + } + ] +} diff --git a/reports/sdk-standard/pp-tracking-after.json b/reports/sdk-standard/pp-tracking-after.json new file mode 100644 index 0000000..3e63971 --- /dev/null +++ b/reports/sdk-standard/pp-tracking-after.json @@ -0,0 +1,269 @@ +{ + "standardVersion": "1.2.0", + "repositories": [ + { + "standardVersion": "1.2.0", + "repository": "web-sdk-PP-Tracking", + "summary": { + "requiredPassed": 17, + "requiredFailed": 0, + "requiredSkipped": 7, + "requiredUnknown": 0, + "requiredNotApplicable": 0, + "recommendedPassed": 3, + "recommendedFailed": 0, + "labs": 1, + "status": "locally-compliant" + }, + "findings": [ + { + "id": "ALGORITHM-001", + "level": "required", + "status": "pass", + "message": "算法清单声明身份、家族、来源、许可、输入输出与有状态语义", + "remediation": "按 sdk-manifest.algorithm.yaml 填写 algorithm 字段并记录状态生命周期。", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "skip", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 algorithm,本规则仅适用于 model;清单已通过完整校验。" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "demo/index.html", + "evidence": "demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "demo/index.html", + "evidence": "demo/index.html, demo/src/App.tsx, examples/vanilla/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "skip", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 algorithm,本规则仅适用于 model;清单已通过完整校验。" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo 展示当前模型或算法的信息、运行信息和耗时", + "remediation": "模型使用 data-sdk-model-info,算法使用 data-sdk-algorithm-info;两者保留 data-sdk-runtime-info 和 data-sdk-timing。", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx" + }, + { + "id": "DEMO-006", + "level": "required", + "status": "pass", + "message": "算法 Demo 提供状态复位操作", + "remediation": "使用 data-sdk-state-reset 标记复位控件,并按状态生命周期契约连接 reset。", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx" + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla/README.en.md", + "evidence": "examples/vanilla/README.en.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.en.md", + "evidence": "examples/react/README.en.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla/README.en.md", + "evidence": "examples/vanilla/README.en.md, examples/react/README.en.md" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + }, + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "skip", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 algorithm,本规则仅适用于 model;清单已通过完整校验。" + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "声明当前 SDK 类型所需的标准耗时字段", + "remediation": "模型保留下载、缓存、校验、会话、推理和总耗时;算法声明 validationMs、predictionMs、associationMs、updateMs、totalMs。", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + } + ] + } + ] +} diff --git a/reports/sdk-standard/pp-tracking-before.json b/reports/sdk-standard/pp-tracking-before.json new file mode 100644 index 0000000..0247385 --- /dev/null +++ b/reports/sdk-standard/pp-tracking-before.json @@ -0,0 +1,225 @@ +{ + "standardVersion": "1.2.0", + "repositories": [ + { + "standardVersion": "1.2.0", + "repository": "web-sdk-PP-Tracking", + "summary": { + "requiredPassed": 0, + "requiredFailed": 18, + "requiredSkipped": 6, + "requiredUnknown": 0, + "requiredNotApplicable": 0, + "recommendedPassed": 0, + "recommendedFailed": 3, + "labs": 1, + "status": "partial" + }, + "findings": [ + { + "id": "ALGORITHM-001", + "level": "required", + "status": "skip", + "message": "算法清单声明身份、家族、来源、许可、输入输出与有状态语义", + "remediation": "按 sdk-manifest.algorithm.yaml 填写 algorithm 字段并记录状态生命周期。", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;未声明清单,沿用旧版模型检查,不豁免模型规则。" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "fail", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo." + }, + { + "id": "DEMO-001", + "level": "required", + "status": "fail", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command." + }, + { + "id": "DEMO-002", + "level": "required", + "status": "fail", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN." + }, + { + "id": "DEMO-003", + "level": "required", + "status": "fail", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state." + }, + { + "id": "DEMO-004", + "level": "required", + "status": "fail", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API." + }, + { + "id": "DEMO-005", + "level": "required", + "status": "fail", + "message": "Demo 展示当前模型或算法的信息、运行信息和耗时", + "remediation": "模型使用 data-sdk-model-info,算法使用 data-sdk-algorithm-info;两者保留 data-sdk-runtime-info 和 data-sdk-timing。" + }, + { + "id": "DEMO-006", + "level": "required", + "status": "skip", + "message": "算法 Demo 提供状态复位操作", + "remediation": "使用 data-sdk-state-reset 标记复位控件,并按状态生命周期契约连接 reset。", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;未声明清单,沿用旧版模型检查,不豁免模型规则。" + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DOC-001", + "level": "required", + "status": "fail", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links." + }, + { + "id": "DOC-002", + "level": "required", + "status": "fail", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance." + }, + { + "id": "DOC-003", + "level": "required", + "status": "fail", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest." + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "fail", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README." + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "fail", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception." + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "fail", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces." + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + }, + { + "id": "META-001", + "level": "required", + "status": "fail", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field." + }, + { + "id": "META-002", + "level": "required", + "status": "fail", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata." + }, + { + "id": "MODEL-001", + "level": "required", + "status": "fail", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PERF-001", + "level": "required", + "status": "fail", + "message": "声明当前 SDK 类型所需的标准耗时字段", + "remediation": "模型保留下载、缓存、校验、会话、推理和总耗时;算法声明 validationMs、predictionMs、associationMs、updateMs、totalMs。" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "fail", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build." + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "fail", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes." + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "fail", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry." + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "fail", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "fail", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors." + } + ] + } + ] +} diff --git a/reports/sdk-standard/pp-tracking-core-after.json b/reports/sdk-standard/pp-tracking-core-after.json new file mode 100644 index 0000000..36ea561 --- /dev/null +++ b/reports/sdk-standard/pp-tracking-core-after.json @@ -0,0 +1,248 @@ +{ + "standardVersion": "1.2.0", + "repositories": [ + { + "standardVersion": "1.2.0", + "repository": "web-sdk-PP-Tracking", + "summary": { + "requiredPassed": 2, + "requiredFailed": 16, + "requiredSkipped": 6, + "requiredUnknown": 0, + "requiredNotApplicable": 0, + "recommendedPassed": 0, + "recommendedFailed": 3, + "labs": 1, + "status": "partial" + }, + "findings": [ + { + "id": "ALGORITHM-001", + "level": "required", + "status": "skip", + "message": "算法清单声明身份、家族、来源、许可、输入输出与有状态语义", + "remediation": "按 sdk-manifest.algorithm.yaml 填写 algorithm 字段并记录状态生命周期。", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;未声明清单,沿用旧版模型检查,不豁免模型规则。" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "fail", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "AGENTS.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "fail", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "AGENTS.md" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "fail", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "AGENTS.md" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "fail", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "AGENTS.md" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "fail", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": "AGENTS.md" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "fail", + "message": "Demo 展示当前模型或算法的信息、运行信息和耗时", + "remediation": "模型使用 data-sdk-model-info,算法使用 data-sdk-algorithm-info;两者保留 data-sdk-runtime-info 和 data-sdk-timing。", + "path": "AGENTS.md" + }, + { + "id": "DEMO-006", + "level": "required", + "status": "skip", + "message": "算法 Demo 提供状态复位操作", + "remediation": "使用 data-sdk-state-reset 标记复位控件,并按状态生命周期契约连接 reset。", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;未声明清单,沿用旧版模型检查,不豁免模型规则。" + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DOC-001", + "level": "required", + "status": "fail", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": "AGENTS.md" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": "AGENTS.md", + "evidence": "AGENTS.md" + }, + { + "id": "DOC-003", + "level": "required", + "status": "fail", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "AGENTS.md" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "fail", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "AGENTS.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "fail", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "AGENTS.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "fail", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "AGENTS.md" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + }, + { + "id": "META-001", + "level": "required", + "status": "fail", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": "AGENTS.md" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": "AGENTS.md", + "evidence": "AGENTS.md" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "fail", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "AGENTS.md" + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PERF-001", + "level": "required", + "status": "fail", + "message": "声明当前 SDK 类型所需的标准耗时字段", + "remediation": "模型保留下载、缓存、校验、会话、推理和总耗时;算法声明 validationMs、predictionMs、associationMs、updateMs、totalMs。", + "path": "AGENTS.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "fail", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": "AGENTS.md" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "fail", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": "AGENTS.md" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "fail", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": "AGENTS.md" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "fail", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "AGENTS.md" + }, + { + "id": "UI-001", + "level": "recommended", + "status": "fail", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "AGENTS.md" + } + ] + } + ] +} diff --git a/reports/tracking/2026-09-19-foundation/README.md b/reports/tracking/2026-09-19-foundation/README.md new file mode 100644 index 0000000..79e6364 --- /dev/null +++ b/reports/tracking/2026-09-19-foundation/README.md @@ -0,0 +1,46 @@ +# 独立跟踪SDK本地验收与标准回归(2026-09-19) + +本轮完成纯算法标准1.2.0及独立 `web-sdk-PP-Tracking` 本地首版。SDK仍未发布npm、Release或在线Demo,因此门户在线目录继续保留7个已发布SDK,Workflow继续暂缓。本目录只归档标准兼容与门户回归证据,不包含跟踪运行时。 + +## 7个既有SDK的新旧标准差异 + +[原始报告](standard-regression.json)于2026-09-19T00:32:22.867Z生成,原字节保留每条规则的级别、状态、证据和修复建议。旧标准提交 `df2863ec22e73790f35fcf57c673a55afd4a1be0`,新标准/检查器提交 `063e8c215b1791d43d3ee704bcb83006ddc43611`。原JSON只记录baseline短SHA,新标准完整SHA在本说明补充,不改写旧测量字段。 + +| SDK | 固定提交 | 既有规则状态变化 | 旧/新required失败 | +| --- | --- | --- | --- | +| Detection | fede55916770922943178acf1de6684708573d04 | 0 | 0 / 0 | +| DocLayoutV3 | 3aedb7b35af49a1c207fd4f846211366a9d09973 | 0 | 0 / 0 | +| LCNet_x1_0_doc_ori | 0e404877890ab79442f3db43b44aaf726b81e131 | 0 | 0 / 0 | +| OCRv6 | 746a44d0dc59b2b21496dc6853cea56adeb1b17b | 0 | 0 / 0 | +| RotatedDetection | b54ae15ca124fd111cac6e683409fdbb88a14e13 | 0 | 0 / 0 | +| Segmentation | 89b350d30305ecbc275780e455d1c115a250570f | 0 | 0 / 0 | +| TinyPose | 70fe7e5a2377be64cd86efc8b306f03121b6f5c9 | 0 | 0 / 0 | + +新增算法专用规则对旧模型SDK为不适用skip,不偷换成pass;远程治理/托管required依然skip,不能由本地扫描宣称全面compliant。检查对象是提交的git archive快照,不包含用户未提交内容。原Detection工作目录有受限临时目录会导致EPERM,本轮未改权限;采用提交快照避免扫描非交付临时内容。 + +原脚本在[provenance/](provenance/)。正式复跑入口基于报告里的固定提交生成临时快照,使用新旧固定检查器,不自动改写历史报告。先安装门户锁定依赖,确保Git和Python3可用,再在门户根目录执行: + +```powershell +node reports/tracking/2026-09-19-foundation/verify-standard-regression.mjs verify +node reports/tracking/2026-09-19-foundation/verify-standard-regression.mjs rerun --repo-root F:/git/00_chenmohan/github --out .tmp/tracking-standard-regression-replay.json +pnpm --config.verify-deps-before-run=false --config.manage-package-manager-versions=false sdk:check -- --repo F:/git/00_chenmohan/github/web-sdk-PP-Tracking --format json --out reports/sdk-standard/pp-tracking-after.json +``` + +`verify`固定原JSON SHA256为 `3c20f94d6e7f099cfc4e14d1848c120ae259249bfd47237ee1394de86af712d4`,重新推导7个SDK的差异和失败列表。`rerun`还从Git提交重新导出并比较每条规则id/level/status,新报告保留新执行时间与新证据路径,不覆盖原报告。源码仓库位置由 `--repo-root` 指定,临时快照在系统临时目录;快照在任务结束后保留供检查。Windows系统tar无法正确解包TinyPose的既有中文截图名,入口改用Python标准库zipfile解包git archive ZIP;这不是原始报告扫描失败。 + +输出路径会解析现有父目录真实位置,拒绝归档目录本身、Windows大小写和symlink/junction别名,写入前重新检查并以排他方式创建文件。已有输出返回 `EEXIST`,复跑请选择新 `--out` 文件名。定向回归命令为 `node --test reports/tracking/2026-09-19-foundation/check-output-path.mjs`。 + +## 门户和SDK证据 + +- [portal-test.log](portal-test.log):Task1完整原始日志,11文件93测试通过。 +- [portal-build.log](portal-build.log):Task1完整原始构建日志,18页,0错误、0警告、7个既有hint。 +- [portal-task-4-build.log](portal-task-4-build.log):归档入口和路线更新后的实际构建,18页,56个诊断文件,0错误、0警告、仍为7个既有hint。 +- [portal-validation-summary.json](portal-validation-summary.json):既有执行结构化摘要;14 e2e基于生产preview通过,原日志在主代理会话93634a,未伪造本地日志。默认dev启动超时仍是已知环境现象。 +- [Tracking after标准报告](../../sdk-standard/pp-tracking-after.json):归档/文档修改后的实际本地扫描,保留远程skip。 +- SDK验收:独立仓库 `F:/git/00_chenmohan/github/web-sdk-PP-Tracking/reports/2026-09-19-desktop/README.md`,原始129次公开API更新、10/50/100框各600个warm样本、29单测/9浏览器组/实际包/全部构建日志及源码来源说明。 + +性能核心提交为518f94a,ESM SHA256为 `fdd721bf78b7dc2ea3c554619418c914041971e37a2274ef3851e251997d4935`。Chromium151.0.7922.34对应性能,Chromium153.0.8010.12对应完整Demo交互,两者没有混为一次验证。390px是桌面视口;不存在真实手机或真实视频MOT精度结论。独立Apache-2.0实现避免分发前期存在来源义务疑点的参考代码,但不宣称上游逐值等价。 + +本轮只更新本地证据、兼容说明与两份总路线。独立整分支审查已通过,见[最终审查记录](final-review.md):严重0、重要0、轻微1;轻微项是检查器DOM标记后缀误匹配,不影响真实Demo。SDK审查提交为 `96f32f0`,门户审查提交为 `72ca1e5`。 + +本地Demo `http://127.0.0.1:4196/` 已交付;SDK目录运行 `npm run dev:demo` 可重新启动。正式发布、远程治理核验和真实授权序列质量需另行安排,两个本地分支及工作树保留。 diff --git a/reports/tracking/2026-09-19-foundation/check-output-path.mjs b/reports/tracking/2026-09-19-foundation/check-output-path.mjs new file mode 100644 index 0000000..237072a --- /dev/null +++ b/reports/tracking/2026-09-19-foundation/check-output-path.mjs @@ -0,0 +1,37 @@ +import assert from 'node:assert/strict'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { spawnSync } from 'node:child_process'; +import { test } from 'node:test'; + +const root = path.dirname(fileURLToPath(import.meta.url)); +const scratch = await fs.mkdtemp(path.resolve(root, '../../../.tmp/output-safety-')); +const alias = path.join(scratch, 'archive-alias'); +await fs.symlink(root, alias, 'junction'); +function run(out) { + return spawnSync(process.execPath, [path.join(root, 'verify-standard-regression.mjs'), 'verify', '--out', out], { encoding: 'utf8' }); +} +function rejected(out) { + const result = run(out); + assert.equal(result.status, 1, '归档目标必须在执行复核前拒绝:' + out); + assert.match(result.stderr, /归档/); +} +test('拒绝规范归档路径及归档目录本身', () => { + rejected(path.join(root, 'standard-regression.json')); rejected(root); +}); +test('拒绝Windows大小写别名', { skip: process.platform !== 'win32' }, () => { + rejected(path.join(root, 'standard-regression.json').toLowerCase()); +}); +test('拒绝junction别名及其尚不存在的子目录', () => { + rejected(path.join(alias, 'standard-regression.json')); rejected(path.join(alias, 'new-directory/new.json')); +}); +test('允许.tmp新输出,写入时仍拒绝归档别名且不覆盖既有文件', async () => { + const output = path.join(scratch, 'new/result.json'); + assert.equal(run(output).status, 0); + const { writeReport } = await import('./output-path.mjs'); + await writeReport(output, '首份输出', root); + await assert.rejects(writeReport(output, '覆盖输出', root), /EEXIST/); + assert.equal(await fs.readFile(output, 'utf8'), '首份输出'); + await assert.rejects(writeReport(path.join(alias, 'new-directory/new.json'), '禁止写入', root), /归档/); +}); diff --git a/reports/tracking/2026-09-19-foundation/final-review.md b/reports/tracking/2026-09-19-foundation/final-review.md new file mode 100644 index 0000000..53885cd --- /dev/null +++ b/reports/tracking/2026-09-19-foundation/final-review.md @@ -0,0 +1,55 @@ +# PP-Tracking 本地首版整分支独立审查 + +日期:2026-09-19。结论:**可按本轮授权范围交付本地版本**。发现共1项:Critical 0、Important 0、Minor/P3 1。该项不影响当前 SDK 或真实 Demo 的运行,也不推翻已完成的浏览器验证。 + +## 范围与审查依据 + +- 门户:`C:/Users/chenm/.codex/worktrees/segmentation-portal/chenmohan123.github.io`,`df2863ec22e73790f35fcf57c673a55afd4a1be0..72ca1e51a55ff84908c02f907941a4358748f5f7`。 +- SDK:`F:/git/00_chenmohan/github/web-sdk-PP-Tracking`,`193bc8825e89784023434a3923a4975b21f5f627..96f32f030398a217e57975bfcaac1dc66a95d228`。 +- 依据 `final-review-context.md`、2026-09-19设计与实施计划、标准入口与受影响契约、四任务报告和两次修复复审。按指定 code-reviewer.md 独立检查,未派子代理。 +- 分批核查冻结提交中的代码、测试、文档、工作流模板及证据;原始大型JSON采用结构化读取。去除审查包说明头并统一换行后,两份冻结diff均与对应Git区间一致(门户使用10行上下文)。产品与Git保持只读,仅写本报告。 + +## 已确认的优点与计划对齐 + +1. **标准与既有模型边界清楚。** schema只允许1.2.0算法分支,model/cache与algorithm互斥;完整清单校验失败时,扫描器向规则层传空清单,不授予类型豁免。模型assets和原必需耗时/缓存要求保留。七SDK固定提交回归记录全部既有规则状态相同,新增算法规则保持不适用skip。 +2. **运行时独立且状态提交一致。** CPU/main结果与实际实现相符,无网络、模型或React生产依赖。校验先于状态操作,计算使用独立工作副本,结果构造成功才提交时钟、ID和轨迹;输出、输入与内部状态隔离。reset/dispose、代次、容量、超时、低分关联和类别隔离与设计一致。 +3. **数学和关联具有可审查的依据。** 八维恒速状态、P/Q/R、Joseph更新、尺寸投影及数值失败边界已文档化,NumPy公式参考与生产消元实现独立。关联将门限放入优化,允许未匹配,最大匹配数后的最小代价目标明确;729矩阵穷举、贪心与门限反例覆盖关键行为。原同框IoU问题修复未加入任意门限容差。 +4. **Demo按公开API消费。** Demo与Vanilla使用公开包入口;JSON导入先全量结构校验,再复位并替换序列;非法文件与参数保留原结果。seek复位顺序重算,播放使用记录时间,语言切换不复位;预测轨迹显示虚线且score为null。参数应用的新实例行为已有明确说明。 +5. **打包与验证范围真实。** ESM/CJS/类型声明通过实际tarball消费,包文件白名单和零生产依赖有运行日志。工作流为未来模板,双语文档、manifest、路线和报告均明确未发布;未将390px等同手机,也未把合成机制或性能当作真实视频MOT精度。 +6. **归档修复与证据链合理。** 两仓输出保护解析既有祖先真实路径、Windows大小写和junction别名,写前重检,使用wx拒绝覆盖。历史JSON摘要固定,当前构建与测量入口一致;新复跑结果另存,未以归档日期冒充重新测量。门户14个e2e如实标为会话摘要,rawLogFile为null;默认dev超时和7条历史Astro hints未被隐去。 + +## 问题 + +### Critical + +无。 + +### Important + +无。 + +### Minor / P3 + +**1. 算法DOM标记的词边界会接受连字符后缀,造成静态检查假阳性。** + +- 位置:`C:/Users/chenm/.codex/worktrees/segmentation-portal/chenmohan123.github.io/tools/sdk-standard-check/src/discover.mjs:63`、`:69`、`:72`。 +- 触发:Demo只有 `data-sdk-state-reset-old`,或三个区域分别只含 `data-sdk-algorithm-info-old`、`data-sdk-runtime-info-old`、`data-sdk-timing-old`。因为连字符不是正则单词字符,现有 `标记名\\b` 仍命中。 +- 影响:DEMO-005/DEMO-006可能通过,但标准要求的完整属性并不存在,按精确属性选择器检查时找不到对应区域或控件。只读Node探针确认四种后缀均返回true。 +- 建议:至少约束完整属性名的前后边界,并加入连字符后缀/属性名前缀负例;若以后要证明真实DOM存在,应在浏览器层校验精确选择器,保持静态检查与交互验证的区别。 +- 定级理由:本轮真实App使用准确的四个标记,9组浏览器交互已经独立验证复位、耗时和状态。标准也明确静态声明不能代替交互证据。因此这是检查器稳健性改进,当前本地交付可不阻断;不应把它升级为SDK功能故障或远程合规结论。 + +## 本次核对与验证依据 + +- 实际读取并核对SDK冻结提交中9份原始证据/清单SHA256,全部匹配验证器固定值;当前8个构建文件摘要全部匹配归档清单。 +- 结构化核对性能的10/50/100框、每档600个warm和3个cold;重新计算warm统计,与原p50/p95/min/max一致。10场景输入和输出帧数逐场景对应,总129次更新。确认性能Chromium151与产品交互Chromium153为不同证据。 +- 结构化核对NumPy fixture四个dt及8维均值/8×8协方差结构;核对锁文件根依赖全部是开发依赖,与package清单一致。 +- 核对门户7SDK原报告固定摘要、逐SDK旧/新required失败列表均为空;before/core-after/after阶段报告分别如实保留18/16/0项required失败。最终17项required通过、7项required skip,状态仅locally-compliant。 +- 核对既有SDK完整verify日志:29单测、类型、真实包、Demo/Vanilla/React构建、9组浏览器交互和零pageerror;门户93单测、18页构建及14个生产preview e2e会话摘要。本次未重复这些套件或性能测量。 +- 针对同框IoU修复可能受中心坐标往返精度影响的具体疑点,使用当前匹配摘要的公开构建入口做4个小数框、门限1的定向只读探针,均保留ID;未发现新增问题。此探针不扩大浏览器或精度声明。 +- 核对Task2/Task4定向修复、测试及复审,原两项Important均已解决;输出路径测试分别4/4的既有结果与当前实现一致。 + +## 建议与交付判断 + +**可交付:是,仅限独立SDK本地首版、算法标准与已有桌面证据。** 当前实现与四任务之间的API、manifest、状态、Demo及证据契约一致,无需为本轮交付追加发布、手机或真实视频验证。计划复选框与“待整分支审查”的收尾文案应在本结论后更新,保留原始证据不变。 + +上述P3建议列入检查器后续修补。首次远程发布、远程治理、真实授权序列质量及其他设备/浏览器验证继续按已经明确的后续范围安排;本结论不表示这些事项已经通过。 diff --git a/reports/tracking/2026-09-19-foundation/output-path.mjs b/reports/tracking/2026-09-19-foundation/output-path.mjs new file mode 100644 index 0000000..d17b6aa --- /dev/null +++ b/reports/tracking/2026-09-19-foundation/output-path.mjs @@ -0,0 +1,40 @@ +import fs from 'node:fs/promises'; +import { lstatSync, realpathSync } from 'node:fs'; +import path from 'node:path'; + +// 目标可能尚不存在:从最近的既有祖先解析junction/symlink,再接回未建部分。 +function resolvedPath(target) { + let ancestor = path.resolve(target); + const missing = []; + while (true) { + try { lstatSync(ancestor); break; } + catch (error) { + if (error.code !== 'ENOENT') throw error; + const parent = path.dirname(ancestor); + if (parent === ancestor) throw error; + missing.unshift(path.basename(ancestor)); + ancestor = parent; + } + } + // 悬空链接不会被当作普通的未建目录;realpath失败时直接拒绝。 + return path.join(realpathSync.native(ancestor), ...missing); +} + +export function protectOutput(output, archive) { + const actualOutput = resolvedPath(output); + const actualArchive = resolvedPath(archive); + const fold = value => process.platform === 'win32' ? value.toLowerCase() : value; + const relative = path.relative(fold(actualArchive), fold(actualOutput)); + if (relative === '' || (!relative.startsWith('..' + path.sep) && relative !== '..' && !path.isAbsolute(relative))) { + throw new Error('复跑输出不得写入固定历史归档,请使用 .tmp 中的新文件'); + } + return actualOutput; +} + +export async function writeReport(output, content, archive) { + const target = protectOutput(output, archive); + await fs.mkdir(path.dirname(target), { recursive: true }); + const checked = protectOutput(target, archive); + // 排他创建阻止已有文件、硬链接及检查后的既有文件别名被覆盖。 + await fs.writeFile(checked, content, { flag: 'wx' }); +} diff --git a/reports/tracking/2026-09-19-foundation/portal-build.log b/reports/tracking/2026-09-19-foundation/portal-build.log new file mode 100644 index 0000000..2500a0f --- /dev/null +++ b/reports/tracking/2026-09-19-foundation/portal-build.log @@ -0,0 +1,82 @@ +$ astro check && astro build +08:29:11 [vite] Re-optimizing dependencies because vite config has changed +08:29:12 [vite] [optimizer] bundling dependencies... +08:29:14 [content] Syncing content +08:29:14 [content] Synced content +08:29:14 [types] Generated 3.07s +08:29:14 [check] Getting diagnostics for Astro files in C:\Users\chenm\.codex\worktrees\segmentation-portal\chenmohan123.github.io... +reports/sdk-standard/2026-09-12-detection-download/verify-example.mjs:76:10 - warning ts(2568): Property 'error' may not exist on type '{ date: string; browser: string; sdk: string; status: string; runs: never[]; errors: never[]; }'. Did you mean 'errors'? + +76 report.error = String(error); +   ~~~~~ +reports/sdk-standard/2026-09-12-detection-download/verify-example.mjs:36:12 - warning ts(2568): Property 'click' may not exist on type 'SVGElement | HTMLElement'. Did you mean 'onclick'? + Property 'click' does not exist on type 'SVGElement'. + +36 button.click(); +   ~~~~~ +reports/sdk-standard/2026-09-12-detection-download/verify-example.mjs:35:12 - warning ts(2568): Property 'click' may not exist on type 'SVGElement | HTMLElement'. Did you mean 'onclick'? + Property 'click' does not exist on type 'SVGElement'. + +35 button.click(); +   ~~~~~ + +reports/sdk-standard/2026-09-15-tiny-release/demo-smoke.mjs:161:10 - warning ts(2568): Property 'error' may not exist on type '{ date: string; base: string; deployment: any; os: string; cpu: string; manifestSha256: string; rows: never[]; errors: never[]; status: string; }'. Did you mean 'errors'? + +161 result.error = String(e); +   ~~~~~ + +src/lib/registry/schema.ts:22:121 - warning ts(6385): '(params?: string | { normalize?: boolean | undefined; pattern?: RegExp | undefined; abort?: boolean | undefined; hostname?: RegExp | undefined; protocol?: RegExp | undefined; error?: string | ... 1 more ... | undefined; message?: string | undefined; } | undefined): ZodString' is deprecated. + +22 assets: z.array(z.object({ id: z.string(), precision: z.string(), bytes: z.number().int().positive(), url: z.string().url(), sha256: z.string().regex(/^[a-f0-9]{64}$/) })).min(1), +   ~~~ +src/lib/registry/schema.ts:15:36 - warning ts(6385): '(params?: string | { normalize?: boolean | undefined; pattern?: RegExp | undefined; abort?: boolean | undefined; hostname?: RegExp | undefined; protocol?: RegExp | undefined; error?: string | ... 1 more ... | undefined; message?: string | undefined; } | undefined): ZodString' is deprecated. + +15 demo: z.object({ url: z.string().url(), localProcessing: z.boolean() }), +   ~~~ +src/lib/registry/schema.ts:12:26 - warning ts(6385): '(params?: string | { normalize?: boolean | undefined; pattern?: RegExp | undefined; abort?: boolean | undefined; hostname?: RegExp | undefined; protocol?: RegExp | undefined; error?: string | ... 1 more ... | undefined; message?: string | undefined; } | undefined): ZodString' is deprecated. + +12 repository: z.string().url(), +   ~~~ + +Result (54 files): +- 0 errors +- 0 warnings +- 7 hints + +08:29:34 [content] Syncing content +08:29:34 [content] Synced content +08:29:34 [types] Generated 697ms +08:29:34 [build] output: "static" +08:29:34 [build] mode: "static" +08:29:34 [build] directory: C:\Users\chenm\.codex\worktrees\segmentation-portal\chenmohan123.github.io\dist\ +08:29:34 [build] Collecting build info... +08:29:34 [build] ✓ Completed in 772ms. +08:29:34 [build] Building static entrypoints... +08:29:36 [vite] ✓ built in 1.16s +08:29:42 [vite] ✓ built in 5.96s +08:29:42 [build] Rearranging server assets... + + generating static routes +08:29:42 ├─ /brands/baidu/index.html (+17ms) +08:29:42 ├─ /docs/index.html (+9ms) +08:29:42 ├─ /models/pp-detection/compare/index.html (+60ms) +08:29:42 ├─ /models/pp-detection/index.html (+3ms) +08:29:42 ├─ /models/pp-doclayoutv3/index.html (+3ms) +08:29:42 ├─ /models/pp-lcnet-x1-0-doc-ori/index.html (+3ms) +08:29:42 ├─ /models/pp-ocrv6/index.html (+3ms) +08:29:42 ├─ /models/pp-rotated-detection/index.html (+3ms) +08:29:42 ├─ /models/pp-segmentation/index.html (+3ms) +08:29:42 ├─ /models/pp-tinypose/index.html (+3ms) +08:29:42 ├─ /tasks/detection/index.html (+4ms) +08:29:42 ├─ /tasks/document-layout/index.html (+4ms) +08:29:42 ├─ /tasks/image-correction/index.html (+3ms) +08:29:42 ├─ /tasks/ocr/index.html (+3ms) +08:29:42 ├─ /tasks/rotated-detection/index.html (+3ms) +08:29:42 ├─ /tasks/instance-segmentation/index.html (+3ms) +08:29:42 ├─ /tasks/pose-estimation/index.html (+3ms) +08:29:42 ├─ /index.html (+89ms) +08:29:42 ✓ Completed in 479ms. + +08:29:42 [build] ✓ Completed in 7.70s. +08:29:42 [build] 18 page(s) built in 8.48s +08:29:42 [build] Complete! diff --git a/reports/tracking/2026-09-19-foundation/portal-task-4-build.log b/reports/tracking/2026-09-19-foundation/portal-task-4-build.log new file mode 100644 index 0000000..98e405f --- /dev/null +++ b/reports/tracking/2026-09-19-foundation/portal-task-4-build.log @@ -0,0 +1,80 @@ +$ astro check && astro build +09:53:13 [content] Syncing content +09:53:13 [content] Synced content +09:53:13 [types] Generated 631ms +09:53:13 [check] Getting diagnostics for Astro files in C:\Users\chenm\.codex\worktrees\segmentation-portal\chenmohan123.github.io... +reports/sdk-standard/2026-09-12-detection-download/verify-example.mjs:76:10 - warning ts(2568): Property 'error' may not exist on type '{ date: string; browser: string; sdk: string; status: string; runs: never[]; errors: never[]; }'. Did you mean 'errors'? + +76 report.error = String(error); +   ~~~~~ +reports/sdk-standard/2026-09-12-detection-download/verify-example.mjs:36:12 - warning ts(2568): Property 'click' may not exist on type 'SVGElement | HTMLElement'. Did you mean 'onclick'? + Property 'click' does not exist on type 'SVGElement'. + +36 button.click(); +   ~~~~~ +reports/sdk-standard/2026-09-12-detection-download/verify-example.mjs:35:12 - warning ts(2568): Property 'click' may not exist on type 'SVGElement | HTMLElement'. Did you mean 'onclick'? + Property 'click' does not exist on type 'SVGElement'. + +35 button.click(); +   ~~~~~ + +reports/sdk-standard/2026-09-15-tiny-release/demo-smoke.mjs:161:10 - warning ts(2568): Property 'error' may not exist on type '{ date: string; base: string; deployment: any; os: string; cpu: string; manifestSha256: string; rows: never[]; errors: never[]; status: string; }'. Did you mean 'errors'? + +161 result.error = String(e); +   ~~~~~ + +src/lib/registry/schema.ts:22:121 - warning ts(6385): '(params?: string | { normalize?: boolean | undefined; pattern?: RegExp | undefined; abort?: boolean | undefined; hostname?: RegExp | undefined; protocol?: RegExp | undefined; error?: string | ... 1 more ... | undefined; message?: string | undefined; } | undefined): ZodString' is deprecated. + +22 assets: z.array(z.object({ id: z.string(), precision: z.string(), bytes: z.number().int().positive(), url: z.string().url(), sha256: z.string().regex(/^[a-f0-9]{64}$/) })).min(1), +   ~~~ +src/lib/registry/schema.ts:15:36 - warning ts(6385): '(params?: string | { normalize?: boolean | undefined; pattern?: RegExp | undefined; abort?: boolean | undefined; hostname?: RegExp | undefined; protocol?: RegExp | undefined; error?: string | ... 1 more ... | undefined; message?: string | undefined; } | undefined): ZodString' is deprecated. + +15 demo: z.object({ url: z.string().url(), localProcessing: z.boolean() }), +   ~~~ +src/lib/registry/schema.ts:12:26 - warning ts(6385): '(params?: string | { normalize?: boolean | undefined; pattern?: RegExp | undefined; abort?: boolean | undefined; hostname?: RegExp | undefined; protocol?: RegExp | undefined; error?: string | ... 1 more ... | undefined; message?: string | undefined; } | undefined): ZodString' is deprecated. + +12 repository: z.string().url(), +   ~~~ + +Result (56 files): +- 0 errors +- 0 warnings +- 7 hints + +09:53:23 [content] Syncing content +09:53:23 [content] Synced content +09:53:23 [types] Generated 643ms +09:53:23 [build] output: "static" +09:53:23 [build] mode: "static" +09:53:23 [build] directory: C:\Users\chenm\.codex\worktrees\segmentation-portal\chenmohan123.github.io\dist\ +09:53:23 [build] Collecting build info... +09:53:23 [build] ✓ Completed in 713ms. +09:53:23 [build] Building static entrypoints... +09:53:23 [vite] ✓ built in 304ms +09:53:23 [vite] ✓ built in 487ms +09:53:23 [build] Rearranging server assets... + + generating static routes +09:53:24 ├─ /brands/baidu/index.html (+14ms) +09:53:24 ├─ /docs/index.html (+5ms) +09:53:24 ├─ /models/pp-detection/compare/index.html (+36ms) +09:53:24 ├─ /models/pp-detection/index.html (+5ms) +09:53:24 ├─ /models/pp-doclayoutv3/index.html (+3ms) +09:53:24 ├─ /models/pp-lcnet-x1-0-doc-ori/index.html (+3ms) +09:53:24 ├─ /models/pp-ocrv6/index.html (+3ms) +09:53:24 ├─ /models/pp-rotated-detection/index.html (+3ms) +09:53:24 ├─ /models/pp-segmentation/index.html (+3ms) +09:53:24 ├─ /models/pp-tinypose/index.html (+3ms) +09:53:24 ├─ /tasks/detection/index.html (+3ms) +09:53:24 ├─ /tasks/document-layout/index.html (+2ms) +09:53:24 ├─ /tasks/image-correction/index.html (+2ms) +09:53:24 ├─ /tasks/ocr/index.html (+3ms) +09:53:24 ├─ /tasks/rotated-detection/index.html (+2ms) +09:53:24 ├─ /tasks/instance-segmentation/index.html (+3ms) +09:53:24 ├─ /tasks/pose-estimation/index.html (+2ms) +09:53:24 ├─ /index.html (+72ms) +09:53:24 ✓ Completed in 250ms. + +09:53:24 [build] ✓ Completed in 1.12s. +09:53:24 [build] 18 page(s) built in 1.84s +09:53:24 [build] Complete! diff --git a/reports/tracking/2026-09-19-foundation/portal-test.log b/reports/tracking/2026-09-19-foundation/portal-test.log new file mode 100644 index 0000000..fdac407 --- /dev/null +++ b/reports/tracking/2026-09-19-foundation/portal-test.log @@ -0,0 +1,31 @@ +$ vitest run + + RUN v3.2.7 C:/Users/chenm/.codex/worktrees/segmentation-portal/chenmohan123.github.io + + ✓ src/lib/registry/query.test.ts (3 tests) 13ms + ✓ tools/detection-comparison/tiny-precision.test.ts (3 tests) 54ms + ✓ tools/detection-comparison/build.test.ts (5 tests) 52ms + ✓ tools/detection-comparison/catalog.test.ts (2 tests) 98ms + ✓ src/content/models/registry.test.ts (6 tests) 302ms + ✓ tools/sdk-standard-check/standard-files.test.ts (7 tests) 596ms + ✓ v1 standard source > 接受包含变体、精度和多来源的模型清单 471ms + ✓ tools/sdk-standard-check/checker.test.ts (13 tests) 1044ms + ✓ SDK repository discovery > accepts both v1.0 manifests and the v1.1 manifest template 534ms + ✓ src/components/registry/ModelDirectory.test.tsx (5 tests) 1482ms + ✓ ModelDirectory > 旋转框检测分类只展示独立 SDK 并提供详情入口 929ms + ✓ src/components/model/DetectionComparison.test.tsx (2 tests) 2562ms + ✓ Detection 模型选型 > 筛选稳定精度并保留批次,不把XS实验量化列入稳定表 1648ms + ✓ Detection 模型选型 > 切换后端同时更新AP与耗时,明确不同汇总规则 912ms + ✓ tools/sdk-standard-check/algorithm.test.ts (25 tests) 2292ms + ✓ 纯算法 SDK 契约 > 合法算法无模型与缓存也通过,模型专属规则有跳过理由和证据 730ms + ✓ 纯算法 SDK 契约 > 缺少 data-sdk-runtime-info 标记会失败,说明文字不能代替标记 320ms + ✓ tools/sdk-standard-check/manifest-validation.test.ts (22 tests) 2511ms + ✓ 清单完整 schema 校验 > 扫描使用所选标准的 schema,标准损坏时不归咎于仓库 592ms + ✓ 清单完整 schema 校验 > YAML 中错误的资产数组返回 CONFIG-001 和 CLI 退出码 1 702ms + ✓ 清单完整 schema 校验 > 多个仓库中的损坏清单不会阻止后续仓库扫描 852ms + + Test Files 11 passed (11) + Tests 93 passed (93) + Start at 08:28:55 + Duration 8.82s (transform 1.19s, setup 10.04s, collect 4.67s, tests 11.01s, environment 42.18s, prepare 3.64s) + diff --git a/reports/tracking/2026-09-19-foundation/portal-validation-summary.json b/reports/tracking/2026-09-19-foundation/portal-validation-summary.json new file mode 100644 index 0000000..97525ce --- /dev/null +++ b/reports/tracking/2026-09-19-foundation/portal-validation-summary.json @@ -0,0 +1,18 @@ +{ + "date": "2026-09-19", + "kind": "既有执行结果的结构化摘要,不是原始测试日志或重新执行", + "unit": { "passed": 93, "files": 11, "source": "portal-test.log" }, + "build": { "pages": 18, "errors": 0, "warnings": 0, "hints": 7, "source": "portal-build.log", "note": "Task 1的既有构建;Task 4归档后构建结果另见实施报告。" }, + "e2e": { + "passed": 14, + "durationSeconds": 6.3, + "server": "本轮生产构建的Astro preview,127.0.0.1:4321", + "viewports": [1280, 390], + "scope": ["目录", "详情", "选型"], + "source": ".superpowers/sdd/2026-09-19-pp-tracking-foundation/progress.md;主代理命令会话93634a", + "rawLogFile": null, + "note": "原始输出保留在会话中,未另存日志;本文件仅据主代理执行记录整理。默认astro dev在60000ms未监听,生产preview测试通过不表示dev问题已修复。" + }, + "remoteChanges": false, + "trackingRegisteredInOnlineCatalog": false +} diff --git a/reports/tracking/2026-09-19-foundation/provenance/tracking-standard-regression.mjs b/reports/tracking/2026-09-19-foundation/provenance/tracking-standard-regression.mjs new file mode 100644 index 0000000..5374ca9 --- /dev/null +++ b/reports/tracking/2026-09-19-foundation/provenance/tracking-standard-regression.mjs @@ -0,0 +1,25 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { execFileSync } from 'node:child_process'; +import { scanRepository as current } from '../tools/sdk-standard-check/src/check.mjs'; +import { scanRepository as baseline } from './tracking-baseline-reference/tools/sdk-standard-check/src/check.mjs'; + +const roots = ['Detection', 'DocLayoutV3', 'LCNet_x1_0_doc_ori', 'OCRv6', 'RotatedDetection', 'Segmentation', 'TinyPose'].map(x=>'web-sdk-PP-'+x); +const baseStandard = path.resolve('.tmp/tracking-baseline-reference/standards/v1'); +const nextStandard = path.resolve('standards/v1'); +const records = []; +for (const name of roots) { + const snapshot = path.resolve('C:/Users/chenm/.codex/tmp/tracking-compat-20260919', name); + const a = await baseline(snapshot, {standardRoot:baseStandard}); + const b = await current(snapshot, {standardRoot:nextStandard}); + const prior = new Map(a.findings.map(x=>[x.id,x])); + const changes = b.findings.filter(x=>prior.has(x.id) && x.status!==prior.get(x.id).status).map(x=>({id:x.id,before:prior.get(x.id).status,after:x.status})); + records.push({repository:name, commit:execFileSync('git',['-C',path.join('F:/git/00_chenmohan/github',name),'rev-parse','HEAD'],{encoding:'utf8'}).trim(), changes, + baselineFailures:a.findings.filter(x=>x.level==='required'&&x.status==='fail').map(x=>x.id), + currentFailures:b.findings.filter(x=>x.level==='required'&&x.status==='fail').map(x=>x.id), + baseline:a.findings,current:b.findings}); +} +const report={verifiedAt:new Date().toISOString(),baseline:'df2863e',scope:'仅各仓库HEAD的git archive快照;不包含用户未提交文件或本地临时目录',records}; +await fs.writeFile('.tmp/tracking-standard-regression.json',JSON.stringify(report,null,2)+'\n'); +console.log(JSON.stringify(records.map(({repository,changes,baselineFailures,currentFailures})=>({repository,changes,baselineFailures,currentFailures})),null,2)); +if(records.some(x=>x.changes.length))process.exitCode=1; diff --git a/reports/tracking/2026-09-19-foundation/standard-regression.json b/reports/tracking/2026-09-19-foundation/standard-regression.json new file mode 100644 index 0000000..5abf757 --- /dev/null +++ b/reports/tracking/2026-09-19-foundation/standard-regression.json @@ -0,0 +1,3414 @@ +{ + "verifiedAt": "2026-09-19T00:32:22.867Z", + "baseline": "df2863e", + "scope": "仅各仓库HEAD的git archive快照;不包含用户未提交文件或本地临时目录", + "records": [ + { + "repository": "web-sdk-PP-Detection", + "commit": "fede55916770922943178acf1de6684708573d04", + "changes": [], + "baselineFailures": [], + "currentFailures": [], + "baseline": [ + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html, apps/demo/src/App.tsx, apps/demo/src/ClassFilter.tsx, apps/demo/src/i18n/en.ts, apps/demo/tests/class-filter.spec.ts, apps/demo/tests/target-selection.spec.ts, examples/cdn/index.html, examples/model-variants/index.html, examples/react/index.html, examples/vanilla-vite/index.html, examples/vanilla/index.html, examples/vue/index.html, examples/wechat-webview/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "apps/demo/src/App.tsx", + "evidence": "apps/demo/src/App.tsx, apps/demo/src/ClassFilter.tsx, apps/demo/src/i18n/detection-labels.ts, apps/demo/src/i18n/en.ts, apps/demo/src/i18n/zh-CN.ts, apps/demo/src/styles.css, apps/demo/tests/class-filter.spec.ts, apps/demo/tests/demo.spec.ts, apps/demo/tests/image-export.spec.ts, apps/demo/tests/image-zoom.spec.ts, apps/demo/tests/precision-selection.spec.ts, apps/demo/tests/small-objects.spec.ts, apps/demo/tests/target-selection.spec.ts" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "pass", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo exposes model/runtime/timing information", + "remediation": "Render data-sdk-model-info, data-sdk-runtime-info, and data-sdk-timing regions.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "pass", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "Standard load and inference timing fields are declared", + "remediation": "Document download, cache, integrity, session, inference, and total timing.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "pass", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla-vite/README.md", + "evidence": "examples/vanilla-vite/README.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.md", + "evidence": "examples/react/README.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla-vite/README.md", + "evidence": "examples/vanilla-vite/README.md, examples/react/README.md, examples/vue/README.md, examples/cdn/README.md, examples/wechat-webview/README.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + } + ], + "current": [ + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html, apps/demo/src/App.tsx, apps/demo/src/ClassFilter.tsx, apps/demo/src/i18n/en.ts, apps/demo/tests/class-filter.spec.ts, apps/demo/tests/target-selection.spec.ts, examples/cdn/index.html, examples/model-variants/index.html, examples/react/index.html, examples/vanilla-vite/index.html, examples/vanilla/index.html, examples/vue/index.html, examples/wechat-webview/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "apps/demo/src/App.tsx", + "evidence": "apps/demo/src/App.tsx, apps/demo/src/ClassFilter.tsx, apps/demo/src/i18n/detection-labels.ts, apps/demo/src/i18n/en.ts, apps/demo/src/i18n/zh-CN.ts, apps/demo/src/styles.css, apps/demo/tests/class-filter.spec.ts, apps/demo/tests/demo.spec.ts, apps/demo/tests/image-export.spec.ts, apps/demo/tests/image-zoom.spec.ts, apps/demo/tests/precision-selection.spec.ts, apps/demo/tests/small-objects.spec.ts, apps/demo/tests/target-selection.spec.ts" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "pass", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo 展示当前模型或算法的信息、运行信息和耗时", + "remediation": "模型使用 data-sdk-model-info,算法使用 data-sdk-algorithm-info;两者保留 data-sdk-runtime-info 和 data-sdk-timing。", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-006", + "level": "required", + "status": "skip", + "message": "算法 Demo 提供状态复位操作", + "remediation": "使用 data-sdk-state-reset 标记复位控件,并按状态生命周期契约连接 reset。", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;清单已通过完整校验。" + }, + { + "id": "ALGORITHM-001", + "level": "required", + "status": "skip", + "message": "算法清单声明身份、家族、来源、许可、输入输出与有状态语义", + "remediation": "按 sdk-manifest.algorithm.yaml 填写 algorithm 字段并记录状态生命周期。", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;清单已通过完整校验。" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "pass", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "声明当前 SDK 类型所需的标准耗时字段", + "remediation": "模型保留下载、缓存、校验、会话、推理和总耗时;算法声明 validationMs、predictionMs、associationMs、updateMs、totalMs。", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "pass", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla-vite/README.md", + "evidence": "examples/vanilla-vite/README.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.md", + "evidence": "examples/react/README.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla-vite/README.md", + "evidence": "examples/vanilla-vite/README.md, examples/react/README.md, examples/vue/README.md, examples/cdn/README.md, examples/wechat-webview/README.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + } + ] + }, + { + "repository": "web-sdk-PP-DocLayoutV3", + "commit": "3aedb7b35af49a1c207fd4f846211366a9d09973", + "changes": [], + "baselineFailures": [], + "currentFailures": [], + "baseline": [ + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html, apps/demo/src/App.tsx, apps/demo/src/i18n/en.ts, apps/demo/src/samples.ts, examples/cdn/index.html, examples/react/index.html, examples/vanilla-vite/index.html, examples/vue/index.html, examples/wechat-webview/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "apps/demo/src/App.tsx", + "evidence": "apps/demo/src/App.tsx, apps/demo/src/i18n/en.ts, apps/demo/src/i18n/zh-CN.ts, apps/demo/src/samples.ts, apps/demo/src/styles.css, apps/demo/tests/cache.spec.ts, apps/demo/tests/demo.spec.ts" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "pass", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo exposes model/runtime/timing information", + "remediation": "Render data-sdk-model-info, data-sdk-runtime-info, and data-sdk-timing regions.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "pass", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "Standard load and inference timing fields are declared", + "remediation": "Document download, cache, integrity, session, inference, and total timing.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "pass", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla-vite/README.md", + "evidence": "examples/vanilla-vite/README.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.md", + "evidence": "examples/react/README.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla-vite/README.md", + "evidence": "examples/vanilla-vite/README.md, examples/react/README.md, examples/vue/README.md, examples/cdn/README.md, examples/wechat-webview/README.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + } + ], + "current": [ + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html, apps/demo/src/App.tsx, apps/demo/src/i18n/en.ts, apps/demo/src/samples.ts, examples/cdn/index.html, examples/react/index.html, examples/vanilla-vite/index.html, examples/vue/index.html, examples/wechat-webview/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "apps/demo/src/App.tsx", + "evidence": "apps/demo/src/App.tsx, apps/demo/src/i18n/en.ts, apps/demo/src/i18n/zh-CN.ts, apps/demo/src/samples.ts, apps/demo/src/styles.css, apps/demo/tests/cache.spec.ts, apps/demo/tests/demo.spec.ts" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "pass", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo 展示当前模型或算法的信息、运行信息和耗时", + "remediation": "模型使用 data-sdk-model-info,算法使用 data-sdk-algorithm-info;两者保留 data-sdk-runtime-info 和 data-sdk-timing。", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-006", + "level": "required", + "status": "skip", + "message": "算法 Demo 提供状态复位操作", + "remediation": "使用 data-sdk-state-reset 标记复位控件,并按状态生命周期契约连接 reset。", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;清单已通过完整校验。" + }, + { + "id": "ALGORITHM-001", + "level": "required", + "status": "skip", + "message": "算法清单声明身份、家族、来源、许可、输入输出与有状态语义", + "remediation": "按 sdk-manifest.algorithm.yaml 填写 algorithm 字段并记录状态生命周期。", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;清单已通过完整校验。" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "pass", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "声明当前 SDK 类型所需的标准耗时字段", + "remediation": "模型保留下载、缓存、校验、会话、推理和总耗时;算法声明 validationMs、predictionMs、associationMs、updateMs、totalMs。", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "pass", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla-vite/README.md", + "evidence": "examples/vanilla-vite/README.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.md", + "evidence": "examples/react/README.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla-vite/README.md", + "evidence": "examples/vanilla-vite/README.md, examples/react/README.md, examples/vue/README.md, examples/cdn/README.md, examples/wechat-webview/README.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + } + ] + }, + { + "repository": "web-sdk-PP-LCNet_x1_0_doc_ori", + "commit": "0e404877890ab79442f3db43b44aaf726b81e131", + "changes": [], + "baselineFailures": [], + "currentFailures": [], + "baseline": [ + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html, apps/demo/src/i18n/en.ts, apps/demo/src/i18n/index.ts, apps/demo/src/i18n/types.ts, apps/demo/src/i18n/zh-CN.ts, apps/demo/src/main.ts, examples/react/index.html, examples/react/src/App.tsx, examples/vanilla-vite/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "apps/demo/src/i18n/en.ts", + "evidence": "apps/demo/src/i18n/en.ts, apps/demo/src/i18n/index.ts, apps/demo/src/i18n/types.ts, apps/demo/src/i18n/zh-CN.ts, apps/demo/src/main.ts, apps/demo/src/render.ts, apps/demo/src/styles.css, apps/demo/tests/cache-standard.spec.ts, apps/demo/tests/demo.spec.ts, examples/react/src/App.tsx" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "pass", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo exposes model/runtime/timing information", + "remediation": "Render data-sdk-model-info, data-sdk-runtime-info, and data-sdk-timing regions.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "pass", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "Standard load and inference timing fields are declared", + "remediation": "Document download, cache, integrity, session, inference, and total timing.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "pass", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla-vite/README.md", + "evidence": "examples/vanilla-vite/README.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.md", + "evidence": "examples/react/README.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla-vite/README.md", + "evidence": "examples/vanilla-vite/README.md, examples/react/README.md, examples/cdn/README.md, examples/wechat-web-view/README.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + } + ], + "current": [ + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html, apps/demo/src/i18n/en.ts, apps/demo/src/i18n/index.ts, apps/demo/src/i18n/types.ts, apps/demo/src/i18n/zh-CN.ts, apps/demo/src/main.ts, examples/react/index.html, examples/react/src/App.tsx, examples/vanilla-vite/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "apps/demo/src/i18n/en.ts", + "evidence": "apps/demo/src/i18n/en.ts, apps/demo/src/i18n/index.ts, apps/demo/src/i18n/types.ts, apps/demo/src/i18n/zh-CN.ts, apps/demo/src/main.ts, apps/demo/src/render.ts, apps/demo/src/styles.css, apps/demo/tests/cache-standard.spec.ts, apps/demo/tests/demo.spec.ts, examples/react/src/App.tsx" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "pass", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo 展示当前模型或算法的信息、运行信息和耗时", + "remediation": "模型使用 data-sdk-model-info,算法使用 data-sdk-algorithm-info;两者保留 data-sdk-runtime-info 和 data-sdk-timing。", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-006", + "level": "required", + "status": "skip", + "message": "算法 Demo 提供状态复位操作", + "remediation": "使用 data-sdk-state-reset 标记复位控件,并按状态生命周期契约连接 reset。", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;清单已通过完整校验。" + }, + { + "id": "ALGORITHM-001", + "level": "required", + "status": "skip", + "message": "算法清单声明身份、家族、来源、许可、输入输出与有状态语义", + "remediation": "按 sdk-manifest.algorithm.yaml 填写 algorithm 字段并记录状态生命周期。", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;清单已通过完整校验。" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "pass", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "声明当前 SDK 类型所需的标准耗时字段", + "remediation": "模型保留下载、缓存、校验、会话、推理和总耗时;算法声明 validationMs、predictionMs、associationMs、updateMs、totalMs。", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "pass", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla-vite/README.md", + "evidence": "examples/vanilla-vite/README.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.md", + "evidence": "examples/react/README.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla-vite/README.md", + "evidence": "examples/vanilla-vite/README.md, examples/react/README.md, examples/cdn/README.md, examples/wechat-web-view/README.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + } + ] + }, + { + "repository": "web-sdk-PP-OCRv6", + "commit": "746a44d0dc59b2b21496dc6853cea56adeb1b17b", + "changes": [], + "baselineFailures": [], + "currentFailures": [], + "baseline": [ + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html, apps/demo/src/App.tsx, apps/demo/src/i18n/en.ts, apps/demo/tests/interaction-regression.spec.ts, examples/cdn/index.html, examples/react/index.html, examples/vanilla/index.html, examples/vite/index.html, examples/wechat-web-view/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "apps/demo/src/App.tsx", + "evidence": "apps/demo/src/App.tsx, apps/demo/src/i18n/en.ts, apps/demo/src/i18n/zh-CN.ts, apps/demo/tests/demo.spec.ts, apps/demo/tests/interaction-regression.spec.ts" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "pass", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo exposes model/runtime/timing information", + "remediation": "Render data-sdk-model-info, data-sdk-runtime-info, and data-sdk-timing regions.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "pass", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "Standard load and inference timing fields are declared", + "remediation": "Document download, cache, integrity, session, inference, and total timing.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "pass", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla/README.md", + "evidence": "examples/vanilla/README.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/App.tsx", + "evidence": "examples/react/App.tsx" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla/README.md", + "evidence": "examples/vanilla/README.md, examples/react/App.tsx, examples/cdn/README.md, examples/vite/README.md, examples/wechat-web-view/README.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + } + ], + "current": [ + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "apps/demo/index.html", + "evidence": "apps/demo/index.html, apps/demo/src/App.tsx, apps/demo/src/i18n/en.ts, apps/demo/tests/interaction-regression.spec.ts, examples/cdn/index.html, examples/react/index.html, examples/vanilla/index.html, examples/vite/index.html, examples/wechat-web-view/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "apps/demo/src/App.tsx", + "evidence": "apps/demo/src/App.tsx, apps/demo/src/i18n/en.ts, apps/demo/src/i18n/zh-CN.ts, apps/demo/tests/demo.spec.ts, apps/demo/tests/interaction-regression.spec.ts" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "pass", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo 展示当前模型或算法的信息、运行信息和耗时", + "remediation": "模型使用 data-sdk-model-info,算法使用 data-sdk-algorithm-info;两者保留 data-sdk-runtime-info 和 data-sdk-timing。", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-006", + "level": "required", + "status": "skip", + "message": "算法 Demo 提供状态复位操作", + "remediation": "使用 data-sdk-state-reset 标记复位控件,并按状态生命周期契约连接 reset。", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;清单已通过完整校验。" + }, + { + "id": "ALGORITHM-001", + "level": "required", + "status": "skip", + "message": "算法清单声明身份、家族、来源、许可、输入输出与有状态语义", + "remediation": "按 sdk-manifest.algorithm.yaml 填写 algorithm 字段并记录状态生命周期。", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;清单已通过完整校验。" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "pass", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "声明当前 SDK 类型所需的标准耗时字段", + "remediation": "模型保留下载、缓存、校验、会话、推理和总耗时;算法声明 validationMs、predictionMs、associationMs、updateMs、totalMs。", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "pass", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla/README.md", + "evidence": "examples/vanilla/README.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/App.tsx", + "evidence": "examples/react/App.tsx" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla/README.md", + "evidence": "examples/vanilla/README.md, examples/react/App.tsx, examples/cdn/README.md, examples/vite/README.md, examples/wechat-web-view/README.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + } + ] + }, + { + "repository": "web-sdk-PP-RotatedDetection", + "commit": "b54ae15ca124fd111cac6e683409fdbb88a14e13", + "changes": [], + "baselineFailures": [], + "currentFailures": [], + "baseline": [ + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "demo/index.html", + "evidence": "demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "demo/index.html", + "evidence": "demo/index.html, demo/src/App.tsx, examples/vanilla/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx, demo/src/draw-polygon.ts" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "pass", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo exposes model/runtime/timing information", + "remediation": "Render data-sdk-model-info, data-sdk-runtime-info, and data-sdk-timing regions.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "pass", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "Standard load and inference timing fields are declared", + "remediation": "Document download, cache, integrity, session, inference, and total timing.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "pass", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla/README.md", + "evidence": "examples/vanilla/README.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.md", + "evidence": "examples/react/README.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla/README.md", + "evidence": "examples/vanilla/README.md, examples/react/README.md, examples/vite/README.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + } + ], + "current": [ + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "demo/index.html", + "evidence": "demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "demo/index.html", + "evidence": "demo/index.html, demo/src/App.tsx, examples/vanilla/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx, demo/src/draw-polygon.ts" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "pass", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo 展示当前模型或算法的信息、运行信息和耗时", + "remediation": "模型使用 data-sdk-model-info,算法使用 data-sdk-algorithm-info;两者保留 data-sdk-runtime-info 和 data-sdk-timing。", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-006", + "level": "required", + "status": "skip", + "message": "算法 Demo 提供状态复位操作", + "remediation": "使用 data-sdk-state-reset 标记复位控件,并按状态生命周期契约连接 reset。", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;清单已通过完整校验。" + }, + { + "id": "ALGORITHM-001", + "level": "required", + "status": "skip", + "message": "算法清单声明身份、家族、来源、许可、输入输出与有状态语义", + "remediation": "按 sdk-manifest.algorithm.yaml 填写 algorithm 字段并记录状态生命周期。", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;清单已通过完整校验。" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "pass", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "声明当前 SDK 类型所需的标准耗时字段", + "remediation": "模型保留下载、缓存、校验、会话、推理和总耗时;算法声明 validationMs、predictionMs、associationMs、updateMs、totalMs。", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "pass", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla/README.md", + "evidence": "examples/vanilla/README.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.md", + "evidence": "examples/react/README.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla/README.md", + "evidence": "examples/vanilla/README.md, examples/react/README.md, examples/vite/README.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + } + ] + }, + { + "repository": "web-sdk-PP-Segmentation", + "commit": "89b350d30305ecbc275780e455d1c115a250570f", + "changes": [], + "baselineFailures": [], + "currentFailures": [], + "baseline": [ + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "demo/index.html", + "evidence": "demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "demo/index.html", + "evidence": "demo/index.html, demo/src/App.tsx, examples/vanilla/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "pass", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo exposes model/runtime/timing information", + "remediation": "Render data-sdk-model-info, data-sdk-runtime-info, and data-sdk-timing regions.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "pass", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "Standard load and inference timing fields are declared", + "remediation": "Document download, cache, integrity, session, inference, and total timing.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "pass", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla/README.md", + "evidence": "examples/vanilla/README.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.md", + "evidence": "examples/react/README.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "fail", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla/README.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + } + ], + "current": [ + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "demo/index.html", + "evidence": "demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "demo/index.html", + "evidence": "demo/index.html, demo/src/App.tsx, examples/vanilla/index.html" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "pass", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo 展示当前模型或算法的信息、运行信息和耗时", + "remediation": "模型使用 data-sdk-model-info,算法使用 data-sdk-algorithm-info;两者保留 data-sdk-runtime-info 和 data-sdk-timing。", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-006", + "level": "required", + "status": "skip", + "message": "算法 Demo 提供状态复位操作", + "remediation": "使用 data-sdk-state-reset 标记复位控件,并按状态生命周期契约连接 reset。", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;清单已通过完整校验。" + }, + { + "id": "ALGORITHM-001", + "level": "required", + "status": "skip", + "message": "算法清单声明身份、家族、来源、许可、输入输出与有状态语义", + "remediation": "按 sdk-manifest.algorithm.yaml 填写 algorithm 字段并记录状态生命周期。", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;清单已通过完整校验。" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "pass", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "声明当前 SDK 类型所需的标准耗时字段", + "remediation": "模型保留下载、缓存、校验、会话、推理和总耗时;算法声明 validationMs、predictionMs、associationMs、updateMs、totalMs。", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "pass", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla/README.md", + "evidence": "examples/vanilla/README.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.md", + "evidence": "examples/react/README.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "fail", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla/README.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + } + ] + }, + { + "repository": "web-sdk-PP-TinyPose", + "commit": "70fe7e5a2377be64cd86efc8b306f03121b6f5c9", + "changes": [], + "baselineFailures": [], + "currentFailures": [], + "baseline": [ + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "demo/index.html", + "evidence": "demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "demo/index.html", + "evidence": "demo/index.html, demo/public/examples/vanilla.html, demo/src/App.tsx" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx, demo/src/media/MediaWorkspace.tsx, demo/src/style.css" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "pass", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo exposes model/runtime/timing information", + "remediation": "Render data-sdk-model-info, data-sdk-runtime-info, and data-sdk-timing regions.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "pass", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "Standard load and inference timing fields are declared", + "remediation": "Document download, cache, integrity, session, inference, and total timing.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "pass", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla/README.md", + "evidence": "examples/vanilla/README.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.md", + "evidence": "examples/react/README.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla/README.md", + "evidence": "examples/vanilla/README.md, examples/react/README.md, examples/vite/README.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + } + ], + "current": [ + { + "id": "META-001", + "level": "required", + "status": "pass", + "message": "SDK manifest is present and declares the v1 contract", + "remediation": "Copy standards/v1/templates/sdk-manifest.yaml and fill every required field.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "META-002", + "level": "required", + "status": "pass", + "message": "package.json declares a public package identity and version", + "remediation": "Add a non-private package with a semver version and repository metadata.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-001", + "level": "required", + "status": "pass", + "message": "Chinese-default and English README files link to one another", + "remediation": "Add README.md and README.en.md with reciprocal language links.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-002", + "level": "required", + "status": "pass", + "message": "Chinese and English documentation directories are present", + "remediation": "Provide equivalent docs/zh-CN and docs/en quick-start/API guidance.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DOC-003", + "level": "required", + "status": "pass", + "message": "README or package metadata exposes GitHub, npm, and live Demo links", + "remediation": "Add repository, package, and Demo URLs to README and manifest.", + "path": "README.md", + "evidence": "README.md" + }, + { + "id": "DEMO-001", + "level": "required", + "status": "pass", + "message": "A runnable standalone Demo entry exists", + "remediation": "Add a Demo app with a documented start/build command.", + "path": "demo/index.html", + "evidence": "demo/index.html" + }, + { + "id": "DEMO-002", + "level": "required", + "status": "pass", + "message": "Demo declares Chinese as its initial language", + "remediation": "Set lang or default language state to zh-CN.", + "path": "demo/index.html", + "evidence": "demo/index.html, demo/public/examples/vanilla.html, demo/src/App.tsx" + }, + { + "id": "DEMO-003", + "level": "required", + "status": "pass", + "message": "Demo provides an in-page Chinese/English toggle", + "remediation": "Add a language toggle that does not alter inference state.", + "path": "demo/src/App.tsx", + "evidence": "demo/src/App.tsx, demo/src/media/MediaWorkspace.tsx, demo/src/style.css" + }, + { + "id": "DEMO-004", + "level": "required", + "status": "pass", + "message": "Demo exposes current-model and global cache cleanup controls", + "remediation": "Wire clear-current and clear-all actions to the SDK cache API.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-005", + "level": "required", + "status": "pass", + "message": "Demo 展示当前模型或算法的信息、运行信息和耗时", + "remediation": "模型使用 data-sdk-model-info,算法使用 data-sdk-algorithm-info;两者保留 data-sdk-runtime-info 和 data-sdk-timing。", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "DEMO-006", + "level": "required", + "status": "skip", + "message": "算法 Demo 提供状态复位操作", + "remediation": "使用 data-sdk-state-reset 标记复位控件,并按状态生命周期契约连接 reset。", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;清单已通过完整校验。" + }, + { + "id": "ALGORITHM-001", + "level": "required", + "status": "skip", + "message": "算法清单声明身份、家族、来源、许可、输入输出与有状态语义", + "remediation": "按 sdk-manifest.algorithm.yaml 填写 algorithm 字段并记录状态生命周期。", + "path": "sdk-manifest.yaml", + "evidence": "当前类型为 model,本规则仅适用于 algorithm;清单已通过完整校验。" + }, + { + "id": "MODEL-001", + "level": "required", + "status": "pass", + "message": "Manifest declares model identity, precision, size, source, license, and checksum", + "remediation": "Complete the model and asset fields in sdk-manifest.yaml.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "RUNTIME-001", + "level": "required", + "status": "pass", + "message": "Requested/actual backend and execution mode are declared", + "remediation": "Add runtime backends, execution modes, and actual backend reporting.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "PERF-001", + "level": "required", + "status": "pass", + "message": "声明当前 SDK 类型所需的标准耗时字段", + "remediation": "模型保留下载、缓存、校验、会话、推理和总耗时;算法声明 validationMs、predictionMs、associationMs、updateMs、totalMs。", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "CACHE-001", + "level": "required", + "status": "pass", + "message": "Cache storage, versioning, estimate, and cleanup are declared", + "remediation": "Add cache contract fields and expose cleanup controls in the Demo.", + "path": "sdk-manifest.yaml", + "evidence": "sdk-manifest.yaml" + }, + { + "id": "EXAMPLE-001", + "level": "required", + "status": "pass", + "message": "Vanilla TypeScript/DOM portability example exists", + "remediation": "Add examples/vanilla with a runnable README.", + "path": "examples/vanilla/README.md", + "evidence": "examples/vanilla/README.md" + }, + { + "id": "EXAMPLE-002", + "level": "required", + "status": "pass", + "message": "React reference example exists", + "remediation": "Add examples/react or explicitly record a migration exception.", + "path": "examples/react/README.md", + "evidence": "examples/react/README.md" + }, + { + "id": "EXAMPLE-003", + "level": "recommended", + "status": "pass", + "message": "Declared target surfaces have runnable examples or explicit unsupported status", + "remediation": "Align examples with manifest target surfaces.", + "path": "examples/vanilla/README.md", + "evidence": "examples/vanilla/README.md, examples/react/README.md, examples/vite/README.md" + }, + { + "id": "RELEASE-001", + "level": "required", + "status": "pass", + "message": "CI workflow runs verification before release", + "remediation": "Add .github/workflows/ci.yml with tests, typecheck, and build.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "RELEASE-002", + "level": "required", + "status": "pass", + "message": "GitHub Release workflow exists", + "remediation": "Add a tag-triggered release workflow and publish notes.", + "path": ".github/workflows/release.yml", + "evidence": ".github/workflows/release.yml" + }, + { + "id": "RELEASE-003", + "level": "recommended", + "status": "pass", + "message": "Changelog documents user-visible SDK and Demo changes", + "remediation": "Add CHANGELOG.md with the current release entry.", + "path": ".github/workflows/ci.yml", + "evidence": ".github/workflows/ci.yml" + }, + { + "id": "GOV-001", + "level": "required", + "status": "skip", + "message": "The default branch has an active least-privilege Ruleset for pull requests, current CI checks, resolved conversations, deletion, and force-push protection", + "remediation": "Configure an active default-branch Ruleset using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "GOV-002", + "level": "required", + "status": "skip", + "message": "Release tags are immutable under an active tag Ruleset", + "remediation": "Protect the documented release tag pattern against updates and deletion, minimize bypass, and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "DEPLOY-001", + "level": "required", + "status": "skip", + "message": "The live Demo has a reproducible HTTPS deployment from protected source with least-privilege credentials", + "remediation": "Configure and verify a deployment that meets standards/v1/repository-governance-contract.md, then record its commit and deployment evidence.", + "evidence": "Requires read-only remote-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "PAGES-001", + "level": "required", + "status": "skip", + "message": "A GitHub Pages Demo deploys through GitHub Actions with scoped permissions, environment binding, HTTPS, and concurrency control", + "remediation": "Configure Pages and its deployment workflow using standards/v1/repository-governance-contract.md and capture dated GitHub API evidence.", + "evidence": "Requires read-only github-api verification; offline sdk:check did not evaluate this rule." + }, + { + "id": "UI-001", + "level": "recommended", + "status": "pass", + "message": "Demo styling references the shared token vocabulary", + "remediation": "Import or copy standards/v1/ui-tokens.json values without introducing conflicting status colors.", + "path": "standards/v1/ui-tokens.json", + "evidence": "standards/v1/ui-tokens.json" + }, + { + "id": "LABS-001", + "level": "labs", + "status": "skip", + "message": "Experimental backends and NPU claims have explicit evidence and limits", + "remediation": "Mark WebNN/NPU as labs unless a dated verification matrix exists.", + "evidence": "Labs rule is informational" + } + ] + } + ] +} diff --git a/reports/tracking/2026-09-19-foundation/verify-standard-regression.mjs b/reports/tracking/2026-09-19-foundation/verify-standard-regression.mjs new file mode 100644 index 0000000..925283e --- /dev/null +++ b/reports/tracking/2026-09-19-foundation/verify-standard-regression.mjs @@ -0,0 +1,72 @@ +import assert from 'node:assert/strict'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import os from 'node:os'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +import { createHash } from 'node:crypto'; +import { execFileSync } from 'node:child_process'; +import { protectOutput, writeReport } from './output-path.mjs'; + +const root = path.dirname(fileURLToPath(import.meta.url)); +const portal = path.resolve(root, '../../..'); +const args = process.argv.slice(2); +const mode = args.shift() ?? 'verify'; +assert.ok(['verify', 'rerun'].includes(mode), '模式为 verify 或 rerun'); +const options = { 'repo-root': path.resolve(portal, '..'), out: path.join(portal, '.tmp/standard-regression-rerun.json') }; +for (let i = 0; i < args.length; i += 2) { + const key = args[i].replace(/^--/, ''); + assert.ok(args[i].startsWith('--') && Object.hasOwn(options, key) && args[i + 1], '参数为 --repo-root 路径、--out 路径'); + options[key] = path.resolve(args[i + 1]); +} +protectOutput(options.out, root); +const bytes = await fs.readFile(path.join(root, 'standard-regression.json')); +assert.equal(createHash('sha256').update(bytes).digest('hex'), '3c20f94d6e7f099cfc4e14d1848c120ae259249bfd47237ee1394de86af712d4', '原始标准回归证据已变更'); +const report = JSON.parse(bytes); +assert.equal(report.records.length, 7); +for (const record of report.records) { + assert.match(record.commit, /^[a-f0-9]{40}$/); + const previous = new Map(record.baseline.map(x => [x.id, x])); + const changes = record.current.filter(x => previous.has(x.id) && x.status !== previous.get(x.id).status).map(x => ({ id: x.id, before: previous.get(x.id).status, after: x.status })); + assert.deepEqual(changes, record.changes); + assert.deepEqual(changes, []); + for (const side of ['baseline', 'current']) { + assert.deepEqual(record[side].filter(x => x.level === 'required' && x.status === 'fail').map(x => x.id), record[side + 'Failures']); + assert.deepEqual(record[side + 'Failures'], []); + } +} +if (mode === 'verify') { + console.log('原始报告摘要与7个SDK的既有规则状态核对通过;未重新扫描或修改SDK。'); +} else { + // 全部基于记录中的不可变提交,不读取用户工作目录的未提交内容。 + const work = await fs.mkdtemp(path.join(os.tmpdir(), 'tracking-standards-')); + const unpack = async (repository, commit, name, paths = []) => { + const target = path.join(work, name); + await fs.mkdir(target); + const archive = path.join(work, name + '.zip'); + execFileSync('git', ['-C', repository, 'archive', '--format=zip', '--output', archive, commit, ...paths]); + // Windows系统tar对既有中文截图路径报错;Python标准库按ZIP的UTF-8文件名解包。 + execFileSync('python', ['-m', 'zipfile', '-e', archive, target]); + return target; + }; + const baselineCommit = 'df2863ec22e73790f35fcf57c673a55afd4a1be0'; + const currentCommit = '063e8c215b1791d43d3ee704bcb83006ddc43611'; + const oldRoot = await unpack(portal, baselineCommit, 'baseline', ['standards/v1', 'tools/sdk-standard-check/src']); + const newRoot = await unpack(portal, currentCommit, 'current', ['standards/v1', 'tools/sdk-standard-check/src']); + // 快照检查器复用门户已安装依赖;不复制生产SDK实现到门户。 + await fs.symlink(path.join(portal, 'node_modules'), path.join(oldRoot, 'node_modules'), 'junction'); + await fs.symlink(path.join(portal, 'node_modules'), path.join(newRoot, 'node_modules'), 'junction'); + const oldScan = (await import(pathToFileURL(path.join(oldRoot, 'tools/sdk-standard-check/src/check.mjs')))).scanRepository; + const newScan = (await import(pathToFileURL(path.join(newRoot, 'tools/sdk-standard-check/src/check.mjs')))).scanRepository; + const records = []; + for (const original of report.records) { + const snapshot = await unpack(path.join(options['repo-root'], original.repository), original.commit, original.repository); + const baseline = await oldScan(snapshot, { standardRoot: path.join(oldRoot, 'standards/v1') }); + const current = await newScan(snapshot, { standardRoot: path.join(newRoot, 'standards/v1') }); + const statuses = findings => findings.map(({ id, level, status }) => ({ id, level, status })); + assert.deepEqual(statuses(baseline.findings), statuses(original.baseline), original.repository + '旧规则状态偏离'); + assert.deepEqual(statuses(current.findings), statuses(original.current), original.repository + '新规则状态偏离'); + records.push({ repository: original.repository, commit: original.commit, baseline: baseline.findings, current: current.findings }); + } + await writeReport(options.out, JSON.stringify({ verifiedAt: new Date().toISOString(), baselineCommit, currentCommit, snapshots: work, records }, null, 2) + '\n', root); + console.log('7个固定提交快照复跑通过:' + options.out + ';临时快照保留于 ' + work); +} diff --git a/reports/tracking/2026-09-19-release-candidate/README.md b/reports/tracking/2026-09-19-release-candidate/README.md new file mode 100644 index 0000000..3ab0027 --- /dev/null +++ b/reports/tracking/2026-09-19-release-candidate/README.md @@ -0,0 +1,27 @@ +# 2026-09-19 门户纯算法发布候选验证 + +本地分支基于 `9db2871a8339cc585b5cac6bd24190a72429ae38`,仅准备 PP-Tracking 第八条记录。生产合并等待独立 SDK 的 npm、Release、HTTPS Demo 和治理证据,不声明已上线。 + +先扩 `standards/v1/portal-contract.md`,再实现模型/算法互斥 schema:缺省模型继续要求 assets 非空且禁止 algorithm;算法 assets=[],完整 algorithm 元数据必填。保留原七款模型;新增 CPU / JavaScript、多目标跟踪、来源与状态详情;门户无跟踪 runtime。 + +## 测试证据 + +所有 pnpm 命令均带 `--config.verify-deps-before-run=false --config.manage-package-manager-versions=false`。 + +- RED:`pnpm ... test src/lib/registry/schema.test.ts`,4 项中 2 失败:CPU 算法不能解析、模型 algorithm 被静默丢弃。符合新增契约预期。 +- GREEN:`pnpm ... test src/lib/registry src/content/models/registry.test.ts src/components/registry/ModelDirectory.test.tsx`,4 文件 20 项通过。 +- `pnpm ... test`:12 文件 99 项全部通过,含 checker/schema 回归。 +- `pnpm ... build`:Astro check 0 errors、0 warnings、7 hints;21 页面构建成功。hints 为已有历史报告脚本类型提示及原 z.string().url() 弃用提示,未扩大本轮范围。 +- `pnpm ... test:e2e`:16 项全过,覆盖原七款模型与新增算法;1280px/390px 的 CPU 筛选、任务分类、详情来源/状态/无权重、准确远程链接和无横向溢出。环境存在既有 NO_COLOR/FORCE_COLOR 提示,不影响结果。 +- SDK 修改前后 `pnpm ... sdk:check -- --repo F:/git/00_chenmohan/github/web-sdk-PP-Tracking --format json --out <报告路径>` 均退出 0;[修改前](../../sdk-standard/pp-tracking-2026-09-19-release-before.json)、[修改后](../../sdk-standard/pp-tracking-2026-09-19-release-after.json):required 17 pass / 0 fail / 7 skip,recommended 3 pass,仅 locally-compliant。 + +浏览器复用 production preview:`ASTRO_PREVIEW_BACKGROUND=0 node node_modules/astro/bin/astro.mjs preview --host 127.0.0.1 --port 4321`,并使用已安装的 Playwright Chromium(`PLAYWRIGHT_BROWSERS_PATH=F:/git/00_chenmohan/github/web-sdk-PP-Detection/.tmp/dependencies-compatible-browsers`)。没有为本任务修改 dev 服务或依赖。 + +已目检以下截图,内容非空、布局无交叠;390px 只代表桌面窄视口: + +- [1280px 目录](tracking-directory-1280.png) +- [390px 目录](tracking-directory-390.png) +- [1280px 详情](tracking-detail-1280.png) +- [390px 详情](tracking-detail-390.png) + +Pages workflow 的 pages/id-token 写权限移至 deploy job,部署串行、不取消正在进行的部署,保留原构建命令。两份路线已同步至候选及真实 MOT17 训练集证据,Workflow 继续暂缓。 diff --git a/reports/tracking/2026-09-19-release-candidate/tracking-detail-1280.png b/reports/tracking/2026-09-19-release-candidate/tracking-detail-1280.png new file mode 100644 index 0000000..2cf31cb Binary files /dev/null and b/reports/tracking/2026-09-19-release-candidate/tracking-detail-1280.png differ diff --git a/reports/tracking/2026-09-19-release-candidate/tracking-detail-390.png b/reports/tracking/2026-09-19-release-candidate/tracking-detail-390.png new file mode 100644 index 0000000..0f3a2aa Binary files /dev/null and b/reports/tracking/2026-09-19-release-candidate/tracking-detail-390.png differ diff --git a/reports/tracking/2026-09-19-release-candidate/tracking-directory-1280.png b/reports/tracking/2026-09-19-release-candidate/tracking-directory-1280.png new file mode 100644 index 0000000..d09c1b7 Binary files /dev/null and b/reports/tracking/2026-09-19-release-candidate/tracking-directory-1280.png differ diff --git a/reports/tracking/2026-09-19-release-candidate/tracking-directory-390.png b/reports/tracking/2026-09-19-release-candidate/tracking-directory-390.png new file mode 100644 index 0000000..5b50347 Binary files /dev/null and b/reports/tracking/2026-09-19-release-candidate/tracking-directory-390.png differ diff --git a/reports/tracking/2026-09-19-release/README.md b/reports/tracking/2026-09-19-release/README.md new file mode 100644 index 0000000..ce53383 --- /dev/null +++ b/reports/tracking/2026-09-19-release/README.md @@ -0,0 +1,19 @@ +# PP-Tracking 0.1.0 发布与门户登记候选 + +日期:2026-09-19。独立 SDK `web-sdk-pp-tracking@0.1.0` 的 npm、GitHub Release、HTTPS Demo、仓库治理与 Pages 部署已完成远程核验;门户第八个算法条目已具备登记条件。本目录只记录门户合并前的链接核验与候选状态,不能作为门户生产站已包含第八条的证据。 + +## 独立 SDK 链接核验 + +- 仓库与不可变来源提交:[`chenmohan123/web-sdk-PP-Tracking`](https://github.com/chenmohan123/web-sdk-PP-Tracking),`c2ee347884426aa1a03962b76ac2915959397611`。 +- npm:[`web-sdk-pp-tracking@0.1.0`](https://www.npmjs.com/package/web-sdk-pp-tracking/v/0.1.0)。公开 tarball 为 16541 字节,sha512 integrity 与本地唯一候选一致,并已完成 ESM/CJS 与状态 API 实际消费。 +- GitHub Release:[`v0.1.0`](https://github.com/chenmohan123/web-sdk-PP-Tracking/releases/tag/v0.1.0)。资产 SHA256 为 `4b532782a008a5ef411d6db00fb58900884fef0c1759c15c9441d30a3093b2bb`。 +- HTTPS Demo:[`https://chenmohan123.github.io/web-sdk-PP-Tracking/`](https://chenmohan123.github.io/web-sdk-PP-Tracking/)。线上交互证据仍限 Windows 桌面 Chromium 153、CPU/main 与 390px 桌面窄视口,不扩展手机或跨浏览器声明。 +- SDK 完整发布证据:[独立仓库交付目录](https://github.com/chenmohan123/web-sdk-PP-Tracking/tree/main/reports/2026-09-19-release)。门户侧摘要见 [sdk-delivery.json](sdk-delivery.json)。 + +首版由本机认证发布,npm registry 返回 `provenance: null`。Trusted Publisher 已通过 HTTP 201 保存为仓库 `chenmohan123/web-sdk-PP-Tracking`、工作流 `release.yml`、环境 `npm`;配置回执没有独立 GET,Release 工作流只核对已存在的同完整性版本并跳过重复发布。因此 0.1.0 不声明经过 OIDC 发布;未来新版本须以实际 npm 回执为准。 + +## 门户候选状态 + +`src/content/models/pp-tracking.yaml` 保持 `status: beta`、CPU/JavaScript 主线程、空资产与无需模型权重语义,并保留固定 MOT17 训练序列、状态生命周期、设备和浏览器限制。beta 表示算法质量与兼容性边界,不表示 SDK 链接仍待发布。 + +当前分支只准备门户第八条记录和部署内容。门户 PR、合并、生产站第八条、筛选/详情及线上回放尚待主代理完成并回读;完成前不得把本报告称为生产验收回执。 diff --git a/reports/tracking/2026-09-19-release/sdk-delivery.json b/reports/tracking/2026-09-19-release/sdk-delivery.json new file mode 100644 index 0000000..b6888ce --- /dev/null +++ b/reports/tracking/2026-09-19-release/sdk-delivery.json @@ -0,0 +1,47 @@ +{ + "verifiedAt": "2026-09-19T05:52:51.7386765Z", + "sdk": { + "repository": "https://github.com/chenmohan123/web-sdk-PP-Tracking", + "sourceCommit": "c2ee347884426aa1a03962b76ac2915959397611", + "package": { + "name": "web-sdk-pp-tracking", + "version": "0.1.0", + "url": "https://www.npmjs.com/package/web-sdk-pp-tracking/v/0.1.0", + "tarball": "https://registry.npmjs.org/web-sdk-pp-tracking/-/web-sdk-pp-tracking-0.1.0.tgz", + "bytes": 16541, + "integrity": "sha512-0ujJfrcXoDcynzIUYQRI7pcETWT1x2t4LkEqB1D2cGQrnT8JCfk9LNrEZwAIDnBh1TLILcPmOaUbCDxsjE+tTQ==", + "provenance": null, + "consumptionVerified": true + }, + "release": { + "url": "https://github.com/chenmohan123/web-sdk-PP-Tracking/releases/tag/v0.1.0", + "id": 391930716, + "assetSha256": "4b532782a008a5ef411d6db00fb58900884fef0c1759c15c9441d30a3093b2bb", + "workflow": "https://github.com/chenmohan123/web-sdk-PP-Tracking/actions/runs/35424969266", + "workflowMode": "verified-existing", + "workflowConclusion": "success" + }, + "demo": { + "url": "https://chenmohan123.github.io/web-sdk-PP-Tracking/", + "verified": true, + "boundary": "Windows 桌面 Chromium 153、CPU/main;390px 为桌面窄视口。" + }, + "trustedPublishing": { + "status": "configured", + "configurationId": "da2f97a7-680c-4041-b902-26c74f639a3c", + "repository": "chenmohan123/web-sdk-PP-Tracking", + "workflow": "release.yml", + "environment": "npm", + "httpStatus": 201, + "independentGetPerformed": false, + "oidcPublicationVerified": false + } + }, + "portal": { + "record": "src/content/models/pp-tracking.yaml", + "recordStatus": "beta", + "deliveryState": "本地候选,待门户 PR、合并与生产回读", + "productionVerified": false + }, + "boundary": "独立 SDK 已发布;当前证据不声明门户生产站已包含第八条,也不声明 0.1.0 经 OIDC 发布。" +} diff --git a/skills/web-model-sdk-standard/references/scaffold.md b/skills/web-model-sdk-standard/references/scaffold.md index ca5d9e0..2a2e1aa 100644 --- a/skills/web-model-sdk-standard/references/scaffold.md +++ b/skills/web-model-sdk-standard/references/scaffold.md @@ -9,3 +9,13 @@ Vanilla baseline and React reference example. Keep the runtime framework-neutral Run the portal checker against the new local path before opening a release PR. Do not publish npm or create a GitHub Release as part of scaffolding unless the user explicitly requests that external operation. + +## 纯算法脚手架 + +纯算法选择 `standards/v1/templates/sdk-manifest.algorithm.yaml`,复制为 +`sdk-manifest.yaml`;模型继续使用原模型模板。按标准 1.2.0 填写 algorithm +的来源、许可、输入输出和 stateful,删除模型下载/缓存 UI 的假设。 +沿用双语 README 和公共 checklist,其中模型专属项不适用;算法专属项必须 +验证。状态生命周期、复位、Demo 标记和计时语义均以 standards/v1 契约为准。 +运行本地检查器,保留所有不适用项的 skip 理由与清单证据;无效清单不能 +获得算法豁免。仅声明实际已实现的执行模式,不预先添加 Worker 空实现。 diff --git a/src/components/model/BackendTable.astro b/src/components/model/BackendTable.astro index 9c94911..5e2711d 100644 --- a/src/components/model/BackendTable.astro +++ b/src/components/model/BackendTable.astro @@ -1,6 +1,7 @@ --- import type { ModelData } from '../../lib/registry/types'; +import { backendDisplayNames } from '../../lib/registry/labels'; const { runtime } = Astro.props as Pick; --- -{runtime.backends.map((backend) => )}
后端状态
{backend.name}{backend.status}
+{runtime.backends.map((backend) => )}
后端状态
{backendDisplayNames[backend.name]}{backend.status}
{runtime.verifiedEnvironments.length === 0 &&

当前没有公开设备验证记录;后端状态不代表所有环境兼容。

} diff --git a/src/components/registry/ModelDirectory.test.tsx b/src/components/registry/ModelDirectory.test.tsx index 4728ba9..89e39dd 100644 --- a/src/components/registry/ModelDirectory.test.tsx +++ b/src/components/registry/ModelDirectory.test.tsx @@ -3,6 +3,9 @@ import { fireEvent, render, screen } from '@testing-library/react'; import { describe, expect, it } from 'vitest'; import ModelDirectory from './ModelDirectory'; import type { ModelData } from '../../lib/registry/types'; +import { readFileSync } from 'node:fs'; +import { parse } from 'yaml'; +import { modelSchema } from '../../lib/registry/schema'; const common = { brand: 'baidu', status: 'available', repository: 'https://example.com', license: 'Apache-2.0', package: { name: 'example', version: '1.0.0' }, demo: { url: 'https://example.com/demo', localProcessing: true }, runtime: { backends: [{ name: 'webgpu', status: 'stable' }], capabilities: [], verifiedEnvironments: [] }, io: { input: ['Blob'], output: ['JSON'] }, assets: [{ id: 'fp16', precision: 'fp16', bytes: 1, url: 'https://example.com/model', sha256: 'a'.repeat(64) }], limitations: [] } as const; const models = [ @@ -14,6 +17,16 @@ const models = [ ] as unknown as ModelData[]; describe('ModelDirectory', () => { + it('CPU 过滤显示独立算法及无需模型权重', () => { + const tracking = modelSchema.parse(parse(readFileSync('src/content/models/pp-tracking.yaml', 'utf8'))); + render(); + fireEvent.change(screen.getByRole('combobox', { name: '后端' }), { target: { value: 'cpu' } }); + fireEvent.change(screen.getByRole('combobox', { name: '任务' }), { target: { value: 'multi-object-tracking' } }); + expect(screen.getByText('1 个条目')).toBeVisible(); + expect(screen.getByText('纯算法 · 无需模型权重')).toBeVisible(); + expect(screen.getByRole('link', { name: 'PP-Tracking' })).toHaveAttribute('href', '/models/pp-tracking/'); + expect(screen.queryByText('PP-DocLayoutV3')).not.toBeInTheDocument(); + }); it('旋转框检测分类只展示独立 SDK 并提供详情入口', () => { render(); expect(screen.getByRole('option', { name: '旋转框检测' })).toHaveValue('rotated-detection'); @@ -53,6 +66,6 @@ describe('ModelDirectory', () => { it('shows an honest empty state', () => { render(); fireEvent.change(screen.getByRole('searchbox'), { target: { value: 'not-a-model' } }); - expect(screen.getByText('没有符合条件的模型')).toBeVisible(); + expect(screen.getByText('没有符合条件的 SDK')).toBeVisible(); }); }); diff --git a/src/components/registry/ModelDirectory.tsx b/src/components/registry/ModelDirectory.tsx index 31c9952..b5066fd 100644 --- a/src/components/registry/ModelDirectory.tsx +++ b/src/components/registry/ModelDirectory.tsx @@ -1,7 +1,7 @@ import { useMemo, useState } from 'react'; import { ArrowUpRight, Search } from 'lucide-react'; import { filterModels, type ModelFilters } from '../../lib/registry/query'; -import { taskDisplayNames } from '../../lib/registry/labels'; +import { backendDisplayNames, taskDisplayNames } from '../../lib/registry/labels'; import type { ModelData } from '../../lib/registry/types'; import './model-directory.css'; @@ -15,22 +15,22 @@ export default function ModelDirectory({ models }: { models: ModelData[] }) { const visible = useMemo(() => filterModels(models, filters), [models, filters]); const set = (key: K, value: ModelFilters[K]) => setFilters((current) => ({ ...current, [key]: value })); - return
+ return
- + - +

{visible.length} 个条目

- {visible.length === 0 ?
没有符合条件的模型
:
{visible.map((model) =>
+ {visible.length === 0 ?
没有符合条件的 SDK
:
{visible.map((model) =>

{model.brand} · {taskDisplayNames[model.task] ?? model.task}

{model.name}

{statusLabels[model.status]}

{model.summary}

-
{model.runtime.backends.map((backend) => {backend.name} · {backend.status})}
+
{model.runtime.backends.map((backend) => {backendDisplayNames[backend.name]} · {backend.status})}{model.kind === 'algorithm' && 纯算法 · 无需模型权重}
查看 SDK
)}
}
; diff --git a/src/content/models/pp-tracking.yaml b/src/content/models/pp-tracking.yaml new file mode 100644 index 0000000..4d524b9 --- /dev/null +++ b/src/content/models/pp-tracking.yaml @@ -0,0 +1,38 @@ +id: pp-tracking +kind: algorithm +name: PP-Tracking +brand: self-developed +task: multi-object-tracking +status: beta +summary: 独立实现 ByteTrack 高低分两阶段关联思想的 CPU 主线程多目标跟踪算法,消费检测框并输出有状态轨迹;0.1.0 已发布至 npm、GitHub Release 与 HTTPS Demo。 +repository: https://github.com/chenmohan123/web-sdk-PP-Tracking +license: Apache-2.0 +package: { name: web-sdk-pp-tracking, version: 0.1.0 } +demo: { url: 'https://chenmohan123.github.io/web-sdk-PP-Tracking/', localProcessing: true } +runtime: + backends: [{ name: cpu, status: stable }] + capabilities: [main, stateful, reset, detection-input] + verifiedEnvironments: + - browser: Chromium 153.0.8010.12 / Playwright 1.63.0 + os: Windows 11 专业版 10.0.26200 + device: Intel Core i5-10400F @2.90GHz + testedAt: '2026-09-19' +io: + input: [TrackingFrame(时间戳、图像尺寸、原图检测框与分数)] + output: [TrackingResult(轨迹 ID、状态、位置、实际后端与五项耗时)] +assets: [] +algorithm: + id: pp-tracking + version: 0.1.0 + family: ByteTrack 机制多目标跟踪 + source: '独立实现;ByteTrack 论文 https://arxiv.org/abs/2110.06864;不是百度或 ByteTrack 官方移植,来源与实现差异见独立仓库 NOTICE 和算法指南。' + license: Apache-2.0 + input: TrackingFrame + output: TrackingResult + stateful: true +limitations: + - 无需模型权重;只消费已有检测,不含检测模型、视频解码、摄像头、ReID 或相机运动补偿。轨迹 ID 不是个人身份。 + - 2026-09-19 固定 MOT17 七段 FRCNN 训练序列 5316 帧,默认 IDF1 48.2922%、IDSW 1101、MOTA 44.4010%、FP 4169、FN 57166;不是测试集成绩或官方 ByteTrack 排名。 + - 低分消融 IDF1 48.3465%、IDSW 1066;默认低分续接减少漏检但增加误检和切 ID,不承诺普遍精度提升或可靠跨遮挡身份。 + - 状态保存在实例内,seek 或图像尺寸改变前须 reset 并顺序重放;dispose 后不可继续更新。 + - 仅验证 Windows 桌面 CPU/main;390px 为桌面窄视口,手机、Safari、Firefox、微信、Worker、WASM、WebGPU 与 NPU 尚未验证或未实现。 diff --git a/src/content/models/registry.test.ts b/src/content/models/registry.test.ts index 7773c42..ba9308a 100644 --- a/src/content/models/registry.test.ts +++ b/src/content/models/registry.test.ts @@ -8,7 +8,7 @@ describe("model registry", () => { const models = readdirSync("src/content/models") .filter((file) => file.endsWith(".yaml")) .map((file) => modelSchema.parse(parse(readFileSync(`src/content/models/${file}`, "utf8")))); - expect(models).toHaveLength(7); + expect(models).toHaveLength(8); const model = models.find((entry) => entry.id === "pp-tinypose"); expect(model).toBeDefined(); expect(model?.task).toBe("pose-estimation"); diff --git a/src/lib/registry/labels.ts b/src/lib/registry/labels.ts index 8458c01..b66663e 100644 --- a/src/lib/registry/labels.ts +++ b/src/lib/registry/labels.ts @@ -4,4 +4,7 @@ export const taskDisplayNames: Partial> = { 'rotated-detection': '旋转框检测', 'pose-estimation': '人体姿态', 'instance-segmentation': '实例分割', + 'multi-object-tracking': '多目标跟踪', }; + +export const backendDisplayNames = { cpu: 'CPU / JavaScript', wasm: 'wasm', webgpu: 'webgpu', webnn: 'webnn' }; diff --git a/src/lib/registry/query.test.ts b/src/lib/registry/query.test.ts index 42600e9..a8a83a4 100644 --- a/src/lib/registry/query.test.ts +++ b/src/lib/registry/query.test.ts @@ -1,6 +1,9 @@ import { describe, expect, it } from 'vitest'; import { filterModels, groupCounts } from './query'; import type { ModelData } from './types'; +import { readFileSync } from 'node:fs'; +import { parse } from 'yaml'; +import { modelSchema } from './schema'; const common = { brand: 'baidu', status: 'available', repository: 'https://example.com', license: 'Apache-2.0', @@ -18,6 +21,10 @@ const models = [ ] as unknown as ModelData[]; describe('filterModels', () => { + it('按 CPU 和算法家族过滤跟踪 SDK', () => { + const tracking = modelSchema.parse(parse(readFileSync('src/content/models/pp-tracking.yaml', 'utf8'))); + expect(filterModels([...models, tracking], { query: 'ByteTrack', task: 'multi-object-tracking', status: 'all', backend: 'cpu', brand: 'self-developed' }).map(item => item.id)).toEqual(['pp-tracking']); + }); it('combines text, task, status, and backend filters', () => { expect(filterModels(models, { query: 'layout', task: 'document-layout', status: 'available', backend: 'webgpu', brand: 'all' }).map((model) => model.id)).toEqual(['layout']); }); diff --git a/src/lib/registry/query.ts b/src/lib/registry/query.ts index ef27f97..5e34917 100644 --- a/src/lib/registry/query.ts +++ b/src/lib/registry/query.ts @@ -11,7 +11,7 @@ export interface ModelFilters { export function filterModels(models: ModelData[], filters: ModelFilters): ModelData[] { const query = filters.query.trim().toLocaleLowerCase(); return models.filter((model) => { - const haystack = `${model.name} ${model.summary} ${model.package.name}`.toLocaleLowerCase(); + const haystack = `${model.name} ${model.summary} ${model.package.name} ${model.algorithm?.family ?? ''}`.toLocaleLowerCase(); return (!query || haystack.includes(query)) && (filters.brand === 'all' || model.brand === filters.brand) && (filters.task === 'all' || model.task === filters.task) diff --git a/src/lib/registry/schema.test.ts b/src/lib/registry/schema.test.ts new file mode 100644 index 0000000..a52cf98 --- /dev/null +++ b/src/lib/registry/schema.test.ts @@ -0,0 +1,28 @@ +import { readFileSync, readdirSync } from 'node:fs'; +import { parse } from 'yaml'; +import { describe, expect, it } from 'vitest'; +import { modelSchema } from './schema'; + +const model = parse(readFileSync('src/content/models/pp-doclayoutv3.yaml', 'utf8')); +const tracking = { ...model, kind: 'algorithm', task: 'multi-object-tracking', assets: [], + runtime: { backends: [{ name: 'cpu', status: 'stable' }] }, + algorithm: { id: 'pp-tracking', version: '0.1.0', family: 'ByteTrack 机制', source: '独立实现;https://arxiv.org/abs/2110.06864', license: 'Apache-2.0', input: 'TrackingFrame', output: 'TrackingResult', stateful: true } }; + +describe('模型与算法互斥契约', () => { + it('继续接受原有七款模型', () => { + const records = readdirSync('src/content/models').filter(file => file.endsWith('.yaml') && file !== 'pp-tracking.yaml'); + expect(records).toHaveLength(7); + for (const file of records) expect(modelSchema.safeParse(parse(readFileSync(`src/content/models/${file}`, 'utf8'))).success).toBe(true); + }); + it('接受完整无权重 CPU 算法', () => expect(modelSchema.safeParse(tracking).success).toBe(true)); + it('拒绝缺来源、缺元数据及携带模型权重的算法', () => { + expect(modelSchema.safeParse({ ...tracking, algorithm: { ...tracking.algorithm, source: '' } }).success).toBe(false); + expect(modelSchema.safeParse({ ...tracking, algorithm: undefined }).success).toBe(false); + expect(modelSchema.safeParse({ ...tracking, assets: [model.assets[0]] }).success).toBe(false); + }); + it('拒绝模型缺资产、模型携带算法及未知类型', () => { + expect(modelSchema.safeParse({ ...model, assets: [] }).success).toBe(false); + expect(modelSchema.safeParse({ ...model, algorithm: tracking.algorithm }).success).toBe(false); + expect(modelSchema.safeParse({ ...tracking, kind: 'unknown' }).success).toBe(false); + }); +}); diff --git a/src/lib/registry/schema.ts b/src/lib/registry/schema.ts index be9f93a..3395974 100644 --- a/src/lib/registry/schema.ts +++ b/src/lib/registry/schema.ts @@ -3,10 +3,11 @@ import { z } from 'zod'; export const backendStatusSchema = z.enum(['stable', 'fallback', 'experimental']); export const modelSchema = z.object({ + kind: z.enum(['model', 'algorithm']).default('model'), id: z.string().regex(/^[a-z0-9-]+$/), name: z.string().min(1), brand: z.string().regex(/^[a-z0-9-]+$/), - task: z.enum(['ocr', 'document-layout', 'detection', 'rotated-detection', 'pose-estimation', 'instance-segmentation', 'asr', 'tts', 'image-correction', 'vision-language']), + task: z.enum(['ocr', 'document-layout', 'detection', 'rotated-detection', 'pose-estimation', 'instance-segmentation', 'multi-object-tracking', 'asr', 'tts', 'image-correction', 'vision-language']), status: z.enum(['available', 'beta', 'in-development', 'research', 'not-applicable']), summary: z.string().min(20), repository: z.string().url(), @@ -14,11 +15,20 @@ export const modelSchema = z.object({ package: z.object({ name: z.string().min(1), version: z.string().regex(/^\d+\.\d+\.\d+$/) }), demo: z.object({ url: z.string().url(), localProcessing: z.boolean() }), runtime: z.object({ - backends: z.array(z.object({ name: z.enum(['webgpu', 'wasm', 'webnn']), status: backendStatusSchema })).min(1), + backends: z.array(z.object({ name: z.enum(['webgpu', 'wasm', 'webnn', 'cpu']), status: backendStatusSchema })).min(1), capabilities: z.array(z.string()).default([]), verifiedEnvironments: z.array(z.object({ browser: z.string(), os: z.string(), device: z.string(), testedAt: z.string().regex(/^\d{4}-\d{2}-\d{2}$/) })).default([]), }), io: z.object({ input: z.array(z.string()).min(1), output: z.array(z.string()).min(1) }), - assets: z.array(z.object({ id: z.string(), precision: z.string(), bytes: z.number().int().positive(), url: z.string().url(), sha256: z.string().regex(/^[a-f0-9]{64}$/) })).min(1), + assets: z.array(z.object({ id: z.string(), precision: z.string(), bytes: z.number().int().positive(), url: z.string().url(), sha256: z.string().regex(/^[a-f0-9]{64}$/) })), + algorithm: z.object({ id: z.string().trim().min(1), version: z.string().trim().min(1), family: z.string().trim().min(1), source: z.string().trim().min(1), license: z.string().trim().min(1), input: z.string().trim().min(1), output: z.string().trim().min(1), stateful: z.boolean() }).strict().optional(), limitations: z.array(z.string()).default([]), +}).superRefine((entry, context) => { + if (entry.kind === 'algorithm') { + if (!entry.algorithm) context.addIssue({ code: 'custom', path: ['algorithm'], message: '算法必须声明来源及完整元数据' }); + if (entry.assets.length !== 0) context.addIssue({ code: 'custom', path: ['assets'], message: '算法不得声明模型权重' }); + } else { + if (entry.algorithm) context.addIssue({ code: 'custom', path: ['algorithm'], message: '模型不得携带算法元数据' }); + if (entry.assets.length === 0) context.addIssue({ code: 'custom', path: ['assets'], message: '模型必须声明非空资产' }); + } }); diff --git a/src/lib/registry/types.ts b/src/lib/registry/types.ts index 01b2c05..ac116fe 100644 --- a/src/lib/registry/types.ts +++ b/src/lib/registry/types.ts @@ -4,3 +4,4 @@ export type ModelEntry = CollectionEntry<'models'>; export type ModelData = ModelEntry['data']; export type BackendName = ModelData['runtime']['backends'][number]['name']; export type ModelStatus = ModelData['status']; +export type SdkKind = ModelData['kind']; diff --git a/src/pages/index.astro b/src/pages/index.astro index 723bec1..a75685f 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -6,12 +6,12 @@ const models = (await getCollection('models')).map((entry) => entry.data); ---
-

浏览器端模型 SDK 目录

-

从本地优先的角度整理可在浏览器中使用的模型 SDK,帮助开发者快速了解能力、运行约束与集成入口。

+

浏览器端模型与算法 SDK 目录

+

从本地优先的角度整理可在浏览器中使用的模型与算法 SDK,帮助开发者快速了解能力、运行约束与集成入口。

diff --git a/src/pages/models/[slug].astro b/src/pages/models/[slug].astro index d38b99e..a12109c 100644 --- a/src/pages/models/[slug].astro +++ b/src/pages/models/[slug].astro @@ -19,5 +19,12 @@ const npmUrl = `https://www.npmjs.com/package/${data.package.name}`;

{data.brand} · {taskDisplayNames[data.task] ?? data.task}

{data.name}

{data.summary}

{model.id === 'pp-detection' &&

模型选型与对比 →

} {model.id === 'pp-tinypose' &&

规格与精度对比 →

} -

运行能力

模型资源

    {data.assets.map((asset) =>
  • {asset.id} · {mib(asset.bytes)} · SHA-256 已记录
  • )}

限制

    {data.limitations.map((item) =>
  • {item}
  • )}
+

运行能力

+ {data.kind === 'algorithm' && data.algorithm ?

算法信息

无需模型权重

+
算法与版本
{data.algorithm.id} · {data.algorithm.version}
+
家族
{data.algorithm.family}
来源
{data.algorithm.source}
+
许可
{data.algorithm.license}
状态
{data.algorithm.stateful ? '有状态;实例生命周期与复位规则见限制和独立 SDK 文档' : '无状态'}
+
输入
{data.algorithm.input}
输出
{data.algorithm.output}
+
:

模型资源

    {data.assets.map((asset) =>
  • {asset.id} · {mib(asset.bytes)} · SHA-256 已记录
  • )}
} +

限制

    {data.limitations.map((item) =>
  • {item}
  • )}
diff --git a/src/pages/tasks/[task].astro b/src/pages/tasks/[task].astro index 40ca0cf..743a8f1 100644 --- a/src/pages/tasks/[task].astro +++ b/src/pages/tasks/[task].astro @@ -10,5 +10,6 @@ export async function getStaticPaths() { const { task, models } = Astro.props as { task: CollectionEntry<'models'>['data']['task']; models: CollectionEntry<'models'>[] }; const taskLabel = taskDisplayNames[task] ?? task; +const kindLabel = models.every(model => model.data.kind === 'algorithm') ? '算法' : '模型'; --- -

{taskLabel}

+

{taskLabel}

diff --git a/standards/v1/README.en.md b/standards/v1/README.en.md index d86f2db..d01c3e3 100644 --- a/standards/v1/README.en.md +++ b/standards/v1/README.en.md @@ -1,9 +1,8 @@ # Web Model SDK Standard v1 [中文(默认)](README.md) is the primary entry point. This equivalent English -document uses standard version `1.1.0`. Version `1.1.0` remains compatible -with `1.0.0` SDK manifests because it adds repository governance rather than -runtime fields. +document uses standard version `1.2.0`, retaining compatibility with `1.0.0` +and `1.1.0` model manifests. Read the [runtime contract](sdk-contract.md), [single-SDK Demo contract](demo-contract.md), [portal boundary](portal-contract.md), [docs and release contract](docs-release-contract.md), @@ -12,7 +11,7 @@ Read the [runtime contract](sdk-contract.md), [single-SDK Demo contract](demo-co then the machine-readable [rules](rules.yaml), [manifest schema](sdk-manifest.schema.json), and [UI tokens](ui-tokens.json). -An SDK repository owns its framework-neutral runtime, npm package, current-model +An SDK repository owns its framework-neutral runtime, npm package, current-model or algorithm Demo, documentation, examples, benchmarks, CI, and Releases. The portal owns catalogs, categories, comparisons, introduction pages, and Workflow entry points. Cross-SDK execution starts only after compatible public contracts and a @@ -63,3 +62,30 @@ and path, an HTTP(S) `downloadUrl` with a host, positive byte count, and a An explicitly selected source must not be silently replaced after failure; only an `auto` policy may try sources in manifest order. A Git LFS pointer is not the browser-downloadable model payload. + +### Pure algorithm SDKs + +Only version `1.2.0` permits `kind: algorithm`. Omitted kind and `kind: model` +retain model requirements; an older version cannot claim algorithm exemptions. +Algorithm manifests require `algorithm` and prohibit `model` and `cache`; +model manifests prohibit `algorithm`. Required algorithm fields are nonempty +strings id, version, family, source, license, input, output, plus boolean stateful. +Input/output describe the contract or reference complete API documentation; +source records papers, code provenance, and implementation differences. Review +license obligations separately. + +Use the [algorithm template](templates/sdk-manifest.algorithm.yaml) and shared +checklists. Runtime reports the actual backend and execution mode; declare only +implemented modes. Required timings are validationMs, predictionMs, associationMs, +updateMs, totalMs. Cold means a new instance; warm means reused instance state. +Do not invent model download or cache timings. Demo markers are +data-sdk-algorithm-info, data-sdk-runtime-info, data-sdk-timing, and +data-sdk-state-reset. Document inputs, outputs, provenance, license, state +lifecycle, and reset semantics. + +Rules with appliesTo specify model or algorithm scope; omitted scope means both. +MODEL-001, CACHE-001, DEMO-004 are model-only. ALGORITHM-001 and DEMO-006 are +algorithm-only. Inapplicable rules retain skip status, manifest evidence path, +and a reason. Only a fully validated manifest grants type exemptions. Invalid +manifests produce CONFIG-001 and cannot bypass model requirements by claiming +algorithm kind. Repositories without manifests retain legacy model checks. diff --git a/standards/v1/README.md b/standards/v1/README.md index c750c1a..89e5966 100644 --- a/standards/v1/README.md +++ b/standards/v1/README.md @@ -1,8 +1,8 @@ # Web Model SDK Standard v1 中文是默认入口;[English](README.en.md) 提供等价英文说明。本文是所有 -SDK、Demo、门户和 Workflow 任务的阅读入口,规范版本为 `1.1.0`。`1.1.0` -仍兼容 `1.0.0` SDK manifest;模型清单可以通过可选的 `variants` 和 `sources` +SDK、Demo、门户和 Workflow 任务的阅读入口,规范版本为 `1.2.0`, +仍兼容 `1.0.0` / `1.1.0` 模型 SDK manifest;模型清单可以通过可选的 `variants` 和 `sources` 声明同一模型的精度、量化、后端和分发来源。 ## 阅读顺序 @@ -19,7 +19,7 @@ SDK、Demo、门户和 Workflow 任务的阅读入口,规范版本为 `1.1.0` ## 分层原则 -- 单 SDK 仓库负责当前模型的 runtime、npm 包、独立 Demo、文档、示例、 +- 单 SDK 仓库负责当前模型或算法的 runtime、npm 包、独立 Demo、文档、示例、 基准和 GitHub Release。 - `chenmohan123.github.io` 负责目录、分类、比较、SDK 介绍页以及组合技和 Workflow 的入口;单 SDK 介绍页跳转到对应仓库、npm 和 Demo。 @@ -27,7 +27,7 @@ SDK、Demo、门户和 Workflow 任务的阅读入口,规范版本为 `1.1.0` 才实现;必要时可以拆成独立 Workflow 网站。 统一的是语义、状态、数据字段和视觉令牌,不是每个页面的像素级复制。 -单 SDK Demo 是当前模型的工作台,门户是目录/检视器。 +单 SDK Demo 是当前模型或算法的工作台,门户是目录/检视器。 ## 合规等级 @@ -94,3 +94,25 @@ CDN/H5/web-view 的兼容基线;SDK runtime 不得依赖 UI 框架。Vue、CDN 40 至 64 位十六进制不可变 `revision`、仓库和路径、含主机的 HTTP(S) `downloadUrl`、正整数 `bytes` 及 64 位十六进制 `sha256`。显式选择的来源失败时不得静默换源;只有 `auto` 策略可以按清单尝试。Git LFS pointer 文件不是浏览器可用的模型本体。 + +### 纯算法 SDK + +仅 `1.2.0` 可声明 `kind: algorithm`。缺省 kind 或 `kind: model` +沿用模型规则,旧版不得通过算法 kind 绕过模型要求。算法与模型分支互斥: +算法必须声明 `algorithm`,禁止 `model` 和 `cache`;模型禁止 `algorithm`。 +`algorithm` 必填 id、version、family、source、license、input、output(非空字符串) +及 stateful(布尔值)。input/output 描述输入输出契约或指向完整 API 文档; +source 记录论文、代码来源和实现差异,许可义务须独立核对。 + +算法使用 [算法清单模板](templates/sdk-manifest.algorithm.yaml) 和公共 checklist。 +runtime 继续报告实际后端和执行模式,只声明已经实现的模式。 +算法耗时为 validationMs、predictionMs、associationMs、updateMs、totalMs; +cold 指新实例,warm 指复用实例状态,不伪造模型下载和缓存耗时。 +Demo 使用 data-sdk-algorithm-info、data-sdk-runtime-info、data-sdk-timing +和 data-sdk-state-reset。状态生命周期、复位、来源、许可、输入输出必须有文档。 + +规则的 appliesTo 声明模型或算法适用性;未声明表示两者适用。 +MODEL-001、CACHE-001、DEMO-004 仅适用模型;ALGORITHM-001、DEMO-006 +仅适用算法。不适用项保留 skip、清单证据路径及理由。 +只有完整校验通过的清单可决定类型豁免;无效清单仍产生 CONFIG-001, +不能靠 algorithm 声明跳过模型必需规则。无清单的旧仓库沿用模型检查。 diff --git a/standards/v1/demo-contract.md b/standards/v1/demo-contract.md index 9e7cba0..cb97476 100644 --- a/standards/v1/demo-contract.md +++ b/standards/v1/demo-contract.md @@ -1,6 +1,6 @@ # Single SDK Demo Contract -An SDK Demo focuses on one SDK/model. It is not a catalog and does not embed +An SDK Demo focuses on one SDK/model or algorithm. It is not a catalog and does not embed another SDK's inference implementation. ## Semantic regions @@ -17,7 +17,7 @@ another SDK's inference implementation. Chinese is the initial language. Switching to English changes UI copy only; refreshing may restore Chinese unless the Demo documents persistence. -The Demo exposes current-model cache usage, a current-model cleanup action, a +A model Demo exposes current-model cache usage, a current-model cleanup action, a global cleanup action, and a privacy statement. It must not render broken image previews for empty state. DOM markers such as `data-sdk-cache-clear`, `data-sdk-model-info`, `data-sdk-runtime-info`, and `data-sdk-timing` make the @@ -25,3 +25,18 @@ contract testable without prescribing a framework. Use [ui-tokens.json](ui-tokens.json) for colors, spacing, radius, focus, and status styles. Responsive layouts must not overflow on a 390px viewport. + +## 纯算法 Demo(1.2.0) + +上述模型名称、模型参数和缓存控件仅适用模型 SDK。纯算法 Demo 聚焦当前算法, +展示算法版本、家族、来源、许可、输入输出及状态限制;使用 +`data-sdk-algorithm-info` 替代模型信息标记,并保留 +`data-sdk-runtime-info`、`data-sdk-timing`。 + +提供 `data-sdk-state-reset` 控件并连接状态复位;重新开始、切换输入序列或 +seek 时按算法契约复位。复位同时清理当前结果,不冒充缓存清理。 +切换语言不得清空算法状态。无状态算法也提供清空结果的复位入口。 +不展示模型下载、缓存按钮或虚构 loading/downloading 阶段;算法计算状态仍 +使用适用的 idle、ready、running、success、error、unsupported 等语义。 +五个算法耗时字段见性能契约。静态标记检查只证明声明存在,交互必须通过 +浏览器验证。中文默认、隐私说明、可访问性和 390px 布局要求仍然适用。 diff --git a/standards/v1/docs-release-contract.md b/standards/v1/docs-release-contract.md index 6cef843..523ffa1 100644 --- a/standards/v1/docs-release-contract.md +++ b/standards/v1/docs-release-contract.md @@ -8,7 +8,7 @@ troubleshooting, privacy/deployment, and performance guidance. README and npm metadata expose install instructions, package name/version, GitHub repository, and live Demo. A public repository has CI, a changelog, at least one GitHub Release, and GitHub About description, Homepage/Demo URL, and -topics. Release notes identify model source, license, default assets, runtime +topics. Model release notes identify model source, license, default assets, runtime backends, and known limitations. Repository protection and live Demo delivery follow the @@ -19,3 +19,14 @@ files alone do not prove that those settings are active. Do not claim universal browser or device support from feature detection alone. Every compatibility entry records browser, OS, device, runtime/driver where relevant, and test date. + +## 纯算法文档与发布(1.2.0) + +算法 SDK 保留上述双语文档、示例、发布和带日期验证要求。以算法来源、许可、 +输入输出契约、状态生命周期和复位语义替代模型资产说明;同时记录算法版本、 +家族、参数约束、后端、性能及已知限制。说明独立实现与参考来源的关系, +不得在缺少证据时声称官方移植、逐值兼容或真实数据精度。 + +算法发布说明列出来源/论文、代码许可、实现差异、状态和 API 变化,不编造 +模型资产、模型校验和或缓存说明。尚未发布 npm/在线 Demo 时如实标明本地 +状态;发布及治理规则仍须按适用范围留存远程证据。 diff --git a/standards/v1/performance-contract.md b/standards/v1/performance-contract.md index 898609e..b8b46d0 100644 --- a/standards/v1/performance-contract.md +++ b/standards/v1/performance-contract.md @@ -1,6 +1,6 @@ # Performance and Timing Contract -Expose stable timing names with documented cold/warm semantics: +Model SDKs expose stable timing names with documented cold/warm semantics: ```text modelDownloadMs @@ -24,3 +24,15 @@ the two without labeling them. Recommended evidence includes peak memory, cache bytes, model precision, batch size, browser/device, and test date. These measurements are observations for the stated matrix, not universal benchmarks. + +## 纯算法耗时(1.2.0) + +算法结果和 Demo 必须提供 validationMs(输入校验)、predictionMs(状态预测)、 +associationMs(观测关联)、updateMs(状态更新)、totalMs(本次计算总耗时), +单位为毫秒。不执行的阶段以 0 表示并说明原因,不虚构模型下载或缓存耗时。 +各阶段边界和 totalMs 的计时范围必须文档化,不能以阶段相加冒充实测总耗时。 + +cold 指新算法实例首次处理;warm 指复用同一实例的已有状态。 +记录初始化/复位边界、输入规模、状态规模、设备、浏览器、runtime 和测试日期, +不能把有状态计算不同输入规模的耗时直接比较为加速比。 +仍报告实际后端及 main/worker 模式,不以特性检测推断兼容性或精度。 diff --git a/standards/v1/portal-contract.md b/standards/v1/portal-contract.md index 4f3665f..ed73a92 100644 --- a/standards/v1/portal-contract.md +++ b/standards/v1/portal-contract.md @@ -17,3 +17,17 @@ Demo links. Until then, add registry records and recipes rather than nodes. Portal UI may be denser than a Demo, but both consume the same status labels, model/runtime fields, brand bar semantics, links, and [UI tokens](ui-tokens.json). + +## 纯算法目录记录(1.2.0) + +门户记录的 `kind` 缺省为 `model`,兼容已有模型;模型必须保留非空 +`assets`,禁止 `algorithm`。`kind: algorithm` 必须使用空 `assets: []`, +并声明 `algorithm.id/version/family/source/license/input/output/stateful`, +前七项为非空字符串,stateful 为布尔值。不得为算法伪造权重、大小或校验和。 +算法来源必须说明论文或代码来源及独立实现关系,不把自研实现标为官方移植。 + +算法可使用 `cpu` 后端、多目标跟踪使用 `multi-object-tracking` 分类。 +目录和详情展示 CPU / JavaScript、无需模型权重、算法来源和状态语义, +筛选结果及分类页继续链接独立 SDK。门户不得导入跟踪 runtime。 +带日期验证仍只覆盖明确环境;待发布记录必须标明 npm/Release/Demo 待远程核验, +门户生产合并须等待目标链接实际可用。 diff --git a/standards/v1/rules.yaml b/standards/v1/rules.yaml index 0df3c05..0eac3bd 100644 --- a/standards/v1/rules.yaml +++ b/standards/v1/rules.yaml @@ -1,4 +1,4 @@ -standardVersion: "1.1.0" +standardVersion: "1.2.0" rules: - id: META-001 level: required @@ -41,6 +41,7 @@ rules: message: Demo provides an in-page Chinese/English toggle remediation: Add a language toggle that does not alter inference state. - id: DEMO-004 + appliesTo: [model] level: required detector: demoCacheClear message: Demo exposes current-model and global cache cleanup controls @@ -48,9 +49,22 @@ rules: - id: DEMO-005 level: required detector: demoTimingMarkers - message: Demo exposes model/runtime/timing information - remediation: Render data-sdk-model-info, data-sdk-runtime-info, and data-sdk-timing regions. + message: Demo 展示当前模型或算法的信息、运行信息和耗时 + remediation: 模型使用 data-sdk-model-info,算法使用 data-sdk-algorithm-info;两者保留 data-sdk-runtime-info 和 data-sdk-timing。 + - id: DEMO-006 + appliesTo: [algorithm] + level: required + detector: demoStateReset + message: 算法 Demo 提供状态复位操作 + remediation: 使用 data-sdk-state-reset 标记复位控件,并按状态生命周期契约连接 reset。 + - id: ALGORITHM-001 + appliesTo: [algorithm] + level: required + detector: algorithmInformation + message: 算法清单声明身份、家族、来源、许可、输入输出与有状态语义 + remediation: 按 sdk-manifest.algorithm.yaml 填写 algorithm 字段并记录状态生命周期。 - id: MODEL-001 + appliesTo: [model] level: required detector: modelInformation message: Manifest declares model identity, precision, size, source, license, and checksum @@ -63,9 +77,10 @@ rules: - id: PERF-001 level: required detector: performanceTimings - message: Standard load and inference timing fields are declared - remediation: Document download, cache, integrity, session, inference, and total timing. + message: 声明当前 SDK 类型所需的标准耗时字段 + remediation: 模型保留下载、缓存、校验、会话、推理和总耗时;算法声明 validationMs、predictionMs、associationMs、updateMs、totalMs。 - id: CACHE-001 + appliesTo: [model] level: required detector: cacheContract message: Cache storage, versioning, estimate, and cleanup are declared diff --git a/standards/v1/sdk-contract.md b/standards/v1/sdk-contract.md index 6362f84..2db6f72 100644 --- a/standards/v1/sdk-contract.md +++ b/standards/v1/sdk-contract.md @@ -26,9 +26,28 @@ an explicit option and the result reports both requested and actual backend. The manifest is the source of truth for model identity, version, assets, precision, format, checksum, input/output contract, and verification matrix. +上述加载、模型下载和推理要求适用于模型 SDK;纯算法接口见下文。 + 模型清单兼容旧版必填的 `model.assets`,并可用 `model.variants[]` 描述同一 模型的 FP32、FP16、INT8 等精度或量化变体。变体必须声明 `id`、`precision`、 `quantization`、`opset`、文件大小、参数量、`wasm`/`webgpu` 后端及一个或多个 来源。来源的 `kind` 只能是 `git-lfs`、`huggingface`、`modelscope`、`custom`, 且必须使用 40 至 64 位十六进制不可变 revision、含主机的 HTTP(S) 下载地址、文件大小和 SHA-256;显式来源失败时 不得自动换源,只有 `auto` 策略可以按清单尝试。Git LFS pointer 不是模型本体。 + +## 纯算法 runtime(1.2.0) + +算法 SDK 不加载模型,不实现虚构的 load、下载或缓存接口。工厂名称和同步/ +异步计算接口可按领域定义,但必须公开输入、输出、参数约束、稳定错误码及 +资源释放契约。algorithm 的 id、version、family、source、license、input、 +output 为非空字符串,stateful 为布尔值;模型 SDK 不得声明此分支。 + +有状态算法必须文档化状态初始化、推进、实例隔离、reset 和 dispose 行为, +包括复位后 ID/代次含义、无效输入是否改变状态,以及释放后可调用的接口。 +复位必须清除算法实例状态;无状态算法也须说明复位如何清空 Demo 结果。 +文档必须说明取消的实际粒度,同步主线程算法只能在计算开始前检查取消, +不得声称中途抢占。来源与许可须区分算法思想、参考代码和本项目独立实现。 + +结果仍报告 requestedBackend、actualBackend、executionMode 和 runtimeVersion, +CPU 主线程实现声明 cpu/main。不得因没有模型而放宽实际后端报告、实例隔离、 +框架无关或带日期兼容性证据的要求。算法性能字段见性能契约。 diff --git a/standards/v1/sdk-manifest.schema.json b/standards/v1/sdk-manifest.schema.json index 130ff38..3dcee96 100644 --- a/standards/v1/sdk-manifest.schema.json +++ b/standards/v1/sdk-manifest.schema.json @@ -3,9 +3,10 @@ "$id": "https://chenmohan123.github.io/web-model-sdk-standard/v1/sdk-manifest.schema.json", "title": "Web Model SDK Standard v1 Manifest", "type": "object", - "required": ["schemaVersion", "id", "name", "summary", "package", "repository", "demo", "docs", "runtime", "model", "performance", "cache", "examples", "verification"], + "required": ["schemaVersion", "id", "name", "summary", "package", "repository", "demo", "docs", "runtime", "performance", "examples", "verification"], "properties": { - "schemaVersion": { "type": "string", "enum": ["1.0.0", "1.1.0"] }, + "schemaVersion": { "type": "string", "enum": ["1.0.0", "1.1.0", "1.2.0"] }, + "kind": { "type": "string", "enum": ["model", "algorithm"] }, "id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" }, "name": { "type": "string", "minLength": 1 }, "summary": { "type": "string", "minLength": 20 }, @@ -50,6 +51,21 @@ }, "additionalProperties": false }, + "algorithm": { + "type": "object", + "required": ["id", "version", "family", "source", "license", "input", "output", "stateful"], + "properties": { + "id": { "type": "string", "minLength": 1 }, + "version": { "type": "string", "minLength": 1 }, + "family": { "type": "string", "minLength": 1 }, + "source": { "type": "string", "minLength": 1 }, + "license": { "type": "string", "minLength": 1 }, + "input": { "type": "string", "minLength": 1 }, + "output": { "type": "string", "minLength": 1 }, + "stateful": { "type": "boolean" } + }, + "additionalProperties": false + }, "model": { "type": "object", "required": ["id", "version", "format", "parameterCount", "precision", "source", "license", "assets"], @@ -91,7 +107,7 @@ "type": "object", "required": ["timings", "coldStartDefined", "warmRunDefined"], "properties": { - "timings": { "type": "array", "items": { "type": "string", "enum": ["modelDownloadMs", "modelCacheReadMs", "integrityMs", "sessionMs", "decodeMs", "preprocessMs", "inferenceMs", "postprocessMs", "totalMs"] }, "minItems": 5 }, + "timings": { "type": "array", "items": { "type": "string", "enum": ["modelDownloadMs", "modelCacheReadMs", "integrityMs", "sessionMs", "decodeMs", "preprocessMs", "inferenceMs", "postprocessMs", "validationMs", "predictionMs", "associationMs", "updateMs", "totalMs"] }, "minItems": 5 }, "coldStartDefined": { "type": "boolean" }, "warmRunDefined": { "type": "boolean" } }, @@ -146,6 +162,15 @@ "additionalProperties": false } }, + "if": { "properties": { "kind": { "const": "algorithm" } }, "required": ["kind"] }, + "then": { + "properties": { "schemaVersion": { "const": "1.2.0" }, "algorithm": true, "model": false, "cache": false }, + "required": ["algorithm"] + }, + "else": { + "properties": { "model": true, "cache": true, "algorithm": false }, + "required": ["model", "cache"] + }, "$defs": { "example": { "type": "object", diff --git a/standards/v1/templates/demo-checklist.md b/standards/v1/templates/demo-checklist.md index baf8dba..e145daa 100644 --- a/standards/v1/templates/demo-checklist.md +++ b/standards/v1/templates/demo-checklist.md @@ -1,15 +1,19 @@ # Demo Checklist -- [ ] Demo focuses on this SDK/model only. +- [ ] Demo focuses on this SDK/model or algorithm only. - [ ] Initial document language is Chinese (`zh-CN`). - [ ] In-page Chinese/English toggle works without reloading model state. - [ ] Brand bar shows SDK name, package version, GitHub, and Demo link. - [ ] Input, backend/precision selection, run/reset, and disabled/loading states exist. - [ ] Empty preview does not render a broken image. - [ ] Status uses the standard state names and accessible text/icons. -- [ ] Model name, version, bytes, parameter count, precision, format, source, license, and SHA-256 are visible. +- [ ] (仅模型)Model name, version, bytes, parameter count, precision, format, source, license, and SHA-256 are visible. - [ ] Requested backend, actual backend, execution mode, runtime version, and verification matrix are visible. -- [ ] Download, cache read, integrity, session, preprocess, inference, postprocess, and total timings are visible. -- [ ] Current-model cache cleanup and global cache cleanup are user initiated and report results. +- [ ] (仅模型)Download, cache read, integrity, session, preprocess, inference, postprocess, and total timings are visible. +- [ ] (仅模型)Current-model cache cleanup and global cache cleanup are user initiated and report results. - [ ] Local-processing/privacy statement is visible. - [ ] 390px viewport has no horizontal overflow. +- [ ] (仅算法)data-sdk-algorithm-info 展示算法身份、来源、许可、输入输出与状态限制。 +- [ ] (仅算法)保留 data-sdk-runtime-info 和 data-sdk-timing,展示五个算法耗时字段及新实例/复用状态语义。 +- [ ] (仅算法)data-sdk-state-reset 实际触发复位;重播/切换序列/seek 遵循状态契约,切语言不复位。 +- [ ] (仅算法)不展示虚构模型下载或缓存操作;浏览器实测复位及错误状态。 diff --git a/standards/v1/templates/release-checklist.md b/standards/v1/templates/release-checklist.md index 7f0637f..c50533e 100644 --- a/standards/v1/templates/release-checklist.md +++ b/standards/v1/templates/release-checklist.md @@ -3,16 +3,19 @@ - [ ] Chinese README is the default and links to equivalent English README/docs. - [ ] npm package name/version, GitHub repository, and live Demo links work. - [ ] `pnpm verify` (or documented equivalent) passes. -- [ ] CI workflow runs tests, typecheck, lint, build, and model/checksum validation. +- [ ] CI workflow runs tests, typecheck, lint, build, and applicable manifest validation. - [ ] The active default-branch Ruleset requires pull requests, current CI checks, resolved conversations, and blocks deletion and force pushes. - [ ] The active release-tag Ruleset prevents matching published tags from being updated or deleted. - [ ] Ruleset bypass actors are absent or have a documented least-privilege reason. - [ ] GitHub About description, Homepage/Demo URL, and topics are configured. - [ ] Changelog contains the release entry. -- [ ] GitHub Release uses an existing immutable tag and states model source, license, assets, backends, and limitations. -- [ ] Model assets use versioned immutable URLs and SHA-256 checksums. +- [ ] GitHub Release uses an existing immutable tag and states source, license, backends, limitations, and model assets when applicable. +- [ ] (仅模型)Model assets use versioned immutable URLs and SHA-256 checksums. - [ ] Compatibility entries include browser, OS, device, backend, runtime, and test date. - [ ] The live Demo is deployed over HTTPS from protected source by a reproducible workflow with a commit-linked deployment record. - [ ] If GitHub Pages is used, Source is GitHub Actions and the deployment uses the `github-pages` environment, scoped Pages permissions, HTTPS, and concurrency control. - [ ] GitHub API governance evidence records the repository, Ruleset/environment identifiers, observed values, and verification time without credentials. - [ ] `pnpm sdk:check -- --repo . --format table` has no required failures. +- [ ] (仅算法)使用 1.2.0 algorithm 清单,来源与许可已核对,不含 model/cache。 +- [ ] (仅算法)双语文档与发布说明记录输入输出、状态生命周期、复位、实现差异及 cold/warm 性能。 +- [ ] 不适用规则以 skip 保留证据和理由,不能把本地通过称为远程发布成功。 diff --git a/standards/v1/templates/sdk-manifest.algorithm.yaml b/standards/v1/templates/sdk-manifest.algorithm.yaml new file mode 100644 index 0000000..048893f --- /dev/null +++ b/standards/v1/templates/sdk-manifest.algorithm.yaml @@ -0,0 +1,40 @@ +schemaVersion: "1.2.0" +kind: algorithm +id: example-algorithm +name: 浏览器算法示例 +summary: 框架无关的浏览器纯算法,公开输入输出、状态生命周期和独立演示页面。 +package: + name: web-sdk-example-algorithm + version: 0.1.0 +repository: https://github.com/owner/web-sdk-example-algorithm +demo: + url: https://owner.github.io/web-sdk-example-algorithm/ + defaultLanguage: zh-CN + framework: react + localProcessing: true +docs: + zhCN: docs/zh-CN/quick-start.md + en: docs/en/quick-start.md +runtime: + backends: [cpu] + executionModes: [main] + actualBackendReported: true + runtimeVersion: example-algorithm@0.1.0 +algorithm: + id: example-algorithm + version: 0.1.0 + family: 状态估计算法 + source: 独立实现;请替换为论文、代码来源和实现差异的说明或文档路径 + license: Apache-2.0 + input: docs/zh-CN/api.md#输入 + output: docs/zh-CN/api.md#输出 + stateful: true +performance: + timings: [validationMs, predictionMs, associationMs, updateMs, totalMs] + coldStartDefined: true + warmRunDefined: true +examples: + vanilla: { status: available, path: examples/vanilla } + react: { status: available, path: examples/react } +verification: + environments: [] diff --git a/tests/portal.spec.ts b/tests/portal.spec.ts index a6d90cb..b992ea2 100644 --- a/tests/portal.spec.ts +++ b/tests/portal.spec.ts @@ -1,11 +1,38 @@ import { test, expect } from "@playwright/test"; for (const width of [1280, 390]) { + test(`纯算法在 ${width}px 支持 CPU 分类和完整详情`, async ({ page }) => { + await page.setViewportSize({ width, height: 844 }); + await page.goto('/'); + await expect(page.locator('astro-island[component-url*="ModelDirectory"]')).not.toHaveAttribute('ssr', ''); + await page.getByRole('combobox', { name: '后端', exact: true }).selectOption('cpu'); + await page.getByRole('combobox', { name: '任务', exact: true }).selectOption('multi-object-tracking'); + await expect(page.getByText('1 个条目', { exact: true })).toBeVisible(); + await expect(page.getByText('纯算法 · 无需模型权重')).toBeVisible(); + expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth)).toBe(true); + await page.screenshot({ path: `test-results/tracking-directory-${width}.png`, fullPage: true }); + await page.getByRole('link', { name: 'PP-Tracking', exact: true }).click(); + await expect(page.getByRole('heading', { level: 1 })).toHaveText('PP-Tracking'); + await expect(page.getByText('CPU / JavaScript', { exact: true })).toBeVisible(); + await expect(page.getByRole('heading', { name: '模型资源', exact: true })).toHaveCount(0); + await expect(page.getByText('无需模型权重', { exact: true })).toBeVisible(); + await expect(page.getByText(/不是百度或 ByteTrack 官方移植/)).toBeVisible(); + await expect(page.getByText(/有状态;实例生命周期/)).toBeVisible(); + await expect(page.getByText(/默认 IDF1 48.2922%/)).toBeVisible(); + await expect(page.getByRole('link', { name: 'GitHub 仓库', exact: true })).toHaveAttribute('href', 'https://github.com/chenmohan123/web-sdk-PP-Tracking'); + await expect(page.getByRole('link', { name: 'npm 包', exact: true })).toHaveAttribute('href', 'https://www.npmjs.com/package/web-sdk-pp-tracking'); + await expect(page.getByRole('link', { name: '打开在线 Demo', exact: true })).toHaveAttribute('href', 'https://chenmohan123.github.io/web-sdk-PP-Tracking/'); + expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth)).toBe(true); + await page.screenshot({ path: `test-results/tracking-detail-${width}.png`, fullPage: true }); + await page.goto('/tasks/multi-object-tracking/'); + await expect(page.getByRole('heading', { level: 1 })).toHaveText('多目标跟踪'); + await expect(page.getByRole('link', { name: 'PP-Tracking' })).toHaveAttribute('href', '/models/pp-tracking/'); + }); test(`旋转框检测在 ${width}px 可筛选、搜索并打开完整发布详情`, async ({ page }) => { await page.setViewportSize({ width, height: 844 }); await page.goto('/'); await expect(page.locator('astro-island[component-url*="ModelDirectory"]')).not.toHaveAttribute('ssr', ''); - await expect(page.getByText('7 个条目', { exact: true })).toBeVisible(); + await expect(page.getByText('8 个条目', { exact: true })).toBeVisible(); await page.getByRole('combobox', { name: '任务', exact: true }).selectOption({ label: '旋转框检测' }); await page.getByRole('searchbox').fill('web-sdk-pp-rotated-detection'); await expect(page.getByText('1 个条目', { exact: true })).toBeVisible(); @@ -33,7 +60,7 @@ for (const width of [1280, 390]) { await page.setViewportSize({ width, height: 844 }); await page.goto('/'); await expect(page.locator('astro-island[component-url*="ModelDirectory"]')).not.toHaveAttribute('ssr', ''); - await expect(page.getByText('7 个条目', { exact: true })).toBeVisible(); + await expect(page.getByText('8 个条目', { exact: true })).toBeVisible(); await page.getByRole('combobox', { name: '任务', exact: true }).selectOption({ label: '实例分割' }); await page.getByRole('searchbox').fill('web-sdk-pp-segmentation'); await expect(page.getByText('1 个条目', { exact: true })).toBeVisible(); @@ -61,7 +88,7 @@ for (const width of [1280, 390]) { await page.setViewportSize({ width, height: 844 }); await page.goto("/"); await expect(page.locator('astro-island[component-url*="ModelDirectory"]')).not.toHaveAttribute("ssr", ""); - await expect(page.getByText("7 个条目", { exact: true })).toBeVisible(); + await expect(page.getByText("8 个条目", { exact: true })).toBeVisible(); await page.getByRole("combobox", { name: "任务", exact: true }).selectOption({ label: "人体姿态" }); await expect(page.getByText("1 个条目", { exact: true })).toBeVisible(); await expect(page.getByRole("link", { name: "PP-DocLayoutV3", exact: true })).toHaveCount(0); @@ -105,7 +132,7 @@ test("homepage exposes the model SDK directory and Models navigation", async ({ await page.goto("/"); await expect(page.getByRole("heading", { level: 1 })).toHaveText( - "浏览器端模型 SDK 目录", + "浏览器端模型与算法 SDK 目录", ); await expect(page.getByRole("navigation")).toContainText("Models"); }); diff --git a/tools/sdk-standard-check/algorithm.test.ts b/tools/sdk-standard-check/algorithm.test.ts new file mode 100644 index 0000000..5311978 --- /dev/null +++ b/tools/sdk-standard-check/algorithm.test.ts @@ -0,0 +1,98 @@ +import { afterEach, describe, expect, it } from "vitest"; +import { cpSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import path from "node:path"; +import YAML from "yaml"; +import { validateManifest } from "./src/manifest.mjs"; +import { scanRepository } from "./src/check.mjs"; + +const complete = "tools/sdk-standard-check/fixtures/complete-sdk"; +const model = () => YAML.parse(readFileSync(`${complete}/sdk-manifest.yaml`, "utf8")); +const algorithm = () => { + const value = model(); + value.schemaVersion = "1.2.0"; + value.kind = "algorithm"; + delete value.model; + delete value.cache; + value.algorithm = { + id: "tracking", version: "0.1.0", family: "multi-object-tracking", + source: "独立实现;论文与差异见 NOTICE", license: "Apache-2.0", + input: "docs/zh-CN/api.md#tracking-frame", output: "docs/zh-CN/api.md#tracking-result", stateful: true, + }; + value.runtime = { backends: ["cpu"], executionModes: ["main"], actualBackendReported: true, runtimeVersion: "tracking@0.1.0" }; + value.performance.timings = ["validationMs", "predictionMs", "associationMs", "updateMs", "totalMs"]; + return value; +}; +const demo = '
'; +const roots: string[] = []; +function repository(value: ReturnType, html = demo) { + const root = mkdtempSync(path.join(tmpdir(), "sdk-algorithm-")); + roots.push(root); + cpSync(complete, root, { recursive: true }); + writeFileSync(path.join(root, "sdk-manifest.yaml"), YAML.stringify(value)); + writeFileSync(path.join(root, "apps/demo/index.html"), html); + return root; +} +afterEach(() => { + for (const root of roots.splice(0)) { + expect(path.dirname(path.resolve(root))).toBe(path.resolve(tmpdir())); + expect(path.basename(root)).toMatch(/^sdk-algorithm-/); + rmSync(root, { recursive: true, force: true }); + } +}); + +describe("纯算法 SDK 契约", () => { + it("合法算法无模型与缓存也通过,模型专属规则有跳过理由和证据", async () => { + const report = await scanRepository(repository(algorithm())); + expect(report.findings.filter((x: { level: string; status: string }) => x.level === "required" && x.status === "fail")).toEqual([]); + for (const id of ["DEMO-004", "MODEL-001", "CACHE-001"]) { + expect(report.findings).toContainEqual(expect.objectContaining({ id, status: "skip", path: "sdk-manifest.yaml", evidence: expect.stringContaining("algorithm") })); + } + for (const id of ["ALGORITHM-001", "DEMO-005", "DEMO-006", "PERF-001"]) { + expect(report.findings).toContainEqual(expect.objectContaining({ id, status: "pass" })); + } + }); + + it.each(["id", "version", "family", "source", "license", "input", "output", "stateful"])("拒绝缺少算法字段 %s", (field) => { + const value = algorithm(); + delete value.algorithm[field]; + expect(validateManifest(value)).toContainEqual(expect.stringContaining(`/algorithm/${field}`)); + }); + + it.each(["缺少 algorithm", "携带 model", "携带 cache", "旧版 1.0.0", "旧版 1.1.0", "伪造 kind", "无效 stateful", "缺少算法 timing"])("%s 不得获得模型豁免", async (scenario) => { + const value = algorithm(); + if (scenario === "缺少 algorithm") delete value.algorithm; + if (scenario === "携带 model") value.model = model().model; + if (scenario === "携带 cache") value.cache = model().cache; + if (scenario.startsWith("旧版")) value.schemaVersion = scenario.slice(3); + if (scenario === "伪造 kind") value.kind = "Algorithm"; + if (scenario === "无效 stateful") value.algorithm.stateful = "true"; + if (scenario === "缺少算法 timing") value.performance.timings = ["validationMs", "predictionMs", "associationMs", "totalMs", "totalMs"]; + const report = await scanRepository(repository(value)); + expect(report.findings).toContainEqual(expect.objectContaining({ id: "CONFIG-001", status: "fail" })); + for (const id of ["MODEL-001", "CACHE-001", "ALGORITHM-001"]) { + expect(report.findings).toContainEqual(expect.objectContaining({ id, status: "fail" })); + } + }); + + it.each(["data-sdk-state-reset", "data-sdk-algorithm-info", "data-sdk-runtime-info", "data-sdk-timing"])("缺少 %s 标记会失败,说明文字不能代替标记", async (marker) => { + const report = await scanRepository(repository(algorithm(), demo.replace(marker, "data-unrelated") + "validationMs totalMs 耗时")); + expect(report.findings).toContainEqual(expect.objectContaining({ id: marker === "data-sdk-state-reset" ? "DEMO-006" : "DEMO-005", status: "fail" })); + }); + + it.each(["1.0.0", "1.1.0", "1.2.0"])("%s 模型保留 assets 必填及算法分支互斥", (schemaVersion) => { + const value = { ...model(), schemaVersion, kind: "model" }; + expect(validateManifest(value)).toEqual([]); + value.algorithm = algorithm().algorithm; + expect(validateManifest(value).length).toBeGreaterThan(0); + delete value.algorithm; + delete value.model.assets; + expect(validateManifest(value)).toContainEqual(expect.stringContaining("/model/assets")); + }); + + it("算法脚手架模板通过完整清单校验", () => { + const value = YAML.parse(readFileSync("standards/v1/templates/sdk-manifest.algorithm.yaml", "utf8")); + expect(value.kind).toBe("algorithm"); + expect(validateManifest(value)).toEqual([]); + }); +}); diff --git a/tools/sdk-standard-check/checker.test.ts b/tools/sdk-standard-check/checker.test.ts index 377b1c6..b4c689a 100644 --- a/tools/sdk-standard-check/checker.test.ts +++ b/tools/sdk-standard-check/checker.test.ts @@ -124,7 +124,7 @@ describe("SDK repository discovery", () => { const summary = summarize(report); const remoteFindings = report.findings.filter((finding: { id: string }) => /^(GOV|DEPLOY|PAGES)-/.test(finding.id)); - expect(report.standardVersion).toBe("1.1.0"); + expect(report.standardVersion).toBe("1.2.0"); expect(remoteFindings.map((finding: { id: string }) => finding.id)).toEqual([ "GOV-001", "GOV-002", @@ -132,7 +132,7 @@ describe("SDK repository discovery", () => { "PAGES-001", ]); expect(remoteFindings.every((finding: { status: string }) => finding.status === "skip")).toBe(true); - expect(summary.requiredSkipped).toBe(4); + expect(summary.requiredSkipped).toBe(6); expect(summary.status).toBe("locally-compliant"); }); diff --git a/tools/sdk-standard-check/src/discover.mjs b/tools/sdk-standard-check/src/discover.mjs index 41098c4..7299c95 100644 --- a/tools/sdk-standard-check/src/discover.mjs +++ b/tools/sdk-standard-check/src/discover.mjs @@ -29,6 +29,9 @@ export async function discoverRepository(root, manifest) { demoLanguageToggle: false, cacheClear: false, timingMarkers: false, + algorithmTimingMarkers: false, + demoStateReset: false, + algorithmInformation: false, modelInformation: false, runtimeInformation: false, performanceTimings: false, @@ -48,6 +51,7 @@ export async function discoverRepository(root, manifest) { if (files.some((file) => file.startsWith("docs/zh-CN/"))) { evidence.locales.push("zh-CN"); addEvidence(evidence, "docs.zhCN", files.find((file) => file.startsWith("docs/zh-CN/"))); } if (files.some((file) => file.startsWith("docs/en/"))) { evidence.locales.push("en"); addEvidence(evidence, "docs.en", files.find((file) => file.startsWith("docs/en/"))); } + if (manifest.path) addEvidence(evidence, "manifestPresent", manifest.path); const demoFile = files.find((file) => /^apps\/demo\/(?:index\.html|src\/main\.[jt]sx?|package\.json)$/i.test(file)) ?? files.find((file) => /^demo\/index\.html$/i.test(file)); evidence.demoEntry = Boolean(demoFile); if (demoFile) addEvidence(evidence, "demoEntry", demoFile); @@ -56,6 +60,21 @@ export async function discoverRepository(root, manifest) { if (/English|中文|language|语言|i18n/i.test(text)) { evidence.demoLanguageToggle = true; addEvidence(evidence, "demoLanguageToggle", file); } if (/data-sdk-cache-clear|clear(?:Model)?Cache|清理缓存/i.test(text)) { evidence.cacheClear = true; addEvidence(evidence, "cacheClear", file); } if (/data-sdk-(?:timing|model-info|runtime-info)|modelDownloadMs|inferenceMs|耗时/i.test(text)) { evidence.timingMarkers = true; addEvidence(evidence, "timingMarkers", file); } + if (/data-sdk-state-reset\b/.test(text)) { evidence.demoStateReset = true; addEvidence(evidence, "demoStateReset", file); } + } + + // 算法必须具备三个独立区域;允许不同组件文件分别提供标记。 + const algorithmMarkers = ["data-sdk-algorithm-info", "data-sdk-runtime-info", "data-sdk-timing"]; + const demoTexts = allText.filter(({ file }) => isDemoFile(file)); + evidence.algorithmTimingMarkers = algorithmMarkers.every((marker) => demoTexts.some(({ text }) => new RegExp(`${marker}\\b`).test(text))); + if (evidence.algorithmTimingMarkers) { + for (const { file, text } of demoTexts) { + if (algorithmMarkers.some((marker) => new RegExp(`${marker}\\b`).test(text))) addEvidence(evidence, "demoTimingMarkers", file); + } + } + if (!manifest.errors.length && manifest.value?.kind === "algorithm") { + evidence.algorithmInformation = true; + addEvidence(evidence, "algorithmInformation", manifest.path); } if (manifest.value?.model?.assets?.length || /model(?:\s|_|-)info|precision|sha256|参数量|精度/i.test(joined)) { evidence.modelInformation = true; addEvidence(evidence, "modelInformation", manifest.path ?? markdown[0] ?? "README.md"); } diff --git a/tools/sdk-standard-check/src/manifest.mjs b/tools/sdk-standard-check/src/manifest.mjs index 3d8b6da..7b53dec 100644 --- a/tools/sdk-standard-check/src/manifest.mjs +++ b/tools/sdk-standard-check/src/manifest.mjs @@ -82,19 +82,22 @@ export function validateManifest(value, options = {}) { // 完整 schema 确认类型后,保留既有契约的 HTTP、必需耗时和缓存能力检查。 const errors = []; if (!isHttpUrlWithHost(value.repository)) errors.push("/repository:必须是含主机的 HTTP(S) 地址"); - for (const [index, asset] of value.model.assets.entries()) { + for (const [index, asset] of (value.model?.assets ?? []).entries()) { if (!isHttpUrlWithHost(asset.url)) errors.push(`/model/assets/${index}/url:必须是含主机的 HTTP(S) 地址`); } - for (const [variantIndex, variant] of (value.model.variants ?? []).entries()) { + for (const [variantIndex, variant] of (value.model?.variants ?? []).entries()) { for (const [sourceIndex, source] of variant.sources.entries()) { if (!isHttpUrlWithHost(source.downloadUrl)) errors.push(`/model/variants/${variantIndex}/sources/${sourceIndex}/downloadUrl:必须是含主机的 HTTP(S) 地址`); } } const timingSet = new Set(value.performance.timings); - for (const field of ["modelDownloadMs", "modelCacheReadMs", "integrityMs", "sessionMs", "inferenceMs", "totalMs"]) { + const requiredTimings = value.kind === "algorithm" + ? ["validationMs", "predictionMs", "associationMs", "updateMs", "totalMs"] + : ["modelDownloadMs", "modelCacheReadMs", "integrityMs", "sessionMs", "inferenceMs", "totalMs"]; + for (const field of requiredTimings) { if (!timingSet.has(field)) errors.push(`/performance/timings:缺少 ${field}`); } - for (const field of ["versionedKeys", "clearCurrent", "clearAll", "estimate"]) { + for (const field of value.kind === "algorithm" ? [] : ["versionedKeys", "clearCurrent", "clearAll", "estimate"]) { if (value.cache[field] !== true) errors.push(`/cache/${field}:必须声明为 true`); } return errors; diff --git a/tools/sdk-standard-check/src/rules.mjs b/tools/sdk-standard-check/src/rules.mjs index 05a08e7..dac5bbc 100644 --- a/tools/sdk-standard-check/src/rules.mjs +++ b/tools/sdk-standard-check/src/rules.mjs @@ -29,7 +29,9 @@ const detectors = { demoChineseDefault: (evidence) => evidence.demoChineseDefault, demoLanguageToggle: (evidence) => evidence.demoLanguageToggle, demoCacheClear: (evidence) => evidence.cacheClear, - demoTimingMarkers: (evidence) => evidence.timingMarkers, + demoTimingMarkers: (evidence, manifest) => manifest?.kind === "algorithm" ? evidence.algorithmTimingMarkers : evidence.timingMarkers, + demoStateReset: (evidence) => evidence.demoStateReset, + algorithmInformation: (evidence, manifest) => Boolean(manifest?.algorithm) && evidence.algorithmInformation, modelInformation: (evidence, manifest) => Boolean(manifest?.model?.assets?.length) && evidence.modelInformation, runtimeInformation: (evidence, manifest) => Boolean(manifest?.runtime?.actualBackendReported) && evidence.runtimeInformation, performanceTimings: (evidence, manifest) => Boolean(manifest?.performance?.timings?.length) && evidence.performanceTimings, @@ -53,6 +55,13 @@ const detectors = { export async function evaluateRules(evidence, manifest, standardRoot = defaultStandardRoot, loadedRuleSet) { const rules = (loadedRuleSet ?? await loadRuleSet(standardRoot)).rules; return rules.map((rule) => { + // 仅经完整校验的清单可决定类型豁免;无清单的旧仓库沿用模型检查。 + const kind = manifest ? (manifest.kind ?? "model") : evidence.manifestDeclared ? null : "model"; + if (kind && rule.appliesTo && !rule.appliesTo.includes(kind)) { + return result(rule.id, rule.level, "skip", rule.message, rule.remediation, + manifest ? evidence.evidenceByKey["manifestPresent"]?.[0] : undefined, + `当前类型为 ${kind},本规则仅适用于 ${rule.appliesTo.join("、")};${manifest ? "清单已通过完整校验" : "未声明清单,沿用旧版模型检查,不豁免模型规则"}。`); + } if (["github-api", "remote-api"].includes(rule.verification)) { return result( rule.id, diff --git a/tools/sdk-standard-check/src/types.mjs b/tools/sdk-standard-check/src/types.mjs index 8d72937..721cc7b 100644 --- a/tools/sdk-standard-check/src/types.mjs +++ b/tools/sdk-standard-check/src/types.mjs @@ -24,6 +24,9 @@ * @property {boolean} demoLanguageToggle * @property {boolean} cacheClear * @property {boolean} timingMarkers + * @property {boolean} algorithmTimingMarkers + * @property {boolean} demoStateReset + * @property {boolean} algorithmInformation * @property {boolean} modelInformation * @property {boolean} runtimeInformation * @property {boolean} performanceTimings diff --git a/tools/sdk-standard-check/standard-files.test.ts b/tools/sdk-standard-check/standard-files.test.ts index 8565acd..00ec69c 100644 --- a/tools/sdk-standard-check/standard-files.test.ts +++ b/tools/sdk-standard-check/standard-files.test.ts @@ -34,12 +34,12 @@ describe("v1 standard source", () => { for (const file of requiredFiles) expect(existsSync(file), file).toBe(true); }); - it("declares v1.1 rules while accepting v1.0 manifests", () => { + it("声明 v1.2 规则并兼容旧模型清单", () => { const rules = YAML.parse(readFileSync("standards/v1/rules.yaml", "utf8")); const schema = JSON.parse(readFileSync("standards/v1/sdk-manifest.schema.json", "utf8")); - expect(rules.standardVersion).toBe("1.1.0"); + expect(rules.standardVersion).toBe("1.2.0"); expect(schema.$id).toContain("web-model-sdk-standard/v1"); - expect(schema.properties.schemaVersion.enum).toEqual(["1.0.0", "1.1.0"]); + expect(schema.properties.schemaVersion.enum).toEqual(["1.0.0", "1.1.0", "1.2.0"]); }); it("defines GitHub Rulesets and Pages as remotely verified governance rules", () => {