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.
- package/.claude/agents/nccgs-adversarial-reviewer.md +7 -1
- package/.claude/agents/nccgs-engine-programmer.md +2 -1
- package/.claude/agents/nccgs-gameplay-programmer.md +2 -1
- package/.claude/agents/nccgs-qa-engineer.md +2 -1
- package/.claude/agents/nccgs-ui-programmer.md +2 -1
- package/.claude/agents/nccgs-unity-build-specialist.md +2 -1
- package/.claude/agents/nccgs-unity-implementer.md +2 -1
- package/.claude/agents/nccgs-unity-systems-specialist.md +2 -1
- package/.claude/agents/nccgs-unity-ui-specialist.md +2 -1
- package/.claude/agents/nccgs-verification-engineer.md +2 -1
- package/.claude/nccgs/VERSION +1 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-accessibility-specialist.md +0 -1
- package/.claude/nccgs/agent-library/nccgs-adversarial-reviewer.md +30 -0
- package/.claude/{agents → nccgs/agent-library}/nccgs-ai-programmer.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-analytics-engineer.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-art-direction-lead.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-audio-direction-lead.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-creative-director.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-documentation-manager.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-economy-designer.md +0 -1
- package/.claude/nccgs/agent-library/nccgs-engine-programmer.md +25 -0
- package/.claude/{agents → nccgs/agent-library}/nccgs-game-design-lead.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-game-designer.md +0 -1
- package/.claude/nccgs/agent-library/nccgs-gameplay-programmer.md +25 -0
- package/.claude/{agents → nccgs/agent-library}/nccgs-level-designer.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-live-ops-designer.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-localization-lead.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-narrative-lead.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-network-programmer.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-performance-analyst.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-producer.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-production-coordinator.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-programming-lead.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-prototyper.md +0 -1
- package/.claude/nccgs/agent-library/nccgs-qa-engineer.md +25 -0
- package/.claude/{agents → nccgs/agent-library}/nccgs-qa-lead.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-release-engineer.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-release-lead.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-security-engineer.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-sound-designer.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-systems-designer.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-technical-architect.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-technical-artist.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-technical-director.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-tools-programmer.md +0 -1
- package/.claude/nccgs/agent-library/nccgs-ui-programmer.md +25 -0
- package/.claude/nccgs/agent-library/nccgs-unity-build-specialist.md +25 -0
- package/.claude/{agents → nccgs/agent-library}/nccgs-unity-content-specialist.md +0 -1
- package/.claude/nccgs/agent-library/nccgs-unity-implementer.md +25 -0
- package/.claude/{agents → nccgs/agent-library}/nccgs-unity-rendering-specialist.md +0 -1
- package/.claude/nccgs/agent-library/nccgs-unity-systems-specialist.md +25 -0
- package/.claude/nccgs/agent-library/nccgs-unity-ui-specialist.md +25 -0
- package/.claude/{agents → nccgs/agent-library}/nccgs-ux-designer.md +0 -1
- package/.claude/nccgs/agent-library/nccgs-verification-engineer.md +25 -0
- package/.claude/{agents → nccgs/agent-library}/nccgs-world-builder.md +0 -1
- package/.claude/{agents → nccgs/agent-library}/nccgs-writer.md +0 -1
- package/.claude/nccgs/constitution.md +13 -0
- package/.claude/nccgs/hooks/agent-audit.mjs +6 -0
- package/.claude/nccgs/hooks/closure-guard.mjs +34 -0
- package/.claude/nccgs/hooks/runtime-observation.mjs +11 -0
- package/.claude/nccgs/hooks/session-start.mjs +8 -1
- package/.claude/nccgs/pipeline.json +176 -0
- package/.claude/nccgs/protocols/agent-contract.md +5 -0
- package/.claude/nccgs/protocols/astra-claude.md +77 -0
- package/.claude/nccgs/protocols/evidence.md +6 -0
- package/.claude/nccgs/protocols/model-routing.md +27 -5
- package/.claude/nccgs/protocols/orchestration.md +5 -0
- package/.claude/nccgs/protocols/task-gates.md +66 -0
- package/.claude/nccgs/routing.generated.md +11 -0
- package/.claude/nccgs/settings.fragment.json +73 -9
- package/.claude/nccgs/studio.json +187 -96
- package/.claude/nccgs/tools/approve-overrides.mjs +81 -0
- package/.claude/nccgs/tools/compile-policy.mjs +83 -0
- package/.claude/nccgs/tools/configure-models.mjs +76 -31
- package/.claude/nccgs/tools/gates.mjs +167 -0
- package/.claude/nccgs/tools/integrity.mjs +69 -0
- package/.claude/nccgs/tools/policy.mjs +62 -0
- package/.claude/nccgs/tools/runtime.mjs +40 -0
- package/.claude/nccgs/tools/task.mjs +77 -0
- package/.claude/nccgs/workflow-catalog.json +91 -14
- package/.claude/skills/accessibility-review/SKILL.md +6 -5
- package/.claude/skills/accessibility-review/references/astra.md +17 -0
- package/.claude/skills/accessibility-review/references/legacy.md +7 -0
- package/.claude/skills/architecture-decision/SKILL.md +6 -5
- package/.claude/skills/architecture-decision/references/astra.md +12 -0
- package/.claude/skills/architecture-decision/references/legacy.md +7 -0
- package/.claude/skills/asset-audit/SKILL.md +6 -5
- package/.claude/skills/asset-audit/references/astra.md +17 -0
- package/.claude/skills/asset-audit/references/legacy.md +7 -0
- package/.claude/skills/audit/SKILL.md +6 -7
- package/.claude/skills/audit/references/astra.md +17 -0
- package/.claude/skills/audit/references/legacy.md +9 -0
- package/.claude/skills/balance-review/SKILL.md +6 -5
- package/.claude/skills/balance-review/references/astra.md +17 -0
- package/.claude/skills/balance-review/references/legacy.md +7 -0
- package/.claude/skills/bug-triage/SKILL.md +6 -5
- package/.claude/skills/bug-triage/references/astra.md +20 -0
- package/.claude/skills/bug-triage/references/legacy.md +7 -0
- package/.claude/skills/closure/SKILL.md +5 -4
- package/.claude/skills/closure/references/astra.md +15 -0
- package/.claude/skills/closure/references/legacy.md +7 -0
- package/.claude/skills/compatibility-review/SKILL.md +6 -5
- package/.claude/skills/compatibility-review/references/astra.md +17 -0
- package/.claude/skills/compatibility-review/references/legacy.md +7 -0
- package/.claude/skills/context-pack/SKILL.md +5 -4
- package/.claude/skills/context-pack/references/astra.md +12 -0
- package/.claude/skills/context-pack/references/legacy.md +7 -0
- package/.claude/skills/dependency-review/SKILL.md +6 -5
- package/.claude/skills/dependency-review/references/astra.md +17 -0
- package/.claude/skills/dependency-review/references/legacy.md +7 -0
- package/.claude/skills/design/SKILL.md +6 -11
- package/.claude/skills/design/references/astra.md +12 -0
- package/.claude/skills/design/references/legacy.md +13 -0
- package/.claude/skills/design-review/SKILL.md +6 -5
- package/.claude/skills/design-review/references/astra.md +17 -0
- package/.claude/skills/design-review/references/legacy.md +7 -0
- package/.claude/skills/evidence-review/SKILL.md +6 -5
- package/.claude/skills/evidence-review/references/astra.md +17 -0
- package/.claude/skills/evidence-review/references/legacy.md +7 -0
- package/.claude/skills/hotfix/SKILL.md +6 -5
- package/.claude/skills/hotfix/references/astra.md +23 -0
- package/.claude/skills/hotfix/references/legacy.md +7 -0
- package/.claude/skills/incident-recovery/SKILL.md +6 -5
- package/.claude/skills/incident-recovery/references/astra.md +20 -0
- package/.claude/skills/incident-recovery/references/legacy.md +7 -0
- package/.claude/skills/localize-game/SKILL.md +6 -5
- package/.claude/skills/localize-game/references/astra.md +20 -0
- package/.claude/skills/localize-game/references/legacy.md +7 -0
- package/.claude/skills/migrate-project/SKILL.md +6 -14
- package/.claude/skills/migrate-project/references/astra.md +23 -0
- package/.claude/skills/migrate-project/references/legacy.md +19 -0
- package/.claude/skills/migrate-project/references/procedure.md +21 -1
- package/.claude/skills/milestone-review/SKILL.md +6 -5
- package/.claude/skills/milestone-review/references/astra.md +12 -0
- package/.claude/skills/milestone-review/references/legacy.md +7 -0
- package/.claude/skills/nccgs-code-review/SKILL.md +15 -0
- package/.claude/skills/nccgs-code-review/references/astra.md +15 -0
- package/.claude/skills/{code-review/SKILL.md → nccgs-code-review/references/legacy.md} +0 -7
- package/.claude/skills/performance-audit/SKILL.md +6 -5
- package/.claude/skills/performance-audit/references/astra.md +17 -0
- package/.claude/skills/performance-audit/references/legacy.md +7 -0
- package/.claude/skills/plan-feature/SKILL.md +6 -5
- package/.claude/skills/plan-feature/references/astra.md +12 -0
- package/.claude/skills/plan-feature/references/legacy.md +7 -0
- package/.claude/skills/playtest/SKILL.md +5 -4
- package/.claude/skills/playtest/references/astra.md +20 -0
- package/.claude/skills/playtest/references/legacy.md +7 -0
- package/.claude/skills/project-stage/SKILL.md +5 -4
- package/.claude/skills/project-stage/references/astra.md +12 -0
- package/.claude/skills/project-stage/references/legacy.md +7 -0
- package/.claude/skills/prototype-feature/SKILL.md +6 -5
- package/.claude/skills/prototype-feature/references/astra.md +20 -0
- package/.claude/skills/prototype-feature/references/legacy.md +7 -0
- package/.claude/skills/qa-plan/SKILL.md +6 -5
- package/.claude/skills/qa-plan/references/astra.md +12 -0
- package/.claude/skills/qa-plan/references/legacy.md +7 -0
- package/.claude/skills/release/SKILL.md +6 -9
- package/.claude/skills/release/references/astra.md +23 -0
- package/.claude/skills/release/references/legacy.md +11 -0
- package/.claude/skills/release-readiness/SKILL.md +6 -5
- package/.claude/skills/release-readiness/references/astra.md +17 -0
- package/.claude/skills/release-readiness/references/legacy.md +7 -0
- package/.claude/skills/retrospective/SKILL.md +6 -5
- package/.claude/skills/retrospective/references/astra.md +12 -0
- package/.claude/skills/retrospective/references/legacy.md +7 -0
- package/.claude/skills/review/SKILL.md +6 -7
- package/.claude/skills/review/references/astra.md +15 -0
- package/.claude/skills/review/references/legacy.md +9 -0
- package/.claude/skills/security-audit/SKILL.md +6 -5
- package/.claude/skills/security-audit/references/astra.md +17 -0
- package/.claude/skills/security-audit/references/legacy.md +7 -0
- package/.claude/skills/sprint-plan/SKILL.md +6 -5
- package/.claude/skills/sprint-plan/references/astra.md +12 -0
- package/.claude/skills/sprint-plan/references/legacy.md +7 -0
- package/.claude/skills/status/SKILL.md +5 -6
- package/.claude/skills/status/references/astra.md +13 -0
- package/.claude/skills/status/references/legacy.md +9 -0
- package/.claude/skills/story-readiness/SKILL.md +5 -4
- package/.claude/skills/story-readiness/references/astra.md +17 -0
- package/.claude/skills/story-readiness/references/legacy.md +7 -0
- package/.claude/skills/test/SKILL.md +6 -7
- package/.claude/skills/test/references/astra.md +20 -0
- package/.claude/skills/test/references/legacy.md +9 -0
- package/.claude/skills/ui-review/SKILL.md +6 -5
- package/.claude/skills/ui-review/references/astra.md +17 -0
- package/.claude/skills/ui-review/references/legacy.md +7 -0
- package/.claude/skills/work/SKILL.md +6 -27
- package/.claude/skills/work/references/astra.md +20 -0
- package/.claude/skills/work/references/closure.md +10 -0
- package/.claude/skills/work/references/feature-contracts.md +4 -0
- package/.claude/skills/work/references/legacy.md +29 -0
- package/README.md +67 -29
- package/UPGRADING.md +54 -4
- package/VERSION +1 -1
- package/docs/ARCHITECTURE.md +30 -13
- package/docs/HUONG-DAN-MIGRATE-VA-SU-DUNG.md +34 -322
- package/docs/MIGRATION-MATRIX.md +1 -1
- package/docs/NCCGS-1.3.md +125 -0
- package/docs/PROJECT-POLICY.md +18 -3
- package/docs/WORKFLOWS.md +20 -14
- package/package-assets/nccgs-project.gitignore +2 -0
- package/package.json +5 -3
- package/scaffold/.nccgs/gates.json +7 -0
- package/scaffold/.nccgs/project.yaml +6 -3
- package/scaffold/.nccgs/state.md +1 -1
- package/scaffold/.nccgs/templates/agent-handoff.md +10 -0
- package/scaffold/.nccgs/templates/closure-record.md +11 -0
- package/scaffold/.nccgs/templates/feature-contract.md +9 -0
- package/scaffold/.nccgs/templates/implementation-report.md +49 -0
- package/scripts/cli.mjs +10 -5
- package/scripts/doctor.mjs +102 -18
- package/scripts/install.mjs +221 -88
- package/scripts/validate.mjs +34 -6
- package/tests/framework.test.mjs +213 -8
- package/tests/gates.test.mjs +170 -0
package/docs/PROJECT-POLICY.md
CHANGED
|
@@ -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
|
-
|
|
28
|
-
|
|
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
|
|
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
|
-
->
|
|
20
|
-
->
|
|
21
|
-
->
|
|
22
|
-
->
|
|
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
|
-
|
|
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
|
|
51
|
-
|
|
52
|
-
|
|
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
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nccgs",
|
|
3
|
-
"version": "1.
|
|
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
|
|
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",
|
|
@@ -15,12 +15,15 @@ studio:
|
|
|
15
15
|
independent_verification: true
|
|
16
16
|
|
|
17
17
|
models:
|
|
18
|
-
profile:
|
|
19
|
-
allow_inherit_fallback:
|
|
20
|
-
allow_automatic_escalation:
|
|
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
|
package/scaffold/.nccgs/state.md
CHANGED
|
@@ -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:
|
|
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
|
|
29
|
-
const
|
|
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
|
|
57
|
-
--model-profile <profile> quality, balanced,
|
|
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
|
}
|
package/scripts/doctor.mjs
CHANGED
|
@@ -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
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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: ${
|
|
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
|
|
70
|
-
|
|
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
|
}
|