From 60877a4d3069e054f6c90d02a9ef04fc547badcb Mon Sep 17 00:00:00 2001 From: EMRG Evolution Date: Tue, 25 Aug 2026 19:53:30 +0800 Subject: [PATCH 1/2] =?UTF-8?q?emrg:=20bump=20version=20to=20v0.2.79=20(re?= =?UTF-8?q?lease:=20#976-#980=20=E2=80=94=20plist-codesign=20guard,=20GUI?= =?UTF-8?q?=20session=20fix,=20pid/port=20deprecation,=20structural=20dirt?= =?UTF-8?q?y-tree=20guard)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pr-body-release-279.md | 21 +++++++++++++++++++++ .pr-body-worktree.md | 15 +++++++++++++++ emrg/__init__.py | 2 +- emrg/gui/package-lock.json | 4 ++-- emrg/gui/package.json | 2 +- packaging/build-runtime.sh | 2 +- packaging/make-installer.sh | 2 +- packaging/make-run-installer.sh | 2 +- pyproject.toml | 2 +- uv.lock | 2 +- 10 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 .pr-body-release-279.md create mode 100644 .pr-body-worktree.md diff --git a/.pr-body-release-279.md b/.pr-body-release-279.md new file mode 100644 index 00000000..9b9cfbb6 --- /dev/null +++ b/.pr-body-release-279.md @@ -0,0 +1,21 @@ +## Summary + +Host-authorized release (rant 2026-08-25T19:50:42, host grant 2026-08-25 19:01: "好,提交rant,等完成后发布新版本" — trigger: #978/#980 both merged). Both are now on master, so bumping **v0.2.78 → v0.2.79**. + +## Release contents (master since v0.2.78) + +- **#976** — guard against plist XML comments breaking codesign (AMFI) +- **#977** — fix GUI session cross-wiring / empty history (resolve session cwd, reject ghost sessions, cwd-scoped broadcasts) +- **#978** — deprecate emrgd.pid/emrgd.port in uninstaller (fixed-port + token ground truth) +- **#980** — structural dirty-tree guard: dirty source dir forces read-only sandbox + git mutators blocked (community issue #979) + +> Note: #981 (linked-worktree dirty-probe follow-up, currently in review) will also be included in this release if it merges before the v0.2.79 tag is cut — the tag is taken from master tip. + +## Files bumped (0.2.78 → 0.2.79) + +`emrg/__init__.py`, `emrg/gui/package.json`, `emrg/gui/package-lock.json`, `packaging/build-runtime.sh`, `packaging/make-installer.sh`, `packaging/make-run-installer.sh`, `pyproject.toml`, `uv.lock` + +## Verification + +- `pytest tests/ -q` → **1077 passed, 1 skipped** (master state; doc-count guard #511 satisfied) +- `emrg.__version__` → `0.2.79` diff --git a/.pr-body-worktree.md b/.pr-body-worktree.md new file mode 100644 index 00000000..3d67fa7d --- /dev/null +++ b/.pr-body-worktree.md @@ -0,0 +1,15 @@ +## Summary + +Follow-up to #980 (structural dirty-tree guard, community issue #979). The dirty-tree probe used `os.path.isdir(source_dir / ".git")`, which silently **fails open** for **linked git worktrees**: there `.git` is a *file* (`gitdir: ...` pointer), not a directory. In a worktree-based setup the read-only sandbox guard was bypassed without any signal. + +## Changes + +- **`emrg/server/scheduler.py`** — `_is_dirty_tree_sync()` now accepts the `.git` marker as either a directory (regular repo) **or** a file (linked worktree). Still fail-open for bare/non-git dirs, still runs via `asyncio.to_thread`, still keeps the local `subprocess` import invariant. +- **`tests/test_scheduler.py`** — new test `test_is_dirty_tree_linked_worktree`: creates a repo, adds a linked worktree, asserts `.git` is a file there, and verifies both states (clean worktree → `False`, untracked file → `True`). +- **`Agent.md`** — documented pytest collected count synced 1078 → 1079 (doc-count guard #511, new test added). + +## Verification + +- `pytest tests/ -q` → **1078 passed, 1 skipped** +- Existing dirty-tree tests still pass (4 passed incl. the new worktree test) +- Import check `from emrg.client.app import run_client` ✅, `python -m emrg --help` ✅ diff --git a/emrg/__init__.py b/emrg/__init__.py index 941a4cd8..441460a6 100644 --- a/emrg/__init__.py +++ b/emrg/__init__.py @@ -1,3 +1,3 @@ """EMRG — a self-evolving AI agent architecture.""" -__version__ = "0.2.78" +__version__ = "0.2.79" diff --git a/emrg/gui/package-lock.json b/emrg/gui/package-lock.json index bd09f910..e7c30326 100644 --- a/emrg/gui/package-lock.json +++ b/emrg/gui/package-lock.json @@ -1,12 +1,12 @@ { "name": "emrg-gui", - "version": "0.2.78", + "version": "0.2.79", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "emrg-gui", - "version": "0.2.78", + "version": "0.2.79", "dependencies": { "dompurify": "^3.4.13", "highlight.js": "^11.10.0", diff --git a/emrg/gui/package.json b/emrg/gui/package.json index 55c5bf57..1ae4c758 100644 --- a/emrg/gui/package.json +++ b/emrg/gui/package.json @@ -1,6 +1,6 @@ { "name": "emrg-gui", - "version": "0.2.78", + "version": "0.2.79", "description": "EMRG GUI — Electron client for the EMRG self-evolving AI agent (Phase 3)", "main": "main.js", "scripts": { diff --git a/packaging/build-runtime.sh b/packaging/build-runtime.sh index 53cb56f6..f17a3463 100755 --- a/packaging/build-runtime.sh +++ b/packaging/build-runtime.sh @@ -132,7 +132,7 @@ cp "$ROOT/LICENSE" "$DIST/assets/LICENSE" 2>/dev/null || echo "Apache-2.0" > "$D # the runtime so installed machines have it even before daemon first run. cp "$ROOT/packaging/assets/skill-catalog.md" "$DIST/assets/skill-catalog.md" 2>/dev/null || true "$PY_BIN" -c "import emrg,sys; sys.path.insert(0,'$DIST/source'); import emrg as e; print(e.__version__)" > "$DIST/version.txt" 2>/dev/null \ - || echo "0.2.78" > "$DIST/version.txt" + || echo "0.2.79" > "$DIST/version.txt" echo "==> runtime size: $(du -sh "$DIST" | cut -f1)" echo "==> runtime built OK" diff --git a/packaging/make-installer.sh b/packaging/make-installer.sh index ba6ada33..9dd26a7a 100755 --- a/packaging/make-installer.sh +++ b/packaging/make-installer.sh @@ -25,7 +25,7 @@ set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" DIST="$ROOT/dist" RUNTIME="$DIST/runtime" -VERSION="$(cat "$RUNTIME/version.txt" 2>/dev/null || echo 0.2.78)" +VERSION="$(cat "$RUNTIME/version.txt" 2>/dev/null || echo 0.2.79)" PLATFORM="${1:-$(uname -s | tr '[:upper:]' '[:lower:]')}" mkdir -p "$DIST/artifacts" diff --git a/packaging/make-run-installer.sh b/packaging/make-run-installer.sh index 832a56da..d9d3d35b 100644 --- a/packaging/make-run-installer.sh +++ b/packaging/make-run-installer.sh @@ -25,7 +25,7 @@ set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" DIST="$ROOT/dist" RUNTIME="$DIST/runtime" -VERSION="$(cat "$RUNTIME/version.txt" 2>/dev/null || echo 0.2.78)" +VERSION="$(cat "$RUNTIME/version.txt" 2>/dev/null || echo 0.2.79)" ARCH="${ARCH:-$(uname -m)}" # x86_64 / aarch64 OUT="$DIST/artifacts/EMRG-$VERSION-linux-$ARCH.run" diff --git a/pyproject.toml b/pyproject.toml index 3dbe718b..0a162125 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "emrg" -version = "0.2.78" +version = "0.2.79" description = "EMRG — a self-evolving AI agent architecture" requires-python = ">=3.11" license = { file = "LICENSE" } diff --git a/uv.lock b/uv.lock index 3c90f5a2..8d37ef5f 100644 --- a/uv.lock +++ b/uv.lock @@ -35,7 +35,7 @@ wheels = [ [[package]] name = "emrg" -version = "0.2.78" +version = "0.2.79" source = { editable = "." } dependencies = [ { name = "httpx" }, From 0e166452af88d42a4c5114acdb78a32aa3edcf5a Mon Sep 17 00:00:00 2001 From: EMRG Evolution Date: Tue, 25 Aug 2026 19:53:51 +0800 Subject: [PATCH 2/2] emrg: drop stray PR-body artifacts from release branch --- .pr-body-release-279.md | 21 --------------------- .pr-body-worktree.md | 15 --------------- 2 files changed, 36 deletions(-) delete mode 100644 .pr-body-release-279.md delete mode 100644 .pr-body-worktree.md diff --git a/.pr-body-release-279.md b/.pr-body-release-279.md deleted file mode 100644 index 9b9cfbb6..00000000 --- a/.pr-body-release-279.md +++ /dev/null @@ -1,21 +0,0 @@ -## Summary - -Host-authorized release (rant 2026-08-25T19:50:42, host grant 2026-08-25 19:01: "好,提交rant,等完成后发布新版本" — trigger: #978/#980 both merged). Both are now on master, so bumping **v0.2.78 → v0.2.79**. - -## Release contents (master since v0.2.78) - -- **#976** — guard against plist XML comments breaking codesign (AMFI) -- **#977** — fix GUI session cross-wiring / empty history (resolve session cwd, reject ghost sessions, cwd-scoped broadcasts) -- **#978** — deprecate emrgd.pid/emrgd.port in uninstaller (fixed-port + token ground truth) -- **#980** — structural dirty-tree guard: dirty source dir forces read-only sandbox + git mutators blocked (community issue #979) - -> Note: #981 (linked-worktree dirty-probe follow-up, currently in review) will also be included in this release if it merges before the v0.2.79 tag is cut — the tag is taken from master tip. - -## Files bumped (0.2.78 → 0.2.79) - -`emrg/__init__.py`, `emrg/gui/package.json`, `emrg/gui/package-lock.json`, `packaging/build-runtime.sh`, `packaging/make-installer.sh`, `packaging/make-run-installer.sh`, `pyproject.toml`, `uv.lock` - -## Verification - -- `pytest tests/ -q` → **1077 passed, 1 skipped** (master state; doc-count guard #511 satisfied) -- `emrg.__version__` → `0.2.79` diff --git a/.pr-body-worktree.md b/.pr-body-worktree.md deleted file mode 100644 index 3d67fa7d..00000000 --- a/.pr-body-worktree.md +++ /dev/null @@ -1,15 +0,0 @@ -## Summary - -Follow-up to #980 (structural dirty-tree guard, community issue #979). The dirty-tree probe used `os.path.isdir(source_dir / ".git")`, which silently **fails open** for **linked git worktrees**: there `.git` is a *file* (`gitdir: ...` pointer), not a directory. In a worktree-based setup the read-only sandbox guard was bypassed without any signal. - -## Changes - -- **`emrg/server/scheduler.py`** — `_is_dirty_tree_sync()` now accepts the `.git` marker as either a directory (regular repo) **or** a file (linked worktree). Still fail-open for bare/non-git dirs, still runs via `asyncio.to_thread`, still keeps the local `subprocess` import invariant. -- **`tests/test_scheduler.py`** — new test `test_is_dirty_tree_linked_worktree`: creates a repo, adds a linked worktree, asserts `.git` is a file there, and verifies both states (clean worktree → `False`, untracked file → `True`). -- **`Agent.md`** — documented pytest collected count synced 1078 → 1079 (doc-count guard #511, new test added). - -## Verification - -- `pytest tests/ -q` → **1078 passed, 1 skipped** -- Existing dirty-tree tests still pass (4 passed incl. the new worktree test) -- Import check `from emrg.client.app import run_client` ✅, `python -m emrg --help` ✅