@jaguilar87/gaia-ops 4.4.0-rc.4 → 4.4.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.
@@ -8,14 +8,8 @@
8
8
  {
9
9
  "name": "gaia-security",
10
10
  "description": "Keeps you in the loop only when it matters. Gaia Security analyzes every command and classifies it into risk tiers: read-only queries run freely, simulations and validations pass through, and state-changing operations (create, delete, apply, push) pause for your explicit approval before executing. Irreversible commands like dropping databases or deleting cloud infrastructure are permanently blocked.",
11
- "version": "4.4.0-rc.4",
11
+ "version": "4.4.0",
12
12
  "source": "./dist/gaia-security"
13
- },
14
- {
15
- "name": "gaia-ops",
16
- "description": "Full DevOps orchestration for Claude Code. Six specialized agents handle the complete development lifecycle — analysis, planning, execution, and deployment. Gaia-Ops scans your codebase to understand it and injects the right context into each sub-agent. Every command is classified by risk: read-only runs freely, state changes pause for your approval, and irreversible operations are permanently blocked.",
17
- "version": "4.4.0-rc.4",
18
- "source": "./dist/gaia-ops"
19
13
  }
20
14
  ]
21
15
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gaia-ops",
3
- "version": "4.4.0-rc.4",
3
+ "version": "4.4.0",
4
4
  "description": "Security-first orchestrator with specialized agents, hooks, and governance for AI coding",
5
5
  "author": {
6
6
  "name": "jaguilar87"
package/ARCHITECTURE.md CHANGED
@@ -15,7 +15,7 @@ The package is published as `@jaguilar87/gaia-ops` on npm and installed into a p
15
15
  | **Hook** | Python scripts that intercept tool calls before and after execution |
16
16
  | **Tool** | Python modules in `tools/` providing context assembly, memory, and validation |
17
17
  | **Config** | JSON files in `config/` defining contracts, rules, surface routing, and security |
18
- | **Orchestrator** | The root `CLAUDE.md` that routes user requests to the correct agent |
18
+ | **Orchestrator** | Identity injected by UserPromptSubmit hook; routes requests to the correct agent via on-demand skills |
19
19
 
20
20
  ## Runtime Flow
21
21
 
@@ -23,17 +23,21 @@ The package is published as `@jaguilar87/gaia-ops` on npm and installed into a p
23
23
  User request
24
24
  |
25
25
  v
26
- Orchestrator (CLAUDE.md)
26
+ user_prompt_submit.py (UserPromptSubmit hook)
27
+ | Inject orchestrator identity via ops_identity.py
28
+ | Skills loaded on-demand: project-dispatch, agent-response
29
+ v
30
+ Orchestrator dispatches to agent
27
31
  | Routes by surface classification
28
32
  v
29
33
  pre_tool_use.py (PreToolUse hook)
30
- | 1. Inject project-context into agent prompt
31
- | 2. Inject session events
34
+ | 1. Inject project-context into agent prompt (Task/Agent)
35
+ | 2. Inject session events (Task/Agent)
32
36
  | 3. Validate Bash commands (security gate)
33
- | 4. Validate Task/Agent invocations
37
+ | 4. Validate SendMessage (agent resumption)
34
38
  v
35
39
  Agent executes
36
- | Uses tools, follows skills, emits AGENT_STATUS
40
+ | Uses tools, follows skills, emits json:contract
37
41
  v
38
42
  subagent_stop.py (SubagentStop hook)
39
43
  | 1. Read transcript, extract task description
@@ -43,10 +47,10 @@ subagent_stop.py (SubagentStop hook)
43
47
  | 5. Store episodic memory
44
48
  | 6. Process CONTEXT_UPDATE blocks
45
49
  v
46
- Orchestrator processes AGENT_STATUS
50
+ Orchestrator processes json:contract (via agent-response skill)
47
51
  | COMPLETE -> summarize to user
48
- | AWAITING_APPROVAL -> get approval -> resume
49
- | NEEDS_INPUT -> ask user -> resume
52
+ | AWAITING_APPROVAL -> get approval -> resume via SendMessage
53
+ | NEEDS_INPUT -> ask user -> resume via SendMessage
50
54
  | BLOCKED -> report blocker
51
55
  ```
52
56
 
@@ -74,10 +78,17 @@ Order is short-circuit -- first match wins:
74
78
 
75
79
  ```
76
80
  1. Response contract guard --> if pending repair exists, block new tasks until resolved
77
- 2. Context injection --> context_provider.py assembles payload, injected into prompt
78
- 3. Session events injection --> recent git commits, pushes, file mods added to prompt
79
- 4. Resume validation --> validate agent ID format, detect approval nonces
80
- 5. TaskValidator --> validate agent name, check available agents
81
+ 2. Context injection --> context_provider.py assembles payload, injected via additionalContext
82
+ 3. Session events injection --> recent git commits, pushes, file mods added via additionalContext
83
+ 4. TaskValidator --> validate agent name, check available agents
84
+ ```
85
+
86
+ ### SendMessage Validation (PreToolUse matcher)
87
+
88
+ ```
89
+ 1. Agent ID format check --> must match /^a[0-9a-f]{5,}$/
90
+ 2. Message presence check --> non-empty message required
91
+ 3. Nonce approval check --> detect APPROVE:{nonce}, activate pending grants
81
92
  ```
82
93
 
83
94
  ## Agent Completion Pipeline: subagent_stop.py
@@ -252,7 +263,7 @@ The adapter layer connects Claude Code's hook protocol to gaia-ops business logi
252
263
  | **File (npm channel)** | `templates/settings.template.json` -- paths use `.claude/hooks/` prefix |
253
264
  | **File (plugin channel)** | `hooks/hooks.json` -- paths use `${CLAUDE_PLUGIN_ROOT}/hooks/` prefix |
254
265
  | **What it does** | Maps Claude Code hook events to handler scripts. Defines which events fire which entry points, the tool matchers (Bash, Task, Agent, `*`), and permissions (allow/deny lists). |
255
- | **Events configured** | PreToolUse, PostToolUse, SubagentStop, SessionStart, Stop, TaskCompleted, SubagentStart (UserPromptSubmit is a static echo in settings.json only) |
266
+ | **Events configured** | PreToolUse (Bash, Task, Agent, SendMessage), PostToolUse, SubagentStop, SessionStart, Stop, TaskCompleted, SubagentStart, UserPromptSubmit (identity injection) |
256
267
 
257
268
  ### HookAdapter ABC Contract
258
269
 
@@ -299,7 +310,9 @@ To support a CLI other than Claude Code (e.g., a hypothetical Cursor or Windsurf
299
310
 
300
311
  | File | Purpose |
301
312
  |------|---------|
302
- | `CLAUDE.md` | Orchestrator identity, routing table, tool restrictions |
313
+ | `hooks/modules/identity/ops_identity.py` | Orchestrator identity (injected by UserPromptSubmit) |
314
+ | `skills/project-dispatch/SKILL.md` | Agent routing table and dispatch rules (on-demand) |
315
+ | `skills/agent-response/SKILL.md` | Contract status handling protocol (on-demand) |
303
316
  | `hooks/pre_tool_use.py` | PreToolUse hook entry point |
304
317
  | `hooks/subagent_stop.py` | SubagentStop hook entry point |
305
318
  | `hooks/modules/tools/bash_validator.py` | Bash command security gate |
package/CHANGELOG.md CHANGED
@@ -1,14 +1,20 @@
1
1
  # Changelog: CLAUDE.md
2
2
 
3
- All notable changes to the CLAUDE.md orchestrator instructions are documented in this file.
3
+ All notable changes to the gaia-ops orchestration system are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [Unreleased]
8
+ ## [4.4.0-rc.5] - 2026-03-19
9
9
 
10
- ### Added
11
- - Plugin distribution: `.claude-plugin/plugin.json` manifest for Claude Code native plugin system
10
+ ### Identity Redesign
11
+
12
+ Orchestrator identity is now minimal (~900 chars) and delegates to on-demand skills. CLAUDE.template.md deleted -- the UserPromptSubmit hook is the single source of truth for orchestrator identity.
13
+
14
+ #### Added
15
+ - **`skills/project-dispatch/SKILL.md`** (Reference type) -- agent routing table and dispatch rules, loaded on-demand via Skill tool
16
+ - **`skills/agent-response/SKILL.md`** (Protocol type) -- contract status handling, loaded on-demand via Skill tool
17
+ - Plugin distribution: `.claude-plugin/plugin.json` manifest with engines + categories for Claude Code native plugin system
12
18
  - Self-hosted marketplace: `.claude-plugin/marketplace.json` with 2 sub-plugin tiers (gaia-security, gaia-ops)
13
19
  - Adapter layer: `hooks/adapters/` with normalized types, abstract base, and Claude Code adapter
14
20
  - `hooks/hooks.json` for plugin-channel hook configuration
@@ -16,9 +22,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
16
22
  - Integration tests for adapter -> business logic -> response flow
17
23
  - Plugin manifest validation tests
18
24
 
19
- ### Changed
25
+ #### Changed
26
+ - **`hooks/modules/identity/ops_identity.py`** -- reduced to ~900 chars; tells orchestrator to load skills on-demand instead of embedding all instructions inline
27
+ - **SendMessage validation** -- moved from invalid hook event to PreToolUse matcher (agent ID format + nonce approval check)
28
+ - **`hooks/modules/scanning/scan_trigger.py`** -- imports `tools.scan` directly (no `bin/` dependency), works in both npm and plugin mode
29
+ - **Agent namespace support** -- accepts both `cloud-troubleshooter` and `gaia-ops:cloud-troubleshooter` forms
30
+ - **`hooks/user_prompt_submit.py`** -- calls `ensure_plugin_registry()` as fallback if SessionStart didn't fire
31
+ - **`hooks/modules/context/context_injector.py`** -- path fixes for plugin mode
32
+ - **`hooks/modules/session/session_event_injector.py`** -- path fixes for plugin mode
20
33
  - Hook entry points (pre_tool_use.py, post_tool_use.py, subagent_stop.py) now use adapter layer for stdin/stdout
21
34
  - hook_response.py delegates to ClaudeCodeAdapter internally
35
+ - npm dist-tag now derived from version suffix (rc -> next, beta -> beta, etc.)
36
+
37
+ #### Removed
38
+ - **`templates/CLAUDE.template.md`** -- identity now injected dynamically; no generated CLAUDE.md
39
+ - **`copy_claude_md()`** in `tools/scan/setup.py` -- deprecated to no-op (callers still reference it for backward compat)
22
40
 
23
41
  ## [4.0.0] - 2026-03-03
24
42
 
package/INSTALL.md CHANGED
@@ -82,7 +82,6 @@ Creates symlinks to gaia-ops:
82
82
  .claude/templates → node_modules/.../templates
83
83
 
84
84
  Generates config files:
85
- - CLAUDE.md (orchestrator)
86
85
  - project-context.json
87
86
  - settings.json
88
87
 
@@ -118,8 +117,8 @@ Example: Installation in project with GitOps and Terraform
118
117
  5. Creates structure:
119
118
  ✅ .claude/ created
120
119
  ✅ 8 symlinks created
121
- ✅ CLAUDE.md generated (196 lines)
122
120
  ✅ project-context.json created
121
+ ✅ settings.json created
123
122
 
124
123
  6. Result:
125
124
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -195,7 +194,6 @@ your-project/
195
194
  │ ├── project-context/ ← Your project context (SSOT)
196
195
  │ ├── logs/ ← Audit logs
197
196
  │ └── settings.json ← Security configuration
198
- ├── CLAUDE.md ← Main orchestrator
199
197
  └── node_modules/
200
198
  └── @jaguilar87/gaia-ops/ ← npm package
201
199
  ```
@@ -211,10 +209,10 @@ Once installed, you have access to **complete documentation** in each directory:
211
209
  ```
212
210
  .claude/
213
211
  ├── agents/ 6 agents (terraform-architect, gitops-operator, etc.)
214
- ├── skills/README.md 16 skill modules
212
+ ├── skills/README.md 20 skill modules
215
213
  ├── commands/README.md 6 slash commands (5 speckit + scan-project)
216
214
  ├── config/README.md Contracts, git standards, universal rules
217
- ├── hooks/README.md 9 hook scripts (3 primary + 6 event handlers)
215
+ ├── hooks/README.md 8 hook scripts (4 primary + 4 event handlers)
218
216
  ├── tools/ Context, memory, validation, review
219
217
  ├── speckit/README.md Spec-Kit framework
220
218
  ├── templates/README.md Installation templates
@@ -239,11 +237,11 @@ ls -la .claude/
239
237
  ### 2. Review Generated Configuration
240
238
 
241
239
  ```bash
242
- # View generated CLAUDE.md
243
- cat CLAUDE.md
244
-
245
240
  # View project-context.json
246
241
  cat .claude/project-context/project-context.json
242
+
243
+ # View settings.json
244
+ cat .claude/settings.json
247
245
  ```
248
246
 
249
247
  ### 3. Start Claude Code
@@ -273,27 +271,22 @@ When you update `@jaguilar87/gaia-ops`, these files are **regenerated from templ
273
271
 
274
272
  | File | Behavior | Recommended Action |
275
273
  |------|----------|-------------------|
276
- | `CLAUDE.md` | ⚠️ **Overwritten** | Backup if you customize |
277
- | `.claude/settings.json` | ✅ **Merged** (hooks/permissions deep-merged, custom rules preserved) | Safe |
274
+ | `.claude/settings.json` | ⚠️ **Replaced** from template (source of truth) | Safe |
278
275
  | `.claude/project-context/project-context.json` | ✅ **Preserved** | Safe |
279
276
  | `.claude/logs/` | ✅ **Preserved** | Safe |
280
277
  | Other `.claude/` files | ✅ **Auto-updated via symlinks** | Safe |
281
278
 
279
+ Orchestrator identity is injected dynamically by the UserPromptSubmit hook -- no `CLAUDE.md` is generated.
280
+
282
281
  ### Update Process
283
282
 
284
283
  ```bash
285
- # 1. Backup (optional, if you customized CLAUDE.md)
286
- cp CLAUDE.md CLAUDE.md.backup
287
-
288
- # 2. Update package
284
+ # 1. Update package
289
285
  npm install @jaguilar87/gaia-ops@latest
290
286
 
291
- # 3. Postinstall hook automatically:
292
- # - Overwrites CLAUDE.md (static orchestrator config)
293
- # - Merges settings.json (hooks/permissions deep-merged, custom rules preserved)
294
-
295
- # 4. If you made a CLAUDE.md backup, compare and merge changes
296
- diff CLAUDE.md CLAUDE.md.backup
287
+ # 2. Postinstall hook automatically:
288
+ # - Replaces settings.json from template
289
+ # - Fixes broken symlinks
297
290
  ```
298
291
 
299
292
  ---
@@ -398,10 +391,7 @@ npx gaia-uninstall --force --remove-all
398
391
  # 1. Remove .claude/ directory
399
392
  rm -rf .claude/
400
393
 
401
- # 2. Remove generated files
402
- rm CLAUDE.md
403
-
404
- # 3. Uninstall npm package
394
+ # 2. Uninstall npm package
405
395
  npm uninstall @jaguilar87/gaia-ops
406
396
  ```
407
397
 
@@ -436,15 +426,12 @@ A: Yes. Install in each project and each will have its own `project-context.json
436
426
  **Q: Do symlinks work on Windows?**
437
427
  A: Yes, but you need to enable developer mode or run as administrator.
438
428
 
439
- **Q: Can I customize CLAUDE.md without it being overwritten?**
440
- A: Not directly. Better: contribute changes to the template in the repository.
441
-
442
- **Q: How do I update only documentation without changing code?**
429
+ **Q: How do I update only documentation without changing code?**
443
430
  A: `npm update @jaguilar87/gaia-ops` - symlinks point to the new version automatically.
444
431
 
445
432
  ---
446
433
 
447
- **Version:** 4.2.0
448
- **Last updated:** 2026-03-11
434
+ **Version:** 4.4.0-rc.5
435
+ **Last updated:** 2026-03-19
449
436
  **Maintained by:** Jorge Aguilar + Gaia (meta-agent)
450
437
 
package/README.md CHANGED
@@ -1,25 +1,27 @@
1
- # @jaguilar87/gaia-ops
1
+ # GAIA-Ops
2
+
3
+ > **G**eneral **A**gentic **I**ntegration **A**rchitecture
2
4
 
3
5
  [![npm version](https://badge.fury.io/js/@jaguilar87%2Fgaia-ops.svg)](https://www.npmjs.com/package/@jaguilar87/gaia-ops)
4
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
7
  [![Node.js Version](https://img.shields.io/node/v/@jaguilar87/gaia-ops.svg)](https://nodejs.org)
6
8
 
7
- Multi-agent orchestration system for Claude Code - DevOps automation toolkit.
9
+ Multi-agent DevOps system that classifies every operation by risk, routes work to specialist agents, and blocks irreversible commands automatically.
8
10
 
9
11
  ## Overview
10
12
 
11
- **Gaia-Ops** provides a complete agent orchestration system for Claude Code, enabling intelligent automation of DevOps workflows through specialized AI agents.
13
+ **GAIA-Ops** is a multi-agent orchestration system for DevOps automation. It provides security-first command classification, specialized AI agents, and plugin-based distribution. Currently integrates with Claude Code.
12
14
 
13
15
  ### Features
14
16
 
15
17
  - **Multi-cloud support** - GCP, AWS
16
18
  - **6 agents** - terraform-architect, gitops-operator, cloud-troubleshooter, devops-developer, speckit-planner, gaia (meta-agent)
17
19
  - **Contracts as SSOT** - Cloud-agnostic base contracts with per-cloud extensions (GCP, AWS)
18
- - **Episodic Memory** - Persistent memory system for operational patterns
19
- - **Approval gates** for T3 operations
20
+ - **Dynamic identity** - Orchestrator identity injected by UserPromptSubmit hook; skills loaded on-demand
21
+ - **Approval gates** for T3 operations via nonce-based workflow
20
22
  - **Git commit validation** with Conventional Commits
21
- - **16 skills** - Injected procedural knowledge modules for agents
22
- - **1800+ tests** at 100% passing
23
+ - **20 skills** - Injected procedural knowledge modules for agents
24
+ - **Plugin + npm** - Distributable as Claude Code native plugin or npm package
23
25
 
24
26
  ## Installation
25
27
 
@@ -56,7 +58,9 @@ This will:
56
58
  1. Auto-detect your project structure (GitOps, Terraform, AppServices)
57
59
  2. Install Claude Code if not present
58
60
  3. Create `.claude/` directory with symlinks to this package
59
- 4. Generate `CLAUDE.md` and `project-context.json`
61
+ 4. Generate `project-context.json` and `settings.json`
62
+
63
+ No `CLAUDE.md` is generated -- orchestrator identity is injected dynamically by the UserPromptSubmit hook.
60
64
 
61
65
  ### Manual Installation
62
66
 
@@ -86,7 +90,7 @@ Once installed, the agent system is ready:
86
90
  claude
87
91
  ```
88
92
 
89
- Claude Code will automatically load `CLAUDE.md` and have access to all agents via `.claude/`.
93
+ The orchestrator identity is injected dynamically by the UserPromptSubmit hook. Skills are loaded on-demand.
90
94
 
91
95
  Skills and injection diagnosis:
92
96
 
@@ -101,15 +105,15 @@ npx gaia-skills-diagnose --run-tests
101
105
  ```
102
106
  node_modules/@jaguilar87/gaia-ops/
103
107
  ├── agents/ # Agent definitions (6 agents)
104
- ├── skills/ # Skill modules (16 skills)
108
+ ├── skills/ # Skill modules (20 skills)
105
109
  ├── tools/ # Orchestration tools
106
110
  ├── hooks/ # Claude Code hooks (modular architecture)
107
- ├── commands/ # Slash commands (6 commands: 5 speckit + scan-project)
111
+ ├── commands/ # Slash commands (5 speckit + scan-project)
108
112
  ├── config/ # Configuration (contracts, git standards, rules)
109
- ├── templates/ # Installation templates
110
- ├── speckit/ # Spec-Kit framework (scripts + templates)
113
+ ├── templates/ # Installation templates (settings, governance)
114
+ ├── speckit/ # Spec-Kit framework (templates)
111
115
  ├── bin/ # CLI utilities (11 scripts)
112
- └── tests/ # Test suite (1800+ tests)
116
+ └── tests/ # Test suite
113
117
  ```
114
118
 
115
119
  ## API
@@ -129,7 +133,7 @@ This package follows [Semantic Versioning](https://semver.org/):
129
133
  - **MINOR:** New features
130
134
  - **PATCH:** Bug fixes
131
135
 
132
- Current version: **4.2.0**
136
+ Current version: **4.4.0-rc.5**
133
137
 
134
138
  See [CHANGELOG.md](./CHANGELOG.md) for version history.
135
139
 
package/SECURITY.md CHANGED
@@ -42,6 +42,6 @@ The following are considered security vulnerabilities in gaia-ops:
42
42
 
43
43
  ## Out of Scope
44
44
 
45
- - Vulnerabilities in Claude Code itself (report to Anthropic)
46
- - Issues in upstream dependencies (report to the respective maintainer)
47
- - Denial of service through large inputs (this is a local development tool)
45
+ - Vulnerabilities in Claude Code itself (report to Anthropic).
46
+ - Issues in upstream dependencies (report to the respective maintainer).
47
+ - Denial of service through large inputs (this is a local development tool).
package/bin/README.md CHANGED
@@ -129,7 +129,6 @@ npm uninstall @jaguilar87/gaia-ops
129
129
 
130
130
  **What it preserves:**
131
131
  - `project-context.json`
132
- - `CLAUDE.md`
133
132
  - `.claude/` symlinks
134
133
 
135
134
  ## Environment Variables
@@ -147,4 +146,4 @@ npx gaia-scan --non-interactive
147
146
 
148
147
  ---
149
148
 
150
- **Version:** 4.2.0 | **Updated:** 2026-03-11 | **Scripts:** 11
149
+ **Version:** 4.4.0-rc.5 | **Updated:** 2026-03-19 | **Scripts:** 11
@@ -61,7 +61,7 @@ function findProjectRoot() {
61
61
  const CWD = findProjectRoot();
62
62
 
63
63
  /**
64
- * Remove CLAUDE.md if it exists
64
+ * Remove legacy CLAUDE.md if it exists (identity now injected by hook).
65
65
  */
66
66
  async function removeClaudeMd() {
67
67
  const spinner = ora('Removing CLAUDE.md...').start();
@@ -73,33 +73,13 @@ async function checkSymlinks() {
73
73
  }
74
74
 
75
75
  async function checkClaudeMd() {
76
+ // CLAUDE.md is no longer generated -- identity is injected by UserPromptSubmit hook.
77
+ // If a project still has a CLAUDE.md from a previous version, that's fine but not required.
76
78
  const path = join(CWD, 'CLAUDE.md');
77
-
78
- if (!existsSync(path)) {
79
- return { name: 'CLAUDE.md', ok: false, detail: 'Missing', fix: 'Run gaia-scan' };
79
+ if (existsSync(path)) {
80
+ return { name: 'CLAUDE.md', ok: true, detail: 'Present (legacy -- identity now injected by hook)' };
80
81
  }
81
-
82
- const content = await fs.readFile(path, 'utf-8');
83
- const issues = [];
84
-
85
- if (content.includes('{{')) {
86
- issues.push('Contains raw {{placeholders}} - template was not processed');
87
- }
88
-
89
- if (content.length < 100) {
90
- issues.push('File is suspiciously short');
91
- }
92
-
93
- if (!content.includes('Binary Delegation') && !content.includes('orchestrator')) {
94
- issues.push('Missing core orchestrator instructions');
95
- }
96
-
97
- if (issues.length > 0) {
98
- return { name: 'CLAUDE.md', ok: false, detail: issues.join('; '), fix: 'Run gaia-scan to regenerate' };
99
- }
100
-
101
- const lines = content.split('\n').length;
102
- return { name: 'CLAUDE.md', ok: true, detail: `Valid (${lines} lines)` };
82
+ return { name: 'CLAUDE.md', ok: true, detail: 'Not present (identity injected by UserPromptSubmit hook)' };
103
83
  }
104
84
 
105
85
  async function checkSettingsJson() {
@@ -354,19 +334,7 @@ async function autoFix() {
354
334
  }
355
335
  }
356
336
 
357
- // Fix CLAUDE.md with raw placeholders
358
- const claudeMdPath = join(CWD, 'CLAUDE.md');
359
- if (existsSync(claudeMdPath)) {
360
- const content = await fs.readFile(claudeMdPath, 'utf-8');
361
- if (content.includes('{{')) {
362
- const templatePath = join(CWD, '.claude', 'templates', 'CLAUDE.template.md');
363
- if (existsSync(templatePath)) {
364
- await fs.copyFile(templatePath, claudeMdPath);
365
- console.log(chalk.green(' Fixed: CLAUDE.md regenerated from template'));
366
- fixed++;
367
- }
368
- }
369
- }
337
+ // CLAUDE.md no longer generated -- identity injected by UserPromptSubmit hook
370
338
 
371
339
  // Create missing project dirs
372
340
  const contextPath = join(CWD, '.claude', 'project-context', 'project-context.json');
@@ -690,19 +690,8 @@ function detectLegacyGapPatterns(ctx, findings, checks) {
690
690
  const conftestPath = path.join(testsDir, "conftest.py");
691
691
  if (exists(conftestPath)) {
692
692
  const content = readText(conftestPath);
693
- const expectsRootClaudeMd = content.includes('(package_root / "CLAUDE.md").read_text()');
694
- const hasRootClaudeMd = exists(ctx.rootClaudeMd);
695
-
696
- if (expectsRootClaudeMd && !hasRootClaudeMd) {
697
- addFinding(findings, {
698
- severity: "high",
699
- code: "TEST_EXPECTS_MISSING_CLAUDE_MD",
700
- title: "Tests require package-root CLAUDE.md that does not exist",
701
- detail: "tests/conftest.py fixture reads package_root/CLAUDE.md, causing routing-table tests to error.",
702
- evidence: `${path.relative(PACKAGE_ROOT, conftestPath)} + missing ${path.relative(PACKAGE_ROOT, ctx.rootClaudeMd)}`,
703
- remediation: "Either include CLAUDE.md in package root or make fixture robust to installed-project layout.",
704
- });
705
- }
693
+ // CLAUDE.md is no longer generated -- identity injected by UserPromptSubmit hook.
694
+ // conftest.py fixture now falls back to ops_identity.py + dispatch/response skills.
706
695
  }
707
696
 
708
697
  checks.push({
@@ -767,16 +756,7 @@ function runTestProbe(ctx, findings, checks) {
767
756
  });
768
757
  }
769
758
 
770
- if (combined.includes("No such file or directory") && combined.includes("CLAUDE.md")) {
771
- addFinding(findings, {
772
- severity: "high",
773
- code: "PYTEST_FAILS_ON_MISSING_CLAUDE_MD",
774
- title: "Routing-table tests fail because package-root CLAUDE.md is missing",
775
- detail: "tests/conftest.py fixture assumes package_root/CLAUDE.md exists.",
776
- evidence: "FileNotFoundError: .../gaia-ops/CLAUDE.md",
777
- remediation: "Provide CLAUDE.md or adjust fixture to locate generated CLAUDE.md in project context.",
778
- });
779
- }
759
+ // CLAUDE.md is no longer required -- conftest.py falls back to ops_identity.py
780
760
  }
781
761
 
782
762
  checks.push({
@@ -10,11 +10,10 @@
10
10
  * - First-time install (.claude/ doesn't exist): skip silently (gaia-scan handles it)
11
11
  * - Update (.claude/ exists):
12
12
  * 1. Show version transition (previous → current)
13
- * 2. CLAUDE.md: overwrite safely (template is static)
14
- * 3. settings.json: REPLACE from template (template is source of truth)
15
- * 4. Symlinks: recreate if missing, fix broken ones
16
- * 5. Verify: hooks, python, project-context, config files
17
- * 6. Report: summary with any issues found
13
+ * 2. settings.json: REPLACE from template (template is source of truth)
14
+ * 3. Symlinks: recreate if missing, fix broken ones
15
+ * 4. Verify: hooks, python, project-context, config files
16
+ * 5. Report: summary with any issues found
18
17
  *
19
18
  * Usage:
20
19
  * npm update @jaguilar87/gaia-ops # Automatic via postinstall
@@ -72,27 +71,6 @@ async function readPackageVersion(path) {
72
71
  // Update Steps
73
72
  // ============================================================================
74
73
 
75
- async function updateClaudeMd() {
76
- const spinner = ora('Updating CLAUDE.md...').start();
77
- try {
78
- const templatePath = join(__dirname, '../templates/CLAUDE.template.md');
79
- const claudeDir = join(CWD, '.claude');
80
-
81
- if (!existsSync(templatePath) || !existsSync(claudeDir)) {
82
- spinner.info('Skipped (template or .claude/ not found)');
83
- return false;
84
- }
85
-
86
- const claudeMdPath = join(CWD, 'CLAUDE.md');
87
- await fs.copyFile(templatePath, claudeMdPath);
88
- spinner.succeed('CLAUDE.md updated');
89
- return true;
90
- } catch (error) {
91
- spinner.fail(`CLAUDE.md: ${error.message}`);
92
- return false;
93
- }
94
- }
95
-
96
74
  async function updateSettingsJson() {
97
75
  const spinner = ora('Updating settings.json...').start();
98
76
  try {
@@ -295,16 +273,15 @@ async function main() {
295
273
 
296
274
  console.log(chalk.cyan(`\n gaia-ops update ${versionLine}\n`));
297
275
 
298
- // Step 1-3: Update files
299
- const claudeUpdated = await updateClaudeMd();
276
+ // Step 1-2: Update files
300
277
  const settingsUpdated = await updateSettingsJson();
301
278
  const { updated: symlinksUpdated, fixed: symlinksFix } = await updateSymlinks();
302
279
 
303
- // Step 4: Verify
280
+ // Step 3: Verify
304
281
  const { issues, passed, total } = await runVerification();
305
282
 
306
283
  // Summary
307
- const changes = [claudeUpdated, settingsUpdated, symlinksUpdated].filter(Boolean).length;
284
+ const changes = [settingsUpdated, symlinksUpdated].filter(Boolean).length;
308
285
 
309
286
  console.log('');
310
287
  if (changes > 0 || issues.length > 0) {