ace-review 0.60.1 → 0.60.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cf22abbaecfa8e1946ec8d74145079d674550f330d80c6a11b6585daf06838c8
|
|
4
|
+
data.tar.gz: f4c8b3bacba1773ce6e524db739f775f0a3f24583b2b95eab82556ebe14405e7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 20a97ff08b91f5ebc898e3ab6d4b251e1effb8be044473cb2875ff34b25cb101de727fb24b6190879b5c133a2bb8e0278608f230d2556b44662ab1872baf91b1
|
|
7
|
+
data.tar.gz: bcc904083e7d122a03ca7dbe3fce06fc9bf6934a74b8a761d9f4404a24c4ed9e6613ac7efdcc6e43f9e9d351720a1cd42b05288fdf61ccdb87a41b8be3e2dc05
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.60.3] - 2026-10-16
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Keep campaign execution receipts stable across unrelated journal appends, preserve historical-head evidence joins, and make delta reports uniquely attributable without requiring a local branch checkout.
|
|
15
|
+
|
|
16
|
+
## [0.60.2] - 2026-10-16
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Follow ace-git-forgejo 0.7 so review and the ordinary merge receiver resolve the same scoped provider API; no review behavior change.
|
|
21
|
+
|
|
10
22
|
## [0.60.1] - 2026-10-10
|
|
11
23
|
|
|
12
24
|
### Fixed
|
|
@@ -68,7 +68,10 @@ module Ace
|
|
|
68
68
|
data["head"] == head && data["kind"] == kind && data["historical"] == historical
|
|
69
69
|
raise Atoms::CampaignContract::Invalid, "accepted execution receipt identity/head/kind mismatch"
|
|
70
70
|
end
|
|
71
|
-
|
|
71
|
+
# The journal tip is a read cursor, not the identity of an accepted
|
|
72
|
+
# receipt. Unrelated attempts advance it without changing this proof.
|
|
73
|
+
# Keep the receipt digest, exact head and canonical ref in the proof.
|
|
74
|
+
data.except("journal_commit")
|
|
72
75
|
rescue Gem::LoadError, JSON::ParserError, SystemCallError => e
|
|
73
76
|
raise Atoms::CampaignContract::Invalid, "ace-assign execution authority unavailable: #{e.message}"
|
|
74
77
|
end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "open3"
|
|
4
4
|
require "yaml"
|
|
5
|
+
require "ace/git/atoms/server_url"
|
|
5
6
|
|
|
6
7
|
module Ace
|
|
7
8
|
module Review
|
|
@@ -46,6 +47,10 @@ module Ace
|
|
|
46
47
|
return {success: false, error: "Delta reference '#{reference}' is not a commit SHA"} unless reference_head.match?(SHA_PATTERN)
|
|
47
48
|
return {success: false, error: "Delta reference head #{reference_head} is not an ancestor of the current PR head #{head}; history was likely rewritten — re-run a full review round"} unless ancestor?(reference_head, head, project_root: project_root)
|
|
48
49
|
|
|
50
|
+
if reference_head == head && newer_local_head?(head, pr_metadata, project_root: project_root)
|
|
51
|
+
return {success: false, error: "PR metadata still reports the reviewed head #{head}, but the local PR branch is newer; reconcile the push and refresh PR metadata before recording an empty delta"}
|
|
52
|
+
end
|
|
53
|
+
|
|
49
54
|
diff = run_git(["diff", "#{reference_head}..#{head}"], project_root: project_root)
|
|
50
55
|
return diff unless diff[:success]
|
|
51
56
|
|
|
@@ -53,6 +58,48 @@ module Ace
|
|
|
53
58
|
session_dir: session_dir, diff: diff[:stdout]}
|
|
54
59
|
end
|
|
55
60
|
|
|
61
|
+
# Repeated provider reads can return the same stale snapshot after a
|
|
62
|
+
# push. A local descendant is evidence against certifying that no code
|
|
63
|
+
# changed. Select the PR branch explicitly; an unrelated checkout does
|
|
64
|
+
# not define that PR's head.
|
|
65
|
+
def self.newer_local_head?(head, metadata, project_root:)
|
|
66
|
+
branch = metadata["headRefName"].to_s
|
|
67
|
+
repository = metadata["head_repository_url"].to_s
|
|
68
|
+
return false if branch.empty? || repository.empty?
|
|
69
|
+
remote = run_git(["for-each-ref", "--format=%(push:remotename)%00%(push:remoteref)", "refs/heads/#{branch}"], project_root: project_root)
|
|
70
|
+
return false unless remote[:success]
|
|
71
|
+
remote_name, remote_ref = remote[:stdout].strip.split("\0", -1)
|
|
72
|
+
return false if remote_name.to_s.empty?
|
|
73
|
+
remote_ref = default_push_ref(branch, remote_name, project_root: project_root) if remote_ref.to_s.empty?
|
|
74
|
+
return false unless remote_ref == "refs/heads/#{branch}"
|
|
75
|
+
urls = run_git(["remote", "get-url", "--push", "--all", remote_name], project_root: project_root)
|
|
76
|
+
return false unless urls[:success] && urls[:stdout].lines.any? do |url|
|
|
77
|
+
Ace::Git::Atoms::ServerUrl.match?(repository, url.strip)
|
|
78
|
+
end
|
|
79
|
+
local = rev_parse("refs/heads/#{branch}", project_root: project_root)
|
|
80
|
+
local[:success] && local[:stdout] != head && ancestor?(head, local[:stdout], project_root: project_root)
|
|
81
|
+
end
|
|
82
|
+
private_class_method :newer_local_head?
|
|
83
|
+
|
|
84
|
+
# Git exposes push:remoteref for explicit push refspecs only. Its
|
|
85
|
+
# default policies use branch names/upstream, not that empty atom.
|
|
86
|
+
def self.default_push_ref(branch, remote, project_root:)
|
|
87
|
+
explicit = run_git(["config", "--get-all", "remote.#{remote}.push"], project_root: project_root)
|
|
88
|
+
return nil if explicit[:success] && !explicit[:stdout].empty?
|
|
89
|
+
policy = run_git(["config", "--get", "push.default"], project_root: project_root)
|
|
90
|
+
upstream = run_git(["config", "--get", "branch.#{branch}.merge"], project_root: project_root)
|
|
91
|
+
case policy[:stdout].to_s.strip
|
|
92
|
+
when "", "simple"
|
|
93
|
+
target = upstream[:stdout].to_s.strip
|
|
94
|
+
fetch = run_git(["config", "--get", "branch.#{branch}.remote"], project_root: project_root)
|
|
95
|
+
triangular = fetch[:success] && fetch[:stdout].strip != remote
|
|
96
|
+
"refs/heads/#{branch}" if triangular || target.empty? || target == "refs/heads/#{branch}"
|
|
97
|
+
when "current", "matching" then "refs/heads/#{branch}"
|
|
98
|
+
when "upstream" then upstream[:stdout].to_s.strip
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
private_class_method :default_push_ref
|
|
102
|
+
|
|
56
103
|
# Find the head SHA recorded by the most recent prior session of this PR.
|
|
57
104
|
#
|
|
58
105
|
# @param pr_url [String] canonical PR URL stored in session metadata
|
|
@@ -23,8 +23,9 @@ module Ace
|
|
|
23
23
|
end
|
|
24
24
|
# Reviewer reports are written as review-report-<model>.md (Ruby API
|
|
25
25
|
# path) or review-<model>.md (CLI provider path); prompt/context and
|
|
26
|
-
# dev-feedback files are not reports.
|
|
27
|
-
|
|
26
|
+
# dev-feedback files are not reports. Single-model and no-op rounds
|
|
27
|
+
# use the maintained review.md output.
|
|
28
|
+
reports = Dir.glob(File.join(dir, "{review-*,review}.md")).select do |path|
|
|
28
29
|
base = File.basename(path)
|
|
29
30
|
!base.end_with?(".prompt.md", ".context.md") &&
|
|
30
31
|
!%w[review-dev-feedback.md].include?(base)
|
data/lib/ace/review/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ace-review
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.60.
|
|
4
|
+
version: 0.60.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michal Czyz
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-10-
|
|
10
|
+
date: 2026-10-16 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: json
|
|
@@ -161,14 +161,14 @@ dependencies:
|
|
|
161
161
|
requirements:
|
|
162
162
|
- - "~>"
|
|
163
163
|
- !ruby/object:Gem::Version
|
|
164
|
-
version: 0.
|
|
164
|
+
version: '0.7'
|
|
165
165
|
type: :runtime
|
|
166
166
|
prerelease: false
|
|
167
167
|
version_requirements: !ruby/object:Gem::Requirement
|
|
168
168
|
requirements:
|
|
169
169
|
- - "~>"
|
|
170
170
|
- !ruby/object:Gem::Version
|
|
171
|
-
version: 0.
|
|
171
|
+
version: '0.7'
|
|
172
172
|
- !ruby/object:Gem::Dependency
|
|
173
173
|
name: ace-support-nav
|
|
174
174
|
requirement: !ruby/object:Gem::Requirement
|