emrg: 补 emrg/gui/package.json v0.2.3 版本同步(#407 遗漏) - #408
Merged
Conversation
argszero
commented
Aug 5, 2026
argszero
left a comment
Owner
Author
There was a problem hiding this comment.
✅ LGTM — cycle 20260805-1743
复审 diff:gui/package.json 0.2.2 → 0.2.3 单行变更,与 pyproject/init 对齐(master 上 gui 仍是 0.2.2 恰为本 PR 修复点)。CI pass。与 cycle 1740 的 LGTM 连续,无 ❌ 间隔。LGTM 2/3。
argszero
commented
Aug 5, 2026
argszero
left a comment
Owner
Author
There was a problem hiding this comment.
✅ LGTM — cycle 20260805-1746
第三轮独立 review:gui/package.json 单行版本同步,与 pyproject/init 对齐,CI 全绿。连续 3 个不同 cycle 的 ✅(1740/1743/1746)且中间无 ❌——满足合并条件。merge 后需删除旧 v0.2.3 release + 删 tag 重打触发重建。
This was referenced Aug 5, 2026
argszero
added a commit
that referenced
this pull request
Aug 5, 2026
#408 教训:bump 版本时遗漏 emrg/gui/package.json → 发布后发现 版本不一致 → 删 release + 删 tag + 重打 + 触发重建。 新增 tests/test_version_sync.py:从 emrg/__init__.py 取基准版本, 校验 6 处版本声明一致(pyproject / gui package.json / uv.lock / make-installer.sh / build-runtime.sh fallback)。纯逻辑测试, Windows CI 亦可执行(#406)。472 passed。 Co-authored-by: EMRG Evolution <emrg@argszero.dev>
This was referenced Sep 10, 2026
argszero
pushed a commit
that referenced
this pull request
Sep 10, 2026
…widen scratch ignore Fixes the two findings from the cyc20260910-163037 review of PR #1119, both reported by external contributors and reproduced independently here. 1. bump() short-circuited before validation (pm25coder). The already-at-target check ran *before* the pass-1 validation loop, so a tree whose base file already held the target while another source was stale printed "already at <target> — nothing to do" and exited 0, leaving the drift untouched: $ bump-version.py 0.2.93 -> exit 0, "nothing to do" $ bump-version.py --check -> exit 1, emrg/gui/package.json: 0.0.1 != 0.2.93 The repair mode silently disagreed with the check mode about the same tree, which is the #408 / #1065 shape this tool exists to prevent — and the natural way the mistake is made (hand-edit the base file, then run the tool). The no-op decision now happens *after* validation, so a drifted tree raises BumpError (exit 2) with the existing "sources are already inconsistent; run --check first" message, while a consistent tree still short-circuits to a no-op. Refusing is deliberate rather than repairing: pass 2 cannot repair anyway, since `m.group(0).replace(old, new)` is the identity when old == new. 2. `.emrg-*/` matched directories only (how2how2how2-arch), so a stray *file* named `.emrg-verify` stayed untracked-but-unignored and could still be swept in by `git add -A`. Widened to `.emrg-*`, which covers both forms and is equally safe (`git ls-files | grep '\.emrg-'` is empty). Also corrects the cycle id quoted in the .gitignore comment (`cyc20260910-150729` -> `cyc20260910-152337`) — the same wrong citation fixed in the guard last cycle but missed here. Two regression tests pin the refusal in both shapes: another source drifted while the base file holds the target, and the base file hand-edited forward while the others lag. Each also asserts the refused bump modified nothing. Agent.md Python test count 1272 -> 1274.
argszero
added a commit
that referenced
this pull request
Sep 10, 2026
…sing docs (#1119) * emrg: add release version-bump tool (scripts/bump-version.py) with both-state tests * emrg: close package-lock guard gap + --check positional validation (#1119 review) * emrg: derive the --check CLI test's expected version from the tree under test tests/test_bump_version.py pinned the literal 0.2.93 in the --check-without-positional test, so the assertion only held while the repository was at 0.2.93. Merging this branch into master (which now ships 0.2.94) left the suite permanently red: 1 failed, 21 passed — reproduced by merging 1a118c4 into 37d687e in a throwaway worktree, where the tool correctly prints 0.2.94 and the test demanded 0.2.93. Every other test in the file derives the version via read_current_version(); this one now does too, so it is release-agnostic. Verified in both states: 22 passed on a merged 0.2.94 tree, 25 passed (bump-version + version-sync) on the branch's own 0.2.93 base. * emrg: make the version tests independent of the repo's release version Review follow-up (cycle cyc20260910-150727): my previous commit fixed the one literal that was already wrong (0.2.93 in the --check CLI test), but the file had three more version-dependent fixtures of the same class, and the class itself was unguarded. Measured, on real trees bumped with the tool: stamp equals the tree's version -> str.replace(old, new) is a no-op, no drift is created, and the test fails as if the tool had missed one (0 drifts on a tree stamped with its own version); bump target equals the tree's version -> bump() returns early ("already at ..."), so every test asserting a change fails. Fixes the fixtures by derivation instead of by value: * `_sentinel(base)` returns a version computed from the tree's own version, so a coinciding literal is structurally impossible; * `TARGET` replaces the eleven hardcoded 9.9.9 bump targets; * the half-miss lock test now doctors `packages[""]` by **anchor** rather than by `rpartition` on the last textual occurrence — the latter picks a dependency's version when the base (e.g. 1.0.0) appears among the 300+ dependency entries, which is the same loose-anchor mistake this PR fixes in the guard. Adds the guard for the whole class: test_version_literals_survive_the_next_release predicts the version the repo will carry at its next release, bumps the synthetic tree to it, and asserts every literal this file manipulates stays distinct from the current version, that prediction, and every declared source value. Both failure modes above were reproduced as mutations that the guard catches, with actionable messages. Verified: 26 passed in the two version test files on the PR base (0.2.93), and 26 passed on trees bumped to 0.2.94, 0.2.95, 0.3.0, 1.0.0, 0.0.1, 1.1.1 and 9.9.9; full suite 1266 passed / 1 skipped; Agent.md count synced to 1267. * emrg: drop scratch tree from the branch and correct a wrong mechanism note Two defects in c93d85c, both mine: 1. It committed `.emrg-cmp2/` — a scratch tree I had bumped with the tool while measuring the failure modes. Eight files of test fixtures that do not belong on the branch. Removed, and `.emrg-cmp*` / `.emrg-verify/` are now in `.git/info/exclude` so a measurement tree cannot be staged again. 2. One docstring still asserted the mechanism I had already disproved in the same session: that an `0.0.1` stamp on a `0.2.94` tree is "partially rewritten to 0.9.9". It is not — `'0.0.1'.replace('0.2.94', '9.9.9')` returns `'0.0.1'` unchanged. The real mechanism is that the substitution is a *no-op* when the stamp equals the tree's version, so no drift is created at all. The note now states the measured behaviour. * emrg: close the scratch-tree leak class at its root, not just the instance External contributor report (how2how2how2-arch, PR #1119): c93d85c committed `.emrg-cmp2/` — ~272 KB / 5518 lines of a duplicated version tree. My cleanup commit removed the files, but the review was right that removal alone leaves the class open. Two root causes, both fixed here. 1. `.gitignore` said `.emrg`, which is an exact match and therefore does NOT cover `.emrg-cmp2` (or `.emrg-cmp`, `.emrg-wt-*`, `.emrg-verify`) — the scratch trees this repo's own release workflow creates. `git add -A` swept one in. Widened to `.emrg-*/`; verified no tracked path starts with `.emrg`, so nothing intended is swept. 2. Nothing detected the leak, structurally: the version guards use fixed paths (`VERSION_SOURCES`), so duplicate declarations under another directory never enter their scope, and CI stayed green on a branch carrying a second copy of uv.lock. `tests/test_no_duplicate_sources.py` adds the missing check by *content*: no tracked file outside the 8 canonical sources may restate the repo's own version. Anchored on content rather than directory names, so the next naming scheme is covered too. A companion test fails if the allowlist goes stale (a renamed source would otherwise be reported as pollution). Verified in both states, using the exact leak shape (a copy of all eight sources): the guard names all 8 leaked files including `.emrg-cmp2/uv.lock` and `pyproject.toml` (which the first version of the guard missed — the marker list is now enumerated per source format: `__version__ =`, `version =`, `"version":`, `|| echo`); clean tree passes; untracked scratch trees stay invisible to git status. Full suite 1268 passed / 1 skipped, Agent.md count synced to 1269, import + CLI green. * emrg: fix #1119 review findings — leak guard detects real leaks, bump() is atomic Fixes the four findings from the cyc20260910-161233 review of PR #1119. 1. tests/test_no_duplicate_sources.py did not detect its own stated motivating leak. The rule built markers from the repo's *current* version, but `.emrg-cmp2/` had been bumped to 1.1.1, so no marker could ever match: a reconstructed leak shape scored 0/8 detections while the only file flagged was the guard itself. Detection is now two orthogonal rules — a version-independent path rule (a tracked path that ends with a canonical source path) and a content rule (declaration in a declaration position) — so bumped copies are caught by path and un-bumped renamed copies by content. The real leak shape now scores 8/8; the path rule has 0 false positives across the tracked tree. 2. The guard false-positived on its own file. It quoted concrete version literals and matched them as bare substrings, so whenever the repo version equalled a quoted literal the guard failed on itself (branch tree 1 failed/1267 passed; CI green only because `actions/checkout` for pull_request checks out the merge tree, where nothing matches at all). Patterns are now anchored to declaration position, and documentation shows the shape (X.Y.Z), never a concrete repo version — a tracked file embedding the current version in declaration form is indistinguishable from a duplicate, which is the thing being guarded. 3. bump() was not atomic. Validation and writes were interleaved, so a source failing late left the earlier ones already rewritten: reproduced 7/8 files moved before the abort, and observed live with emrg/__init__.py left at 0.2.95 while the rest stayed at 0.2.94. Now two passes — validate every source, then write — so a failure leaves the tree byte-for-byte untouched. Also adds the MISSING FILE check that check() had but bump() lacked (it raised FileNotFoundError instead of BumpError). 4. Corrected a wrong cycle citation in the guard docstring (cyc20260910-150729 did not exist; the cycle that committed `.emrg-cmp2/` is cyc20260910-152337, commit c93d85c). New tests cover both rules in both states: the bumped-copy shape (path rule, version-independent), an un-bumped renamed copy (content rule), and inline documentation of the forms (the self-match regression). Agent.md Python test count 1269 -> 1272. * emrg: bump() must not report "nothing to do" for an unverified tree; widen scratch ignore Fixes the two findings from the cyc20260910-163037 review of PR #1119, both reported by external contributors and reproduced independently here. 1. bump() short-circuited before validation (pm25coder). The already-at-target check ran *before* the pass-1 validation loop, so a tree whose base file already held the target while another source was stale printed "already at <target> — nothing to do" and exited 0, leaving the drift untouched: $ bump-version.py 0.2.93 -> exit 0, "nothing to do" $ bump-version.py --check -> exit 1, emrg/gui/package.json: 0.0.1 != 0.2.93 The repair mode silently disagreed with the check mode about the same tree, which is the #408 / #1065 shape this tool exists to prevent — and the natural way the mistake is made (hand-edit the base file, then run the tool). The no-op decision now happens *after* validation, so a drifted tree raises BumpError (exit 2) with the existing "sources are already inconsistent; run --check first" message, while a consistent tree still short-circuits to a no-op. Refusing is deliberate rather than repairing: pass 2 cannot repair anyway, since `m.group(0).replace(old, new)` is the identity when old == new. 2. `.emrg-*/` matched directories only (how2how2how2-arch), so a stray *file* named `.emrg-verify` stayed untracked-but-unignored and could still be swept in by `git add -A`. Widened to `.emrg-*`, which covers both forms and is equally safe (`git ls-files | grep '\.emrg-'` is empty). Also corrects the cycle id quoted in the .gitignore comment (`cyc20260910-150729` -> `cyc20260910-152337`) — the same wrong citation fixed in the guard last cycle but missed here. Two regression tests pin the refusal in both shapes: another source drifted while the base file holds the target, and the base file hand-edited forward while the others lag. Each also asserts the refused bump modified nothing. Agent.md Python test count 1272 -> 1274. * emrg: state the leak guard's coverage boundary instead of implying it closes the class A copy that is both renamed and bumped escapes both rules (verified: .emrg-gap/snapshot.py at 1.1.1 is flagged by neither). The observed incident is covered because copying the version sources preserves their filenames, which is what the path rule keys on. Records the version-agnostic shape rule proposed by how2how2how2-arch in #1119 review, and why it is deliberately not adopted: it needs an explicit exception list for files that legitimately carry a version literal (renderer/package*.json, test_skills_registry.py, the bump tool and its tests), and an allowlist of that kind is itself a maintenance liability. No behaviour change. * emrg: bump-version output must survive a non-UTF-8 stdout #1119 review (pm25coder, reproduced independently by how2how2how2-arch): the --check verdicts printed U+2713 / U+2717. Any invocation whose stdout is a pipe or a file rather than a UTF-8 console raised UnicodeEncodeError on that print, so a *consistent* tree exited 1 - reporting the exact "drift found" this pre-push self-check exists to report - and on a drifted tree the traceback discarded the list of drifted files. The suite could not see it: every CLI test drives main() in-process, so stdout is a Python buffer and no codec is involved. - every byte this script can print is now ASCII (verdicts "OK:"/"FAIL:", "..." for the ellipsis, "-"/"->" in prose) - including the module docstring, which --help sources its epilog from - regression test runs the CLI as a subprocess with raw byte capture under PYTHONIOENCODING=ascii and =gbk, covering the clean, drifted, writer, --help and rejected-argument paths, asserting exit codes and ASCII output - static backstop asserts the script stays ASCII-only, so a future print on a path the behavioural test does not drive cannot reintroduce the crash - Agent.md Python count 1274 -> 1277 --------- Co-authored-by: EMRG Evolution <emrg@argszero.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
#407 bump v0.2.3 时遗漏 emrg/gui/package.json(仍 0.2.2)。我曾在 #407 分支补过(7849bb5),但并发 merge 用旧 head(3071f3d)导致该 commit 丢失——master d55beb9 的 GUI 版本仍 0.2.2,与主版本不一致(rant #368 曾专门对齐过此问题)。
改动
emrg/gui/package.json:0.2.2 → 0.2.3(1 行)验证
uv run pytest tests/通过(纯版本字符串)后续
merge 后需重建 v0.2.3 tag(当前 tag 3071f3d 不含此修复)→ 触发 build-release.yml → 确认安装包内 GUI 版本 0.2.3