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` (867) — import check: `uv run python -c "from emrg.client.app import run_client"`
Python: `uv run pytest tests/ -v` (868) — import check: `uv run python -c "from emrg.client.app import run_client"`
GUI: `cd emrg/gui && npm test` (257: 45 daemon_client + 19 conn-manager + 22 app-commands + 129 renderer smoke + 16 i18n + 7 integration + 3 commands + 7 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
2 changes: 1 addition & 1 deletion emrg/server/evolution_prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ Old entries without a `status` field are treated as pending.

When reading rants, follow these rules:
- Any unhandled rants? Previously skipped? Large changes can be staged
- Only read rants whose `project` field matches the current task's `config.project`; **ignore rants without a `project` field entirely**
- Match the rant's `project` field against **either** this task's `config.project` (**`{{ task.project }}`**) or the owner/repo form (**`{{ owner }}/{{ repo }}`**) — equal to either counts as a match; **ignore rants without a `project` field entirely** (rant 2026-08-17T12:09:57: the two forms must both match — a rant written with one form must never silently fail to match the other)

> **Note**: first check whether a rant was already handled, to avoid duplicate work:
> 1. Check `git log --oneline -20` for commits referencing the rant (search the rant's timestamp or message keywords) — **note: a commit referencing the rant timestamp is only evidence the rant was touched, NOT sufficient proof of completion**. You must further verify: does the rant have unmet acceptance items? Are there unmerged branches? An early PR merge in a multi-stage effort does not mean the rant is done.
Expand Down
8 changes: 7 additions & 1 deletion emrg/server/open_source_prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,15 @@ 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**
- Match the rant's `project` field against **either** of these two values — equal to either counts as a match:
- this task's `config.project` (tasks.yml): **`{{ task.project }}`**
- owner/repo form: **`{{ owner }}/{{ repo }}`**
- Example: if `config.project` is `aitokenpool` and the repo is `argszero/aitokenpool`, then a rant with `project: aitokenpool` **or** `project: argszero/aitokenpool` both match.
- **Ignore rants without a `project` field entirely**
- Only consider rants with status `pending` or `in_progress`

**⚠️ Unmatched-rant hint**: after the scan, if there exist rants with status `pending`/`in_progress` whose `project` starts with `{{ task.project }}` or `{{ owner }}/{{ repo }}` but did NOT match the filter above, record the count in the state file / reflection (e.g. "存在 N 条 project 疑似本项目但未匹配的 rant" / "N rants with a project resembling this repo were not matched") — never silently skip them.

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

```bash
Expand Down
30 changes: 30 additions & 0 deletions tests/test_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,11 @@ def test_open_source_template_renders_with_context():
assert "0.5 Rant scan" in out, "rant-scan 0.5 节应渲染"
assert "rants.jsonl" in out, "rant 扫描命令应渲染"
assert "config.project" in out, "project 匹配过滤应渲染"
# Rant 2026-08-17T12:09:57: dual-compatible project matching (config.project
# OR owner/repo) must be rendered with the actual values.
assert "aitokenpool" in out, "task.project 值应渲染进 0.5 节"
assert "x/y" in out, "owner/repo 形式应渲染进 0.5 节"
assert "Unmatched-rant hint" in out, "未匹配疑似 rant 提示应渲染"
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 状态写入要求应渲染"
Expand Down Expand Up @@ -2113,3 +2118,28 @@ async def _run():
asyncio.run(_run())
finally:
mod.config_dir = orig


def test_evolution_template_renders_dual_project_match():
"""evolution_prompt.md renders the dual-compatible rant project match
(rant 2026-08-17T12:09:57): both config.project AND owner/repo forms
must be accepted when scanning rants."""
import jinja2

template_path = (
Path(__file__).resolve().parent.parent
/ "emrg" / "server" / "evolution_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/argszero/emrg.git", owner="argszero",
repo="emrg", local_source="/tmp/evo", source_dir="/tmp/evo",
session_id="s1", evolution_cwd="/tmp/evo", timestamp="20260817",
task={"role": "committer", "project": "emrg"},
project={}, evolution_count=0, git_path="git", gh_path="gh",
)
assert "emrg" in out, "task.project 值应渲染"
assert "argszero/emrg" in out, "owner/repo 形式应渲染"
assert "ignore rants without a `project` field entirely" in out
Loading