Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Community needs voiced in HN agent-UI discussions map directly to EMRG's design:
pkill -f "emrg.server"; rm -f ~/.emrg/emrgd.token; python -m emrg
```

Python: `uv run pytest tests/ -v` (1039) — import check: `uv run python -c "from emrg.client.app import run_client"`
Python: `uv run pytest tests/ -v` (1040) — import check: `uv run python -c "from emrg.client.app import run_client"`
GUI: `cd emrg/gui && npm test` (259: 45 daemon_client + 20 conn-manager + 22 app-commands + 129 renderer smoke + 15 i18n + 8 integration + 3 commands + 8 build-config + 7 gui-state + 2 tool-group) — syntax: `node --check main.js preload.js daemon_client.js renderer/js/*.js`
CI: `uv run pytest` (ubuntu + **windows-2025 matrix** — Windows pytest 回归在 PR CI 即失败,v0.2.29 教训 #725) + GUI tests + **actionlint workflow lint** (`rhysd/actionlint@v1.7.12` gate, #444 — workflow 解析错误在 PR CI 即失败,如 `if:` secrets 上下文)
Re-trigger: `scripts/re-trigger-ci.sh [branch]` (workflow_dispatch, #527 — 替代空 commit 重触发:Actions outage 会整段丢弃 push 事件,dispatch 走 API 路径不受影响)
Expand Down
42 changes: 39 additions & 3 deletions emrg/server/open_source_prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ State file format:
```markdown
# Open-Source State: {{ owner }}/{{ repo }}
- role: Committer | Contributor
- current stage: Prep | Recon | Contribute | Track | Review
- current stage: Prep | Recon | Contribute | Track | Track+Recon | Review
- last completed: <what was done last round>
- active PRs: <own open PR list, one per line>
- in progress: <what is being implemented | none>
Expand Down Expand Up @@ -206,6 +206,13 @@ Is "in progress" non-empty in the state file?

Are there open items in "active PRs"?
→ Phase Tracking (check PR status, respond to reviews)
All open PRs healthy (MERGEABLE + CI green, no conflicts, no pending
review feedback) AND no rebase maintenance due this round (≤1 round
since last maintenance)?
→ May run Recon in parallel this round (stage = Track+Recon):
scan issues/PRs for a new contribution direction; found one →
enter Phase Contribution next round (recon this round, implement
next round). See Phase C.1.5.

No active work?
→ Phase Recon (scan issues/PRs for something to do)
Expand All @@ -214,7 +221,8 @@ Role = Committer and many PRs awaiting review?
→ May move to Phase Review after recon
```

**Only one phase per cycle. Don't aim for completeness, just for progress.**
**One primary phase per cycle. Don't aim for completeness, just for progress.**
**Exception**: during Phase Tracking, when all open PRs are healthy (MERGEABLE + CI green, no conflicts, no pending review feedback) and no rebase maintenance is due this round, Recon may run **in parallel** (stage = `Track+Recon`) — see Phase C.1.5. Parallel Recon must still respect the output cap and direction-diversity rules there.

---

Expand Down Expand Up @@ -420,10 +428,38 @@ For each open PR:
| **Closed (unmerged)** | Understand why → record in memory file → remove from active PR list |
| **No feedback for 7+ days** | May politely ask on the PR "any updates or feedback?" |

#### C.1.5 Parallel Recon (healthy-PR rule, rant 2026-08-24T14:05:06)

Tracking is **not maintenance-only**. When **all** open PRs are healthy and this round needs no maintenance, you may run Recon in parallel instead of finishing the cycle — a long-lived healthy PR (MERGEABLE + CI green) must not lock the task out of producing new contributions.

**Healthy** = for **every** open PR in the active list:
- **MERGEABLE** — no conflicts (`gh pr view <N> -R {{ owner }}/{{ repo }} --json mergeable,mergeableState`)
- **CI green** — `gh pr checks <N> -R {{ owner }}/{{ repo }}`: no failed/pending checks reported (a PR with **zero** checks reported means the push event was dropped — re-trigger, do not count as healthy)
- **No unaddressed feedback** — no unanswered change requests / bot / maintainer comments (`gh api repos/{{ owner }}/{{ repo }}/pulls/<N>/reviews` + `/issues/<N>/comments`)
- **No rebase maintenance due** — last maintenance round ≤ 1 round ago

When healthy (all of the above), in the **same round**:
1. Run Phase A Recon steps (A.1 scan issues, A.2 scan PRs) to find a new contribution direction
2. Direction found → update the state file (stage = `Track+Recon`; keep all active PRs; set in-progress = new candidate), enter **Phase Contribution next round**
3. Nothing found → update the state file (stage = `Track+Recon`, next step = continue recon), finish this cycle

**Maintenance duty is NOT waived**: any open PR that needs rebase / review-feedback response / 7-day nudge → do Tracking maintenance first (C.1 table), and only then consider parallel Recon.

**Parallel output cap**: while Tracking+Recon runs in parallel, hold at most **3 total same-day open PRs** (avoid stacking PRs that overload maintainers; PRs accumulated across days are not capped by this rule, but keep the total prudent).

**Direction diversity**: if a Recon candidate's topic conflicts with existing open PR themes, prefer a contribution in a different module/type (broaden coverage rather than stacking similar work).

**State file when parallel**:
- `current stage: Track+Recon`
- `active PRs:` keeps all healthy open PRs (one per line)
- `in progress:` records the new candidate (issue URL / next contribution) alongside

#### C.2 Exit condition

- No open PRs → state file (active PRs = none), enter Phase Recon next round
- Still have open PRs → update the state file, finish this cycle
- Still have open PRs:
- All healthy + no maintenance due (per C.1.5) → run parallel Recon (stage = `Track+Recon`); found a direction → enter Phase Contribution next round; otherwise finish the cycle
- Any PR needs maintenance (rebase / feedback / nudge) → do it, update the state file, finish this cycle

---

Expand Down
37 changes: 37 additions & 0 deletions tests/test_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,43 @@ def test_open_source_template_full_code_study_b2b():
assert "Only when you understand the author's design intent should you consider how to contribute" in out, "理解设计意图后才可贡献应渲染"


def test_open_source_template_parallel_recon_c15():
"""open_source_prompt.md Phase C.1.5 allows parallel Recon when all open
PRs are healthy (rant 2026-08-24T14:05:06): a long-lived healthy PR must
not lock the task out of producing new contributions."""
import jinja2

template_path = (
Path(__file__).resolve().parent.parent
/ "emrg" / "server" / "open_source_prompt.md"
)
env = jinja2.Environment(undefined=jinja2.Undefined)
template = env.from_string(template_path.read_text(encoding="utf-8"))
out = template.render(
instance_id="test", host_name="host", uptime="0h 0m",
repo_url="https://github.com/x/y.git", owner="x", repo="y",
local_source="/tmp/os", source_dir="/tmp/os", session_id="s1",
evolution_cwd="/tmp/evo", timestamp="20260824",
task={"role": "committer", "project": "aitokenpool"},
project={}, evolution_count=0, git_path="git", gh_path="gh",
)
# 1) the new section exists
assert "C.1.5 Parallel Recon" in out, "C.1.5 并行 Recon 节应渲染"
assert "not maintenance-only" in out, "Tracking 非纯维护说明应渲染"
# 2) healthy = MERGEABLE + CI green + no unaddressed feedback + no rebase due
assert "MERGEABLE" in out, "健康判定含 MERGEABLE"
assert "CI green" in out, "健康判定含 CI 绿"
assert "No unaddressed feedback" in out, "健康判定含无未处理评审反馈"
assert "No rebase maintenance due" in out, "健康判定含无需 rebase 维护"
# 3) parallel output cap + direction diversity rules render
assert "3 total same-day open PRs" in out, "同日 open PR 上限 3 个应渲染"
assert "Direction diversity" in out, "方向多样性规则应渲染"
# 4) state file stage value Track+Recon is documented in the format spec
assert "Track+Recon" in out, "Track+Recon stage 值应渲染"
# 5) the state machine no longer hard-locks open PRs into Tracking-only
assert "May run Recon in parallel this round" in out, "状态机应允许并行 Recon"


def test_promote_template_learn_latest_state_04():
"""promote_prompt.md §0.4 requires learning the project's latest state
before promoting (rant 2026-08-14T22:13:57, mirrors open-source B.2b #790)."""
Expand Down
Loading