nccgs 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/.claude/agents/nccgs-adversarial-reviewer.md +7 -1
  2. package/.claude/agents/nccgs-engine-programmer.md +2 -1
  3. package/.claude/agents/nccgs-gameplay-programmer.md +2 -1
  4. package/.claude/agents/nccgs-qa-engineer.md +2 -1
  5. package/.claude/agents/nccgs-ui-programmer.md +2 -1
  6. package/.claude/agents/nccgs-unity-build-specialist.md +2 -1
  7. package/.claude/agents/nccgs-unity-implementer.md +2 -1
  8. package/.claude/agents/nccgs-unity-systems-specialist.md +2 -1
  9. package/.claude/agents/nccgs-unity-ui-specialist.md +2 -1
  10. package/.claude/agents/nccgs-verification-engineer.md +2 -1
  11. package/.claude/nccgs/VERSION +1 -1
  12. package/.claude/{agents → nccgs/agent-library}/nccgs-accessibility-specialist.md +0 -1
  13. package/.claude/nccgs/agent-library/nccgs-adversarial-reviewer.md +30 -0
  14. package/.claude/{agents → nccgs/agent-library}/nccgs-ai-programmer.md +0 -1
  15. package/.claude/{agents → nccgs/agent-library}/nccgs-analytics-engineer.md +0 -1
  16. package/.claude/{agents → nccgs/agent-library}/nccgs-art-direction-lead.md +0 -1
  17. package/.claude/{agents → nccgs/agent-library}/nccgs-audio-direction-lead.md +0 -1
  18. package/.claude/{agents → nccgs/agent-library}/nccgs-creative-director.md +0 -1
  19. package/.claude/{agents → nccgs/agent-library}/nccgs-documentation-manager.md +0 -1
  20. package/.claude/{agents → nccgs/agent-library}/nccgs-economy-designer.md +0 -1
  21. package/.claude/nccgs/agent-library/nccgs-engine-programmer.md +25 -0
  22. package/.claude/{agents → nccgs/agent-library}/nccgs-game-design-lead.md +0 -1
  23. package/.claude/{agents → nccgs/agent-library}/nccgs-game-designer.md +0 -1
  24. package/.claude/nccgs/agent-library/nccgs-gameplay-programmer.md +25 -0
  25. package/.claude/{agents → nccgs/agent-library}/nccgs-level-designer.md +0 -1
  26. package/.claude/{agents → nccgs/agent-library}/nccgs-live-ops-designer.md +0 -1
  27. package/.claude/{agents → nccgs/agent-library}/nccgs-localization-lead.md +0 -1
  28. package/.claude/{agents → nccgs/agent-library}/nccgs-narrative-lead.md +0 -1
  29. package/.claude/{agents → nccgs/agent-library}/nccgs-network-programmer.md +0 -1
  30. package/.claude/{agents → nccgs/agent-library}/nccgs-performance-analyst.md +0 -1
  31. package/.claude/{agents → nccgs/agent-library}/nccgs-producer.md +0 -1
  32. package/.claude/{agents → nccgs/agent-library}/nccgs-production-coordinator.md +0 -1
  33. package/.claude/{agents → nccgs/agent-library}/nccgs-programming-lead.md +0 -1
  34. package/.claude/{agents → nccgs/agent-library}/nccgs-prototyper.md +0 -1
  35. package/.claude/nccgs/agent-library/nccgs-qa-engineer.md +25 -0
  36. package/.claude/{agents → nccgs/agent-library}/nccgs-qa-lead.md +0 -1
  37. package/.claude/{agents → nccgs/agent-library}/nccgs-release-engineer.md +0 -1
  38. package/.claude/{agents → nccgs/agent-library}/nccgs-release-lead.md +0 -1
  39. package/.claude/{agents → nccgs/agent-library}/nccgs-security-engineer.md +0 -1
  40. package/.claude/{agents → nccgs/agent-library}/nccgs-sound-designer.md +0 -1
  41. package/.claude/{agents → nccgs/agent-library}/nccgs-systems-designer.md +0 -1
  42. package/.claude/{agents → nccgs/agent-library}/nccgs-technical-architect.md +0 -1
  43. package/.claude/{agents → nccgs/agent-library}/nccgs-technical-artist.md +0 -1
  44. package/.claude/{agents → nccgs/agent-library}/nccgs-technical-director.md +0 -1
  45. package/.claude/{agents → nccgs/agent-library}/nccgs-tools-programmer.md +0 -1
  46. package/.claude/nccgs/agent-library/nccgs-ui-programmer.md +25 -0
  47. package/.claude/nccgs/agent-library/nccgs-unity-build-specialist.md +25 -0
  48. package/.claude/{agents → nccgs/agent-library}/nccgs-unity-content-specialist.md +0 -1
  49. package/.claude/nccgs/agent-library/nccgs-unity-implementer.md +25 -0
  50. package/.claude/{agents → nccgs/agent-library}/nccgs-unity-rendering-specialist.md +0 -1
  51. package/.claude/nccgs/agent-library/nccgs-unity-systems-specialist.md +25 -0
  52. package/.claude/nccgs/agent-library/nccgs-unity-ui-specialist.md +25 -0
  53. package/.claude/{agents → nccgs/agent-library}/nccgs-ux-designer.md +0 -1
  54. package/.claude/nccgs/agent-library/nccgs-verification-engineer.md +25 -0
  55. package/.claude/{agents → nccgs/agent-library}/nccgs-world-builder.md +0 -1
  56. package/.claude/{agents → nccgs/agent-library}/nccgs-writer.md +0 -1
  57. package/.claude/nccgs/constitution.md +13 -0
  58. package/.claude/nccgs/hooks/agent-audit.mjs +6 -0
  59. package/.claude/nccgs/hooks/closure-guard.mjs +34 -0
  60. package/.claude/nccgs/hooks/runtime-observation.mjs +11 -0
  61. package/.claude/nccgs/hooks/session-start.mjs +8 -1
  62. package/.claude/nccgs/pipeline.json +176 -0
  63. package/.claude/nccgs/protocols/agent-contract.md +5 -0
  64. package/.claude/nccgs/protocols/astra-claude.md +77 -0
  65. package/.claude/nccgs/protocols/evidence.md +6 -0
  66. package/.claude/nccgs/protocols/model-routing.md +27 -5
  67. package/.claude/nccgs/protocols/orchestration.md +5 -0
  68. package/.claude/nccgs/protocols/task-gates.md +66 -0
  69. package/.claude/nccgs/routing.generated.md +11 -0
  70. package/.claude/nccgs/settings.fragment.json +73 -9
  71. package/.claude/nccgs/studio.json +187 -96
  72. package/.claude/nccgs/tools/approve-overrides.mjs +81 -0
  73. package/.claude/nccgs/tools/compile-policy.mjs +83 -0
  74. package/.claude/nccgs/tools/configure-models.mjs +76 -31
  75. package/.claude/nccgs/tools/gates.mjs +167 -0
  76. package/.claude/nccgs/tools/integrity.mjs +69 -0
  77. package/.claude/nccgs/tools/policy.mjs +62 -0
  78. package/.claude/nccgs/tools/runtime.mjs +40 -0
  79. package/.claude/nccgs/tools/task.mjs +77 -0
  80. package/.claude/nccgs/workflow-catalog.json +91 -14
  81. package/.claude/skills/accessibility-review/SKILL.md +6 -5
  82. package/.claude/skills/accessibility-review/references/astra.md +17 -0
  83. package/.claude/skills/accessibility-review/references/legacy.md +7 -0
  84. package/.claude/skills/architecture-decision/SKILL.md +6 -5
  85. package/.claude/skills/architecture-decision/references/astra.md +12 -0
  86. package/.claude/skills/architecture-decision/references/legacy.md +7 -0
  87. package/.claude/skills/asset-audit/SKILL.md +6 -5
  88. package/.claude/skills/asset-audit/references/astra.md +17 -0
  89. package/.claude/skills/asset-audit/references/legacy.md +7 -0
  90. package/.claude/skills/audit/SKILL.md +6 -7
  91. package/.claude/skills/audit/references/astra.md +17 -0
  92. package/.claude/skills/audit/references/legacy.md +9 -0
  93. package/.claude/skills/balance-review/SKILL.md +6 -5
  94. package/.claude/skills/balance-review/references/astra.md +17 -0
  95. package/.claude/skills/balance-review/references/legacy.md +7 -0
  96. package/.claude/skills/bug-triage/SKILL.md +6 -5
  97. package/.claude/skills/bug-triage/references/astra.md +20 -0
  98. package/.claude/skills/bug-triage/references/legacy.md +7 -0
  99. package/.claude/skills/closure/SKILL.md +5 -4
  100. package/.claude/skills/closure/references/astra.md +15 -0
  101. package/.claude/skills/closure/references/legacy.md +7 -0
  102. package/.claude/skills/compatibility-review/SKILL.md +6 -5
  103. package/.claude/skills/compatibility-review/references/astra.md +17 -0
  104. package/.claude/skills/compatibility-review/references/legacy.md +7 -0
  105. package/.claude/skills/context-pack/SKILL.md +5 -4
  106. package/.claude/skills/context-pack/references/astra.md +12 -0
  107. package/.claude/skills/context-pack/references/legacy.md +7 -0
  108. package/.claude/skills/dependency-review/SKILL.md +6 -5
  109. package/.claude/skills/dependency-review/references/astra.md +17 -0
  110. package/.claude/skills/dependency-review/references/legacy.md +7 -0
  111. package/.claude/skills/design/SKILL.md +6 -11
  112. package/.claude/skills/design/references/astra.md +12 -0
  113. package/.claude/skills/design/references/legacy.md +13 -0
  114. package/.claude/skills/design-review/SKILL.md +6 -5
  115. package/.claude/skills/design-review/references/astra.md +17 -0
  116. package/.claude/skills/design-review/references/legacy.md +7 -0
  117. package/.claude/skills/evidence-review/SKILL.md +6 -5
  118. package/.claude/skills/evidence-review/references/astra.md +17 -0
  119. package/.claude/skills/evidence-review/references/legacy.md +7 -0
  120. package/.claude/skills/hotfix/SKILL.md +6 -5
  121. package/.claude/skills/hotfix/references/astra.md +23 -0
  122. package/.claude/skills/hotfix/references/legacy.md +7 -0
  123. package/.claude/skills/incident-recovery/SKILL.md +6 -5
  124. package/.claude/skills/incident-recovery/references/astra.md +20 -0
  125. package/.claude/skills/incident-recovery/references/legacy.md +7 -0
  126. package/.claude/skills/localize-game/SKILL.md +6 -5
  127. package/.claude/skills/localize-game/references/astra.md +20 -0
  128. package/.claude/skills/localize-game/references/legacy.md +7 -0
  129. package/.claude/skills/migrate-project/SKILL.md +6 -14
  130. package/.claude/skills/migrate-project/references/astra.md +23 -0
  131. package/.claude/skills/migrate-project/references/legacy.md +19 -0
  132. package/.claude/skills/migrate-project/references/procedure.md +21 -1
  133. package/.claude/skills/milestone-review/SKILL.md +6 -5
  134. package/.claude/skills/milestone-review/references/astra.md +12 -0
  135. package/.claude/skills/milestone-review/references/legacy.md +7 -0
  136. package/.claude/skills/nccgs-code-review/SKILL.md +15 -0
  137. package/.claude/skills/nccgs-code-review/references/astra.md +15 -0
  138. package/.claude/skills/{code-review/SKILL.md → nccgs-code-review/references/legacy.md} +0 -7
  139. package/.claude/skills/performance-audit/SKILL.md +6 -5
  140. package/.claude/skills/performance-audit/references/astra.md +17 -0
  141. package/.claude/skills/performance-audit/references/legacy.md +7 -0
  142. package/.claude/skills/plan-feature/SKILL.md +6 -5
  143. package/.claude/skills/plan-feature/references/astra.md +12 -0
  144. package/.claude/skills/plan-feature/references/legacy.md +7 -0
  145. package/.claude/skills/playtest/SKILL.md +5 -4
  146. package/.claude/skills/playtest/references/astra.md +20 -0
  147. package/.claude/skills/playtest/references/legacy.md +7 -0
  148. package/.claude/skills/project-stage/SKILL.md +5 -4
  149. package/.claude/skills/project-stage/references/astra.md +12 -0
  150. package/.claude/skills/project-stage/references/legacy.md +7 -0
  151. package/.claude/skills/prototype-feature/SKILL.md +6 -5
  152. package/.claude/skills/prototype-feature/references/astra.md +20 -0
  153. package/.claude/skills/prototype-feature/references/legacy.md +7 -0
  154. package/.claude/skills/qa-plan/SKILL.md +6 -5
  155. package/.claude/skills/qa-plan/references/astra.md +12 -0
  156. package/.claude/skills/qa-plan/references/legacy.md +7 -0
  157. package/.claude/skills/release/SKILL.md +6 -9
  158. package/.claude/skills/release/references/astra.md +23 -0
  159. package/.claude/skills/release/references/legacy.md +11 -0
  160. package/.claude/skills/release-readiness/SKILL.md +6 -5
  161. package/.claude/skills/release-readiness/references/astra.md +17 -0
  162. package/.claude/skills/release-readiness/references/legacy.md +7 -0
  163. package/.claude/skills/retrospective/SKILL.md +6 -5
  164. package/.claude/skills/retrospective/references/astra.md +12 -0
  165. package/.claude/skills/retrospective/references/legacy.md +7 -0
  166. package/.claude/skills/review/SKILL.md +6 -7
  167. package/.claude/skills/review/references/astra.md +15 -0
  168. package/.claude/skills/review/references/legacy.md +9 -0
  169. package/.claude/skills/security-audit/SKILL.md +6 -5
  170. package/.claude/skills/security-audit/references/astra.md +17 -0
  171. package/.claude/skills/security-audit/references/legacy.md +7 -0
  172. package/.claude/skills/sprint-plan/SKILL.md +6 -5
  173. package/.claude/skills/sprint-plan/references/astra.md +12 -0
  174. package/.claude/skills/sprint-plan/references/legacy.md +7 -0
  175. package/.claude/skills/status/SKILL.md +5 -6
  176. package/.claude/skills/status/references/astra.md +13 -0
  177. package/.claude/skills/status/references/legacy.md +9 -0
  178. package/.claude/skills/story-readiness/SKILL.md +5 -4
  179. package/.claude/skills/story-readiness/references/astra.md +17 -0
  180. package/.claude/skills/story-readiness/references/legacy.md +7 -0
  181. package/.claude/skills/test/SKILL.md +6 -7
  182. package/.claude/skills/test/references/astra.md +20 -0
  183. package/.claude/skills/test/references/legacy.md +9 -0
  184. package/.claude/skills/ui-review/SKILL.md +6 -5
  185. package/.claude/skills/ui-review/references/astra.md +17 -0
  186. package/.claude/skills/ui-review/references/legacy.md +7 -0
  187. package/.claude/skills/work/SKILL.md +6 -27
  188. package/.claude/skills/work/references/astra.md +20 -0
  189. package/.claude/skills/work/references/closure.md +10 -0
  190. package/.claude/skills/work/references/feature-contracts.md +4 -0
  191. package/.claude/skills/work/references/legacy.md +29 -0
  192. package/README.md +67 -29
  193. package/UPGRADING.md +54 -4
  194. package/VERSION +1 -1
  195. package/docs/ARCHITECTURE.md +30 -13
  196. package/docs/HUONG-DAN-MIGRATE-VA-SU-DUNG.md +34 -322
  197. package/docs/MIGRATION-MATRIX.md +1 -1
  198. package/docs/NCCGS-1.3.md +125 -0
  199. package/docs/PROJECT-POLICY.md +18 -3
  200. package/docs/WORKFLOWS.md +20 -14
  201. package/package-assets/nccgs-project.gitignore +2 -0
  202. package/package.json +5 -3
  203. package/scaffold/.nccgs/gates.json +7 -0
  204. package/scaffold/.nccgs/project.yaml +6 -3
  205. package/scaffold/.nccgs/state.md +1 -1
  206. package/scaffold/.nccgs/templates/agent-handoff.md +10 -0
  207. package/scaffold/.nccgs/templates/closure-record.md +11 -0
  208. package/scaffold/.nccgs/templates/feature-contract.md +9 -0
  209. package/scaffold/.nccgs/templates/implementation-report.md +49 -0
  210. package/scripts/cli.mjs +10 -5
  211. package/scripts/doctor.mjs +102 -18
  212. package/scripts/install.mjs +221 -88
  213. package/scripts/validate.mjs +34 -6
  214. package/tests/framework.test.mjs +213 -8
  215. package/tests/gates.test.mjs +170 -0
@@ -8,7 +8,7 @@ verification, closure, or Unity execution for the project.
8
8
 
9
9
  - project stage and platforms;
10
10
  - enabled departments and bounded orchestration;
11
- - `quality`, `balanced`, or `inherit` model profile and fallback policy;
11
+ - `astra-claude`, `quality`, `balanced`, or `inherit` model profile and fallback policy;
12
12
  - canonical sources for product, design, architecture, planning, art, narrative,
13
13
  audio, and release;
14
14
  - protected/user-owned/generated paths and hand-tuned settings;
@@ -19,13 +19,28 @@ verification, closure, or Unity execution for the project.
19
19
 
20
20
  ## Model policy
21
21
 
22
+ The default `astra-claude` profile assigns planning and canonical documents to Astra,
23
+ implementation to pinned Opus 5.5/xhigh, and independent review to Fable/high.
24
+ The report is handed to Astra only after Fable PASS; Astra checks it before Product
25
+ Owner acceptance. All these gates apply even to FAST work and lean closure. See
26
+ [the protocol](../.claude/nccgs/protocols/astra-claude.md). No silent inherited model
27
+ or lower effort may satisfy a required stage. Legacy profile selection explicitly
28
+ opts out of this chain and ordinary updates preserve the existing selection.
29
+
22
30
  Use `quality` when result quality is primary and all model tiers are available. Use
23
31
  `balanced` when leadership coordination does not need Opus by default. Use `inherit`
24
32
  when subscription/context compatibility or explicit user control is more important
25
33
  than automatic routing.
26
34
 
27
- Project overrides may pin a specific role/class, but avoid full model IDs unless the
28
- project intentionally owns upgrade timing.
35
+ The `models.overrides` field is reserved; the configurator does not apply it. Routing
36
+ is compiled from `.claude/nccgs/pipeline.json`. The astra-claude profile intentionally
37
+ pins Opus 5.5; changing its required stage models is a Product Owner policy decision.
38
+
39
+ For the Astra profile, map the checks, artifacts and manual gates below into
40
+ `.nccgs/gates.json` and pin its `policySha256` to this project policy. Task-specific
41
+ requirements may add obligations. The executable manifest does not automatically
42
+ translate YAML conditions: Astra must preserve and map all existing safeguards.
43
+ See [task gates](../.claude/nccgs/protocols/task-gates.md) for evidence formats.
29
44
 
30
45
  ## Canonical sources and context
31
46
 
package/docs/WORKFLOWS.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # NCCGS workflows
2
2
 
3
+ The default `astra-claude` profile applies the
4
+ [Astra/Claude handoff protocol](../.claude/nccgs/protocols/astra-claude.md) to every
5
+ workflow below. Astra owns planning and documents; Claude implements with
6
+ Opus 5.5/xhigh; Fable/high independently reviews before the report goes to Astra.
7
+ Astra checks the report and the Product Owner accepts before DONE. Each dispatcher
8
+ loads only `references/astra.md` or `references/legacy.md` for the selected profile.
9
+ Task records and executable gates follow the [1.3 guide](NCCGS-1.3.md).
10
+
3
11
  ## Risk tiers
4
12
 
5
13
  | Tier | Typical work | Required structure |
@@ -11,16 +19,13 @@
11
19
  ## End-to-end work
12
20
 
13
21
  ```text
14
- request
15
- -> risk and domain routing
16
- -> context packet and readiness
17
- -> decisions/plan when needed
22
+ request -> Astra plan/documents and gate manifest
23
+ -> Claude risk/domain routing and context readiness
18
24
  -> one-owner implementation nodes
19
- -> independent verification
20
- -> adversarial review for CONTROLLED work
21
- -> evidence review
22
- -> record synchronization
23
- -> configured closure
25
+ -> verification evidence
26
+ -> independent Fable review for every code change
27
+ -> report -> Astra check -> Product Owner acceptance
28
+ -> task close after all executable gates pass
24
29
  ```
25
30
 
26
31
  The primary session composes modules automatically. Explicit specialized commands are
@@ -33,7 +38,7 @@ available when a user wants a bounded workflow or output.
33
38
  - **Design**: `design`, `design-review`, `balance-review`, `accessibility-review`,
34
39
  `ui-review`, `prototype-feature`, `playtest`.
35
40
  - **Technical**: `architecture-decision`, `dependency-review`,
36
- `compatibility-review`, `code-review`, `performance-audit`, `security-audit`.
41
+ `compatibility-review`, `nccgs-code-review`, `performance-audit`, `security-audit`.
37
42
  - **Implementation/quality**: `work`, `qa-plan`, `test`, `bug-triage`,
38
43
  `evidence-review`, `review`, `asset-audit`, `closure`.
39
44
  - **Delivery/recovery**: `release-readiness`, `release`, `hotfix`,
@@ -42,14 +47,15 @@ available when a user wants a bounded workflow or output.
42
47
 
43
48
  ## Role composition examples
44
49
 
45
- A gameplay feature may use game designer → gameplay programmer and Unity systems
50
+ Astra plans a gameplay feature; optional game-designer consultation may support it.
51
+ Implementation may use gameplay programmer and Unity systems
46
52
  specialist in parallel where ownership differs → verification engineer. A UI feature
47
53
  may use UX designer and accessibility specialist for design, UI programmer and Unity
48
54
  UI specialist for implementation/integration, then independent verification.
49
55
 
50
- CONTROLLED network-save work adds technical architect, network programmer, security
51
- engineer, compatibility review, and adversarial review. It does not automatically
52
- spawn every director or department.
56
+ CONTROLLED network-save work can enable optional technical architect, network
57
+ programmer and security engineer roles. Fable reviews FAST, STANDARD and CONTROLLED
58
+ code changes. Optional roles are activated explicitly; the default loads ten roles.
53
59
 
54
60
  ## Evidence states
55
61
 
@@ -0,0 +1,2 @@
1
+ backups/
2
+ runtime/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nccgs",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Unity-first game-studio operating system for Claude Code",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -29,8 +29,10 @@
29
29
  },
30
30
  "scripts": {
31
31
  "validate": "node scripts/validate.mjs",
32
- "test": "node --test tests/framework.test.mjs",
33
- "pack:check": "npm pack --dry-run"
32
+ "test": "node --test tests/*.test.mjs",
33
+ "pack:check": "npm pack --dry-run",
34
+ "policy:build": "node .claude/nccgs/tools/compile-policy.mjs --write",
35
+ "policy:check": "node .claude/nccgs/tools/compile-policy.mjs"
34
36
  },
35
37
  "keywords": [
36
38
  "claude-code",
@@ -0,0 +1,7 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "policySha256": null,
4
+ "requiredChecks": [],
5
+ "requiredArtifacts": [],
6
+ "manualGates": []
7
+ }
@@ -15,12 +15,15 @@ studio:
15
15
  independent_verification: true
16
16
 
17
17
  models:
18
- profile: quality
19
- allow_inherit_fallback: true
20
- allow_automatic_escalation: true
18
+ profile: astra-claude
19
+ allow_inherit_fallback: false
20
+ allow_automatic_escalation: false
21
21
  notify_on_escalation: true
22
22
  overrides: {}
23
23
 
24
+ # Profile contracts are resolved from this canonical configuration.
25
+ pipeline_policy: .claude/nccgs/pipeline.json
26
+
24
27
  workflow:
25
28
  operating_mode: solo
26
29
  autonomy: high
@@ -14,7 +14,7 @@ Updated: [timestamp]
14
14
 
15
15
  - Last completed checkpoint: NCCGS initialized
16
16
  - Current step: configure or migrate project policy
17
- - Next safe action: run `/migrate-project review` for an existing project
17
+ - Next safe action: Astra prepares project policy, gate mapping and migration plan; Claude then runs `/migrate-project`
18
18
 
19
19
  ## Decisions pending
20
20
 
@@ -23,3 +23,13 @@
23
23
  ## Next owner
24
24
 
25
25
  [role or workflow]
26
+
27
+ ## Model and review trace (astra-claude profile)
28
+
29
+ - Requested model/effort:
30
+ - Observed model/effort and session/agent reference:
31
+ - Plan and working snapshot:
32
+ - Fable review record and verdict:
33
+ - Report path for Astra (after Fable PASS only):
34
+ - Astra check: PENDING unless referenced
35
+ - Product Owner acceptance: PENDING unless explicitly referenced
@@ -49,3 +49,14 @@
49
49
  ## Known issues and residual risk
50
50
 
51
51
  - None
52
+
53
+ ## Astra/Claude chain (required for astra-claude)
54
+
55
+ - **Final snapshot**: [commit plus dirty/untracked diff or file hashes]
56
+ - **Fable review**: PENDING/PASS/CHANGES_REQUIRED/BLOCKED [record and snapshot]
57
+ - **Report to Astra**: [path; issued only after Fable PASS]
58
+ - **Astra check**: PENDING/PASS/CHANGES_REQUIRED [Astra reference and snapshot]
59
+ - **Product Owner acceptance**: PENDING/ACCEPTED/REJECTED [user reference and snapshot]
60
+ - **Current phase**: IMPLEMENTING/FABLE_REVIEW/AWAITING_ASTRA_CHECK/AWAITING_PO_ACCEPTANCE/CLOSED
61
+
62
+ All sign-offs must cover the same final snapshot. Pending or stale gates prevent DONE.
@@ -33,3 +33,12 @@
33
33
  ## Open PO decisions
34
34
 
35
35
  - None
36
+
37
+ ## Astra/Claude ownership (astra-claude profile)
38
+
39
+ - Plan and canonical documents: Astra [plan revision/reference]
40
+ - Implementation and remediation: Claude Opus 5.5 / xhigh
41
+ - Independent review: Fable / high
42
+ - Report checking and document synchronization: Astra
43
+ - Final acceptance: Product Owner [explicit decision required]
44
+ - Review/report snapshot identification: [commit plus dirty/untracked diff or hashes]
@@ -0,0 +1,49 @@
1
+ # Implementation report for Astra: [feature ID]
2
+
3
+ - **Phase**: AWAITING_ASTRA_CHECK
4
+ - **Task ID and record**: [ID; .nccgs/tasks/ID.json]
5
+ - **Report gate**: [task check --id ID --target report result]
6
+ - **Technical state**: IMPLEMENTED | VERIFIED | BLOCKED
7
+ - **Astra plan and revision**: [path/reference]
8
+ - **Implemented snapshot**: [SHA-256 from task snapshot]
9
+ - **Implementation model / effort (requested)**: [from pipeline.json]
10
+ - **Implementation model / effort (observed)**: [runtime evidence; unknown is not proof]
11
+ - **Implementation session / agent**: [ID/reference]
12
+
13
+ ## Plan compliance and changes
14
+
15
+ | Requirement | Changed files/behavior | Evidence and result | Deviations |
16
+ |---|---|---|---|
17
+ | [REQ-ID] | [change] | [direct reference] | [none or explanation] |
18
+
19
+ ## Verification
20
+
21
+ - Commands/scenarios, environment, counts, failures, skips, runtime/build results:
22
+ - Relevant regression and unverified behavior:
23
+
24
+ ## Independent Fable review
25
+
26
+ - Requested model / effort: [review route from pipeline.json]
27
+ - Observed model / effort and session / agent: [runtime evidence]
28
+ - Reviewed snapshot: [must match implemented snapshot]
29
+ - Verdict: PASS | CHANGES_REQUIRED | BLOCKED
30
+ - Review record: [path or verbatim independent findings]
31
+ - Findings, Opus fixes, repeated checks, and Fable re-review references:
32
+ - Remaining non-blocking findings and residual risk:
33
+
34
+ ## Documents for Astra
35
+
36
+ - Proposed canonical document updates with exact sections and reasons:
37
+ - Changed scope or decisions requiring Astra/Product Owner resolution:
38
+
39
+ ## Downstream decisions — stored separately
40
+
41
+ Do not amend this report after recording its hash. Astra check and Product Owner
42
+ acceptance are separate JSON evidence files linked by the task record. Both are
43
+ pending when this report is handed over; never author their decisions for them.
44
+
45
+ - Reproduction/acceptance steps:
46
+
47
+ ## Next owner
48
+
49
+ Astra. Do not mark DONE while either downstream sign-off is pending.
package/scripts/cli.mjs CHANGED
@@ -19,14 +19,16 @@ if (command === "version" || command === "--version" || command === "-v") {
19
19
  process.exit(0);
20
20
  }
21
21
 
22
- if (!new Set(["install", "update", "doctor"]).has(command)) {
22
+ if (!new Set(["install", "update", "doctor", "task", "agents", "policy"]).has(command)) {
23
23
  console.error(`Unknown command: ${command}`);
24
24
  printHelp();
25
25
  process.exit(2);
26
26
  }
27
27
 
28
- const script = command === "doctor" ? "doctor.mjs" : "install.mjs";
29
- const forwardedArgs = command === "update" ? ["--update-only", ...args] : args;
28
+ const scripts = { doctor: "doctor.mjs", task: "../.claude/nccgs/tools/task.mjs", agents: "../.claude/nccgs/tools/configure-models.mjs", policy: "../.claude/nccgs/tools/compile-policy.mjs" };
29
+ const script = scripts[command] || "install.mjs";
30
+ let forwardedArgs = command === "update" ? ["--update-only", ...args] : args;
31
+ if (command === "agents" && !args.includes("--project")) forwardedArgs = ["--project", process.cwd(), ...args];
30
32
  const result = spawnSync(process.execPath, [path.join(scriptDir, script), ...forwardedArgs], {
31
33
  cwd: process.cwd(),
32
34
  stdio: "inherit"
@@ -45,6 +47,9 @@ Usage:
45
47
  nccgs install [options]
46
48
  nccgs update [options]
47
49
  nccgs doctor [options]
50
+ nccgs task init|snapshot|ref|observe|verify|record|check|close|bind [options]
51
+ nccgs agents --enable <role> | --disable <role> [--project <directory>]
52
+ nccgs policy [--write] Check/regenerate package routing
48
53
  nccgs --version
49
54
 
50
55
  Install target:
@@ -53,8 +58,8 @@ Install target:
53
58
 
54
59
  Options:
55
60
  --dry-run Preview without writing files
56
- --force Back up and replace framework conflicts
57
- --model-profile <profile> quality, balanced, or inherit
61
+ --force Back up and discard detected project overrides
62
+ --model-profile <profile> astra-claude (default), quality, balanced, inherit
58
63
  --project <directory> Optional explicit target directory
59
64
  --allow-non-unity Allow a target without Unity markers`);
60
65
  }
@@ -1,39 +1,72 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import crypto from "node:crypto";
4
3
  import fs from "node:fs";
5
4
  import path from "node:path";
5
+ import { matchesFingerprint, sameFingerprint } from "../.claude/nccgs/tools/integrity.mjs";
6
+ import { check as checkTask, snapshot, stages } from "../.claude/nccgs/tools/gates.mjs";
7
+ import { contained, hash, json } from "../.claude/nccgs/tools/policy.mjs";
6
8
 
7
9
  const args = process.argv.slice(2);
8
10
  const projectIndex = args.indexOf("--project");
9
- const allowPolicyMigration = args.includes("--allow-policy-migration");
11
+ const allowMigrationRequired = args.includes("--allow-migration-required") || args.includes("--allow-policy-migration");
10
12
  const warnings = [];
13
+ const errors = [];
11
14
  if (projectIndex >= 0 && !args[projectIndex + 1]) {
12
15
  console.error("--project requires a directory path.");
13
16
  process.exit(2);
14
17
  }
15
18
 
16
19
  const project = projectIndex >= 0 ? path.resolve(args[projectIndex + 1]) : process.cwd();
17
- const errors = [];
18
20
  for (const marker of ["Assets", "Packages", "ProjectSettings"]) {
19
21
  if (!fs.existsSync(path.join(project, marker))) errors.push(`Missing Unity marker: ${marker}`);
20
22
  }
21
23
 
22
24
  const statePath = path.join(project, ".claude", "nccgs", "install-state.json");
23
- let state = null;
24
- if (!fs.existsSync(statePath)) errors.push("NCCGS install state is missing.");
25
- else {
26
- try { state = JSON.parse(fs.readFileSync(statePath, "utf8")); }
27
- catch (error) { errors.push(`Install state is invalid JSON: ${error.message}`); }
25
+ const overridePath = path.join(project, ".nccgs", "framework-overrides.json");
26
+ const state = readJson(statePath, "NCCGS install state", true);
27
+ const overrideManifest = readJson(overridePath, "NCCGS framework override manifest", false);
28
+ if (state && ![1, 2, 3].includes(state.schemaVersion)) errors.push(`Unsupported install-state schema: ${state.schemaVersion ?? "unknown"}.`);
29
+ if (overrideManifest && overrideManifest.schemaVersion !== 1) errors.push(`Unsupported framework override schema: ${overrideManifest.schemaVersion ?? "unknown"}.`);
30
+
31
+ const overrides = new Map();
32
+ for (const item of overrideManifest?.overrides ?? []) {
33
+ if (!isManagedRelative(item.path) || !new Set(["preserve", "absent"]).has(item.disposition)
34
+ || !new Set(["approved", "pending_review"]).has(item.status)) {
35
+ errors.push(`Invalid framework override record: ${item.path ?? "path missing"}`);
36
+ continue;
37
+ }
38
+ if (overrides.has(item.path)) errors.push(`Duplicate framework override: ${item.path}`);
39
+ overrides.set(item.path, item);
28
40
  }
29
41
 
42
+ let verifiedManaged = 0;
30
43
  if (state) {
31
44
  for (const item of state.files ?? []) {
45
+ if (!isManagedRelative(item.relative)) {
46
+ errors.push(`Unsafe managed path in install state: ${item.relative ?? "missing"}`);
47
+ continue;
48
+ }
32
49
  const file = path.join(project, ...item.relative.split("/"));
50
+ const override = overrides.get(item.relative);
51
+ if (override) {
52
+ const recordedUpstream = {
53
+ sha256: override.upstreamSha256,
54
+ canonicalSha256: override.upstreamCanonicalSha256
55
+ };
56
+ if (!sameFingerprint(item, recordedUpstream)) errors.push(`Framework override has stale upstream hashes: ${item.relative}`);
57
+ validateOverride(override, file);
58
+ verifiedManaged++;
59
+ continue;
60
+ }
33
61
  if (!fs.existsSync(file)) errors.push(`Managed file is missing: ${item.relative}`);
34
- else if (hashFile(file) !== item.sha256) errors.push(`Managed file was modified: ${item.relative}`);
62
+ else if (!matchesFingerprint(file, item)) errors.push(`Managed file was modified: ${item.relative}`);
63
+ else verifiedManaged++;
35
64
  }
36
65
  }
66
+ for (const item of overrides.values()) {
67
+ if ((state?.files ?? []).some((managed) => managed.relative === item.path)) continue;
68
+ validateOverride(item, path.join(project, ...item.path.split("/")));
69
+ }
37
70
 
38
71
  const claudePath = path.join(project, "CLAUDE.md");
39
72
  if (!fs.existsSync(claudePath) || !fs.readFileSync(claudePath, "utf8").includes("@.claude/nccgs/constitution.md")) {
@@ -44,17 +77,38 @@ const policyPath = path.join(project, ".nccgs", "project.yaml");
44
77
  let policySchema = null;
45
78
  if (!fs.existsSync(policyPath)) errors.push(".nccgs/project.yaml is missing.");
46
79
  else {
47
- const match = fs.readFileSync(policyPath, "utf8").match(/^schema_version:\s*(\d+)\s*$/m);
80
+ const policyText = fs.readFileSync(policyPath, "utf8");
81
+ const match = policyText.match(/^schema_version:\s*(\d+)\s*$/m);
48
82
  policySchema = match ? Number(match[1]) : null;
49
- if (policySchema !== 2) {
50
- const message = `Project policy schema must be 2; found ${policySchema ?? "unknown"}.`;
51
- if (allowPolicyMigration) warnings.push(message);
52
- else errors.push(message);
53
- }
83
+ if (policySchema !== 2) migrationIssue(`Project policy schema must be 2; found ${policySchema ?? "unknown"}.`);
84
+ if (/^profile_contracts:/m.test(policyText)) migrationIssue("Legacy embedded profile_contracts require Astra migration to pipeline.json plus project gate mapping.");
54
85
  }
55
86
 
87
+ const activationPath = path.join(project, ".nccgs/agent-activation.json");
88
+ if (fs.existsSync(activationPath)) {
89
+ try {
90
+ const activation = json(activationPath);
91
+ for (const [relative, expected] of Object.entries(activation.generated)) {
92
+ const bytes = fs.readFileSync(contained(project, relative));
93
+ if (hash(bytes) !== expected && hash(bytes.toString("utf8").replace(/\r\n/g, "\n")) !== activation.generatedCanonical?.[relative]) errors.push(`Activated agent modified: ${relative}`);
94
+ }
95
+ for (const warning of activation.warnings ?? []) migrationIssue(warning);
96
+ } catch (error) { errors.push(`Invalid agent activation state: ${error.message}`); }
97
+ }
98
+ const tasksDir = path.join(project, ".nccgs/tasks");
99
+ if (fs.existsSync(tasksDir)) for (const file of fs.readdirSync(tasksDir).filter(f => f.endsWith(".json"))) {
100
+ try {
101
+ const task = json(path.join(tasksDir, file));
102
+ if (task.closed) {
103
+ if (!stages.every(s => task.stages?.[s]) || task.closed.snapshot !== task.stages.acceptance.snapshot) throw new Error("Closure lacks its required stage records");
104
+ if (task.closed.snapshot === snapshot(project).sha256) checkTask(project, task, "done");
105
+ else warnings.push(`Historical closure ${task.id} is for a different snapshot; it cannot approve current work.`);
106
+ }
107
+ } catch (error) { errors.push(`Invalid closed task ${file}: ${error.message}`); }
108
+ }
56
109
  if (errors.length) {
57
110
  for (const error of errors) console.error(`ERROR: ${error}`);
111
+ for (const warning of warnings) console.warn(`WARN: ${warning}`);
58
112
  console.error(`NCCGS doctor failed with ${errors.length} error(s).`);
59
113
  process.exit(1);
60
114
  }
@@ -63,9 +117,39 @@ for (const warning of warnings) console.warn(`WARN: ${warning}`);
63
117
  console.log("NCCGS doctor passed.");
64
118
  console.log(`Framework version: ${state.frameworkVersion}`);
65
119
  console.log(`Model profile: ${state.modelProfile}`);
66
- console.log(`Managed files verified: ${state.files.length}`);
120
+ console.log(`Managed files verified: ${verifiedManaged}`);
121
+ console.log(`Framework overrides: ${overrides.size} (${[...overrides.values()].filter((item) => item.status !== "approved").length} pending review)`);
67
122
  console.log(`Project policy schema: ${policySchema ?? "migration required"}`);
68
123
 
69
- function hashFile(file) {
70
- return crypto.createHash("sha256").update(fs.readFileSync(file)).digest("hex");
124
+ function validateOverride(item, file) {
125
+ if (item.status !== "approved") migrationIssue(`Framework override awaits /migrate-project review: ${item.path}`);
126
+ if (item.disposition === "absent") {
127
+ if (fs.existsSync(file)) errors.push(`Override expects a missing file, but it exists: ${item.path}`);
128
+ return;
129
+ }
130
+ if (!fs.existsSync(file)) errors.push(`Preserved framework override is missing: ${item.path}`);
131
+ else if (!matchesFingerprint(file, item)) errors.push(`Preserved framework override changed after it was recorded: ${item.path}`);
132
+ }
133
+
134
+ function migrationIssue(message) {
135
+ if (allowMigrationRequired) warnings.push(message);
136
+ else errors.push(message);
137
+ }
138
+
139
+ function readJson(file, label, required) {
140
+ if (!fs.existsSync(file)) {
141
+ if (required) errors.push(`${label} is missing.`);
142
+ return null;
143
+ }
144
+ try { return JSON.parse(fs.readFileSync(file, "utf8")); }
145
+ catch (error) {
146
+ errors.push(`${label} is invalid JSON: ${error.message}`);
147
+ return null;
148
+ }
149
+ }
150
+
151
+ function isManagedRelative(value) {
152
+ if (typeof value !== "string" || !value.startsWith(".claude/")) return false;
153
+ const parts = value.split("/");
154
+ return !parts.includes("") && !parts.includes(".") && !parts.includes("..");
71
155
  }