skill-family-engineering-kit 0.5.0 → 0.7.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 (36) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/CHANGELOG.zh-CN.md +43 -0
  3. package/README.md +19 -10
  4. package/README.zh-CN.md +19 -10
  5. package/docs/agents/capability-catalog.en.json +243 -17
  6. package/docs/agents/capability-catalog.json +179 -13
  7. package/docs/agents/capability-catalog.zh-CN.json +243 -17
  8. package/docs/architecture/index.html +3 -3
  9. package/docs/en/migration/index.html +32 -87
  10. package/docs/en/reference/failure-and-side-effect-matrix/index.html +1 -1
  11. package/docs/integration/audit/index.html +2 -1
  12. package/docs/integration/audit/version-compatibility/index.html +66 -3
  13. package/docs/migration/index.html +32 -87
  14. package/docs/public/status/index.html +3 -3
  15. package/docs/reference/api/engineering-kit/index.html +117 -12
  16. package/docs/reference/api/harness/index.html +83 -3
  17. package/docs/reference/failure-and-side-effect-matrix/index.html +1 -1
  18. package/docs/search/search_index.json +1 -1
  19. package/package.json +6 -4
  20. package/profile-spi/extension-spi.json +162 -0
  21. package/profile-spi/index.mjs +574 -0
  22. package/profile-spi/profile-adoption.schema.json +120 -0
  23. package/profile-spi/profile-descriptor.schema.json +99 -0
  24. package/profile-spi/rule-baseline-catalog.json +50 -0
  25. package/release-notes/0.6.0.yaml +25 -0
  26. package/release-notes/0.7.0.yaml +23 -0
  27. package/src/adopt-plan.mjs +81 -159
  28. package/src/check.mjs +443 -19
  29. package/src/cli.mjs +80 -1
  30. package/src/core-check.mjs +8 -4
  31. package/src/entry-check.mjs +384 -0
  32. package/src/errors.mjs +21 -0
  33. package/src/index.mjs +36 -6
  34. package/src/projection.mjs +298 -45
  35. package/src/relock.mjs +397 -0
  36. package/src/skeleton.mjs +162 -4
@@ -762,10 +762,10 @@
762
762
  <ul class="md-nav__list">
763
763
 
764
764
  <li class="md-nav__item">
765
- <a href="#planAdoption--buildHandoffDraft--evaluateMigrationCompletion--validateException--assessLegacyExitList--findNestedRepositories" class="md-nav__link">
765
+ <a href="#planAdoption--buildProfileDraft--evaluateMigrationCompletion--validateException--assessLegacyExitList--findNestedRepositories" class="md-nav__link">
766
766
  <span class="md-ellipsis">
767
767
 
768
- planAdoption / buildHandoffDraft / evaluateMigrationCompletion / validateException / assessLegacyExitList / findNestedRepositories
768
+ planAdoption / buildProfileDraft / evaluateMigrationCompletion / validateException / assessLegacyExitList / findNestedRepositories
769
769
 
770
770
  </span>
771
771
  </a>
@@ -798,6 +798,17 @@
798
798
  </span>
799
799
  </a>
800
800
 
801
+ </li>
802
+
803
+ <li class="md-nav__item">
804
+ <a href="#buildProjectionClosure" class="md-nav__link">
805
+ <span class="md-ellipsis">
806
+
807
+ buildProjectionClosure
808
+
809
+ </span>
810
+ </a>
811
+
801
812
  </li>
802
813
 
803
814
  </ul>
@@ -999,6 +1010,34 @@
999
1010
  </ul>
1000
1011
  </nav>
1001
1012
 
1013
+ </li>
1014
+
1015
+ <li class="md-nav__item">
1016
+ <a href="#Profile-SPI-公共投影" class="md-nav__link">
1017
+ <span class="md-ellipsis">
1018
+
1019
+ Profile SPI 公共投影
1020
+
1021
+ </span>
1022
+ </a>
1023
+
1024
+ <nav class="md-nav" aria-label="Profile SPI 公共投影">
1025
+ <ul class="md-nav__list">
1026
+
1027
+ <li class="md-nav__item">
1028
+ <a href="#公共入口" class="md-nav__link">
1029
+ <span class="md-ellipsis">
1030
+
1031
+ 公共入口
1032
+
1033
+ </span>
1034
+ </a>
1035
+
1036
+ </li>
1037
+
1038
+ </ul>
1039
+ </nav>
1040
+
1002
1041
  </li>
1003
1042
 
1004
1043
  <li class="md-nav__item">
@@ -2016,10 +2055,10 @@
2016
2055
  <ul class="md-nav__list">
2017
2056
 
2018
2057
  <li class="md-nav__item">
2019
- <a href="#planAdoption--buildHandoffDraft--evaluateMigrationCompletion--validateException--assessLegacyExitList--findNestedRepositories" class="md-nav__link">
2058
+ <a href="#planAdoption--buildProfileDraft--evaluateMigrationCompletion--validateException--assessLegacyExitList--findNestedRepositories" class="md-nav__link">
2020
2059
  <span class="md-ellipsis">
2021
2060
 
2022
- planAdoption / buildHandoffDraft / evaluateMigrationCompletion / validateException / assessLegacyExitList / findNestedRepositories
2061
+ planAdoption / buildProfileDraft / evaluateMigrationCompletion / validateException / assessLegacyExitList / findNestedRepositories
2023
2062
 
2024
2063
  </span>
2025
2064
  </a>
@@ -2052,6 +2091,17 @@
2052
2091
  </span>
2053
2092
  </a>
2054
2093
 
2094
+ </li>
2095
+
2096
+ <li class="md-nav__item">
2097
+ <a href="#buildProjectionClosure" class="md-nav__link">
2098
+ <span class="md-ellipsis">
2099
+
2100
+ buildProjectionClosure
2101
+
2102
+ </span>
2103
+ </a>
2104
+
2055
2105
  </li>
2056
2106
 
2057
2107
  </ul>
@@ -2253,6 +2303,34 @@
2253
2303
  </ul>
2254
2304
  </nav>
2255
2305
 
2306
+ </li>
2307
+
2308
+ <li class="md-nav__item">
2309
+ <a href="#Profile-SPI-公共投影" class="md-nav__link">
2310
+ <span class="md-ellipsis">
2311
+
2312
+ Profile SPI 公共投影
2313
+
2314
+ </span>
2315
+ </a>
2316
+
2317
+ <nav class="md-nav" aria-label="Profile SPI 公共投影">
2318
+ <ul class="md-nav__list">
2319
+
2320
+ <li class="md-nav__item">
2321
+ <a href="#公共入口" class="md-nav__link">
2322
+ <span class="md-ellipsis">
2323
+
2324
+ 公共入口
2325
+
2326
+ </span>
2327
+ </a>
2328
+
2329
+ </li>
2330
+
2331
+ </ul>
2332
+ </nav>
2333
+
2256
2334
  </li>
2257
2335
 
2258
2336
  <li class="md-nav__item">
@@ -2301,7 +2379,7 @@
2301
2379
  <ul>
2302
2380
  <li><a href="#scaffold-foundationkitscaffold">scaffold</a> → <code>scaffoldTarget</code></li>
2303
2381
  <li><a href="#adopt-plan-foundationkitadopt-plan">adopt-plan</a> → <code>planAdoption</code> / <code>evaluateMigrationCompletion</code></li>
2304
- <li><a href="#projection-foundationkitprojection">projection</a> → <code>runProjection</code> / <code>loadProjectionManifest</code></li>
2382
+ <li><a href="#projection-foundationkitprojection">projection</a> → <code>buildProjectionClosure</code> / <code>runProjection</code> / <code>loadProjectionManifest</code></li>
2305
2383
  <li><a href="#check-foundationkitcheck">check</a> → <code>runChecks</code> / <code>runCoreCheck</code></li>
2306
2384
  <li><a href="#report-foundationkitreport">report</a> → <code>renderReportAction</code> / <code>checkReportAction</code></li>
2307
2385
  <li><a href="#git-probe-foundationkitgit-probe">git-probe</a> → <code>probeGitState</code> / <code>probeGitFacts</code></li>
@@ -2319,11 +2397,11 @@
2319
2397
  <li><code>describeSkeletonFiles(inputs)</code>(async)</li>
2320
2398
  <li><code>normalizeSkeletonInputs({ projectId, projectName, profileId, licensingProfile, licensingVariant, rootBasename })</code></li>
2321
2399
  <li>输入:目标根、骨架选项(<code>projectId</code> 等)。</li>
2322
- <li>输出:精确集合的托管骨架文件(原子 + 路径收容)。</li>
2400
+ <li>输出:精确集合的托管骨架文件(原子 + 路径收容)。含两个目标侧手写种子(<code>handwritten</code> 类,adopt 永不覆写):<code>SOURCE-OF-TRUTH.md</code>(唯一声明点、真源清单与生成谱系、运行与证据目录约定)与 <code>profile.json</code>(<code>foundation_profile</code> / <code>foundation_pin</code> 采用字段加只收紧方向的 overrides 示例);<code>.gitignore</code> / <code>.projenrc.js</code> / file-registry 三处同步携带根级唯一忽略基线 <code>/site/</code>、<code>/.qoder/</code>、<code>/.artifacts/</code>、<code>/.runs/</code>、<code>/.evidence/</code>(嵌套同名目录不被忽略)。</li>
2323
2401
  <li>纯函数:<code>normalizeSkeletonInputs</code> 是;<code>scaffoldTarget</code> 落盘。</li>
2324
2402
  <li>副作用:在受收容目标创建文件(原子 + 收容);目标非空则拒绝、不覆盖。</li>
2325
2403
  <li>稳定错误码与 <code>details.kind</code>:非法 kebab <code>projectId</code> / 非空目标抛 <code>KitError</code>(<code>KIT_ERROR_KINDS</code> 的 <code>invalid-params</code> / <code>rejected</code>);非法参数 <code>+ INVALID_PARAMS</code>(<code>SFC2003</code>)。</li>
2326
- <li>前置条件与信任锚:目标为可写空目录;Node &gt;= 22.22.2;骨架集合与 <code>scaffold-conformance</code> fixture 一致。</li>
2404
+ <li>前置条件与信任锚:目标为可写空目录;Node &gt;= 22.22.2;骨架集合与 <code>scaffold-conformance</code> fixture 一致(33 个计划文件)。</li>
2327
2405
  <li><code>since</code> / <code>stability</code>:<code>0.2.0</code> / <code>stable</code>。</li>
2328
2406
  <li>源文件:<code>packages/skill-family-engineering-kit/src/scaffold.mjs</code>、<code>skeleton.mjs</code>。</li>
2329
2407
  <li>正例/负例测试:<code>packages/skill-family-engineering-kit/test/scaffold.test.mjs</code>、<code>skeleton-contract.test.mjs</code>。</li>
@@ -2331,17 +2409,17 @@
2331
2409
  </ul>
2332
2410
  <hr />
2333
2411
  <h2 id="adopt-plan-foundationkitadopt-plan">adopt-plan (foundation.kit.adopt-plan)<a class="headerlink" href="#adopt-plan-foundationkitadopt-plan" title="Permanent link">&para;</a></h2>
2334
- <h3 id="planAdoption--buildHandoffDraft--evaluateMigrationCompletion--validateException--assessLegacyExitList--findNestedRepositories">planAdoption / buildHandoffDraft / evaluateMigrationCompletion / validateException / assessLegacyExitList / findNestedRepositories<a class="headerlink" href="#planAdoption--buildHandoffDraft--evaluateMigrationCompletion--validateException--assessLegacyExitList--findNestedRepositories" title="Permanent link">&para;</a></h3>
2412
+ <h3 id="planAdoption--buildProfileDraft--evaluateMigrationCompletion--validateException--assessLegacyExitList--findNestedRepositories">planAdoption / buildProfileDraft / evaluateMigrationCompletion / validateException / assessLegacyExitList / findNestedRepositories<a class="headerlink" href="#planAdoption--buildProfileDraft--evaluateMigrationCompletion--validateException--assessLegacyExitList--findNestedRepositories" title="Permanent link">&para;</a></h3>
2335
2413
  <ul>
2336
2414
  <li>签名(节选):</li>
2337
2415
  <li><code>planAdoption({ root, manifest, ... } = {})</code>(async)</li>
2338
- <li><code>buildHandoffDraft({ ... })</code></li>
2416
+ <li><code>buildProfileDraft({ inputs, migrationManifest, writeSet, entries })</code></li>
2339
2417
  <li><code>evaluateMigrationCompletion({ ... })</code></li>
2340
2418
  <li><code>validateException(exception, index, nowMs)</code></li>
2341
2419
  <li><code>assessLegacyExitList(root, legacyItems)</code>(async)</li>
2342
2420
  <li><code>findNestedRepositories(entries)</code></li>
2343
2421
  <li>输入:目标根、迁移清单路径。</li>
2344
- <li>输出:采用分类(<code>direct-adoption</code> / <code>compatibility-layer</code> / <code>keep-business</code> / <code>foundation-gap</code>)、完成判定、handoff 草稿(仅输出,不落盘)。</li>
2422
+ <li>输出:采用分类(<code>direct-adoption</code> / <code>compatibility-layer</code> / <code>keep-business</code> / <code>foundation-gap</code>)、完成判定、profile 草稿(kind=<code>skill-family.profile-draft</code>:预填 D-8 最小采用声明 + 空 overrides 示例,仅输出,不落盘;adoption-lock 形态已废弃)。</li>
2345
2423
  <li>纯函数:分类与评估函数为纯函数;<code>planAdoption</code> 含只读探测。</li>
2346
2424
  <li>副作用:<strong>严格只读</strong>——不写文件(临时文件也不写)、不 Git 写、不 rename、不触网;可能触发只读 Git 探测。</li>
2347
2425
  <li>稳定错误码与 <code>details.kind</code>:例外缺字段 / 未退出旧实现则完成判定 <code>false</code>;硬失败抛 <code>KitError</code>(<code>CONTRACTS_VERSION</code> 不一致等)。</li>
@@ -2369,6 +2447,21 @@
2369
2447
  <li>正例/负例测试:<code>packages/skill-family-engineering-kit/test/projection.test.mjs</code>。</li>
2370
2448
  <li>调用方仍拥有的业务语义:投影内容的业务含义(远端发布转 <code>release-skill</code>)。</li>
2371
2449
  </ul>
2450
+ <h3 id="buildProjectionClosure">buildProjectionClosure<a class="headerlink" href="#buildProjectionClosure" title="Permanent link">&para;</a></h3>
2451
+ <ul>
2452
+ <li>签名:<code>buildProjectionClosure(resources)</code></li>
2453
+ <li>输入:资源数组,成员为 <code>{path, sha256, mode}</code>(显式 <code>type: "file"</code> 被容忍)。</li>
2454
+ <li>输出:规范投影闭包 <code>{digestAlgorithm: "sha256", digest, resourceCount, resources}</code>(成员规范化为 <code>{path, type: "file", sha256, mode}</code>,按 path 确定性排序,<code>digest = sha256(JSON.stringify(resources))</code>),可原样作为 <code>compileProjectionPlan()</code> 的 <code>previousOwnedClosure</code> 或 <code>externalCandidateClosure</code>;空数组是合法空闭包。</li>
2455
+ <li>纯函数:是(无文件读写、无网络、无子进程;入参不被改写)。</li>
2456
+ <li>副作用:无。</li>
2457
+ <li>稳定错误码与 <code>details.kind</code>:非数组输入、重复路径、可移植路径碰撞、非法 path/type/sha256/mode 在既有 <code>projection plan input invalid</code> 错误域内失败关闭(<code>SFC2004</code>,<code>details.kind</code> 为 <code>invalid-manifest</code>)。</li>
2458
+ <li>边界:本函数构造的是投影/计划闭包,与 Harness <code>computeResourceClosure()</code> 的资源闭包(成员 <code>{path, role, exists, sha256}</code>、整体信封摘要)形状与用途不同,两者不可互换;与 <code>normalizePlanClosure()</code>、候选枚举闭包共享同一规范化与摘要事实源。</li>
2459
+ <li>前置条件与信任锚:无;结果直接满足 <code>compileProjectionPlan()</code> 的闭包合同,不新增第二个编译入口。</li>
2460
+ <li><code>since</code> / <code>stability</code>:<code>0.7.0</code> / <code>stable</code>。</li>
2461
+ <li>源文件:<code>packages/skill-family-engineering-kit/src/projection.mjs</code>。</li>
2462
+ <li>正例/负例测试:<code>packages/skill-family-engineering-kit/test/projection-closure-builder.test.mjs</code>。</li>
2463
+ <li>调用方仍拥有的业务语义:投影内容的业务含义与资源字节的来源证明。</li>
2464
+ </ul>
2372
2465
  <hr />
2373
2466
  <h2 id="check-foundationkitcheck">check (foundation.kit.check)<a class="headerlink" href="#check-foundationkitcheck" title="Permanent link">&para;</a></h2>
2374
2467
  <h3 id="runChecks--runCoreCheck--isContainedDeclaration">runChecks / runCoreCheck / isContainedDeclaration<a class="headerlink" href="#runChecks--runCoreCheck--isContainedDeclaration" title="Permanent link">&para;</a></h3>
@@ -2377,11 +2470,11 @@
2377
2470
  <li><code>runChecks({ root, allowGitSpawn = true, only, profilesRoot } = {})</code>(async)</li>
2378
2471
  <li><code>runCoreCheck({ root, allowGitSpawn = true, profilesRoot } = {})</code>(async)</li>
2379
2472
  <li><code>isContainedDeclaration(rel)</code></li>
2380
- <li>输入:<code>--only</code> 取值 <code>contracts|drift|closure|version|docs|git|identity</code>。</li>
2473
+ <li>输入:<code>--only</code> 取值 <code>contracts|drift|closure|version|docs|git|identity|boundary|platform</code>。</li>
2381
2474
  <li>输出:发现清单;退出码 <code>findings=1</code>(有发现)、<code>mechanism=2</code>(某类检查无法完成)、<code>ok=0</code>。</li>
2382
2475
  <li>纯函数:否(读取目标文件与只读 Git 状态);但<strong>只诊断、不修复、不写</strong>。</li>
2383
2476
  <li>副作用:无文件写入;只读 Git 探测(至多一次冻结 <code>status</code> 查询)。</li>
2384
- <li>稳定错误码与 <code>details.kind</code>:<code>CHECK_CLASSES</code> 为七类闭集,不扩张;机制失败抛 <code>KitError</code>(<code>mechanism</code> 类)。</li>
2477
+ <li>稳定错误码与 <code>details.kind</code>:<code>CHECK_CLASSES</code> 为九类闭集,不扩张(审计整改 C2 依裁决 SG-13/14、SG-17、SFA-PLAT-002 增设 <code>boundary</code>、<code>platform</code> 两类,并为 <code>version</code> 类加装版本单源一致性事实;扩类经治理批准,此后仍不扩张);机制失败抛 <code>KitError</code>(<code>mechanism</code> 类)。</li>
2385
2478
  <li>前置条件与信任锚:<code>GIT_READ_ONLY_ALLOWLIST</code> 限定可调用子命令。</li>
2386
2479
  <li><code>since</code> / <code>stability</code>:<code>0.2.0</code> / <code>stable</code>。</li>
2387
2480
  <li>源文件:<code>packages/skill-family-engineering-kit/src/check.mjs</code>、<code>core-check.mjs</code>。</li>
@@ -2509,6 +2602,18 @@
2509
2602
  </ul>
2510
2603
  <p>Kit 错误类型:<code>KitError extends ContractsError</code>(构造未登记码立即抛 <code>TypeError</code>);<code>KIT_ERROR_KINDS</code> 为稳定 kind 枚举;<code>kitError</code> / <code>invalidParamsError</code> / <code>unknownCommandError</code> / <code>mutationModeError</code> / <code>refusalError</code> 为构造辅助。<code>REFUSED_MUTATION_FLAGS</code> 列出入口即拒的变更旗标(如 <code>--apply</code>)。</p>
2511
2604
  <hr />
2605
+ <h2 id="Profile-SPI-公共投影">Profile SPI 公共投影<a class="headerlink" href="#Profile-SPI-公共投影" title="Permanent link">&para;</a></h2>
2606
+ <p><code>skill-family-engineering-kit/profile-spi</code> 是 Profile SPI v2 的公共数据入口。它由 Profiles 源实现投影生成,包内同时携带三个 SPI JSON 资源与 Contracts 的 <code>profile-descriptor.schema.json</code>;投影脚本只替换两个公共包导入和一个本地 Schema URL,资源字节保持绑定。</p>
2607
+ <h3 id="公共入口">公共入口<a class="headerlink" href="#公共入口" title="Permanent link">&para;</a></h3>
2608
+ <ul>
2609
+ <li><code>loadSpiDefinition()</code>:读取 <code>extension-spi.json</code>,返回开放扩展点、核心所有权和 entrypoint 规则。</li>
2610
+ <li><code>loadExtendedDescriptorSchema()</code>:读取 <code>profile-descriptor.schema.json</code>,返回扩展 Profile descriptor Schema。</li>
2611
+ <li><code>loadRuleBaselineCatalog()</code>:读取 <code>rule-baseline-catalog.json</code>,返回 overrides-policy 的基线目录。</li>
2612
+ <li><code>verifyProfile({ profileRoot, descriptorRelPath = "profile.json" } = {})</code>(async):只读校验 Profile descriptor、资源收容、核心反向依赖、采用 pin 与 overrides;返回 <code>SPE0000</code> 或 <code>SPE1001</code>–<code>SPE1007</code> 结果码,不执行 Profile entrypoint。</li>
2613
+ <li><code>verifyAdoptionDigests({ profileRoot, adoption })</code> 与 <code>assessOverridesPolicy(overrides)</code>:分别校验采用 pin 摘要和只收紧的 overrides。</li>
2614
+ </ul>
2615
+ <p>公共投影入口没有文件写入、Git、网络或进程副作用。<code>profileRoot</code> 必须是可读取目录,资源 entrypoint 必须留在该目录内且为 JSON 数据文件;符号链接和路径逃逸均失败关闭。Profile 的领域语义仍由调用方拥有。</p>
2616
+ <p><code>profiles/spi</code> 是唯一手写真源;<code>packages/skill-family-engineering-kit/profile-spi</code> 由 projen 机械生成,不得直接编辑投影文件。</p>
2512
2617
  <h2 id="Quickstart-Profile-v2-candidate">Quickstart Profile v2 candidate<a class="headerlink" href="#Quickstart-Profile-v2-candidate" title="Permanent link">&para;</a></h2>
2513
2618
  <p><code>skill-family-engineering-kit/candidate/quickstart-profile</code> 导出 <code>buildQuickstartProfileProjection</code> 与 <code>QUICKSTART_PROFILE_TARGET_PREFIX</code>。builder 接收显式消费者 Schema 路径与冻结来源身份,生成按 Schema <code>$id</code> 查询的 standalone validator、机械投影的 Contracts/Harness runtime、许可证和完整 provenance。</p>
2514
2619
  <p>Bundle 离线运行时不需要 Foundation 包、<code>node_modules</code> 或 Ajv。builder 只返回稳定 projection manifest,不写目标文件,也不增加第五个 Kit 顶层命令;调用方仍需把 manifest 交给 <code>runProjection</code> 完成授权写入。0.3.0 的 v2 与 0.2.1 的依赖闭包 Bundle 不兼容,必须精确锁定版本。</p>
@@ -1079,6 +1079,28 @@
1079
1079
  </span>
1080
1080
  </a>
1081
1081
 
1082
+ </li>
1083
+
1084
+ <li class="md-nav__item">
1085
+ <a href="#estimateTokens--isCjkCodePoint--估算器常量" class="md-nav__link">
1086
+ <span class="md-ellipsis">
1087
+
1088
+ estimateTokens / isCjkCodePoint / 估算器常量
1089
+
1090
+ </span>
1091
+ </a>
1092
+
1093
+ </li>
1094
+
1095
+ <li class="md-nav__item">
1096
+ <a href="#CLIskill-family-token-estimate" class="md-nav__link">
1097
+ <span class="md-ellipsis">
1098
+
1099
+ CLI:skill-family-token-estimate
1100
+
1101
+ </span>
1102
+ </a>
1103
+
1082
1104
  </li>
1083
1105
 
1084
1106
  </ul>
@@ -2500,6 +2522,28 @@
2500
2522
  </span>
2501
2523
  </a>
2502
2524
 
2525
+ </li>
2526
+
2527
+ <li class="md-nav__item">
2528
+ <a href="#estimateTokens--isCjkCodePoint--估算器常量" class="md-nav__link">
2529
+ <span class="md-ellipsis">
2530
+
2531
+ estimateTokens / isCjkCodePoint / 估算器常量
2532
+
2533
+ </span>
2534
+ </a>
2535
+
2536
+ </li>
2537
+
2538
+ <li class="md-nav__item">
2539
+ <a href="#CLIskill-family-token-estimate" class="md-nav__link">
2540
+ <span class="md-ellipsis">
2541
+
2542
+ CLI:skill-family-token-estimate
2543
+
2544
+ </span>
2545
+ </a>
2546
+
2503
2547
  </li>
2504
2548
 
2505
2549
  </ul>
@@ -2576,7 +2620,7 @@
2576
2620
 
2577
2621
  <h1 id="skill-family-harness-node-公共-API-参考">skill-family-harness-node 公共 API 参考<a class="headerlink" href="#skill-family-harness-node-公共-API-参考" title="Permanent link">&para;</a></h1>
2578
2622
  <p>本页从真实导出(<code>src/index.mjs</code> 与各源模块)核对,不手写无法证明新鲜度的全集。每个公共入口按 hand-off §4.3 说明:签名、输入与输出、是否纯函数、文件/进程/Git/网络副作用、稳定错误码与 <code>details.kind</code>、前置条件与信任锚、<code>since</code> 与 <code>stability</code>、源文件与正例/负例测试、调用方仍拥有的业务语义。</p>
2579
- <p>Harness 是薄运行时:消费 Contracts,只实现业务中立机制;不拥有业务语义、编排、Git、网络与第二语言。包级常量:<code>HARNESS_CAPABILITIES</code>(16 项能力,闭集)、<code>HARNESS_EXCLUSIONS</code>(明确排除 <code>business-semantics</code> / <code>workflow-orchestration</code> / <code>git-writes</code> / <code>model-calls</code> / <code>release-state</code> / <code>remote-network-access</code>)。</p>
2623
+ <p>Harness 是薄运行时:消费 Contracts,只实现业务中立机制;不拥有业务语义、编排、Git、网络与第二语言。包级常量:<code>HARNESS_CAPABILITIES</code>(19 项能力,闭集)、<code>HARNESS_EXCLUSIONS</code>(明确排除 <code>business-semantics</code> / <code>workflow-orchestration</code> / <code>git-writes</code> / <code>model-calls</code> / <code>release-state</code> / <code>remote-network-access</code>)。</p>
2580
2624
  <p>能力分组(与 <code>docs/agents/capability-catalog.json</code> 对应):</p>
2581
2625
  <ul>
2582
2626
  <li><a href="#契约校验-foundationharnesscontract-validation">契约校验</a> → <code>validateContractDocument</code> / <code>getValidator</code></li>
@@ -2591,7 +2635,7 @@
2591
2635
  <li><a href="#基线物化-foundationharnessbaseline-materialization">基线物化</a> → <code>computeDirectoryDigest</code> / <code>materializeBaseline</code>(FND-ADR-009)</li>
2592
2636
  <li><a href="#只读-chokepoint-foundationharnessread-chokepoint">只读 chokepoint</a> → <code>createReadChokepoint</code>(FND-ADR-009)</li>
2593
2637
  <li><a href="#策略化表面扫描-foundationharnesssurface-scan">策略化表面扫描</a> → <code>scanSurface</code>(FND-ADR-009)</li>
2594
- <li><a href="#token-上界估算-foundationharnesstoken-estimation">token 上界估算</a> → <code>estimateTokenUpperBound</code>(FND-ADR-009)</li>
2638
+ <li><a href="#token-上界估算-foundationharnesstoken-estimation">token 上界估算</a> → <code>estimateTokenUpperBound</code> / <code>estimateTokens</code>(FND-ADR-009)</li>
2595
2639
  <li><a href="#通用上限守卫-foundationharnessupper-bound-guard">通用上限守卫</a> → <code>openUsageGuard</code> / <code>appendUsageEvent</code> / <code>readUsage</code> / <code>closeUsageGuard</code>(FND-ADR-009)</li>
2596
2640
  <li><a href="#机制错误-foundationharnesserrors">机制错误</a> → <code>HarnessError</code> / <code>mechanismError</code> / <code>HARNESS_ERROR_KINDS</code></li>
2597
2641
  </ul>
@@ -2924,7 +2968,7 @@
2924
2968
  <p>注入式自测约定:扫描器无状态——注入模式并扫描后移除注入,再次扫描结果字节一致(自测见测试文件,不冒充独立复核)。</p>
2925
2969
  <hr />
2926
2970
  <h2 id="token-上界估算-foundationharnesstoken-estimation">token 上界估算 (foundation.harness.token-estimation)<a class="headerlink" href="#token-上界估算-foundationharnesstoken-estimation" title="Permanent link">&para;</a></h2>
2927
- <p>FND-ADR-009。确定性领域估算原语:UTF-8 字节数纯函数,无模型、无网络、无 tokenizer 依赖、无持久状态导入;结果符合 <code>token-estimate-result</code> 契约(无时间戳,<code>guarantees</code> 为封闭枚举)。</p>
2971
+ <p>FND-ADR-009。确定性领域估算原语,两个互相独立的估算器:UTF-8 字节数上界(<code>estimateTokenUpperBound</code>)与按 CJK 码位/空白切分的词元数估算(<code>estimateTokens</code>,算法 <code>cjk-char-whitespace-split</code>)。两者均为无模型、无网络、无 tokenizer 依赖、无持久状态导入的纯函数;字节上界结果符合 <code>token-estimate-result</code> 契约(无时间戳,<code>guarantees</code> 为封闭枚举)。每条词元估算记录携带估算器 id 与版本(SFA-CONTEXT-028:消费方必须能回答结果出自哪个估算器),两个估算器的结果不得静默混用、不得互相替代。</p>
2928
2972
  <h3 id="estimateTokenUpperBound">estimateTokenUpperBound<a class="headerlink" href="#estimateTokenUpperBound" title="Permanent link">&para;</a></h3>
2929
2973
  <ul>
2930
2974
  <li>签名:<code>estimateTokenUpperBound(text)</code>(纯函数)</li>
@@ -2939,6 +2983,42 @@
2939
2983
  <li>正例/负例测试:<code>packages/skill-family-harness-node/test/token-estimate.test.mjs</code>。</li>
2940
2984
  <li>调用方仍拥有的业务语义:估算结果的解释与消费侧换算(模型调用与真实 token 计数不在 Foundation)。</li>
2941
2985
  </ul>
2986
+ <h3 id="estimateTokens--isCjkCodePoint--估算器常量">estimateTokens / isCjkCodePoint / 估算器常量<a class="headerlink" href="#estimateTokens--isCjkCodePoint--估算器常量" title="Permanent link">&para;</a></h3>
2987
+ <ul>
2988
+ <li>签名:</li>
2989
+ <li><code>estimateTokens(text)</code>(纯函数)</li>
2990
+ <li><code>isCjkCodePoint(codePoint)</code>(纯函数)</li>
2991
+ <li>常量:<code>TOKEN_ESTIMATOR_ID</code>(<code>skill-family.token-estimator</code>)、<code>TOKEN_ESTIMATOR_VERSION</code>(<code>1.0.0</code>)、<code>TOKEN_ESTIMATION_ALGORITHM</code>(<code>cjk-char-whitespace-split</code>)、<code>CJK_CODE_POINT_RANGES</code>(冻结码位区间表)</li>
2992
+ <li>输入:文本字符串;<code>isCjkCodePoint</code> 接收整数码位。</li>
2993
+ <li>输出:冻结的词元估算记录(<code>kind: skill-family.token-estimate-record</code>,<code>schemaVersion: 1</code>),携带 <code>estimator.id</code> / <code>estimator.version</code> / <code>algorithm</code>、输入统计(<code>codePoints</code> / <code>inputBytes</code>)、切分统计(<code>cjkCharacters</code> / <code>whitespaceSeparators</code> / <code>otherRuns</code>)与 <code>tokens</code>;<code>unit</code> 为 <code>tokens</code>,<code>precision</code> 为 <code>deterministic-heuristic</code>,<code>scope</code> 为 <code>content-text-only</code>。</li>
2994
+ <li>算法(<code>cjk-char-whitespace-split</code>,逐码位单遍扫描):</li>
2995
+ <li>CJK 码位区间(冻结):U+3400–U+4DBF(扩展 A)、U+4E00–U+9FFF(统一表意文字)、U+F900–U+FAFF(兼容表意文字)、U+20000–U+3134F(扩展 B–G)。</li>
2996
+ <li>每个 CJK 码位计 1 词元,并立即终结其前尚未闭合的 OTHER 段。</li>
2997
+ <li>连续的非 CJK、非空白码位构成 OTHER 段,被空白或 CJK 码位分隔时每段计 1 词元。</li>
2998
+ <li>空白(ECMAScript <code>\s</code> 类)只起分隔作用,不贡献词元。</li>
2999
+ <li>恒等式:<code>tokens === cjkCharacters + otherRuns</code>;中英混排、纯 CJK、纯 ASCII、空串(0 词元)全部适用。</li>
3000
+ <li>纯函数:是;零依赖、零 import(模块纯度由测试复检)。</li>
3001
+ <li>副作用:无。</li>
3002
+ <li>稳定错误码与 <code>details.kind</code>:非字符串输入抛 <code>TypeError</code>(无 SFC 码)。</li>
3003
+ <li>前置条件与信任锚:估算是对目标 tokenizer 的确定性启发式近似,不承诺与任何具体模型 tokenizer 相等;比较阈值时同一批次必须使用同一估算器(记录内的 <code>estimator</code> 与 <code>algorithm</code> 即裁决依据)。</li>
3004
+ <li><code>since</code> / <code>stability</code>:<code>0.6.0</code> / <code>stable</code>。</li>
3005
+ <li>源文件:<code>packages/skill-family-harness-node/src/token-estimate.mjs</code>。</li>
3006
+ <li>正例/负例测试:<code>packages/skill-family-harness-node/test/token-estimator.test.mjs</code>(中英混排、纯 CJK、纯 ASCII、空串与空白串、扩展 B 码位、区间边界、记录封闭键集、恒等式、确定性、CLI 子进程行为)。</li>
3007
+ <li>调用方仍拥有的业务语义:阈值策略与超限处置;把启发式词元数换算为目标模型的真实消耗。</li>
3008
+ </ul>
3009
+ <h3 id="CLIskill-family-token-estimate">CLI:skill-family-token-estimate<a class="headerlink" href="#CLIskill-family-token-estimate" title="Permanent link">&para;</a></h3>
3010
+ <ul>
3011
+ <li>入口:harness 包 bin <code>skill-family-token-estimate</code>(<code>src/token-estimate-cli.mjs</code>);与工程 Kit 的四命令互不混用。</li>
3012
+ <li>用法:<code>skill-family-token-estimate (--text &lt;s&gt; | --file &lt;p&gt; | --stdin) [--estimator tokens|upper-bound|both]</code>;默认 <code>--estimator tokens</code>。<code>both</code> 输出 <code>{ tokens, upperBound }</code> 两个键,明示两个估算器并存而非混合。</li>
3013
+ <li>输出:stdout 打印 JSON 估算记录(<code>tokens</code> 为估算记录,<code>upper-bound</code> 为 <code>token-estimate-result</code>),换行结尾。</li>
3014
+ <li>副作用:只读取命令行参数、<code>--file</code> 指定文件或 stdin;只写 stdout。</li>
3015
+ <li>稳定退出码:<code>0</code> 成功;<code>2</code> 用法错误(输入源缺失或互斥、未知参数、<code>--file</code> 目标不是普通文件等,stderr 给出原因);<code>--help</code> 打印用法后退出 0。</li>
3016
+ <li>前置条件与信任锚:<code>--file</code> 按调用方给定的路径原样读取,CLI 不做路径收容;需要收容时在库内用 <code>readFileContained</code>。</li>
3017
+ <li><code>since</code> / <code>stability</code>:<code>0.6.0</code> / <code>stable</code>。</li>
3018
+ <li>源文件:<code>packages/skill-family-harness-node/src/token-estimate-cli.mjs</code>。</li>
3019
+ <li>正例/负例测试:<code>packages/skill-family-harness-node/test/token-estimator.test.mjs</code>(子进程 CLI 用例:确定性、<code>--file</code>/<code>--stdin</code>/<code>both</code>、用法错误退出码 2、<code>--help</code>)。</li>
3020
+ <li>调用方仍拥有的业务语义:输入文本的采集与裁剪策略、输出记录的归档位置。</li>
3021
+ </ul>
2942
3022
  <hr />
2943
3023
  <h2 id="通用上限守卫-foundationharnessupper-bound-guard">通用上限守卫 (foundation.harness.upper-bound-guard)<a class="headerlink" href="#通用上限守卫-foundationharnessupper-bound-guard" title="Permanent link">&para;</a></h2>
2944
3024
  <p>FND-ADR-009。复用 state-store 事件账与 token-lock 显式占用实现通用上限守卫:越限事件失败关闭且不写入;上限值、单位类别与超限策略全部由消费者配置,模块不携带任何固定数额或定价词汇。</p>
@@ -2050,7 +2050,7 @@
2050
2050
  <td><code>SFC2004</code>(<code>target-not-empty</code>)</td>
2051
2051
  </tr>
2052
2052
  <tr>
2053
- <td><code>planAdoption</code> / <code>buildHandoffDraft</code></td>
2053
+ <td><code>planAdoption</code> / <code>buildProfileDraft</code></td>
2054
2054
  <td>是</td>
2055
2055
  <td>否</td>
2056
2056
  <td>否</td>