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.
- package/CHANGELOG.md +76 -235
- package/LICENSE +1 -1
- package/README.md +87 -206
- package/THIRD_PARTY_NOTICES.md +6 -34
- package/bin/nccgs.mjs +96 -0
- package/cli/doctor.mjs +82 -0
- package/cli/feedback.mjs +13 -0
- package/cli/install.mjs +111 -0
- package/cli/release.mjs +59 -0
- package/cli/run.mjs +35 -0
- package/cli/spawn.mjs +20 -0
- package/cli/uninstall.mjs +43 -0
- package/cli/update-check.mjs +66 -0
- package/docs/EVIDENCE-VERIFICATION.md +22 -0
- package/package.json +23 -30
- package/runtime/core/diag.mjs +43 -0
- package/runtime/core/feedback-policy.mjs +54 -0
- package/runtime/core/fs.mjs +80 -0
- package/runtime/core/job-object.mjs +73 -0
- package/runtime/core/modes.mjs +87 -0
- package/runtime/core/process-tree.mjs +109 -0
- package/runtime/core/project.mjs +113 -0
- package/runtime/core/snapshot.mjs +114 -0
- package/runtime/hooks/common.mjs +22 -0
- package/runtime/hooks/done-guard.mjs +15 -0
- package/runtime/hooks/guard-mcp.mjs +8 -0
- package/runtime/hooks/guard-shell.mjs +16 -0
- package/runtime/hooks/guard-write.mjs +25 -0
- package/runtime/hooks/session-log.mjs +7 -0
- package/runtime/hooks/session-start.mjs +40 -0
- package/runtime/hooks/unity-transport.mjs +12 -0
- package/runtime/modes.json +39 -0
- package/runtime/task/cost.mjs +103 -0
- package/runtime/task/criteria.mjs +128 -0
- package/runtime/task/feedback.mjs +136 -0
- package/runtime/task/ledger.mjs +109 -0
- package/runtime/task/plan.mjs +69 -0
- package/runtime/task/project.mjs +79 -0
- package/runtime/task/report.mjs +252 -0
- package/runtime/task/task.mjs +238 -0
- package/runtime/unity/assets.mjs +51 -0
- package/runtime/unity/playtest.mjs +145 -0
- package/runtime/unity/unity.mjs +350 -0
- package/scripts/check-job-object.mjs +18 -0
- package/scripts/sync-unity-skills.mjs +35 -119
- package/template/CLAUDE.md +39 -0
- package/template/agents/fast-fix.md +9 -0
- package/template/agents/implementer.md +19 -0
- package/template/agents/playtester.md +15 -0
- package/template/agents/reviewer.md +19 -0
- package/template/agents/scout.md +9 -0
- package/template/ponytail/README.md +8 -0
- package/{.claude/nccgs/packages → template}/ponytail/engineering.md +10 -0
- package/template/protocols/evidence.md +52 -0
- package/template/protocols/playtest.md +45 -0
- package/template/protocols/review.md +34 -0
- package/template/protocols/unity-cli-notes.md +56 -0
- package/template/settings.fragment.json +33 -0
- package/template/skills/art-bible/SKILL.md +19 -0
- package/template/skills/asset-spec/SKILL.md +19 -0
- package/template/skills/brainstorm/SKILL.md +17 -0
- package/template/skills/feedback/SKILL.md +16 -0
- package/template/skills/map-systems/SKILL.md +25 -0
- package/template/skills/playtest/SKILL.md +17 -0
- package/template/skills/status/SKILL.md +18 -0
- package/template/skills/test/SKILL.md +34 -0
- package/template/skills/unity-foundation/SKILL.md +17 -0
- package/template/skills/vertical-slice/SKILL.md +17 -0
- package/template/skills/work/SKILL.md +65 -0
- package/tools/feedback-worker/README.md +12 -0
- package/tools/feedback-worker/worker.js +39 -0
- package/tools/feedback-worker/wrangler.toml +12 -0
- package/unity-skills/2d-pixel-perfect/SKILL.md +208 -0
- package/unity-skills/2d-pixel-perfect/references/api-reference.md +81 -0
- package/unity-skills/2d-pixel-perfect/references/camera-setup-builtin.cs +40 -0
- package/unity-skills/2d-pixel-perfect/references/camera-setup-urp.cs +49 -0
- package/unity-skills/2d-pixel-perfect/references/pipeline-detection.cs +50 -0
- package/unity-skills/2d-pixel-perfect/references/sprite-settings.cs +37 -0
- package/unity-skills/asset-transformer-toolkit/SECURITY.md +15 -0
- package/unity-skills/asset-transformer-toolkit/SKILL.md +39 -0
- package/unity-skills/asset-transformer-toolkit/references/create-importer.md +121 -0
- package/unity-skills/asset-transformer-toolkit/references/lods.md +61 -0
- package/unity-skills/asset-transformer-toolkit/references/rule-api.md +154 -0
- package/unity-skills/asset-transformer-toolkit/references/ruleblock-api.md +37 -0
- package/unity-skills/asset-transformer-toolkit/references/ruleset-api.md +138 -0
- package/unity-skills/asset-transformer-toolkit/references/rulesets-and-actions.md +227 -0
- package/unity-skills/audio-setup-mixers/SECURITY.md +16 -0
- package/unity-skills/audio-setup-mixers/SKILL.md +127 -0
- package/unity-skills/audio-setup-mixers/references/api.md +162 -0
- package/unity-skills/build-gtk/SKILL.md +242 -0
- package/unity-skills/build-gtk/references/graph-api.md +324 -0
- package/unity-skills/build-gtk/references/pitfalls.md +86 -0
- package/unity-skills/build-gtk/references/runtime-and-visualization.md +196 -0
- package/unity-skills/build-gtk/references/state-machine-api.md +286 -0
- package/unity-skills/build-live-game/SKILL.md +255 -0
- package/{.claude/skills → unity-skills}/build-live-game/references/achievements.md +132 -154
- package/{.claude/skills → unity-skills}/build-live-game/references/apis.md +10 -19
- package/{.claude/skills → unity-skills}/build-live-game/references/authentication.md +14 -20
- package/{.claude/skills → unity-skills}/build-live-game/references/battlepass.md +269 -225
- package/unity-skills/build-live-game/references/blueprints-and-samples.md +75 -0
- package/unity-skills/build-live-game/references/cloud-code-cloudbehaviours.md +1111 -0
- package/unity-skills/build-live-game/references/cloud-code-modules.md +1276 -0
- package/unity-skills/build-live-game/references/cloud-code.md +58 -0
- package/{.claude/skills → unity-skills}/build-live-game/references/cloud-save.md +15 -25
- package/{.claude/skills → unity-skills}/build-live-game/references/deployment.md +33 -18
- package/{.claude/skills → unity-skills}/build-live-game/references/player-account.md +31 -23
- package/{.claude/skills → unity-skills}/build-live-game/references/tooling.md +0 -56
- package/unity-skills/build-live-game/references/ugs-cli.md +86 -0
- package/unity-skills/craft-game-floors/SECURITY.md +23 -0
- package/unity-skills/craft-game-floors/SKILL.md +134 -0
- package/unity-skills/craft-game-floors/references/art-direction.md +85 -0
- package/unity-skills/craft-game-floors/references/camera-rigs.md +51 -0
- package/unity-skills/craft-game-floors/references/character-motion.md +35 -0
- package/unity-skills/craft-game-floors/references/game-audio.md +47 -0
- package/unity-skills/craft-game-floors/references/game-feel.md +68 -0
- package/unity-skills/craft-game-floors/references/game-shell.md +45 -0
- package/unity-skills/craft-game-floors/references/live-floor.md +35 -0
- package/unity-skills/craft-game-floors/references/placeholder-assets.md +35 -0
- package/unity-skills/craft-game-floors/references/scene-lighting.md +52 -0
- package/unity-skills/craft-game-floors/references/toon-shading.md +34 -0
- package/unity-skills/craft-game-floors/references/vfx.md +40 -0
- package/unity-skills/craft-game-floors/references/visual-scorecard.md +43 -0
- package/unity-skills/create-2d-physics/SECURITY.md +16 -0
- package/unity-skills/create-2d-physics/SKILL.md +128 -0
- package/unity-skills/create-2d-physics/references/2d-physics-core.md +155 -0
- package/unity-skills/create-2d-physics/references/legacy-2d-physics.md +45 -0
- package/unity-skills/create-tile-palette-or-rule-tiles/SKILL.md +12 -0
- package/unity-skills/create-tile-palette-or-rule-tiles/references/hexagonalruletile.md +71 -0
- package/unity-skills/create-tile-palette-or-rule-tiles/references/palette-create.md +38 -0
- package/unity-skills/create-tile-palette-or-rule-tiles/references/ruletile-createempty.md +35 -0
- package/unity-skills/create-tile-palette-or-rule-tiles/references/ruletile-createfromsegment.md +212 -0
- package/unity-skills/create-tile-palette-or-rule-tiles/references/ruletile.md +90 -0
- package/unity-skills/create-tile-palette-or-rule-tiles/scripts/CreatePaletteTemplate.cs +148 -0
- package/unity-skills/create-tile-palette-or-rule-tiles/scripts/ManualWorkflowExample.cs +63 -0
- package/unity-skills/create-tile-palette-or-rule-tiles/scripts/RuleTileGenerator.cs +61 -0
- package/unity-skills/create-tile-palette-or-rule-tiles/scripts/TilemapRuleTileCreateFromSegment.cs +225 -0
- package/unity-skills/generate-editor-search-query/SECURITY.md +17 -0
- package/unity-skills/generate-editor-search-query/SKILL.md +117 -0
- package/unity-skills/generate-editor-search-query/references/open-search-window.md +70 -0
- package/unity-skills/generate-editor-search-query/references/query-patterns.md +124 -0
- package/{.claude/skills → unity-skills}/implement-in-app-purchases/SKILL.md +1 -2
- package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/api-notes.md +25 -28
- package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/path-convert-native-google-billing.md +1 -1
- package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/path-implement-iap-d2c.md +40 -5
- package/{.claude/skills → unity-skills}/initialize-ai-navigation/SKILL.md +4 -4
- package/{.claude/skills → unity-skills}/initialize-ai-navigation/references/navigation-system.md +3 -3
- package/{.claude/skills → unity-skills}/levelplay-unity-integration/CHANGELOG.md +12 -0
- package/{.claude/skills → unity-skills}/levelplay-unity-integration/README.md +9 -5
- package/unity-skills/levelplay-unity-integration/SKILL.md +442 -0
- package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/banner-api.md +15 -8
- package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/best-practices.md +604 -536
- package/unity-skills/levelplay-unity-integration/references/dependency-resolution.md +94 -0
- package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/ilrd-api.md +2 -2
- package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/initialization-api.md +221 -0
- package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/interstitial-api.md +11 -3
- package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/ios-setup.md +6 -34
- package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/migration-sdk-9.md +1 -1
- package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/privacy-settings.md +14 -29
- package/{.claude/skills → unity-skills}/levelplay-unity-integration/references/rewarded-api.md +20 -4
- package/unity-skills/levelplay-unity-integration/references/testing-and-validation.md +222 -0
- package/unity-skills/levelplay-unity-integration/references/troubleshooting.md +99 -0
- package/unity-skills/localization/SKILL.md +347 -0
- package/{.claude/skills → unity-skills}/localization/references/api-notes.md +4 -0
- package/unity-skills/localization/resources/L10nBatchProcessor.cs +191 -0
- package/unity-skills/manage-sprite-atlas/SKILL.md +351 -0
- package/unity-skills/manage-sprite-atlas/references/addressables-delivery.md +58 -0
- package/unity-skills/manage-sprite-atlas/references/api.md +382 -0
- package/unity-skills/manage-sprite-atlas/references/best-practices.md +183 -0
- package/unity-skills/manage-sprite-atlas/references/common-errors.md +123 -0
- package/unity-skills/manage-sprite-atlas/references/custom-packing.md +147 -0
- package/unity-skills/manage-sprite-atlas/references/manual-authoring.md +39 -0
- package/unity-skills/manage-sprite-atlas/resources/authoringvsruntime.cs +176 -0
- package/unity-skills/manage-sprite-atlas/resources/buildaddressablespostprocess.cs +59 -0
- package/unity-skills/manage-sprite-atlas/resources/cacheloadedatlases.cs +145 -0
- package/unity-skills/manage-sprite-atlas/resources/cleanupbatchoperations.cs +119 -0
- package/unity-skills/manage-sprite-atlas/resources/createandconfiguremasteratlas.cs +57 -0
- package/unity-skills/manage-sprite-atlas/resources/custompackersetup.cs +88 -0
- package/unity-skills/manage-sprite-atlas/resources/deprecatedmethods.cs +142 -0
- package/unity-skills/manage-sprite-atlas/resources/dontmodifywithoutsaving.cs +120 -0
- package/unity-skills/manage-sprite-atlas/resources/dontpackinruntimebuilds.cs +190 -0
- package/unity-skills/manage-sprite-atlas/resources/dontscriptspriteatlasineditor.cs +114 -0
- package/unity-skills/manage-sprite-atlas/resources/editorconfiguration.cs +95 -0
- package/unity-skills/manage-sprite-atlas/resources/enablespritepacking.cs +172 -0
- package/unity-skills/manage-sprite-atlas/resources/gridspritepacker.cs +50 -0
- package/unity-skills/manage-sprite-atlas/resources/handlelatebinding.cs +147 -0
- package/unity-skills/manage-sprite-atlas/resources/handlenullcases.cs +141 -0
- package/unity-skills/manage-sprite-atlas/resources/migratev1tov2.cs +335 -0
- package/unity-skills/manage-sprite-atlas/resources/multipagepacker.cs +80 -0
- package/unity-skills/manage-sprite-atlas/resources/optimizetexturesettings.cs +191 -0
- package/unity-skills/manage-sprite-atlas/resources/packerdebugging.cs +158 -0
- package/unity-skills/manage-sprite-atlas/resources/packtransform.cs +51 -0
- package/unity-skills/manage-sprite-atlas/resources/platformnames.cs +127 -0
- package/unity-skills/manage-sprite-atlas/resources/queryspritesefficiently.cs +222 -0
- package/unity-skills/manage-sprite-atlas/resources/registercallbacks.cs +152 -0
- package/unity-skills/manage-sprite-atlas/resources/runtimeatlasloader.cs +15 -0
- package/unity-skills/manage-sprite-atlas/resources/runtimespriteaccess.cs +19 -0
- package/unity-skills/manage-sprite-atlas/resources/savespriteatlasasset.cs +107 -0
- package/unity-skills/manage-sprite-atlas/resources/scriptablepacker.cs +81 -0
- package/unity-skills/manage-sprite-atlas/resources/setincludeinbuild.cs +164 -0
- package/unity-skills/manage-sprite-atlas/resources/sizeoptimizedpacker.cs +88 -0
- package/unity-skills/manage-sprite-atlas/resources/spriteatlaslatebinding.cs +123 -0
- package/unity-skills/manage-sprite-atlas/resources/spriteatlasprebuildgenerator.cs +219 -0
- package/unity-skills/manage-sprite-atlas/resources/spritedata.cs +35 -0
- package/unity-skills/manage-sprite-atlas/resources/spritepack.cs +39 -0
- package/unity-skills/manage-sprite-atlas/resources/texturedata.cs +15 -0
- package/unity-skills/manage-sprite-atlas/resources/updatebuildscripts.cs +357 -0
- package/unity-skills/manage-sprite-atlas/resources/updatesettingsconfiguration.cs +135 -0
- package/unity-skills/manage-sprite-atlas/resources/usevariantswisely.cs +179 -0
- package/unity-skills/manage-sprite-atlas/resources/variantatlas.cs +39 -0
- package/unity-skills/manifest.json +1155 -0
- package/unity-skills/migrate-birp-to-urp/SECURITY.md +16 -0
- package/unity-skills/migrate-birp-to-urp/SKILL.md +543 -0
- package/unity-skills/migrate-birp-to-urp/references/capturing-the-editor.md +66 -0
- package/unity-skills/migrate-birp-to-urp/references/complex-shader-situations.md +272 -0
- package/unity-skills/migrate-birp-to-urp/references/custom-shader-triage.md +123 -0
- package/unity-skills/migrate-birp-to-urp/references/implementation-patterns.md +529 -0
- package/unity-skills/migrate-birp-to-urp/references/migration-workflow.md +265 -0
- package/unity-skills/migrate-birp-to-urp/references/quality-settings-map.md +69 -0
- package/unity-skills/new-unity-project/SECURITY.md +26 -0
- package/unity-skills/new-unity-project/SKILL.md +386 -0
- package/unity-skills/new-unity-project/references/skill-setup.md +66 -0
- package/unity-skills/optimize-audio/SECURITY.md +16 -0
- package/{.claude/skills → unity-skills}/optimize-audio/SKILL.md +17 -17
- package/{.claude/skills → unity-skills}/optimize-audio/resources/audio-import-api.md +8 -5
- package/{.claude/skills → unity-skills}/optimize-text-mesh-pro/SKILL.md +1 -11
- package/unity-skills/optimize-web/SECURITY.md +16 -0
- package/{.claude/skills → unity-skills}/optimize-web/SKILL.md +164 -27
- package/unity-skills/optimize-web/scripts/WebOptimizer.cs +46 -0
- package/unity-skills/optimize-web/scripts/toktx-examples.sh +11 -0
- package/{.claude/skills → unity-skills}/physics-3d-collision/SKILL.md +2 -2
- package/unity-skills/physics-3d-collision/references/troubleshooting.md +8 -0
- package/unity-skills/project-auditor-fixes/SKILL.md +64 -0
- package/{.claude/skills → unity-skills}/setup-multiplayer-services/SKILL.md +1 -4
- package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/SKILL.md +1 -1
- package/{.claude/skills → unity-skills}/shader-graph-create-custom-node/SKILL.md +1 -1
- package/unity-skills/sprite-editor/SECURITY.md +16 -0
- package/{.claude/skills → unity-skills}/sprite-editor/SKILL.md +9 -9
- package/{.claude/skills → unity-skills}/sprite-editor/references/templates.md +1 -1
- package/unity-skills/sprite-segment-3x3grid/SKILL.md +136 -0
- package/unity-skills/sprite-segment-3x3grid/scripts/SpriteGridAnalysis.cs +119 -0
- package/{.claude/skills → unity-skills}/ui/SKILL.md +1 -1
- package/{.claude/skills → unity-skills}/ui-imgui/SKILL.md +1 -7
- package/{.claude/skills → unity-skills}/ui-ugui/SKILL.md +3 -9
- package/{.claude/skills → unity-skills}/ui-uitk/SKILL.md +8 -14
- package/{.claude/skills → unity-skills}/ui-uitk/references/custom-elements.md +1 -1
- package/unity-skills/unity-cli/CHANGELOG.md +515 -0
- package/unity-skills/unity-cli/SECURITY.md +68 -0
- package/unity-skills/unity-cli/SKILL.md +723 -0
- package/unity-skills/unity-cli/references/auth-license-cloud.md +318 -0
- package/unity-skills/unity-cli/references/build-run-test.md +555 -0
- package/unity-skills/unity-cli/references/cloud-automation.md +736 -0
- package/{.claude/skills → unity-skills}/unity-cli/references/collaboration.md +166 -105
- package/unity-skills/unity-cli/references/config-hub.md +239 -0
- package/unity-skills/unity-cli/references/diagnostics-maintenance.md +720 -0
- package/unity-skills/unity-cli/references/docs-workflow.md +179 -0
- package/unity-skills/unity-cli/references/editors-install.md +476 -0
- package/unity-skills/unity-cli/references/integration-advanced.md +1130 -0
- package/unity-skills/unity-cli/references/playmode-verification-loop.md +279 -0
- package/unity-skills/unity-cli/references/projects-templates.md +996 -0
- package/unity-skills/unity-cli/references/version-control.md +612 -0
- package/{.claude/skills → unity-skills}/unity-package-management/SKILL.md +60 -12
- package/{.claude/skills → unity-skills}/unity-package-management/references/select-packages.md +39 -21
- package/unity-skills/unity-pipeline/SECURITY.md +17 -0
- package/unity-skills/unity-pipeline/SKILL.md +335 -0
- package/unity-skills/urp-postprocessing/SECURITY.md +16 -0
- package/{.claude/skills → unity-skills}/urp-postprocessing/SKILL.md +12 -12
- package/{.claude/skills → unity-skills}/urp-postprocessing/references/code-templates.md +39 -8
- package/{.claude/skills → unity-skills}/validate-urp-render-graph-renderer-feature/SKILL.md +1 -1
- package/.claude/agents/nccgs-adversarial-reviewer.md +0 -43
- package/.claude/agents/nccgs-engine-programmer.md +0 -27
- package/.claude/agents/nccgs-fast-implementer.md +0 -30
- package/.claude/agents/nccgs-game-designer.md +0 -26
- package/.claude/agents/nccgs-gameplay-programmer.md +0 -26
- package/.claude/agents/nccgs-qa-engineer.md +0 -27
- package/.claude/agents/nccgs-task-scout.md +0 -24
- package/.claude/agents/nccgs-ui-programmer.md +0 -27
- package/.claude/agents/nccgs-unity-build-specialist.md +0 -27
- package/.claude/agents/nccgs-unity-implementer.md +0 -28
- package/.claude/agents/nccgs-unity-systems-specialist.md +0 -27
- package/.claude/agents/nccgs-unity-ui-specialist.md +0 -27
- package/.claude/agents/nccgs-verification-engineer.md +0 -27
- package/.claude/nccgs/MEMORY.md +0 -66
- package/.claude/nccgs/THIRD_PARTY_NOTICES.md +0 -29
- package/.claude/nccgs/VERSION +0 -1
- package/.claude/nccgs/agent-library/nccgs-accessibility-specialist.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-adversarial-reviewer.md +0 -41
- package/.claude/nccgs/agent-library/nccgs-ai-programmer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-analytics-engineer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-art-direction-lead.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-audio-direction-lead.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-creative-director.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-documentation-manager.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-economy-designer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-engine-programmer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-fast-implementer.md +0 -28
- package/.claude/nccgs/agent-library/nccgs-game-design-lead.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-game-designer.md +0 -24
- package/.claude/nccgs/agent-library/nccgs-gameplay-programmer.md +0 -24
- package/.claude/nccgs/agent-library/nccgs-level-designer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-live-ops-designer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-localization-lead.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-narrative-lead.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-network-programmer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-performance-analyst.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-producer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-production-coordinator.md +0 -22
- package/.claude/nccgs/agent-library/nccgs-programming-lead.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-prototyper.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-qa-engineer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-qa-lead.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-release-engineer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-release-lead.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-security-engineer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-sound-designer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-systems-designer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-task-scout.md +0 -22
- package/.claude/nccgs/agent-library/nccgs-technical-architect.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-technical-artist.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-technical-director.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-tools-programmer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-ui-programmer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-unity-build-specialist.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-unity-content-specialist.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-unity-implementer.md +0 -26
- package/.claude/nccgs/agent-library/nccgs-unity-rendering-specialist.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-unity-systems-specialist.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-unity-ui-specialist.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-ux-designer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-verification-engineer.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-world-builder.md +0 -25
- package/.claude/nccgs/agent-library/nccgs-writer.md +0 -25
- package/.claude/nccgs/constitution.md +0 -187
- package/.claude/nccgs/hooks/agent-audit.mjs +0 -16
- package/.claude/nccgs/hooks/closure-guard.mjs +0 -59
- package/.claude/nccgs/hooks/common.mjs +0 -42
- package/.claude/nccgs/hooks/post-compact.mjs +0 -1
- package/.claude/nccgs/hooks/pre-compact.mjs +0 -8
- package/.claude/nccgs/hooks/protect-git.mjs +0 -22
- package/.claude/nccgs/hooks/protect-write.mjs +0 -17
- package/.claude/nccgs/hooks/runtime-observation.mjs +0 -11
- package/.claude/nccgs/hooks/session-start.mjs +0 -29
- package/.claude/nccgs/hooks/session-stop.mjs +0 -7
- package/.claude/nccgs/hooks/unity-transport-guard.mjs +0 -11
- package/.claude/nccgs/packages/ponytail/README.md +0 -46
- package/.claude/nccgs/packages/ponytail/manifest.json +0 -24
- package/.claude/nccgs/pipeline.json +0 -260
- package/.claude/nccgs/protocols/agent-contract.md +0 -101
- package/.claude/nccgs/protocols/astra-claude.md +0 -111
- package/.claude/nccgs/protocols/bounded-repair.md +0 -246
- package/.claude/nccgs/protocols/context-packets.md +0 -23
- package/.claude/nccgs/protocols/delivery-acceptance.md +0 -105
- package/.claude/nccgs/protocols/design-lifecycle.md +0 -139
- package/.claude/nccgs/protocols/editor-session-evidence.md +0 -52
- package/.claude/nccgs/protocols/evidence.md +0 -31
- package/.claude/nccgs/protocols/model-routing.md +0 -46
- package/.claude/nccgs/protocols/orchestration.md +0 -74
- package/.claude/nccgs/protocols/review-handoff.md +0 -101
- package/.claude/nccgs/protocols/shared-workflow-context.md +0 -33
- package/.claude/nccgs/protocols/standalone-gates.md +0 -329
- package/.claude/nccgs/protocols/standalone-pilot.md +0 -144
- package/.claude/nccgs/protocols/standalone.md +0 -207
- package/.claude/nccgs/protocols/task-autonomy.md +0 -55
- package/.claude/nccgs/protocols/task-gates.md +0 -144
- package/.claude/nccgs/protocols/task-slices.md +0 -106
- package/.claude/nccgs/protocols/unity-boundary.md +0 -31
- package/.claude/nccgs/routing.generated.md +0 -49
- package/.claude/nccgs/settings.fragment.json +0 -213
- package/.claude/nccgs/studio.json +0 -472
- package/.claude/nccgs/tools/approve-overrides.mjs +0 -81
- package/.claude/nccgs/tools/autonomy.mjs +0 -40
- package/.claude/nccgs/tools/command-process.mjs +0 -50
- package/.claude/nccgs/tools/command-tokens.mjs +0 -22
- package/.claude/nccgs/tools/compile-policy.mjs +0 -121
- package/.claude/nccgs/tools/configure-models.mjs +0 -96
- package/.claude/nccgs/tools/criteria.mjs +0 -121
- package/.claude/nccgs/tools/delivery-budget.mjs +0 -52
- package/.claude/nccgs/tools/design-readiness.mjs +0 -158
- package/.claude/nccgs/tools/editor-session-evidence.mjs +0 -66
- package/.claude/nccgs/tools/evidence.mjs +0 -153
- package/.claude/nccgs/tools/gates.mjs +0 -297
- package/.claude/nccgs/tools/handoff.mjs +0 -51
- package/.claude/nccgs/tools/hook-transport.mjs +0 -34
- package/.claude/nccgs/tools/inputs.mjs +0 -108
- package/.claude/nccgs/tools/installation-guard.mjs +0 -55
- package/.claude/nccgs/tools/integrity.mjs +0 -69
- package/.claude/nccgs/tools/lifecycle.mjs +0 -542
- package/.claude/nccgs/tools/native-completion.mjs +0 -30
- package/.claude/nccgs/tools/orchestration.mjs +0 -680
- package/.claude/nccgs/tools/paths.mjs +0 -60
- package/.claude/nccgs/tools/policy.mjs +0 -107
- package/.claude/nccgs/tools/process-lock.mjs +0 -74
- package/.claude/nccgs/tools/repair-packet.mjs +0 -106
- package/.claude/nccgs/tools/returned-handoff.mjs +0 -47
- package/.claude/nccgs/tools/review-budget.mjs +0 -171
- package/.claude/nccgs/tools/review-handoff.mjs +0 -66
- package/.claude/nccgs/tools/runtime.mjs +0 -71
- package/.claude/nccgs/tools/session-budget.mjs +0 -67
- package/.claude/nccgs/tools/shared-context-guard.mjs +0 -60
- package/.claude/nccgs/tools/shared-context.mjs +0 -25
- package/.claude/nccgs/tools/task-slices.mjs +0 -147
- package/.claude/nccgs/tools/task.mjs +0 -145
- package/.claude/nccgs/tools/tool-guard.mjs +0 -120
- package/.claude/nccgs/tools/unity-repair.mjs +0 -128
- package/.claude/nccgs/tools/unity-transport.mjs +0 -170
- package/.claude/nccgs/tools/verification-jobs.mjs +0 -171
- package/.claude/nccgs/tools/verification-worker.mjs +0 -71
- package/.claude/nccgs/tools/windows-compiler-server.cs +0 -163
- package/.claude/nccgs/tools/windows-job.cs +0 -103
- package/.claude/nccgs/unity-skills-manifest.json +0 -727
- package/.claude/nccgs/workflow-catalog.json +0 -654
- package/.claude/rules/nccgs-canonical-docs.md +0 -19
- package/.claude/rules/nccgs-editor-tools.md +0 -12
- package/.claude/rules/nccgs-localization.md +0 -12
- package/.claude/rules/nccgs-networking.md +0 -13
- package/.claude/rules/nccgs-performance.md +0 -14
- package/.claude/rules/nccgs-rendering.md +0 -16
- package/.claude/rules/nccgs-security.md +0 -13
- package/.claude/rules/nccgs-tests.md +0 -18
- package/.claude/rules/nccgs-ui.md +0 -14
- package/.claude/rules/nccgs-unity-assets.md +0 -21
- package/.claude/rules/nccgs-unity-code.md +0 -22
- package/.claude/skills/accessibility-review/SKILL.md +0 -22
- package/.claude/skills/accessibility-review/references/astra.md +0 -17
- package/.claude/skills/accessibility-review/references/legacy.md +0 -7
- package/.claude/skills/architecture-decision/SKILL.md +0 -22
- package/.claude/skills/architecture-decision/references/astra.md +0 -12
- package/.claude/skills/architecture-decision/references/legacy.md +0 -7
- package/.claude/skills/asset-audit/SKILL.md +0 -22
- package/.claude/skills/asset-audit/references/astra.md +0 -17
- package/.claude/skills/asset-audit/references/legacy.md +0 -7
- package/.claude/skills/audit/SKILL.md +0 -22
- package/.claude/skills/audit/references/astra.md +0 -17
- package/.claude/skills/audit/references/dimensions.md +0 -46
- package/.claude/skills/audit/references/legacy.md +0 -9
- package/.claude/skills/balance-review/SKILL.md +0 -22
- package/.claude/skills/balance-review/references/astra.md +0 -17
- package/.claude/skills/balance-review/references/legacy.md +0 -7
- package/.claude/skills/bug-triage/SKILL.md +0 -22
- package/.claude/skills/bug-triage/references/astra.md +0 -27
- package/.claude/skills/bug-triage/references/legacy.md +0 -7
- package/.claude/skills/build-live-game/SKILL.md +0 -317
- package/.claude/skills/build-live-game/references/cloud-code.md +0 -563
- package/.claude/skills/closure/SKILL.md +0 -22
- package/.claude/skills/closure/references/astra.md +0 -15
- package/.claude/skills/closure/references/legacy.md +0 -7
- package/.claude/skills/compatibility-review/SKILL.md +0 -22
- package/.claude/skills/compatibility-review/references/astra.md +0 -17
- package/.claude/skills/compatibility-review/references/legacy.md +0 -7
- package/.claude/skills/context-pack/SKILL.md +0 -22
- package/.claude/skills/context-pack/references/astra.md +0 -12
- package/.claude/skills/context-pack/references/legacy.md +0 -7
- package/.claude/skills/dependency-review/SKILL.md +0 -22
- package/.claude/skills/dependency-review/references/astra.md +0 -17
- package/.claude/skills/dependency-review/references/legacy.md +0 -7
- package/.claude/skills/design/SKILL.md +0 -24
- package/.claude/skills/design/references/astra.md +0 -12
- package/.claude/skills/design/references/legacy.md +0 -13
- package/.claude/skills/design-review/SKILL.md +0 -24
- package/.claude/skills/design-review/references/astra.md +0 -17
- package/.claude/skills/design-review/references/legacy.md +0 -7
- package/.claude/skills/evidence-review/SKILL.md +0 -22
- package/.claude/skills/evidence-review/references/astra.md +0 -17
- package/.claude/skills/evidence-review/references/legacy.md +0 -7
- package/.claude/skills/hotfix/SKILL.md +0 -22
- package/.claude/skills/hotfix/references/astra.md +0 -30
- package/.claude/skills/hotfix/references/legacy.md +0 -7
- package/.claude/skills/incident-recovery/SKILL.md +0 -22
- package/.claude/skills/incident-recovery/references/astra.md +0 -27
- package/.claude/skills/incident-recovery/references/legacy.md +0 -7
- package/.claude/skills/levelplay-unity-integration/SKILL.md +0 -1126
- package/.claude/skills/localization/SKILL.md +0 -135
- package/.claude/skills/localization/resources/L10nBatchProcessor.cs +0 -69
- package/.claude/skills/localize-game/SKILL.md +0 -22
- package/.claude/skills/localize-game/references/astra.md +0 -27
- package/.claude/skills/localize-game/references/legacy.md +0 -7
- package/.claude/skills/migrate-project/SKILL.md +0 -22
- package/.claude/skills/migrate-project/references/astra.md +0 -30
- package/.claude/skills/migrate-project/references/legacy.md +0 -19
- package/.claude/skills/migrate-project/references/procedure.md +0 -96
- package/.claude/skills/milestone-review/SKILL.md +0 -22
- package/.claude/skills/milestone-review/references/astra.md +0 -12
- package/.claude/skills/milestone-review/references/legacy.md +0 -7
- package/.claude/skills/nccgs-code-review/SKILL.md +0 -22
- package/.claude/skills/nccgs-code-review/references/astra.md +0 -21
- package/.claude/skills/nccgs-code-review/references/legacy.md +0 -7
- package/.claude/skills/new-unity-project/SKILL.md +0 -179
- package/.claude/skills/performance-audit/SKILL.md +0 -22
- package/.claude/skills/performance-audit/references/astra.md +0 -17
- package/.claude/skills/performance-audit/references/legacy.md +0 -7
- package/.claude/skills/physics-3d-collision/references/troubleshooting.md +0 -41
- package/.claude/skills/plan-feature/SKILL.md +0 -22
- package/.claude/skills/plan-feature/references/astra.md +0 -12
- package/.claude/skills/plan-feature/references/legacy.md +0 -7
- package/.claude/skills/playtest/SKILL.md +0 -22
- package/.claude/skills/playtest/references/astra.md +0 -31
- package/.claude/skills/playtest/references/legacy.md +0 -7
- package/.claude/skills/project-stage/SKILL.md +0 -22
- package/.claude/skills/project-stage/references/astra.md +0 -12
- package/.claude/skills/project-stage/references/legacy.md +0 -7
- package/.claude/skills/prototype-feature/SKILL.md +0 -22
- package/.claude/skills/prototype-feature/references/astra.md +0 -31
- package/.claude/skills/prototype-feature/references/legacy.md +0 -7
- package/.claude/skills/qa-plan/SKILL.md +0 -22
- package/.claude/skills/qa-plan/references/astra.md +0 -12
- package/.claude/skills/qa-plan/references/legacy.md +0 -7
- package/.claude/skills/release/SKILL.md +0 -22
- package/.claude/skills/release/references/astra.md +0 -30
- package/.claude/skills/release/references/legacy.md +0 -11
- package/.claude/skills/release-readiness/SKILL.md +0 -22
- package/.claude/skills/release-readiness/references/astra.md +0 -17
- package/.claude/skills/release-readiness/references/legacy.md +0 -7
- package/.claude/skills/retrospective/SKILL.md +0 -22
- package/.claude/skills/retrospective/references/astra.md +0 -12
- package/.claude/skills/retrospective/references/legacy.md +0 -7
- package/.claude/skills/review/SKILL.md +0 -22
- package/.claude/skills/review/references/astra.md +0 -21
- package/.claude/skills/review/references/legacy.md +0 -9
- package/.claude/skills/security-audit/SKILL.md +0 -22
- package/.claude/skills/security-audit/references/astra.md +0 -17
- package/.claude/skills/security-audit/references/legacy.md +0 -7
- package/.claude/skills/sprint-plan/SKILL.md +0 -22
- package/.claude/skills/sprint-plan/references/astra.md +0 -12
- package/.claude/skills/sprint-plan/references/legacy.md +0 -7
- package/.claude/skills/status/SKILL.md +0 -22
- package/.claude/skills/status/references/astra.md +0 -19
- package/.claude/skills/status/references/legacy.md +0 -9
- package/.claude/skills/story-readiness/SKILL.md +0 -24
- package/.claude/skills/story-readiness/references/astra.md +0 -17
- package/.claude/skills/story-readiness/references/legacy.md +0 -7
- package/.claude/skills/test/SKILL.md +0 -22
- package/.claude/skills/test/references/astra.md +0 -27
- package/.claude/skills/test/references/legacy.md +0 -9
- package/.claude/skills/ui-review/SKILL.md +0 -22
- package/.claude/skills/ui-review/references/astra.md +0 -17
- package/.claude/skills/ui-review/references/legacy.md +0 -7
- package/.claude/skills/unity-cli/CHANGELOG.md +0 -233
- package/.claude/skills/unity-cli/SECURITY.md +0 -22
- package/.claude/skills/unity-cli/SKILL.md +0 -414
- package/.claude/skills/unity-cli/references/auth-license-cloud.md +0 -146
- package/.claude/skills/unity-cli/references/build-run-test.md +0 -349
- package/.claude/skills/unity-cli/references/config-hub.md +0 -103
- package/.claude/skills/unity-cli/references/diagnostics-maintenance.md +0 -326
- package/.claude/skills/unity-cli/references/editors-install.md +0 -327
- package/.claude/skills/unity-cli/references/integration-advanced.md +0 -472
- package/.claude/skills/unity-cli/references/projects-templates.md +0 -574
- package/.claude/skills/work/SKILL.md +0 -22
- package/.claude/skills/work/references/astra.md +0 -32
- package/.claude/skills/work/references/classification.md +0 -41
- package/.claude/skills/work/references/closure.md +0 -60
- package/.claude/skills/work/references/feature-contracts.md +0 -36
- package/.claude/skills/work/references/legacy.md +0 -29
- package/.claude/skills/work/references/verification.md +0 -26
- package/CLAUDE.md +0 -10
- package/MEMORY.md +0 -109
- package/UPGRADING.md +0 -130
- package/VERSION +0 -1
- package/docs/ARCHITECTURE.md +0 -131
- package/docs/ASSET-PRODUCTION-GRAPHIFY-PLAN.md +0 -230
- package/docs/BOUNDED-REPAIR.md +0 -80
- package/docs/EDITOR-SESSION-EVIDENCE.md +0 -52
- package/docs/HANDOFF-AUTOMATION.md +0 -144
- package/docs/HUONG-DAN-MIGRATE-VA-SU-DUNG.md +0 -117
- package/docs/MIGRATION-MATRIX.md +0 -23
- package/docs/NCCGS-1.3.md +0 -13
- package/docs/NCCGS-1.4.1.md +0 -149
- package/docs/NCCGS-1.4.md +0 -184
- package/docs/NCCGS-1.5-IMPLEMENTATION-PLAN.md +0 -378
- package/docs/NCCGS-1.5-PILOT.md +0 -130
- package/docs/NCCGS-1.5.md +0 -237
- package/docs/PHASE-1-OPERATIONS.md +0 -278
- package/docs/PHASE-2-OPERATIONS.md +0 -183
- package/docs/PROJECT-POLICY.md +0 -94
- package/docs/RELEASE-STATUS.md +0 -150
- package/docs/TASK-SLICING.md +0 -57
- package/docs/UNINSTALL.md +0 -134
- package/docs/UPGRADE-QUALIFICATION.md +0 -45
- package/docs/WFK17-HOOK-REPAIR.md +0 -71
- package/docs/WORKFLOWS.md +0 -85
- package/package-assets/nccgs-project.gitignore +0 -2
- package/package-assets/setup-vivox-voice-chat-evals.gitignore +0 -7
- package/scaffold/.nccgs/autonomy.json +0 -4
- package/scaffold/.nccgs/bugs/.gitkeep +0 -1
- package/scaffold/.nccgs/closures/.gitkeep +0 -1
- package/scaffold/.nccgs/context/.gitkeep +0 -1
- package/scaffold/.nccgs/decisions/.gitkeep +0 -1
- package/scaffold/.nccgs/evidence/.gitkeep +0 -1
- package/scaffold/.nccgs/execution.json +0 -10
- package/scaffold/.nccgs/features/.gitkeep +0 -1
- package/scaffold/.nccgs/gates.json +0 -7
- package/scaffold/.nccgs/inputs.json +0 -6
- package/scaffold/.nccgs/migrations/.gitkeep +0 -1
- package/scaffold/.nccgs/playtests/.gitkeep +0 -1
- package/scaffold/.nccgs/project.yaml +0 -109
- package/scaffold/.nccgs/requirements.yaml +0 -10
- package/scaffold/.nccgs/reviews/.gitkeep +0 -1
- package/scaffold/.nccgs/state.md +0 -40
- package/scaffold/.nccgs/templates/agent-handoff.md +0 -37
- package/scaffold/.nccgs/templates/architecture-decision.md +0 -27
- package/scaffold/.nccgs/templates/closure-record.md +0 -62
- package/scaffold/.nccgs/templates/context-packet.yaml +0 -17
- package/scaffold/.nccgs/templates/design-contract.json +0 -34
- package/scaffold/.nccgs/templates/evidence-record.md +0 -23
- package/scaffold/.nccgs/templates/feature-contract.md +0 -60
- package/scaffold/.nccgs/templates/implementation-report.md +0 -52
- package/scaffold/.nccgs/templates/migration-plan.md +0 -40
- package/scaffold/.nccgs/templates/repair-packet.json +0 -14
- package/scaffold/.nccgs/templates/repair-unity-code.json +0 -18
- package/scaffold/.nccgs/templates/repair-unity-editor.json +0 -21
- package/scaffold/.nccgs/templates/task-slices.json +0 -28
- package/scaffold/.nccgs/templates/waiver.md +0 -11
- package/scripts/benchmark-snapshot.mjs +0 -205
- package/scripts/benchmark-v15.mjs +0 -173
- package/scripts/cli.mjs +0 -205
- package/scripts/doctor.mjs +0 -261
- package/scripts/install.mjs +0 -530
- package/scripts/recover-session.mjs +0 -89
- package/scripts/run.mjs +0 -86
- package/scripts/supervise.mjs +0 -152
- package/scripts/uninstall.mjs +0 -292
- package/scripts/validate.mjs +0 -285
- package/scripts/work-handoff.mjs +0 -38
- package/tests/autonomy.test.mjs +0 -126
- package/tests/benchmark-v15.test.mjs +0 -65
- package/tests/design-readiness.test.mjs +0 -200
- package/tests/editor-session-evidence.test.mjs +0 -45
- package/tests/evidence.test.mjs +0 -186
- package/tests/fixtures/compiler-shutdown.cs +0 -67
- package/tests/fixtures/native-provider.mjs +0 -61
- package/tests/framework.test.mjs +0 -740
- package/tests/gates.test.mjs +0 -479
- package/tests/hook-repair.test.mjs +0 -106
- package/tests/lifecycle-v15.test.mjs +0 -346
- package/tests/native-completion-notices.test.mjs +0 -181
- package/tests/orchestration-v15.test.mjs +0 -596
- package/tests/phase1.test.mjs +0 -427
- package/tests/phase2.test.mjs +0 -250
- package/tests/policy-v15.test.mjs +0 -234
- package/tests/ponytail-package.test.mjs +0 -75
- package/tests/returned-handoff-notices.test.mjs +0 -170
- package/tests/review-budget.test.mjs +0 -177
- package/tests/runtime-v15.test.mjs +0 -1198
- package/tests/session-budget.test.mjs +0 -34
- package/tests/task-slices.test.mjs +0 -285
- package/tests/uninstall.test.mjs +0 -477
- package/tests/unity-generated.test.mjs +0 -140
- package/tests/unity-transport.test.mjs +0 -348
- /package/{.claude/nccgs/packages → template}/ponytail/LICENSE +0 -0
- /package/{.claude/nccgs/packages → template}/ponytail/NOTICE.md +0 -0
- /package/{.claude/nccgs/packages → template}/ponytail/complexity-review.md +0 -0
- /package/{.claude/skills → unity-skills}/build-live-game/references/remote-config.md +0 -0
- /package/{.claude/skills → unity-skills}/implement-in-app-purchases/README.md +0 -0
- /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/codeless-catalog.md +0 -0
- /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/convert-adapty.md +0 -0
- /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/convert-essentialkit.md +0 -0
- /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/convert-revenuecat.md +0 -0
- /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/convert-unipay.md +0 -0
- /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/migration-v4-to-v5.md +0 -0
- /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/path-add-iap-to-new-project.md +0 -0
- /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/path-convert-native-storekit.md +0 -0
- /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/platform-notes.md +0 -0
- /package/{.claude/skills → unity-skills}/implement-in-app-purchases/references/pre-check.md +0 -0
- /package/{.claude/skills → unity-skills}/localization/resources/LocalizedFontAsset.cs +0 -0
- /package/{.claude/skills → unity-skills}/optimize-audio/resources/platform-settings.md +0 -0
- /package/{.claude/skills → unity-skills}/optimize-web/resources/WebOptimizer.cs +0 -0
- /package/{.claude/skills → unity-skills}/optimize-web/resources/toktx-examples.sh +0 -0
- /package/{.claude/skills → unity-skills}/physics-3d-collision/resources/CollisionDebugger.cs +0 -0
- /package/{.claude/skills → unity-skills}/setup-multiplayer-services/references/dgs-entrypoint.md +0 -0
- /package/{.claude/skills → unity-skills}/setup-multiplayer-services/references/entrypoints.md +0 -0
- /package/{.claude/skills → unity-skills}/setup-multiplayer-services/references/examples.md +0 -0
- /package/{.claude/skills → unity-skills}/setup-multiplayer-services/references/implementation-fit.md +0 -0
- /package/{.claude/skills → unity-skills}/setup-multiplayer-services/references/underlying-services.md +0 -0
- /package/{.claude/skills → unity-skills}/setup-multiplayer-services/references/workflows-prerequisites.md +0 -0
- /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/evals/.env.example +0 -0
- /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/evals/README.md +0 -0
- /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/evals/promptfooconfig.yaml +0 -0
- /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/evals/tests/init-and-login.yaml +0 -0
- /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/evals/tests/text-chat.yaml +0 -0
- /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/evals/tests/voice-channels.yaml +0 -0
- /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/references/events-and-participants.md +0 -0
- /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/references/init-and-login.md +0 -0
- /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/references/text-chat.md +0 -0
- /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/references/troubleshooting.md +0 -0
- /package/{.claude/skills → unity-skills}/setup-vivox-voice-chat/references/voice-channels.md +0 -0
- /package/{.claude/skills → unity-skills}/shader-graph-create-custom-node/resources/all_hints.hlsl +0 -0
- /package/{.claude/skills → unity-skills}/sprite-editor/references/api_reference.md +0 -0
- /package/{.claude/skills → unity-skills}/sprite-editor/references/background.md +0 -0
- /package/{.claude/skills → unity-skills}/sprite-editor/scripts/AutomaticSliceTexture.cs +0 -0
- /package/{.claude/skills → unity-skills}/sprite-editor/scripts/GenerateNewSpriteRects.cs +0 -0
- /package/{.claude/skills → unity-skills}/sprite-editor/scripts/GetTextureSourceImageSize.cs +0 -0
- /package/{.claude/skills → unity-skills}/sprite-editor/scripts/GetTextureToSlice.cs +0 -0
- /package/{.claude/skills → unity-skills}/sprite-editor/scripts/GridSliceTexture.cs +0 -0
- /package/{.claude/skills → unity-skills}/sprite-editor/scripts/IsometricSliceTexture.cs +0 -0
- /package/{.claude/skills → unity-skills}/sprite-editor/scripts/README.md +0 -0
- /package/{.claude/skills → unity-skills}/sprite-editor/scripts/SetPivotExample.cs +0 -0
- /package/{.claude/skills → unity-skills}/sprite-editor/scripts/SpriteToPng.cs +0 -0
- /package/{.claude/skills → unity-skills}/ui-imgui/references/gui-elements.md +0 -0
- /package/{.claude/skills → unity-skills}/ui-imgui/references/templates.md +0 -0
- /package/{.claude/skills → unity-skills}/ui-ugui/references/scrollview-setup.md +0 -0
- /package/{.claude/skills → unity-skills}/ui-uitk/references/common-issues.md +0 -0
- /package/{.claude/skills → unity-skills}/ui-uitk/references/painter2d.md +0 -0
- /package/{.claude/skills → unity-skills}/ui-uitk/references/pointermanipulator-guide.md +0 -0
- /package/{.claude/skills → unity-skills}/ui-uitk/references/svg-icons.md +0 -0
- /package/{.claude/skills → unity-skills}/ui-uitk/references/ui-runtime-binding.md +0 -0
- /package/{.claude/skills → unity-skills}/ui-uitk/references/uss-guide.md +0 -0
- /package/{.claude/skills → unity-skills}/urp-postprocessing/references/effect-reference.md +0 -0
|
@@ -1,596 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import { spawn } from "node:child_process";
|
|
6
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
|
-
import test from "node:test";
|
|
8
|
-
import { reserve, claim, complete, reconcile, status, checkpoint, resume, telemetry, validateStageDispatch, extendDispatch } from "../.claude/nccgs/tools/orchestration.mjs";
|
|
9
|
-
import { snapshot } from "../.claude/nccgs/tools/gates.mjs";
|
|
10
|
-
import { pinInputs } from "../.claude/nccgs/tools/inputs.mjs";
|
|
11
|
-
import { artifact, atomicJson, hash, json } from "../.claude/nccgs/tools/policy.mjs";
|
|
12
|
-
import { persistRuntimeObservation } from "../.claude/nccgs/tools/evidence.mjs";
|
|
13
|
-
import { observe } from "../.claude/nccgs/tools/runtime.mjs";
|
|
14
|
-
import { validateStandaloneRuntime, initializeStandalone, recordStandalone, migrateFrameworkBaseline } from "../.claude/nccgs/tools/lifecycle.mjs";
|
|
15
|
-
import { guardTool } from "../.claude/nccgs/tools/tool-guard.mjs";
|
|
16
|
-
import { acquireLock } from "../.claude/nccgs/tools/process-lock.mjs";
|
|
17
|
-
import { sessionBudgetLock } from "../.claude/nccgs/tools/session-budget.mjs";
|
|
18
|
-
|
|
19
|
-
// These are synthetic framework fixtures, never Claude Code execution evidence.
|
|
20
|
-
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
21
|
-
const moduleUrl = pathToFileURL(path.join(root, ".claude/nccgs/tools/orchestration.mjs")).href;
|
|
22
|
-
const agents = { implementation: "nccgs-gameplay-programmer", analysis: "nccgs-task-scout", review: "nccgs-adversarial-reviewer" };
|
|
23
|
-
function fixture() {
|
|
24
|
-
const temporaryRoot = fs.realpathSync(os.tmpdir());
|
|
25
|
-
const project = fs.mkdtempSync(path.join(temporaryRoot, "nccgs-orchestration-v15-"));
|
|
26
|
-
const write = (relative, value) => {
|
|
27
|
-
const file = path.join(project, relative);
|
|
28
|
-
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
29
|
-
fs.writeFileSync(file, Buffer.isBuffer(value) || typeof value === "string" ? value : `${JSON.stringify(value, null, 2)}\n`);
|
|
30
|
-
return artifact(project, relative);
|
|
31
|
-
};
|
|
32
|
-
for (const name of ["pipeline.json", "studio.json"]) write(`.claude/nccgs/${name}`, fs.readFileSync(path.join(root, ".claude/nccgs", name)));
|
|
33
|
-
write(".nccgs/project.yaml", "schema_version: 2\nmodels:\n profile: claude-standalone\n");
|
|
34
|
-
write(".nccgs/execution.json", { schemaVersion: 1, name: "standalone", externalReview: { mode: "off" }, acceptanceRequired: false, requireObservedEffort: false, maxParallelWorkers: 2 });
|
|
35
|
-
write("Assets/game.cs", "// TEST FIXTURE source, not a game implementation\n");
|
|
36
|
-
write(".nccgs/requirements.yaml", "schema_version: 1\nrequirements: []\n");
|
|
37
|
-
function task(id, overrides = {}) {
|
|
38
|
-
const mode = overrides.mode ?? "implement";
|
|
39
|
-
const contract = { schemaVersion: 1, revision: 1, mode, scope: "local", target: "production-change", acceptance: [], analysisArtifacts: [".nccgs/evidence/analysis/plan.md"] };
|
|
40
|
-
const value = { schemaVersion: 2, id, mode, risk: "STANDARD", profile: "claude-standalone", createdAt: new Date().toISOString(),
|
|
41
|
-
contract, contractHash: hash(JSON.stringify(contract)), reviewBudget: { used: 0, limit: 3, extensions: [] },
|
|
42
|
-
implementationRoute: { class: "standard", model: "claude-opus-5-5", effort: "medium" },
|
|
43
|
-
canonicalInputs: pinInputs(project), stages: {}, history: [], parentId: null, ...overrides };
|
|
44
|
-
write(`.nccgs/tasks/${id}.json`, value);
|
|
45
|
-
return value;
|
|
46
|
-
}
|
|
47
|
-
let serial = 0;
|
|
48
|
-
function request(kind, overrides = {}) {
|
|
49
|
-
return { requestKey: `fixture-request-${++serial}`, kind, agent: agents[kind], writePaths: kind === "implementation" ? ["Assets/game.cs"] : [],
|
|
50
|
-
reason: "TEST FIXTURE bounded work", ...overrides };
|
|
51
|
-
}
|
|
52
|
-
function start(id, req = request("analysis")) {
|
|
53
|
-
const reservation = reserve(project, id, req);
|
|
54
|
-
const identity = { sessionId: `session-${++serial}`, toolUseId: `tool-${serial}`, agent: req.agent, kind: req.kind };
|
|
55
|
-
claim(project, reservation.id, identity);
|
|
56
|
-
return { reservation, identity, request: req, taskId: id };
|
|
57
|
-
}
|
|
58
|
-
function observation(run, overrides = {}, rawOverrides = {}) {
|
|
59
|
-
const current = json(path.join(project, `.nccgs/tasks/${run.taskId}.json`));
|
|
60
|
-
const data = { schemaVersion: 1, origin: "runtime-observation", observedProvider: "claude-code",
|
|
61
|
-
dispatchId: run.reservation.id, taskId: run.taskId, contractHash: current.contractHash,
|
|
62
|
-
snapshot: snapshot(project).sha256, capturedAt: new Date().toISOString(),
|
|
63
|
-
sessionId: run.identity.sessionId, toolUseId: run.identity.toolUseId, agentId: `agent-${run.reservation.id}`,
|
|
64
|
-
agentType: run.request.agent, observedModel: "claude-opus-5-5", observedEffort: null, modelsUsed: ["claude-opus-5-5"],
|
|
65
|
-
status: "completed", durationMs: null, toolUseCount: null, totalTokens: null, costUsd: null,
|
|
66
|
-
provenance: { kind: "provider-log", reference: "SYNTHETIC TEST FIXTURE ONLY; not a real provider run" }, ...overrides };
|
|
67
|
-
const source = write(`.nccgs/evidence/runtime/sources/fixture-${++serial}.json`, { ...data, ...rawOverrides });
|
|
68
|
-
return persistRuntimeObservation(project, { ...data, observationSource: source }, source);
|
|
69
|
-
}
|
|
70
|
-
return { project, write, task, request, start, observation,
|
|
71
|
-
dispose() {
|
|
72
|
-
const resolved = path.resolve(project);
|
|
73
|
-
assert.equal(path.dirname(resolved).toLowerCase(), temporaryRoot.toLowerCase());
|
|
74
|
-
assert.ok(path.basename(resolved).startsWith("nccgs-orchestration-v15-"));
|
|
75
|
-
assert.equal(fs.lstatSync(resolved).isSymbolicLink(), false);
|
|
76
|
-
assert.equal(fs.realpathSync(resolved).toLowerCase(), resolved.toLowerCase());
|
|
77
|
-
fs.rmSync(resolved, { recursive: true, force: true });
|
|
78
|
-
} };
|
|
79
|
-
}
|
|
80
|
-
function external(action) {
|
|
81
|
-
const saved = [process.env.CLAUDECODE, process.env.CLAUDE_CODE_ENTRYPOINT];
|
|
82
|
-
delete process.env.CLAUDECODE; delete process.env.CLAUDE_CODE_ENTRYPOINT;
|
|
83
|
-
try { return action(); } finally {
|
|
84
|
-
for (const [index, name] of ["CLAUDECODE", "CLAUDE_CODE_ENTRYPOINT"].entries()) {
|
|
85
|
-
if (saved[index] === undefined) delete process.env[name]; else process.env[name] = saved[index];
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
function failRun(f, run) {
|
|
90
|
-
return external(() => reconcile(f.project, run.reservation.id, { status: "failed", reason: "TEST FIXTURE process confirmed terminated", reference: "TEST FIXTURE external process-exit receipt" }));
|
|
91
|
-
}
|
|
92
|
-
test("external framework migration proves the old inventory, rejects game changes and invalidates all approvals without quota refunds", () => {
|
|
93
|
-
const f = fixture();
|
|
94
|
-
try {
|
|
95
|
-
f.write('.nccgs/intake.json', { objective: 'Synthetic plan migration', mode: 'plan', analysisArtifacts: ['.nccgs/evidence/analysis/plan.md'] });
|
|
96
|
-
const t = initializeStandalone(f.project, 'migration', { intake: '.nccgs/intake.json' });
|
|
97
|
-
const beforeFiles = snapshot(f.project, t, { includeFiles: true }).fileEntries;
|
|
98
|
-
const run = f.start('migration'); failRun(f, run);
|
|
99
|
-
t.reviewBudget.used = 1; t.stages = { analysis: { fixture: true }, report: { outcome: 'partial' } }; f.write('.nccgs/tasks/migration.json', t);
|
|
100
|
-
const decision = '.nccgs/evidence/migration.json';
|
|
101
|
-
f.write(decision, { reason: 'Fixture framework patch', authority: 'Synthetic external fixture', beforeFiles });
|
|
102
|
-
f.write('.claude/nccgs/new-tool.mjs', '// fixture framework update');
|
|
103
|
-
f.write('Assets/game.cs', '// unauthorized source change');
|
|
104
|
-
assert.throws(() => external(() => migrateFrameworkBaseline(f.project, 'migration', decision)), /non-framework/);
|
|
105
|
-
f.write('Assets/game.cs', '// TEST FIXTURE source, not a game implementation\n');
|
|
106
|
-
process.env.CLAUDECODE = 'fixture';
|
|
107
|
-
try { assert.throws(() => migrateFrameworkBaseline(f.project, 'migration', decision), /external|External/); } finally { delete process.env.CLAUDECODE; }
|
|
108
|
-
const result = external(() => migrateFrameworkBaseline(f.project, 'migration', decision));
|
|
109
|
-
assert.equal(result.contractHash, t.contractHash); assert.equal(result.reviewBudget.used, 1); assert.deepEqual(result.stages, {});
|
|
110
|
-
assert.deepEqual(result.history.at(-1).stages, t.stages); assert.equal(result.history.at(-1).previousBaseline, t.analysisBaseline);
|
|
111
|
-
assert.equal(status(f.project, 'migration').usage.dispatches, 1);
|
|
112
|
-
assert.throws(() => external(() => migrateFrameworkBaseline(f.project, 'migration', decision)), /inventory/);
|
|
113
|
-
} finally { f.dispose(); }
|
|
114
|
-
});
|
|
115
|
-
test("missing worker cost admits only its live supervised allowance and keeps telemetry/limits/history", () => {
|
|
116
|
-
const f = fixture(), saved = [process.env.NCCGS_SUPERVISED_RUN, process.env.NCCGS_SUPERVISED_SESSION];
|
|
117
|
-
let lock;
|
|
118
|
-
try {
|
|
119
|
-
f.task("budget");
|
|
120
|
-
const run = f.start("budget", f.request("analysis", { limits: { maxCostUsd: 3 } }));
|
|
121
|
-
const observed = f.observation(run); complete(f.project, run.reservation.id, { runtime: observed });
|
|
122
|
-
assert.throws(() => reserve(f.project, "budget", f.request("analysis")), /missing costUsd/);
|
|
123
|
-
const id = "12345678-1234-1234-1234-123456789abc", sessionId = run.identity.sessionId;
|
|
124
|
-
f.write(`.nccgs/runs/${id}/run.json`, { id, project: f.project, taskId: "budget", sessionId, budgetUsd: 3, cumulativeCostUsd: 0,
|
|
125
|
-
deadline: Date.now() + 60000, status: "running", invocations: [{ status: "running", pid: process.pid }] });
|
|
126
|
-
lock = acquireLock(path.join(f.project, sessionBudgetLock), { runId: id, sessionId });
|
|
127
|
-
process.env.NCCGS_SUPERVISED_RUN = id; process.env.NCCGS_SUPERVISED_SESSION = sessionId;
|
|
128
|
-
const next = reserve(f.project, "budget", f.request("analysis"));
|
|
129
|
-
assert.equal(next.budgetEvidence[0].ceilingUsd, 3);
|
|
130
|
-
assert.throws(() => claim(f.project, next.id, { sessionId: "other", toolUseId: "next", agent: next.agent }), /owns its budget/);
|
|
131
|
-
const current = status(f.project, "budget"); assert.equal(current.usage.dispatches, 2); assert.equal(current.limits.maxCostUsd, 3);
|
|
132
|
-
assert.equal(current.telemetry.metrics.costUsd.total, null); assert.equal(current.telemetry.metrics.costUsd.measured, 0);
|
|
133
|
-
lock.release(); lock = null;
|
|
134
|
-
assert.throws(() => reserve(f.project, "budget", f.request("analysis")), /ENOENT/);
|
|
135
|
-
} finally {
|
|
136
|
-
lock?.release();
|
|
137
|
-
for (const [i,k] of ["NCCGS_SUPERVISED_RUN", "NCCGS_SUPERVISED_SESSION"].entries()) { if(saved[i]===undefined) delete process.env[k]; else process.env[k]=saved[i]; }
|
|
138
|
-
f.dispose();
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
test("external dispatch extension keeps spent attempts and parent cap, and rejects live or native changes", () => {
|
|
142
|
-
const f = fixture();
|
|
143
|
-
try {
|
|
144
|
-
f.task("parent"); f.task("child", { parentId: "parent" });
|
|
145
|
-
const parent = f.start("parent", f.request("analysis", { limits: { maxDispatches: 2 } }));
|
|
146
|
-
failRun(f, parent);
|
|
147
|
-
const child = f.start("child", f.request("analysis", { limits: { maxDispatches: 1 } }));
|
|
148
|
-
const decision = { previousLimit: 1, maxDispatches: 2, reason: "External fixture allocation", reference: f.write(".nccgs/evidence/authority.json", { fixture: true }) };
|
|
149
|
-
assert.throws(() => guardTool(f.project, { session_id: "coordinator", tool_name: "Bash", tool_input: {
|
|
150
|
-
command: "node .claude/nccgs/tools/task.mjs extend-dispatch --id child --request .nccgs/evidence/authority.json"
|
|
151
|
-
} }), /External decisions/);
|
|
152
|
-
assert.throws(() => external(() => extendDispatch(f.project, "child", decision)), /active dispatches/);
|
|
153
|
-
failRun(f, child);
|
|
154
|
-
external(() => {
|
|
155
|
-
process.env.CLAUDECODE = "1";
|
|
156
|
-
try { assert.throws(() => extendDispatch(f.project, "child", decision), /external operator/); }
|
|
157
|
-
finally { delete process.env.CLAUDECODE; }
|
|
158
|
-
assert.throws(() => extendDispatch(f.project, "child", { ...decision, previousLimit: 0 }), /stale/);
|
|
159
|
-
assert.throws(() => extendDispatch(f.project, "child", { ...decision, maxDispatches: 1 }), /increase/);
|
|
160
|
-
extendDispatch(f.project, "child", decision);
|
|
161
|
-
});
|
|
162
|
-
assert.equal(status(f.project, "child").usage.dispatches, 1);
|
|
163
|
-
assert.equal(status(f.project, "child").limits.maxDispatches, 2);
|
|
164
|
-
assert.throws(() => reserve(f.project, "child", f.request("analysis")), /budget exhausted for parent/);
|
|
165
|
-
assert.equal(json(path.join(f.project, ".nccgs/orchestration.json")).events.filter(e => e.action === "extend-dispatch").length, 1);
|
|
166
|
-
} finally { f.dispose(); }
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
test("native invocation completion cannot replace a declared missing handoff", () => {
|
|
170
|
-
const f = fixture();
|
|
171
|
-
try {
|
|
172
|
-
const task = f.task("handoff"), request = f.request("analysis", { handoffPaths: [".nccgs/evidence/analysis/plan.md"] });
|
|
173
|
-
const run = f.start("handoff", request), runtime = f.observation(run);
|
|
174
|
-
const completed = complete(f.project, run.reservation.id, { runtime });
|
|
175
|
-
assert.equal(completed.status, "failed"); assert.equal(completed.workStatus, "incomplete"); assert.equal(completed.invocationStatus, "completed");
|
|
176
|
-
assert.equal(completed.handoff.status, "missing"); assert.equal(status(f.project, "handoff").usage.dispatches, 1);
|
|
177
|
-
const trace = json(path.join(f.project, runtime.path));
|
|
178
|
-
assert.throws(() => validateStageDispatch(f.project, task, { dispatchId: completed.id, snapshot: completed.completedSnapshot, runtime }, trace, "analysis"), /handoff artifacts are missing/);
|
|
179
|
-
f.write(".nccgs/evidence/analysis/plan.md", "Late text is not the original worker handoff");
|
|
180
|
-
assert.equal(reserve(f.project, "handoff", request).id, completed.id);
|
|
181
|
-
assert.throws(() => validateStageDispatch(f.project, task, { dispatchId: completed.id, snapshot: completed.completedSnapshot, runtime }, trace, "analysis"), /handoff artifacts are missing/);
|
|
182
|
-
} finally { f.dispose(); }
|
|
183
|
-
});
|
|
184
|
-
async function simultaneousReservations(project, id, requests) {
|
|
185
|
-
const code = `import { reserve } from ${JSON.stringify(moduleUrl)};
|
|
186
|
-
process.on('message', message => {
|
|
187
|
-
if (message !== 'go') return;
|
|
188
|
-
try { process.send({ result: { ok: true, value: reserve(process.argv[1], process.argv[2], JSON.parse(process.argv[3])) } }); }
|
|
189
|
-
catch (error) { process.send({ result: { ok: false, error: error.message } }); }
|
|
190
|
-
process.disconnect();
|
|
191
|
-
});
|
|
192
|
-
process.send({ ready: true });`;
|
|
193
|
-
const children = [];
|
|
194
|
-
try {
|
|
195
|
-
const workers = requests.map(item => {
|
|
196
|
-
const taskId = item.taskId ?? id, request = item.request ?? item;
|
|
197
|
-
const child = spawn(process.execPath, ["--input-type=module", "-e", code, project, taskId, JSON.stringify(request)], { windowsHide: true, stdio: ["ignore", "pipe", "pipe", "ipc"] });
|
|
198
|
-
children.push(child);
|
|
199
|
-
let stderr = "";
|
|
200
|
-
child.stderr.on("data", chunk => { stderr += chunk; });
|
|
201
|
-
let received;
|
|
202
|
-
let readyResolve;
|
|
203
|
-
const ready = new Promise(resolve => { readyResolve = resolve; });
|
|
204
|
-
const result = new Promise((resolve, reject) => {
|
|
205
|
-
const timer = setTimeout(() => { child.kill(); reject(new Error("Race subprocess timeout")); }, 20000);
|
|
206
|
-
child.on("message", message => { if (message.ready) readyResolve(); if (message.result) received = message.result; });
|
|
207
|
-
child.on("error", error => { clearTimeout(timer); readyResolve(); reject(error); });
|
|
208
|
-
child.on("exit", code => {
|
|
209
|
-
clearTimeout(timer); readyResolve();
|
|
210
|
-
if (code !== 0 || !received) reject(new Error(`Race subprocess failed (${code}): ${stderr}`)); else resolve(received);
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
|
-
return { child, ready, result };
|
|
214
|
-
});
|
|
215
|
-
await Promise.all(workers.map(worker => worker.ready));
|
|
216
|
-
for (const worker of workers) if (worker.child.connected) worker.child.send("go");
|
|
217
|
-
return await Promise.all(workers.map(worker => worker.result));
|
|
218
|
-
} finally { for (const child of children) if (child.exitCode === null) child.kill(); }
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
test("reservation retry is idempotent but cannot replace an existing request", () => {
|
|
222
|
-
const f = fixture();
|
|
223
|
-
try {
|
|
224
|
-
f.task("task");
|
|
225
|
-
const request = f.request("analysis");
|
|
226
|
-
const first = reserve(f.project, "task", request);
|
|
227
|
-
assert.equal(reserve(f.project, "task", structuredClone(request)).id, first.id);
|
|
228
|
-
assert.equal(status(f.project, "task").reservations.length, 1);
|
|
229
|
-
assert.throws(() => reserve(f.project, "task", { ...request, reason: "Changed request under reused key" }), /key|request|duplicate|different/i);
|
|
230
|
-
assert.throws(() => reserve(f.project, "task", { ...request, requestKey: "" }), /key|request/i);
|
|
231
|
-
} finally { f.dispose(); }
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
test("project path ownership covers descendants and Windows case aliases", () => {
|
|
235
|
-
const f = fixture();
|
|
236
|
-
try {
|
|
237
|
-
for (const id of ["owner", "other"]) f.task(id);
|
|
238
|
-
reserve(f.project, "owner", f.request("implementation", { writePaths: ["Assets/Actors"] }));
|
|
239
|
-
assert.throws(() => reserve(f.project, "other", f.request("implementation", { writePaths: ["Assets/Actors/player.cs"] })), /path|writer|overlap|conflict/i);
|
|
240
|
-
if (process.platform === "win32") assert.throws(() => reserve(f.project, "other", f.request("implementation", { writePaths: ["assets/actors/player.cs"] })), /path|writer|overlap|conflict/i);
|
|
241
|
-
assert.throws(() => reserve(f.project, "other", f.request("implementation", { writePaths: ["../outside.cs"] })), /path|relative|outside|travers/i);
|
|
242
|
-
assert.equal(status(f.project, "other").reservations.length, 0);
|
|
243
|
-
} finally { f.dispose(); }
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
test("no more than two implementation workers reserve across separate tasks", () => {
|
|
247
|
-
const f = fixture();
|
|
248
|
-
try {
|
|
249
|
-
for (const id of ["one", "two", "three"]) f.task(id);
|
|
250
|
-
reserve(f.project, "one", f.request("implementation", { writePaths: ["Assets/One"] }));
|
|
251
|
-
reserve(f.project, "two", f.request("implementation", { writePaths: ["Assets/Two"] }));
|
|
252
|
-
assert.throws(() => reserve(f.project, "three", f.request("implementation", { writePaths: ["Assets/Three"] })), /parallel|worker|concurr|limit/i);
|
|
253
|
-
} finally { f.dispose(); }
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
test("audit and plan cannot reserve source writers; read-only roles cannot become implementers", () => {
|
|
257
|
-
const f = fixture();
|
|
258
|
-
try {
|
|
259
|
-
// Check role capability before reserving any other read-only work, so a
|
|
260
|
-
// concurrency conflict cannot accidentally satisfy the role assertion.
|
|
261
|
-
f.task("code");
|
|
262
|
-
assert.throws(() => reserve(f.project, "code", f.request("implementation", { agent: agents.analysis })), /read.only|role|agent|implement/i);
|
|
263
|
-
for (const mode of ["audit", "plan"]) {
|
|
264
|
-
f.task(mode, { mode });
|
|
265
|
-
assert.throws(() => reserve(f.project, mode, f.request("implementation")), /mode|read.only|implement|audit|plan/i);
|
|
266
|
-
assert.throws(() => reserve(f.project, mode, f.request("analysis", { writePaths: ["Assets/game.cs"] })), /path|read.only|analysis|writ/i);
|
|
267
|
-
assert.ok(reserve(f.project, mode, f.request("analysis")).id);
|
|
268
|
-
}
|
|
269
|
-
} finally { f.dispose(); }
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
test("an already exhausted recorded review budget blocks a first managed reviewer", () => {
|
|
273
|
-
const f = fixture();
|
|
274
|
-
try {
|
|
275
|
-
f.task("task", { reviewBudget: { used: 3, limit: 3, extensions: [] } });
|
|
276
|
-
assert.throws(() => reserve(f.project, "task", f.request("review")), /review|budget|limit|exhaust/i);
|
|
277
|
-
assert.equal(status(f.project, "task").reservations.length, 0);
|
|
278
|
-
} finally { f.dispose(); }
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
test("two subprocess reviewers racing for the last round cannot both reserve", async () => {
|
|
282
|
-
const f = fixture();
|
|
283
|
-
try {
|
|
284
|
-
f.write(".nccgs/intake.json", { mode: "implement", objective: "Synthetic concurrency fixture", scope: "feature", readiness: "ready", requiredChecks: [] });
|
|
285
|
-
let task = initializeStandalone(f.project, "task", { intake: ".nccgs/intake.json" });
|
|
286
|
-
const run = f.start("task", f.request("implementation")), runtime = f.observation(run);
|
|
287
|
-
const done = complete(f.project, run.reservation.id, { runtime });
|
|
288
|
-
const evidence = f.write(".nccgs/evidence/synthetic-check.txt", "SYNTHETIC verification fixture");
|
|
289
|
-
task = recordStandalone(f.project, task, "implementation", { dispatchId: done.id, snapshot: done.completedSnapshot, runtime, checks: [{ name: "synthetic-check", status: "PASS", evidence }] });
|
|
290
|
-
task.reviewBudget.used = task.reviewBudget.limit - 1;
|
|
291
|
-
f.write(".nccgs/tasks/task.json", task);
|
|
292
|
-
const results = await simultaneousReservations(f.project, "task", [f.request("review"), f.request("review")]);
|
|
293
|
-
assert.equal(results.filter(result => result.ok).length, 1, JSON.stringify(results));
|
|
294
|
-
assert.equal(status(f.project, "task").active.filter(item => item.kind === "review").length, 1);
|
|
295
|
-
} finally { f.dispose(); }
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
test("claim identities and exact completion retries cannot duplicate accounting", () => {
|
|
299
|
-
const f = fixture();
|
|
300
|
-
try {
|
|
301
|
-
f.task("task");
|
|
302
|
-
const run = f.start("task");
|
|
303
|
-
claim(f.project, run.reservation.id, run.identity);
|
|
304
|
-
assert.throws(() => claim(f.project, run.reservation.id, { ...run.identity, toolUseId: "different-tool" }), /claim|identity|running|bound|dispatch/i);
|
|
305
|
-
const runtime = f.observation(run);
|
|
306
|
-
complete(f.project, run.reservation.id, { runtime });
|
|
307
|
-
const before = status(f.project, "task").usage;
|
|
308
|
-
complete(f.project, run.reservation.id, { runtime });
|
|
309
|
-
assert.deepEqual(status(f.project, "task").usage, before);
|
|
310
|
-
assert.equal(status(f.project, "task").active.length, 0);
|
|
311
|
-
assert.equal(reserve(f.project, "task", run.request).id, run.reservation.id);
|
|
312
|
-
assert.equal(telemetry(f.project, "task").attempts, 1);
|
|
313
|
-
} finally { f.dispose(); }
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
test("child dispatches consume the ancestor budget and new children cannot mint quota", () => {
|
|
317
|
-
const f = fixture();
|
|
318
|
-
try {
|
|
319
|
-
f.task("parent"); f.task("child", { parentId: "parent" }); f.task("new-child", { parentId: "parent" });
|
|
320
|
-
const parent = f.start("parent", f.request("analysis", { limits: { maxDispatches: 2 } }));
|
|
321
|
-
complete(f.project, parent.reservation.id, { runtime: f.observation(parent) });
|
|
322
|
-
const child = f.start("child");
|
|
323
|
-
failRun(f, child);
|
|
324
|
-
assert.equal(status(f.project, "parent").usage.dispatches, 2);
|
|
325
|
-
assert.equal(telemetry(f.project, "parent").attempts, 2);
|
|
326
|
-
assert.equal(telemetry(f.project, "parent").metrics.durationMs.expected, 2);
|
|
327
|
-
assert.throws(() => reserve(f.project, "new-child", f.request("analysis")), /budget|quota|dispatch|limit/i);
|
|
328
|
-
assert.throws(() => reserve(f.project, "parent", f.request("analysis", { limits: { maxDispatches: 20 } })), /budget|quota|limit|extend|chang/i);
|
|
329
|
-
} finally { f.dispose(); }
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
test("separate child processes racing for the last ancestor dispatch share one quota", async () => {
|
|
333
|
-
const f = fixture();
|
|
334
|
-
try {
|
|
335
|
-
f.task("parent"); f.task("first", { parentId: "parent" }); f.task("second", { parentId: "parent" });
|
|
336
|
-
const parent = f.start("parent", f.request("analysis", { limits: { maxDispatches: 2 } }));
|
|
337
|
-
complete(f.project, parent.reservation.id, { runtime: f.observation(parent) });
|
|
338
|
-
const results = await simultaneousReservations(f.project, "parent", [
|
|
339
|
-
{ taskId: "first", request: f.request("analysis") }, { taskId: "second", request: f.request("analysis") }
|
|
340
|
-
]);
|
|
341
|
-
assert.equal(results.filter(result => result.ok).length, 1, JSON.stringify(results));
|
|
342
|
-
assert.equal(status(f.project, "parent").usage.dispatches, 2);
|
|
343
|
-
} finally { f.dispose(); }
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
test("checkpoint and resume do not free an uncertain run or reset consumed budget", () => {
|
|
347
|
-
const f = fixture();
|
|
348
|
-
try {
|
|
349
|
-
f.task("task");
|
|
350
|
-
const run = f.start("task", f.request("implementation", { limits: { maxDispatches: 1 } }));
|
|
351
|
-
const before = status(f.project, "task");
|
|
352
|
-
checkpoint(f.project, "task", { reason: "TEST FIXTURE interrupted coordinator" });
|
|
353
|
-
resume(f.project, "task");
|
|
354
|
-
const after = status(f.project, "task");
|
|
355
|
-
assert.deepEqual(after.usage, before.usage);
|
|
356
|
-
assert.ok(after.active.some(item => item.id === run.reservation.id));
|
|
357
|
-
assert.throws(() => reserve(f.project, "task", f.request("implementation")), /budget|quota|dispatch|limit|path|writer/i);
|
|
358
|
-
failRun(f, run);
|
|
359
|
-
assert.equal(status(f.project, "task").active.length, 0);
|
|
360
|
-
assert.throws(() => reserve(f.project, "task", f.request("analysis")), /budget|quota|dispatch|limit/i);
|
|
361
|
-
} finally { f.dispose(); }
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
test("external reconciliation needs provenance and is rejected inside Claude", () => {
|
|
365
|
-
const f = fixture();
|
|
366
|
-
try {
|
|
367
|
-
f.task("task");
|
|
368
|
-
const run = f.start("task");
|
|
369
|
-
external(() => assert.throws(() => reconcile(f.project, run.reservation.id, { status: "failed", reason: "", reference: "" }), /reason|reference|provenance/i));
|
|
370
|
-
const original = process.env.CLAUDECODE;
|
|
371
|
-
process.env.CLAUDECODE = "1";
|
|
372
|
-
try { assert.throws(() => reconcile(f.project, run.reservation.id, { status: "failed", reason: "Self-declared stop", reference: "self" }), /external|Claude|operator/i); }
|
|
373
|
-
finally { if (original === undefined) delete process.env.CLAUDECODE; else process.env.CLAUDECODE = original; }
|
|
374
|
-
assert.equal(status(f.project, "task").active.length, 1);
|
|
375
|
-
} finally { f.dispose(); }
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
test("source or contract changes before claim make the reservation stale", () => {
|
|
379
|
-
const f = fixture();
|
|
380
|
-
try {
|
|
381
|
-
f.task("source");
|
|
382
|
-
const source = reserve(f.project, "source", f.request("analysis"));
|
|
383
|
-
f.write("Assets/game.cs", "// changed after reserve\n");
|
|
384
|
-
assert.throws(() => claim(f.project, source.id, { sessionId: "s", toolUseId: "u", agent: agents.analysis }), /stale|snapshot|changed/i);
|
|
385
|
-
f.task("contract");
|
|
386
|
-
const contract = reserve(f.project, "contract", f.request("analysis"));
|
|
387
|
-
const changed = json(path.join(f.project, ".nccgs/tasks/contract.json"));
|
|
388
|
-
changed.contractHash = hash("changed contract");
|
|
389
|
-
atomicJson(path.join(f.project, ".nccgs/tasks/contract.json"), changed);
|
|
390
|
-
assert.throws(() => claim(f.project, contract.id, { sessionId: "s", toolUseId: "v", agent: agents.analysis }), /contract|stale|changed/i);
|
|
391
|
-
} finally { f.dispose(); }
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
test("completion rejects stale, mismatched or corrupt durable evidence without releasing the slot", () => {
|
|
395
|
-
const f = fixture();
|
|
396
|
-
try {
|
|
397
|
-
f.task("task");
|
|
398
|
-
const run = f.start("task");
|
|
399
|
-
for (const override of [{ sessionId: "foreign-session" }, { toolUseId: "foreign-tool" }, { dispatchId: "foreign-dispatch" }, { taskId: "foreign-task" }, { contractHash: "foreign-contract" }, { snapshot: "stale-snapshot" }, { observedProvider: "codex" }]) {
|
|
400
|
-
assert.throws(() => complete(f.project, run.reservation.id, { runtime: f.observation(run, override) }), /identity|session|tool|dispatch|task|contract|snapshot|provider|Claude|stale|match/i);
|
|
401
|
-
assert.equal(status(f.project, "task").active.length, 1);
|
|
402
|
-
}
|
|
403
|
-
assert.throws(() => complete(f.project, run.reservation.id, { runtime: f.observation(run, { durationMs: 0 }, { durationMs: 100 }) }), /source|observation|duration|telemetry|match/i);
|
|
404
|
-
const runtime = f.observation(run);
|
|
405
|
-
const observation = json(path.join(f.project, runtime.path));
|
|
406
|
-
fs.appendFileSync(path.join(f.project, observation.observationSource.path), "\ncorruption");
|
|
407
|
-
assert.throws(() => complete(f.project, run.reservation.id, { runtime }), /artifact|hash|source|stale|JSON/i);
|
|
408
|
-
assert.equal(status(f.project, "task").active.length, 1);
|
|
409
|
-
} finally { f.dispose(); }
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
test("an analysis worker source mutation is retained as failure, never successful completion", () => {
|
|
413
|
-
const f = fixture();
|
|
414
|
-
try {
|
|
415
|
-
f.task("task", { mode: "audit" });
|
|
416
|
-
const run = f.start("task");
|
|
417
|
-
f.write("Assets/game.cs", "// forbidden analysis mutation\n");
|
|
418
|
-
complete(f.project, run.reservation.id, { runtime: f.observation(run) });
|
|
419
|
-
const entry = status(f.project, "task").reservations.find(item => item.id === run.reservation.id);
|
|
420
|
-
assert.equal(entry.status, "failed");
|
|
421
|
-
assert.equal(status(f.project, "task").usage.dispatches, 1);
|
|
422
|
-
} finally { f.dispose(); }
|
|
423
|
-
});
|
|
424
|
-
|
|
425
|
-
test("a failed provider observation releases concurrency but still consumes its dispatch", () => {
|
|
426
|
-
const f = fixture();
|
|
427
|
-
try {
|
|
428
|
-
f.task("task");
|
|
429
|
-
const run = f.start("task", f.request("implementation", { limits: { maxDispatches: 1 } }));
|
|
430
|
-
complete(f.project, run.reservation.id, { runtime: f.observation(run, { status: "failed", durationMs: 17 }) });
|
|
431
|
-
const result = status(f.project, "task");
|
|
432
|
-
assert.equal(result.active.length, 0);
|
|
433
|
-
assert.equal(result.reservations[0].status, "failed");
|
|
434
|
-
assert.equal(result.usage.dispatches, 1);
|
|
435
|
-
assert.equal(telemetry(f.project, "task").metrics.durationMs.total, 17);
|
|
436
|
-
assert.throws(() => reserve(f.project, "task", f.request("implementation")), /budget|quota|dispatch|limit/i);
|
|
437
|
-
} finally { f.dispose(); }
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
test("unknown telemetry remains null while observed zero stays measured zero", () => {
|
|
441
|
-
const f = fixture();
|
|
442
|
-
try {
|
|
443
|
-
f.task("unknown");
|
|
444
|
-
const unknown = f.start("unknown");
|
|
445
|
-
complete(f.project, unknown.reservation.id, { runtime: f.observation(unknown) });
|
|
446
|
-
const missing = telemetry(f.project, "unknown");
|
|
447
|
-
for (const key of ["durationMs", "toolUseCount", "totalTokens", "costUsd"]) {
|
|
448
|
-
assert.equal(missing.metrics[key].total, null, key);
|
|
449
|
-
assert.equal(missing.metrics[key].measured, 0, key);
|
|
450
|
-
assert.equal(missing.metrics[key].expected, 1, key);
|
|
451
|
-
assert.equal(missing.metrics[key].coverage, 0, key);
|
|
452
|
-
}
|
|
453
|
-
f.task("zero");
|
|
454
|
-
const zero = f.start("zero");
|
|
455
|
-
complete(f.project, zero.reservation.id, { runtime: f.observation(zero, { durationMs: 0, toolUseCount: 0, totalTokens: 0, costUsd: 0 }) });
|
|
456
|
-
for (const key of ["durationMs", "toolUseCount", "totalTokens", "costUsd"]) {
|
|
457
|
-
assert.equal(telemetry(f.project, "zero").metrics[key].total, 0, key);
|
|
458
|
-
assert.equal(telemetry(f.project, "zero").metrics[key].measured, 1, key);
|
|
459
|
-
}
|
|
460
|
-
} finally { f.dispose(); }
|
|
461
|
-
});
|
|
462
|
-
|
|
463
|
-
test("corrupt orchestration ledger fails closed instead of resetting quotas", () => {
|
|
464
|
-
const f = fixture();
|
|
465
|
-
try {
|
|
466
|
-
f.task("task");
|
|
467
|
-
reserve(f.project, "task", f.request("analysis", { limits: { maxDispatches: 1 } }));
|
|
468
|
-
f.write(".nccgs/orchestration.json", "{ broken durable ledger");
|
|
469
|
-
assert.throws(() => status(f.project, "task"), /JSON|corrupt|ledger|Unexpected|property/i);
|
|
470
|
-
assert.throws(() => reserve(f.project, "task", f.request("analysis")), /JSON|corrupt|ledger|Unexpected|property/i);
|
|
471
|
-
assert.equal(fs.readFileSync(path.join(f.project, ".nccgs/orchestration.json"), "utf8"), "{ broken durable ledger");
|
|
472
|
-
} finally { f.dispose(); }
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
test("losing an initialized ledger cannot silently restore exhausted dispatch quota", () => {
|
|
476
|
-
const f = fixture();
|
|
477
|
-
try {
|
|
478
|
-
f.task("task");
|
|
479
|
-
const run = f.start("task", f.request("analysis", { limits: { maxDispatches: 1 } }));
|
|
480
|
-
complete(f.project, run.reservation.id, { runtime: f.observation(run) });
|
|
481
|
-
fs.unlinkSync(path.join(f.project, ".nccgs/orchestration.json"));
|
|
482
|
-
assert.throws(() => reserve(f.project, "task", f.request("analysis")), /ledger|missing|history|recover|initial/i);
|
|
483
|
-
} finally { f.dispose(); }
|
|
484
|
-
});
|
|
485
|
-
|
|
486
|
-
test("a lost dispatch entry with surviving history cannot refund spent quota", () => {
|
|
487
|
-
const f = fixture();
|
|
488
|
-
try {
|
|
489
|
-
f.task("task");
|
|
490
|
-
const run = f.start("task", f.request("analysis", { limits: { maxDispatches: 1 } }));
|
|
491
|
-
complete(f.project, run.reservation.id, { runtime: f.observation(run) });
|
|
492
|
-
const file = path.join(f.project, ".nccgs/orchestration.json");
|
|
493
|
-
const ledger = json(file);
|
|
494
|
-
delete ledger.dispatches[run.reservation.id];
|
|
495
|
-
atomicJson(file, ledger);
|
|
496
|
-
assert.throws(() => reserve(f.project, "task", f.request("analysis")), /ledger|history|corrupt|dispatch|event/i);
|
|
497
|
-
} finally { f.dispose(); }
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
test("durable observations cannot complete against an ignored raw source", () => {
|
|
501
|
-
const f = fixture();
|
|
502
|
-
try {
|
|
503
|
-
f.task("task");
|
|
504
|
-
const run = f.start("task");
|
|
505
|
-
const good = f.observation(run);
|
|
506
|
-
const observation = json(path.join(f.project, good.path));
|
|
507
|
-
const sourceBytes = fs.readFileSync(path.join(f.project, observation.observationSource.path));
|
|
508
|
-
observation.observationSource = f.write(".nccgs/runtime/ignored-source.json", sourceBytes);
|
|
509
|
-
const runtime = f.write(".nccgs/evidence/runtime/observations/ignored-source-ref.json", observation);
|
|
510
|
-
assert.throws(() => complete(f.project, run.reservation.id, { runtime }), /durable|source|runtime/i);
|
|
511
|
-
assert.equal(status(f.project, "task").active.length, 1);
|
|
512
|
-
} finally { f.dispose(); }
|
|
513
|
-
});
|
|
514
|
-
|
|
515
|
-
test("valid task IDs that match object prototype properties can reserve normally", () => {
|
|
516
|
-
const f = fixture();
|
|
517
|
-
try {
|
|
518
|
-
for (const id of ["constructor", "toString"]) {
|
|
519
|
-
f.task(id);
|
|
520
|
-
assert.ok(reserve(f.project, id, f.request("analysis")).id);
|
|
521
|
-
assert.equal(status(f.project, id).reservations.length, 1);
|
|
522
|
-
}
|
|
523
|
-
} finally { f.dispose(); }
|
|
524
|
-
});
|
|
525
|
-
|
|
526
|
-
test("telemetry fails closed when the durable evidence behind measured totals is lost or corrupt", () => {
|
|
527
|
-
const f = fixture();
|
|
528
|
-
try {
|
|
529
|
-
f.task("task");
|
|
530
|
-
const run = f.start("task");
|
|
531
|
-
const runtime = f.observation(run, { durationMs: 31 });
|
|
532
|
-
complete(f.project, run.reservation.id, { runtime });
|
|
533
|
-
assert.equal(telemetry(f.project, "task").metrics.durationMs.total, 31);
|
|
534
|
-
const observation = json(path.join(f.project, runtime.path));
|
|
535
|
-
const sourcePath = path.join(f.project, observation.observationSource.path);
|
|
536
|
-
const originalBytes = fs.readFileSync(sourcePath);
|
|
537
|
-
fs.unlinkSync(sourcePath);
|
|
538
|
-
assert.throws(() => telemetry(f.project, "task"), /ENOENT|artifact|evidence|source|missing/i);
|
|
539
|
-
fs.writeFileSync(sourcePath, Buffer.concat([originalBytes, Buffer.from("\ncorrupt")]));
|
|
540
|
-
assert.throws(() => telemetry(f.project, "task"), /artifact|evidence|source|hash|stale/i);
|
|
541
|
-
} finally { f.dispose(); }
|
|
542
|
-
});
|
|
543
|
-
|
|
544
|
-
function nativeFixtureEvent(run) {
|
|
545
|
-
return { session_id: run.identity.sessionId, tool_use_id: run.identity.toolUseId,
|
|
546
|
-
tool_input: { subagent_type: run.request.agent, prompt: `[NCCGS-DISPATCH:${run.reservation.id}] SYNTHETIC TEST FIXTURE ONLY` },
|
|
547
|
-
tool_response: { status: "completed", agentId: `agent-${run.reservation.id}`, resolvedModel: "claude-opus-5-5",
|
|
548
|
-
modelsUsed: ["claude-opus-5-5"], totalDurationMs: 23, totalToolUseCount: 2, totalTokens: 10 } };
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
test("native standalone observation produces provenance accepted by runtime validation", () => {
|
|
552
|
-
const f = fixture();
|
|
553
|
-
try {
|
|
554
|
-
const task = f.task("task", { execution: { requireObservedEffort: false } });
|
|
555
|
-
const run = f.start("task", f.request("analysis", { agent: agents.implementation }));
|
|
556
|
-
const observation = observe(f.project, nativeFixtureEvent(run), "agent_result");
|
|
557
|
-
const stage = { runtime: artifact(f.project, observation.path) };
|
|
558
|
-
const verified = validateStandaloneRuntime(f.project, task, stage, task.implementationRoute, snapshot(f.project).sha256);
|
|
559
|
-
assert.equal(verified.observedProvider, "claude-code");
|
|
560
|
-
assert.equal(verified.observedEffort, null);
|
|
561
|
-
assert.equal(verified.effortEvidence, "UNKNOWN");
|
|
562
|
-
} finally { f.dispose(); }
|
|
563
|
-
});
|
|
564
|
-
|
|
565
|
-
test("duplicate native terminal callback is idempotent and keeps the original dispatch evidence", () => {
|
|
566
|
-
const f = fixture();
|
|
567
|
-
try {
|
|
568
|
-
f.task("task");
|
|
569
|
-
const run = f.start("task", f.request("analysis", { agent: agents.implementation }));
|
|
570
|
-
const event = nativeFixtureEvent(run);
|
|
571
|
-
observe(f.project, event, "agent_result");
|
|
572
|
-
const before = status(f.project, "task").reservations[0];
|
|
573
|
-
assert.doesNotThrow(() => observe(f.project, structuredClone(event), "agent_result"));
|
|
574
|
-
const after = status(f.project, "task").reservations[0];
|
|
575
|
-
assert.deepEqual(after.runtime, before.runtime);
|
|
576
|
-
assert.equal(telemetry(f.project, "task").attempts, 1);
|
|
577
|
-
assert.equal(telemetry(f.project, "task").metrics.durationMs.total, 23);
|
|
578
|
-
} finally { f.dispose(); }
|
|
579
|
-
});
|
|
580
|
-
|
|
581
|
-
test("coordinator verification allowance cannot hide trailing shell commands", () => {
|
|
582
|
-
const f = fixture();
|
|
583
|
-
const savedTask = process.env.NCCGS_TASK_ID;
|
|
584
|
-
try {
|
|
585
|
-
f.task("task");
|
|
586
|
-
process.env.NCCGS_TASK_ID = "task";
|
|
587
|
-
for (const suffix of ["; echo injected", " && echo injected", " | echo injected", "\necho injected"]) {
|
|
588
|
-
assert.throws(() => guardTool(f.project, { session_id: "coordinator", tool_name: "Bash", tool_input: {
|
|
589
|
-
command: `node .claude/nccgs/tools/task.mjs verify --id task --name regression -- node -e 0${suffix}`
|
|
590
|
-
} }), /shell|compos|verif|command|correlat|worker|blocked|unsafe/i);
|
|
591
|
-
}
|
|
592
|
-
} finally {
|
|
593
|
-
if (savedTask === undefined) delete process.env.NCCGS_TASK_ID; else process.env.NCCGS_TASK_ID = savedTask;
|
|
594
|
-
f.dispose();
|
|
595
|
-
}
|
|
596
|
-
});
|