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,60 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
-
4
- // Managed manifests are portable POSIX paths. Reject Windows aliases even on
5
- // another host so an otherwise valid package cannot become unsafe on Windows.
6
- export function assertRelativePath(relative) {
7
- if (typeof relative !== "string" || !relative || path.posix.isAbsolute(relative)
8
- || path.win32.isAbsolute(relative) || /[\\<>:"|?*\u0000-\u001f]/.test(relative)) {
9
- throw new Error(`Unsafe project-relative POSIX path: ${String(relative)}`);
10
- }
11
- for (const part of relative.split("/")) {
12
- if (!part || part === "." || part === ".." || /[. ]$/.test(part)
13
- || /^(?:con|prn|aux|nul|conin\$|conout\$|clock\$|com[1-9¹²³]|lpt[1-9¹²³])(?:\.|$)/i.test(part)) {
14
- throw new Error(`Unsafe project-relative path component: ${relative}`);
15
- }
16
- }
17
- return relative;
18
- }
19
-
20
- function statWithoutLinks(file) {
21
- let stat;
22
- try { stat = fs.lstatSync(file); }
23
- catch (error) { if (error.code === "ENOENT") return null; throw error; }
24
- if (stat.isSymbolicLink()) throw new Error(`Symlink/junction/reparse path is not supported: ${file}`);
25
- return stat;
26
- }
27
-
28
- export function assertProjectRoot(project) {
29
- const root = path.resolve(project);
30
- let current = path.parse(root).root;
31
- for (const part of root.slice(current.length).split(path.sep).filter(Boolean)) {
32
- current = path.join(current, part);
33
- const stat = statWithoutLinks(current);
34
- if (!stat?.isDirectory()) throw new Error(`Project directory does not exist or is not a directory: ${current}`);
35
- }
36
- return root;
37
- }
38
-
39
- function inside(root, target) {
40
- const relative = path.relative(root, target);
41
- return relative === "" || (!path.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path.sep}`));
42
- }
43
-
44
- export function containedPath(project, relative) {
45
- assertRelativePath(relative);
46
- const root = assertProjectRoot(project);
47
- const target = path.resolve(root, ...relative.split("/"));
48
- if (target === root || !inside(root, target)) throw new Error(`Path escapes project: ${relative}`);
49
- const realRoot = fs.realpathSync(root);
50
- let current = root;
51
- const parts = relative.split("/");
52
- for (let index = 0; index < parts.length; index++) {
53
- current = path.join(current, parts[index]);
54
- const stat = statWithoutLinks(current);
55
- if (!stat) break; // All remaining components are new, after lexical validation.
56
- if (index < parts.length - 1 && !stat.isDirectory()) throw new Error(`Parent path is not a directory: ${current}`);
57
- if (!inside(realRoot, fs.realpathSync(current))) throw new Error(`Resolved path escapes project: ${relative}`);
58
- }
59
- return target;
60
- }
@@ -1,107 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import crypto from "node:crypto";
4
- import { containedPath } from "./paths.mjs";
5
-
6
- export const hash = (value) => crypto.createHash("sha256").update(value).digest("hex");
7
- export const json = (file) => JSON.parse(fs.readFileSync(file, "utf8"));
8
- export function loadPipeline(project) {
9
- const pipeline = json(path.join(project, ".claude/nccgs/pipeline.json"));
10
- if (pipeline.schemaVersion !== 1) throw new Error("Unsupported pipeline schema");
11
- if (!pipeline.profiles?.[pipeline.defaultProfile]) throw new Error("Invalid default profile");
12
- if (!Array.isArray(pipeline.coreAgents) || !pipeline.coreAgents.includes(pipeline.contract?.reviewAgent)) throw new Error("Core agents must include the required reviewer");
13
- if (JSON.stringify(pipeline.profiles["astra-claude"]?.activeAgents) !== JSON.stringify(pipeline.coreAgents)) throw new Error("Default Astra active agents must match coreAgents");
14
- if (pipeline.profiles["claude-standalone"] && JSON.stringify(pipeline.profiles["claude-standalone"].activeAgents) !== JSON.stringify(pipeline.coreAgents)) throw new Error("Standalone active agents must match coreAgents");
15
- for (const profile of Object.values(pipeline.profiles)) {
16
- for (const route of Object.values(profile.models ?? {})) {
17
- if (!(route.model === null || typeof route.model === "string") || ![null, "low", "medium", "high", "xhigh", "max"].includes(route.effort)) throw new Error("Invalid model/effort route");
18
- }
19
- if (profile.session && !profile.models[profile.session.class]) throw new Error("Unknown session model class");
20
- }
21
- for (const risk of ["FAST", "STANDARD", "CONTROLLED"]) {
22
- const tier = pipeline.contract.taskTiers?.[risk];
23
- const expectedClass = { FAST: "lightweight", STANDARD: "standard", CONTROLLED: "deep" }[risk];
24
- if (tier?.implementationClass !== expectedClass || !pipeline.profiles["astra-claude"].models[expectedClass]) throw new Error(`Invalid implementation route for ${risk}`);
25
- if (!Number.isSafeInteger(tier.maxReviewRounds) || tier.maxReviewRounds < 1 || tier.maxReviewRounds > 10) throw new Error(`Invalid review-round budget for ${risk}`);
26
- }
27
- return pipeline;
28
- }
29
- export function selectedProfile(project, explicit) {
30
- const file = contained(project, ".nccgs/project.yaml");
31
- const text = fs.existsSync(file) ? fs.readFileSync(file, "utf8") : "";
32
- const block = text.match(/^models:[ \t]*\r?\n((?:[ \t]+[^\n]*\n?|\s*\n)*)/m)?.[1] ?? "";
33
- const value = block.match(/^\s+profile:\s*([^#\r\n]+)/m)?.[1]?.trim().replace(/^['"]|['"]$/g, "");
34
- if (explicit || value) return explicit || value;
35
- // Legacy schema-1 policy is preserved byte-for-byte during installation.
36
- // Its explicit selection lives in installation/activation metadata until the
37
- // user migrates the project policy; never silently replace it with a new default.
38
- const installed = contained(project, ".claude/nccgs/install-state.json");
39
- const installedProfile = fs.existsSync(installed) ? json(installed).modelProfile : null;
40
- if (installedProfile) return installedProfile;
41
- const activated = contained(project, ".nccgs/agent-activation.json");
42
- const activatedProfile = fs.existsSync(activated) ? json(activated).profile : null;
43
- if (activatedProfile) return activatedProfile;
44
- return loadPipeline(project).defaultProfile;
45
- }
46
- export function profilePolicy(project, explicit) {
47
- const pipeline = loadPipeline(project);
48
- const name = selectedProfile(project, explicit);
49
- if (!Object.hasOwn(pipeline.profiles, name)) throw new Error(`Unknown model profile '${name}'`);
50
- return { pipeline, name, profile: pipeline.profiles[name] };
51
- }
52
- export function executionPolicy(value) {
53
- if (!value || typeof value !== "object" || Array.isArray(value) || value.schemaVersion !== 1) throw new Error("Unsupported execution policy schema; expected schemaVersion 1");
54
- const allowed = new Set(["schemaVersion", "name", "externalReview", "acceptanceRequired", "requireObservedEffort", "maxParallelWorkers", "designReviewRequired", "reviewContractRequired"]);
55
- for (const key of Object.keys(value)) if (!allowed.has(key)) throw new Error(`Unknown execution policy field: ${key}`);
56
- if (!["standalone", "compatibility"].includes(value.name)) throw new Error("Execution name must be standalone or compatibility");
57
- const standalone = value.name === "standalone";
58
- const external = value.externalReview === undefined ? { mode: standalone ? "off" : "required" } : value.externalReview;
59
- if (!external || typeof external !== "object" || Array.isArray(external) || Object.keys(external).some(key => key !== "mode") || !["off", "advisory", "required"].includes(external.mode)) throw new Error("externalReview.mode must be off, advisory or required");
60
- for (const field of ["acceptanceRequired", "requireObservedEffort", "designReviewRequired", "reviewContractRequired"]) if (value[field] !== undefined && typeof value[field] !== "boolean") throw new Error(`${field} must be boolean`);
61
- const workers = value.maxParallelWorkers === undefined ? (standalone ? 2 : 4) : value.maxParallelWorkers;
62
- if (!Number.isSafeInteger(workers) || workers < 1 || workers > 4) throw new Error("maxParallelWorkers must be an integer from 1 to 4");
63
- if (!standalone && (external.mode !== "required" || value.acceptanceRequired === false || value.requireObservedEffort === false)) throw new Error("Compatibility execution preserves required external review, acceptance and observed effort; migrate explicitly to standalone to change these obligations");
64
- return { name: value.name, externalReview: { mode: external.mode }, acceptanceRequired: value.acceptanceRequired ?? !standalone,
65
- requireObservedEffort: value.requireObservedEffort ?? !standalone, maxParallelWorkers: workers,
66
- ...(value.designReviewRequired !== undefined ? { designReviewRequired: value.designReviewRequired } : {}),
67
- ...(value.reviewContractRequired !== undefined ? { reviewContractRequired: value.reviewContractRequired } : {}) };
68
- }
69
- // Model selection and execution obligations are intentionally independent. A
70
- // missing file is a legacy project, never implicit permission to drop gates.
71
- export function resolveExecution(project) {
72
- const { name: profileName, profile } = profilePolicy(project);
73
- const file = contained(project, ".nccgs/execution.json");
74
- const execution = executionPolicy(fs.existsSync(file) ? json(file) : { schemaVersion: 1, name: "compatibility" });
75
- return { name: execution.name, profileName, profile, externalReview: execution.externalReview,
76
- acceptanceRequired: execution.acceptanceRequired, requireObservedEffort: execution.requireObservedEffort, maxParallelWorkers: execution.maxParallelWorkers,
77
- ...(execution.designReviewRequired !== undefined ? { designReviewRequired: execution.designReviewRequired } : {}),
78
- ...(execution.reviewContractRequired !== undefined ? { reviewContractRequired: execution.reviewContractRequired } : {}) };
79
- }
80
- export function contained(project, relative) {
81
- return containedPath(project, relative);
82
- }
83
- export function atomicJson(file, value) {
84
- fs.mkdirSync(path.dirname(file), { recursive: true });
85
- const temp = `${file}.${crypto.randomUUID()}.tmp`;
86
- fs.writeFileSync(temp, `${JSON.stringify(value, null, 2)}\n`, { flag: "wx" });
87
- // Windows readers/scanners can briefly deny atomic replacement. Retain the old
88
- // complete file and retry only bounded sharing failures, never unlink it first.
89
- for (let attempt = 0; ; attempt++) {
90
- try { fs.renameSync(temp, file); break; }
91
- catch (error) {
92
- if (process.platform !== "win32" || !["EPERM", "EACCES", "EBUSY"].includes(error.code) || attempt >= 24) throw error;
93
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 20);
94
- }
95
- }
96
- }
97
- export function artifact(project, relative) {
98
- const file = contained(project, relative);
99
- if (!fs.statSync(file).isFile()) throw new Error(`Artifact is not a file: ${relative}`);
100
- const bytes = fs.readFileSync(file);
101
- if (!bytes.length) throw new Error(`Empty artifact: ${relative}`);
102
- return { path: relative, sha256: hash(bytes) };
103
- }
104
- export function verifyArtifact(project, ref) {
105
- if (!ref?.sha256 || artifact(project, ref.path).sha256 !== ref.sha256) throw new Error(`Missing or stale artifact: ${ref?.path ?? "unknown"}`);
106
- return contained(project, ref.path);
107
- }
@@ -1,74 +0,0 @@
1
- import fs from "node:fs";
2
- import os from "node:os";
3
- import path from "node:path";
4
- import crypto from "node:crypto";
5
- import { atomicJson } from "./policy.mjs";
6
- import { windowsGroupState } from "./command-process.mjs";
7
-
8
- export const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
9
- export function pidState(pid) {
10
- if (!Number.isSafeInteger(pid) || pid <= 0) return "unknown";
11
- try { process.kill(pid, 0); return "alive"; }
12
- catch (error) { return error.code === "ESRCH" ? "dead" : "unknown"; }
13
- }
14
- // No age-based eviction. A reused PID is conservatively treated as live.
15
- // Foreground commands must not daemonize/detach their descendants.
16
- export function treeState(child) {
17
- if (!child?.pid) return "unknown";
18
- const root = pidState(child.pid);
19
- if (root !== "dead") return root;
20
- if (process.platform !== "win32") {
21
- if (!child.group) return "unknown";
22
- try { process.kill(-child.pid, 0); return "alive"; }
23
- catch (error) { return error.code === "ESRCH" ? "dead" : "unknown"; }
24
- }
25
- // Only OS-owned groups prove descendant termination. Legacy/unmanaged process
26
- // trees remain unknown, even when the direct child PID no longer exists.
27
- return child.windowsJob ? windowsGroupState(child.groupName) : "unknown";
28
- }
29
- export function ownerState(record) {
30
- if (record?.schemaVersion !== 1 || record.host !== os.hostname() || !record.token) return "unknown";
31
- const owner = pidState(record.pid);
32
- if (owner !== "dead") return owner;
33
- if (record.phase === "spawning") return "unknown"; // crash between spawn and PID persistence
34
- if (record.child) return treeState(record.child);
35
- return "dead";
36
- }
37
- export function acquireLock(file, metadata = {}) {
38
- fs.mkdirSync(path.dirname(file), { recursive: true });
39
- const record = { ...metadata, schemaVersion: 1, host: os.hostname(), pid: process.pid,
40
- token: crypto.randomUUID(), createdAt: new Date().toISOString(), phase: "owned", child: null };
41
- const create = () => {
42
- const fd = fs.openSync(file, "wx");
43
- try { fs.writeFileSync(fd, JSON.stringify(record)); } finally { fs.closeSync(fd); }
44
- };
45
- try { create(); }
46
- catch (error) {
47
- if (error.code !== "EEXIST") throw error;
48
- let old;
49
- try { old = JSON.parse(fs.readFileSync(file, "utf8")); } catch { /* unknown owner */ }
50
- if (ownerState(old) !== "dead") throw new Error(`Locked: ${file}; owner/child is live or unverified; no lease expiry`);
51
- // Serialize reclaimers. An interrupted recovery is deliberately fail-closed.
52
- let recovery;
53
- try { recovery = fs.openSync(`${file}.recovery`, "wx"); }
54
- catch { throw new Error(`Locked: ${file}; recovery already in progress or needs inspection`); }
55
- try {
56
- fs.writeFileSync(recovery, JSON.stringify(record));
57
- const current = JSON.parse(fs.readFileSync(file, "utf8"));
58
- if (current.token !== old.token || ownerState(current) !== "dead") throw new Error(`Locked: ${file}; ownership changed`);
59
- fs.appendFileSync(`${file}.recoveries.jsonl`, JSON.stringify({ at: new Date().toISOString(), previous: current, recoveredBy: record }) + "\n");
60
- fs.unlinkSync(file);
61
- create();
62
- } finally { fs.closeSync(recovery); fs.unlinkSync(`${file}.recovery`); }
63
- }
64
- return {
65
- record,
66
- update(changes) {
67
- if (JSON.parse(fs.readFileSync(file, "utf8")).token !== record.token) throw new Error("Lock ownership changed");
68
- Object.assign(record, changes); atomicJson(file, record);
69
- },
70
- release() {
71
- if (fs.existsSync(file) && JSON.parse(fs.readFileSync(file, "utf8")).token === record.token) fs.unlinkSync(file);
72
- }
73
- };
74
- }
@@ -1,106 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import { artifact, contained, json, verifyArtifact } from "./policy.mjs";
4
- import { validateUnityRepair, unityEditorToolScope, repairEditorCommand, unityCodePath, unitySceneSafety } from "./unity-repair.mjs";
5
-
6
- const need = (ok, message) => { if (!ok) throw new Error(message); };
7
- export const repairLimits = Object.freeze({ workCalls: 12, readCalls: 6, handoffCalls: 3, durationMs: 600000 });
8
- const text = (value, max) => typeof value === "string" && value.trim().length > 0 && value.length <= max;
9
- const keys = (value, allowed) => value && typeof value === "object" && !Array.isArray(value) && Object.keys(value).every(k => allowed.includes(k));
10
-
11
- // A repair is an already-decided source edit, not another discovery experiment.
12
- // Checks stay with the coordinator and retain the existing verification receipts.
13
- export function pinRepairPacket(project, task, request, snapshot) {
14
- need(typeof request.workPacket === "string" && request.workPacket.startsWith(".nccgs/evidence/work-packets/") && request.workPacket.endsWith(".json"), "Repair requires a workPacket JSON under .nccgs/evidence/work-packets/");
15
- const reference = artifact(project, request.workPacket);
16
- need(fs.statSync(contained(project, reference.path)).size <= 32768, "Repair packet exceeds 32 KiB; narrow the work before dispatch");
17
- const packet = json(verifyArtifact(project, reference));
18
- const unity = packet.schemaVersion === 2;
19
- need(keys(packet, ["schemaVersion", "taskId", "contractHash", "sourceSnapshot", "problem", "solution", "changes", "context", "verification", "budget", ...(unity ? ["repairType", "unity"] : [])]) && [1, 2].includes(packet.schemaVersion), "Invalid repair packet schema");
20
- if (!unity) need(fs.statSync(contained(project, reference.path)).size <= 16384, "Repair packet exceeds 16 KiB; narrow the work before dispatch");
21
- need(packet.taskId === task.id && packet.contractHash === task.contractHash && packet.sourceSnapshot === snapshot, "Repair packet task/contract/source snapshot is stale or mismatched");
22
- need(text(packet.problem, 800) && text(packet.solution, 1600), "Repair packet needs a concise problem and chosen solution");
23
- need(Array.isArray(packet.changes) && packet.changes.length >= 1 && packet.changes.length <= (unity ? 8 : 4), "Repair packet must specify 1-4 exact existing source files (up to 8 in a typed Unity packet)");
24
- for (const change of packet.changes) {
25
- need(keys(change, ["path", "instruction", ...(unity ? ["operation"] : [])]) && text(change.instruction, 1600), "Each repair change needs an exact path and bounded instruction");
26
- const file = contained(project, change.path);
27
- if (!unity) need(!/^\.(?:nccgs|claude|git)(?:\/|$)/i.test(change.path) && fs.statSync(file).isFile(), "Repair changes must be existing source files, not governance or evidence");
28
- }
29
- const limits = unity ? validateUnityRepair(project, packet) : repairLimits;
30
- const paths = packet.changes.map(c => c.path).sort();
31
- need(new Set(paths.map(p => p.toLowerCase())).size === paths.length && JSON.stringify(paths) === JSON.stringify([...request.writePaths].sort()), "Repair writePaths must exactly match packet files; directory ownership is not allowed");
32
- need(request.handoffPaths?.length === 1, "Repair requires exactly one fresh handoff path");
33
- if (unity) need(!request.handoffPaths.includes(packet.unity.capabilities?.path), "Unity capability evidence cannot be its handoff");
34
- need(Array.isArray(packet.context) && packet.context.length <= 4, "Repair context must contain at most four pinned evidence references");
35
- for (const ref of packet.context) {
36
- need(ref?.path?.startsWith(".nccgs/evidence/") && !ref.path.startsWith(".nccgs/evidence/work-packets/") && !request.handoffPaths.includes(ref.path), "Repair context must reference existing evidence, not the packet or its handoff");
37
- verifyArtifact(project, ref);
38
- }
39
- need(Array.isArray(packet.verification) && packet.verification.length > 0 && new Set(packet.verification).size === packet.verification.length &&
40
- packet.verification.every(name => task.contract.requiredChecks.includes(name)) && task.contract.requiredChecks.every(name => packet.verification.includes(name)), "Repair verification must list the task's required checks for the coordinator");
41
- need(packet.budget === undefined || keys(packet.budget, Object.keys(repairLimits)), "Unknown repair budget field");
42
- const budget = { ...limits, ...packet.budget };
43
- for (const [name, value] of Object.entries(budget)) need(Number.isSafeInteger(value) && value >= 1 && value <= limits[name], `Repair ${name} must be between 1 and ${limits[name]}`);
44
- need(budget.readCalls <= budget.workCalls, "Repair readCalls cannot exceed workCalls");
45
- return { ...packet, reference, budget, ...(unity ? { sceneSafety: unitySceneSafety } : {}) };
46
- }
47
-
48
- export function verifyRepairPacket(project, dispatch) {
49
- verifyArtifact(project, dispatch.workPacket.reference);
50
- for (const ref of dispatch.workPacket.context) verifyArtifact(project, ref);
51
- if (dispatch.workPacket.schemaVersion === 2) {
52
- if (dispatch.workPacket.unity.capabilities) verifyArtifact(project, dispatch.workPacket.unity.capabilities);
53
- verifyArtifact(project, dispatch.workPacket.scope);
54
- }
55
- }
56
-
57
- export function repairPrompt(task, dispatch) {
58
- const p = dispatch.workPacket;
59
- return `[NCCGS-DISPATCH:${dispatch.id}]\nBounded repair for task ${task.id}: ${task.contract.objective ?? task.objective ?? dispatch.reason}\n` +
60
- `Packet: ${p.reference.path} sha256=${p.reference.sha256}\nContract: ${dispatch.contractHash}\nStarting source: ${dispatch.snapshot}\n` +
61
- `Problem: ${p.problem}\nChosen solution: ${p.solution}\n` +
62
- p.changes.map(c => `${c.operation ?? "Edit"} ${c.path}: ${c.instruction}`).join("\n") +
63
- `\nContext references: ${JSON.stringify(p.context)}\n` +
64
- `Limits: ${p.budget.workCalls} work tool calls, including at most ${p.budget.readCalls} reads/searches; ${p.budget.durationMs} ms from claim. Separate ${p.budget.handoffCalls} handoff writes. Native turns are separate and are not guaranteed by these counters.\n` +
65
- (p.schemaVersion === 2
66
- ? `Repair profile: ${p.repairType}. Read/Grep/Glob within this project. ${p.repairType === "unity-code" ? "Write/Edit/MultiEdit only the listed source files." : "Write/Edit/MultiEdit only the listed code files. Change serialized assets only through pinned Editor steps; no raw asset or metadata edits."} Never hand-write .meta files. No general shell, MCP, web, nested agents or parameter sweeps.\n` +
67
- (p.sceneSafety ? "Every Editor step first checks all loaded scenes in the same eval. If any scene is dirty, the operation is blocked without saving/discarding it. Return PARTIAL; preserve the attempt and let the owner resolve unsaved work.\n" : "") +
68
- (p.unity.steps.length ? `Pinned Unity capabilities: ${JSON.stringify(p.unity.capabilities)}\nRun these foreground Bash tool inputs once, in order; stop and return PARTIAL on a failed or uncertain step:\n`
69
- : "No Editor steps are reserved; apply only the existing-file code correction.\n") +
70
- p.unity.steps.map(s => JSON.stringify({ command: repairEditorCommand(dispatch, s), timeout: s.timeoutMs + 5000 }) + `\nEditor operation: ${s.command} ${JSON.stringify(s.arguments)}\n`).join("") +
71
- "Finish saving/importing all exact files and their Unity-generated metadata before returning; new paths, deleted files or changed existing GUIDs fail completion. Editor return/exit zero is not verification evidence.\n"
72
- : `Read/Grep/Glob within this project; Write/Edit/MultiEdit only the listed files. No shell, MCP, web, nested agents, or parameter sweeps.\n`) +
73
- `Handoff: ${dispatch.handoffPaths[0]}. Write NCCGS-HANDOFF: PARTIAL early, then replace with NCCGS-HANDOFF: COMPLETE only when these edits are finished. Include changed files, rationale, unverified checks, risks and next owner. Return PARTIAL if the chosen solution needs more investigation.\n` +
74
- `Coordinator runs required checks after return: ${p.verification.join(", ")}. COMPLETE is edit handoff, not acceptance PASS. Do not run or invent verification.\n`;
75
- }
76
-
77
- function toolPath(project, value, rootAllowed = false) {
78
- need(typeof value === "string" && value.length > 0, "Repair tool needs an explicit project path");
79
- const absolute = path.resolve(project, value), relative = path.relative(project, absolute).split(path.sep).join("/");
80
- if (rootAllowed && !relative) return "";
81
- contained(project, relative);
82
- return relative;
83
- }
84
-
85
- // Classifies the request before admission; never executes a tool or command.
86
- export function repairToolScope(project, dispatch, input) {
87
- const tool = input.tool_input ?? {}, name = input.tool_name;
88
- const editor = unityEditorToolScope(dispatch, input);
89
- if (editor) return editor;
90
- if (["Write", "Edit", "MultiEdit"].includes(name)) {
91
- const relative = toolPath(project, tool.file_path);
92
- if (dispatch.handoffPaths.includes(relative)) return { bucket: "handoff", read: false };
93
- need(dispatch.workPacket.repairType !== "unity-editor" || unityCodePath(relative), "Unity assets must be changed through pinned Editor steps, never raw file edits");
94
- need(dispatch.writePaths.includes(relative), "Repair write is outside the packet's exact files");
95
- return { bucket: "work", read: false };
96
- }
97
- if (["Read", "Grep", "Glob"].includes(name)) {
98
- toolPath(project, name === "Read" ? tool.file_path : tool.path ?? project, name !== "Read");
99
- if (name === "Glob" || (name === "Grep" && tool.glob)) {
100
- const glob = name === "Glob" ? tool.pattern : tool.glob;
101
- need(typeof glob === "string" && !path.posix.isAbsolute(glob) && !path.win32.isAbsolute(glob) && !/[\\:\x00-\x1f]/.test(glob) && !glob.includes(".."), "Repair search pattern must stay within the project");
102
- }
103
- return { bucket: "work", read: true };
104
- }
105
- throw new Error("Bounded repair permits only project reads and exact file edits; return the handoff and let the coordinator run declared checks");
106
- }
@@ -1,47 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import { artifact, contained } from "./policy.mjs";
4
- import { nativeCompletion } from "./native-completion.mjs";
5
-
6
- // Opt-in transport for read-only workers whose native client returns reports as
7
- // text. Copy the sole model text block verbatim; never synthesize a verdict,
8
- // COMPLETE marker, identity, missing content or a replacement for an old attempt.
9
- export function captureReturnedHandoff(project, dispatch, input, completion, currentSnapshot) {
10
- if (dispatch?.handoffTransport !== "native-result") return null;
11
- const reject = reason => ({ transport: "native-result", status: "rejected", reason });
12
- const response = input.tool_response;
13
- if (input.hook_event_name !== "PostToolUse" || !["Agent", "Task"].includes(input.tool_name)
14
- || dispatch.status !== "running" || !["analysis", "review"].includes(dispatch.kind)
15
- || dispatch.sessionId !== input.session_id || dispatch.toolUseId !== input.tool_use_id
16
- || !dispatch.agentId || dispatch.agentId !== response?.agentId
17
- || dispatch.agent !== input.tool_input?.subagent_type || dispatch.snapshot !== currentSnapshot)
18
- return reject("identity-or-snapshot-mismatch");
19
- // Preserve an upstream failure and independently classify the actual response.
20
- // A caller-supplied completion cannot certify unknown or incomplete metadata.
21
- if (completion?.status !== "completed" || completion.reason)
22
- return reject("native-incomplete");
23
- const actual = nativeCompletion(response);
24
- if (actual.status !== "completed" || actual.reason) return reject("native-incomplete");
25
- // Classification validates every designated note and both counts. Strip only
26
- // those blocks; model text, including lookalike tags, remains byte-for-byte.
27
- const all = response.content;
28
- const leading = response.harnessNoteCount ?? 0, tail = response.harnessTailCount ?? 0;
29
- const blocks = Array.isArray(all) ? all.slice(leading, all.length - tail) : null;
30
- if (!Array.isArray(blocks) || blocks.length !== 1 || blocks[0]?.type !== "text"
31
- || typeof blocks[0].text !== "string" || !blocks[0].text.trim()
32
- || Buffer.byteLength(blocks[0].text, "utf8") > 262144)
33
- return reject("expected-one-bounded-text-block");
34
- if (dispatch.handoffPaths?.length !== 1) return reject("expected-one-pinned-handoff");
35
- const relative = dispatch.handoffPaths[0];
36
- try {
37
- const file = contained(project, relative);
38
- fs.mkdirSync(path.dirname(file), { recursive: true });
39
- // Revalidate newly created parents and refuse symlinks, existing drafts or
40
- // concurrent writes. Existing file transport retains its original behavior.
41
- contained(project, relative);
42
- fs.writeFileSync(file, blocks[0].text, { flag: "wx" });
43
- return { transport: "native-result", status: "captured", evidence: artifact(project, relative) };
44
- } catch (error) {
45
- return reject(error.code === "EEXIST" ? "handoff-already-exists" : "handoff-publication-failed");
46
- }
47
- }
@@ -1,171 +0,0 @@
1
- import fs from "node:fs";
2
- import { artifact, atomicJson, contained, hash, json, verifyArtifact } from "./policy.mjs";
3
- import { acquireLock, ownerState, pidState } from "./process-lock.mjs";
4
- import { sessionBudgetLock, settledCost, taskWithin } from "./session-budget.mjs";
5
-
6
- const need = (ok, message) => { if (!ok) throw new Error(`Review reserve: ${message}`); };
7
- const taskFile = (project, id) => {
8
- need(typeof id === "string" && /^[a-zA-Z0-9][\w-]{0,79}$/.test(id), "invalid task ID");
9
- return contained(project, `.nccgs/tasks/${id}.json`);
10
- };
11
- const planPath = id => `.nccgs/budgets/${id}.json`;
12
- const markerPath = id => `.nccgs/budgets/${id}.initialized.json`;
13
- const terms = plan => ({ schemaVersion: plan.schemaVersion, taskId: plan.taskId, limits: plan.limits,
14
- request: plan.request, createdAt: plan.createdAt, deadline: plan.deadline, workDeadline: plan.workDeadline });
15
- function readPlan(project, id) {
16
- const file = contained(project, planPath(id)), marker = contained(project, markerPath(id));
17
- if (!fs.existsSync(file)) { need(!fs.existsSync(marker), "initialized budget history is missing; never reset it"); return null; }
18
- const plan = json(file);
19
- need(plan.schemaVersion === 1 && plan.taskId === id && Array.isArray(plan.allocations), "invalid budget plan");
20
- need(fs.existsSync(marker) && json(marker).sha256 === hash(JSON.stringify(terms(plan))), "pinned budget terms changed or marker missing");
21
- verifyArtifact(project, plan.request);
22
- return plan;
23
- }
24
- export function findReviewBudget(project, id) {
25
- const seen = new Set(); let found = null;
26
- while (id) {
27
- need(!seen.has(id), "task ancestry cycle"); seen.add(id);
28
- const task = json(taskFile(project, id)), plan = readPlan(project, id);
29
- need(!plan || !found, "nested budgets cannot mint another reserve");
30
- if (plan) found = plan;
31
- id = task.parentId;
32
- }
33
- return found;
34
- }
35
- function familyRuns(project, id) {
36
- const dir = contained(project, ".nccgs/runs");
37
- if (!fs.existsSync(dir)) return [];
38
- return fs.readdirSync(dir, { withFileTypes: true }).filter(e => e.isDirectory()).map(e => {
39
- const run = json(contained(project, `.nccgs/runs/${e.name}/run.json`));
40
- need(run.id === e.name && run.project === project, "invalid native run history"); return run;
41
- }).filter(run => taskWithin(project, run.taskId, id));
42
- }
43
- function requireWorkerCoverage(project, id, runs, ledger = null) {
44
- const file = contained(project, ".nccgs/orchestration.json");
45
- ledger ??= fs.existsSync(file) ? json(file) : null;
46
- const sessions = new Set(runs.map(run => run.sessionId));
47
- need(sessions.size === runs.length, "duplicate session across run records");
48
- const workers = Object.values(ledger?.dispatches ?? {}).filter(d => d.startedAt && taskWithin(project, d.taskId, id));
49
- need(workers.every(d => sessions.has(d.sessionId)), "worker session has no supervised cost coverage; preserve and reconcile historical spend");
50
- }
51
- function history(project, plan, currentId = null) {
52
- const records = plan.allocations.map(ref => ({ ...json(verifyArtifact(project, ref)), reference: ref }));
53
- need(new Set(records.map(r => r.runId)).size === records.length, "duplicate run allocation");
54
- const runs = familyRuns(project, plan.taskId), ids = new Set(runs.map(r => r.id));
55
- requireWorkerCoverage(project, plan.taskId, runs);
56
- need(records.every(r => ids.has(r.runId)), "allocated run history is missing; spent allowances cannot be refunded");
57
- const neverStarted = r => r.status === "blocked" && r.costCoverage === "complete" && r.invocations.length === 0 && r.cumulativeCostUsd === 0;
58
- need(runs.every(r => r.id === currentId || records.some(a => a.runId === r.id) || neverStarted(r)), "unallocated native session; reconcile history before spending");
59
- let workUsd = 0, reviewUsd = 0;
60
- const sessions = [];
61
- for (const run of runs.filter(r => r.id !== currentId)) {
62
- const allocation = records.find(r => r.runId === run.id);
63
- if (!allocation && neverStarted(run)) { sessions.push({ runId: run.id, sessionId: run.sessionId, phase: "not-started", costUsd: 0 }); continue; }
64
- need(allocation.sessionId === run.sessionId && ["work", "final-review"].includes(allocation.phase), "allocation identity mismatch");
65
- if (!allocation.legacy) need(run.budgetAllocation?.sha256 === allocation.reference.sha256, "native run allocation changed");
66
- const cost = settledCost(project, run);
67
- if (allocation.phase === "final-review") reviewUsd += cost; else workUsd += cost;
68
- sessions.push({ runId: run.id, sessionId: run.sessionId, phase: allocation.phase, costUsd: cost });
69
- }
70
- return { records, sessions, workUsd, reviewUsd, totalUsd: workUsd + reviewUsd };
71
- }
72
- export function registerReviewBudget(project, id, relative) {
73
- need(!process.env.CLAUDECODE && !process.env.CLAUDE_CODE_ENTRYPOINT, "budget allocation is external only");
74
- const lock = acquireLock(contained(project, sessionBudgetLock), { operation: "register-review-reserve", taskId: id });
75
- try {
76
- const task = json(taskFile(project, id)), request = artifact(project, relative), input = json(verifyArtifact(project, request));
77
- need(task.schemaVersion === 2 && !task.closed, "an open standalone root task is required");
78
- const existing = findReviewBudget(project, id);
79
- if (existing) { need(existing.taskId === id && existing.request.sha256 === request.sha256, "budget terms are already pinned; no replacement or extension"); return existing; }
80
- need(!task.parentId, "register the reserve on the existing task root, never on a child");
81
- need(input.schemaVersion === 1 && typeof input.authority === "string" && input.authority.trim(), "explicit external allocation authority is required");
82
- const { totalUsd, finalReviewUsd, totalDurationMs, finalReviewDurationMs } = input;
83
- need(Number.isFinite(totalUsd) && totalUsd > 0 && Number.isFinite(finalReviewUsd) && finalReviewUsd > 0 && finalReviewUsd < totalUsd, "invalid total/review cost allocation");
84
- need(Number.isSafeInteger(totalDurationMs) && totalDurationMs >= 1000 && totalDurationMs <= 86400000
85
- && Number.isSafeInteger(finalReviewDurationMs) && finalReviewDurationMs >= 1000 && finalReviewDurationMs < totalDurationMs, "invalid total/review time allocation");
86
- const ledgerFile = contained(project, ".nccgs/orchestration.json"), ledger = fs.existsSync(ledgerFile) ? json(ledgerFile) : null;
87
- need(!Object.values(ledger?.dispatches ?? {}).some(d => ["reserved", "running", "uncertain"].includes(d.status)), "settle all workers before allocating a reserve");
88
- const pinned = ledger?.tasks[id]?.limits.maxCostUsd;
89
- need(pinned == null || totalUsd <= pinned, "allocation cannot raise the pinned aggregate cap");
90
- const prior = familyRuns(project, id);
91
- requireWorkerCoverage(project, id, prior, ledger);
92
- const spent = prior.reduce((sum, run) => sum + settledCost(project, run), 0);
93
- need(spent < totalUsd - finalReviewUsd, "past spending leaves insufficient work/review reserve; cannot reserve spent money retroactively");
94
- const createdAt = new Date().toISOString();
95
- const deadline = prior.length ? Math.min(Date.now() + totalDurationMs, Math.max(...prior.map(r => r.deadline))) : Date.now() + totalDurationMs;
96
- const workDeadline = deadline - finalReviewDurationMs;
97
- need(Date.now() < workDeadline, "past elapsed time leaves no protected review window");
98
- const plan = { schemaVersion: 1, taskId: id, request, limits: { totalUsd, finalReviewUsd, totalDurationMs, finalReviewDurationMs },
99
- createdAt, deadline, workDeadline, allocations: [] };
100
- for (const run of prior) {
101
- const file = `.nccgs/budgets/allocations/${run.id}.json`;
102
- atomicJson(contained(project, file), { runId: run.id, sessionId: run.sessionId, taskId: run.taskId, phase: "work", legacy: true, recordedAt: createdAt });
103
- plan.allocations.push(artifact(project, file));
104
- }
105
- atomicJson(contained(project, markerPath(id)), { sha256: hash(JSON.stringify(terms(plan))) });
106
- atomicJson(contained(project, planPath(id)), plan);
107
- return plan;
108
- } finally { lock.release(); }
109
- }
110
- export function allocateReviewBudget(project, state, phase = "work") {
111
- const plan = findReviewBudget(project, state.taskId);
112
- if (!plan) { need(phase === "work", "final-review needs a pinned aggregate reserve"); return null; }
113
- need(["work", "final-review"].includes(phase), "unknown budget phase");
114
- const lock = json(contained(project, sessionBudgetLock));
115
- need(lock.runId === state.id && lock.sessionId === state.sessionId && ownerState(lock) === "alive", "exclusive supervisor ownership is required");
116
- const task = json(taskFile(project, state.taskId));
117
- need(phase !== "final-review" || ["implement", "audit"].includes(task.mode), "design review cannot consume the final delivery reserve");
118
- const prior = history(project, plan, state.id), existing = prior.records.find(a => a.runId === state.id);
119
- const available = phase === "work"
120
- ? plan.limits.totalUsd - prior.workUsd - Math.max(plan.limits.finalReviewUsd, prior.reviewUsd)
121
- : plan.limits.totalUsd - prior.totalUsd;
122
- const deadline = phase === "work" ? plan.workDeadline : plan.deadline;
123
- need(available > 0 && Date.now() < deadline, "phase allowance exhausted; retain the final review reserve and original total");
124
- if (existing) {
125
- need(existing.phase === phase && state.budgetAllocation?.sha256 === existing.reference.sha256
126
- && state.budgetUsd === existing.allowanceUsd && state.deadline === existing.deadline, "recovery cannot alter the allocated phase, cost or deadline");
127
- need(state.budgetUsd <= available + 1e-9 && state.deadline <= deadline && Date.now() < state.deadline, "historical spending/time no longer covers this allocation");
128
- return existing;
129
- }
130
- const requestedUsd = state.budgetUsd, requestedDeadline = state.deadline;
131
- state.budgetUsd = Math.min(requestedUsd, available); state.deadline = Math.min(requestedDeadline, deadline); state.budgetPhase = phase;
132
- const value = { schemaVersion: 1, rootTaskId: plan.taskId, taskId: state.taskId, runId: state.id, sessionId: state.sessionId,
133
- phase, requestedUsd, allowanceUsd: state.budgetUsd, requestedDeadline, deadline: state.deadline,
134
- recordedAt: new Date().toISOString(), priorSessions: prior.sessions, protectedReviewUsd: Math.max(0, plan.limits.finalReviewUsd - prior.reviewUsd),
135
- workerCostInferred: false };
136
- const file = `.nccgs/budgets/allocations/${state.id}.json`;
137
- need(!fs.existsSync(contained(project, file)), "allocation already exists; preserve interrupted history");
138
- atomicJson(contained(project, file), value); state.budgetAllocation = artifact(project, file);
139
- plan.allocations.push(state.budgetAllocation); atomicJson(contained(project, planPath(plan.taskId)), plan);
140
- return value;
141
- }
142
- export function plannedDispatchBudget(project, id, request) {
143
- const plan = findReviewBudget(project, id); if (!plan) return null;
144
- const runId = process.env.NCCGS_SUPERVISED_RUN;
145
- need(typeof runId === "string" && /^[a-f0-9-]{36}$/.test(runId), "planned tasks require their supervised allocation");
146
- const state = json(contained(project, `.nccgs/runs/${runId}/run.json`));
147
- need(state.taskId === id && state.sessionId === process.env.NCCGS_SUPERVISED_SESSION && state.status === "running"
148
- && pidState(state.invocations.at(-1)?.pid) === "alive", "current allocated native session is not live/correlated");
149
- const allocation = allocateReviewBudget(project, state, state.budgetPhase);
150
- const task = json(taskFile(project, id));
151
- if (allocation.phase === "final-review") need(request.kind === "review" && ["implement", "audit"].includes(task.mode), "final-review funds cannot dispatch implementation, repair, analysis or design workers");
152
- else need(request.kind !== "review" || !["implement", "audit"].includes(task.mode), "delivery/audit review must use the protected final-review phase");
153
- return { ...allocation, reference: state.budgetAllocation };
154
- }
155
- export function inFinalReviewPhase(project, sessionId) {
156
- const id = process.env.NCCGS_SUPERVISED_RUN; if (!id) return false;
157
- need(/^[a-f0-9-]{36}$/.test(id), "invalid supervised run ID");
158
- const run = json(contained(project, `.nccgs/runs/${id}/run.json`));
159
- need(run.sessionId === sessionId, "supervised session mismatch");
160
- return run.budgetPhase === "final-review";
161
- }
162
- export function reviewBudgetStatus(project, id) {
163
- const plan = findReviewBudget(project, id); if (!plan) return { taskId: id, planned: false };
164
- const live = familyRuns(project, plan.taskId).filter(r => ["ready", "running", "waiting-for-verification"].includes(r.status));
165
- need(live.length <= 1, "multiple unresolved native allocations");
166
- const current = process.env.NCCGS_SUPERVISED_RUN ?? live[0]?.id ?? null, prior = history(project, plan, current);
167
- return { taskId: id, planned: true, rootTaskId: plan.taskId, limits: plan.limits, deadline: plan.deadline, workDeadline: plan.workDeadline,
168
- settledSessions: prior.sessions, settledCostUsd: prior.totalUsd, protectedReviewUsd: Math.max(0, plan.limits.finalReviewUsd - prior.reviewUsd),
169
- currentAllocation: prior.records.find(a => a.runId === current) ?? null,
170
- note: "In-flight actual cost remains unknown; the current allocation is a ceiling, never a worker cost or acceptance result." };
171
- }