gaia-framework 1.83.2 → 1.105.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 (32) hide show
  1. package/.claude/commands/gaia-ci-edit.md +17 -0
  2. package/CLAUDE.md +10 -0
  3. package/_gaia/_config/environment-presets.yaml +140 -0
  4. package/_gaia/_config/global.yaml +1 -1
  5. package/_gaia/_config/lifecycle-sequence.yaml +9 -0
  6. package/_gaia/_config/workflow-manifest.csv +1 -0
  7. package/_gaia/core/engine/workflow.xml +2 -0
  8. package/_gaia/core/validators/ci-edit-audit.js +181 -0
  9. package/_gaia/core/validators/ci-edit-test-env-scan.js +89 -0
  10. package/_gaia/core/validators/dev-story-security-controls.js +264 -0
  11. package/_gaia/core/validators/promotion-chain-env-resolver.js +140 -0
  12. package/_gaia/core/validators/test-environment-validator.js +292 -0
  13. package/_gaia/dev/agents/_base-dev.md +6 -1
  14. package/_gaia/dev/skills/_skill-index.yaml +12 -6
  15. package/_gaia/dev/skills/figma-integration.md +203 -1
  16. package/_gaia/lifecycle/knowledge/brownfield/test-execution-scan.md +56 -9
  17. package/_gaia/lifecycle/templates/story-template.md +7 -0
  18. package/_gaia/lifecycle/workflows/2-planning/create-ux-design/instructions.xml +48 -4
  19. package/_gaia/lifecycle/workflows/4-implementation/code-review/instructions.xml +10 -0
  20. package/_gaia/lifecycle/workflows/4-implementation/create-story/instructions.xml +4 -0
  21. package/_gaia/lifecycle/workflows/4-implementation/dev-story/checklist.md +2 -0
  22. package/_gaia/lifecycle/workflows/4-implementation/dev-story/instructions.xml +104 -3
  23. package/_gaia/testing/workflows/ci-edit/checklist.md +41 -0
  24. package/_gaia/testing/workflows/ci-edit/instructions.xml +132 -0
  25. package/_gaia/testing/workflows/ci-edit/workflow.yaml +30 -0
  26. package/_gaia/testing/workflows/ci-setup/instructions.xml +75 -7
  27. package/_gaia/testing/workflows/test-gap-analysis/checklist.md +12 -0
  28. package/_gaia/testing/workflows/test-gap-analysis/instructions.xml +61 -2
  29. package/_gaia/testing/workflows/test-gap-analysis/workflow.yaml +2 -0
  30. package/gaia-install.sh +72 -76
  31. package/lib/copy-lib.sh +81 -0
  32. package/package.json +2 -1
@@ -14,7 +14,9 @@ instructions: "{installed_path}/instructions.xml"
14
14
  validation: "{installed_path}/checklist.md"
15
15
  traces_to:
16
16
  - FR-221
17
+ - FR-222
17
18
  - FR-223
19
+ - FR-226
18
20
  - NFR-040
19
21
  performance_constraints:
20
22
  max_duration_seconds: 60 # NFR-040 — workflow must complete in under 60 seconds
package/gaia-install.sh CHANGED
@@ -77,6 +77,7 @@ OPT_YES=false
77
77
  OPT_DRY_RUN=false
78
78
  OPT_VERBOSE=false
79
79
  OPT_BRANCH=""
80
+ OPT_SKIP_SPRINT_GATE=false
80
81
 
81
82
  # ─── Utility Functions ──────────────────────────────────────────────────────
82
83
 
@@ -195,76 +196,10 @@ copy_with_backup() {
195
196
  [[ "$OPT_VERBOSE" == true ]] && detail "Updated (backed up): $dst" || true
196
197
  }
197
198
 
198
- # Remove .resolved/*.yaml files from target _gaia/ directory.
199
- # Called after cp/tar copy to replicate rsync's --exclude behavior.
200
- # Only .resolved/*.yaml is relevant to the _gaia/ subtree; the other rsync
201
- # --exclude patterns target _memory/ paths outside _gaia/ and never match.
202
- clean_resolved_yaml() {
203
- local target_gaia="$1"
204
- find "$target_gaia" -path '*/.resolved/*.yaml' -delete 2>/dev/null || true
205
- }
206
-
207
- # Copy _gaia/ directory from source to target using a fallback chain:
208
- # rsync → cp -rp → tar
209
- # Tries each tool in order. If a tool is found but fails at runtime (e.g.,
210
- # broken rsync stub on Windows), falls through to the next tool. Exits with
211
- # a diagnostic error if all tools fail or none are available.
212
- #
213
- # Excludes .resolved/*.yaml files from the final output (rsync handles this
214
- # natively via --exclude; cp and tar do a post-copy cleanup).
215
- #
216
- # Note: No symlinks currently exist in _gaia/. If symlinks are introduced
217
- # in the future, verify that cp -rp behavior matches rsync -a on all
218
- # target platforms (ADR-004).
219
- copy_gaia_files() {
220
- local src="$1" dst="$2"
221
- local copy_done=false
222
-
223
- # Try rsync first (preferred — handles excludes natively)
224
- if command -v rsync >/dev/null 2>&1; then
225
- if rsync -a \
226
- --exclude='_memory/checkpoints/*.yaml' \
227
- --exclude='_memory/checkpoints/completed/*.yaml' \
228
- --exclude='.resolved/*.yaml' \
229
- --exclude='_memory/*-sidecar/*.md' \
230
- --exclude='_memory/*-sidecar/*.yaml' \
231
- "$src/_gaia/" "$dst/_gaia/" 2>/dev/null; then
232
- detail "Copied framework files using rsync"
233
- copy_done=true
234
- else
235
- detail "rsync found but failed — trying fallback methods"
236
- fi
237
- fi
238
-
239
- # Fallback: cp -rp (preserves permissions like rsync -a)
240
- if [[ "$copy_done" == false ]] && command -v cp >/dev/null 2>&1; then
241
- if cp -rp "$src/_gaia/." "$dst/_gaia/" 2>/dev/null; then
242
- clean_resolved_yaml "$dst/_gaia"
243
- detail "Copied framework files using cp -rp (rsync unavailable)"
244
- copy_done=true
245
- else
246
- error "cp failed to copy framework files — check permissions and disk space"
247
- exit 1
248
- fi
249
- fi
250
-
251
- # Fallback: tar (last resort — available on virtually all POSIX systems)
252
- if [[ "$copy_done" == false ]] && command -v tar >/dev/null 2>&1; then
253
- if (tar -cf - -C "$src" _gaia | tar -xf - -C "$dst") 2>/dev/null; then
254
- clean_resolved_yaml "$dst/_gaia"
255
- detail "Copied framework files using tar (rsync and cp unavailable)"
256
- copy_done=true
257
- else
258
- error "tar failed to copy framework files — check permissions and disk space"
259
- exit 1
260
- fi
261
- fi
262
-
263
- if [[ "$copy_done" == false ]]; then
264
- error "No suitable copy tool found (tried rsync, cp, tar). Cannot copy framework files."
265
- exit 1
266
- fi
267
- }
199
+ # Source extracted copy functions (clean_resolved_yaml, copy_gaia_files)
200
+ # from lib/copy-lib.sh E3-S11
201
+ # shellcheck source=lib/copy-lib.sh
202
+ source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/copy-lib.sh"
268
203
 
269
204
  append_if_missing() {
270
205
  local file="$1" marker="$2" content="$3"
@@ -322,6 +257,53 @@ count_files() {
322
257
  find "$dir" -name "$pattern" -type f 2>/dev/null | wc -l | tr -d ' '
323
258
  }
324
259
 
260
+ # ─── Sprint Gate (E18-S1, ADR-029 §10.21.2) ───────────────────────────────
261
+ # Reads sprint-status.yaml and hard-blocks the upgrade if any story has an
262
+ # active status (in-progress, review, or ready-for-dev).
263
+
264
+ check_sprint_gate() {
265
+ local target="$1"
266
+ local sprint_file="$target/docs/implementation-artifacts/sprint-status.yaml"
267
+
268
+ # AC3: If no sprint file exists, gate passes silently
269
+ if [[ ! -f "$sprint_file" ]]; then
270
+ [[ "$OPT_VERBOSE" == true ]] && detail "No sprint-status.yaml found — sprint gate passes"
271
+ return 0
272
+ fi
273
+
274
+ # Extract sprint_id (top-level field, unindented)
275
+ local sprint_id
276
+ sprint_id="$(extract_yaml_value "$sprint_file" "sprint_id")"
277
+ [[ -z "$sprint_id" ]] && sprint_id="unknown"
278
+
279
+ # Count active stories — match only indented status: lines (story entries)
280
+ local active_count=0
281
+ while IFS= read -r line; do
282
+ local status_val
283
+ status_val="${line#*status:}" # strip key
284
+ status_val="${status_val#"${status_val%%[![:space:]]*}"}" # trim leading whitespace
285
+ status_val="${status_val#[\"\']}" # trim leading quote
286
+ status_val="${status_val%[\"\']}" # trim trailing quote
287
+ case "$status_val" in
288
+ in-progress|review|ready-for-dev)
289
+ active_count=$((active_count + 1))
290
+ ;;
291
+ esac
292
+ done < <(grep '^[[:space:]]\{1,\}status:' "$sprint_file")
293
+
294
+ # AC3: If no active stories, gate passes
295
+ if [[ "$active_count" -eq 0 ]]; then
296
+ [[ "$OPT_VERBOSE" == true ]] && detail "Sprint gate passes — no active stories"
297
+ return 0
298
+ fi
299
+
300
+ # AC2: Hard block with clear error message
301
+ local story_word="stories"
302
+ [[ "$active_count" -eq 1 ]] && story_word="story"
303
+ error "Upgrade blocked: sprint \`${sprint_id}\` is active (${active_count} ${story_word} in progress). Complete or pause the sprint before upgrading."
304
+ return 1
305
+ }
306
+
325
307
  # ─── cmd_init ───────────────────────────────────────────────────────────────
326
308
 
327
309
  cmd_init() {
@@ -602,6 +584,15 @@ cmd_update() {
602
584
  [[ "$confirm" =~ ^[Yy] ]] || { info "Aborted."; exit 0; }
603
585
  fi
604
586
 
587
+ # Sprint Gate (E18-S1, ADR-029 §10.21.2): block upgrade if active sprint
588
+ if [[ "$OPT_SKIP_SPRINT_GATE" == true ]]; then
589
+ warn "Sprint gate bypassed via --skip-sprint-gate — proceed with caution"
590
+ else
591
+ if ! check_sprint_gate "$TARGET"; then
592
+ exit 1
593
+ fi
594
+ fi
595
+
605
596
  local timestamp
606
597
  timestamp="$(date +%Y%m%d-%H%M%S)"
607
598
  local backup_dir="$TARGET/_gaia/_backups/$timestamp"
@@ -995,12 +986,13 @@ ${BOLD}Commands:${RESET}
995
986
  status Show installation info
996
987
 
997
988
  ${BOLD}Options:${RESET}
998
- --source <path> Local GAIA source (or clones from GitHub if omitted)
999
- --branch <name> Clone from a specific branch
1000
- --yes Skip confirmation prompts
1001
- --dry-run Show what would be done without making changes
1002
- --verbose Show detailed progress
1003
- --help Show this help message
989
+ --source <path> Local GAIA source (or clones from GitHub if omitted)
990
+ --branch <name> Clone from a specific branch
991
+ --yes Skip confirmation prompts
992
+ --dry-run Show what would be done without making changes
993
+ --verbose Show detailed progress
994
+ --skip-sprint-gate Bypass the active-sprint upgrade gate (NOT RECOMMENDED)
995
+ --help Show this help message
1004
996
 
1005
997
  ${BOLD}Examples:${RESET}
1006
998
  gaia-install.sh init ~/my-new-project
@@ -1070,6 +1062,10 @@ parse_args() {
1070
1062
  OPT_VERBOSE=true
1071
1063
  shift
1072
1064
  ;;
1065
+ --skip-sprint-gate)
1066
+ OPT_SKIP_SPRINT_GATE=true
1067
+ shift
1068
+ ;;
1073
1069
  --branch)
1074
1070
  if [[ -z "${2:-}" ]]; then
1075
1071
  error "--branch requires a branch name argument"
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env bash
2
+ # ─────────────────────────────────────────────────────────────────────────────
3
+ # copy-lib.sh — Extracted copy functions for gaia-install.sh
4
+ # Origin: gaia-install.sh (E3-S11 — Extract copy_gaia_files for Unit Testability)
5
+ #
6
+ # This library is intentionally free of `set -euo pipefail`. The caller's
7
+ # shell options govern execution. When BATS sources this directly, the BATS
8
+ # process shell options apply. When gaia-install.sh sources it, the
9
+ # installer's `set -euo pipefail` applies. Function bodies are neutral.
10
+ # ─────────────────────────────────────────────────────────────────────────────
11
+
12
+ # Remove .resolved/*.yaml files from target _gaia/ directory.
13
+ # Called after cp/tar copy to replicate rsync's --exclude behavior.
14
+ # Only .resolved/*.yaml is relevant to the _gaia/ subtree; the other rsync
15
+ # --exclude patterns target _memory/ paths outside _gaia/ and never match.
16
+ clean_resolved_yaml() {
17
+ local target_gaia="$1"
18
+ find "$target_gaia" -path '*/.resolved/*.yaml' -delete 2>/dev/null || true
19
+ }
20
+
21
+ # Copy _gaia/ directory from source to target using a fallback chain:
22
+ # rsync → cp -rp → tar
23
+ # Tries each tool in order. If a tool is found but fails at runtime (e.g.,
24
+ # broken rsync stub on Windows), falls through to the next tool. Exits with
25
+ # a diagnostic error if all tools fail or none are available.
26
+ #
27
+ # Excludes .resolved/*.yaml files from the final output (rsync handles this
28
+ # natively via --exclude; cp and tar do a post-copy cleanup).
29
+ #
30
+ # Note: No symlinks currently exist in _gaia/. If symlinks are introduced
31
+ # in the future, verify that cp -rp behavior matches rsync -a on all
32
+ # target platforms (ADR-004).
33
+ copy_gaia_files() {
34
+ local src="$1" dst="$2"
35
+ local copy_done=false
36
+
37
+ # Try rsync first (preferred — handles excludes natively)
38
+ if command -v rsync >/dev/null 2>&1; then
39
+ if rsync -a \
40
+ --exclude='_memory/checkpoints/*.yaml' \
41
+ --exclude='_memory/checkpoints/completed/*.yaml' \
42
+ --exclude='.resolved/*.yaml' \
43
+ --exclude='_memory/*-sidecar/*.md' \
44
+ --exclude='_memory/*-sidecar/*.yaml' \
45
+ "$src/_gaia/" "$dst/_gaia/" 2>/dev/null; then
46
+ detail "Copied framework files using rsync"
47
+ copy_done=true
48
+ else
49
+ detail "rsync found but failed — trying fallback methods"
50
+ fi
51
+ fi
52
+
53
+ # Fallback: cp -rp (preserves permissions like rsync -a)
54
+ if [[ "$copy_done" == false ]] && command -v cp >/dev/null 2>&1; then
55
+ if cp -rp "$src/_gaia/." "$dst/_gaia/" 2>/dev/null; then
56
+ clean_resolved_yaml "$dst/_gaia"
57
+ detail "Copied framework files using cp -rp (rsync unavailable)"
58
+ copy_done=true
59
+ else
60
+ error "cp failed to copy framework files — check permissions and disk space"
61
+ exit 1
62
+ fi
63
+ fi
64
+
65
+ # Fallback: tar (last resort — available on virtually all POSIX systems)
66
+ if [[ "$copy_done" == false ]] && command -v tar >/dev/null 2>&1; then
67
+ if (tar -cf - -C "$src" _gaia | tar -xf - -C "$dst") 2>/dev/null; then
68
+ clean_resolved_yaml "$dst/_gaia"
69
+ detail "Copied framework files using tar (rsync and cp unavailable)"
70
+ copy_done=true
71
+ else
72
+ error "tar failed to copy framework files — check permissions and disk space"
73
+ exit 1
74
+ fi
75
+ fi
76
+
77
+ if [[ "$copy_done" == false ]]; then
78
+ error "No suitable copy tool found (tried rsync, cp, tar). Cannot copy framework files."
79
+ exit 1
80
+ fi
81
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gaia-framework",
3
- "version": "1.83.2",
3
+ "version": "1.105.0",
4
4
  "description": "GAIA — Generative Agile Intelligence Architecture installer",
5
5
  "bin": {
6
6
  "gaia-framework": "./bin/gaia-framework.js"
@@ -42,6 +42,7 @@
42
42
  },
43
43
  "files": [
44
44
  "bin/",
45
+ "lib/",
45
46
  "gaia-install.sh",
46
47
  "_gaia/",
47
48
  ".claude/",