Skip to content

Add Nexus Agent Runner workflow configuration#15

Merged
FuzzysTodd merged 1 commit into
SAfrom
FuzzysTodd-patch-5
Nov 12, 2025
Merged

Add Nexus Agent Runner workflow configuration#15
FuzzysTodd merged 1 commit into
SAfrom
FuzzysTodd-patch-5

Conversation

@FuzzysTodd

Copy link
Copy Markdown
Owner

This workflow automates the Nexus Agent Runner with scheduled runs, dependency installation, and self-healing attempts based on test results.

This workflow automates the Nexus Agent Runner with scheduled runs, dependency installation, and self-healing attempts based on test results.
Copilot AI review requested due to automatic review settings November 12, 2025 00:31
@FuzzysTodd FuzzysTodd merged commit 8fb3942 into SA Nov 12, 2025
2 of 4 checks passed

Copilot AI 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.

Pull Request Overview

This PR introduces an automated Nexus Agent Runner workflow that executes on a 30-minute schedule, on pushes to agent branches, and manually. The workflow performs iterative repository scanning, test execution, and implements a multi-stage self-healing mechanism to recover from test failures.

Key changes:

  • Adds automated agent runner with scheduled execution every 30 minutes
  • Implements three-tier self-healing strategy with diagnostics injection, module reversion, and test isolation
  • Creates automatic pull requests when tests pass after healing attempts

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread dselfheal.yaml

on:
schedule:
- cron: "*/30 * * * *" # every 30 minutes

Copilot AI Nov 12, 2025

Copy link

Choose a reason for hiding this comment

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

Running this workflow every 30 minutes may consume significant CI/CD resources and GitHub Actions minutes. Consider increasing the interval to hourly or using event-driven triggers based on actual changes to reduce unnecessary runs.

Suggested change
- cron: "*/30 * * * *" # every 30 minutes
- cron: "0 * * * *" # every hour

Copilot uses AI. Check for mistakes.
Comment thread dselfheal.yaml
Comment on lines +27 to +30
- name: Install deps
run: |
python -m pip install --upgrade pip
pip install flask ecdsa pytest

Copilot AI Nov 12, 2025

Copy link

Choose a reason for hiding this comment

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

Dependencies are installed without version pinning, which can lead to unpredictable behavior when package versions change. Consider creating a requirements.txt file with pinned versions or specify versions directly (e.g., flask==2.3.0).

Suggested change
- name: Install deps
run: |
python -m pip install --upgrade pip
pip install flask ecdsa pytest
- name: Create requirements.txt
run: |
echo "flask==2.3.3" > requirements.txt
echo "ecdsa==0.18.0" >> requirements.txt
echo "pytest==7.4.4" >> requirements.txt
- name: Install deps
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

Copilot uses AI. Check for mistakes.
Comment thread dselfheal.yaml
PY

- name: Run reliability CI (python)
run: pytest -q || echo "TESTS_FAILED" > .agent/status

Copilot AI Nov 12, 2025

Copy link

Choose a reason for hiding this comment

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

The pattern of writing 'TESTS_FAILED' to .agent/status is repeated across multiple steps (lines 46, 63, 70, 76). Consider extracting this into a reusable script or shell function to reduce duplication.

Copilot uses AI. Check for mistakes.
Comment thread dselfheal.yaml
Comment on lines +53 to +61
p="simulator/app.py"
try:
buf=open(p).read()
if "LOG_DIAGNOSTICS" not in buf:
buf = buf.replace("app = Flask(__name__)", "app = Flask(__name__)\nLOG_DIAGNOSTICS=True")
open(p,"w").write(buf)
print("Diagnostics flag injected.")
except FileNotFoundError:
print("No app.py; skipping.")

Copilot AI Nov 12, 2025

Copy link

Choose a reason for hiding this comment

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

String replacement for code injection is fragile and will fail if the Flask initialization pattern differs (e.g., with extra whitespace, different quotes, or split across lines). Consider using a more robust approach like AST manipulation or configuration-based diagnostics.

Suggested change
p="simulator/app.py"
try:
buf=open(p).read()
if "LOG_DIAGNOSTICS" not in buf:
buf = buf.replace("app = Flask(__name__)", "app = Flask(__name__)\nLOG_DIAGNOSTICS=True")
open(p,"w").write(buf)
print("Diagnostics flag injected.")
except FileNotFoundError:
print("No app.py; skipping.")
import ast, os
p = "simulator/app.py"
try:
with open(p, "r") as f:
src = f.read()
if "LOG_DIAGNOSTICS" in src:
print("Diagnostics flag already present.")
else:
tree = ast.parse(src)
class Injector(ast.NodeTransformer):
def __init__(self):
self.injected = False
def visit_Assign(self, node):
# Look for: app = Flask(__name__)
if (isinstance(node.targets[0], ast.Name) and
node.targets[0].id == "app" and
isinstance(node.value, ast.Call) and
getattr(getattr(node.value.func, 'id', None), 'lower', lambda: None)() == "flask" and
len(node.value.args) == 1 and
isinstance(node.value.args[0], ast.Name) and
node.value.args[0].id == "__name__"):
self.injected = True
# Insert LOG_DIAGNOSTICS = True after this node
return [node, ast.parse("LOG_DIAGNOSTICS = True").body[0]]
return node
injector = Injector()
new_tree = injector.visit(tree)
ast.fix_missing_locations(new_tree)
if injector.injected:
new_src = ast.unparse(new_tree)
with open(p, "w") as f:
f.write(new_src)
print("Diagnostics flag injected.")
else:
print("Flask app assignment not found; skipping injection.")
except FileNotFoundError:
print("No app.py; skipping.")

Copilot uses AI. Check for mistakes.
Comment thread dselfheal.yaml
Comment on lines +78 to +85
- name: Create PR on success
if: ${{ hashFiles('.agent/status') == '' }}
run: |
BR="agent/iteration-$(date +%s)"
git checkout -b "$BR"
git add -A
git commit -m "Agent iteration: CI green, diagnostics added"
git push origin "$BR"

Copilot AI Nov 12, 2025

Copy link

Choose a reason for hiding this comment

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

This step will fail because Git operations require authentication and user configuration. The workflow needs to configure git user email/name and use a token with appropriate permissions (e.g., GITHUB_TOKEN) for pushing to the repository.

Copilot uses AI. Check for mistakes.
Comment thread dselfheal.yaml
run: |
BR="agent/iteration-$(date +%s)"
git checkout -b "$BR"
git add -A

Copilot AI Nov 12, 2025

Copy link

Choose a reason for hiding this comment

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

Using git add -A stages all changes including potentially sensitive files like logs, credentials, or temporary files. This could inadvertently commit sensitive data. Consider using more specific paths like git add .agent/ or explicitly listing files to commit.

Suggested change
git add -A
git add .agent/plans .agent/provenance

Copilot uses AI. Check for mistakes.
Comment thread dselfheal.yaml
BR="agent/iteration-$(date +%s)"
git checkout -b "$BR"
git add -A
git commit -m "Agent iteration: CI green, diagnostics added"

Copilot AI Nov 12, 2025

Copy link

Choose a reason for hiding this comment

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

The commit will fail if there are no changes to commit (e.g., when the workflow runs but makes no modifications). Add git diff-index --quiet HEAD || git commit or use git commit --allow-empty to handle this case.

Suggested change
git commit -m "Agent iteration: CI green, diagnostics added"
git diff-index --quiet HEAD || git commit -m "Agent iteration: CI green, diagnostics added"

Copilot uses AI. Check for mistakes.
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.

2 participants