Skip to content

Commit b857897

Browse files
authored
Merge pull request #41 from githubnext/copilot/collapse-steering-issue-experiment-log
Collapse steering issue + experiment log into a single program issue
2 parents e3eecbf + 519ada7 commit b857897

3 files changed

Lines changed: 90 additions & 107 deletions

File tree

.github/workflows/autoloop.md

Lines changed: 44 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ The pre-step has already determined which program to run. Read `/tmp/gh-aw/autol
171171
- **`unconfigured`**: Programs that still have the sentinel or placeholder content.
172172
- **`skipped`**: Programs not due yet based on their per-program schedule.
173173
- **`no_programs`**: If `true`, no program files exist at all.
174+
- **`not_due`**: If `true`, programs exist but none are due for this run.
174175

175176
If `selected` is not null:
176177
1. Read the program file from the `selected_file` path.
@@ -202,7 +203,7 @@ GitHub Issues (labeled 'autoloop-program'):
202203
Each program runs independently with its own:
203204
- Goal, target files, and evaluation command
204205
- Metric tracking and best-metric history
205-
- Steering issue: `[Autoloop: {program-name}] Steering` (persistent, links branch/PR/state)
206+
- Program issue: `[Autoloop: {program-name}]` (a single GitHub issue labeled `autoloop-program` — created automatically for file-based programs, the source issue for issue-based programs — that hosts the status comment, per-iteration comments, and human steering)
206207
- Long-running branch: `autoloop/{program-name}` (persists across iterations)
207208
- Single draft PR per program: `[Autoloop: {program-name}]` (accumulates all accepted iterations)
208209
- State file: `{program-name}.md` in repo-memory (all state: scheduling, research context, iteration history)
@@ -288,10 +289,10 @@ Examples:
288289

289290
Each program has three coordinated resources:
290291
- **Branch + PR**: `autoloop/{program-name}` with a single draft PR
291-
- **Steering Issue**: `[Autoloop: {program-name}] Steering`persistent GitHub issue linking branch, PR, and state
292+
- **Program Issue**: `[Autoloop: {program-name}]`a single GitHub issue (labeled `autoloop-program`) that hosts the status comment, per-iteration comments, and human steering. For issue-based programs this is the source issue. For file-based programs it is auto-created on the first run.
292293
- **State File**: `{program-name}.md` in repo-memory — all state, history, and research context
293294

294-
All three reference each other. The steering issue is created on the first accepted iteration and updated with links to the PR and state.
295+
All three reference each other. The program issue is created (or, for issue-based programs, adopted) on the first run and updated with links to the PR and state.
295296

296297
## Iteration Loop
297298

@@ -346,15 +347,15 @@ Each run executes **one iteration for the single selected program**:
346347
2. Push the commit to the long-running branch.
347348
3. If a draft PR does not already exist for this branch, create one:
348349
- Title: `[Autoloop: {program-name}]`
349-
- Body includes: a summary of the program goal, link to the steering issue, the current best metric, and AI disclosure: `🤖 *This PR is maintained by Autoloop. Each accepted iteration adds a commit to this branch.*`
350+
- Body includes: a summary of the program goal, link to the program issue, the current best metric, and AI disclosure: `🤖 *This PR is maintained by Autoloop. Each accepted iteration adds a commit to this branch.*`
350351
If a draft PR already exists, update the PR body with the latest metric and a summary of the most recent accepted iteration. Add a comment to the PR summarizing the iteration: what changed, old metric, new metric, improvement delta, and a link to the actions run.
351-
4. Ensure the steering issue exists (see [Steering Issue](#steering-issue) below). Add a comment to the steering issue linking to the commit and actions run.
352+
4. Ensure the program issue exists (see [Program Issue](#program-issue) below) — for file-based programs that have no program issue yet (`selected_issue` is null in `/tmp/gh-aw/autoloop.json`), create one and record its number in the state file's `Issue` field.
352353
5. Update the state file `{program-name}.md` in the repo-memory folder:
353354
- Update the **⚙️ Machine State** table: reset `consecutive_errors` to 0, set `best_metric`, increment `iteration_count`, set `last_run` to current UTC timestamp, append `"accepted"` to `recent_statuses` (keep last 10), set `paused` to false.
354355
- Prepend an entry to **📊 Iteration History** (newest first) with status ✅, metric, PR link, and a one-line summary of what changed and why it worked.
355356
- Update **📚 Lessons Learned** if this iteration revealed something new about the problem or what works.
356357
- Update **🔭 Future Directions** if this iteration opened new promising paths.
357-
6. **If this is an issue-based program** (`selected_issue` is not null): update the status comment and post a per-run comment on the source issue (see [Issue-Based Program Updates](#issue-based-program-updates)).
358+
6. **Update the program issue**: edit the status comment and post a per-iteration comment on the program issue (see [Program Issue](#program-issue)).
358359
7. **Check halting condition** (see [Halting Condition](#halting-condition)): If the program has a `target-metric` in its frontmatter and the new `best_metric` meets or surpasses the target, mark the program as completed.
359360

360361
**If the metric did not improve**:
@@ -364,58 +365,41 @@ Each run executes **one iteration for the single selected program**:
364365
- Prepend an entry to **📊 Iteration History** with status ❌, metric, and a one-line summary of what was tried.
365366
- If this approach is conclusively ruled out (e.g., tried multiple variations and all fail), add it to **🚧 Foreclosed Avenues** with a clear explanation.
366367
- Update **🔭 Future Directions** if this rejection clarified what to try next.
367-
3. **If this is an issue-based program** (`selected_issue` is not null): update the status comment and post a per-run comment on the source issue (see [Issue-Based Program Updates](#issue-based-program-updates)).
368+
3. **Update the program issue**: edit the status comment and post a per-iteration comment on the program issue (see [Program Issue](#program-issue)).
368369

369370
**If evaluation could not run** (build failure, missing dependencies, etc.):
370371
1. Discard the code changes (do not commit them to the long-running branch).
371372
2. Update the state file `{program-name}.md` in the repo-memory folder:
372373
- Update the **⚙️ Machine State** table: increment `consecutive_errors`, increment `iteration_count`, set `last_run`, append `"error"` to `recent_statuses` (keep last 10).
373374
- If `consecutive_errors` reaches 3+, set `paused` to `true` and set `pause_reason` in the Machine State table, and create an issue describing the problem.
374375
- Prepend an entry to **📊 Iteration History** with status ⚠️ and a brief error description.
375-
3. **If this is an issue-based program** (`selected_issue` is not null): update the status comment and post a per-run comment on the source issue (see [Issue-Based Program Updates](#issue-based-program-updates)).
376+
3. **Update the program issue**: edit the status comment and post a per-iteration comment on the program issue (see [Program Issue](#program-issue)).
376377

377-
## Steering Issue
378+
## Program Issue
378379

379-
Maintain a single **persistent** open issue per program titled `[Autoloop: {program-name}] Steering`. The steering issue lives for the entire lifetime of the program.
380+
Each program has **exactly one** open GitHub issue (labeled `autoloop-program`) titled `[Autoloop: {program-name}]`. This single issue is the source of truth for the program — it hosts:
380381

381-
The steering issue serves as the central coordination point linking together the program's key resources:
382-
- The **long-running branch** `autoloop/{program-name}` and its draft PR
383-
- The **state file** `{program-name}.md` in repo-memory (on the `memory/autoloop` branch)
382+
- The **status comment** (the earliest bot comment, edited in place each iteration) — a dashboard of current state.
383+
- A **per-iteration comment** for every iteration (accepted, rejected, or error) — the rolling log.
384+
- **Human steering comments** — plain-prose comments from maintainers, treated by the agent as directives.
384385

385-
### Steering Issue Body Format
386+
There are no separate "steering" or "experiment log" issues — they have all been collapsed into this one issue.
386387

387-
```markdown
388-
🤖 *Autoloop — steering issue for the `{program-name}` program.*
389-
390-
## Links
391-
392-
- **Branch**: [`autoloop/{program-name}`](https://github.com/{owner}/{repo}/tree/autoloop/{program-name})
393-
- **Pull Request**: #{pr_number}
394-
- **State File**: [`{program-name}.md`](https://github.com/{owner}/{repo}/blob/memory/autoloop/{program-name}.md)
388+
### Auto-Creation for File-Based Programs
395389

396-
## Program
390+
If `selected_issue` is `null` in `/tmp/gh-aw/autoloop.json`, the program is file-based **and** has no program issue yet. On the first run, create one with `create-issue`:
397391

398-
**Goal**: {one-line summary from program.md}
399-
**Metric**: {metric-name} ({higher/lower} is better)
400-
**Current best**: {best_metric}
401-
**Iterations**: {iteration_count}
402-
```
392+
- **Title**: `[Autoloop: {program-name}]` (the `[Autoloop] ` prefix is added automatically by the safe-output `title-prefix`, so pass the title as `{program-name}`).
393+
- **Body**: the contents of the program file (`program.md`) plus a placeholder for the status comment so maintainers know one will be edited in place.
394+
- **Labels**: `[autoloop-program, automation, autoloop]`.
403395

404-
### Steering Issue Rules
396+
Record the new issue number in the state file's `Issue` field. On subsequent runs, the pre-step will discover the existing program issue (it scans open issues with the `autoloop-program` label) and `selected_issue` will be populated automatically.
405397

406-
- Create the steering issue on the **first accepted iteration** for the program if it does not already exist.
407-
- **Update the issue body** whenever the best metric or PR number changes.
408-
- **Add a comment** on each accepted iteration with a link to the commit and actions run.
409-
- The steering issue is labeled `[automation, autoloop]`.
410-
- Do NOT close the steering issue when the PR is merged — the branch continues to accumulate future iterations.
411-
412-
## Issue-Based Program Updates
413-
414-
When a program is defined via a GitHub issue (i.e., `selected_issue` is not null in `/tmp/gh-aw/autoloop.json`), the source issue itself serves as the program definition **and** as the primary interface for steering and monitoring the program. In addition to the normal iteration workflow (state file, steering issue, PR), you must also update the source issue.
398+
For issue-based programs (`selected_issue` is not null on the very first run), no creation is needed — the source issue is already the program issue. The flow below is identical from there on.
415399

416400
### Status Comment
417401

418-
On the **first iteration** for an issue-based program, post a comment on the source issue. On **every subsequent iteration**, update that same comment (edit it, do not post a new one). This is the "status comment" — always the earliest bot comment on the issue.
402+
On the **first iteration**, post a comment on the program issue. On **every subsequent iteration**, update that same comment (edit it, do not post a new one). This is the "status comment" — always the earliest bot comment on the issue.
419403

420404
Find the status comment by searching for a comment containing `<!-- AUTOLOOP:STATUS -->`. If multiple comments contain this sentinel, use the earliest one (lowest comment ID) and ignore the others.
421405

@@ -435,16 +419,16 @@ Find the status comment by searching for a comment containing `<!-- AUTOLOOP:STA
435419
| **Branch** | [`autoloop/{program-name}`](https://github.com/{owner}/{repo}/tree/autoloop/{program-name}) |
436420
| **Pull Request** | #{pr_number} |
437421
| **State File** | [`{program-name}.md`](https://github.com/{owner}/{repo}/blob/memory/autoloop/{program-name}.md) |
438-
| **Steering Issue** | #{steering_issue_number} |
422+
| **Paused** | {true/false} ({pause_reason if paused}) |
439423

440424
### Summary
441425

442426
{2-3 sentence summary of current state: what has been accomplished so far, what the current best approach is, and what direction the next iteration will likely take.}
443427
```
444428

445-
### Per-Run Comment
429+
### Per-Iteration Comment
446430

447-
After **every iteration** (accepted, rejected, or error), post a **new comment** on the source issue with a summary of what happened:
431+
After **every iteration** (accepted, rejected, or error), post a **new comment** on the program issue with a summary of what happened:
448432

449433
```markdown
450434
🤖 **Iteration {N}**[{status_emoji} {status}]({run_url})
@@ -457,15 +441,23 @@ After **every iteration** (accepted, rejected, or error), post a **new comment**
457441

458442
### Steering via Issue Comments
459443

460-
For issue-based programs, **human comments on the source issue act as steering input** (in addition to the state file's Current Priorities section). Before proposing a change, read all comments on the source issue and treat any human comments as directives — similar to how the Current Priorities section works in the state file.
444+
**Human comments on the program issue act as steering input** (in addition to the state file's Current Priorities section). Before proposing a change, read all comments on the program issue and treat any human (non-bot) comments posted since the last iteration as directives — similar to how the Current Priorities section works in the state file.
461445

462-
### Issue-Based Program Rules
446+
### Program Issue Rules
463447

464-
- The source issue body IS the program definition — do not modify it (the user owns it).
448+
- For issue-based programs, the source issue body IS the program definition — do not modify it (the user owns it).
449+
- For file-based programs, the program issue body is informational and may be lightly updated (e.g., to refresh the program summary), but the program file (`program.md`) remains the source of truth for the goal/target/evaluation.
465450
- The `autoloop-program` label must remain on the issue for the program to be discovered. When a program completes (target metric reached), the label is removed automatically and replaced with `autoloop-completed`.
466-
- Closing the issue stops the program from being discovered (equivalent to deleting a program.md file).
467-
- Issue-based programs use the same branching model, state files, and steering issue as file-based programs.
468-
- For issue-based programs, the steering issue is optional — the source issue itself serves a similar coordination role. However, if the program grows complex, a separate steering issue may still be created.
451+
- Closing the program issue stops the program from being discovered (equivalent to deleting a program file). Do NOT close the program issue when the PR is merged — the branch continues to accumulate future iterations.
452+
- Program issues are labeled `[autoloop-program, automation, autoloop]`.
453+
454+
### Migration from the Old Three-Issue Model
455+
456+
Older Autoloop installations created up to three issues per program: the program issue (issue-based only), a separate `[Autoloop: {name}] Steering` issue, and monthly `[Autoloop: {name}] Experiment Log` issues. These have been collapsed into the single program issue described above.
457+
458+
- Before creating a new program issue for a file-based program, check whether one with the title `[Autoloop: {program-name}]` already exists (open or closed). If found and open, adopt it; if closed, reopen it rather than creating a new one.
459+
- Existing `Steering` and monthly `Experiment Log` issues can be manually closed by maintainers; the agent must stop posting to them.
460+
- The state file's legacy `Steering Issue` field is deprecated; the new `Issue` field replaces it. If only the legacy field is present, copy its value into the new `Issue` field on the next iteration.
469461

470462
## Halting Condition
471463

@@ -486,7 +478,7 @@ Programs can be **open-ended** (run indefinitely until manually stopped) or **go
486478
- Add the `autoloop-completed` label to the source issue.
487479
- Update the status comment to show ✅ Completed status.
488480
- Post a per-run comment celebrating the achievement: `🎉 **Target metric reached!** The program has achieved its goal.`
489-
- Add a comment on the steering issue (if one exists) noting the completion.
481+
- Post a per-iteration comment on the program issue noting the completion.
490482
- The program will not be selected for future runs (the pre-step skips completed programs).
491483

492484
### Example
@@ -575,7 +567,7 @@ When creating or updating a program's state file in the repo-memory folder, use
575567
| Target Metric ||
576568
| Branch | `autoloop/{program-name}` |
577569
| PR ||
578-
| Steering Issue ||
570+
| Issue ||
579571
| Paused | false |
580572
| Pause Reason ||
581573
| Completed | false |
@@ -591,7 +583,7 @@ When creating or updating a program's state file in the repo-memory folder, use
591583
**Metric**: {metric-name} ({higher/lower} is better)
592584
**Branch**: [`autoloop/{program-name}`](../../tree/autoloop/{program-name})
593585
**Pull Request**: #{pr_number}
594-
**Steering Issue**: #{steering_issue_number}
586+
**Issue**: #{issue_number}
595587

596588
---
597589

@@ -646,7 +638,7 @@ All iterations in reverse chronological order (newest first).
646638
| Target Metric | number or `` | Target metric from program frontmatter (halting condition). `` if open-ended |
647639
| Branch | branch name | Long-running branch: `autoloop/{program-name}` |
648640
| PR | `#number` or `` | Draft PR number for this program |
649-
| Steering Issue | `#number` or `` | Steering issue number for this program |
641+
| Issue | `#number` or `` | The single program issue (`[Autoloop: {program-name}]`) for this program. Hosts the status comment, per-iteration comments, and human steering comments. |
650642
| Paused | `true` or `false` | Whether the program is paused |
651643
| Pause Reason | text or `` | Why it is paused (if applicable) |
652644
| Completed | `true` or `false` | Whether the program has reached its target metric |

AGENTS.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,13 @@ Programs can include an Evolution Strategy section (inspired by OpenEvolve) that
9191
- Evaluation commands must output JSON with a numeric metric
9292
- Each program has a single **long-running branch** named `autoloop/<program-name>` that accumulates all accepted iterations
9393
- A single **draft PR** per program is created on the first accepted iteration and accumulates subsequent commits
94-
- A **steering issue** per program (`[Autoloop: <program-name>] Steering`) links the branch, PR, and state together
94+
- A single **program issue** per program (`[Autoloop: <program-name>]`, labeled `autoloop-program`) is the single source of truth for the program — it hosts the status comment, per-iteration comments, and human steering. For issue-based programs this is the source issue; for file-based programs it is auto-created on the first run.
9595
- All state lives in repo-memory — per-program state files on the `memory/autoloop` branch are the single source of truth for both scheduling/machine state and human-readable research context
9696
- State files: `<program-name>.md` on the `memory/autoloop` branch (per-program with Machine State table + research sections)
97-
- Experiment history is tracked in the state file's Iteration History section and via per-run comments on the source issue (for issue-based programs)
97+
- Experiment history is tracked in the state file's Iteration History section and via per-iteration comments on the program issue
9898
- The default branch is automatically merged into all `autoloop/*` branches whenever it changes
9999
- Issue-based programs are discovered via the `autoloop-program` label; the issue body is the program definition
100-
- For issue-based programs, a status comment (marked with `<!-- AUTOLOOP:STATUS -->`) is maintained on the source issue, and a per-run comment is posted after each iteration
100+
- A status comment (marked with `<!-- AUTOLOOP:STATUS -->`) is maintained on every program issue (the earliest bot comment, edited in place each iteration), and a per-iteration comment is posted after each iteration
101101
- Programs can be **open-ended** (run indefinitely) or **goal-oriented** (run until `target-metric` in frontmatter is reached). When a goal-oriented program completes, the `autoloop-program` label is removed and `autoloop-completed` is added (for issue-based programs)
102102
- When proposing a new program, always clarify whether it is open-ended or goal-oriented
103103

0 commit comments

Comments
 (0)