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.port; python -m emrg
```

Python: `uv run pytest tests/ -v` (800) — import check: `uv run python -c "from emrg.client.app import run_client"`
Python: `uv run pytest tests/ -v` (801) — import check: `uv run python -c "from emrg.client.app import run_client"`
GUI: `cd emrg/gui && npm test` (236: 44 daemon_client + 19 conn-manager + 22 app-commands + 114 renderer smoke + 15 i18n + 7 integration + 3 commands + 5 build-config + 7 gui-state) — 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
56 changes: 55 additions & 1 deletion emrg/server/open_source_prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,53 @@ State file format:
- 阻塞: <什么在阻止进展?空=无阻塞>
```

#### 0.5 Rant scan (host development instructions)

**Rants are the host's development work orders.** A rant whose `project` field equals this task's `config.project` (tasks.yml) is a development instruction for THIS repository.

```bash
cat ~/.emrg/rants.jsonl 2>/dev/null || echo "[no rants.jsonl — skip rant scan]"
```

Filter rules (aligned with evolution_prompt.md):

- Only rants whose `project` field == this task's `config.project`; **ignore rants without a `project` field entirely**
- Only consider rants with status `pending` or `in_progress`

**Dedup check — before treating any candidate rant as actionable** (run for each candidate):

```bash
cd {{ source_dir }} && git log --oneline -20
```

- Search the log for the rant's timestamp or message keywords
- ⚠️ A commit referencing the rant timestamp is only evidence the rant was **touched** — NOT sufficient proof of completion. It counts as already handled only when: all its acceptance items are satisfied AND all related branches/PRs are merged. Otherwise treat it as actionable.

**Rant status management** (aligned with evolution_prompt.md):

| status | meaning |
|--------|---------|
| `pending` | waiting to be handled (default for new rants) |
| `in_progress` | being handled — set when starting work; write `progress` (e.g. "implementing X (PR #N)") |
| `completed` | done — all PRs for the rant merged + self-verification passes (project test suite, e.g. `cargo test` / `pytest` / `npm test`); write the `completed` ISO timestamp. Host verification is NOT a precondition — host feedback arrives as new rants |

- State transitions: pending → in_progress → completed. **Never jump directly from pending to completed**
- Host opens a new rant saying a fix is insufficient → revert the old rant to `in_progress`, note the reason in `progress`
- Cleanup: keep all pending/in_progress rants; keep only the 10 most recent completed
- When rewriting: sort by `timestamp` ascending; field order `timestamp → project → status → progress → completed → message` (message last); write with `json.dumps(..., ensure_ascii=False)`

**Language policy**: rant-driven outputs (PR title/body, review comments, issue replies) MUST be written in English; keep rant content verbatim when quoting it. Internal artifacts (state file, reflection, memory) may stay in the author's language.

---

### 1. State Assessment (decide which phase this cycle enters, based on the state file)

**Decision logic**:

```
Unhandled rant found in 0.5 (project matches, pending/in_progress, dedup check passed)?
→ Phase Contribution (handle the rant — host instruction, highest priority)

Is "进行中" (in progress) in the state file non-empty?
→ Phase Contribution (continue the unfinished implementation)

Expand Down Expand Up @@ -198,6 +238,20 @@ cd {{ source_dir }} && gh issue view <N> -R {{ owner }}/{{ repo }} --json state,

- If claimed by someone else or closed → return to Phase Recon

#### B.1b Rant-driven mode (host rant as development instruction)

When Phase Contribution is entered because an **unhandled rant** (project-matching, pending/in_progress) was found in the 0.5 scan:

- The rant is the host's explicit development instruction — **priority over issues**
- Before implementing: mark the rant `in_progress` in `~/.emrg/rants.jsonl` with a `progress` description (e.g. "implementing X (PR #N)")
- One rant may be split into multiple PRs (one acceptance item per PR, small iterations); reference the rant (timestamp + keywords) in the PR description
- Flow continues with B.2–B.6 below (read conventions → fork/branch → implement → test → commit + PR)
- After a PR is submitted: update the rant's `progress` (e.g. "PR #N submitted, awaiting review")
- When ALL the rant's PRs are merged and self-verification passes (the project's test suite, per B.5): set status `completed` and write the `completed` timestamp
- Language policy: PR title/body in English; quote the rant verbatim when referencing it

> ⚠️ The dedup check is already done in 0.5 — never start work on a rant whose acceptance items are already satisfied and branches merged.

#### B.2 Study project conventions (MUST do before implementing)

**Before writing any code, read the target repository's contribution guide files**:
Expand Down Expand Up @@ -395,7 +449,7 @@ Each round must answer these 7 questions (cannot be omitted):

1. **What was this round's goal?** — Which Phase did this round enter (recon/contribution/tracking/review)? What specific task to complete? If there's rant feedback, list the rants considered this round (write "no new rant feedback" if none)
2. **What does success look like?** — What would "done" look like? (PR merged? Issue claimed? Review completed? Contribution accepted?)
3. **What was actually done?** — Concrete actions: which issues scanned, what code written, which PRs reviewed, what discussions replied to, what waited on
3. **What was actually done?** — Concrete actions: which issues scanned, what code written, which PRs reviewed, what discussions replied to, what waited on. **If this round submitted a PR for a rant, record the PR number and the rant it addresses (timestamp/keywords).**
4. **What is the current progress?** — Compared to the ideal outcome, how far along? What's missing? (How many more reviews does the PR need? Which part of the code is unfinished? Was the issue claimed by someone else?)
5. **What pitfalls were hit?** — Which attempts failed, what CI broke, why reviews were rejected, network/permission blockers, platform CLI or browser unavailability. Record honestly, don't gloss over
6. **What opportunities were discovered?** — Which issues are worth doing, which PRs have potential, what new directions in community activity, which project conventions deserve attention?
Expand Down
26 changes: 26 additions & 0 deletions tests/test_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,32 @@ def test_paper_template_renders_with_context():
assert "literature" in out, "文献去重指引应渲染"


def test_open_source_template_renders_with_context():
"""open_source_prompt.md renders without Jinja2 errors (rant-scan section)."""
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="20260813",
task={"role": "committer", "project": "aitokenpool"},
project={}, evolution_count=0, git_path="git", gh_path="gh",
)
assert "0.5 Rant scan" in out, "rant-scan 0.5 节应渲染"
assert "rants.jsonl" in out, "rant 扫描命令应渲染"
assert "config.project" in out, "project 匹配过滤应渲染"
assert "B.1b Rant-driven mode" in out, "rant 驱动模式应渲染"
assert "ROLE LOCK" in out, "既有 ROLE LOCK 应保留"
assert "json.dumps(..., ensure_ascii=False)" in out, "rant 状态写入要求应渲染"


# ── Evolution workspace self-heal (rant 2026-08-06T20:42:05, 方案 C) ──────


Expand Down
Loading