mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
fix(agents): replace gh CLI with curl for PR checking to prevent duplicate work
Agents do not have access to gh CLI, causing them to skip the pre-flight PR check and collide on duplicate work. This replaces all gh-based PR checking commands with curl + jq using the GitHub REST API, updates the task claiming protocol to use branch push + started log file as the primary lock mechanism, and updates automation scripts to use curl for PR listing and git fetch for PR checkout. Files updated: - AGENTS.md (Section 12 coordination rules) - CLAUDE.md (coordination rules) - META_PROMPTS.md (daily + weekly meta prompts) - daily-scheduler.md (pre-flight gate, task claiming, error handling) - weekly-scheduler.md (pre-flight gate, task claiming, error handling) - bitvid-pr-review-agent.md (PR enumeration + checkout) - bitvid-ci-health-agent.md (CI run gathering) - bitvid-weekly-synthesis-agent.md (PR metadata gathering) - bitvid-changelog-agent.md (PR metadata verification) - scripts/agent/review-open-prs.mjs (PR listing + checkout) - scripts/automated-pr-review.mjs (--all mode PR listing + checkout) https://claude.ai/code/session_01L5bzzGpZ6YTiLXcfqaL81G
This commit is contained in:
11 files changed
+97
-103
No files matched your search
@@ -204,7 +204,11 @@ This project uses multiple AI agents (Claude Code, OpenAI Codex, Google Jules) w
|
|||||||
|
|
||||||
### Before Starting Work
|
### Before Starting Work
|
||||||
|
|
||||||
1. **Check open PRs.** Run `gh pr list --state open` or check GitHub. If another agent already has a PR touching the same files or subsystem, do not create a competing PR. Instead, note the conflict and ask the maintainer how to proceed.
|
1. **Check open PRs.** Run the following command to list all open PRs:
|
||||||
|
```
|
||||||
|
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}'
|
||||||
|
```
|
||||||
|
If another agent already has a PR touching the same files or subsystem, do not create a competing PR. Instead, note the conflict and ask the maintainer how to proceed.
|
||||||
2. **Check this section for in-flight work.** The maintainer may list active work areas below. Respect these reservations.
|
2. **Check this section for in-flight work.** The maintainer may list active work areas below. Respect these reservations.
|
||||||
3. **Read KNOWN_ISSUES.md.** Do not open PRs to fix issues already documented there unless explicitly asked.
|
3. **Read KNOWN_ISSUES.md.** Do not open PRs to fix issues already documented there unless explicitly asked.
|
||||||
|
|
||||||
@@ -242,37 +246,28 @@ When you create a PR or start work, leave a clear signal:
|
|||||||
|
|
||||||
### Task Claiming Protocol (Draft PR Lock)
|
### Task Claiming Protocol (Draft PR Lock)
|
||||||
|
|
||||||
To prevent multiple agents from working on the same task simultaneously, every agent must **check for and create a draft PR** before starting work. The draft PR acts as a distributed lock visible to all agents across all platforms (Claude Code, Codex, Jules).
|
To prevent multiple agents from working on the same task simultaneously, every agent must **check open PRs and create a claim** before starting work. The claim (pushed branch + `started` log file) acts as a distributed lock visible to all agents across all platforms (Claude Code, Codex, Jules).
|
||||||
|
|
||||||
**Before starting any task:**
|
**Before starting any task:**
|
||||||
|
|
||||||
1. **Check for existing claims.** Search for open or draft PRs matching the task:
|
1. **Check for existing claims.** Search for open PRs matching the task:
|
||||||
```
|
```
|
||||||
gh pr list --state open --search "<agent-name-or-task-identifier>"
|
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}'
|
||||||
```
|
```
|
||||||
If a matching PR exists (open or draft), **skip the task** — another agent is already working on it.
|
If a matching PR exists (open or draft) for the same agent or subsystem, **skip the task** — another agent is already working on it.
|
||||||
|
|
||||||
2. **Claim the task.** If no matching PR exists:
|
2. **Claim the task.** If no matching PR exists:
|
||||||
a. Create your working branch.
|
a. Create your working branch.
|
||||||
b. Make a minimal initial commit (e.g., update `CONTEXT.md` with the task scope).
|
b. Make a minimal initial commit (e.g., create a `context/CONTEXT_<timestamp>.md` with the task scope).
|
||||||
c. Push the branch and immediately open a **draft PR**:
|
c. Create a `started` log file in the appropriate task-log directory.
|
||||||
```
|
d. Push the branch immediately to make the claim visible.
|
||||||
gh pr create --draft \
|
e. Only after the branch is pushed and the claim is visible, begin the actual work.
|
||||||
--title "[<zone>] <agent-name>: <brief description>" \
|
|
||||||
--body "Claimed by <agent-name> at <timestamp>. Work in progress."
|
|
||||||
```
|
|
||||||
d. Only after the draft PR is successfully created, begin the actual work.
|
|
||||||
|
|
||||||
3. **Handle race conditions.** After creating your draft PR, re-check for duplicates:
|
3. **Handle race conditions.** After pushing your claim, re-check for duplicates:
|
||||||
```
|
```
|
||||||
gh pr list --state open --search "<agent-name-or-task-identifier>"
|
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}'
|
||||||
```
|
|
||||||
If you find another agent's PR for the same task that was created **before** yours, close your PR with `gh pr close <your-pr-number>` and skip the task.
|
|
||||||
|
|
||||||
4. **Convert to ready when done.** When the task is complete and verified, mark the draft PR as ready for review:
|
|
||||||
```
|
|
||||||
gh pr ready
|
|
||||||
```
|
```
|
||||||
|
If you find another agent's PR for the same task that was created **before** yours, abandon your branch and skip the task.
|
||||||
|
|
||||||
**Scheduler agents:** Daily and weekly scheduler agents must follow this protocol in addition to their directory-based rotation logic (`docs/agents/task-logs/daily/` and `docs/agents/task-logs/weekly/`). The draft PR check happens _after_ determining the next task but _before_ executing it. See the scheduler prompts for the specific implementation steps.
|
**Scheduler agents:** Daily and weekly scheduler agents must follow this protocol in addition to their directory-based rotation logic (`docs/agents/task-logs/daily/` and `docs/agents/task-logs/weekly/`). The draft PR check happens _after_ determining the next task but _before_ executing it. See the scheduler prompts for the specific implementation steps.
|
||||||
|
|
||||||
|
|||||||
@@ -458,7 +458,11 @@ This project uses multiple AI coding agents working in parallel:
|
|||||||
|
|
||||||
All agents **must** follow the subsystem boundaries and PR discipline rules in `AGENTS.md` Section 12. The key principles:
|
All agents **must** follow the subsystem boundaries and PR discipline rules in `AGENTS.md` Section 12. The key principles:
|
||||||
|
|
||||||
1. **Check before you start.** Look at open PRs (`gh pr list`) before beginning work. If another agent has an open PR touching the same files, stop and flag the conflict.
|
1. **Check before you start.** Look at open PRs before beginning work by running:
|
||||||
|
```
|
||||||
|
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}'
|
||||||
|
```
|
||||||
|
If another agent has an open PR touching the same files, stop and flag the conflict.
|
||||||
2. **One subsystem per PR.** Don't mix unrelated changes. A lint fix and a feature addition are two separate PRs.
|
2. **One subsystem per PR.** Don't mix unrelated changes. A lint fix and a feature addition are two separate PRs.
|
||||||
3. **`js/app.js` is single-writer.** Only one PR at a time should modify the main orchestrator.
|
3. **`js/app.js` is single-writer.** Only one PR at a time should modify the main orchestrator.
|
||||||
4. **Merge fast, branch short.** Long-lived branches cause exponential merge pain with multiple agents. Keep PRs small and mergeable in one sitting.
|
4. **Merge fast, branch short.** Long-lived branches cause exponential merge pain with multiple agents. Keep PRs small and mergeable in one sitting.
|
||||||
|
|||||||
@@ -14,10 +14,9 @@ before choosing a task — is to run these two commands. Not later. NOW.
|
|||||||
|
|
||||||
COMMAND 1 — Check for open daily agent PRs:
|
COMMAND 1 — Check for open daily agent PRs:
|
||||||
|
|
||||||
gh pr list --repo PR0M3TH3AN/bitvid --state open --json number,title,createdAt,author --limit 100 | grep -i "\[daily\]"
|
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}'
|
||||||
|
|
||||||
If `gh` is not available, use this fallback:
|
Review the output. Any title containing "[daily]" means that agent is OFF LIMITS.
|
||||||
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | grep -o '"title":"[^"]*\[daily\][^"]*"'
|
|
||||||
|
|
||||||
COMMAND 2 — Check for in-progress task logs:
|
COMMAND 2 — Check for in-progress task logs:
|
||||||
|
|
||||||
@@ -63,10 +62,9 @@ before choosing a task — is to run these two commands. Not later. NOW.
|
|||||||
|
|
||||||
COMMAND 1 — Check for open weekly agent PRs:
|
COMMAND 1 — Check for open weekly agent PRs:
|
||||||
|
|
||||||
gh pr list --repo PR0M3TH3AN/bitvid --state open --json number,title,createdAt,author --limit 100 | grep -i "\[weekly\]"
|
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}'
|
||||||
|
|
||||||
If `gh` is not available, use this fallback:
|
Review the output. Any title containing "[weekly]" means that agent is OFF LIMITS.
|
||||||
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | grep -o '"title":"[^"]*\[weekly\][^"]*"'
|
|
||||||
|
|
||||||
COMMAND 2 — Check for in-progress task logs:
|
COMMAND 2 — Check for in-progress task logs:
|
||||||
|
|
||||||
|
|||||||
@@ -76,17 +76,12 @@ If you arrived here from the meta prompt and already ran these commands and past
|
|||||||
|
|
||||||
Run this command:
|
Run this command:
|
||||||
```bash
|
```bash
|
||||||
gh pr list --repo PR0M3TH3AN/bitvid --state open --json number,title,createdAt,author --limit 100 | grep -i "\[daily\]"
|
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}'
|
||||||
```
|
```
|
||||||
|
|
||||||
If `gh` is unavailable, use this fallback:
|
**Paste the complete raw output.** If the command returns nothing or errors, write: `OUTPUT: (empty — no results)`
|
||||||
```bash
|
|
||||||
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | grep -o '"title":"[^"]*\[daily\][^"]*"'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Paste the complete raw output.** If the command returns nothing, write: `OUTPUT: (empty — no results)`
|
Review the titles in the output. Every agent name that appears in a PR title containing `[daily]` is **OFF LIMITS** — do not select it.
|
||||||
|
|
||||||
Every agent name that appears in these PR titles is **OFF LIMITS** — do not select it.
|
|
||||||
|
|
||||||
### COMMAND 2 — Check the task log for incomplete runs
|
### COMMAND 2 — Check the task log for incomplete runs
|
||||||
|
|
||||||
@@ -114,7 +109,7 @@ or:
|
|||||||
EXCLUDED AGENTS: (none)
|
EXCLUDED AGENTS: (none)
|
||||||
```
|
```
|
||||||
|
|
||||||
**If Command 1 failed** (network error, API limit, `gh`/`curl` unavailable): you MUST still check the task log directory (Command 2). Log a warning in your summary that PR-based claim checking was unavailable.
|
**If Command 1 failed** (network error, API rate limit, `curl`/`jq` unavailable): you MUST still check the task log directory (Command 2). Log a warning in your summary that PR-based claim checking was unavailable.
|
||||||
|
|
||||||
**Do not proceed to Step 1 until you have pasted command outputs and written your exclusion list.**
|
**Do not proceed to Step 1 until you have pasted command outputs and written your exclusion list.**
|
||||||
|
|
||||||
@@ -164,25 +159,19 @@ EXCLUDED AGENTS: (none)
|
|||||||
|
|
||||||
You must create a visible claim before doing any work. This claim is a **distributed lock** that prevents agents on other platforms (Claude Code, Codex, Jules) from picking up the same task.
|
You must create a visible claim before doing any work. This claim is a **distributed lock** that prevents agents on other platforms (Claude Code, Codex, Jules) from picking up the same task.
|
||||||
|
|
||||||
### 2a. Create your working branch and claim via draft PR
|
### 2a. Create your working branch and push a claim
|
||||||
|
|
||||||
1. Create your working branch.
|
1. Create your working branch.
|
||||||
2. Make a minimal initial commit (e.g., create a new `context/CONTEXT_<timestamp>.md` with the task scope).
|
2. Make a minimal initial commit (e.g., create a new `context/CONTEXT_<timestamp>.md` with the task scope).
|
||||||
3. Push the branch and open a **draft PR**:
|
3. Push the branch immediately to make it visible to other agents.
|
||||||
```bash
|
|
||||||
gh pr create --draft \
|
|
||||||
--title "[daily] <agent-name>: <brief task description>" \
|
|
||||||
--body "Claimed by daily scheduler at $(date -u +%Y-%m-%dT%H:%M:%SZ). Work in progress."
|
|
||||||
```
|
|
||||||
4. Verify the draft PR was created successfully before proceeding.
|
|
||||||
|
|
||||||
### 2b. Race condition check
|
### 2b. Race condition check
|
||||||
|
|
||||||
After creating the draft PR, immediately re-check:
|
After pushing, re-check for competing claims:
|
||||||
```bash
|
```bash
|
||||||
gh pr list --repo PR0M3TH3AN/bitvid --state open --json number,title,createdAt --limit 100 | grep -i "<agent-name>"
|
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}'
|
||||||
```
|
```
|
||||||
If you see another PR for this agent that was created *before* yours (by a different agent instance), close your PR with `gh pr close <your-pr-number>` and go back to Step 1 to select the next agent.
|
If you see another PR for this agent that was created *before* yours, abandon your branch and go back to Step 1 to select the next agent.
|
||||||
|
|
||||||
### 2c. Log "started" in the task log immediately
|
### 2c. Log "started" in the task log immediately
|
||||||
|
|
||||||
@@ -209,7 +198,7 @@ Use the current UTC timestamp. The file content should be:
|
|||||||
|
|
||||||
Commit and push this log file to your branch. This `started` entry serves as a secondary lock: other scheduler instances will see it and skip this agent.
|
Commit and push this log file to your branch. This `started` entry serves as a secondary lock: other scheduler instances will see it and skip this agent.
|
||||||
|
|
||||||
**If `gh` is unavailable:** You MUST still create the `started` log file and push it. The log file is your minimum viable claim.
|
**The `started` log file is your primary claim mechanism.** Push it immediately so other agents can see it.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -279,7 +268,7 @@ Use the current UTC timestamp (which will be later than the `started` file). The
|
|||||||
- If the agent prompt file is **empty or missing**, skip it, log the run as `failed` with summary `"Prompt file empty or missing"`, and proceed to the **next agent** in the roster.
|
- If the agent prompt file is **empty or missing**, skip it, log the run as `failed` with summary `"Prompt file empty or missing"`, and proceed to the **next agent** in the roster.
|
||||||
- If a task **fails mid-execution** (test failures, build errors), log the run as `failed` with a summary describing the failure. Still commit the log file and any partial artifacts.
|
- If a task **fails mid-execution** (test failures, build errors), log the run as `failed` with a summary describing the failure. Still commit the log file and any partial artifacts.
|
||||||
- If the task log directory is **missing**, create it: `mkdir -p docs/agents/task-logs/daily/`.
|
- If the task log directory is **missing**, create it: `mkdir -p docs/agents/task-logs/daily/`.
|
||||||
- If `gh` or `curl` is **unavailable or errors**, fall back to log-file-only claiming (the `started` file). Log a warning in your summary that PR-based claim checking was degraded.
|
- If `curl` or `jq` is **unavailable or errors**, fall back to log-file-only claiming (the `started` file). Log a warning in your summary that PR-based claim checking was degraded.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -287,9 +276,9 @@ Use the current UTC timestamp (which will be later than the `started` file). The
|
|||||||
|
|
||||||
| Layer | Mechanism | Catches |
|
| Layer | Mechanism | Catches |
|
||||||
|-------|-----------|---------|
|
|-------|-----------|---------|
|
||||||
| **Pre-flight gate** | Scan ALL open `[daily]` PRs via `gh`/`curl` | Agents claimed by any platform |
|
| **Pre-flight gate** | Scan ALL open `[daily]` PRs via `curl` | Agents claimed by any platform |
|
||||||
| **Pre-flight gate** | Check task log dir for `started` files | Agents in progress (even without PR) |
|
| **Pre-flight gate** | Check task log dir for `started` files | Agents in progress (even without PR) |
|
||||||
| **Step 2a** | Create draft PR as lock | Cross-platform visibility |
|
| **Step 2a** | Push branch with claim commit | Cross-platform visibility |
|
||||||
| **Step 2b** | Race condition re-check | Simultaneous claims |
|
| **Step 2b** | Race condition re-check | Simultaneous claims |
|
||||||
| **Step 2c** | Create `started` log file immediately | Crash recovery — rotation advances |
|
| **Step 2c** | Create `started` log file immediately | Crash recovery — rotation advances |
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ WORKFLOW
|
|||||||
2) CI health check (evidence gathering)
|
2) CI health check (evidence gathering)
|
||||||
- Gather recent CI run results using one of:
|
- Gather recent CI run results using one of:
|
||||||
- GitHub Actions UI/manual inspection, OR
|
- GitHub Actions UI/manual inspection, OR
|
||||||
- GitHub API / `gh` CLI (only if available; do not assume).
|
- GitHub API via `curl` (e.g., `curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/actions/runs?per_page=20"`).
|
||||||
- Identify candidate flakes:
|
- Identify candidate flakes:
|
||||||
- same test fails on one run but passes on another with no relevant code change
|
- same test fails on one run but passes on another with no relevant code change
|
||||||
- failures are timing-related, network-mocking-related, ordering-related
|
- failures are timing-related, network-mocking-related, ordering-related
|
||||||
|
|||||||
@@ -76,17 +76,12 @@ If you arrived here from the meta prompt and already ran these commands and past
|
|||||||
|
|
||||||
Run this command:
|
Run this command:
|
||||||
```bash
|
```bash
|
||||||
gh pr list --repo PR0M3TH3AN/bitvid --state open --json number,title,createdAt,author --limit 100 | grep -i "\[weekly\]"
|
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}'
|
||||||
```
|
```
|
||||||
|
|
||||||
If `gh` is unavailable, use this fallback:
|
**Paste the complete raw output.** If the command returns nothing or errors, write: `OUTPUT: (empty — no results)`
|
||||||
```bash
|
|
||||||
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | grep -o '"title":"[^"]*\[weekly\][^"]*"'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Paste the complete raw output.** If the command returns nothing, write: `OUTPUT: (empty — no results)`
|
Review the titles in the output. Every agent name that appears in a PR title containing `[weekly]` is **OFF LIMITS** — do not select it.
|
||||||
|
|
||||||
Every agent name that appears in these PR titles is **OFF LIMITS** — do not select it.
|
|
||||||
|
|
||||||
### COMMAND 2 — Check the task log for incomplete runs
|
### COMMAND 2 — Check the task log for incomplete runs
|
||||||
|
|
||||||
@@ -114,7 +109,7 @@ or:
|
|||||||
EXCLUDED AGENTS: (none)
|
EXCLUDED AGENTS: (none)
|
||||||
```
|
```
|
||||||
|
|
||||||
**If Command 1 failed** (network error, API limit, `gh`/`curl` unavailable): you MUST still check the task log directory (Command 2). Log a warning in your summary that PR-based claim checking was unavailable.
|
**If Command 1 failed** (network error, API rate limit, `curl`/`jq` unavailable): you MUST still check the task log directory (Command 2). Log a warning in your summary that PR-based claim checking was unavailable.
|
||||||
|
|
||||||
**Do not proceed to Step 1 until you have pasted command outputs and written your exclusion list.**
|
**Do not proceed to Step 1 until you have pasted command outputs and written your exclusion list.**
|
||||||
|
|
||||||
@@ -159,25 +154,19 @@ EXCLUDED AGENTS: (none)
|
|||||||
|
|
||||||
You must create a visible claim before doing any work. This claim is a **distributed lock** that prevents agents on other platforms (Claude Code, Codex, Jules) from picking up the same task.
|
You must create a visible claim before doing any work. This claim is a **distributed lock** that prevents agents on other platforms (Claude Code, Codex, Jules) from picking up the same task.
|
||||||
|
|
||||||
### 2a. Create your working branch and claim via draft PR
|
### 2a. Create your working branch and push a claim
|
||||||
|
|
||||||
1. Create your working branch.
|
1. Create your working branch.
|
||||||
2. Make a minimal initial commit (e.g., create a new `context/CONTEXT_<timestamp>.md` with the task scope).
|
2. Make a minimal initial commit (e.g., create a new `context/CONTEXT_<timestamp>.md` with the task scope).
|
||||||
3. Push the branch and open a **draft PR**:
|
3. Push the branch immediately to make it visible to other agents.
|
||||||
```bash
|
|
||||||
gh pr create --draft \
|
|
||||||
--title "[weekly] <agent-name>: <brief task description>" \
|
|
||||||
--body "Claimed by weekly scheduler at $(date -u +%Y-%m-%dT%H:%M:%SZ). Work in progress."
|
|
||||||
```
|
|
||||||
4. Verify the draft PR was created successfully before proceeding.
|
|
||||||
|
|
||||||
### 2b. Race condition check
|
### 2b. Race condition check
|
||||||
|
|
||||||
After creating the draft PR, immediately re-check:
|
After pushing, re-check for competing claims:
|
||||||
```bash
|
```bash
|
||||||
gh pr list --repo PR0M3TH3AN/bitvid --state open --json number,title,createdAt --limit 100 | grep -i "<agent-name>"
|
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}'
|
||||||
```
|
```
|
||||||
If you see another PR for this agent that was created *before* yours (by a different agent instance), close your PR with `gh pr close <your-pr-number>` and go back to Step 1 to select the next agent.
|
If you see another PR for this agent that was created *before* yours, abandon your branch and go back to Step 1 to select the next agent.
|
||||||
|
|
||||||
### 2c. Log "started" in the task log immediately
|
### 2c. Log "started" in the task log immediately
|
||||||
|
|
||||||
@@ -204,7 +193,7 @@ Use the current UTC timestamp. The file content should be:
|
|||||||
|
|
||||||
Commit and push this log file to your branch. This `started` entry serves as a secondary lock: other scheduler instances will see it and skip this agent.
|
Commit and push this log file to your branch. This `started` entry serves as a secondary lock: other scheduler instances will see it and skip this agent.
|
||||||
|
|
||||||
**If `gh` is unavailable:** You MUST still create the `started` log file and push it. The log file is your minimum viable claim.
|
**The `started` log file is your primary claim mechanism.** Push it immediately so other agents can see it.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -276,7 +265,7 @@ Use the current UTC timestamp (which will be later than the `started` file). The
|
|||||||
- If the agent prompt file is **empty or missing**, skip it, log the run as `failed` with summary `"Prompt file empty or missing"`, and proceed to the **next agent** in the roster.
|
- If the agent prompt file is **empty or missing**, skip it, log the run as `failed` with summary `"Prompt file empty or missing"`, and proceed to the **next agent** in the roster.
|
||||||
- If a task **fails mid-execution** (test failures, build errors), log the run as `failed` with a summary describing the failure. Still commit the log file and any partial artifacts.
|
- If a task **fails mid-execution** (test failures, build errors), log the run as `failed` with a summary describing the failure. Still commit the log file and any partial artifacts.
|
||||||
- If the task log directory is **missing**, create it: `mkdir -p docs/agents/task-logs/weekly/`.
|
- If the task log directory is **missing**, create it: `mkdir -p docs/agents/task-logs/weekly/`.
|
||||||
- If `gh` or `curl` is **unavailable or errors**, fall back to log-file-only claiming (the `started` file). Log a warning in your summary that PR-based claim checking was degraded.
|
- If `curl` or `jq` is **unavailable or errors**, fall back to log-file-only claiming (the `started` file). Log a warning in your summary that PR-based claim checking was degraded.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -284,9 +273,9 @@ Use the current UTC timestamp (which will be later than the `started` file). The
|
|||||||
|
|
||||||
| Layer | Mechanism | Catches |
|
| Layer | Mechanism | Catches |
|
||||||
|-------|-----------|---------|
|
|-------|-----------|---------|
|
||||||
| **Pre-flight gate** | Scan ALL open `[weekly]` PRs via `gh`/`curl` | Agents claimed by any platform |
|
| **Pre-flight gate** | Scan ALL open `[weekly]` PRs via `curl` | Agents claimed by any platform |
|
||||||
| **Pre-flight gate** | Check task log dir for `started` files | Agents in progress (even without PR) |
|
| **Pre-flight gate** | Check task log dir for `started` files | Agents in progress (even without PR) |
|
||||||
| **Step 2a** | Create draft PR as lock | Cross-platform visibility |
|
| **Step 2a** | Push branch with claim commit | Cross-platform visibility |
|
||||||
| **Step 2b** | Race condition re-check | Simultaneous claims |
|
| **Step 2b** | Race condition re-check | Simultaneous claims |
|
||||||
| **Step 2c** | Create `started` log file immediately | Crash recovery — rotation advances |
|
| **Step 2c** | Create `started` log file immediately | Crash recovery — rotation advances |
|
||||||
|
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ PR METADATA (PR number, author) — RULES
|
|||||||
|
|
||||||
Only include PR number and author if you can **verify** them via:
|
Only include PR number and author if you can **verify** them via:
|
||||||
- merge commit messages that include PR numbers, OR
|
- merge commit messages that include PR numbers, OR
|
||||||
- an available local tool/config that exposes PR metadata (e.g., `gh`)
|
- the GitHub API via `curl` (e.g., `curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=closed&per_page=50" | jq '[.[] | {number, title, merged_at: .merged_at}]'`)
|
||||||
If not verifiable:
|
If not verifiable:
|
||||||
- omit PR numbers/authors and keep bullets keyed to commit subjects/hashes.
|
- omit PR numbers/authors and keep bullets keyed to commit subjects/hashes.
|
||||||
|
|
||||||
|
|||||||
@@ -73,21 +73,22 @@ WORKFLOW
|
|||||||
- security-sensitive boundaries and logging policy
|
- security-sensitive boundaries and logging policy
|
||||||
- Confirm tooling availability:
|
- Confirm tooling availability:
|
||||||
- `npm` available
|
- `npm` available
|
||||||
- PR checkout method available (`gh` CLI or equivalent)
|
- `curl` and `jq` available for GitHub API queries
|
||||||
If `gh` is not available, fall back to manual instructions in the audit log.
|
If `curl` is not available, document that PR enumeration was not possible in the audit log.
|
||||||
|
|
||||||
2) Enumerate open PRs
|
2) Enumerate open PRs
|
||||||
- Preferred: `curl` command (works without gh auth):
|
- Preferred: `curl` command (works without gh auth):
|
||||||
```bash
|
```bash
|
||||||
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq -c '.[] | {number: .number, title: .title, created_at: .created_at, author: .user.login}'
|
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq -c '.[] | {number: .number, title: .title, created_at: .created_at, author: .user.login}'
|
||||||
```
|
```
|
||||||
- Alternative: `gh pr list` (if available/configured).
|
|
||||||
- Otherwise: document that PR enumeration was not possible in this environment.
|
- Otherwise: document that PR enumeration was not possible in this environment.
|
||||||
|
|
||||||
3) For each PR: checkout and run verification
|
3) For each PR: checkout and run verification
|
||||||
Checkout:
|
Checkout:
|
||||||
- Preferred: `gh pr checkout <num>`
|
- Fetch the PR branch via git remote refs:
|
||||||
- Otherwise: fetch the PR branch via git remote refs (only if you can verify).
|
```bash
|
||||||
|
git fetch origin pull/<num>/head:pr-<num> && git checkout pr-<num>
|
||||||
|
```
|
||||||
|
|
||||||
Install + checks (verify the script names first):
|
Install + checks (verify the script names first):
|
||||||
- `npm ci` (preferred) or `npm install` if CI install is not supported
|
- `npm ci` (preferred) or `npm install` if CI install is not supported
|
||||||
|
|||||||
@@ -76,11 +76,16 @@ WORKFLOW
|
|||||||
- Gather branch refs:
|
- Gather branch refs:
|
||||||
- `git for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname:short)' refs/heads/ai`
|
- `git for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname:short)' refs/heads/ai`
|
||||||
|
|
||||||
Optional method (only if tooling is available and policy allows):
|
Optional method (use curl to query the GitHub API):
|
||||||
- Use `gh` CLI or other configured tooling to fetch:
|
- Fetch open PRs:
|
||||||
- PR links/status
|
```
|
||||||
- issue links/priorities
|
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}'
|
||||||
If not available: do not guess links; report locally-derived identifiers.
|
```
|
||||||
|
- Fetch recently closed/merged PRs:
|
||||||
|
```
|
||||||
|
curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=closed&per_page=50&sort=updated&direction=desc" | jq '[.[] | {title: .title, merged: .merged_at, number: .number}]'
|
||||||
|
```
|
||||||
|
If curl is unavailable: do not guess links; report locally-derived identifiers.
|
||||||
|
|
||||||
3) Normalize items into report sections
|
3) Normalize items into report sections
|
||||||
For each item discovered, capture:
|
For each item discovered, capture:
|
||||||
|
|||||||
@@ -13,18 +13,25 @@ function runCommand(command, args = [], options = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getOpenPRs() {
|
function getOpenPRs() {
|
||||||
console.log('Fetching open PRs...');
|
console.log('Fetching open PRs via GitHub API...');
|
||||||
try {
|
try {
|
||||||
const res = spawnSync('gh', ['pr', 'list', '--json', 'number,headRefName,baseRefName,url'], { encoding: 'utf-8' });
|
const res = spawnSync('curl', ['-s', 'https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100'], { encoding: 'utf-8' });
|
||||||
if (res.error) {
|
if (res.error) {
|
||||||
console.error('Error fetching PRs (gh CLI not installed?):', res.error.message);
|
console.error('Error fetching PRs (curl not available?):', res.error.message);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
if (res.status !== 0) {
|
if (res.status !== 0) {
|
||||||
console.error('Error fetching PRs:', res.stderr);
|
console.error('Error fetching PRs:', res.stderr);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return JSON.parse(res.stdout);
|
const apiPRs = JSON.parse(res.stdout);
|
||||||
|
// Map GitHub API response to the shape we need
|
||||||
|
return apiPRs.map(pr => ({
|
||||||
|
number: pr.number,
|
||||||
|
headRefName: pr.head.ref,
|
||||||
|
baseRefName: pr.base.ref,
|
||||||
|
url: pr.html_url
|
||||||
|
}));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Exception fetching PRs:', e);
|
console.error('Exception fetching PRs:', e);
|
||||||
return [];
|
return [];
|
||||||
@@ -52,15 +59,16 @@ async function main() {
|
|||||||
for (const pr of openPRs) {
|
for (const pr of openPRs) {
|
||||||
console.log(`\n=== Processing PR #${pr.number}: ${pr.url} ===`);
|
console.log(`\n=== Processing PR #${pr.number}: ${pr.url} ===`);
|
||||||
try {
|
try {
|
||||||
// Checkout PR
|
// Checkout PR via git fetch
|
||||||
runCommand('gh', ['pr', 'checkout', pr.number]);
|
runCommand('git', ['fetch', 'origin', `pull/${pr.number}/head:pr-${pr.number}`]);
|
||||||
|
runCommand('git', ['checkout', `pr-${pr.number}`]);
|
||||||
|
|
||||||
// Set Environment Variables
|
// Set Environment Variables
|
||||||
const env = {
|
const env = {
|
||||||
...process.env,
|
...process.env,
|
||||||
PR_NUMBER: pr.number.toString(),
|
PR_NUMBER: pr.number.toString(),
|
||||||
GITHUB_BASE_REF: pr.baseRefName,
|
GITHUB_BASE_REF: pr.baseRefName,
|
||||||
// Assuming origin is the base repo or gh pr checkout handled the remote setup.
|
// Assuming origin is the base repo.
|
||||||
// automated-pr-review.mjs handles missing GITHUB_BASE_REPO_URL by defaulting to upstream/origin.
|
// automated-pr-review.mjs handles missing GITHUB_BASE_REPO_URL by defaulting to upstream/origin.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -258,16 +258,20 @@ async function main() {
|
|||||||
const isAll = process.argv.includes('--all');
|
const isAll = process.argv.includes('--all');
|
||||||
|
|
||||||
if (isAll) {
|
if (isAll) {
|
||||||
console.log('Fetching all open PRs...');
|
console.log('Fetching all open PRs via GitHub API...');
|
||||||
// Get list of open PRs
|
// Get list of open PRs via curl (no gh dependency)
|
||||||
const listCmd = ['pr', 'list', '--state', 'open', '--json', 'number,baseRefName,headRefName'];
|
const result = spawnSync('curl', ['-s', 'https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100'], { encoding: 'utf-8' });
|
||||||
const result = spawnSync('gh', listCmd, { encoding: 'utf-8' });
|
|
||||||
|
|
||||||
if (result.error || result.status !== 0) {
|
if (result.error || result.status !== 0) {
|
||||||
throw new Error(`Failed to list PRs: ${result.stderr || result.error?.message}`);
|
throw new Error(`Failed to list PRs: ${result.stderr || result.error?.message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const prs = JSON.parse(result.stdout);
|
const apiPRs = JSON.parse(result.stdout);
|
||||||
|
const prs = apiPRs.map(pr => ({
|
||||||
|
number: pr.number,
|
||||||
|
baseRefName: pr.base.ref,
|
||||||
|
headRefName: pr.head.ref
|
||||||
|
}));
|
||||||
console.log(`Found ${prs.length} open PRs.`);
|
console.log(`Found ${prs.length} open PRs.`);
|
||||||
|
|
||||||
let hasGlobalFailures = false;
|
let hasGlobalFailures = false;
|
||||||
@@ -284,8 +288,9 @@ async function main() {
|
|||||||
try {
|
try {
|
||||||
console.log(`\n=== Processing PR #${pr.number} ===`);
|
console.log(`\n=== Processing PR #${pr.number} ===`);
|
||||||
|
|
||||||
// Checkout PR
|
// Checkout PR via git fetch
|
||||||
runCommand('gh', ['pr', 'checkout', pr.number]);
|
runCommand('git', ['fetch', 'origin', `pull/${pr.number}/head:pr-${pr.number}`]);
|
||||||
|
runCommand('git', ['checkout', `pr-${pr.number}`]);
|
||||||
|
|
||||||
// Run Review
|
// Run Review
|
||||||
await reviewPR(pr.number, pr.baseRefName);
|
await reviewPR(pr.number, pr.baseRefName);
|
||||||
@@ -296,7 +301,7 @@ async function main() {
|
|||||||
// Continue to next PR
|
// Continue to next PR
|
||||||
} finally {
|
} finally {
|
||||||
// Clean up or reset if needed?
|
// Clean up or reset if needed?
|
||||||
// Since we use gh pr checkout, we are on a different branch.
|
// Since we fetch and checkout each PR branch, we are on a different branch.
|
||||||
// Next iteration will checkout another branch.
|
// Next iteration will checkout another branch.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user