@mcptoolshop/style-dataset-lab 3.3.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.es.md +117 -55
  3. package/README.fr.md +125 -65
  4. package/README.hi.md +117 -68
  5. package/README.it.md +119 -58
  6. package/README.ja.md +124 -74
  7. package/README.md +73 -7
  8. package/README.pt-BR.md +128 -63
  9. package/README.zh.md +116 -65
  10. package/bin/sdlab.js +100 -4
  11. package/lib/adapters/ai-toolkit.js +224 -35
  12. package/lib/adapters/comfyui-runner.js +79 -26
  13. package/lib/adapters/comfyui-workflows.js +94 -11
  14. package/lib/adapters/diffusers-lora.js +37 -5
  15. package/lib/adapters/generic-image-caption.js +43 -5
  16. package/lib/args.js +16 -1
  17. package/lib/asset-ingest.js +575 -0
  18. package/lib/asset-masks.js +323 -0
  19. package/lib/asset-source.js +1176 -0
  20. package/lib/batch-modes.js +29 -8
  21. package/lib/batch-runs.js +29 -1
  22. package/lib/batch-sheet-render.js +13 -3
  23. package/lib/brief-compiler.js +19 -0
  24. package/lib/candidate-sheet.js +327 -0
  25. package/lib/canon-author.js +350 -0
  26. package/lib/canon-build/build.js +146 -93
  27. package/lib/canon-review-gate.js +205 -0
  28. package/lib/captions.js +57 -0
  29. package/lib/card.js +74 -2
  30. package/lib/colab-launcher-guards.js +285 -0
  31. package/lib/comfyui.js +116 -18
  32. package/lib/config.js +116 -12
  33. package/lib/critique-engine.js +36 -2
  34. package/lib/eligibility.js +121 -9
  35. package/lib/eval-pack.js +14 -14
  36. package/lib/eval-runs.js +33 -0
  37. package/lib/export.js +122 -34
  38. package/lib/freeze-gate.js +16 -3
  39. package/lib/freeze-stamp.js +28 -3
  40. package/lib/generated-provenance.js +194 -6
  41. package/lib/implementation-packs.js +95 -17
  42. package/lib/ingest.js +396 -0
  43. package/lib/judgment-provenance.js +220 -0
  44. package/lib/lane1-render.js +668 -0
  45. package/lib/measure.js +422 -0
  46. package/lib/memory-store.js +663 -0
  47. package/lib/model-licences.js +305 -0
  48. package/lib/npy-meta.js +130 -0
  49. package/lib/paths.js +196 -7
  50. package/lib/png-meta.js +512 -0
  51. package/lib/records.js +54 -8
  52. package/lib/reingest-selected.js +113 -17
  53. package/lib/reingest.js +27 -3
  54. package/lib/run-manifest.js +159 -25
  55. package/lib/run-summary.js +12 -6
  56. package/lib/runtime-runs.js +45 -4
  57. package/lib/snapshot.js +114 -15
  58. package/lib/split.js +364 -48
  59. package/lib/train-runs.js +214 -0
  60. package/lib/training-manifests.js +114 -21
  61. package/lib/training-packages.js +147 -15
  62. package/lib/verifier.js +3 -0
  63. package/lib/verify-chain.js +367 -0
  64. package/lib/workflow-profiles.js +24 -3
  65. package/package.json +4 -3
  66. package/runtime/comfyui/txt2img-qwen.json +38 -0
  67. package/runtime/comfyui/txt2img-standard.json +21 -0
  68. package/scripts/_resume.js +62 -0
  69. package/scripts/_shared-args.js +44 -0
  70. package/scripts/asset-ingest.js +160 -0
  71. package/scripts/brief-compile.js +2 -1
  72. package/scripts/brief-show.js +2 -1
  73. package/scripts/canon-bind.js +2 -2
  74. package/scripts/canon-build.js +27 -20
  75. package/scripts/canon-draft.js +82 -0
  76. package/scripts/canon-drift.js +16 -7
  77. package/scripts/canon-freeze-status.js +14 -6
  78. package/scripts/canon-freeze.js +31 -11
  79. package/scripts/canon-unfreeze.js +17 -9
  80. package/scripts/card.js +2 -2
  81. package/scripts/colab/REAL_SERVICE_ASSUMPTIONS.md +14 -0
  82. package/scripts/colab/ai-toolkit-override-py315.txt +45 -0
  83. package/scripts/colab/colab_window.sh +587 -0
  84. package/scripts/colab/lane1_render.py +970 -0
  85. package/scripts/colab/launch_guards.py +564 -0
  86. package/scripts/colab/launch_lane1_stub.sh +309 -0
  87. package/scripts/colab/launch_lane3_stub.sh +366 -0
  88. package/scripts/colab/remote_runner.py +59 -0
  89. package/scripts/compare.js +2 -2
  90. package/scripts/critique.js +16 -1
  91. package/scripts/curate.js +2 -2
  92. package/scripts/doctor.js +182 -55
  93. package/scripts/eligibility.js +42 -2
  94. package/scripts/eval-pack.js +2 -2
  95. package/scripts/eval-run.js +2 -2
  96. package/scripts/export.js +2 -2
  97. package/scripts/generate-controlnet.js +45 -25
  98. package/scripts/generate-identity.js +53 -23
  99. package/scripts/generate-ipadapter.js +44 -23
  100. package/scripts/generate.js +86 -17
  101. package/scripts/implementation-pack.js +2 -2
  102. package/scripts/ingest.js +145 -0
  103. package/scripts/init.js +73 -13
  104. package/scripts/measure.js +170 -0
  105. package/scripts/measure_image.py +458 -0
  106. package/scripts/migrate-records.js +142 -0
  107. package/scripts/painterly-test.js +4 -3
  108. package/scripts/painterly.js +7 -3
  109. package/scripts/qwen_generate.py +138 -20
  110. package/scripts/reingest.js +2 -2
  111. package/scripts/sheet.js +142 -0
  112. package/scripts/snapshot.js +2 -2
  113. package/scripts/split.js +2 -2
  114. package/scripts/training-manifest.js +2 -2
  115. package/scripts/training-package.js +2 -2
  116. package/scripts/training-profile.js +2 -2
  117. package/scripts/verify.js +67 -0
  118. package/scripts/workflow-list.js +2 -1
  119. package/scripts/workflow-show.js +2 -1
package/README.zh.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <a href="README.ja.md">日本語</a> | <a href="README.md">English</a> | <a href="README.es.md">Español</a> | <a href="README.fr.md">Français</a> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português (BR)</a>
2
+ <a href="README.md">English</a> | <a href="README.es.md">Español</a> | <a href="README.fr.md">Français</a> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português (BR)</a>
3
3
  </p>
4
4
 
5
5
  <p align="center">
@@ -13,11 +13,11 @@
13
13
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT License"></a>
14
14
  </p>
15
15
 
16
- 编写你的视觉规则。生成艺术作品。根据这些规则评估每张图像。将结果作为版本化的、可审计的训练数据进行交付——然后将训练好的模型应用于实际的生产流程中,并将最佳输出反馈到你的语料库中。
16
+ 编写你的视觉规则。生成艺术作品。根据这些规则评估每张图像。将结果作为版本化的、可审计的训练数据进行输出——然后将训练好的模型应用于实际的生产工作流程中,并将最佳输出反馈到你的语料库中。
17
17
 
18
- “风格数据集实验室”将你记录下来的关于艺术风格的内容与你实际用于训练的数据集联系起来,然后贯穿整个生产过程,形成一个闭环。你可以定义一套规范——轮廓规则、调色板约束、材质语言,或者对你的项目有意义的任何内容。流水线会生成候选作品,根据这些规则对其进行评分,并将批准的作品打包成可重现的数据集,其中每条记录都解释了它被包含的原因。
18
+ “风格数据集实验室”将你记录的关于你的艺术风格的内容与你实际用于训练的数据集联系起来,然后将整个流程贯穿到生产阶段。你定义一套规范——轮廓规则、调色板约束、材质语言,以及对你的项目有意义的任何内容。流水线生成候选作品,根据这些规则对其进行评分,并将批准的作品打包成可重现的数据集,其中每条记录都解释了它被包含的原因。
19
19
 
20
- 然后,生产工作台接管:从项目的真实数据中编译生成简报,通过 ComfyUI 运行它们,评估输出结果,批量生成表现图和环境板,选择最佳结果,并将这些结果作为新的候选作品重新导入。循环完成:生成、选择、审查、改进。
20
+ 然后,生产工作台接管:从项目的事实中编译生成简报,通过 ComfyUI 运行,评估输出结果,批量生成表现图和环境图,选择最佳结果,并将它们重新导入作为新的候选作品。循环结束:生成、选择、审查、改进。
21
21
 
22
22
  ## 流水线
23
23
 
@@ -27,8 +27,15 @@ sdlab init my-project --domain character-design
27
27
 
28
28
  # Generate candidates via ComfyUI, then review them
29
29
  sdlab generate inputs/prompts/wave1.json --project my-project
30
+ sdlab sheet outputs/candidates --project my-project # HTML contact sheet to triage
30
31
  sdlab curate <id> approved "Strong silhouette, correct faction palette"
31
32
 
33
+ # Already have images? Bring them in without generating anything
34
+ sdlab ingest ~/renders/wave1 --project my-project
35
+
36
+ # Measure what the pixels actually are — palette and texture, as numbers
37
+ sdlab measure outputs/candidates --project my-project
38
+
32
39
  # Bind approved work to constitution rules
33
40
  # (`sdlab bind` is a shorter alias for `canon-bind`)
34
41
  sdlab canon-bind --project my-project
@@ -56,11 +63,47 @@ sdlab select --run run_2026-04-16_001 --approve 001.png,003.png
56
63
  sdlab reingest selected --selection selection_2026-04-16_001
57
64
  ```
58
65
 
59
- 最后一条命令就是关键。选定的输出会通过与所有其他内容相同的审核流程进行评估。语料库不断增长,规则始终有效。
66
+ 最后一条命令就是关键。选定的输出会通过与所有其他内容相同的审查流程。语料库不断增长,规则始终有效。
67
+
68
+ ## 资产通道——3D 导出作为训练数据
69
+
70
+ `sdlab ingest` 信任原始图像。`sdlab asset ingest` 签订一份**协议**。
71
+
72
+ 当一个 3D 资产通过其验收关口后,从 N 个角度重新渲染它,可以得到一个视角一致的图像——这是通过构建方式实现的,而基于视角的扩散模型无法保证这一点。资产通道将这些导出作为带有来源信息的训练数据:
73
+
74
+ ```bash
75
+ # Validate an export's manifest end to end, run the gates, write nothing
76
+ sdlab asset ingest ~/exports/dragon_dense --project my-project --dry-run
77
+
78
+ # Register it: records, candidates, masks, channels, receipt
79
+ sdlab asset ingest ~/exports/dragon_dense --project my-project
80
+ ```
81
+
82
+ 导出目录包含一个 `asset-source.json` 清单(模式 **1.3.0**),声明了其通道、调色板频段、关口阈值、验收结果、风格注册表,以及渲染图像的生成方式和来源。sdlab 会根据实际字节验证每个声明,并且如果发现任何违规行为,将拒绝整个导入——任何不符合规范的清单都不会被注册。
83
+
84
+ **连接点:** sdlab 提供机制,资产提供语义。sdlab 从不进行光线追踪,从不进行渲染,并且从不认为名为“来源”的通道是特殊的。它会证明、测量、注册和打包。数字的*含义*与资产相关联。
85
+
86
+ 协议强制执行的内容:
87
+
88
+ | 阶段 | 验证的内容 |
89
+ |---|---|
90
+ | **schema** | 形状、ID、格式良好的调色板频段,以及实际上为 `"accepted"` 的验收结果 |
91
+ | **containment** | 每个引用的路径都*位于*导出目录中(它是不受信任的输入),并且存在 |
92
+ | **encoding** | PNG 的 IHDR 与其声明的编码匹配;NPY 标头的 dtype 和形状与其声明的 dtype 和形状匹配。如果清单“看起来正确”,但与它的字节不一致,那么这就是本通道旨在阻止的情况。 |
93
+ | **categorical** | 索引 PNG 证明 PLTE ⊆ 声明的调色板;使用 `nearest` 过滤的通道会进行*详尽的*像素解码;分类 NPY 会进行详尽的值扫描。 |
94
+ | **gates** | 调色板关口在每次渲染时运行,基于清单自身的频段和阈值——如果渲染失败,则会发出明确的拒绝并报告,而不会悄悄地接受。 |
95
+
96
+ 记录以**未整理**(`judgment: null`)的形式与 `provenance.source: "asset"` 一起导入,并携带
97
+ 验收块的完整内容、每个文件的哈希值、相机和导向信息、关口测量值、声明的风格注册表以及每个图像的生成帧和种子。然后,它们会经历与其他记录相同的整理过程。
98
+
99
+ 导入还会报告清单*未*声明的内容——未知的风格注册表、缺失的 `identity.subject_name`、缺失的生成来源——作为**通知**,而不是
100
+ 失败。它们会显示在收据中并在 CLI 中打印。如果有一个问题没有人被告知,那么就无法解决这个问题;并且,由于清单可以*声明*其渲染是确定性的派生,并且没有自己的种子,因此该通道不会报告任何导出的差距。
101
+
102
+ 完整的协议、验证层级以及每个字段背后的原因:[docs/asset-lane-design.md](docs/asset-lane-design.md)。
60
103
 
61
104
  ## 规范创作
62
105
 
63
- 在数据集流水线运行之前,“sdlab canon *”命名空间会将你的项目的规范实体存储转换为三个投影,这些投影是训练和生产实际使用的——并且锁定那些不应发生变化的项目。
106
+ 在数据集流水线运行之前,`sdlab canon *` 命名空间将你的项目的规范实体存储转换为训练和生产实际使用的三个投影——并锁定那些不应漂移的条目。
64
107
 
65
108
  ```bash
66
109
  # Build three projections from the canon entity store:
@@ -76,62 +119,64 @@ sdlab canon freeze kael_maren --project my-project --reason "prologue portrait l
76
119
  sdlab canon drift --project my-project
77
120
  ```
78
121
 
79
- “canon build”(构建规范)是基于内容的——它的输出由一个“canon_sha”标识并进行缓存,因此未更改的规范可以立即重建。“canon freeze”(冻结规范)会针对特定的构建记录每次冻结操作,并将结果附加到“freeze-events.jsonl”审计跟踪中: “frozen”(已冻结)条目完全拒绝重新生成,“soft-advisory”(软提示)条目默认情况下拒绝(通过使用“--i-know”选项可以绕过)。“canon drift”(规范漂移)会重新计算每个受监控条目的哈希值,并标记自上次干净构建以来发生更改的任何内容。
122
+ 本地模型也可以草拟规范,但它不能决定规范。`sdlab canon draft <class_id> --endpoint <url> --brief "<text>" --out <path>` 向仅循环的、与 OpenAI 兼容的服务器请求规范条目和提示,并使用 `status: "draft"`、`judgment: null` 和草拟模型对每个输出进行标记。在有人批准之前,草拟内容不能被冻结:冻结关口拒绝任何由模型草拟的条目,除非有人的批准、理由以及批准的确切草拟的哈希值。
80
123
 
81
- 完整的流程在手册中:[构建规范](handbook/canon-build/)、[冻结规范](handbook/canon-freeze/)和[双 LoRA 堆叠](handbook/two-lora-stacking/)。
124
+ `canon build` 是基于内容的——它的输出由 `canon_sha` 键控并缓存,因此未更改的规范可以立即重建。`canon freeze` 见证每次冻结,并附加到 `freeze-events.jsonl` 审计跟踪中:`frozen` 条目完全拒绝重新生成,`soft-advisory` 条目默认拒绝(使用 `--i-know` 绕过)。`canon drift` 重新计算每个已监视条目的哈希值,并标记自上次干净构建以来发生更改的任何内容。
82
125
 
83
- ## 它产生的结果
126
+ 完整的流程在手册中:[规范构建](handbook/canon-build/)、[规范冻结](handbook/canon-freeze/) 和 [双 LoRA 堆叠](handbook/two-lora-stacking/)。
127
+
128
+ ## 它产生的内容
84
129
 
85
130
  七个数据集工件和一个完整的生产工作台。每个工件都链接到其前身,因此你可以追溯任何训练记录到批准它的规则。
86
131
 
87
132
  | 工件 | 它是什么 |
88
133
  |----------|-----------|
89
- | **Snapshot** | 带有配置指纹的冻结记录选择。每个包含项都有明确的原因。 |
134
+ | **Snapshot** | 带有配置指纹的冻结记录选择。每个包含都有明确的理由。 |
90
135
  | **Split** | 训练/验证/测试分区,其中主题系列不会跨越边界。 |
91
136
  | **Export package** | 自包含数据集:清单、元数据、图像、分割、数据集卡、校验和。 |
92
- | **Eval pack** | 考虑规范的测试任务:车道覆盖率、禁止漂移、锚点/黄金标准、主题连续性。 |
93
- | **Training package** | 通过适配器(“diffusers-lora”、“generic-image-caption”)实现的,可用于训练器的布局。相同的真实数据,不同的格式。 |
94
- | **Eval scorecard** | 根据评估包对生成的输出进行评分后的每个任务的通过/失败结果。 |
95
- | **Implementation pack** | 提示示例、已知错误、连续性测试和重新导入指南。 |
137
+ | **Eval pack** | 了解规范的测试任务:车道覆盖、禁止漂移、锚点/黄金样本、主题连续性。 |
138
+ | **Training package** | 通过适配器(`diffusers-lora`、`generic-image-caption`)构建可用于训练的布局。相同的真实数据,不同的格式。 |
139
+ | **Eval scorecard** | 根据评估包对生成的输出进行评分,从而得出每个任务的通过/失败结果。 |
140
+ | **Implementation pack** | 提示示例、已知失败案例、连续性测试和重新导入指南。 |
96
141
 
97
- 生产工作台添加的内容:
142
+ 生产工作台新增:
98
143
 
99
- | 表面 | 它做什么 |
144
+ | 表面 | 其作用 |
100
145
  |---------|-------------|
101
- | **Compiled brief** | 来自工作流程配置文件 + 项目真实数据的确定性生成指令。 |
102
- | **Run** | 冻结的执行工件:简报 + 种子 + ComfyUI 输出 + 清单。 |
146
+ | **Compiled brief** | 从工作流程配置文件 + 项目真实数据中生成确定性的生成指令。 |
147
+ | **Run** | 冻结的执行工件:简要说明 + 种子 + ComfyUI 输出 + 清单。 |
103
148
  | **Critique** | 对运行输出相对于规范进行结构化的多维评估。 |
104
- | **Batch** | 协调的多插槽生产(表现图、环境板、轮廓包)。 |
105
- | **Selection** | 创意决策工件:选择了哪些输出,原因是什么,以及它们来自哪里。 |
106
- | **Re-ingest** | 选定的输出作为带有完整生成来源的候选记录返回。 |
149
+ | **Batch** | 协调多插槽生产(表情表、环境板、轮廓包)。 |
150
+ | **Selection** | 创意决策工件:选择了哪些输出,原因是什么,以及它们的来源。 |
151
+ | **Re-ingest** | 选定的输出作为包含完整生成来源的候选记录返回。 |
107
152
 
108
- ## 为什么这个系统存在
153
+ ## 为什么存在这个系统
109
154
 
110
- 训练数据是任何视觉 AI 流水线中最重要的工件。但是,大多数训练数据只是一个包含图像的文件夹,没有历史记录、没有判断轨迹,也没有与它应该遵循的风格规则的联系。
155
+ 在任何视觉 AI 流水线中,训练数据是最有价值的资源。但大多数训练数据只是一个包含图像的文件夹,没有历史记录、没有判断依据,也没有与它应该遵循的风格规则的联系。
111
156
 
112
- “风格数据集实验室”使这种联系变得明确。你的规范定义了规则。你的评分标准定义了评分维度。你的策划记录了判断结果。你的规范绑定证明了这种联系。并且你的数据集将所有这些内容作为结构化、可查询、可重现的真实数据进行传递。
157
+ “风格数据集实验室”使这种联系变得明确。您的规范定义了规则。您的评分标准定义了评分维度。您的整理记录了判断过程。您的规范绑定证明了这种联系。并且您的数据集将所有这些内容作为结构化、可查询、可重现的真实数据进行保留。
113
158
 
114
- 实际效果:当你的 LoRA 发生漂移时,你可以询问*原因*。当你的下一个训练轮次需要更好的数据时,你确切地知道哪些记录是接近成功的,以及它们未能满足哪个单一规则。当新的团队成员询问项目的视觉语言是什么时,答案不是 Figma 板——而是一个可搜索的规范,其中包含 1,182 个分级的示例。
159
+ 实际结果:当您的 LoRA 发生漂移时,您可以询问*原因*。当您的下一个训练需要更好的数据时,您会确切地知道哪些记录接近失败,以及它们未能满足的单一规则。当新的团队成员询问项目的视觉语言时,答案不是一个 Figma 板——而是一个可搜索的规范,其中包含 1182 个分级示例。
115
160
 
116
- ## 在生产中得到验证
161
+ ## 已在生产中验证
117
162
 
118
- 这不是一个演示流水线。两个真实的风格 LoRA 都通过它完成了端到端的流程——相同的规范 → 策划 → 训练 → 发布循环,位于策划频谱的两端。
163
+ 这不是一个演示流水线。两个真实的风格 LoRA 已经通过它完成了端到端的流程——相同的规范 → 整理 → 训练 → 发布循环,位于整理频谱的相对两端。
119
164
 
120
- - **[Tallow Fen](handbook/case-study-tallow-fen/)**(生物设计)——一个从头开始构建的奇幻生物典籍规范,在 293 个策划记录中,大约有 **34% 的批准率**(169 个被拒绝——审核严格)。发布了 `tallow_fen_style_v3.safetensors`,权重为 1.5,用于 `qwen-image`。
121
- - **[Rustline](handbook/case-study-rustline/)**(概念设计)——密集、预先构建的规范,在 180 个记录中,大约有 **96% 的批准率**。发布了 `rustline_v3ckpt_1500.safetensors`,权重为 1.0,用于 `qwen-image`,并在后续项目中被第二个项目重用。
165
+ - **[Tallow Fen](handbook/case-study-tallow-fen/)**(生物设计)——一个从零开始构建的生物图鉴规范,在 293 个整理的记录中,约有 **34% 的批准率**(169 个被拒绝——筛选非常严格)。发布 `tallow_fen_style_v3.safetensors`,参数为 1.5,在 `qwen-image` 上运行。
166
+ - **[Rustline](handbook/case-study-rustline/)**(概念设计)——密集、预先构建的规范,在 180 个记录中,约有 **96% 的批准率**。发布 `rustline_v3ckpt_1500.safetensors`,参数为 1.0,在 `qwen-image` 上运行,并在后续项目中被第二个项目重用。
122
167
 
123
- 相同的流水线,两种生产配置:策划审核是真实的(它会严格拒绝开放主题),并且严谨的规范可以产生很高的接受率。
168
+ 相同的流水线,两种生产配置文件:整理筛选是真实的(它会严格拒绝开放主题),并且严格的规范会产生很高的接受率。
124
169
 
125
170
  ## 五个领域,真实的规则
126
171
 
127
- 不是占位符模板。每个领域都提供生产级别的规范规则、车道定义、评分标准和组词汇表。
172
+ 不是占位符模板。每个领域都提供生产级别的规范规则、车道定义、评分标准和组词汇。
128
173
 
129
- | 领域 | 通道 | 评估标准 |
174
+ | 领域 | 车道 | 需要判断的内容 |
130
175
  |--------|-------|-----------------|
131
- | **game-art** | 角色、环境、道具、用户界面、飞船、内部场景、设备 | 游戏中的轮廓、阵营特征、磨损和老化效果 |
132
- | **character-design** | 肖像、全身图、旋转图、表情表、动作姿势 | 比例、服装逻辑、个性、手势清晰度 |
133
- | **creature-design** | 概念图、正投影图、细节研究、动态效果、比例参考、栖息地 | 解剖结构、进化逻辑、轮廓区分 |
134
- | **architecture** | 外部、内部、街景、结构细节、废墟、景观 | 结构、材质一致性、透视、时代背景的一致性 |
176
+ | **game-art** | 角色、环境、道具、UI、飞船、内部、设备 | 在游戏规模下,轮廓、派系特征、磨损和老化 |
177
+ | **character-design** | 肖像、全身、旋转图、表情表、动作姿势 | 比例、服装逻辑、个性、姿势清晰度 |
178
+ | **creature-design** | 概念、正投影、细节研究、动作、比例参考、栖息地 | 解剖结构、进化逻辑、轮廓区分 |
179
+ | **architecture** | 外部、内部、街景、结构细节、废墟、景观 | 结构、材料一致性、透视、时代一致性 |
135
180
  | **vehicle-mech** | 外部、驾驶舱、组件、示意图、轮廓图、损坏变体 | 机械逻辑、设计语言、访问点、损坏叙事 |
136
181
 
137
182
  ## 项目结构
@@ -160,19 +205,23 @@ projects/my-project/
160
205
 
161
206
  ## 信任属性
162
207
 
163
- 这些不是理想化的,而是强制执行的。
208
+ 这些不是理想化的。它们是强制执行的。
164
209
 
165
- - **快照是不可变的。** 配置指纹(SHA-256)证明没有任何更改。
166
- - **分割可以防止数据泄露。** 主题组(按身份、血统或 ID 后缀划分)永远不会跨越分区边界。
167
- - **清单是冻结的合同。** 导出哈希 + 配置指纹。如果发生任何更改,请创建一个新的。
168
- - **运行会固定其确切的图。** 每次生成都会记录 `comfy_workflow_sha` + 模型/LoRA 内容哈希 + 种子策略,因此一个批次可以完全重现——在 JS 和 Python 运行器中都是相同的。模型哈希是可选的(`--hash-models`),并且绝不会被伪造。
169
- - **没有模型会验证自己的输出。** 评估会记录 `judged_by_model` 和 `generator_model`;如果它们曾经是同一个模型,则会发出警告。
170
- - **适配器不能改变真相。** 不同的布局,相同的数据。没有添加、删除或重新分类。
171
- - **生成的输出通过审核后重新进入。** 没有绕过。像其他所有内容一样进行策划和绑定。
210
+ - **快照是不可变的。** 配置指纹(SHA-256)证明没有发生任何更改。ID 以原子方式声明,因此两个并发运行不能交错到同一个目录中。
211
+ - **分割可以防止数据泄露——并且验证这一点的是一个独立的检查。** 主题族(按身份、谱系或规范化的 ID 词干)绝不会跨越分区边界,并且第二个检查会从头开始重新推导主题身份,而不是重新读取分割本身使用的映射。数据集卡仅在两个检查都运行并通过时声明“数据泄露:无(已验证)”;如果分割早于第二个检查,则会明确说明这一点。
212
+ - **清单是固定的协议。** 导出哈希 + 配置指纹,并且 `validate` 会重新哈希 `checksums.txt` 列出的每个文件——因此,替换已完成导出中的图像会被捕获,包括在创建清单之前进行的检查。
213
+ - **每次运行都会固定其确切的图。** 每次生成都会记录 `comfy_workflow_sha` + 模型/LoRA 内容哈希 + 种子策略,因此可以完全重现一次生成。JS 和 Python 运行器通过一个测试来确保字节级的哈希值完全相同,该测试会同时启动两者。模型哈希是可选的(`--hash-models`),并且绝不会伪造——无法解析的文件会记录 `sha256: null` 并附带说明。
214
+ - **没有模型会验证自己的输出。** 判决会记录 `judged_by_model` 和 `generator_model`;如果它们曾经是同一个模型,则会发出警告。
215
+ - **判决会说明是谁做出的。** `eligibility audit` 区分了某人编写的判决和批量脚本生成的判决,因此,描述的是一个类别而不是一个图像的理由,不能被视为策展。
216
+ - **测量不是判决。** `sdlab measure` 将数字附加到记录中。它绝不会设置判决、拟合或批准——并且对于图像而言,如果某个指标未定义,它会记录 `null` 而不是一个合理的数字。
217
+ - **发布可以证明每张图像的来源。** `sdlab verify --project <name>` 会为每条记录遍历链条:记录上的所有者和许可,它所绑定的规范条目(通过哈希),每个模型和 LoRA 的许可(SPDX ID、许可 URL、读取日期和文件哈希),以及运行清单中的工作流哈希。如果缺少链接,则检查会失败,而不是通过。
218
+ - **适配器不能改变真相。** 不同的布局,相同的记录。没有添加、没有删除、没有重新分类。
219
+ - **生成的输出会通过审核重新进入。** 没有绕过。像其他内容一样进行策展和绑定。外部生成的图像通过 `sdlab ingest` 以相同的方式进入,未经策展。
220
+ - **失败是可见的。** 缺少记录、无法放置的图像或无法构建的标题会停止导出或训练包,而不是悄悄地缩小它。
172
221
 
173
222
  ## 星际货运
174
223
 
175
- 该仓库包含一个完整的可运行示例:1,182 条记录、5 个阵营、7 个通道、24 条宪法规则、892 个已批准的资源、2 个训练配置文件。这是一个粗犷的科幻 RPG 视觉规范,经过完全策划。
224
+ 该存储库包含一个完整的可用示例:1182 条记录、5 个派系、7 条路线、24 条宪法规则、892 个已批准的资产、2 个训练配置文件。一个粗犷的科幻 RPG 视觉规范,已完全策展。
176
225
 
177
226
  ```bash
178
227
  git clone https://github.com/mcp-tool-shop-org/style-dataset-lab
@@ -184,7 +233,7 @@ sdlab split build --project star-freight # zero subject leakage
184
233
 
185
234
  ## 下游格式
186
235
 
187
- `sdlab` 拥有数据集。格式转换由 [`repo-dataset`](https://github.com/mcp-tool-shop-org/repo-dataset) 处理:TRL、LLaVA、Qwen2-VL、JSONL、Parquet 等。`repo-dataset` 进行渲染;它不会决定是否包含。
236
+ `sdlab` 拥有数据集。格式转换由 [`repo-dataset`](https://github.com/mcp-tool-shop-org/repo-dataset) 处理:TRL、LLaVA、Qwen2-VL、JSONL、Parquet 等。`repo-dataset` 进行渲染;它绝不会决定是否包含。
188
237
 
189
238
  ## 安装
190
239
 
@@ -192,11 +241,11 @@ sdlab split build --project star-freight # zero subject leakage
192
241
  npm install -g @mcptoolshop/style-dataset-lab
193
242
  ```
194
243
 
195
- 需要 Node.js 20+ 和本地主机上的 [ComfyUI](https://github.com/comfyanonymous/ComfyUI),地址为 8188,用于生成。
244
+ 需要 Node.js 20+ 和本地主机 8188 上的 [ComfyUI](https://github.com/comfyanonymous/ComfyUI) 进行生成。
196
245
 
197
- ### 在不使用 ComfyUI 的情况下试用
246
+ ### 尝试不使用 ComfyUI
198
247
 
199
- 您可以探索完整的非生成界面——检查、策划、快照、分割、导出——使用捆绑的星际货运项目,而无需安装 ComfyUI 或下载任何 SDXL 权重。
248
+ 您可以使用捆绑的星际货运项目探索完整的非生成表面——检查、策展、快照、分割、导出——而无需安装 ComfyUI 或下载任何 SDXL 权重。
200
249
 
201
250
  ```bash
202
251
  # Scaffold a fresh project (no ComfyUI needed)
@@ -209,9 +258,9 @@ sdlab project doctor --project test
209
258
  sdlab snapshot create --dry-run --project star-freight
210
259
  ```
211
260
 
212
- `sdlab project doctor` 会验证每个项目配置(宪法、通道、评分标准、术语),并在不触及 GPU 的情况下报告资格。任何会更改生成状态的命令都接受 `--dry-run`,以便首先预览效果。
261
+ `sdlab project doctor` 验证每个项目配置(宪法、路线、评分标准、术语),并在不触及 GPU 的情况下报告资格。任何更改生成状态的命令都接受 `--dry-run` 以首先预览效果。
213
262
 
214
- 如果您忘记了 `--project`,CLI 将回退到在 `projects/` 下找到的第一个项目并打印警告——明确传递 `--project` 以使其停止发出警告。
263
+ 如果您忘记了 `--project`,CLI 将回退到 `projects/` 下找到的第一个项目,并打印警告——明确传递 `--project` 以使其停止。
215
264
 
216
265
  ### 恢复中断的运行
217
266
 
@@ -227,41 +276,43 @@ sdlab generate inputs/prompts/wave1.json --project my-project --resume
227
276
  sdlab batch generate --resume batch_2026-04-22_001 --project my-project
228
277
  ```
229
278
 
230
- 这两个命令都有效,因为每个插槽都会在其完成后以原子方式写入其清单条目——在运行过程中发生崩溃绝不会破坏部分状态。
279
+ 这两个命令都有效,因为每个插槽都会在其完成时以原子方式写入其清单条目——运行过程中发生崩溃绝不会破坏部分状态。
231
280
 
232
281
  ## 故障排除
233
282
 
234
- 常见的失败模式和解决方法:
283
+ 常见故障模式和解决方法:
235
284
 
236
- **任何 `sdlab generate` / `sdlab run generate` / `sdlab batch generate` 上的 `ECONNREFUSED 127.0.0.1:8188`**
237
- ComfyUI 没有运行。启动 ComfyUI(`python main.py --listen 127.0.0.1 --port 8188`),并使用 `curl http://127.0.0.1:8188/system_stats` 进行确认。要指向不同的主机/端口,请设置 `COMFY_URL=http://host:port`。
285
+ **`ECONNREFUSED 127.0.0.1:8188` 在任何 `sdlab generate` / `sdlab run generate` / `sdlab batch generate` 上**
286
+ ComfyUI 尚未运行。启动 ComfyUI(`python main.py --listen 127.0.0.1 --port 8188`),并使用 `curl http://127.0.0.1:8188/system_stats` 进行确认。要指向不同的主机/端口,请设置 `COMFY_URL=http://host:port`。
238
287
 
239
288
  **`missing checkpoint` / `LoRA weight not found`**
240
- 您的工作流程配置文件指定了一个不在 ComfyUI 的 `models/checkpoints/` 或 `models/loras/` 文件夹中的模型文件。打开 `projects/<project>/workflows/profiles/<profile>.json`,找到 `checkpoint` 或 `lora` 字段,然后下载引用的权重或将其替换为您已有的权重。重新运行 `sdlab project doctor --project <project>` 以确认修复。
289
+ 您的工作流配置文件指定了一个不在 ComfyUI 的 `models/checkpoints/` 或 `models/loras/` 文件夹中的模型文件。打开 `projects/<project>/workflows/profiles/<profile>.json`,找到 `checkpoint` 或 `lora` 字段,然后下载引用的权重或将其替换为您已有的权重。重新运行 `sdlab project doctor --project <project>` 以确认修复。
241
290
 
242
291
  **`sdlab project doctor` 错误**
243
- Doctor 返回结构化的错误代码。常见的错误:
244
- - `E_PROJECT_NOT_FOUND`——项目目录在 `projects/` 下不存在。检查拼写。
292
+ Doctor 返回结构化的错误代码。常见错误:
293
+ - `E_PROJECT_NOT_FOUND`——项目目录不存在于 `projects/` 下。检查拼写。
245
294
  - `E_CONFIG_INVALID`——五个 JSON 配置文件中的一个未能通过模式验证。`hint` 字段指定了错误的 文件和字段。
246
- - `E_RECORD_DRIFT`——记录的配置指纹不再与其来源匹配。如提示所述,重新策划或重新绑定。
295
+ - `E_RECORD_DRIFT`——记录的配置指纹不再与其来源匹配。如提示所述,重新策展或重新绑定。
247
296
 
248
297
  **`No --project specified, falling back to <name>`**
249
- 一个软警告。明确传递 `--project <name>` 以选择正确的项目并停止发出警告。
298
+ 一个软警告。明确传递 `--project <name>` 以选择正确的项目并停止警告。
250
299
 
251
300
  **绘画风格 / VRAM 内存不足问题**
252
- 请参阅 `docs/internal/HANDOFF.md`,了解有关绘画风格降噪调整说明。简而言之:降低降噪强度、减少批处理大小或在工作流程配置文件中切换到较小的检查点。
301
+ 请参阅 `docs/internal/HANDOFF.md` 以获取绘画风格去噪调整说明。简而言之:降低去噪强度、减少批处理大小或在工作流配置文件中切换到较小的检查点。
253
302
 
254
303
  **报告错误**
255
- 在 https://github.com/mcp-tool-shop-org/style-dataset-lab/issues 上提交问题,并提供您的 sdlab 版本(`sdlab --version`)、Node 版本(`node -v`)、完整的命令以及结构化的错误输出。一个错误报告模板会预填充这些字段。
304
+ 在 https://github.com/mcp-tool-shop-org/style-dataset-lab/issues 上提交问题,并提供您的 sdlab 版本(`sdlab --version`)、Node 版本(`node -v`)、完整的命令以及结构化的错误输出。错误报告模板会预填充字段。
256
305
 
257
306
  ## 安全性
258
307
 
259
- 仅限本地使用。没有遥测、分析或外部请求。图像保留在您的 GPU 和文件系统中。
308
+ 默认情况下为本地。没有遥测、没有分析,并且 `sdlab` CLI 不会进行任何外部请求:图像保留在您的 GPU 和文件系统中,并且 `canon draft` 拒绝任何非环回的端点。
309
+
310
+ 唯一的例外是“选择加入”功能。`scripts/colab/` 包含用于在您自己的 Google Colab 帐户上运行渲染或 LoRA 训练步骤的启动工具包。它们只会上传您指定的文件,并在不超过从您的 Colab 帐户余额中读取的预算限制的情况下运行,并在退出时停止自身的会话。这些工具包是**实验性的**:它们尚未完成完整的端到端测试。
260
311
 
261
- ## 许可协议
312
+ ## 许可
262
313
 
263
314
  MIT
264
315
 
265
316
  ---
266
317
 
267
- 由 <a href="https://mcp-tool-shop.github.io/">MCP Tool Shop</a> 构建。
318
+ 由 <a href="https://mcp-tool-shop.github.io/">MCP Tool Shop</a> 构建
package/bin/sdlab.js CHANGED
@@ -18,6 +18,21 @@ const COMMANDS = {
18
18
  'generate:controlnet': '../scripts/generate-controlnet.js',
19
19
  'generate:ipadapter': '../scripts/generate-ipadapter.js',
20
20
  'curate': '../scripts/curate.js',
21
+ // Bring images that were generated OUTSIDE sdlab into the pipeline. The
22
+ // documented production loop (brief→run→critique→batch→select→reingest) has
23
+ // never run on any project in this repo — real generation happens in
24
+ // external Python against Comfy Cloud, and until now those images had no
25
+ // CLI path in. `reingest generated` needs a trained LoRA's manifest;
26
+ // `reingest selected` needs a selection only the loop can mint.
27
+ 'ingest': '../scripts/ingest.js',
28
+ // Contact sheet over ANY directory of candidates. The renderer already
29
+ // existed (lib/batch-sheet-render.js) but was reachable only via
30
+ // `batch sheet`, which needs a batch manifest nothing has ever produced —
31
+ // so five hand-rolled PIL contact-sheet scripts grew up in projects/ instead.
32
+ 'sheet': '../scripts/sheet.js',
33
+ // Deterministic pixel measurement. Nothing in this tool opened an image
34
+ // before this: critique scores brief TEXT, not pixels.
35
+ 'measure': '../scripts/measure.js',
21
36
  'compare': '../scripts/compare.js',
22
37
  'bind': '../scripts/canon-bind.js',
23
38
  'canon-bind': '../scripts/canon-bind.js',
@@ -36,6 +51,7 @@ const COMMANDS = {
36
51
  'eval-run': '../scripts/eval-run.js',
37
52
  'implementation-pack': '../scripts/implementation-pack.js',
38
53
  'reingest': '../scripts/reingest.js',
54
+ 'verify': '../scripts/verify.js',
39
55
  };
40
56
 
41
57
  // Two-word commands under "project" namespace
@@ -87,6 +103,14 @@ const CANON_COMMANDS = {
87
103
  'unfreeze': '../scripts/canon-unfreeze.js',
88
104
  'freeze-status': '../scripts/canon-freeze-status.js',
89
105
  'drift': '../scripts/canon-drift.js',
106
+ 'draft': '../scripts/canon-draft.js',
107
+ };
108
+
109
+ // Two-word commands under "asset" namespace — the asset lane
110
+ // (docs/asset-lane-design.md): manifest-driven, gated ingest of
111
+ // provenance-carrying asset exports, beside the bare `sdlab ingest`.
112
+ const ASSET_COMMANDS = {
113
+ 'ingest': '../scripts/asset-ingest.js',
90
114
  };
91
115
 
92
116
  // ─── Per-command help ─────────────────────────────────────────────────
@@ -337,6 +361,41 @@ Subcommands:
337
361
 
338
362
  Flags:
339
363
  --project <name> Project to operate on`,
364
+
365
+ 'verify': `sdlab verify --project <name> [--record <id>] [--snapshot <id>] [--json]
366
+
367
+ Verify the full offline provenance chain for CC-BY-4.0 release:
368
+ record (G5 owner + CC-BY-4.0) -> canon (G6 canon_sha + entry_sha256)
369
+ -> model licence (G4 SPDX id + licence_url + date_read) -> run manifest (workflow sha).
370
+
371
+ Flags:
372
+ --project <name> Project to verify
373
+ --record <id> Verify a single record id
374
+ --snapshot <id> Verify all records in a snapshot
375
+ --json Emit machine-readable JSON report`,
376
+
377
+ 'asset ingest': `sdlab asset ingest <dir> --project <name> [--dry-run] [--json]
378
+
379
+ Register a provenance-carrying asset export into a project. The export
380
+ directory must contain an asset-source.json manifest; ingest validates it
381
+ end to end (schema, path containment, encoding proofs against actual file
382
+ bytes, categorical palette proofs, the acceptance verdict) and refuses
383
+ loudly on any violation — nothing registers on a bad manifest.
384
+
385
+ Admitted renders land as uncurated candidate records (judgment: null,
386
+ provenance.source: "asset") with per-render gate measurements attached.
387
+ An ingest-receipt.json under assets/<asset-id>/ lists every written path.
388
+
389
+ Positional:
390
+ dir Asset export directory (may live outside the
391
+ workspace — read-only source)
392
+
393
+ Flags:
394
+ --project <name> Project to register into
395
+ --dry-run Validate + run gates + report; write nothing
396
+ --json Emit the result as JSON on stdout
397
+
398
+ Contract reference: docs/asset-lane-design.md`,
340
399
  };
341
400
 
342
401
  // "bind" is a short alias for "canon-bind" — share help.
@@ -356,19 +415,26 @@ function printHelp() {
356
415
  console.log(' init <name> Scaffold a new project from a domain template');
357
416
  console.log(' project doctor Validate project config and structure');
358
417
  console.log(' project migrate Migrate record schemas');
418
+ console.log(' verify Verify full provenance chain (record -> canon -> licence -> run)');
359
419
  console.log('');
360
420
  console.log('Pipeline:');
361
421
  console.log(' generate Generate candidates from a prompt pack');
362
422
  console.log(' generate:identity Generate named-subject identity images');
363
423
  console.log(' generate:controlnet ControlNet-guided structural generation');
364
424
  console.log(' generate:ipadapter IP-Adapter reference-guided generation');
425
+ console.log(' ingest <dir> Ingest externally-generated images as candidates');
365
426
  console.log(' curate Move candidate to approved/rejected/borderline');
427
+ console.log(' sheet [<dir>] Render an HTML contact sheet for visual review');
428
+ console.log(' measure <target> Measure candidate pixels (palette, texture)');
366
429
  console.log(' compare Record pairwise A-vs-B comparison');
367
430
  console.log(' canon-bind Bind approved records to constitution rules');
368
431
  console.log(' ("bind" is a short alias for canon-bind)');
369
432
  console.log(' painterly Post-processing painterly style pass');
370
433
  console.log(' painterly:test Calibrate painterly denoise level on sample images');
371
434
  console.log('');
435
+ console.log('Asset lane:');
436
+ console.log(' asset ingest <dir> Register a provenance-carrying asset export (asset-source.json)');
437
+ console.log('');
372
438
  console.log('Canon:');
373
439
  console.log(' canon build Build dataset.jsonl + prompts/*.j2 + context/*.md from canon entries');
374
440
  console.log(' canon freeze <id> Stamp a freeze block on an entry (--reason required)');
@@ -445,15 +511,19 @@ function printHelp() {
445
511
  console.log('Examples:');
446
512
  console.log(' sdlab init my-project --domain character-design');
447
513
  console.log(' sdlab generate --help');
448
- console.log(' sdlab snapshot create --project star-freight');
449
- console.log(' sdlab split build --dry-run --project star-freight');
450
- console.log(' sdlab training-package build --debug --project star-freight');
514
+ console.log(' sdlab snapshot create --project my-project');
515
+ console.log(' sdlab split build --dry-run --project my-project');
516
+ console.log(' sdlab training-package build --debug --project my-project');
451
517
  }
452
518
 
453
519
  // All top-level command tokens users can type (including two-word heads).
454
520
  function allKnownCommands() {
455
521
  const oneWord = Object.keys(COMMANDS);
456
- const heads = ['project', 'workflow', 'brief', 'run', 'critique', 'refine', 'batch', 'select', 'selection'];
522
+ // SDL-L8: 'canon' is a real two-word namespace (see CANON_COMMANDS / the
523
+ // `namespaces` table in main()) but was missing from this list, so a typo
524
+ // like "sdlab cannon build" had no candidate to suggest against — every
525
+ // other namespace head got a "Did you mean ...?" hint, canon did not.
526
+ const heads = ['project', 'workflow', 'brief', 'run', 'critique', 'refine', 'batch', 'select', 'selection', 'canon', 'asset'];
457
527
  return [...new Set([...oneWord, ...heads])];
458
528
  }
459
529
 
@@ -515,6 +585,7 @@ async function main() {
515
585
  twoWord('batch', BATCH_COMMANDS),
516
586
  twoWord('selection', SELECTION_COMMANDS),
517
587
  twoWord('canon', CANON_COMMANDS),
588
+ twoWord('asset', ASSET_COMMANDS),
518
589
  ];
519
590
 
520
591
  // "project", "workflow", "brief", "run", "batch", "selection" two-word forms
@@ -529,6 +600,31 @@ async function main() {
529
600
  }
530
601
  }
531
602
 
603
+ // SDL-L2: a bare or invalid namespace verb ("sdlab workflow", "sdlab batch
604
+ // bogus"). These heads only exist as two-word commands — falling through to
605
+ // the generic COMMANDS[command] lookup below used to hand `command` itself
606
+ // to findClosest() against a corpus that includes that same head, so the
607
+ // suggester matched itself at distance 0 and printed "Unknown command:
608
+ // workflow" / 'Did you mean "workflow"?' — a hint that echoes the very
609
+ // thing the user just typed. List the real subcommands instead.
610
+ for (const { head, table } of namespaces) {
611
+ if (command === head) {
612
+ const subs = Object.keys(table);
613
+ if (!args[1] || args[1] === '--help' || args[1] === '-h') {
614
+ console.log(`sdlab ${head} <${subs.join('|')}>\n`);
615
+ console.log('Subcommands:');
616
+ for (const s of subs) console.log(` ${s}`);
617
+ console.log(`\nRun "sdlab ${head} <subcommand> --help" for details.`);
618
+ return;
619
+ }
620
+ const suggestion = findClosest(args[1], subs);
621
+ const hint = suggestion
622
+ ? `Did you mean "sdlab ${head} ${suggestion}"?`
623
+ : `Try: ${subs.map(s => `sdlab ${head} ${s}`).join(', ')}`;
624
+ throw inputError('INPUT_UNKNOWN_SUBCOMMAND', `Unknown ${head} subcommand: ${args[1]}`, hint);
625
+ }
626
+ }
627
+
532
628
  // "critique" — bare or "critique show"
533
629
  if (command === 'critique') {
534
630
  if (args[1] && CRITIQUE_COMMANDS[args[1]]) {