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.
- package/.claude/commands/gaia-ci-edit.md +17 -0
- package/CLAUDE.md +10 -0
- package/_gaia/_config/environment-presets.yaml +140 -0
- package/_gaia/_config/global.yaml +1 -1
- package/_gaia/_config/lifecycle-sequence.yaml +9 -0
- package/_gaia/_config/workflow-manifest.csv +1 -0
- package/_gaia/core/engine/workflow.xml +2 -0
- package/_gaia/core/validators/ci-edit-audit.js +181 -0
- package/_gaia/core/validators/ci-edit-test-env-scan.js +89 -0
- package/_gaia/core/validators/dev-story-security-controls.js +264 -0
- package/_gaia/core/validators/promotion-chain-env-resolver.js +140 -0
- package/_gaia/core/validators/test-environment-validator.js +292 -0
- package/_gaia/dev/agents/_base-dev.md +6 -1
- package/_gaia/dev/skills/_skill-index.yaml +12 -6
- package/_gaia/dev/skills/figma-integration.md +203 -1
- package/_gaia/lifecycle/knowledge/brownfield/test-execution-scan.md +56 -9
- package/_gaia/lifecycle/templates/story-template.md +7 -0
- package/_gaia/lifecycle/workflows/2-planning/create-ux-design/instructions.xml +48 -4
- package/_gaia/lifecycle/workflows/4-implementation/code-review/instructions.xml +10 -0
- package/_gaia/lifecycle/workflows/4-implementation/create-story/instructions.xml +4 -0
- package/_gaia/lifecycle/workflows/4-implementation/dev-story/checklist.md +2 -0
- package/_gaia/lifecycle/workflows/4-implementation/dev-story/instructions.xml +104 -3
- package/_gaia/testing/workflows/ci-edit/checklist.md +41 -0
- package/_gaia/testing/workflows/ci-edit/instructions.xml +132 -0
- package/_gaia/testing/workflows/ci-edit/workflow.yaml +30 -0
- package/_gaia/testing/workflows/ci-setup/instructions.xml +75 -7
- package/_gaia/testing/workflows/test-gap-analysis/checklist.md +12 -0
- package/_gaia/testing/workflows/test-gap-analysis/instructions.xml +61 -2
- package/_gaia/testing/workflows/test-gap-analysis/workflow.yaml +2 -0
- package/gaia-install.sh +72 -76
- package/lib/copy-lib.sh +81 -0
- 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
|
-
#
|
|
199
|
-
#
|
|
200
|
-
#
|
|
201
|
-
|
|
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>
|
|
999
|
-
--branch <name>
|
|
1000
|
-
--yes
|
|
1001
|
-
--dry-run
|
|
1002
|
-
--verbose
|
|
1003
|
-
--
|
|
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"
|
package/lib/copy-lib.sh
ADDED
|
@@ -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.
|
|
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/",
|