Skip to content

[Self-Heal] Add self-scheduling auto-repair workflow#59

Draft
badMade wants to merge 1 commit into
mainfrom
feature/self-healing-pipeline-4064027269009872807
Draft

[Self-Heal] Add self-scheduling auto-repair workflow#59
badMade wants to merge 1 commit into
mainfrom
feature/self-healing-pipeline-4064027269009872807

Conversation

@badMade

@badMade badMade commented Jun 6, 2026

Copy link
Copy Markdown
Owner

[Self-Heal] Add self-scheduling auto-repair workflow

This PR implements an automated, self-healing CI pipeline capable of rectifying common code drift or build failures proactively and reactively.

Implementation Details:

  • Three trigger modes:
    1. Scheduled (dynamically computed based on commit history)
    2. Reactive (triggers via workflow_run on ci workflow failure)
    3. Manual (workflow_dispatch)
  • Idempotent Repair Pipeline: Performs Rebuild, Linting/Formatting, Test Snapshots, Types, Lockfiles, and Asset generation sequentially. It exits early when the codebase reaches a healthy state with a fixing diff.
  • Telemetry-Driven Scheduling: A dedicated workflow parses recent commit velocity (7 day lookback) to adjust the scheduled cadence dynamically, preventing resource waste on dormant projects while maintaining high vigilance on active ones.
  • Guards & Safeties: Includes PR deduplication checks, stale PR cleanup, branch loop prevention, git-history-based oscillation guards, and entropy pattern scanning for secrets.
  • Documentation: Full setup and reviewer guidelines are documented in SELF_HEAL_SETUP.md.

Initial schedule computed based on telemetry: 0 0 * * 0 (Dormant repository, running weekly).

Reviewers: Please ensure you review the attached logs from the associated Action runs.


PR created automatically by Jules for task 4064027269009872807 started by @badMade

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces an automated self-healing CI pipeline, including configuration files, a detailed setup guide, and scripts to dynamically compute schedules, run health checks, and execute repair steps. While the implementation is solid, several improvements are needed: the self-heal script should exit with code 0 if the codebase is already healthy, and the linting and formatting steps should be split to ensure both run even if one fails. Additionally, the schedule computation script should guard against silent regex replacement failures, and the ESLint configuration should avoid globally disabling core rules to maintain static analysis effectiveness.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread scripts/self_heal.mjs
Comment on lines +62 to +63
console.log('[Self-Heal] Pipeline finished without a successful repair + diff.');
process.exit(1);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

If the repository is already healthy (e.g., during a scheduled run on a clean branch), no diff will be produced. The loop will complete all steps, and the script will exit with code 1 (failure). This will cause the GitHub Action run to falsely report a failure. We should check if the codebase is healthy at the end of the pipeline, and if so, exit with 0.

  const { isHealthy } = checkHealthAndDiff();
  if (isHealthy) {
    console.log('[Self-Heal] Codebase is healthy. Exiting 0.');
    process.exit(0);
  }

  console.log('[Self-Heal] Pipeline finished and codebase is still unhealthy. Exiting 1.');
  process.exit(1);

Comment thread scripts/self_heal.mjs
Comment on lines +35 to +42
const steps = [
{ name: '1: Rebuild/reinstall', cmd: 'npm ci' },
{ name: '2: Lint auto-fix', cmd: 'npx eslint . --fix && npx prettier -w .' },
{ name: '3: Snapshot regeneration', cmd: 'npx vitest run -u --passWithNoTests' },
{ name: '4: Type stubs', cmd: 'npm install' },
{ name: '5: Dependency resolve', cmd: 'npm update' },
{ name: '6: Static assets', cmd: 'npm run build' }
];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If npx eslint . --fix exits with a non-zero code (which happens when there are remaining unfixable lint errors), the && operator will prevent npx prettier -w . from running. Since linting and formatting are independent auto-fix steps, they should both run to maximize the chances of repairing the codebase. Splitting them into separate steps in the steps array ensures both are executed.

Suggested change
const steps = [
{ name: '1: Rebuild/reinstall', cmd: 'npm ci' },
{ name: '2: Lint auto-fix', cmd: 'npx eslint . --fix && npx prettier -w .' },
{ name: '3: Snapshot regeneration', cmd: 'npx vitest run -u --passWithNoTests' },
{ name: '4: Type stubs', cmd: 'npm install' },
{ name: '5: Dependency resolve', cmd: 'npm update' },
{ name: '6: Static assets', cmd: 'npm run build' }
];
const steps = [
{ name: '1: Rebuild/reinstall', cmd: 'npm ci' },
{ name: '2: Lint auto-fix', cmd: 'npx eslint . --fix' },
{ name: '3: Formatting auto-fix', cmd: 'npx prettier -w .' },
{ name: '4: Snapshot regeneration', cmd: 'npx vitest run -u --passWithNoTests' },
{ name: '5: Type stubs', cmd: 'npm install' },
{ name: '6: Dependency resolve', cmd: 'npm update' },
{ name: '7: Static assets', cmd: 'npm run build' }
];

Comment on lines +71 to +75
const updatedContent = workflowContent.replace(
/cron:\s*['"][^'"]+['"]\s*# AUTO-UPDATED/g,
`cron: '${newSchedule}' # AUTO-UPDATED`
);
writeFileSync(WORKFLOW_FILE, updatedContent, 'utf8');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If the regex replacement does not match anything (e.g., if the # AUTO-UPDATED comment is missing or formatted differently in the workflow file), workflowContent.replace will silently return the original string. The script will write the unchanged content and report success, leading to a silent failure where the actual GitHub Actions schedule is never updated. We should check if the content actually changed and log a warning or throw an error if it did not.

    const updatedContent = workflowContent.replace(
      /cron:\\s*['\"][^'\"]+['\"]\\s*# AUTO-UPDATED/g,
      `cron: '${newSchedule}' # AUTO-UPDATED`
    );
    if (updatedContent === workflowContent) {
      console.warn('[Compute] Warning: No cron schedule placeholder found in workflow file. Make sure it contains the \"# AUTO-UPDATED\" comment.');
    }
    writeFileSync(WORKFLOW_FILE, updatedContent, 'utf8');

Comment thread eslint.config.mjs
Comment on lines +26 to +31
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/ban-ts-comment": "off",
"prefer-const": "off"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Disabling core TypeScript and ESLint rules globally (such as @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, and prefer-const) reduces the effectiveness of static analysis. It is highly recommended to keep these rules enabled (or set them to warn) to maintain code quality and type safety, and only disable them via inline comments where absolutely necessary.

Suggested change
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/ban-ts-comment": "off",
"prefer-const": "off"
}
rules: {
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": "warn",
"@typescript-eslint/ban-ts-comment": "warn",
"prefer-const": "error"
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant