nccgs 2.1.1 → 3.0.0-rc.2

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 (705) hide show
  1. package/CHANGELOG.md +76 -235
  2. package/LICENSE +1 -1
  3. package/README.md +87 -206
  4. package/THIRD_PARTY_NOTICES.md +6 -34
  5. package/bin/nccgs.mjs +96 -0
  6. package/cli/doctor.mjs +82 -0
  7. package/cli/feedback.mjs +13 -0
  8. package/cli/install.mjs +111 -0
  9. package/cli/release.mjs +59 -0
  10. package/cli/run.mjs +35 -0
  11. package/cli/spawn.mjs +20 -0
  12. package/cli/uninstall.mjs +43 -0
  13. package/cli/update-check.mjs +66 -0
  14. package/docs/EVIDENCE-VERIFICATION.md +22 -0
  15. package/package.json +23 -30
  16. package/runtime/core/diag.mjs +43 -0
  17. package/runtime/core/feedback-policy.mjs +54 -0
  18. package/runtime/core/fs.mjs +80 -0
  19. package/runtime/core/job-object.mjs +73 -0
  20. package/runtime/core/modes.mjs +87 -0
  21. package/runtime/core/process-tree.mjs +109 -0
  22. package/runtime/core/project.mjs +113 -0
  23. package/runtime/core/snapshot.mjs +114 -0
  24. package/runtime/hooks/common.mjs +22 -0
  25. package/runtime/hooks/done-guard.mjs +15 -0
  26. package/runtime/hooks/guard-mcp.mjs +8 -0
  27. package/runtime/hooks/guard-shell.mjs +16 -0
  28. package/runtime/hooks/guard-write.mjs +25 -0
  29. package/runtime/hooks/session-log.mjs +7 -0
  30. package/runtime/hooks/session-start.mjs +40 -0
  31. package/runtime/hooks/unity-transport.mjs +12 -0
  32. package/runtime/modes.json +39 -0
  33. package/runtime/task/cost.mjs +103 -0
  34. package/runtime/task/criteria.mjs +128 -0
  35. package/runtime/task/feedback.mjs +136 -0
  36. package/runtime/task/ledger.mjs +109 -0
  37. package/runtime/task/plan.mjs +69 -0
  38. package/runtime/task/project.mjs +79 -0
  39. package/runtime/task/report.mjs +252 -0
  40. package/runtime/task/task.mjs +238 -0
  41. package/runtime/unity/assets.mjs +51 -0
  42. package/runtime/unity/playtest.mjs +145 -0
  43. package/runtime/unity/unity.mjs +350 -0
  44. package/scripts/check-job-object.mjs +18 -0
  45. package/scripts/sync-unity-skills.mjs +35 -119
  46. package/template/CLAUDE.md +39 -0
  47. package/template/agents/fast-fix.md +9 -0
  48. package/template/agents/implementer.md +19 -0
  49. package/template/agents/playtester.md +15 -0
  50. package/template/agents/reviewer.md +19 -0
  51. package/template/agents/scout.md +9 -0
  52. package/template/ponytail/README.md +8 -0
  53. package/{.claude/nccgs/packages → template}/ponytail/engineering.md +10 -0
  54. package/template/protocols/evidence.md +52 -0
  55. package/template/protocols/playtest.md +45 -0
  56. package/template/protocols/review.md +34 -0
  57. package/template/protocols/unity-cli-notes.md +56 -0
  58. package/template/settings.fragment.json +33 -0
  59. package/template/skills/art-bible/SKILL.md +19 -0
  60. package/template/skills/asset-spec/SKILL.md +19 -0
  61. package/template/skills/brainstorm/SKILL.md +17 -0
  62. package/template/skills/feedback/SKILL.md +16 -0
  63. package/template/skills/map-systems/SKILL.md +25 -0
  64. package/template/skills/playtest/SKILL.md +17 -0
  65. package/template/skills/status/SKILL.md +18 -0
  66. package/template/skills/test/SKILL.md +34 -0
  67. package/template/skills/unity-foundation/SKILL.md +17 -0
  68. package/template/skills/vertical-slice/SKILL.md +17 -0
  69. package/template/skills/work/SKILL.md +65 -0
  70. package/tools/feedback-worker/README.md +12 -0
  71. package/tools/feedback-worker/worker.js +39 -0
  72. package/tools/feedback-worker/wrangler.toml +12 -0
  73. package/unity-skills/2d-pixel-perfect/SKILL.md +208 -0
  74. package/unity-skills/2d-pixel-perfect/references/api-reference.md +81 -0
  75. package/unity-skills/2d-pixel-perfect/references/camera-setup-builtin.cs +40 -0
  76. package/unity-skills/2d-pixel-perfect/references/camera-setup-urp.cs +49 -0
  77. package/unity-skills/2d-pixel-perfect/references/pipeline-detection.cs +50 -0
  78. package/unity-skills/2d-pixel-perfect/references/sprite-settings.cs +37 -0
  79. package/unity-skills/asset-transformer-toolkit/SECURITY.md +15 -0
  80. package/unity-skills/asset-transformer-toolkit/SKILL.md +39 -0
  81. package/unity-skills/asset-transformer-toolkit/references/create-importer.md +121 -0
  82. package/unity-skills/asset-transformer-toolkit/references/lods.md +61 -0
  83. package/unity-skills/asset-transformer-toolkit/references/rule-api.md +154 -0
  84. package/unity-skills/asset-transformer-toolkit/references/ruleblock-api.md +37 -0
  85. package/unity-skills/asset-transformer-toolkit/references/ruleset-api.md +138 -0
  86. package/unity-skills/asset-transformer-toolkit/references/rulesets-and-actions.md +227 -0
  87. package/unity-skills/audio-setup-mixers/SECURITY.md +16 -0
  88. package/unity-skills/audio-setup-mixers/SKILL.md +127 -0
  89. package/unity-skills/audio-setup-mixers/references/api.md +162 -0
  90. package/unity-skills/build-gtk/SKILL.md +242 -0
  91. package/unity-skills/build-gtk/references/graph-api.md +324 -0
  92. package/unity-skills/build-gtk/references/pitfalls.md +86 -0
  93. package/unity-skills/build-gtk/references/runtime-and-visualization.md +196 -0
  94. package/unity-skills/build-gtk/references/state-machine-api.md +286 -0
  95. package/unity-skills/build-live-game/SKILL.md +255 -0
  96. package/{.claude/skills → unity-skills}/build-live-game/references/achievements.md +132 -154
  97. package/{.claude/skills → unity-skills}/build-live-game/references/apis.md +10 -19
  98. package/{.claude/skills → unity-skills}/build-live-game/references/authentication.md +14 -20
  99. package/{.claude/skills → unity-skills}/build-live-game/references/battlepass.md +269 -225
  100. package/unity-skills/build-live-game/references/blueprints-and-samples.md +75 -0
  101. package/unity-skills/build-live-game/references/cloud-code-cloudbehaviours.md +1111 -0
  102. package/unity-skills/build-live-game/references/cloud-code-modules.md +1276 -0
  103. package/unity-skills/build-live-game/references/cloud-code.md +58 -0
  104. package/{.claude/skills → unity-skills}/build-live-game/references/cloud-save.md +15 -25
  105. package/{.claude/skills → unity-skills}/build-live-game/references/deployment.md +33 -18
  106. package/{.claude/skills → unity-skills}/build-live-game/references/player-account.md +31 -23
  107. package/{.claude/skills → unity-skills}/build-live-game/references/tooling.md +0 -56
  108. package/unity-skills/build-live-game/references/ugs-cli.md +86 -0
  109. package/unity-skills/craft-game-floors/SECURITY.md +23 -0
  110. package/unity-skills/craft-game-floors/SKILL.md +134 -0
  111. package/unity-skills/craft-game-floors/references/art-direction.md +85 -0
  112. package/unity-skills/craft-game-floors/references/camera-rigs.md +51 -0
  113. package/unity-skills/craft-game-floors/references/character-motion.md +35 -0
  114. package/unity-skills/craft-game-floors/references/game-audio.md +47 -0
  115. package/unity-skills/craft-game-floors/references/game-feel.md +68 -0
  116. package/unity-skills/craft-game-floors/references/game-shell.md +45 -0
  117. package/unity-skills/craft-game-floors/references/live-floor.md +35 -0
  118. package/unity-skills/craft-game-floors/references/placeholder-assets.md +35 -0
  119. package/unity-skills/craft-game-floors/references/scene-lighting.md +52 -0
  120. package/unity-skills/craft-game-floors/references/toon-shading.md +34 -0
  121. package/unity-skills/craft-game-floors/references/vfx.md +40 -0
  122. package/unity-skills/craft-game-floors/references/visual-scorecard.md +43 -0
  123. package/unity-skills/create-2d-physics/SECURITY.md +16 -0
  124. package/unity-skills/create-2d-physics/SKILL.md +128 -0
  125. package/unity-skills/create-2d-physics/references/2d-physics-core.md +155 -0
  126. package/unity-skills/create-2d-physics/references/legacy-2d-physics.md +45 -0
  127. package/unity-skills/create-tile-palette-or-rule-tiles/SKILL.md +12 -0
  128. package/unity-skills/create-tile-palette-or-rule-tiles/references/hexagonalruletile.md +71 -0
  129. package/unity-skills/create-tile-palette-or-rule-tiles/references/palette-create.md +38 -0
  130. package/unity-skills/create-tile-palette-or-rule-tiles/references/ruletile-createempty.md +35 -0
  131. package/unity-skills/create-tile-palette-or-rule-tiles/references/ruletile-createfromsegment.md +212 -0
  132. package/unity-skills/create-tile-palette-or-rule-tiles/references/ruletile.md +90 -0
  133. package/unity-skills/create-tile-palette-or-rule-tiles/scripts/CreatePaletteTemplate.cs +148 -0
  134. package/unity-skills/create-tile-palette-or-rule-tiles/scripts/ManualWorkflowExample.cs +63 -0
  135. package/unity-skills/create-tile-palette-or-rule-tiles/scripts/RuleTileGenerator.cs +61 -0
  136. package/unity-skills/create-tile-palette-or-rule-tiles/scripts/TilemapRuleTileCreateFromSegment.cs +225 -0
  137. package/unity-skills/generate-editor-search-query/SECURITY.md +17 -0
  138. package/unity-skills/generate-editor-search-query/SKILL.md +117 -0
  139. package/unity-skills/generate-editor-search-query/references/open-search-window.md +70 -0
  140. package/unity-skills/generate-editor-search-query/references/query-patterns.md +124 -0
  141. package/{.claude/skills → unity-skills}/implement-in-app-purchases/SKILL.md +1 -2
  142. package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/api-notes.md +25 -28
  143. package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/path-convert-native-google-billing.md +1 -1
  144. package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/path-implement-iap-d2c.md +40 -5
  145. package/{.claude/skills → unity-skills}/initialize-ai-navigation/SKILL.md +4 -4
  146. package/{.claude/skills → unity-skills}/initialize-ai-navigation/references/navigation-system.md +3 -3
  147. package/{.claude/skills → unity-skills}/levelplay-unity-integration/CHANGELOG.md +12 -0
  148. package/{.claude/skills → unity-skills}/levelplay-unity-integration/README.md +9 -5
  149. package/unity-skills/levelplay-unity-integration/SKILL.md +442 -0
  150. package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/banner-api.md +15 -8
  151. package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/best-practices.md +604 -536
  152. package/unity-skills/levelplay-unity-integration/references/dependency-resolution.md +94 -0
  153. package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/ilrd-api.md +2 -2
  154. package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/initialization-api.md +221 -0
  155. package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/interstitial-api.md +11 -3
  156. package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/ios-setup.md +6 -34
  157. package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/migration-sdk-9.md +1 -1
  158. package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/privacy-settings.md +14 -29
  159. package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/rewarded-api.md +20 -4
  160. package/unity-skills/levelplay-unity-integration/references/testing-and-validation.md +222 -0
  161. package/unity-skills/levelplay-unity-integration/references/troubleshooting.md +99 -0
  162. package/unity-skills/localization/SKILL.md +347 -0
  163. package/{.claude/skills → unity-skills}/localization/references/api-notes.md +4 -0
  164. package/unity-skills/localization/resources/L10nBatchProcessor.cs +191 -0
  165. package/unity-skills/manage-sprite-atlas/SKILL.md +351 -0
  166. package/unity-skills/manage-sprite-atlas/references/addressables-delivery.md +58 -0
  167. package/unity-skills/manage-sprite-atlas/references/api.md +382 -0
  168. package/unity-skills/manage-sprite-atlas/references/best-practices.md +183 -0
  169. package/unity-skills/manage-sprite-atlas/references/common-errors.md +123 -0
  170. package/unity-skills/manage-sprite-atlas/references/custom-packing.md +147 -0
  171. package/unity-skills/manage-sprite-atlas/references/manual-authoring.md +39 -0
  172. package/unity-skills/manage-sprite-atlas/resources/authoringvsruntime.cs +176 -0
  173. package/unity-skills/manage-sprite-atlas/resources/buildaddressablespostprocess.cs +59 -0
  174. package/unity-skills/manage-sprite-atlas/resources/cacheloadedatlases.cs +145 -0
  175. package/unity-skills/manage-sprite-atlas/resources/cleanupbatchoperations.cs +119 -0
  176. package/unity-skills/manage-sprite-atlas/resources/createandconfiguremasteratlas.cs +57 -0
  177. package/unity-skills/manage-sprite-atlas/resources/custompackersetup.cs +88 -0
  178. package/unity-skills/manage-sprite-atlas/resources/deprecatedmethods.cs +142 -0
  179. package/unity-skills/manage-sprite-atlas/resources/dontmodifywithoutsaving.cs +120 -0
  180. package/unity-skills/manage-sprite-atlas/resources/dontpackinruntimebuilds.cs +190 -0
  181. package/unity-skills/manage-sprite-atlas/resources/dontscriptspriteatlasineditor.cs +114 -0
  182. package/unity-skills/manage-sprite-atlas/resources/editorconfiguration.cs +95 -0
  183. package/unity-skills/manage-sprite-atlas/resources/enablespritepacking.cs +172 -0
  184. package/unity-skills/manage-sprite-atlas/resources/gridspritepacker.cs +50 -0
  185. package/unity-skills/manage-sprite-atlas/resources/handlelatebinding.cs +147 -0
  186. package/unity-skills/manage-sprite-atlas/resources/handlenullcases.cs +141 -0
  187. package/unity-skills/manage-sprite-atlas/resources/migratev1tov2.cs +335 -0
  188. package/unity-skills/manage-sprite-atlas/resources/multipagepacker.cs +80 -0
  189. package/unity-skills/manage-sprite-atlas/resources/optimizetexturesettings.cs +191 -0
  190. package/unity-skills/manage-sprite-atlas/resources/packerdebugging.cs +158 -0
  191. package/unity-skills/manage-sprite-atlas/resources/packtransform.cs +51 -0
  192. package/unity-skills/manage-sprite-atlas/resources/platformnames.cs +127 -0
  193. package/unity-skills/manage-sprite-atlas/resources/queryspritesefficiently.cs +222 -0
  194. package/unity-skills/manage-sprite-atlas/resources/registercallbacks.cs +152 -0
  195. package/unity-skills/manage-sprite-atlas/resources/runtimeatlasloader.cs +15 -0
  196. package/unity-skills/manage-sprite-atlas/resources/runtimespriteaccess.cs +19 -0
  197. package/unity-skills/manage-sprite-atlas/resources/savespriteatlasasset.cs +107 -0
  198. package/unity-skills/manage-sprite-atlas/resources/scriptablepacker.cs +81 -0
  199. package/unity-skills/manage-sprite-atlas/resources/setincludeinbuild.cs +164 -0
  200. package/unity-skills/manage-sprite-atlas/resources/sizeoptimizedpacker.cs +88 -0
  201. package/unity-skills/manage-sprite-atlas/resources/spriteatlaslatebinding.cs +123 -0
  202. package/unity-skills/manage-sprite-atlas/resources/spriteatlasprebuildgenerator.cs +219 -0
  203. package/unity-skills/manage-sprite-atlas/resources/spritedata.cs +35 -0
  204. package/unity-skills/manage-sprite-atlas/resources/spritepack.cs +39 -0
  205. package/unity-skills/manage-sprite-atlas/resources/texturedata.cs +15 -0
  206. package/unity-skills/manage-sprite-atlas/resources/updatebuildscripts.cs +357 -0
  207. package/unity-skills/manage-sprite-atlas/resources/updatesettingsconfiguration.cs +135 -0
  208. package/unity-skills/manage-sprite-atlas/resources/usevariantswisely.cs +179 -0
  209. package/unity-skills/manage-sprite-atlas/resources/variantatlas.cs +39 -0
  210. package/unity-skills/manifest.json +1155 -0
  211. package/unity-skills/migrate-birp-to-urp/SECURITY.md +16 -0
  212. package/unity-skills/migrate-birp-to-urp/SKILL.md +543 -0
  213. package/unity-skills/migrate-birp-to-urp/references/capturing-the-editor.md +66 -0
  214. package/unity-skills/migrate-birp-to-urp/references/complex-shader-situations.md +272 -0
  215. package/unity-skills/migrate-birp-to-urp/references/custom-shader-triage.md +123 -0
  216. package/unity-skills/migrate-birp-to-urp/references/implementation-patterns.md +529 -0
  217. package/unity-skills/migrate-birp-to-urp/references/migration-workflow.md +265 -0
  218. package/unity-skills/migrate-birp-to-urp/references/quality-settings-map.md +69 -0
  219. package/unity-skills/new-unity-project/SECURITY.md +26 -0
  220. package/unity-skills/new-unity-project/SKILL.md +386 -0
  221. package/unity-skills/new-unity-project/references/skill-setup.md +66 -0
  222. package/unity-skills/optimize-audio/SECURITY.md +16 -0
  223. package/{.claude/skills → unity-skills}/optimize-audio/SKILL.md +17 -17
  224. package/{.claude/skills → unity-skills}/optimize-audio/resources/audio-import-api.md +8 -5
  225. package/{.claude/skills → unity-skills}/optimize-text-mesh-pro/SKILL.md +1 -11
  226. package/unity-skills/optimize-web/SECURITY.md +16 -0
  227. package/{.claude/skills → unity-skills}/optimize-web/SKILL.md +164 -27
  228. package/unity-skills/optimize-web/scripts/WebOptimizer.cs +46 -0
  229. package/unity-skills/optimize-web/scripts/toktx-examples.sh +11 -0
  230. package/{.claude/skills → unity-skills}/physics-3d-collision/SKILL.md +2 -2
  231. package/unity-skills/physics-3d-collision/references/troubleshooting.md +8 -0
  232. package/unity-skills/project-auditor-fixes/SKILL.md +64 -0
  233. package/{.claude/skills → unity-skills}/setup-multiplayer-services/SKILL.md +1 -4
  234. package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/SKILL.md +1 -1
  235. package/{.claude/skills → unity-skills}/shader-graph-create-custom-node/SKILL.md +1 -1
  236. package/unity-skills/sprite-editor/SECURITY.md +16 -0
  237. package/{.claude/skills → unity-skills}/sprite-editor/SKILL.md +9 -9
  238. package/{.claude/skills → unity-skills}/sprite-editor/references/templates.md +1 -1
  239. package/unity-skills/sprite-segment-3x3grid/SKILL.md +136 -0
  240. package/unity-skills/sprite-segment-3x3grid/scripts/SpriteGridAnalysis.cs +119 -0
  241. package/{.claude/skills → unity-skills}/ui/SKILL.md +1 -1
  242. package/{.claude/skills → unity-skills}/ui-imgui/SKILL.md +1 -7
  243. package/{.claude/skills → unity-skills}/ui-ugui/SKILL.md +3 -9
  244. package/{.claude/skills → unity-skills}/ui-uitk/SKILL.md +8 -14
  245. package/{.claude/skills → unity-skills}/ui-uitk/references/custom-elements.md +1 -1
  246. package/unity-skills/unity-cli/CHANGELOG.md +515 -0
  247. package/unity-skills/unity-cli/SECURITY.md +68 -0
  248. package/unity-skills/unity-cli/SKILL.md +723 -0
  249. package/unity-skills/unity-cli/references/auth-license-cloud.md +318 -0
  250. package/unity-skills/unity-cli/references/build-run-test.md +555 -0
  251. package/unity-skills/unity-cli/references/cloud-automation.md +736 -0
  252. package/{.claude/skills → unity-skills}/unity-cli/references/collaboration.md +166 -105
  253. package/unity-skills/unity-cli/references/config-hub.md +239 -0
  254. package/unity-skills/unity-cli/references/diagnostics-maintenance.md +720 -0
  255. package/unity-skills/unity-cli/references/docs-workflow.md +179 -0
  256. package/unity-skills/unity-cli/references/editors-install.md +476 -0
  257. package/unity-skills/unity-cli/references/integration-advanced.md +1130 -0
  258. package/unity-skills/unity-cli/references/playmode-verification-loop.md +279 -0
  259. package/unity-skills/unity-cli/references/projects-templates.md +996 -0
  260. package/unity-skills/unity-cli/references/version-control.md +612 -0
  261. package/{.claude/skills → unity-skills}/unity-package-management/SKILL.md +60 -12
  262. package/{.claude/skills → unity-skills}/unity-package-management/references/select-packages.md +39 -21
  263. package/unity-skills/unity-pipeline/SECURITY.md +17 -0
  264. package/unity-skills/unity-pipeline/SKILL.md +335 -0
  265. package/unity-skills/urp-postprocessing/SECURITY.md +16 -0
  266. package/{.claude/skills → unity-skills}/urp-postprocessing/SKILL.md +12 -12
  267. package/{.claude/skills → unity-skills}/urp-postprocessing/references/code-templates.md +39 -8
  268. package/{.claude/skills → unity-skills}/validate-urp-render-graph-renderer-feature/SKILL.md +1 -1
  269. package/.claude/agents/nccgs-adversarial-reviewer.md +0 -43
  270. package/.claude/agents/nccgs-engine-programmer.md +0 -27
  271. package/.claude/agents/nccgs-fast-implementer.md +0 -30
  272. package/.claude/agents/nccgs-game-designer.md +0 -26
  273. package/.claude/agents/nccgs-gameplay-programmer.md +0 -26
  274. package/.claude/agents/nccgs-qa-engineer.md +0 -27
  275. package/.claude/agents/nccgs-task-scout.md +0 -24
  276. package/.claude/agents/nccgs-ui-programmer.md +0 -27
  277. package/.claude/agents/nccgs-unity-build-specialist.md +0 -27
  278. package/.claude/agents/nccgs-unity-implementer.md +0 -28
  279. package/.claude/agents/nccgs-unity-systems-specialist.md +0 -27
  280. package/.claude/agents/nccgs-unity-ui-specialist.md +0 -27
  281. package/.claude/agents/nccgs-verification-engineer.md +0 -27
  282. package/.claude/nccgs/MEMORY.md +0 -66
  283. package/.claude/nccgs/THIRD_PARTY_NOTICES.md +0 -29
  284. package/.claude/nccgs/VERSION +0 -1
  285. package/.claude/nccgs/agent-library/nccgs-accessibility-specialist.md +0 -25
  286. package/.claude/nccgs/agent-library/nccgs-adversarial-reviewer.md +0 -41
  287. package/.claude/nccgs/agent-library/nccgs-ai-programmer.md +0 -25
  288. package/.claude/nccgs/agent-library/nccgs-analytics-engineer.md +0 -25
  289. package/.claude/nccgs/agent-library/nccgs-art-direction-lead.md +0 -25
  290. package/.claude/nccgs/agent-library/nccgs-audio-direction-lead.md +0 -25
  291. package/.claude/nccgs/agent-library/nccgs-creative-director.md +0 -25
  292. package/.claude/nccgs/agent-library/nccgs-documentation-manager.md +0 -25
  293. package/.claude/nccgs/agent-library/nccgs-economy-designer.md +0 -25
  294. package/.claude/nccgs/agent-library/nccgs-engine-programmer.md +0 -25
  295. package/.claude/nccgs/agent-library/nccgs-fast-implementer.md +0 -28
  296. package/.claude/nccgs/agent-library/nccgs-game-design-lead.md +0 -25
  297. package/.claude/nccgs/agent-library/nccgs-game-designer.md +0 -24
  298. package/.claude/nccgs/agent-library/nccgs-gameplay-programmer.md +0 -24
  299. package/.claude/nccgs/agent-library/nccgs-level-designer.md +0 -25
  300. package/.claude/nccgs/agent-library/nccgs-live-ops-designer.md +0 -25
  301. package/.claude/nccgs/agent-library/nccgs-localization-lead.md +0 -25
  302. package/.claude/nccgs/agent-library/nccgs-narrative-lead.md +0 -25
  303. package/.claude/nccgs/agent-library/nccgs-network-programmer.md +0 -25
  304. package/.claude/nccgs/agent-library/nccgs-performance-analyst.md +0 -25
  305. package/.claude/nccgs/agent-library/nccgs-producer.md +0 -25
  306. package/.claude/nccgs/agent-library/nccgs-production-coordinator.md +0 -22
  307. package/.claude/nccgs/agent-library/nccgs-programming-lead.md +0 -25
  308. package/.claude/nccgs/agent-library/nccgs-prototyper.md +0 -25
  309. package/.claude/nccgs/agent-library/nccgs-qa-engineer.md +0 -25
  310. package/.claude/nccgs/agent-library/nccgs-qa-lead.md +0 -25
  311. package/.claude/nccgs/agent-library/nccgs-release-engineer.md +0 -25
  312. package/.claude/nccgs/agent-library/nccgs-release-lead.md +0 -25
  313. package/.claude/nccgs/agent-library/nccgs-security-engineer.md +0 -25
  314. package/.claude/nccgs/agent-library/nccgs-sound-designer.md +0 -25
  315. package/.claude/nccgs/agent-library/nccgs-systems-designer.md +0 -25
  316. package/.claude/nccgs/agent-library/nccgs-task-scout.md +0 -22
  317. package/.claude/nccgs/agent-library/nccgs-technical-architect.md +0 -25
  318. package/.claude/nccgs/agent-library/nccgs-technical-artist.md +0 -25
  319. package/.claude/nccgs/agent-library/nccgs-technical-director.md +0 -25
  320. package/.claude/nccgs/agent-library/nccgs-tools-programmer.md +0 -25
  321. package/.claude/nccgs/agent-library/nccgs-ui-programmer.md +0 -25
  322. package/.claude/nccgs/agent-library/nccgs-unity-build-specialist.md +0 -25
  323. package/.claude/nccgs/agent-library/nccgs-unity-content-specialist.md +0 -25
  324. package/.claude/nccgs/agent-library/nccgs-unity-implementer.md +0 -26
  325. package/.claude/nccgs/agent-library/nccgs-unity-rendering-specialist.md +0 -25
  326. package/.claude/nccgs/agent-library/nccgs-unity-systems-specialist.md +0 -25
  327. package/.claude/nccgs/agent-library/nccgs-unity-ui-specialist.md +0 -25
  328. package/.claude/nccgs/agent-library/nccgs-ux-designer.md +0 -25
  329. package/.claude/nccgs/agent-library/nccgs-verification-engineer.md +0 -25
  330. package/.claude/nccgs/agent-library/nccgs-world-builder.md +0 -25
  331. package/.claude/nccgs/agent-library/nccgs-writer.md +0 -25
  332. package/.claude/nccgs/constitution.md +0 -187
  333. package/.claude/nccgs/hooks/agent-audit.mjs +0 -16
  334. package/.claude/nccgs/hooks/closure-guard.mjs +0 -59
  335. package/.claude/nccgs/hooks/common.mjs +0 -42
  336. package/.claude/nccgs/hooks/post-compact.mjs +0 -1
  337. package/.claude/nccgs/hooks/pre-compact.mjs +0 -8
  338. package/.claude/nccgs/hooks/protect-git.mjs +0 -22
  339. package/.claude/nccgs/hooks/protect-write.mjs +0 -17
  340. package/.claude/nccgs/hooks/runtime-observation.mjs +0 -11
  341. package/.claude/nccgs/hooks/session-start.mjs +0 -29
  342. package/.claude/nccgs/hooks/session-stop.mjs +0 -7
  343. package/.claude/nccgs/hooks/unity-transport-guard.mjs +0 -11
  344. package/.claude/nccgs/packages/ponytail/README.md +0 -46
  345. package/.claude/nccgs/packages/ponytail/manifest.json +0 -24
  346. package/.claude/nccgs/pipeline.json +0 -260
  347. package/.claude/nccgs/protocols/agent-contract.md +0 -101
  348. package/.claude/nccgs/protocols/astra-claude.md +0 -111
  349. package/.claude/nccgs/protocols/bounded-repair.md +0 -246
  350. package/.claude/nccgs/protocols/context-packets.md +0 -23
  351. package/.claude/nccgs/protocols/delivery-acceptance.md +0 -105
  352. package/.claude/nccgs/protocols/design-lifecycle.md +0 -139
  353. package/.claude/nccgs/protocols/editor-session-evidence.md +0 -52
  354. package/.claude/nccgs/protocols/evidence.md +0 -31
  355. package/.claude/nccgs/protocols/model-routing.md +0 -46
  356. package/.claude/nccgs/protocols/orchestration.md +0 -74
  357. package/.claude/nccgs/protocols/review-handoff.md +0 -101
  358. package/.claude/nccgs/protocols/shared-workflow-context.md +0 -33
  359. package/.claude/nccgs/protocols/standalone-gates.md +0 -329
  360. package/.claude/nccgs/protocols/standalone-pilot.md +0 -144
  361. package/.claude/nccgs/protocols/standalone.md +0 -207
  362. package/.claude/nccgs/protocols/task-autonomy.md +0 -55
  363. package/.claude/nccgs/protocols/task-gates.md +0 -144
  364. package/.claude/nccgs/protocols/task-slices.md +0 -106
  365. package/.claude/nccgs/protocols/unity-boundary.md +0 -31
  366. package/.claude/nccgs/routing.generated.md +0 -49
  367. package/.claude/nccgs/settings.fragment.json +0 -213
  368. package/.claude/nccgs/studio.json +0 -472
  369. package/.claude/nccgs/tools/approve-overrides.mjs +0 -81
  370. package/.claude/nccgs/tools/autonomy.mjs +0 -40
  371. package/.claude/nccgs/tools/command-process.mjs +0 -50
  372. package/.claude/nccgs/tools/command-tokens.mjs +0 -22
  373. package/.claude/nccgs/tools/compile-policy.mjs +0 -121
  374. package/.claude/nccgs/tools/configure-models.mjs +0 -96
  375. package/.claude/nccgs/tools/criteria.mjs +0 -121
  376. package/.claude/nccgs/tools/delivery-budget.mjs +0 -52
  377. package/.claude/nccgs/tools/design-readiness.mjs +0 -158
  378. package/.claude/nccgs/tools/editor-session-evidence.mjs +0 -66
  379. package/.claude/nccgs/tools/evidence.mjs +0 -153
  380. package/.claude/nccgs/tools/gates.mjs +0 -297
  381. package/.claude/nccgs/tools/handoff.mjs +0 -51
  382. package/.claude/nccgs/tools/hook-transport.mjs +0 -34
  383. package/.claude/nccgs/tools/inputs.mjs +0 -108
  384. package/.claude/nccgs/tools/installation-guard.mjs +0 -55
  385. package/.claude/nccgs/tools/integrity.mjs +0 -69
  386. package/.claude/nccgs/tools/lifecycle.mjs +0 -542
  387. package/.claude/nccgs/tools/native-completion.mjs +0 -30
  388. package/.claude/nccgs/tools/orchestration.mjs +0 -680
  389. package/.claude/nccgs/tools/paths.mjs +0 -60
  390. package/.claude/nccgs/tools/policy.mjs +0 -107
  391. package/.claude/nccgs/tools/process-lock.mjs +0 -74
  392. package/.claude/nccgs/tools/repair-packet.mjs +0 -106
  393. package/.claude/nccgs/tools/returned-handoff.mjs +0 -47
  394. package/.claude/nccgs/tools/review-budget.mjs +0 -171
  395. package/.claude/nccgs/tools/review-handoff.mjs +0 -66
  396. package/.claude/nccgs/tools/runtime.mjs +0 -71
  397. package/.claude/nccgs/tools/session-budget.mjs +0 -67
  398. package/.claude/nccgs/tools/shared-context-guard.mjs +0 -60
  399. package/.claude/nccgs/tools/shared-context.mjs +0 -25
  400. package/.claude/nccgs/tools/task-slices.mjs +0 -147
  401. package/.claude/nccgs/tools/task.mjs +0 -145
  402. package/.claude/nccgs/tools/tool-guard.mjs +0 -120
  403. package/.claude/nccgs/tools/unity-repair.mjs +0 -128
  404. package/.claude/nccgs/tools/unity-transport.mjs +0 -170
  405. package/.claude/nccgs/tools/verification-jobs.mjs +0 -171
  406. package/.claude/nccgs/tools/verification-worker.mjs +0 -71
  407. package/.claude/nccgs/tools/windows-compiler-server.cs +0 -163
  408. package/.claude/nccgs/tools/windows-job.cs +0 -103
  409. package/.claude/nccgs/unity-skills-manifest.json +0 -727
  410. package/.claude/nccgs/workflow-catalog.json +0 -654
  411. package/.claude/rules/nccgs-canonical-docs.md +0 -19
  412. package/.claude/rules/nccgs-editor-tools.md +0 -12
  413. package/.claude/rules/nccgs-localization.md +0 -12
  414. package/.claude/rules/nccgs-networking.md +0 -13
  415. package/.claude/rules/nccgs-performance.md +0 -14
  416. package/.claude/rules/nccgs-rendering.md +0 -16
  417. package/.claude/rules/nccgs-security.md +0 -13
  418. package/.claude/rules/nccgs-tests.md +0 -18
  419. package/.claude/rules/nccgs-ui.md +0 -14
  420. package/.claude/rules/nccgs-unity-assets.md +0 -21
  421. package/.claude/rules/nccgs-unity-code.md +0 -22
  422. package/.claude/skills/accessibility-review/SKILL.md +0 -22
  423. package/.claude/skills/accessibility-review/references/astra.md +0 -17
  424. package/.claude/skills/accessibility-review/references/legacy.md +0 -7
  425. package/.claude/skills/architecture-decision/SKILL.md +0 -22
  426. package/.claude/skills/architecture-decision/references/astra.md +0 -12
  427. package/.claude/skills/architecture-decision/references/legacy.md +0 -7
  428. package/.claude/skills/asset-audit/SKILL.md +0 -22
  429. package/.claude/skills/asset-audit/references/astra.md +0 -17
  430. package/.claude/skills/asset-audit/references/legacy.md +0 -7
  431. package/.claude/skills/audit/SKILL.md +0 -22
  432. package/.claude/skills/audit/references/astra.md +0 -17
  433. package/.claude/skills/audit/references/dimensions.md +0 -46
  434. package/.claude/skills/audit/references/legacy.md +0 -9
  435. package/.claude/skills/balance-review/SKILL.md +0 -22
  436. package/.claude/skills/balance-review/references/astra.md +0 -17
  437. package/.claude/skills/balance-review/references/legacy.md +0 -7
  438. package/.claude/skills/bug-triage/SKILL.md +0 -22
  439. package/.claude/skills/bug-triage/references/astra.md +0 -27
  440. package/.claude/skills/bug-triage/references/legacy.md +0 -7
  441. package/.claude/skills/build-live-game/SKILL.md +0 -317
  442. package/.claude/skills/build-live-game/references/cloud-code.md +0 -563
  443. package/.claude/skills/closure/SKILL.md +0 -22
  444. package/.claude/skills/closure/references/astra.md +0 -15
  445. package/.claude/skills/closure/references/legacy.md +0 -7
  446. package/.claude/skills/compatibility-review/SKILL.md +0 -22
  447. package/.claude/skills/compatibility-review/references/astra.md +0 -17
  448. package/.claude/skills/compatibility-review/references/legacy.md +0 -7
  449. package/.claude/skills/context-pack/SKILL.md +0 -22
  450. package/.claude/skills/context-pack/references/astra.md +0 -12
  451. package/.claude/skills/context-pack/references/legacy.md +0 -7
  452. package/.claude/skills/dependency-review/SKILL.md +0 -22
  453. package/.claude/skills/dependency-review/references/astra.md +0 -17
  454. package/.claude/skills/dependency-review/references/legacy.md +0 -7
  455. package/.claude/skills/design/SKILL.md +0 -24
  456. package/.claude/skills/design/references/astra.md +0 -12
  457. package/.claude/skills/design/references/legacy.md +0 -13
  458. package/.claude/skills/design-review/SKILL.md +0 -24
  459. package/.claude/skills/design-review/references/astra.md +0 -17
  460. package/.claude/skills/design-review/references/legacy.md +0 -7
  461. package/.claude/skills/evidence-review/SKILL.md +0 -22
  462. package/.claude/skills/evidence-review/references/astra.md +0 -17
  463. package/.claude/skills/evidence-review/references/legacy.md +0 -7
  464. package/.claude/skills/hotfix/SKILL.md +0 -22
  465. package/.claude/skills/hotfix/references/astra.md +0 -30
  466. package/.claude/skills/hotfix/references/legacy.md +0 -7
  467. package/.claude/skills/incident-recovery/SKILL.md +0 -22
  468. package/.claude/skills/incident-recovery/references/astra.md +0 -27
  469. package/.claude/skills/incident-recovery/references/legacy.md +0 -7
  470. package/.claude/skills/levelplay-unity-integration/SKILL.md +0 -1126
  471. package/.claude/skills/localization/SKILL.md +0 -135
  472. package/.claude/skills/localization/resources/L10nBatchProcessor.cs +0 -69
  473. package/.claude/skills/localize-game/SKILL.md +0 -22
  474. package/.claude/skills/localize-game/references/astra.md +0 -27
  475. package/.claude/skills/localize-game/references/legacy.md +0 -7
  476. package/.claude/skills/migrate-project/SKILL.md +0 -22
  477. package/.claude/skills/migrate-project/references/astra.md +0 -30
  478. package/.claude/skills/migrate-project/references/legacy.md +0 -19
  479. package/.claude/skills/migrate-project/references/procedure.md +0 -96
  480. package/.claude/skills/milestone-review/SKILL.md +0 -22
  481. package/.claude/skills/milestone-review/references/astra.md +0 -12
  482. package/.claude/skills/milestone-review/references/legacy.md +0 -7
  483. package/.claude/skills/nccgs-code-review/SKILL.md +0 -22
  484. package/.claude/skills/nccgs-code-review/references/astra.md +0 -21
  485. package/.claude/skills/nccgs-code-review/references/legacy.md +0 -7
  486. package/.claude/skills/new-unity-project/SKILL.md +0 -179
  487. package/.claude/skills/performance-audit/SKILL.md +0 -22
  488. package/.claude/skills/performance-audit/references/astra.md +0 -17
  489. package/.claude/skills/performance-audit/references/legacy.md +0 -7
  490. package/.claude/skills/physics-3d-collision/references/troubleshooting.md +0 -41
  491. package/.claude/skills/plan-feature/SKILL.md +0 -22
  492. package/.claude/skills/plan-feature/references/astra.md +0 -12
  493. package/.claude/skills/plan-feature/references/legacy.md +0 -7
  494. package/.claude/skills/playtest/SKILL.md +0 -22
  495. package/.claude/skills/playtest/references/astra.md +0 -31
  496. package/.claude/skills/playtest/references/legacy.md +0 -7
  497. package/.claude/skills/project-stage/SKILL.md +0 -22
  498. package/.claude/skills/project-stage/references/astra.md +0 -12
  499. package/.claude/skills/project-stage/references/legacy.md +0 -7
  500. package/.claude/skills/prototype-feature/SKILL.md +0 -22
  501. package/.claude/skills/prototype-feature/references/astra.md +0 -31
  502. package/.claude/skills/prototype-feature/references/legacy.md +0 -7
  503. package/.claude/skills/qa-plan/SKILL.md +0 -22
  504. package/.claude/skills/qa-plan/references/astra.md +0 -12
  505. package/.claude/skills/qa-plan/references/legacy.md +0 -7
  506. package/.claude/skills/release/SKILL.md +0 -22
  507. package/.claude/skills/release/references/astra.md +0 -30
  508. package/.claude/skills/release/references/legacy.md +0 -11
  509. package/.claude/skills/release-readiness/SKILL.md +0 -22
  510. package/.claude/skills/release-readiness/references/astra.md +0 -17
  511. package/.claude/skills/release-readiness/references/legacy.md +0 -7
  512. package/.claude/skills/retrospective/SKILL.md +0 -22
  513. package/.claude/skills/retrospective/references/astra.md +0 -12
  514. package/.claude/skills/retrospective/references/legacy.md +0 -7
  515. package/.claude/skills/review/SKILL.md +0 -22
  516. package/.claude/skills/review/references/astra.md +0 -21
  517. package/.claude/skills/review/references/legacy.md +0 -9
  518. package/.claude/skills/security-audit/SKILL.md +0 -22
  519. package/.claude/skills/security-audit/references/astra.md +0 -17
  520. package/.claude/skills/security-audit/references/legacy.md +0 -7
  521. package/.claude/skills/sprint-plan/SKILL.md +0 -22
  522. package/.claude/skills/sprint-plan/references/astra.md +0 -12
  523. package/.claude/skills/sprint-plan/references/legacy.md +0 -7
  524. package/.claude/skills/status/SKILL.md +0 -22
  525. package/.claude/skills/status/references/astra.md +0 -19
  526. package/.claude/skills/status/references/legacy.md +0 -9
  527. package/.claude/skills/story-readiness/SKILL.md +0 -24
  528. package/.claude/skills/story-readiness/references/astra.md +0 -17
  529. package/.claude/skills/story-readiness/references/legacy.md +0 -7
  530. package/.claude/skills/test/SKILL.md +0 -22
  531. package/.claude/skills/test/references/astra.md +0 -27
  532. package/.claude/skills/test/references/legacy.md +0 -9
  533. package/.claude/skills/ui-review/SKILL.md +0 -22
  534. package/.claude/skills/ui-review/references/astra.md +0 -17
  535. package/.claude/skills/ui-review/references/legacy.md +0 -7
  536. package/.claude/skills/unity-cli/CHANGELOG.md +0 -233
  537. package/.claude/skills/unity-cli/SECURITY.md +0 -22
  538. package/.claude/skills/unity-cli/SKILL.md +0 -414
  539. package/.claude/skills/unity-cli/references/auth-license-cloud.md +0 -146
  540. package/.claude/skills/unity-cli/references/build-run-test.md +0 -349
  541. package/.claude/skills/unity-cli/references/config-hub.md +0 -103
  542. package/.claude/skills/unity-cli/references/diagnostics-maintenance.md +0 -326
  543. package/.claude/skills/unity-cli/references/editors-install.md +0 -327
  544. package/.claude/skills/unity-cli/references/integration-advanced.md +0 -472
  545. package/.claude/skills/unity-cli/references/projects-templates.md +0 -574
  546. package/.claude/skills/work/SKILL.md +0 -22
  547. package/.claude/skills/work/references/astra.md +0 -32
  548. package/.claude/skills/work/references/classification.md +0 -41
  549. package/.claude/skills/work/references/closure.md +0 -60
  550. package/.claude/skills/work/references/feature-contracts.md +0 -36
  551. package/.claude/skills/work/references/legacy.md +0 -29
  552. package/.claude/skills/work/references/verification.md +0 -26
  553. package/CLAUDE.md +0 -10
  554. package/MEMORY.md +0 -109
  555. package/UPGRADING.md +0 -130
  556. package/VERSION +0 -1
  557. package/docs/ARCHITECTURE.md +0 -131
  558. package/docs/ASSET-PRODUCTION-GRAPHIFY-PLAN.md +0 -230
  559. package/docs/BOUNDED-REPAIR.md +0 -80
  560. package/docs/EDITOR-SESSION-EVIDENCE.md +0 -52
  561. package/docs/HANDOFF-AUTOMATION.md +0 -144
  562. package/docs/HUONG-DAN-MIGRATE-VA-SU-DUNG.md +0 -117
  563. package/docs/MIGRATION-MATRIX.md +0 -23
  564. package/docs/NCCGS-1.3.md +0 -13
  565. package/docs/NCCGS-1.4.1.md +0 -149
  566. package/docs/NCCGS-1.4.md +0 -184
  567. package/docs/NCCGS-1.5-IMPLEMENTATION-PLAN.md +0 -378
  568. package/docs/NCCGS-1.5-PILOT.md +0 -130
  569. package/docs/NCCGS-1.5.md +0 -237
  570. package/docs/PHASE-1-OPERATIONS.md +0 -278
  571. package/docs/PHASE-2-OPERATIONS.md +0 -183
  572. package/docs/PROJECT-POLICY.md +0 -94
  573. package/docs/RELEASE-STATUS.md +0 -150
  574. package/docs/TASK-SLICING.md +0 -57
  575. package/docs/UNINSTALL.md +0 -134
  576. package/docs/UPGRADE-QUALIFICATION.md +0 -45
  577. package/docs/WFK17-HOOK-REPAIR.md +0 -71
  578. package/docs/WORKFLOWS.md +0 -85
  579. package/package-assets/nccgs-project.gitignore +0 -2
  580. package/package-assets/setup-vivox-voice-chat-evals.gitignore +0 -7
  581. package/scaffold/.nccgs/autonomy.json +0 -4
  582. package/scaffold/.nccgs/bugs/.gitkeep +0 -1
  583. package/scaffold/.nccgs/closures/.gitkeep +0 -1
  584. package/scaffold/.nccgs/context/.gitkeep +0 -1
  585. package/scaffold/.nccgs/decisions/.gitkeep +0 -1
  586. package/scaffold/.nccgs/evidence/.gitkeep +0 -1
  587. package/scaffold/.nccgs/execution.json +0 -10
  588. package/scaffold/.nccgs/features/.gitkeep +0 -1
  589. package/scaffold/.nccgs/gates.json +0 -7
  590. package/scaffold/.nccgs/inputs.json +0 -6
  591. package/scaffold/.nccgs/migrations/.gitkeep +0 -1
  592. package/scaffold/.nccgs/playtests/.gitkeep +0 -1
  593. package/scaffold/.nccgs/project.yaml +0 -109
  594. package/scaffold/.nccgs/requirements.yaml +0 -10
  595. package/scaffold/.nccgs/reviews/.gitkeep +0 -1
  596. package/scaffold/.nccgs/state.md +0 -40
  597. package/scaffold/.nccgs/templates/agent-handoff.md +0 -37
  598. package/scaffold/.nccgs/templates/architecture-decision.md +0 -27
  599. package/scaffold/.nccgs/templates/closure-record.md +0 -62
  600. package/scaffold/.nccgs/templates/context-packet.yaml +0 -17
  601. package/scaffold/.nccgs/templates/design-contract.json +0 -34
  602. package/scaffold/.nccgs/templates/evidence-record.md +0 -23
  603. package/scaffold/.nccgs/templates/feature-contract.md +0 -60
  604. package/scaffold/.nccgs/templates/implementation-report.md +0 -52
  605. package/scaffold/.nccgs/templates/migration-plan.md +0 -40
  606. package/scaffold/.nccgs/templates/repair-packet.json +0 -14
  607. package/scaffold/.nccgs/templates/repair-unity-code.json +0 -18
  608. package/scaffold/.nccgs/templates/repair-unity-editor.json +0 -21
  609. package/scaffold/.nccgs/templates/task-slices.json +0 -28
  610. package/scaffold/.nccgs/templates/waiver.md +0 -11
  611. package/scripts/benchmark-snapshot.mjs +0 -205
  612. package/scripts/benchmark-v15.mjs +0 -173
  613. package/scripts/cli.mjs +0 -205
  614. package/scripts/doctor.mjs +0 -261
  615. package/scripts/install.mjs +0 -530
  616. package/scripts/recover-session.mjs +0 -89
  617. package/scripts/run.mjs +0 -86
  618. package/scripts/supervise.mjs +0 -152
  619. package/scripts/uninstall.mjs +0 -292
  620. package/scripts/validate.mjs +0 -285
  621. package/scripts/work-handoff.mjs +0 -38
  622. package/tests/autonomy.test.mjs +0 -126
  623. package/tests/benchmark-v15.test.mjs +0 -65
  624. package/tests/design-readiness.test.mjs +0 -200
  625. package/tests/editor-session-evidence.test.mjs +0 -45
  626. package/tests/evidence.test.mjs +0 -186
  627. package/tests/fixtures/compiler-shutdown.cs +0 -67
  628. package/tests/fixtures/native-provider.mjs +0 -61
  629. package/tests/framework.test.mjs +0 -740
  630. package/tests/gates.test.mjs +0 -479
  631. package/tests/hook-repair.test.mjs +0 -106
  632. package/tests/lifecycle-v15.test.mjs +0 -346
  633. package/tests/native-completion-notices.test.mjs +0 -181
  634. package/tests/orchestration-v15.test.mjs +0 -596
  635. package/tests/phase1.test.mjs +0 -427
  636. package/tests/phase2.test.mjs +0 -250
  637. package/tests/policy-v15.test.mjs +0 -234
  638. package/tests/ponytail-package.test.mjs +0 -75
  639. package/tests/returned-handoff-notices.test.mjs +0 -170
  640. package/tests/review-budget.test.mjs +0 -177
  641. package/tests/runtime-v15.test.mjs +0 -1198
  642. package/tests/session-budget.test.mjs +0 -34
  643. package/tests/task-slices.test.mjs +0 -285
  644. package/tests/uninstall.test.mjs +0 -477
  645. package/tests/unity-generated.test.mjs +0 -140
  646. package/tests/unity-transport.test.mjs +0 -348
  647. /package/{.claude/nccgs/packages → template}/ponytail/LICENSE +0 -0
  648. /package/{.claude/nccgs/packages → template}/ponytail/NOTICE.md +0 -0
  649. /package/{.claude/nccgs/packages → template}/ponytail/complexity-review.md +0 -0
  650. /package/{.claude/skills → unity-skills}/build-live-game/references/remote-config.md +0 -0
  651. /package/{.claude/skills → unity-skills}/implement-in-app-purchases/README.md +0 -0
  652. /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/codeless-catalog.md +0 -0
  653. /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/convert-adapty.md +0 -0
  654. /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/convert-essentialkit.md +0 -0
  655. /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/convert-revenuecat.md +0 -0
  656. /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/convert-unipay.md +0 -0
  657. /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/migration-v4-to-v5.md +0 -0
  658. /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/path-add-iap-to-new-project.md +0 -0
  659. /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/path-convert-native-storekit.md +0 -0
  660. /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/platform-notes.md +0 -0
  661. /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/pre-check.md +0 -0
  662. /package/{.claude/skills → unity-skills}/localization/resources/LocalizedFontAsset.cs +0 -0
  663. /package/{.claude/skills → unity-skills}/optimize-audio/resources/platform-settings.md +0 -0
  664. /package/{.claude/skills → unity-skills}/optimize-web/resources/WebOptimizer.cs +0 -0
  665. /package/{.claude/skills → unity-skills}/optimize-web/resources/toktx-examples.sh +0 -0
  666. /package/{.claude/skills → unity-skills}/physics-3d-collision/resources/CollisionDebugger.cs +0 -0
  667. /package/{.claude/skills → unity-skills}/setup-multiplayer-services/references/dgs-entrypoint.md +0 -0
  668. /package/{.claude/skills → unity-skills}/setup-multiplayer-services/references/entrypoints.md +0 -0
  669. /package/{.claude/skills → unity-skills}/setup-multiplayer-services/references/examples.md +0 -0
  670. /package/{.claude/skills → unity-skills}/setup-multiplayer-services/references/implementation-fit.md +0 -0
  671. /package/{.claude/skills → unity-skills}/setup-multiplayer-services/references/underlying-services.md +0 -0
  672. /package/{.claude/skills → unity-skills}/setup-multiplayer-services/references/workflows-prerequisites.md +0 -0
  673. /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/evals/.env.example +0 -0
  674. /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/evals/README.md +0 -0
  675. /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/evals/promptfooconfig.yaml +0 -0
  676. /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/evals/tests/init-and-login.yaml +0 -0
  677. /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/evals/tests/text-chat.yaml +0 -0
  678. /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/evals/tests/voice-channels.yaml +0 -0
  679. /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/references/events-and-participants.md +0 -0
  680. /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/references/init-and-login.md +0 -0
  681. /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/references/text-chat.md +0 -0
  682. /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/references/troubleshooting.md +0 -0
  683. /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/references/voice-channels.md +0 -0
  684. /package/{.claude/skills → unity-skills}/shader-graph-create-custom-node/resources/all_hints.hlsl +0 -0
  685. /package/{.claude/skills → unity-skills}/sprite-editor/references/api_reference.md +0 -0
  686. /package/{.claude/skills → unity-skills}/sprite-editor/references/background.md +0 -0
  687. /package/{.claude/skills → unity-skills}/sprite-editor/scripts/AutomaticSliceTexture.cs +0 -0
  688. /package/{.claude/skills → unity-skills}/sprite-editor/scripts/GenerateNewSpriteRects.cs +0 -0
  689. /package/{.claude/skills → unity-skills}/sprite-editor/scripts/GetTextureSourceImageSize.cs +0 -0
  690. /package/{.claude/skills → unity-skills}/sprite-editor/scripts/GetTextureToSlice.cs +0 -0
  691. /package/{.claude/skills → unity-skills}/sprite-editor/scripts/GridSliceTexture.cs +0 -0
  692. /package/{.claude/skills → unity-skills}/sprite-editor/scripts/IsometricSliceTexture.cs +0 -0
  693. /package/{.claude/skills → unity-skills}/sprite-editor/scripts/README.md +0 -0
  694. /package/{.claude/skills → unity-skills}/sprite-editor/scripts/SetPivotExample.cs +0 -0
  695. /package/{.claude/skills → unity-skills}/sprite-editor/scripts/SpriteToPng.cs +0 -0
  696. /package/{.claude/skills → unity-skills}/ui-imgui/references/gui-elements.md +0 -0
  697. /package/{.claude/skills → unity-skills}/ui-imgui/references/templates.md +0 -0
  698. /package/{.claude/skills → unity-skills}/ui-ugui/references/scrollview-setup.md +0 -0
  699. /package/{.claude/skills → unity-skills}/ui-uitk/references/common-issues.md +0 -0
  700. /package/{.claude/skills → unity-skills}/ui-uitk/references/painter2d.md +0 -0
  701. /package/{.claude/skills → unity-skills}/ui-uitk/references/pointermanipulator-guide.md +0 -0
  702. /package/{.claude/skills → unity-skills}/ui-uitk/references/svg-icons.md +0 -0
  703. /package/{.claude/skills → unity-skills}/ui-uitk/references/ui-runtime-binding.md +0 -0
  704. /package/{.claude/skills → unity-skills}/ui-uitk/references/uss-guide.md +0 -0
  705. /package/{.claude/skills → unity-skills}/urp-postprocessing/references/effect-reference.md +0 -0
@@ -1,121 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import { json, loadPipeline } from "./policy.mjs";
5
- import { acquireInstallationLease } from "./installation-guard.mjs";
6
-
7
- export function renderAgent(template, route) {
8
- const match = template.match(/^---\r?\n([\s\S]*?)\r?\n---/);
9
- if (!match) throw new Error("Missing agent frontmatter");
10
- const lines = match[1].split(/\r?\n/).filter(line => !/^(model|effort):/.test(line));
11
- if (route.model) lines.push(`model: ${route.model}`);
12
- if (route.effort) lines.push(`effort: ${route.effort}`);
13
- return `---\n${lines.join("\n")}\n---${template.slice(match[0].length).replace(/\r\n/g, "\n")}`;
14
- }
15
- export function generated(project) {
16
- const pipeline = loadPipeline(project);
17
- const studio = json(path.join(project, ".claude/nccgs/studio.json"));
18
- const workflows = json(path.join(project, ".claude/nccgs/workflow-catalog.json"));
19
- const outputs = new Map();
20
- studio.defaultProfile = pipeline.defaultProfile;
21
- studio.modelProfiles = {};
22
- studio.effortProfiles = {};
23
- studio.sessionProfiles = {};
24
- for (const [name, profile] of Object.entries(pipeline.profiles)) {
25
- studio.modelProfiles[name] = Object.fromEntries(Object.entries(profile.models).map(([k, v]) => [k, v.model]));
26
- studio.effortProfiles[name] = Object.fromEntries(Object.entries(profile.models).map(([k, v]) => [k, v.effort]));
27
- if (profile.session) {
28
- const route = profile.models[profile.session.class];
29
- studio.sessionProfiles[name] = { model: route.model, effortLevel: route.effort };
30
- }
31
- }
32
- const primary = pipeline.profiles[pipeline.defaultProfile];
33
- for (const agent of studio.agents) {
34
- const template = fs.readFileSync(path.join(project, ".claude/nccgs/agent-library", `${agent.name}.md`), "utf8");
35
- const turns = template.match(/^maxTurns: (\d+)\r?$/m);
36
- if (turns) agent.maxTurns = Number(turns[1]);
37
- const route = primary.models[agent.modelClass];
38
- if (!route) throw new Error(`Missing route for ${agent.name}`);
39
- agent.defaultModel = route.model;
40
- agent.defaultEffort = route.effort;
41
- if (primary.activeAgents === "all" || primary.activeAgents.includes(agent.name)) {
42
- outputs.set(`.claude/agents/${agent.name}.md`, renderAgent(template, route));
43
- }
44
- }
45
- const { contract } = pipeline;
46
- const contractProfile = pipeline.profiles["astra-claude"];
47
- const standalone = pipeline.executionPolicies.standalone;
48
- const standaloneProfile = pipeline.profiles["claude-standalone"];
49
- workflows.executionContracts = { standalone, compatibility: { ...contract, runtime: "claude-code" } };
50
- workflows.profileContracts = { "claude-standalone": { ...standalone,
51
- implementationRoutes: Object.fromEntries(Object.entries(contract.taskTiers).map(([risk, tier]) =>
52
- [risk, { ...tier, ...standaloneProfile.models[tier.implementationClass] }])),
53
- reviewModel: standaloneProfile.models.review.model, reviewEffort: standaloneProfile.models.review.effort }, "astra-claude": { ...contract,
54
- implementationModel: contractProfile.models.standard.model, implementationEffort: contractProfile.models.standard.effort,
55
- implementationRoutes: Object.fromEntries(Object.entries(contract.taskTiers).map(([risk, tier]) =>
56
- [risk, { ...tier, ...contractProfile.models[tier.implementationClass] }])),
57
- reviewModel: contractProfile.models.review.model, reviewEffort: contractProfile.models.review.effort } };
58
- for (const workflow of workflows.workflows) {
59
- delete workflow.ownerByProfile;
60
- delete workflow.primaryRolesByProfile;
61
- workflow.ownerByExecution = { standalone: "Claude Code" };
62
- if (contract.astraWorkflows.includes(workflow.name)) workflow.ownerByExecution.compatibility = "Astra";
63
- if (contract.astraWorkflows.includes(workflow.name)) workflow.ownerByProfile = { "astra-claude": "Astra" };
64
- if (contract.reviewWorkflows.includes(workflow.name)) workflow.primaryRolesByProfile = { "astra-claude": [contract.reviewAgent], "claude-standalone": [contract.reviewAgent] };
65
- const relative = `.claude/skills/${workflow.name}/SKILL.md`;
66
- if (!fs.existsSync(path.join(project, relative))) continue; // Minimal policy fixtures may omit workflow files; validate checks package completeness.
67
- const wrapper = fs.readFileSync(path.join(project, relative), "utf8").replace(/\r\n/g, "\n");
68
- const frontmatter = wrapper.match(/^---\n[\s\S]*?\n---/);
69
- const heading = wrapper.match(/^# .+$/m);
70
- if (!frontmatter || !heading) throw new Error(`Invalid workflow wrapper: ${relative}`);
71
- const designRoute = ["design", "design-review", "story-readiness"].includes(workflow.name)
72
- ? " Also load the [standalone design lifecycle](../../nccgs/protocols/design-lifecycle.md)\n and follow its specific procedure for this workflow.\n" : "";
73
- outputs.set(relative, `${frontmatter[0]}\n\n${heading[0]}\n\nResolve execution policy from .nccgs/execution.json before model routing. Missing\nexecution.json means compatibility; model profile alone never removes obligations.\n\n- standalone: load the [shared standalone procedure](../../nccgs/protocols/standalone.md)\n for this workflow, using its intake, mode, bounded domain steps and report rules.\n${designRoute} Do not load the compatibility branches or inherit their external approval chain.\n- compatibility: read models.profile from .nccgs/project.yaml and load exactly one:\n astra-claude uses [Astra/Claude procedure](references/astra.md); quality, balanced\n or inherit uses [Legacy procedure](references/legacy.md). Existing task records\n retain their original gates even after project execution policy changes.\n\nUnknown execution policies or model profiles are configuration errors. External\nreview in standalone is off, advisory or required according to execution policy;\nconfigured routes do not prove actual provider model or effort.\n`);
74
- }
75
- outputs.set(".claude/nccgs/studio.json", `${JSON.stringify(studio, null, 2)}\n`);
76
- outputs.set(".claude/nccgs/workflow-catalog.json", `${JSON.stringify(workflows, null, 2)}\n`);
77
- const tierRows = Object.entries(contract.taskTiers).map(([risk, tier]) => {
78
- const route = standaloneProfile.models[tier.implementationClass];
79
- return `| ${risk} implementation | ${route.model} | ${route.effort} | ${tier.maxReviewRounds} |`;
80
- }).join("\n");
81
- const activeCount = primary.activeAgents === "all" ? studio.agents.length : primary.activeAgents.length;
82
- const legacyRows = Object.entries(contract.taskTiers).map(([risk, tier]) => {
83
- const route = contractProfile.models[tier.implementationClass];
84
- return `| ${risk} | ${route.model} | ${route.effort} |`;
85
- }).join("\n");
86
- outputs.set(".claude/nccgs/routing.generated.md", `# Generated routing — edit pipeline.json, then compile-policy.mjs\n\nNCCGS runs in Claude Code. New installations use standalone execution; model aliases describe requested routes, not observed provider versions. Model selection in project.yaml and execution obligations in execution.json are separate policies.\n\n| Stage | Owner/model | Effort | Maximum review rounds |\n|---|---|---|---|\n| Intake, plan and documents | Claude Code | Routed by task | — |\n${tierRows}\n| Independent review | ${standaloneProfile.models.review.model} | ${standaloneProfile.models.review.effort} | Shared task budget |\n| External review | Off by default; advisory or required when configured | External evidence | — |\n| Acceptance | Contract-defined Product Owner decision | Explicit when required | — |\n\nFAST: nccgs-fast-implementer. STANDARD: the relevant domain programmer. CONTROLLED: nccgs-unity-implementer with the affected specialists. Use nccgs-task-scout only for a bounded missing fact; it does not replace review.\n\nA task-wide review budget survives implementation retries and continuation. Exhaustion stops the loop; a reasoned extension is required. Report is available for blocked/partial work and is not approval. Missing runtime effort remains unknown unless supplied by observed evidence.\n\nExisting installations without execution.json retain compatibility execution: Astra plan/document ownership, required external check and Product Owner acceptance. Legacy astra-claude routes remain unchanged:\n\n| Risk | Model | Effort |\n|---|---|---|\n${legacyRows}\n\nLegacy independent review: ${contractProfile.models.review.model}/${contractProfile.models.review.effort}. Updating never converts historical approval into a current approval. Explicit migration preserves tasks and consumed budgets.\n\nDefault active agents: ${activeCount}. Full library: ${studio.agents.length}.\n`);
87
- const nativeRows = studio.agents.filter(agent => primary.activeAgents === "all" || primary.activeAgents.includes(agent.name))
88
- .map(agent => `| ${agent.name} | ${agent.maxTurns ?? "Unspecified"} |`).join("\n");
89
- const routingPath = ".claude/nccgs/routing.generated.md";
90
- outputs.set(routingPath, outputs.get(routingPath) + `\n## Configured native turn ceilings\n\nGenerated from agent-library frontmatter by compile-policy.mjs. These are ceilings, not targets or observed session settings. Verify the installed role and any native session override before dispatch; prompt text cannot increase maxTurns.\n\n| Default active role | maxTurns |\n|---|---:|\n${nativeRows}\n`);
91
- const scaffold = path.join(project, "scaffold/.nccgs/project.yaml");
92
- if (fs.existsSync(scaffold)) {
93
- const text = fs.readFileSync(scaffold, "utf8");
94
- const start = text.indexOf("# Apply only when models.profile");
95
- const end = text.indexOf("\nworkflow:", start);
96
- const reference = "# Profile contracts are resolved from this canonical configuration.\npipeline_policy: .claude/nccgs/pipeline.json\n";
97
- outputs.set("scaffold/.nccgs/project.yaml", start >= 0 && end > start ? text.slice(0, start) + reference + text.slice(end) : text);
98
- }
99
- return outputs;
100
- }
101
- export function compile(project, write = false) {
102
- const lease = write ? acquireInstallationLease(project, "nccgs-policy") : null;
103
- try {
104
- const differences = [];
105
- for (const [relative, content] of generated(project)) {
106
- const file = path.join(project, relative);
107
- if (fs.existsSync(file) && fs.readFileSync(file, "utf8").replace(/\r\n/g, "\n") === content.replace(/\r\n/g, "\n")) continue;
108
- differences.push(relative);
109
- if (write) { fs.mkdirSync(path.dirname(file), { recursive: true }); fs.writeFileSync(file, content, "utf8"); }
110
- }
111
- return differences;
112
- } finally { lease?.release(); }
113
- }
114
- if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
115
- const project = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../..");
116
- const write = process.argv.includes("--write");
117
- const differences = compile(project, write);
118
- console.log(`${write ? "Generated" : "Stale generated files"}: ${differences.length}`);
119
- for (const file of differences) console.log(file);
120
- if (!write && differences.length) process.exitCode = 1;
121
- }
@@ -1,96 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import { atomicJson, hash, json, profilePolicy, contained, resolveExecution } from "./policy.mjs";
5
- import { renderAgent } from "./compile-policy.mjs";
6
- import { fingerprintFile } from "./integrity.mjs";
7
- import { acquireInstallationLease } from "./installation-guard.mjs";
8
-
9
- const args = process.argv.slice(2);
10
- const values = flag => args.flatMap((arg, index) => {
11
- if (arg !== flag) return [];
12
- if (!args[index + 1] || args[index + 1].startsWith("--")) throw new Error(`${flag} requires a value`);
13
- return [args[index + 1]];
14
- });
15
- const project = path.resolve(values("--project")[0] || path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../.."));
16
- const lease = acquireInstallationLease(project, "nccgs-agents");
17
- try {
18
- const explicit = values("--profile")[0];
19
- const { name, profile, pipeline } = profilePolicy(project, explicit);
20
- // Profile changes never change the execution policy or pending task obligations.
21
- resolveExecution(project);
22
- const studio = json(path.join(project, ".claude/nccgs/studio.json"));
23
- const skip = new Set(values("--skip-path").map(p => p.replaceAll("\\", "/")));
24
- const activationFile = contained(project, ".nccgs/agent-activation.json");
25
- const previous = fs.existsSync(activationFile) ? json(activationFile) : { enabled: [], generated: {} };
26
- const extras = new Set(previous.enabled);
27
- for (const role of values("--enable")) {
28
- if (!studio.agents.some(a => a.name === role)) throw new Error(`Unknown agent: ${role}`);
29
- extras.add(role);
30
- }
31
- for (const role of values("--disable")) {
32
- if (pipeline.coreAgents.includes(role)) throw new Error(`Cannot disable core agent: ${role}`);
33
- extras.delete(role);
34
- }
35
- const active = new Set(profile.activeAgents === "all" ? studio.agents.map(a => a.name) : [...profile.activeAgents, ...extras]);
36
- const settingsFile = contained(project, ".claude/settings.json");
37
- const oldSettings = fs.existsSync(settingsFile) ? fs.readFileSync(settingsFile, "utf8") : "";
38
- const settings = oldSettings ? JSON.parse(oldSettings) : {};
39
- if (!settings || typeof settings !== "object" || Array.isArray(settings)) throw new Error("Claude settings must be an object");
40
- const policyFile = contained(project, ".nccgs/project.yaml");
41
- const oldPolicy = fs.existsSync(policyFile) ? fs.readFileSync(policyFile, "utf8") : "";
42
- const policyPattern = /(^models:[ \t]*\r?\n(?:[ \t]+[^\n]*\n)*?[ \t]+profile:[ \t]*)[^#\r\n]+/m;
43
- const legacyPolicy = /^schema_version:\s*1\s*$/m.test(oldPolicy);
44
- if (explicit && !policyPattern.test(oldPolicy) && !legacyPolicy) throw new Error("Project policy must declare models.profile before reconfiguration");
45
- const writes = [], removes = [], warnings = [], generated = {}, generatedCanonical = {};
46
- for (const agent of studio.agents) {
47
- const relative = `.claude/agents/${agent.name}.md`;
48
- const file = contained(project, relative);
49
- const old = fs.existsSync(file) ? fs.readFileSync(file, "utf8") : null;
50
- if (skip.has(relative)) { warnings.push(`Preserved override: ${relative}`); continue; }
51
- const template = fs.readFileSync(contained(project, `.claude/nccgs/agent-library/${agent.name}.md`), "utf8");
52
- const route = profile.models[agent.modelClass];
53
- if (!route) throw new Error(`Missing class: ${agent.modelClass}`);
54
- const next = renderAgent(template, route);
55
- const shipped = renderAgent(template, pipeline.profiles[pipeline.defaultProfile].models[agent.modelClass]);
56
- const known = old === null || old.replace(/\r\n/g, "\n") === shipped || hash(old) === previous.generated?.[relative] || hash(old.replace(/\r\n/g, "\n")) === previous.generatedCanonical?.[relative];
57
- if (!known) { warnings.push(`Preserved modified agent: ${relative}`); continue; }
58
- if (active.has(agent.name)) {
59
- if (old !== next) writes.push([file, next]);
60
- generated[relative] = hash(next);
61
- generatedCanonical[relative] = hash(next.replace(/\r\n/g, "\n"));
62
- } else if (old !== null) removes.push(file);
63
- }
64
- // No writes until all inputs and existing settings have passed preflight.
65
- for (const [file, text] of writes) { fs.mkdirSync(path.dirname(file), { recursive: true }); fs.writeFileSync(file, text, "utf8"); }
66
- for (const file of removes) fs.unlinkSync(file); // contained, known generated files only
67
- if (profile.session) {
68
- const route = profile.models[profile.session.class];
69
- const merged = { ...settings, model: route.model, effortLevel: route.effort,
70
- modelSettings: { ...settings.modelSettings, [route.model]: { ...settings.modelSettings?.[route.model], effortLevel: route.effort } } };
71
- const next = `${JSON.stringify(merged, null, 2)}\n`;
72
- if (oldSettings !== next) {
73
- if (oldSettings) {
74
- const backup = contained(project, `.nccgs/backups/models-${Date.now()}/settings.json`);
75
- fs.mkdirSync(path.dirname(backup), { recursive: true }); fs.writeFileSync(backup, oldSettings, "utf8");
76
- }
77
- fs.mkdirSync(path.dirname(settingsFile), { recursive: true }); fs.writeFileSync(settingsFile, next, "utf8");
78
- }
79
- }
80
- if (explicit && policyPattern.test(oldPolicy)) {
81
- fs.writeFileSync(policyFile, oldPolicy.replace(policyPattern, `$1${name}`), "utf8");
82
- }
83
- atomicJson(activationFile, { schemaVersion: 1, profile: name, enabled: [...extras], generated, generatedCanonical, warnings });
84
- const installState = contained(project, ".claude/nccgs/install-state.json");
85
- if (fs.existsSync(installState)) {
86
- const state = json(installState);
87
- state.modelProfile = name;
88
- state.files = state.files.filter(item => !removes.includes(contained(project, item.relative))).map(item =>
89
- generated[item.relative] ? { ...item, ...fingerprintFile(contained(project, item.relative)) } : item);
90
- atomicJson(installState, state);
91
- }
92
- console.log(`NCCGS model profile '${name}' configured; ${writes.length} agent file(s) changed; ${active.size} selected agents.`);
93
- console.log("Model configuration records requested aliases/effort only. Runtime resolution requires Claude Code observation; execution policy and existing task approvals are unchanged.");
94
- if (legacyPolicy && !policyPattern.test(oldPolicy)) console.log("Legacy project policy preserved; model selection is stored in activation/install metadata until explicit policy migration.");
95
- for (const warning of warnings) console.warn(warning);
96
- } finally { lease.release(); }
@@ -1,121 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import { artifact, atomicJson, contained, hash, json, verifyArtifact } from "./policy.mjs";
4
-
5
- const need = (condition, message) => { if (!condition) throw new Error(message); };
6
- const text = value => typeof value === "string" && value.trim().length > 0;
7
- const scalar = value => value === null || typeof value === "boolean" || typeof value === "string" || (typeof value === "number" && Number.isFinite(value));
8
-
9
- export function validateCriteria(project, criteria) {
10
- for (const item of criteria) {
11
- need(item.manual === undefined || typeof item.manual === "boolean", "Criterion manual must be boolean");
12
- need(item.checkpoint === undefined || ["early", "final"].includes(item.checkpoint), "Criterion checkpoint must be early or final");
13
- need(!(item.manual && (item.check || item.assertions || item.checkpoint === "early")), "Manual criteria cannot also declare automatic checks/assertions or an early checkpoint");
14
- if (item.assertions === undefined) continue; // Old check-only criteria remain explicitly UNVERIFIED.
15
- need(Array.isArray(item.assertions) && item.assertions.length > 0 && item.assertions.length <= 100, "Criterion assertions must be a nonempty bounded array");
16
- for (const rule of item.assertions) {
17
- need(rule && text(rule.artifact) && rule.artifact.startsWith(".nccgs/evidence/measurements/") && rule.artifact.endsWith(".json"), "Criterion measurement must be JSON under .nccgs/evidence/measurements/");
18
- need(rule.artifact.split("/").every(part => part && part !== "." && part !== ".." && !/[:\\]/.test(part) && !/[. ]$/.test(part)), "Criterion measurement paths must be canonical and cannot alias governance files");
19
- contained(project, rule.artifact);
20
- need(typeof rule.pointer === "string" && (rule.pointer === "" || rule.pointer.startsWith("/")) && !/~(?![01])/.test(rule.pointer), "Criterion needs a valid JSON pointer");
21
- need(["eq", "gte", "lte"].includes(rule.op) && Object.hasOwn(rule, "value") && scalar(rule.value), "Criterion assertion needs eq/gte/lte and an explicit scalar value");
22
- need(rule.op === "eq" || (typeof rule.value === "number" && Number.isFinite(rule.value)), "Numeric criterion thresholds must be finite numbers");
23
- }
24
- }
25
- }
26
-
27
- function fingerprint(project, relative) {
28
- const file = contained(project, relative);
29
- if (!fs.existsSync(file)) return null;
30
- const stat = fs.statSync(file, { bigint: true });
31
- need(stat.isFile() && stat.size <= 1024n * 1024n, "Criterion measurement must be a file of at most 1 MiB");
32
- return { sha256: hash(fs.readFileSync(file)), size: String(stat.size), mtimeNs: String(stat.mtimeNs), ctimeNs: String(stat.ctimeNs) };
33
- }
34
- export function measurementBaseline(project, criteria) {
35
- return Object.fromEntries([...new Set(criteria.flatMap(c => (c.assertions ?? []).map(r => r.artifact)))].map(relative => [relative, fingerprint(project, relative)]));
36
- }
37
- function readPointer(value, pointer) {
38
- for (const part of pointer === "" ? [] : pointer.slice(1).split("/").map(s => s.replaceAll("~1", "/").replaceAll("~0", "~"))) {
39
- if (value === null || typeof value !== "object" || !Object.hasOwn(value, part)) return { found: false };
40
- value = value[part];
41
- }
42
- return { found: true, value };
43
- }
44
- function evaluate(rule, data) {
45
- const actual = readPointer(data, rule.pointer);
46
- if (!actual.found || !scalar(actual.value)) return { status: "UNVERIFIED", reason: "Missing or non-scalar measurement", pointer: rule.pointer };
47
- if (rule.op !== "eq" && typeof actual.value !== "number") return { status: "UNVERIFIED", reason: "Numeric measurement has the wrong type", pointer: rule.pointer };
48
- const pass = rule.op === "eq" ? actual.value === rule.value : rule.op === "gte" ? actual.value >= rule.value : actual.value <= rule.value;
49
- return { status: pass ? "PASS" : "FAIL", pointer: rule.pointer, actual: actual.value, op: rule.op, expected: rule.value };
50
- }
51
- const overall = items => items.some(i => i.status === "FAIL") ? "FAIL" : items.some(i => i.status !== "PASS") ? "UNVERIFIED" : "PASS";
52
-
53
- // Capture measurement bytes once, at command completion, independently of exit 0.
54
- export function captureCriteria(project, job, technicalStatus) {
55
- const outputs = new Map();
56
- const criteria = (job.criteria ?? []).map(criterion => {
57
- const checks = (criterion.assertions ?? []).map(rule => {
58
- if (!outputs.has(rule.artifact)) {
59
- try {
60
- const after = fingerprint(project, rule.artifact);
61
- need(after && JSON.stringify(after) !== JSON.stringify(job.measurementBaseline?.[rule.artifact] ?? null), "Measurement missing or unchanged since command launch");
62
- const bytes = fs.readFileSync(contained(project, rule.artifact));
63
- need(hash(bytes) === after.sha256, "Measurement changed while capturing");
64
- const data = JSON.parse(bytes.toString("utf8"));
65
- const relative = `.nccgs/evidence/criteria/${job.id}/${outputs.size}.json`;
66
- atomicJson(contained(project, relative), data);
67
- outputs.set(rule.artifact, { data, evidence: artifact(project, relative) });
68
- } catch (error) { outputs.set(rule.artifact, { error: error.message }); }
69
- }
70
- const output = outputs.get(rule.artifact);
71
- return output.error ? { status: "UNVERIFIED", reason: output.error, artifact: rule.artifact }
72
- : { ...evaluate(rule, output.data), artifact: rule.artifact, evidence: output.evidence };
73
- });
74
- const status = technicalStatus !== "PASS" || checks.length === 0 ? "UNVERIFIED" : overall(checks);
75
- return { id: criterion.id, status, checks, ...(checks.length ? {} : { reason: "Criterion has no measurable assertions" }) };
76
- });
77
- return { schemaVersion: 1, criteria };
78
- }
79
-
80
- // Read-only assessment: latest attempts win, even failures/pending attempts.
81
- export function assessCriteria(project, task, snap, { earlyOnly = false } = {}) {
82
- const directory = contained(project, ".nccgs/jobs");
83
- const jobs = fs.existsSync(directory) ? fs.readdirSync(directory, { withFileTypes: true }).filter(e => e.isDirectory()).map(e => {
84
- const request = json(path.join(directory, e.name, "request.json"));
85
- need(request.id === e.name && request.taskId, "Invalid criterion job identity");
86
- return request;
87
- }).filter(j => j.taskId === task.id) : [];
88
- const criteria = (task.contract.acceptance ?? []).filter(c => !earlyOnly || c.checkpoint === "early").map(c => {
89
- const base = { id: c.id, description: c.description, check: c.check ?? null, checkpoint: c.checkpoint ?? "final" };
90
- if (c.manual) return { ...base, status: "MANUAL_PENDING", reason: "Requires separate Product Owner gate" };
91
- const candidates = jobs.filter(j => j.name === c.check).sort((a, b) => Date.parse(b.queuedAt) - Date.parse(a.queuedAt));
92
- const job = candidates[0];
93
- let receiptRef = null;
94
- try {
95
- need(c.assertions?.length, "Check name alone does not prove the acceptance criterion; declare assertions");
96
- need(job, "No verification attempt for criterion");
97
- need(!candidates[1] || candidates[1].queuedAt !== job.queuedAt, "Ambiguous concurrent verification attempts");
98
- need(job.snapshot === snap && job.contractHash === task.contractHash, "Criterion evidence is stale for source/contract");
99
- const result = json(path.join(directory, job.id, "result.json"));
100
- const receipt = json(verifyArtifact(project, result.evidence));
101
- need(receipt.taskId === task.id && receipt.jobId === job.id && receipt.name === c.check && receipt.snapshot === snap && receipt.contractHash === task.contractHash, "Criterion receipt identity mismatch");
102
- need(Date.parse(receipt.startedAt) >= Date.parse(task.canonicalInputs.pinnedAt), "Criterion evidence predates current input pin");
103
- receiptRef = result.evidence;
104
- need(receipt.status === "PASS" && receipt.exitCode === 0 && receipt.sourceUnchanged && !receipt.timedOut, "Technical verification failed or is incomplete");
105
- verifyArtifact(project, receipt.log);
106
- const captured = receipt.acceptance?.criteria?.find(x => x.id === c.id);
107
- need(captured && captured.checks.length === c.assertions.length, "Receipt does not capture every criterion assertion");
108
- const checks = c.assertions.map((rule, index) => {
109
- const observed = captured.checks[index];
110
- need(observed.artifact === rule.artifact, "Captured measurement mapping mismatch");
111
- if (!observed.evidence) return { status: "UNVERIFIED", reason: observed.reason || "Missing captured measurement" };
112
- return evaluate(rule, json(verifyArtifact(project, observed.evidence)));
113
- });
114
- return { ...base, status: overall(checks), checks, receipt: result.evidence, jobId: job.id };
115
- } catch (error) { return { ...base, status: "UNVERIFIED", reason: error.message, jobId: job?.id ?? null, ...(receiptRef ? { receipt: receiptRef } : {}) }; }
116
- });
117
- const automatic = criteria.filter(c => c.status !== "MANUAL_PENDING");
118
- return { schemaVersion: 1, taskId: task.id, snapshot: snap, contractHash: task.contractHash, criteria,
119
- automaticPassed: automatic.every(c => c.status === "PASS"), manualPending: criteria.filter(c => c.status === "MANUAL_PENDING").map(c => c.id),
120
- status: overall(automatic), scope: "Measured criteria only; technical PASS and human acceptance are separate" };
121
- }
@@ -1,52 +0,0 @@
1
- import { verifyArtifact } from "./policy.mjs";
2
- import { assessCriteria } from "./criteria.mjs";
3
-
4
- const need = (condition, message) => { if (!condition) throw new Error(message); };
5
- export function deliveryBudget(entry, items) {
6
- if (!entry?.deliveryReserve) return null;
7
- const remaining = Object.fromEntries(Object.entries(entry.deliveryReserve).map(([purpose, count]) =>
8
- [purpose, Math.max(0, count - items.filter(d => (d.purpose ?? (d.kind === "review" ? "review" : "delivery")) === purpose).length)]));
9
- const protectedSlots = Object.values(remaining).reduce((a, b) => a + b, 0);
10
- return { reserved: entry.deliveryReserve, remaining, protectedSlots,
11
- totalRemaining: Math.max(0, entry.limits.maxDispatches - items.length),
12
- deliveryRemaining: Math.max(0, entry.limits.maxDispatches - items.length - protectedSlots),
13
- note: "Attempts consume quota even on failure/cancellation; protected slots are not extra budget" };
14
- }
15
- export function requireDeliveryRoom(entry, items, purpose, taskId) {
16
- const next = deliveryBudget(entry, [...items, { purpose }]);
17
- need(!next || items.length + 1 + next.protectedSlots <= entry.limits.maxDispatches,
18
- `Delivery budget reserved for ${taskId}: repair, QA and independent review; stop expansion and report partial or use an eligible protected purpose`);
19
- }
20
- export function dispatchPurpose(project, task, request, snap) {
21
- const purpose = request.purpose ?? (request.kind === "review" ? "review" : "delivery");
22
- need(["delivery", "repair", "qa", "review"].includes(purpose), "Invalid dispatch purpose");
23
- need((purpose === "review") === (request.kind === "review"), "Review dispatch requires review purpose");
24
- need(purpose !== "repair" || request.kind === "implementation", "Repair purpose requires an implementation worker");
25
- need(purpose !== "qa" || (request.kind === "analysis" && ["nccgs-qa-engineer", "nccgs-verification-engineer"].includes(request.agent)), "QA purpose requires a read-only QA/verification worker");
26
- need(purpose !== "qa" || request.repairFeedback, "Protected QA is reserved for a completed repair; initial QA uses delivery purpose");
27
- let feedback = null;
28
- if (["repair", "qa"].includes(purpose)) {
29
- const reviews = [task.stages?.review, ...(task.history ?? []).slice().reverse().map(h => h.stages?.review)].filter(Boolean);
30
- const latest = reviews.find(r => r.contractHash === task.contractHash);
31
- const negative = latest && ["CHANGES_REQUIRED", "BLOCKED"].includes(latest.verdict) ? latest : null;
32
- if (negative) { verifyArtifact(project, negative.evidence); feedback = { kind: "review", evidence: negative.evidence, verdict: negative.verdict }; }
33
- else {
34
- const assessment = assessCriteria(project, task, snap);
35
- const failed = assessment.criteria.filter(c => ["FAIL", "UNVERIFIED"].includes(c.status) && c.receipt);
36
- if (failed.length) feedback = { kind: "criteria", criteria: failed.map(c => ({ id: c.id, status: c.status, receipt: c.receipt })) };
37
- }
38
- // QA must also be available after a repair changes source and invalidates
39
- // the failing measurements. The caller supplies the pinned repair history.
40
- if (!feedback && purpose === "qa" && request.repairFeedback) feedback = request.repairFeedback;
41
- need(feedback, "Protected repair/QA requires recorded negative review or measured acceptance failure; missing initial evidence alone is not feedback");
42
- }
43
- return { purpose, feedback };
44
- }
45
- export function requireEarlyCheckpoint(project, task, entry, items, purpose, kind, snap) {
46
- const early = (task.contract.acceptance ?? []).filter(c => c.checkpoint === "early");
47
- if (kind !== "implementation" || purpose !== "delivery" || !early.length || !items.some(d => d.kind === "implementation" && (d.status === "completed" || d.runtime))) return;
48
- if (entry.earlyCheckpoint?.contractHash === task.contractHash) return;
49
- const assessment = assessCriteria(project, task, snap, { earlyOnly: true });
50
- need(assessment.automaticPassed, `Early acceptance checkpoint blocks expansion: ${assessment.criteria.filter(c => c.status !== "PASS").map(c => `${c.id}=${c.status}`).join(", ")}; collect a playable-slice measurement or report partial`);
51
- entry.earlyCheckpoint = { contractHash: task.contractHash, snapshot: snap, capturedAt: new Date().toISOString(), assessment };
52
- }
@@ -1,158 +0,0 @@
1
- import crypto from "node:crypto";
2
- import { artifact, atomicJson, contained, json, resolveExecution, verifyArtifact } from "./policy.mjs";
3
- import { check, taskPath } from "./gates.mjs";
4
- import { validateCriteria } from "./criteria.mjs";
5
-
6
- const need = (ok, message) => { if (!ok) throw new Error(`Design readiness: ${message}`); };
7
- const text = value => typeof value === "string" && value.trim().length > 0;
8
- const list = (value, label) => { need(Array.isArray(value), `${label} must be an array`); return value; };
9
- const strings = (value, label) => { list(value, label); need(value.every(text) && new Set(value).size === value.length, `${label} must contain unique nonempty strings`); return value; };
10
- const canonical = value => Array.isArray(value) ? value.map(canonical) : value && typeof value === "object"
11
- ? Object.fromEntries(Object.keys(value).sort().map(key => [key, canonical(value[key])])) : value;
12
- export const sameDesignValue = (a, b) => JSON.stringify(canonical(a)) === JSON.stringify(canonical(b));
13
-
14
- // Structural coverage is enforceable; the independent reviewer owns semantic adequacy.
15
- export function validateDesign(project, document) {
16
- need(document?.schemaVersion === 1 && text(document.objective), "document needs schemaVersion 1 and objective");
17
- need(["READY", "READY_WITH_RISKS", "BLOCKED"].includes(document.readiness), "invalid document readiness");
18
- need(["local", "feature", "cross-system"].includes(document.scope), "invalid scope");
19
- need(["fix", "learning-prototype", "alpha-ready", "production-change"].includes(document.target), "invalid target");
20
- const ready = document.readiness !== "BLOCKED";
21
- const sources = list(document.sources, "sources");
22
- need(sources.length > 0, "at least one hashed canonical source is required");
23
- for (const source of sources) verifyArtifact(project, source);
24
- need(new Set(sources.map(s => s.path)).size === sources.length, "duplicate source path");
25
- const citation = (value, label) => need(value && text(value.anchor) && sources.some(s => s.path === value.path && s.sha256 === value.sha256), `${label} needs a pinned source and section/excerpt anchor`);
26
- const criteria = list(document.acceptance, "acceptance"), ids = new Set();
27
- for (const criterion of criteria) {
28
- need(text(criterion.id) && !ids.has(criterion.id) && text(criterion.description), "criterion needs unique id and description"); ids.add(criterion.id);
29
- for (const field of ["procedure", "environment", "passCondition", "rationale"]) need(text(criterion[field]), `${criterion.id} needs ${field}`);
30
- citation(criterion.authority, `${criterion.id} threshold authority`);
31
- need(criterion.manual === true || (text(criterion.check) && criterion.assertions?.length > 0), `${criterion.id} needs measured assertions or an explicit human gate`);
32
- }
33
- validateCriteria(project, criteria);
34
- const requirements = list(document.requirements, "requirements"), reqIds = new Set(), covered = new Set();
35
- need(requirements.length > 0, "requirements are missing");
36
- for (const requirement of requirements) {
37
- need(text(requirement.id) && !reqIds.has(requirement.id), "requirement id is missing or duplicated"); reqIds.add(requirement.id);
38
- citation(requirement.source, `${requirement.id} source`);
39
- need(text(requirement.statement) && text(requirement.rules), `${requirement.id} needs statement and explicit rules/states/edge cases`);
40
- need(["fixed", "delegated-tuning"].includes(requirement.kind), `${requirement.id} must distinguish fixed rules and delegated tuning`);
41
- if (requirement.kind === "delegated-tuning") {
42
- need(text(requirement.tuning?.bounds) && text(requirement.tuning?.parameters), `${requirement.id} needs tuning parameters and bounds`);
43
- citation(requirement.tuning?.authority, `${requirement.id} tuning authority`);
44
- }
45
- strings(requirement.criteria, `${requirement.id} criteria`);
46
- need(!ready || requirement.criteria.length > 0, `${requirement.id} has no acceptance mapping`);
47
- for (const id of requirement.criteria) { need(ids.has(id), `${requirement.id} references unknown criterion ${id}`); covered.add(id); }
48
- }
49
- need(criteria.every(c => covered.has(c.id)), "an acceptance criterion has no requirement source");
50
- const decisions = list(document.decisions, "decisions"), decisionIds = new Set();
51
- for (const decision of decisions) {
52
- need(text(decision.id) && !decisionIds.has(decision.id) && text(decision.question), "decision needs unique id and question"); decisionIds.add(decision.id);
53
- need(["open", "resolved"].includes(decision.status), "invalid decision status");
54
- if (decision.status === "resolved") { need(text(decision.resolution), "resolved decision needs resolution"); citation(decision.authority, `${decision.id} decision authority`); }
55
- need(!ready || decision.status === "resolved", "open product decisions cannot be READY");
56
- }
57
- strings(document.requiredChecks, "requiredChecks"); strings(document.manualGates, "manualGates");
58
- for (const criterion of criteria) need(criterion.manual ? document.manualGates.includes(criterion.id) : document.requiredChecks.includes(criterion.check), `${criterion.id} is absent from required checks/manual gates`);
59
- strings(document.outOfScope, "outOfScope"); strings(document.risks, "risks");
60
- for (const diagnostic of list(document.diagnostics, "diagnostics")) {
61
- need(text(diagnostic.id) && text(diagnostic.procedure) && text(diagnostic.limitations), "diagnostics need id, procedure and limitations");
62
- need(!ids.has(diagnostic.id), "a diagnostic cannot silently double as an acceptance criterion");
63
- }
64
- return document;
65
- }
66
-
67
- export function validateDesignCommand(project, id, relative) {
68
- const task = json(taskPath(project, id));
69
- need(task.schemaVersion === 2 && task.mode === "plan" && task.contract.workflow === "design", "design-validate requires a standalone /design plan task");
70
- need(task.contract.analysisArtifacts.includes(relative), "document must be a declared analysis artifact");
71
- need(task.contract.requiredChecks.includes("design-contract"), "plan must require the design-contract check");
72
- const state = check(project, task, "analysis"); need(state.allowed, state.message);
73
- const reference = artifact(project, relative), document = validateDesign(project, json(verifyArtifact(project, reference)));
74
- const receipt = { schemaVersion: 1, origin: "design-contract-validation", taskId: id, contractHash: task.contractHash,
75
- snapshot: state.snapshot, status: "PASS", name: "design-contract", document: reference,
76
- readiness: document.readiness, capturedAt: new Date().toISOString(), scope: "Structural document validation only; independent semantic review is still required" };
77
- const output = `.nccgs/evidence/design-checks/${crypto.randomUUID()}.json`;
78
- atomicJson(contained(project, output), receipt);
79
- return { ...receipt, evidence: artifact(project, output) };
80
- }
81
-
82
- export function verifyDesignReceipt(project, task, stage, receipt) {
83
- need(receipt.origin === "design-contract-validation" && receipt.status === "PASS" && receipt.name === "design-contract"
84
- && receipt.taskId === task.id && receipt.contractHash === task.contractHash && receipt.snapshot === stage.snapshot, "validation receipt is stale or belongs to another task");
85
- need(sameDesignValue(receipt.document, stage.evidence), "validated document differs from the analysis handoff");
86
- return validateDesign(project, json(verifyArtifact(project, receipt.document)));
87
- }
88
-
89
- // Fixed read-only comparison for plan coordinators; no arbitrary shell or code.
90
- // Allowed changes remain a semantic scope decision for the independent reviewer.
91
- export function compareDesignCommand(project, id, baselinePath, candidatePath) {
92
- const task = json(taskPath(project, id));
93
- need(task.schemaVersion === 2 && task.mode === "plan" && task.contract.workflow === "design", "design-compare requires a standalone /design plan task");
94
- need(task.contract.analysisArtifacts.includes(candidatePath), "candidate must be a declared analysis artifact");
95
- const baseline = task.contract.sources.find(ref => ref.path === baselinePath);
96
- need(baseline && baselinePath !== candidatePath, "baseline must be a distinct pinned intake source");
97
- const state = check(project, task, "analysis"); need(state.allowed, state.message);
98
- const candidate = artifact(project, candidatePath);
99
- const before = json(verifyArtifact(project, baseline)), after = json(verifyArtifact(project, candidate));
100
- const changes = key => {
101
- const index = document => {
102
- const entries = list(document[key], key), ids = new Set();
103
- for (const item of entries) { need(text(item.id) && !ids.has(item.id), `${key} needs unique ids`); ids.add(item.id); }
104
- return new Map(entries.map(item => [item.id, item]));
105
- };
106
- const a = index(before), b = index(after);
107
- return { added: [...b.keys()].filter(id => !a.has(id)), removed: [...a.keys()].filter(id => !b.has(id)),
108
- changed: [...a.keys()].filter(id => b.has(id) && !sameDesignValue(a.get(id), b.get(id))),
109
- orderChanged: !sameDesignValue([...a.keys()], [...b.keys()]) };
110
- };
111
- const otherKeys = [...new Set([...Object.keys(before), ...Object.keys(after)])].filter(key => !["requirements", "acceptance"].includes(key));
112
- const receipt = { schemaVersion: 1, origin: "design-contract-comparison", taskId: id, contractHash: task.contractHash,
113
- snapshot: state.snapshot, baseline, candidate, capturedAt: new Date().toISOString(),
114
- requirements: changes("requirements"), acceptance: changes("acceptance"),
115
- otherTopLevelChanges: otherKeys.filter(key => !sameDesignValue(before[key], after[key])),
116
- scope: "JSON value comparison only; not semantic review, allowed-change approval or game acceptance" };
117
- // Recheck the bytes after comparing so the receipt never pins a raced read.
118
- verifyArtifact(project, baseline); verifyArtifact(project, candidate);
119
- const output = `.nccgs/evidence/design-checks/${crypto.randomUUID()}.json`;
120
- atomicJson(contained(project, output), receipt);
121
- return { ...receipt, evidence: artifact(project, output) };
122
- }
123
-
124
- export function pinDesign(project, designId, consumerId) {
125
- need(text(designId) && designId !== consumerId, "use a distinct completed design task");
126
- const taskRef = artifact(project, `.nccgs/tasks/${designId}.json`), task = json(verifyArtifact(project, taskRef));
127
- need(task.id === designId && task.mode === "plan" && task.contract.workflow === "design"
128
- && task.closed?.snapshot && task.closed.snapshot === task.stages.review?.snapshot, "design task must be a completed /design plan");
129
- const gate = check(project, task, "done"); need(gate.allowed, gate.message);
130
- const analysis = task.stages.analysis, review = task.stages.review;
131
- const document = validateDesign(project, json(verifyArtifact(project, analysis.evidence)));
132
- need(document.readiness !== "BLOCKED", "design is BLOCKED");
133
- const checked = analysis.checks.find(c => c.name === "design-contract"); need(checked, "design validation receipt missing");
134
- verifyDesignReceipt(project, task, analysis, json(verifyArtifact(project, checked.evidence)));
135
- const references = [taskRef, task.intake, analysis.evidence, checked.evidence, review.evidence, ...document.sources];
136
- for (const stage of [analysis, review]) {
137
- references.push(stage.runtime);
138
- const runtime = json(verifyArtifact(project, stage.runtime)); references.push(runtime.observationSource);
139
- }
140
- return { schemaVersion: 1, taskId: designId, document: analysis.evidence, references,
141
- reviewedSnapshot: review.snapshot, pinnedAt: new Date().toISOString(), specification: document };
142
- }
143
-
144
- export function requireDesignReady(project, task) {
145
- if (task.schemaVersion !== 2 || task.mode !== "implement") return;
146
- const pinned = task.contract.design;
147
- const required = (task.execution ?? resolveExecution(project)).designReviewRequired === true;
148
- if (!required && !pinned) return; // Historical policies retain their original obligations.
149
- need(task.contract.readiness === "ready", "implementation still needs inspection or a product decision");
150
- const localFix = task.contract.scope === "local" && task.contract.target === "fix" && task.contract.acceptance.length > 0;
151
- if (!pinned && localFix) return; // Explicit, testable local fix; no new feature semantics.
152
- need(pinned?.schemaVersion === 1, "reviewed design missing; complete /design -> /design-review -> /story-readiness before implementation");
153
- for (const ref of pinned.references) verifyArtifact(project, ref);
154
- const document = validateDesign(project, json(verifyArtifact(project, pinned.document)));
155
- need(document.readiness !== "BLOCKED", "design is BLOCKED");
156
- for (const key of ["objective", "scope", "target", "acceptance"]) need(sameDesignValue(task.contract[key], document[key]), `implementation ${key} differs from reviewed design`);
157
- for (const key of ["requiredChecks", "manualGates"]) need(document[key].every(item => task.contract[key].includes(item)), `implementation omits reviewed ${key}`);
158
- }
@@ -1,66 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import crypto from "node:crypto";
4
-
5
- const need = (ok, message) => { if (!ok) throw new Error(`Editor session evidence: ${message}`); };
6
- const hash = bytes => crypto.createHash("sha256").update(bytes).digest("hex");
7
- const samePath = (a, b) => path.resolve(a) === path.resolve(b);
8
- const identity = value => value?.windowsJob === true && Number.isSafeInteger(value.pid) && value.pid > 0 && /^Local\\NCCGS-[a-f0-9-]{36}$/.test(value.groupName ?? "");
9
-
10
- // Copy existing operator receipts for the reviewer. Never execute a command,
11
- // stop a process, rewrite a task/review, or manufacture a new runtime observation.
12
- // This is evidence publication, not acceptance or independent verification.
13
- export function publishEditorSessionEvidence(project, { sourceProject, startFile, stopFile, shutdownFile, id = crypto.randomUUID() }) {
14
- need(typeof sourceProject === "string" && path.isAbsolute(sourceProject), "sourceProject must be explicit and absolute");
15
- need(/^[a-f0-9-]{36}$/.test(id), "invalid bundle id");
16
- project = fs.realpathSync(project);
17
- const originals = { start: startFile, stop: stopFile, shutdown: shutdownFile };
18
- const data = {}, bytes = {};
19
- for (const [kind, file] of Object.entries(originals)) {
20
- need(typeof file === "string" && path.isAbsolute(file), `${kind} path must be absolute`);
21
- const stat = fs.lstatSync(file);
22
- need(stat.isFile() && !stat.isSymbolicLink() && stat.size <= 1024 * 1024, `${kind} must be a bounded regular receipt`);
23
- bytes[kind] = fs.readFileSync(file);
24
- try { data[kind] = JSON.parse(bytes[kind].toString("utf8")); } catch { need(false, `${kind} is not JSON`); }
25
- }
26
- const { start, stop, shutdown } = data;
27
- need(identity(start.identity) && identity(stop.identity), "owned Windows Editor identities required");
28
- need(start.identity.pid === stop.identity.pid && start.identity.groupName === stop.identity.groupName, "start/stop ownership mismatch");
29
- need(typeof start.project === "string" && samePath(start.project, sourceProject), "start project mismatch");
30
- need(stop.state === "dead" && stop.forced === false && stop.result?.code === 0 && stop.result?.signal === null, "normal settled Editor exit required; retain failed/uncertain evidence separately");
31
- const args = shutdown.args;
32
- need(Array.isArray(args) && args.every(v => typeof v === "string"), "shutdown arguments required");
33
- need(args[0] === "command" && ["eval", "script"].includes(args[1]), "expected recorded Unity command");
34
- need(args.filter(v => v === "--project-path").length === 1 && samePath(args[args.indexOf("--project-path") + 1] ?? "", sourceProject), "shutdown project mismatch");
35
- need(args.some(v => /UnityEditor\.EditorApplication\.Exit\(0\)/.test(v)), "recorded graceful Editor exit is missing");
36
- need(identity(shutdown.identity) && shutdown.treeState === "dead", "shutdown CLI ownership must be settled");
37
- need(shutdown.code === 0 && shutdown.signal === null, "shutdown CLI did not complete normally");
38
- need(Number.isFinite(Date.parse(start.at)) && Number.isFinite(Date.parse(shutdown.at)) && Date.parse(shutdown.at) >= Date.parse(start.at), "invalid event ordering");
39
-
40
- // No junction/symlink in the output chain, even when importing into an addendum.
41
- const relative = `.nccgs/evidence/editor-control/operator-${id}`;
42
- let directory = project;
43
- for (const segment of [".nccgs", "evidence", "editor-control"]) {
44
- directory = path.join(directory, segment);
45
- if (fs.existsSync(directory)) need(fs.lstatSync(directory).isDirectory() && !fs.lstatSync(directory).isSymbolicLink() && fs.realpathSync(directory) === directory, "output path redirects outside the project");
46
- else fs.mkdirSync(directory);
47
- }
48
- directory = path.join(project, relative);
49
- fs.mkdirSync(directory); // exclusive directory creation: never replace a prior bundle
50
- const references = {};
51
- for (const kind of Object.keys(originals)) {
52
- const name = `${kind}.json`;
53
- fs.writeFileSync(path.join(directory, name), bytes[kind], { flag: "wx" });
54
- references[kind] = { path: `${relative}/${name}`, sha256: hash(bytes[kind]) };
55
- }
56
- const receipt = {
57
- schemaVersion: 1, origin: "external-operator-editor-evidence", recordedAt: new Date().toISOString(),
58
- sourceProject, evidenceProject: project, historicalImport: !samePath(sourceProject, project),
59
- editorIdentity: start.identity, reportedProcessState: stop.state, forced: stop.forced,
60
- references, currentProcessProbe: "not performed by this publisher",
61
- note: "Byte-preserved operator receipts only. Not native worker execution, acceptance, a reviewer verdict, or a new Editor stop. Original event times and ownership remain in the referenced files."
62
- };
63
- const manifest = Buffer.from(JSON.stringify(receipt, null, 2) + "\n");
64
- fs.writeFileSync(path.join(directory, "receipt.json"), manifest, { flag: "wx" });
65
- return { path: `${relative}/receipt.json`, sha256: hash(manifest) };
66
- }