Decouple policy updates and modifications. Prevent accidental destructive actions.

This commit is contained in:
Christian Gunderman
2026-04-22 11:07:42 -07:00
parent 5e24d6285e
commit 8b4c10dd15
6 changed files with 67 additions and 30 deletions
+29 -14
View File
@@ -10,9 +10,9 @@ async function main() {
const program = new Command();
program
.option('--investigate', 'Run investigation phase', false)
.option('--update-processes', 'Update processes based on learnings', false)
.option('--update-processes', 'Run the update-processes phase to generate/improve scripts', false)
.option('--create-pr', 'Create a PR when updating processes', false)
.option('--commit', 'Run processes and commit changes', false)
.option('--execute-actions', 'Actually execute destructive or state-changing actions (e.g., closing issues, commenting)', false)
.parse(process.argv);
const options = program.opts();
@@ -48,27 +48,36 @@ async function main() {
console.warn('Artifact check/download skipped, proceeding with fresh state.');
}
const policyPath = options.executeActions ? undefined : path.join(__dirname, 'policies', 'readonly-gh.toml');
// 1. Initial Metrics
await runPhase('metrics', { PRE_RUN: 'true' }, options);
await runPhase('metrics', { PRE_RUN: 'true' }, options, policyPath);
// 2. Investigation (Optional)
if (options.investigate) {
await runPhase('investigations', {}, options);
await runPhase('investigations', {}, options, policyPath);
}
// 3. Update Processes & Run
await runPhase('processes', {
UPDATE_PROCESSES: String(options.updateProcesses),
COMMIT: String(options.commit),
}, options);
// 3. Update Processes (Optional)
if (options.updateProcesses) {
await runPhase('process-updater', {
CREATE_PR: String(options.createPr),
EXECUTE_ACTIONS: String(options.executeActions),
}, options, policyPath);
}
// 4. Final Metrics
await runPhase('metrics', { PRE_RUN: 'false' }, options);
// 4. Run Processes
await runPhase('processes', {
EXECUTE_ACTIONS: String(options.executeActions),
}, options, policyPath);
// 5. Final Metrics
await runPhase('metrics', { PRE_RUN: 'false' }, options, policyPath);
console.log('\nOptimizer1000 completed.');
}
async function runPhase(phaseDir: string, env: Record<string, string>, options: any) {
async function runPhase(phaseDir: string, env: Record<string, string>, options: any, policyPath?: string) {
console.log(`\n--- Phase: ${phaseDir} ---`);
const phasePath = path.join(__dirname, phaseDir);
@@ -98,11 +107,17 @@ async function runPhase(phaseDir: string, env: Record<string, string>, options:
const rootDir = path.resolve(__dirname, '../..');
try {
// Run GCLI non-interactively with --yolo to bypass policies
// Run GCLI non-interactively. Use --yolo to auto-approve 'allow' rules,
// but policies can still 'deny' actions.
const cliPath = path.join(rootDir, 'packages', 'cli');
const args = ['--prompt', userPrompt, '--yolo', '--model', 'gemini-3-flash-preview'];
if (policyPath) {
args.push('--admin-policy', policyPath);
}
await new Promise<void>((resolve, reject) => {
const child = spawn('node', [cliPath, '--prompt', userPrompt, '--yolo', '--model', 'gemini-3-flash-preview'], {
const child = spawn('node', [cliPath, ...args], {
stdio: 'inherit',
cwd: rootDir,
env: { ...process.env, ...env }
@@ -13,7 +13,7 @@ of the data and identify any opportunities for improvement.
- **Develop Competing Hypotheses**: Brainstorm multiple potential root causes (e.g., "Latency is due to slow reviews" vs. "Latency is due to slow author responses").
- **Gather Evidence**: Use or create scripts to collect data that supports or refutes EACH hypothesis (e.g., check timestamp of last review vs. last commit).
- **Select Root Cause**: Identify the hypothesis most strongly supported by the data.
5. **Output Actionable Data**: Write specific targets for optimization to CSV files (e.g., `reviewer_bottlenecks.csv`, `author_stale_prs.csv`). These files MUST contain identifiers and the specific reason (evidence) for targeting.
5. **Output Actionable Data**: Write specific targets for optimization to CSV files (e.g., `author_stale_prs.csv`). These files MUST contain identifiers and the specific reason (evidence) for targeting.
6. Maintain a table of all available investigation scripts in
`investigations/INVESTIGATIONS.md`.
7. Document your hypotheses, the data gathered for each, and your final conclusion in `investigations/INVESTIGATIONS.md`.
+2 -1
View File
@@ -12,6 +12,7 @@
"devDependencies": {
"tsx": "^4.20.3",
"typescript": "^5.4.5",
"@types/node": "^20.12.7"
"@types/node": "^20.12.7",
"@google/gemini-cli-core": "file:../../packages/core"
}
}
+17
View File
@@ -0,0 +1,17 @@
# Optimizer Read-Only Policy
# This policy prevents the agent from performing destructive actions on GitHub.
[[rule]]
toolName = "run_shell_command"
commandRegex = "^gh (issue|pr) (list|view)"
decision = "allow"
priority = 200
description = "Allow listing and viewing issues/PRs for data gathering."
[[rule]]
toolName = "run_shell_command"
commandPrefix = "gh"
decision = "deny"
priority = 100
denyMessage = "State-changing GitHub commands are prohibited in dry-run mode. Use --execute-actions to enable them."
description = "Deny all other gh commands to prevent accidental modifications."
@@ -0,0 +1,10 @@
# Process Updater Agent
Your task is to safely improve the optimization scripts in the repository based on investigations and current state. You are strictly responsible for updating the scripts, NOT for running them against GitHub.
1. Analyze `metrics-before.csv`, `investigations/INVESTIGATIONS.md`, and any actionable target files produced by the Investigations Agent.
2. **Targeted Mitigation**: Ensure your proposed improvements or new scripts in `processes/scripts/` directly address the *confirmed* root cause.
3. **Safety & Idempotency**: Ensure any new scripts or updates you write are safe to run multiple times. They must check for existing states before acting.
4. **Execution Gate**: All scripts you write MUST respect the `EXECUTE_ACTIONS` environment variable. If `process.env.EXECUTE_ACTIONS !== 'true'`, the script must perform a "dry-run" only (logging what it would do) and MUST NOT execute any state-changing `gh` CLI commands (like commenting, closing issues, labeling, etc.).
5. **No Direct Execution**: You MUST NOT run `gh issue close`, `gh issue comment`, `gh issue edit`, `gh pr comment` or any other destructive GitHub CLI commands yourself. You are only allowed to write/update the local `.ts` files in `processes/scripts/`.
6. If `CREATE_PR=true` is provided in your environment, submit a PR with these changes using the `gh pr create` command. Otherwise, leave the changes locally.
+8 -14
View File
@@ -1,16 +1,10 @@
# Processes Agent
# Processes Runner Agent
Your task is to optimize repository metrics based on investigations and current state.
Your task is to run the existing optimization processes to improve repository metrics based on investigations and current state. You are strictly a runner, you MUST NOT modify or update the scripts themselves.
1. Analyze `metrics-before.csv`, `investigations/INVESTIGATIONS.md`, and any actionable target files (e.g., `reviewer_bottlenecks.csv`) produced by the Investigations Agent.
2. **Targeted Mitigation**: Ensure your proposed improvements or new scripts in `processes/scripts/` directly address the *confirmed* root cause.
3. **Professional Communication & Empathy**: All automated communications MUST be friendly, professional, and appreciative.
- **Always thank the contributor** for their work or for reporting an issue.
- **Tone**: Maintain a helpful and collaborative tone. Avoid blunt or dismissive language (e.g., "low signal", "non-actionable").
- **Clarification First**: NEVER close an item without first politely requesting the specific missing details and allowing at least 7 days for a response.
- **Example**: "Thank you for your contribution to Gemini CLI! We are interested in resolving this, but we need a bit more information to take action. Could you please provide [specific details]? If we don't hear back in 7 days, we'll close this for now, but you're welcome to reopen it once the info is available."
4. **Safety & Idempotency**: Ensure scripts are safe to run multiple times. They should check for existing states (e.g., "Has a reminder already been sent in the last 24h?") before acting.
5. If `UPDATE_PROCESSES=true`, apply changes to `tools/optimizer/` locally. If `CREATE_PR=true` is also provided, submit a PR with these changes using the `gh` CLI. Otherwise, DO NOT submit a PR.
6. Run all active processes documented in `processes/PROCESSES.md`.
7. **Mandatory Simulation**: Regardless of `COMMIT` value, always generate `[concept]-after.csv` (e.g., `issues-after.csv`) in the project root simulating the final state. Use `[concept]-before.csv` as a baseline.
8. If any tool fails (e.g., policy denial), report the error and do not claim success for that specific optimization.
1. Read `processes/PROCESSES.md` to identify all active processes and their corresponding scripts in `processes/scripts/`.
2. Run each documented script (e.g., using `npx tsx <script-path>`). The scripts will automatically read `metrics-before.csv` and `investigations/INVESTIGATIONS.md` if needed.
3. The scripts are already programmed to respect the `EXECUTE_ACTIONS` environment variable. Do not override this variable.
4. **Professional Communication & Empathy**: The scripts have been written to maintain a helpful and collaborative tone, clarifying before closing issues.
5. **Mandatory Simulation**: The scripts will generate `[concept]-after.csv` (e.g., `issues-after.csv`) in the project root simulating the final state.
6. If any tool fails (e.g., policy denial), report the error.