Compare commits

...

1 Commits

Author SHA1 Message Date
Alexander Whitestone
dbad1cdf0b fix: closes #1277
Some checks failed
CI / test (pull_request) Failing after 9s
CI / validate (pull_request) Failing after 14s
Review Approval Gate / verify-review (pull_request) Failing after 3s
2026-04-12 19:27:19 -04:00
2 changed files with 30 additions and 11 deletions

View File

@@ -7,6 +7,7 @@ routes to lanes, and spawns one-shot mimo-v2-pro workers.
No new issues created. No duplicate claims. No bloat. No new issues created. No duplicate claims. No bloat.
""" """
import glob
import json import json
import os import os
import sys import sys
@@ -38,6 +39,7 @@ else:
CLAIM_TIMEOUT_MINUTES = 30 CLAIM_TIMEOUT_MINUTES = 30
CLAIM_LABEL = "mimo-claimed" CLAIM_LABEL = "mimo-claimed"
MAX_QUEUE_DEPTH = 10 # Don't dispatch if queue already has this many prompts
CLAIM_COMMENT = "/claim" CLAIM_COMMENT = "/claim"
DONE_COMMENT = "/done" DONE_COMMENT = "/done"
ABANDON_COMMENT = "/abandon" ABANDON_COMMENT = "/abandon"
@@ -451,6 +453,13 @@ def dispatch(token):
prefetch_pr_refs(target_repo, token) prefetch_pr_refs(target_repo, token)
log(f" Prefetched {len(_PR_REFS)} PR references") log(f" Prefetched {len(_PR_REFS)} PR references")
# Check queue depth — don't pile up if workers haven't caught up
pending_prompts = len(glob.glob(os.path.join(STATE_DIR, "prompt-*.txt")))
if pending_prompts >= MAX_QUEUE_DEPTH:
log(f" QUEUE THROTTLE: {pending_prompts} prompts pending (max {MAX_QUEUE_DEPTH}) — skipping dispatch")
save_state(state)
return 0
# FOCUS MODE: scan only the focus repo. FIREHOSE: scan all. # FOCUS MODE: scan only the focus repo. FIREHOSE: scan all.
if FOCUS_MODE: if FOCUS_MODE:
ordered = [FOCUS_REPO] ordered = [FOCUS_REPO]

View File

@@ -24,6 +24,23 @@ def log(msg):
f.write(f"[{ts}] {msg}\n") f.write(f"[{ts}] {msg}\n")
def write_result(worker_id, status, repo=None, issue=None, branch=None, pr=None, error=None):
"""Write a result file — always, even on failure."""
result_file = os.path.join(STATE_DIR, f"result-{worker_id}.json")
data = {
"status": status,
"worker": worker_id,
"timestamp": datetime.now(timezone.utc).isoformat(),
}
if repo: data["repo"] = repo
if issue: data["issue"] = int(issue) if str(issue).isdigit() else issue
if branch: data["branch"] = branch
if pr: data["pr"] = pr
if error: data["error"] = error
with open(result_file, "w") as f:
json.dump(data, f)
def get_oldest_prompt(): def get_oldest_prompt():
"""Get the oldest prompt file with file locking (atomic rename).""" """Get the oldest prompt file with file locking (atomic rename)."""
prompts = sorted(glob.glob(os.path.join(STATE_DIR, "prompt-*.txt"))) prompts = sorted(glob.glob(os.path.join(STATE_DIR, "prompt-*.txt")))
@@ -63,6 +80,7 @@ def run_worker(prompt_file):
if not repo or not issue: if not repo or not issue:
log(f" SKIPPING: couldn't parse repo/issue from prompt") log(f" SKIPPING: couldn't parse repo/issue from prompt")
write_result(worker_id, "parse_error", error="could not parse repo/issue from prompt")
os.remove(prompt_file) os.remove(prompt_file)
return False return False
@@ -79,6 +97,7 @@ def run_worker(prompt_file):
) )
if result.returncode != 0: if result.returncode != 0:
log(f" CLONE FAILED: {result.stderr[:200]}") log(f" CLONE FAILED: {result.stderr[:200]}")
write_result(worker_id, "clone_failed", repo=repo, issue=issue, error=result.stderr[:200])
os.remove(prompt_file) os.remove(prompt_file)
return False return False
@@ -126,6 +145,7 @@ def run_worker(prompt_file):
urllib.request.urlopen(req, timeout=10) urllib.request.urlopen(req, timeout=10)
except: except:
pass pass
write_result(worker_id, "abandoned", repo=repo, issue=issue, error="no changes produced")
if os.path.exists(prompt_file): if os.path.exists(prompt_file):
os.remove(prompt_file) os.remove(prompt_file)
return False return False
@@ -193,17 +213,7 @@ def run_worker(prompt_file):
pr_num = "?" pr_num = "?"
# Write result # Write result
result_file = os.path.join(STATE_DIR, f"result-{worker_id}.json") write_result(worker_id, "completed", repo=repo, issue=issue, branch=branch, pr=pr_num)
with open(result_file, "w") as f:
json.dump({
"status": "completed",
"worker": worker_id,
"repo": repo,
"issue": int(issue) if issue.isdigit() else issue,
"branch": branch,
"pr": pr_num,
"timestamp": datetime.now(timezone.utc).isoformat()
}, f)
# Remove prompt # Remove prompt
# Remove prompt file (handles .processing extension) # Remove prompt file (handles .processing extension)