Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export A2A_NODE_ID=node_xxxxxxxxxxxx
Or in your agent config (e.g., `~/.openclaw/openclaw.json`):

```json
{ "env": { "A2A_NODE_ID": "node_xxxxxxxxxxxx", "A2A_HUB_URL": "https://evomap.ai" } }
{ "env": { "A2A_NODE_ID": "node_xxxxxxxxxxxx" } }
```

Do not hardcode the node ID in scripts. `getNodeId()` in `src/gep/a2aProtocol.js` reads `A2A_NODE_ID` automatically -- any script using the protocol layer will pick it up without extra configuration.
Expand All @@ -65,6 +65,7 @@ Do not hardcode the node ID in scripts. `getNodeId()` in `src/gep/a2aProtocol.js
| `EVOLVE_ALLOW_SELF_MODIFY` | `false` | Allow evolution to modify evolver's own source code. **NOT recommended for production.** Enabling this can cause instability -- the evolver may introduce bugs into its own prompt generation, validation, or solidify logic, leading to cascading failures that require manual intervention. Only enable for controlled experiments. |
| `EVOLVE_LOAD_MAX` | `2.0` | Maximum 1-minute load average before evolver backs off. |
| `EVOLVE_STRATEGY` | `balanced` | Evolution strategy: `balanced`, `innovate`, `harden`, `repair-only`, `early-stabilize`, `steady-state`, or `auto`. |
| `EVOLVER_ROLLBACK_MODE` | `hard` | Rollback strategy when evolution fails. `hard`: use `git reset --hard` (destructive, original behavior). `stash`: use `git stash` to preserve changes for recovery. `none`: skip rollback entirely. Use `stash` for safer operation in active workspaces. |

## GEP Protocol (Auditable Evolution)

Expand Down
24 changes: 24 additions & 0 deletions src/gep/solidify.js
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,30 @@ function buildFailureReason(constraintCheck, validation, protocolViolations, can
}

function rollbackTracked(repoRoot) {
const mode = String(process.env.EVOLVER_ROLLBACK_MODE || 'hard').toLowerCase();

if (mode === 'none') {
console.log('[Rollback] EVOLVER_ROLLBACK_MODE=none, skipping rollback');
return;
}

if (mode === 'stash') {
// SAFETY: Use git stash instead of git reset --hard to preserve changes.
// Changes can be recovered via "git stash list" and "git stash pop".
const stashRef = 'evolver-rollback-' + Date.now();
const result = tryRunCmd('git stash push -m "' + stashRef + '" --include-untracked', { cwd: repoRoot, timeoutMs: 60000 });
if (result.ok) {
console.log('[Rollback] Changes stashed with ref: ' + stashRef + '. Recover with "git stash list" and "git stash pop".');
} else {
// Fallback to hard reset if stash fails (e.g., no changes to stash)
console.log('[Rollback] Stash failed or no changes, using hard reset');
tryRunCmd('git restore --staged --worktree .', { cwd: repoRoot, timeoutMs: 60000 });
tryRunCmd('git reset --hard', { cwd: repoRoot, timeoutMs: 60000 });
}
return;
}

// Default: hard reset (original behavior)
tryRunCmd('git restore --staged --worktree .', { cwd: repoRoot, timeoutMs: 60000 });
tryRunCmd('git reset --hard', { cwd: repoRoot, timeoutMs: 60000 });
}
Expand Down