@jaguilar87/gaia 5.0.4 → 5.0.6

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 (113) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +65 -0
  4. package/INSTALL.md +0 -2
  5. package/README.md +1 -6
  6. package/bin/README.md +0 -1
  7. package/bin/cli/_install_helpers.py +1 -1
  8. package/bin/cli/cleanup.py +0 -1
  9. package/bin/cli/doctor.py +2 -2
  10. package/bin/cli/memory.py +2 -0
  11. package/bin/cli/update.py +1 -1
  12. package/bin/pre-publish-validate.js +48 -5
  13. package/config/README.md +22 -44
  14. package/config/surface-routing.json +0 -1
  15. package/dist/gaia-ops/.claude-plugin/plugin.json +1 -1
  16. package/dist/gaia-ops/config/README.md +22 -44
  17. package/dist/gaia-ops/config/surface-routing.json +0 -1
  18. package/dist/gaia-ops/hooks/modules/agents/handoff_persister.py +2 -0
  19. package/dist/gaia-ops/hooks/modules/security/approval_grants.py +2 -0
  20. package/dist/gaia-ops/hooks/modules/tools/bash_validator.py +2 -0
  21. package/dist/gaia-ops/hooks/modules/validation/commit_validator.py +90 -55
  22. package/dist/gaia-ops/skills/README.md +1 -1
  23. package/dist/gaia-ops/skills/gaia-patterns/SKILL.md +1 -1
  24. package/dist/gaia-ops/skills/gaia-patterns/reference.md +0 -1
  25. package/dist/gaia-ops/skills/gaia-release/SKILL.md +60 -24
  26. package/dist/gaia-ops/skills/gaia-release/reference.md +35 -11
  27. package/dist/gaia-ops/skills/git-conventions/SKILL.md +6 -2
  28. package/dist/gaia-ops/skills/orchestrator-present-approval/SKILL.md +10 -2
  29. package/dist/gaia-ops/skills/readme-writing/SKILL.md +1 -1
  30. package/dist/gaia-ops/skills/readme-writing/reference.md +0 -1
  31. package/dist/gaia-ops/tools/scan/ui.py +20 -4
  32. package/dist/gaia-ops/tools/scan/verify.py +3 -3
  33. package/dist/gaia-ops/tools/validation/README.md +15 -24
  34. package/dist/gaia-security/.claude-plugin/plugin.json +1 -1
  35. package/dist/gaia-security/hooks/modules/agents/handoff_persister.py +2 -0
  36. package/dist/gaia-security/hooks/modules/security/approval_grants.py +2 -0
  37. package/dist/gaia-security/hooks/modules/tools/bash_validator.py +2 -0
  38. package/dist/gaia-security/hooks/modules/validation/commit_validator.py +90 -55
  39. package/hooks/modules/agents/handoff_persister.py +2 -0
  40. package/hooks/modules/security/approval_grants.py +2 -0
  41. package/hooks/modules/tools/bash_validator.py +2 -0
  42. package/hooks/modules/validation/commit_validator.py +90 -55
  43. package/index.js +2 -12
  44. package/package.json +4 -6
  45. package/pyproject.toml +3 -3
  46. package/scripts/bootstrap_database.sh +88 -439
  47. package/scripts/check_schema_drift.py +208 -0
  48. package/scripts/migrations/README.md +78 -28
  49. package/scripts/migrations/schema.checksum +8 -0
  50. package/scripts/release-prepare.mjs +199 -0
  51. package/skills/README.md +1 -1
  52. package/skills/gaia-patterns/SKILL.md +1 -1
  53. package/skills/gaia-patterns/reference.md +0 -1
  54. package/skills/gaia-release/SKILL.md +60 -24
  55. package/skills/gaia-release/reference.md +35 -11
  56. package/skills/git-conventions/SKILL.md +6 -2
  57. package/skills/orchestrator-present-approval/SKILL.md +10 -2
  58. package/skills/readme-writing/SKILL.md +1 -1
  59. package/skills/readme-writing/reference.md +0 -1
  60. package/tools/scan/ui.py +20 -4
  61. package/tools/scan/verify.py +3 -3
  62. package/tools/validation/README.md +15 -24
  63. package/commands/README.md +0 -64
  64. package/commands/gaia.md +0 -37
  65. package/commands/scan-project.md +0 -74
  66. package/config/crons-schema.md +0 -81
  67. package/config/git_standards.json +0 -72
  68. package/dist/gaia-ops/commands/gaia.md +0 -37
  69. package/dist/gaia-ops/config/crons-schema.md +0 -81
  70. package/dist/gaia-ops/config/git_standards.json +0 -72
  71. package/dist/gaia-ops/tools/agentic-loop/decide-status.py +0 -210
  72. package/dist/gaia-ops/tools/agentic-loop/parse-metric.py +0 -106
  73. package/dist/gaia-ops/tools/agentic-loop/record-iteration.py +0 -223
  74. package/git-hooks/commit-msg +0 -41
  75. package/scripts/migrations/v10_to_v11.sql +0 -170
  76. package/scripts/migrations/v10_to_v11_fresh.sql +0 -18
  77. package/scripts/migrations/v11_to_v12.sql +0 -195
  78. package/scripts/migrations/v11_to_v12_fresh.sql +0 -19
  79. package/scripts/migrations/v12_to_v13.sql +0 -48
  80. package/scripts/migrations/v12_to_v13_fresh.sql +0 -17
  81. package/scripts/migrations/v13_to_v14.sql +0 -44
  82. package/scripts/migrations/v13_to_v14_fresh.sql +0 -17
  83. package/scripts/migrations/v14_to_v15.sql +0 -71
  84. package/scripts/migrations/v14_to_v15_fresh.sql +0 -19
  85. package/scripts/migrations/v15_to_v16.sql +0 -57
  86. package/scripts/migrations/v15_to_v16_fresh.sql +0 -18
  87. package/scripts/migrations/v16_to_v17.sql +0 -51
  88. package/scripts/migrations/v16_to_v17_fresh.sql +0 -18
  89. package/scripts/migrations/v17_to_v18.sql +0 -66
  90. package/scripts/migrations/v17_to_v18_fresh.sql +0 -24
  91. package/scripts/migrations/v1_to_v2.sql +0 -97
  92. package/scripts/migrations/v2_to_v3.sql +0 -68
  93. package/scripts/migrations/v2_to_v3_merge.sql +0 -69
  94. package/scripts/migrations/v3_to_v4.sql +0 -67
  95. package/scripts/migrations/v3_to_v4_fresh.sql +0 -20
  96. package/scripts/migrations/v4_to_v5.sql +0 -55
  97. package/scripts/migrations/v4_to_v5_fresh.sql +0 -20
  98. package/scripts/migrations/v5_to_v6.sql +0 -48
  99. package/scripts/migrations/v5_to_v6_fresh.sql +0 -17
  100. package/scripts/migrations/v6_to_v7.sql +0 -26
  101. package/scripts/migrations/v6_to_v7_fresh.sql +0 -13
  102. package/scripts/migrations/v7_to_v8.sql +0 -44
  103. package/scripts/migrations/v7_to_v8_fresh.sql +0 -14
  104. package/scripts/migrations/v8_to_v9.sql +0 -87
  105. package/scripts/migrations/v8_to_v9_fresh.sql +0 -15
  106. package/scripts/migrations/v9_to_v10.sql +0 -109
  107. package/scripts/migrations/v9_to_v10_episodes_workspace.sql +0 -109
  108. package/scripts/migrations/v9_to_v10_fresh.sql +0 -18
  109. package/templates/README.md +0 -70
  110. package/templates/managed-settings.template.json +0 -43
  111. package/tools/agentic-loop/decide-status.py +0 -210
  112. package/tools/agentic-loop/parse-metric.py +0 -106
  113. package/tools/agentic-loop/record-iteration.py +0 -223
@@ -1,223 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- record-iteration.py
4
-
5
- Atomically update state.json and append to worklog.md after each iteration.
6
- The LLM never writes state.json directly — this script is the only writer.
7
-
8
- Usage:
9
- python3 record-iteration.py \
10
- --state-file state.json \
11
- --worklog worklog.md \
12
- --iteration 5 \
13
- --metric-value 94.5 \
14
- --status keep \
15
- --description "Handle hyphenated verbs" \
16
- --insight "delete-objects splits correctly" \
17
- --next "Check camelCase+hyphen combined"
18
-
19
- Optional flags:
20
- --changed TEXT What was modified (default: same as description)
21
- --metric-name TEXT Name of the metric recorded (default: "metric")
22
-
23
- Atomic write guarantee: state.json is written to a .tmp sibling, fsynced,
24
- then renamed over the original. Either the full write lands or the original
25
- is untouched.
26
- """
27
-
28
- from __future__ import annotations
29
-
30
- import argparse
31
- import json
32
- import os
33
- import sys
34
- import tempfile
35
- from datetime import datetime, timezone
36
-
37
-
38
- def load_state(path: str) -> dict:
39
- """Load existing state.json or return an empty skeleton."""
40
- if not os.path.exists(path):
41
- return {
42
- "iteration": 0,
43
- "current_metric": None,
44
- "best_metric": None,
45
- "consecutive_discards": 0,
46
- "pivot_count": 0,
47
- "timestamp": None,
48
- "status": None,
49
- }
50
- try:
51
- with open(path, "r") as fh:
52
- data = json.load(fh)
53
- return data
54
- except (OSError, json.JSONDecodeError) as exc:
55
- print(f"error: cannot read state file '{path}': {exc}", file=sys.stderr)
56
- sys.exit(1)
57
-
58
-
59
- def atomic_write_json(path: str, data: dict) -> None:
60
- """Write *data* to *path* atomically using write-fsync-rename."""
61
- dir_name = os.path.dirname(os.path.abspath(path))
62
- # Use a temp file in the same directory so rename is on the same filesystem.
63
- try:
64
- fd, tmp_path = tempfile.mkstemp(dir=dir_name, suffix=".tmp")
65
- try:
66
- with os.fdopen(fd, "w") as fh:
67
- json.dump(data, fh, indent=2)
68
- fh.write("\n")
69
- fh.flush()
70
- os.fsync(fh.fileno())
71
- os.replace(tmp_path, path)
72
- except Exception:
73
- # Clean up orphaned temp file on failure.
74
- try:
75
- os.unlink(tmp_path)
76
- except OSError:
77
- pass
78
- raise
79
- except OSError as exc:
80
- print(f"error: atomic write to '{path}' failed: {exc}", file=sys.stderr)
81
- sys.exit(1)
82
-
83
-
84
- def append_worklog(
85
- path: str,
86
- iteration: int,
87
- description: str,
88
- metric_name: str,
89
- metric_value: float,
90
- status: str,
91
- changed: str,
92
- insight: str,
93
- next_step: str,
94
- best_metric: float | None,
95
- ) -> None:
96
- """Append a structured run entry to worklog.md."""
97
- status_upper = status.upper()
98
-
99
- # Build result sentence
100
- if best_metric is None:
101
- result_text = f"{metric_name}={metric_value} (first run, no prior best)"
102
- else:
103
- comparison = (
104
- f"improved from {best_metric}"
105
- if metric_value > best_metric
106
- else (
107
- f"unchanged from {best_metric}"
108
- if metric_value == best_metric
109
- else f"regressed from {best_metric}"
110
- )
111
- )
112
- result_text = f"{metric_name}={metric_value} ({comparison})"
113
-
114
- entry = (
115
- f"\n### Run {iteration}: {description} — {metric_name}={metric_value} ({status_upper})\n"
116
- f"- **Changed:** {changed}\n"
117
- f"- **Result:** {result_text}\n"
118
- f"- **Insight:** {insight}\n"
119
- f"- **Next:** {next_step}\n"
120
- )
121
-
122
- try:
123
- with open(path, "a") as fh:
124
- fh.write(entry)
125
- except OSError as exc:
126
- print(f"error: cannot append to worklog '{path}': {exc}", file=sys.stderr)
127
- sys.exit(1)
128
-
129
-
130
- def main() -> None:
131
- parser = argparse.ArgumentParser(
132
- description="Atomically record an agentic-loop iteration into state.json and worklog.md.",
133
- formatter_class=argparse.RawDescriptionHelpFormatter,
134
- epilog="""
135
- Status values:
136
- keep — metric improved; best is updated, consecutive_discards reset to 0
137
- discard — metric did not improve; consecutive_discards incremented
138
- pivot — forced strategy change (also increments pivot_count)
139
- stop — terminal state; loop should halt
140
-
141
- Exit codes:
142
- 0 success
143
- 1 error (message on stderr)
144
- """,
145
- )
146
- parser.add_argument("--state-file", required=True, metavar="PATH", help="Path to state.json")
147
- parser.add_argument("--worklog", required=True, metavar="PATH", help="Path to worklog.md (append-only)")
148
- parser.add_argument("--iteration", required=True, type=int, help="Current iteration number (1-based)")
149
- parser.add_argument("--metric-value", required=True, type=float, metavar="NUM", help="Numeric metric value this run")
150
- parser.add_argument(
151
- "--status",
152
- required=True,
153
- choices=["keep", "discard", "pivot", "stop"],
154
- help="Outcome classification for this iteration",
155
- )
156
- parser.add_argument("--description", required=True, help="Short description of what changed this run")
157
- parser.add_argument("--insight", required=True, help="What was learned from this run")
158
- parser.add_argument("--next", required=True, dest="next_step", help="What to try in the next iteration")
159
- parser.add_argument(
160
- "--changed",
161
- default=None,
162
- metavar="TEXT",
163
- help="What was specifically modified (defaults to --description)",
164
- )
165
- parser.add_argument(
166
- "--metric-name",
167
- default="metric",
168
- metavar="NAME",
169
- help="Name label for the metric (default: metric)",
170
- )
171
- args = parser.parse_args()
172
-
173
- changed = args.changed if args.changed is not None else args.description
174
-
175
- # --- Load current state ---
176
- state = load_state(args.state_file)
177
-
178
- prev_best: float | None = state.get("best_metric")
179
-
180
- # --- Compute new state values ---
181
- state["iteration"] = args.iteration
182
- state["current_metric"] = args.metric_value
183
- state["status"] = args.status
184
- state["timestamp"] = datetime.now(tz=timezone.utc).isoformat()
185
-
186
- if args.status == "keep":
187
- # Keep: this run is better; promote to best.
188
- state["best_metric"] = args.metric_value
189
- state["consecutive_discards"] = 0
190
- elif args.status == "discard":
191
- # Do not update best; increment discard counter.
192
- state["consecutive_discards"] = int(state.get("consecutive_discards") or 0) + 1
193
- elif args.status == "pivot":
194
- # Pivot: counts as a discard for streak purposes, but also advances pivot_count.
195
- state["consecutive_discards"] = int(state.get("consecutive_discards") or 0) + 1
196
- state["pivot_count"] = int(state.get("pivot_count") or 0) + 1
197
- elif args.status == "stop":
198
- # Terminal — no counter changes needed beyond recording.
199
- pass
200
-
201
- # --- Atomic write ---
202
- atomic_write_json(args.state_file, state)
203
-
204
- # --- Append worklog ---
205
- append_worklog(
206
- path=args.worklog,
207
- iteration=args.iteration,
208
- description=args.description,
209
- metric_name=args.metric_name,
210
- metric_value=args.metric_value,
211
- status=args.status,
212
- changed=changed,
213
- insight=args.insight,
214
- next_step=args.next_step,
215
- best_metric=prev_best,
216
- )
217
-
218
- # Emit updated state summary for easy inspection.
219
- print(json.dumps(state, indent=2))
220
-
221
-
222
- if __name__ == "__main__":
223
- main()