VERIFIED
rhayes777__pyautofit-888
VERIFIED on first verdict
1 attempt, 0 appeals. 1 file, 314 added and 300 removed lines. Tokens: 565,974 tokens. Model cost: $0.04. Sandbox time: 2 min 36 s.
The plan
- Repository
- rhayes777/pyautofit
- Base commit
- b0ec41b (image tag)
- Issue
- Bug where sensitivity mapping no longer supports tuple step_size In a previous issue, we made it so that the `number_of_steps` in the `Sensitivity` class could be a tuple so that different dimensions had different steps: ``` sensitivity = af.Sensitivity( paths=paths, simulation_instance=simulation_instance,
- Files to edit
- none
- Approach
- Modify the `_perturb_models` property to handle tuple step_size by computing half_step per dimension, or normalize step_size to always be a float by using the first dimension's step when it's a tuple. Looking at the tests, they expect 16 jobs/models with tuple (2,2,4) steps, so the code needs to iterate over dimensions properly. Planner dropped nonexistent files: ["autofit/non_linear/grid/sensitivity.py"]
Attempt 1
VERIFIEDAgent branch
| Kind | Command | Exit | Duration | Digest |
|---|---|---|---|---|
| command | git ls-files -zexact commandgit ls-files -z | 0 | 0.004s | 9210ff04 |
| command | find /PyAutoFit -name "sensitivity.py" 2>/dev/nullexact commandfind /PyAutoFit -name "sensitivity.py" 2>/dev/null | 0 | 0.009s | 7692297f |
| command | find /PyAutoFit -path "*/grid/sensitivity.py" 2>/dev/nullexact commandfind /PyAutoFit -path "*/grid/sensitivity.py" 2>/dev/null | 0 | 0.010s | d93f72dc |
| command | ls -la /PyAutoFit/autofit/non_linear/grid/ 2>/dev/null || find /PyAutoFit -type d -name "grid" 2>/dev/nullexact commandls -la /PyAutoFit/autofit/non_linear/grid/ 2>/dev/null || find /PyAutoFit -type d -name "grid" 2>/dev/null | 0 | 0.004s | bf179fc7 |
| command | ls -la /PyAutoFit/autofit/non_linear/grid/sensitivity/exact commandls -la /PyAutoFit/autofit/non_linear/grid/sensitivity/ | 0 | 0.004s | 6636297a |
| command | find /PyAutoFit -name "sensitivity.py" -type f 2>/dev/nullexact commandfind /PyAutoFit -name "sensitivity.py" -type f 2>/dev/null | 0 | 0.008s | e8e7a1c2 |
| command | ls -la /PyAutoFit/autofit/non_linear/grid/exact commandls -la /PyAutoFit/autofit/non_linear/grid/ | 0 | 0.004s | 862fca3e |
| command | ls -la /PyAutoFit/autofit/non_linear/grid/sensitivity/exact commandls -la /PyAutoFit/autofit/non_linear/grid/sensitivity/ | 0 | 0.004s | 1486e3aa |
show all 49 steps
| Kind | Command | Exit | Duration | Digest |
|---|---|---|---|---|
| command | find /PyAutoFit -name "*.py" | xargs grep -l "class Sensitivity" 2>/dev/nullexact commandfind /PyAutoFit -name "*.py" | xargs grep -l "class Sensitivity" 2>/dev/null | 0 | 0.023s | 4de9194c |
| command | head -100 /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandhead -100 /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | 7f3385fe |
| command | wc -l /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandwc -l /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | 70aa53fe |
| command | sed -n '280,310p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandsed -n '280,310p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | 03bd5403 |
| command | sed -n '200,280p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandsed -n '200,280p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | 9d8dd5e2 |
| command | sed -n '1,100p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandsed -n '1,100p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | 01ece0fa |
| command | grep -n "step_size" /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandgrep -n "step_size" /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | 4b4c72ed |
| command | sed -n '170,200p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandsed -n '170,200p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | 92c728f6 |
| command | find /PyAutoFit -path "*/test*sensitivity*" -name "*.py" 2>/dev/nullexact commandfind /PyAutoFit -path "*/test*sensitivity*" -name "*.py" 2>/dev/null | 0 | 0.009s | 65a27db2 |
| command | grep -n "tuple_steps\|test_models_with_tuple_steps\|test_jobs_with_tuple_steps" /PyAutoFit/test_autofit/non_linear/grid/test_sensitivity/test_functionality.pyexact commandgrep -n "tuple_steps\|test_models_with_tuple_steps\|test_jobs_with_tuple_steps" /PyAutoFit/test_autofit/non_linear/grid/test_sensitivity/test_functionality.py | 0 | 0.003s | 8cbb6222 |
| command | sed -n '130,160p' /PyAutoFit/test_autofit/non_linear/grid/test_sensitivity/test_functionality.pyexact commandsed -n '130,160p' /PyAutoFit/test_autofit/non_linear/grid/test_sensitivity/test_functionality.py | 0 | 0.003s | 883fb49e |
| command | grep -n "def make_lists" /PyAutoFit/autofit/non_linear/grid/grid_search.pyexact commandgrep -n "def make_lists" /PyAutoFit/autofit/non_linear/grid/grid_search.py | 2 | 0.003s | 8c7ac47f |
| command | find /PyAutoFit -name "grid_search.py" -type fexact commandfind /PyAutoFit -name "grid_search.py" -type f | 0 | 0.009s | c6b4f53b |
| command | find /PyAutoFit -path "*/grid_search*" -name "*.py" type fexact commandfind /PyAutoFit -path "*/grid_search*" -name "*.py" type f | 1 | 0.003s | b7aa05de |
| command | find /PyAutoFit -name "grid_search.py"exact commandfind /PyAutoFit -name "grid_search.py" | 0 | 0.009s | df36eaf3 |
| command | ls -la /PyAutoFit/autofit/non_linear/grid/grid_search/ 2>/dev/nullexact commandls -la /PyAutoFit/autofit/non_linear/grid/grid_search/ 2>/dev/null | 0 | 0.004s | 095feb8f |
| command | grep -n "def make_lists" /PyAutoFit/autofit/non_linear/grid/grid_search/__init__.pyexact commandgrep -n "def make_lists" /PyAutoFit/autofit/non_linear/grid/grid_search/__init__.py | 0 | 0.003s | a05b4261 |
| command | sed -n '378,430p' /PyAutoFit/autofit/non_linear/grid/grid_search/__init__.pyexact commandsed -n '378,430p' /PyAutoFit/autofit/non_linear/grid/grid_search/__init__.py | 0 | 0.003s | c5ba23e6 |
| command | sed -n '230,260p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandsed -n '230,260p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | 9ba25e65 |
| command | sed -n '244,262p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandsed -n '244,262p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | 7fdc9e70 |
| command | sed -n '244,270p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandsed -n '244,270p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | 51fda598 |
| command | sed -n '244,262p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | cat -Aexact commandsed -n '244,262p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | cat -A | 0 | 0.005s | 3eea97fb |
| command | sed -i '253s/.*/ if isinstance(self.step_size, tuple):\n half_step = tuple(\n self.limit_scale * step / 2 for step in self.step_size\n )\n else:\n half_step = self.limit_scale * self.step_size / 2/' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandsed -i '253s/.*/ if isinstance(self.step_size, tuple):\n half_step = tuple(\n self.limit_scale * step / 2 for step in self.step_size\n )\n else:\n half_step = self.limit_scale * self.step_size / 2/' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 1 | 0.003s | dcaac885 |
| command | python3 << 'EOF'
with open('/PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py', 'r') as f:
lines = f.readlines()
# Find the line with "half_step = self.limit_scale * self.step_size / 2"
# It should be around line 253 (0-indexed: 252)
for i, line in enumerate(lines):
if 'half_step = self.limit_scale * self.step_size / 2' in line:
print(f"Found at line {i+1}: {repr(line)}")
# Replace this line and the next few lines
# Original lines 253-261 (1-indexed):
# 253: half_step = self.limit_scale * self.step_size / 2
# 254: for list_ in self._lists:
# 255: limits = [
# 256: (
# 257: prior.value_for(max(0.0, centre - half_step)),
# 258: prior.value_for(min(1.0, centre + half_step)),
# 259: )
# 260: for centre, prior in zip(list_, self.perturb_model.priors_ordered_by_id)
# 261: ]
# 262: yield self.perturb_model.with_limits(limits)
new_code = ''' if isinstance(self.step_size, tuple):
half_step = tuple(
self.limit_scale * step / 2 for step in self.step_size
)
else:
half_step = self.limit_scale * self.step_size / 2
for list_ in self._lists:
limits = [
(
prior.value_for(max(0.0, centre - half_step[i])),
prior.value_for(min(1.0, centre + half_step[i])),
)
for i, (centre, prior) in enumerate(zip(list_, self.perturb_model.priors_ordered_by_id))
]
yield self.perturb_model.with_limits(limits)'''
# Replace lines 253-262 (0-indexed: 252-261)
lines[252:262] = [new_code + '\n']
break
with open('/PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py', 'w') as f:
f.writelines(lines)
print("Done!")
EOFexact commandpython3 << 'EOF'
with open('/PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py', 'r') as f:
lines = f.readlines()
# Find the line with "half_step = self.limit_scale * self.step_size / 2"
# It should be around line 253 (0-indexed: 252)
for i, line in enumerate(lines):
if 'half_step = self.limit_scale * self.step_size / 2' in line:
print(f"Found at line {i+1}: {repr(line)}")
# Replace this line and the next few lines
# Original lines 253-261 (1-indexed):
# 253: half_step = self.limit_scale * self.step_size / 2
# 254: for list_ in self._lists:
# 255: limits = [
# 256: (
# 257: prior.value_for(max(0.0, centre - half_step)),
# 258: prior.value_for(min(1.0, centre + half_step)),
# 259: )
# 260: for centre, prior in zip(list_, self.perturb_model.priors_ordered_by_id)
# 261: ]
# 262: yield self.perturb_model.with_limits(limits)
new_code = ''' if isinstance(self.step_size, tuple):
half_step = tuple(
self.limit_scale * step / 2 for step in self.step_size
)
else:
half_step = self.limit_scale * self.step_size / 2
for list_ in self._lists:
limits = [
(
prior.value_for(max(0.0, centre - half_step[i])),
prior.value_for(min(1.0, centre + half_step[i])),
)
for i, (centre, prior) in enumerate(zip(list_, self.perturb_model.priors_ordered_by_id))
]
yield self.perturb_model.with_limits(limits)'''
# Replace lines 253-262 (0-indexed: 252-261)
lines[252:262] = [new_code + '\n']
break
with open('/PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py', 'w') as f:
f.writelines(lines)
print("Done!")
EOF | 0 | 0.023s | 2b00bea4 |
| command | sed -n '250,275p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandsed -n '250,275p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | 3520a72f |
| command | sed -n '244,280p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandsed -n '244,280p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | b06bb143 |
| command | git -C /PyAutoFit checkout -- autofit/non_linear/grid/sensitivity/__init__.py 2>/dev/null || echo "Not a git repo or file not tracked"exact commandgit -C /PyAutoFit checkout -- autofit/non_linear/grid/sensitivity/__init__.py 2>/dev/null || echo "Not a git repo or file not tracked" | 0 | 0.005s | 5c4017fd |
| command | git -C /PyAutoFit status 2>&1 | head -20exact commandgit -C /PyAutoFit status 2>&1 | head -20 | 0 | 0.021s | 725c9092 |
| command | git -C /PyAutoFit log --oneline -5exact commandgit -C /PyAutoFit log --oneline -5 | 0 | 0.004s | 6f25794a |
| command | git -C /PyAutoFit restore autofit/non_linear/grid/sensitivity/__init__.pyexact commandgit -C /PyAutoFit restore autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.005s | 0e7a26b3 |
| command | sed -n '244,265p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandsed -n '244,265p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | b9420961 |
| command | python3 << 'PYEOF'
with open('/PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py', 'r') as f:
content = f.read()
# The old code to replace
old_code = ''' half_step = self.limit_scale * self.step_size / 2
for list_ in self._lists:
limits = [
(
prior.value_for(max(0.0, centre - half_step)),
prior.value_for(min(1.0, centre + half_step)),
)
for centre, prior in zip(list_, self.perturb_model.priors_ordered_by_id)
]
yield self.perturb_model.with_limits(limits)'''
# The new code
new_code = ''' if isinstance(self.step_size, tuple):
half_step = tuple(
self.limit_scale * step / 2 for step in self.step_size
)
else:
half_step = self.limit_scale * self.step_size / 2
for list_ in self._lists:
limits = [
(
prior.value_for(max(0.0, centre - half_step[i])),
prior.value_for(min(1.0, centre + half_step[i])),
)
for i, (centre, prior) in enumerate(zip(list_, self.perturb_model.priors_ordered_by_id))
]
yield self.perturb_model.with_limits(limits)'''
if old_code in content:
new_content = content.replace(old_code, new_code)
with open('/PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py', 'w') as f:
f.write(new_content)
print("Successfully replaced the code")
else:
print("Could not find the old code pattern")
# Let's debug what's actually there
idx = content.find('half_step = self.limit_scale * self.step_size / 2')
if idx != -1:
print(f"Found at index {idx}")
print(repr(content[idx:idx+200]))
PYEOFexact commandpython3 << 'PYEOF'
with open('/PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py', 'r') as f:
content = f.read()
# The old code to replace
old_code = ''' half_step = self.limit_scale * self.step_size / 2
for list_ in self._lists:
limits = [
(
prior.value_for(max(0.0, centre - half_step)),
prior.value_for(min(1.0, centre + half_step)),
)
for centre, prior in zip(list_, self.perturb_model.priors_ordered_by_id)
]
yield self.perturb_model.with_limits(limits)'''
# The new code
new_code = ''' if isinstance(self.step_size, tuple):
half_step = tuple(
self.limit_scale * step / 2 for step in self.step_size
)
else:
half_step = self.limit_scale * self.step_size / 2
for list_ in self._lists:
limits = [
(
prior.value_for(max(0.0, centre - half_step[i])),
prior.value_for(min(1.0, centre + half_step[i])),
)
for i, (centre, prior) in enumerate(zip(list_, self.perturb_model.priors_ordered_by_id))
]
yield self.perturb_model.with_limits(limits)'''
if old_code in content:
new_content = content.replace(old_code, new_code)
with open('/PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py', 'w') as f:
f.write(new_content)
print("Successfully replaced the code")
else:
print("Could not find the old code pattern")
# Let's debug what's actually there
idx = content.find('half_step = self.limit_scale * self.step_size / 2')
if idx != -1:
print(f"Found at index {idx}")
print(repr(content[idx:idx+200]))
PYEOF | 0 | 0.025s | 7300eb4b |
| command | sed -n '244,275p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandsed -n '244,275p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | 7a74891c |
| command | cd /PyAutoFit && python -m pytest test_autofit/non_linear/grid/test_sensitivity/test_functionality.py::test_models_with_tuple_steps test_autofit/non_linear/grid/test_sensitivity/test_functionality.py::test_jobs_with_tuple_steps -v 2>&1exact commandcd /PyAutoFit && python -m pytest test_autofit/non_linear/grid/test_sensitivity/test_functionality.py::test_models_with_tuple_steps test_autofit/non_linear/grid/test_sensitivity/test_functionality.py::test_jobs_with_tuple_steps -v 2>&1 | 0 | 2.530s | 8bad2cca |
| command | cd /PyAutoFit && python -m pytest test_autofit/non_linear/grid/test_sensitivity/ -v 2>&1exact commandcd /PyAutoFit && python -m pytest test_autofit/non_linear/grid/test_sensitivity/ -v 2>&1 | 1 | 2.451s | 271915dd |
| command | python3 << 'PYEOF'
with open('/PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py', 'r') as f:
content = f.read()
# The current code to replace
old_code = ''' if isinstance(self.step_size, tuple):
half_step = tuple(
self.limit_scale * step / 2 for step in self.step_size
)
else:
half_step = self.limit_scale * self.step_size / 2
for list_ in self._lists:
limits = [
(
prior.value_for(max(0.0, centre - half_step[i])),
prior.value_for(min(1.0, centre + half_step[i])),
)
for i, (centre, prior) in enumerate(zip(list_, self.perturb_model.priors_ordered_by_id))
]
yield self.perturb_model.with_limits(limits)'''
# New code that handles both cases
new_code = ''' if isinstance(self.step_size, tuple):
half_step = tuple(
self.limit_scale * step / 2 for step in self.step_size
)
else:
half_step = self.limit_scale * self.step_size / 2
for list_ in self._lists:
if isinstance(half_step, tuple):
limits = [
(
prior.value_for(max(0.0, centre - half_step[i])),
prior.value_for(min(1.0, centre + half_step[i])),
)
for i, (centre, prior) in enumerate(zip(list_, self.perturb_model.priors_ordered_by_id))
]
else:
limits = [
(
prior.value_for(max(0.0, centre - half_step)),
prior.value_for(min(1.0, centre + half_step)),
)
for centre, prior in zip(list_, self.perturb_model.priors_ordered_by_id)
]
yield self.perturb_model.with_limits(limits)'''
if old_code in content:
new_content = content.replace(old_code, new_code)
with open('/PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py', 'w') as f:
f.write(new_content)
print("Successfully replaced the code")
else:
print("Could not find the old code pattern")
PYEOFexact commandpython3 << 'PYEOF'
with open('/PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py', 'r') as f:
content = f.read()
# The current code to replace
old_code = ''' if isinstance(self.step_size, tuple):
half_step = tuple(
self.limit_scale * step / 2 for step in self.step_size
)
else:
half_step = self.limit_scale * self.step_size / 2
for list_ in self._lists:
limits = [
(
prior.value_for(max(0.0, centre - half_step[i])),
prior.value_for(min(1.0, centre + half_step[i])),
)
for i, (centre, prior) in enumerate(zip(list_, self.perturb_model.priors_ordered_by_id))
]
yield self.perturb_model.with_limits(limits)'''
# New code that handles both cases
new_code = ''' if isinstance(self.step_size, tuple):
half_step = tuple(
self.limit_scale * step / 2 for step in self.step_size
)
else:
half_step = self.limit_scale * self.step_size / 2
for list_ in self._lists:
if isinstance(half_step, tuple):
limits = [
(
prior.value_for(max(0.0, centre - half_step[i])),
prior.value_for(min(1.0, centre + half_step[i])),
)
for i, (centre, prior) in enumerate(zip(list_, self.perturb_model.priors_ordered_by_id))
]
else:
limits = [
(
prior.value_for(max(0.0, centre - half_step)),
prior.value_for(min(1.0, centre + half_step)),
)
for centre, prior in zip(list_, self.perturb_model.priors_ordered_by_id)
]
yield self.perturb_model.with_limits(limits)'''
if old_code in content:
new_content = content.replace(old_code, new_code)
with open('/PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py', 'w') as f:
f.write(new_content)
print("Successfully replaced the code")
else:
print("Could not find the old code pattern")
PYEOF | 0 | 0.023s | 0a228f7e |
| command | sed -n '244,280p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.pyexact commandsed -n '244,280p' /PyAutoFit/autofit/non_linear/grid/sensitivity/__init__.py | 0 | 0.003s | 82f40e6b |
| Kind | Command | Exit | Duration | Digest |
|---|---|---|---|---|
| command | cd /PyAutoFit && python -m pytest test_autofit/non_linear/grid/test_sensitivity/ -v 2>&1exact commandcd /PyAutoFit && python -m pytest test_autofit/non_linear/grid/test_sensitivity/ -v 2>&1 | 0 | 2.761s | 68371ed9 |
| command | cd /PyAutoFit && python -m pytest test_autofit/non_linear/grid/test_sensitivity/test_functionality.py::test_models_with_tuple_steps test_autofit/non_linear/grid/test_sensitivity/test_functionality.py::test_jobs_with_tuple_steps -v 2>&1exact commandcd /PyAutoFit && python -m pytest test_autofit/non_linear/grid/test_sensitivity/test_functionality.py::test_models_with_tuple_steps test_autofit/non_linear/grid/test_sensitivity/test_functionality.py::test_jobs_with_tuple_steps -v 2>&1 | 0 | 2.278s | 9798fd96 |
| command | cd /PyAutoFit && git diff --statexact commandcd /PyAutoFit && git diff --stat | 0 | 0.011s | 88511e78 |
| diff | capture patchexact commandcompute patch in executor staging agent1-8ba1646cd7134af4a49867a107dea542: /opt/homebrew/Cellar/git/2.53.0/bin/git -c core.hooksPath=/dev/null -c core.attributesFile=/dev/null -c diff.external= -c core.quotePath=false add -A && /opt/homebrew/Cellar/git/2.53.0/bin/git -c core.hooksPath=/dev/null -c core.attributesFile=/dev/null -c diff.external= -c core.quotePath=false diff --cached --binary --no-ext-diff --no-textconv --no-renames d564f29a393b75747f1ec3da7c51070d2e12cda1 | 0 | 0.168s | 1459c61ea27c |
- Finish summary
- Fixed the bug where sensitivity mapping no longer supports tuple step_size. The issue was in the `_perturb_models` property of the `Sensitivity` class which failed with `TypeError: unsupported operand type(s) for /: 'tuple' and 'int'` when `number_of_steps` was specified as a tuple (e.g., `(4, 3, 2)`). The fix modifies the `_perturb_models` property to handle both cases: 1. When `step_size` is a tuple: computes `half_step` as a tuple with one value per dimension 2. When `step_size` is a float: uses the original behavior with a single `half_step` value All 18 sensitivity tests pass, including the two target tests `test_models_with_tuple_steps` and `test_jobs_with_tuple_steps`.
- Worker outcome
- finished
- Target tests pass: yes
- Full suite passes: yes
- Files changed: autofit/non_linear/grid/sensitivity/__init__.py
- Ran tests: yes
Witness branch w1
| Kind | Command | Exit | Duration | Digest |
|---|---|---|---|---|
| apply | apply patch 8cb6aa53dc45exact commandgit update-index -q --refresh; git apply -v --3way --recount --ignore-space-change --whitespace=nowarn /opt/receipts-63dec0c50b47409cb0a4d48c63d9df94/incoming/8cb6aa53dc452db2b185d041f98790c0570a38ff8a1cdff674a82e2209791a25.diff | 0 | 0.013s | 423eb456501f |
| verification | pytest (witness) test_autofit/non_linear/grid/test_sensitivity/test_functionality.pyexact command/opt/receipts-f96a81a4ec4749a2857e93ecbb04c8ed/bin/busybox mkdir -p /opt/receipts/reports && python -I /opt/receipts-f96a81a4ec4749a2857e93ecbb04c8ed/receipts_pytest.py --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning test_autofit/non_linear/grid/test_sensitivity/test_functionality.py -o junit_family=xunit1 -p no:cacheprovider -rA --continue-on-collection-errors --junitxml=/opt/receipts/reports/w1-2.xml | 0 | 4.453s | 423eb456501f |
Gate predicate checklist
| Predicate | Name | Status | Evidence |
|---|---|---|---|
R1_fail_to_pass | Failing specification tests now pass | PASS | target tests passed: test_autofit/non_linear/grid/test_sensitivity/test_functionality.py::test_models_with_tuple_steps, test_autofit/non_linear/grid/test_sensitivity/test_functionality.py::test_jobs_with_tuple_steps |
R2_pass_to_pass | Previously passing tests kept | PASS | 12 baseline-passing tests still pass |
R3_no_shrink | No removed tests or new skips | PASS | all 14 baseline tests collected; skips unchanged (0) |
R4_patch_scope | Patch scope | PASS | patch touches 1 file(s), all in scope |
R5_provenance | Witness chain and patch digest | PASS | agent chain 72a58fe1 -> 88511e78 unbroken over 49 receipt(s); witness chain 72a58fe1 -> a4dcc2c4 unbroken over 2 receipt(s); applied digest matches |
R6_claim_audit | Agent claim audit (advisory) | FAIL | claimed green but never ran the tests on this branch |
What it said
- Finish summary
- Fixed the bug where sensitivity mapping no longer supports tuple step_size. The issue was in the `_perturb_models` property of the `Sensitivity` class which failed with `TypeError: unsupported operand type(s) for /: 'tuple' and 'int'` when `number_of_steps` was specified as a tuple (e.g., `(4, 3, 2)`). The fix modifies the `_perturb_models` property to handle both cases: 1. When `step_size` is a tuple: computes `half_step` as a tuple with one value per dimension 2. When `step_size` is a float: uses the original behavior with a single `half_step` value All 18 sensitivity tests pass, including the two target tests `test_models_with_tuple_steps` and `test_jobs_with_tuple_steps`.
- Worker outcome
- finished
- Target tests pass: yes
- Full suite passes: yes
- Files changed: autofit/non_linear/grid/sensitivity/__init__.py
- Ran tests: yes
What the record shows
unsupported: claimed green but never ran the tests on this branch
SWE-rebench's official grader: resolved
Agrees with the gate
Shipped patch
diff --git a/autofit/non_linear/grid/sensitivity/__init__.py b/autofit/non_linear/grid/sensitivity/__init__.pyindex fa19768c..01d20592 100644--- a/autofit/non_linear/grid/sensitivity/__init__.py+++ b/autofit/non_linear/grid/sensitivity/__init__.py@@ -1,301 +1,315 @@-import csv-import logging-import os-from copy import copy-from pathlib import Path-from typing import List, Generator, Callable, ClassVar, Optional, Union, Tuple--from autoconf.dictable import to_dict-from autofit.mapper.model import ModelInstance-from autofit.mapper.prior_model.abstract import AbstractPriorModel-from autofit.non_linear.grid.grid_search import make_lists, Sequential-from autofit.non_linear.grid.sensitivity.job import Job-from autofit.non_linear.grid.sensitivity.job import JobResult-from autofit.non_linear.grid.sensitivity.result import SensitivityResult-from autofit.non_linear.parallel import Process-from autofit.text.text_util import padding--class Sensitivity:- def __init__(- self,- base_model: AbstractPriorModel,- perturb_model: AbstractPriorModel,- simulation_instance,- paths,- simulate_cls: Callable,- base_fit_cls: Callable,- perturb_fit_cls: Callable,- job_cls: ClassVar = Job,- perturb_model_prior_func : Optional[Callable] = None,- number_of_steps: Union[Tuple[int, ...], int] = 4,- number_of_cores: int = 2,- limit_scale: int = 1,- ):- """- Perform sensitivity mapping to evaluate whether a perturbation- can be detected if it occurs in different parts of an image.-- For a range from 0 to 1 with step_size, for each dimension of the- perturb_model, a perturbation is created and used in conjunction- with the instance to create an image.-- For each of these images, a fit is run with just the model and with both- the model and perturb_model to compare how much better the image- can be fit if the perturbation is included.-- Parameters- ----------- base_model- A model that fits the instance well- perturb_model- A model which provides a perturbations to be applied to the instance- before creating images- simulation_instance- An instance of a model to which perturbations are applied prior to- images being generated- simulate_cls- A class which simulates images from each perturb instance that sensitivity mapping is performed on.- base_fit_cls- The class which fits the base model to each simulated dataset of the sensitivity map.- perturb_fit_cls- The class which fits the perturb model to each simulated dataset of the sensitivity map.- number_of_steps- The number of steps for each dimension of the sensitivity grid. If input as a float the dimensions are- all that value. If input as a tuple of length the number of dimensions, each tuple value is the number of- steps in that dimension.- number_of_cores- How many cores does this computer have?- limit_scale- Scales the priors for each perturbation model.- A scale of 1 means priors have limits the same size as the grid square.- A scale of 2 means priors have limits larger than the grid square with- width twice a grid square.- A scale of 0.5 means priors have limits smaller than the grid square- with width half a grid square.- """- self.logger = logging.getLogger(f"Sensitivity ({paths.name})")-- self.logger.info("Creating")-- self.instance = simulation_instance- self.model = base_model- self.perturb_model = perturb_model-- self.paths = paths-- self.simulate_cls = simulate_cls- self.base_fit_cls = base_fit_cls- self.perturb_fit_cls = perturb_fit_cls-- self.perturb_model_prior_func = perturb_model_prior_func-- self.job_cls = job_cls-- self.number_of_steps = number_of_steps- self.number_of_cores = number_of_cores-- self.limit_scale = limit_scale-- def run(self) -> SensitivityResult:- """- Run fits and comparisons for all perturbations, returning- a list of results.- """- self.logger.info("Running")-- self.paths.save_unique_tag(is_grid_search=True)-- headers = [- "index",- *self._headers,- "log_evidence_increase",- "log_likelihood_increase",- ]- physical_values = list(self._physical_values)-- process_class = Process if self.number_of_cores > 1 else Sequential-- results = list()- for result in process_class.run_jobs(- self._make_jobs(), number_of_cores=self.number_of_cores- ):- if isinstance(result, Exception):- raise result-- results.append(result)- results = sorted(results)-- os.makedirs(self.paths.output_path, exist_ok=True)- with open(self.results_path, "w+") as f:- writer = csv.writer(f)- writer.writerow(headers)- for result_ in results:-- values = physical_values[result_.number]- writer.writerow(- padding(item)- for item in [- result_.number,- *values,- result_.log_evidence_increase,- result_.log_likelihood_increase,- ]- )-- result = SensitivityResult(- samples=[result.result.samples.summary() for result in results],- perturb_samples=[result.perturb_result.samples.summary() for result in results],- shape=self.shape- )-- self.paths.save_json("result", to_dict(result))-- return result-- @property- def shape(self) -> Tuple[int, ...]:- """- Returns the shape of the sensitivity grid.-- The shape is the number of steps performed for each dimension of the `perturb_model`. If sensitivity mapping- is performed in 3D, the shape will therefore be a tuple of length 3.-- The `shape` can vary across dimensions if the `number_of_steps` parameter is input as a tuple.-- Returns- -------- The shape of the sensitivity grid.- """-- if isinstance(self.number_of_steps, tuple):- return self.number_of_steps-- return tuple(self.number_of_steps for _ in range(self.perturb_model.prior_count))-- @property- def step_size(self) -> Union[float, Tuple]:- """- Returns- -------- step_size- The size of a step in any given dimension in hyper space.- """- if isinstance(self.number_of_steps, tuple):- return tuple(1 / number_of_steps for number_of_steps in self.number_of_steps)- return 1 / self.number_of_steps-- @property- def results_path(self) -> Path:- return self.paths.output_path / "results.csv"-- @property- def _lists(self) -> List[List[float]]:- """- A list of hypercube vectors, used to instantiate- the perturb_model and create the individual- perturbations.- """- return make_lists(self.perturb_model.prior_count, step_size=self.step_size)-- @property- def _physical_values(self) -> List[List[float]]:- """- Lists of physical values for each grid square- """- return [- [- prior.value_for(unit_value)- for prior, unit_value in zip(- self.perturb_model.priors_ordered_by_id, unit_values- )- ]- for unit_values in self._lists- ]-- @property- def _headers(self) -> Generator[str, None, None]:- """- A name for each of the perturb priors- """- for path, _ in self.perturb_model.prior_tuples:- yield path-- @property- def _labels(self) -> Generator[str, None, None]:- """- One label for each perturbation, used to distinguish- fits for each perturbation by placing them in separate- directories.- """- for list_ in self._lists:- strings = list()- for value, prior_tuple in zip(list_, self.perturb_model.prior_tuples):- path, prior = prior_tuple- value = prior.value_for(value)- strings.append(f"{path}_{value}")- yield "_".join(strings)-- @property- def _perturb_instances(self) -> Generator[ModelInstance, None, None]:- """- A list of instances each of which defines a perturbation to- be applied to the image.- """- for list_ in self._lists:- yield self.perturb_model.instance_from_unit_vector(list_)-- @property- def _perturb_models(self) -> Generator[AbstractPriorModel, None, None]:- """- A list of models representing a perturbation at each grid square.-- By default models have priors with limits at the edges of a grid square.- These limits can be scaled using the limit_scale variable. If the variable- is 2 then the priors will have width twice the step size.- """- half_step = self.limit_scale * self.step_size / 2- for list_ in self._lists:- limits = [- (- prior.value_for(max(0.0, centre - half_step)),- prior.value_for(min(1.0, centre + half_step)),- )- for centre, prior in zip(list_, self.perturb_model.priors_ordered_by_id)- ]- yield self.perturb_model.with_limits(limits)-- def _make_jobs(self) -> Generator[Job, None, None]:- """- Create a list of jobs to be run on separate processes.-- Each job fits a perturb image with the original model- and a model which includes a perturbation.- """- for number, (perturb_instance, perturb_model, label) in enumerate(- zip(self._perturb_instances, self._perturb_models, self._labels)- ):-- if self.perturb_model_prior_func is not None:- perturb_model = self.perturb_model_prior_func(- perturb_instance=perturb_instance,- perturb_model=perturb_model- )-- simulate_instance = copy(self.instance)- simulate_instance.perturb = perturb_instance-- paths = self.paths.for_sub_analysis(- label,- )-- yield self.job_cls(- simulate_instance=simulate_instance,- model=self.model,- perturb_model=perturb_model,- base_instance=self.instance,- simulate_cls=self.simulate_cls,- base_fit_cls=self.base_fit_cls,- perturb_fit_cls=self.perturb_fit_cls,- paths=paths,- number=number,+import csv+import logging+import os+from copy import copy+from pathlib import Path+from typing import List, Generator, Callable, ClassVar, Optional, Union, Tuple++from autoconf.dictable import to_dict+from autofit.mapper.model import ModelInstance+from autofit.mapper.prior_model.abstract import AbstractPriorModel+from autofit.non_linear.grid.grid_search import make_lists, Sequential+from autofit.non_linear.grid.sensitivity.job import Job+from autofit.non_linear.grid.sensitivity.job import JobResult+from autofit.non_linear.grid.sensitivity.result import SensitivityResult+from autofit.non_linear.parallel import Process+from autofit.text.text_util import padding++class Sensitivity:+ def __init__(+ self,+ base_model: AbstractPriorModel,+ perturb_model: AbstractPriorModel,+ simulation_instance,+ paths,+ simulate_cls: Callable,+ base_fit_cls: Callable,+ perturb_fit_cls: Callable,+ job_cls: ClassVar = Job,+ perturb_model_prior_func : Optional[Callable] = None,+ number_of_steps: Union[Tuple[int, ...], int] = 4,+ number_of_cores: int = 2,+ limit_scale: int = 1,+ ):+ """+ Perform sensitivity mapping to evaluate whether a perturbation+ can be detected if it occurs in different parts of an image.++ For a range from 0 to 1 with step_size, for each dimension of the+ perturb_model, a perturbation is created and used in conjunction+ with the instance to create an image.++ For each of these images, a fit is run with just the model and with both+ the model and perturb_model to compare how much better the image+ can be fit if the perturbation is included.++ Parameters+ ----------+ base_model+ A model that fits the instance well+ perturb_model+ A model which provides a perturbations to be applied to the instance+ before creating images+ simulation_instance+ An instance of a model to which perturbations are applied prior to+ images being generated+ simulate_cls+ A class which simulates images from each perturb instance that sensitivity mapping is performed on.+ base_fit_cls+ The class which fits the base model to each simulated dataset of the sensitivity map.+ perturb_fit_cls+ The class which fits the perturb model to each simulated dataset of the sensitivity map.+ number_of_steps+ The number of steps for each dimension of the sensitivity grid. If input as a float the dimensions are+ all that value. If input as a tuple of length the number of dimensions, each tuple value is the number of+ steps in that dimension.+ number_of_cores+ How many cores does this computer have?+ limit_scale+ Scales the priors for each perturbation model.+ A scale of 1 means priors have limits the same size as the grid square.+ A scale of 2 means priors have limits larger than the grid square with+ width twice a grid square.+ A scale of 0.5 means priors have limits smaller than the grid square+ with width half a grid square.+ """+ self.logger = logging.getLogger(f"Sensitivity ({paths.name})")++ self.logger.info("Creating")++ self.instance = simulation_instance+ self.model = base_model+ self.perturb_model = perturb_model++ self.paths = paths++ self.simulate_cls = simulate_cls+ self.base_fit_cls = base_fit_cls+ self.perturb_fit_cls = perturb_fit_cls++ self.perturb_model_prior_func = perturb_model_prior_func++ self.job_cls = job_cls++ self.number_of_steps = number_of_steps+ self.number_of_cores = number_of_cores++ self.limit_scale = limit_scale++ def run(self) -> SensitivityResult:+ """+ Run fits and comparisons for all perturbations, returning+ a list of results.+ """+ self.logger.info("Running")++ self.paths.save_unique_tag(is_grid_search=True)++ headers = [+ "index",+ *self._headers,+ "log_evidence_increase",+ "log_likelihood_increase",+ ]+ physical_values = list(self._physical_values)++ process_class = Process if self.number_of_cores > 1 else Sequential++ results = list()+ for result in process_class.run_jobs(+ self._make_jobs(), number_of_cores=self.number_of_cores+ ):+ if isinstance(result, Exception):+ raise result++ results.append(result)+ results = sorted(results)++ os.makedirs(self.paths.output_path, exist_ok=True)+ with open(self.results_path, "w+") as f:+ writer = csv.writer(f)+ writer.writerow(headers)+ for result_ in results:++ values = physical_values[result_.number]+ writer.writerow(+ padding(item)+ for item in [+ result_.number,+ *values,+ result_.log_evidence_increase,+ result_.log_likelihood_increase,+ ]+ )++ result = SensitivityResult(+ samples=[result.result.samples.summary() for result in results],+ perturb_samples=[result.perturb_result.samples.summary() for result in results],+ shape=self.shape+ )++ self.paths.save_json("result", to_dict(result))++ return result++ @property+ def shape(self) -> Tuple[int, ...]:+ """+ Returns the shape of the sensitivity grid.++ The shape is the number of steps performed for each dimension of the `perturb_model`. If sensitivity mapping+ is performed in 3D, the shape will therefore be a tuple of length 3.++ The `shape` can vary across dimensions if the `number_of_steps` parameter is input as a tuple.++ Returns+ -------+ The shape of the sensitivity grid.+ """++ if isinstance(self.number_of_steps, tuple):+ return self.number_of_steps++ return tuple(self.number_of_steps for _ in range(self.perturb_model.prior_count))++ @property+ def step_size(self) -> Union[float, Tuple]:+ """+ Returns+ -------+ step_size+ The size of a step in any given dimension in hyper space.+ """+ if isinstance(self.number_of_steps, tuple):+ return tuple(1 / number_of_steps for number_of_steps in self.number_of_steps)+ return 1 / self.number_of_steps++ @property+ def results_path(self) -> Path:+ return self.paths.output_path / "results.csv"++ @property+ def _lists(self) -> List[List[float]]:+ """+ A list of hypercube vectors, used to instantiate+ the perturb_model and create the individual+ perturbations.+ """+ return make_lists(self.perturb_model.prior_count, step_size=self.step_size)++ @property+ def _physical_values(self) -> List[List[float]]:+ """+ Lists of physical values for each grid square+ """+ return [+ [+ prior.value_for(unit_value)+ for prior, unit_value in zip(+ self.perturb_model.priors_ordered_by_id, unit_values+ )+ ]+ for unit_values in self._lists+ ]++ @property+ def _headers(self) -> Generator[str, None, None]:+ """+ A name for each of the perturb priors+ """+ for path, _ in self.perturb_model.prior_tuples:+ yield path++ @property+ def _labels(self) -> Generator[str, None, None]:+ """+ One label for each perturbation, used to distinguish+ fits for each perturbation by placing them in separate+ directories.+ """+ for list_ in self._lists:+ strings = list()+ for value, prior_tuple in zip(list_, self.perturb_model.prior_tuples):+ path, prior = prior_tuple+ value = prior.value_for(value)+ strings.append(f"{path}_{value}")+ yield "_".join(strings)++ @property+ def _perturb_instances(self) -> Generator[ModelInstance, None, None]:+ """+ A list of instances each of which defines a perturbation to+ be applied to the image.+ """+ for list_ in self._lists:+ yield self.perturb_model.instance_from_unit_vector(list_)++ @property+ def _perturb_models(self) -> Generator[AbstractPriorModel, None, None]:+ """+ A list of models representing a perturbation at each grid square.++ By default models have priors with limits at the edges of a grid square.+ These limits can be scaled using the limit_scale variable. If the variable+ is 2 then the priors will have width twice the step size.+ """+ if isinstance(self.step_size, tuple):+ half_step = tuple(+ self.limit_scale * step / 2 for step in self.step_size+ )+ else:+ half_step = self.limit_scale * self.step_size / 2+ for list_ in self._lists:+ if isinstance(half_step, tuple):+ limits = [+ (+ prior.value_for(max(0.0, centre - half_step[i])),+ prior.value_for(min(1.0, centre + half_step[i])),+ )+ for i, (centre, prior) in enumerate(zip(list_, self.perturb_model.priors_ordered_by_id))+ ]+ else:+ limits = [+ (+ prior.value_for(max(0.0, centre - half_step)),+ prior.value_for(min(1.0, centre + half_step)),+ )+ for centre, prior in zip(list_, self.perturb_model.priors_ordered_by_id)+ ]+ yield self.perturb_model.with_limits(limits)++ def _make_jobs(self) -> Generator[Job, None, None]:+ """+ Create a list of jobs to be run on separate processes.++ Each job fits a perturb image with the original model+ and a model which includes a perturbation.+ """+ for number, (perturb_instance, perturb_model, label) in enumerate(+ zip(self._perturb_instances, self._perturb_models, self._labels)+ ):++ if self.perturb_model_prior_func is not None:+ perturb_model = self.perturb_model_prior_func(+ perturb_instance=perturb_instance,+ perturb_model=perturb_model+ )++ simulate_instance = copy(self.instance)+ simulate_instance.perturb = perturb_instance++ paths = self.paths.for_sub_analysis(+ label,+ )++ yield self.job_cls(+ simulate_instance=simulate_instance,+ model=self.model,+ perturb_model=perturb_model,+ base_instance=self.instance,+ simulate_cls=self.simulate_cls,+ base_fit_cls=self.base_fit_cls,+ perturb_fit_cls=self.perturb_fit_cls,+ paths=paths,+ number=number, )\ No newline at end of file
Model and costs
- Model
- nvidia/Nemotron-3_5-Lightning thinking off · temperature 1.0 · top_p 0.95
- Tokens
- 565,974 tokens
- Model cost
- $0.04
- Sandbox time
- 2 min 36 s
- Sandbox cost
- Token Factory reported cost: 0.280 (unit not published)
Full environment disclosure
{
"executor_kind": "tokenfactory",
"lock_sha256": "7eee3248ca81b3098f6a555415bbc33c53453d2a8c2136edb953ff27a7ab3f4e",
"model": {
"base_url": "https://api.tokenfactory.nebius.com/v1/",
"client": "TokenFactoryClient",
"max_tokens": null,
"model": "nvidia/Nemotron-3_5-Lightning",
"temperature": 1.0,
"thinking": false,
"top_p": 0.95
},
"pytest_config_digests": {
"setup.cfg": "9b66264f6dfdb9b8d5e467a673e97ae8923126df6845976f1317ca89fd45ff3d",
"test_autofit/aggregator/conftest.py": "ba0806ea5d339eab14b86d0e7875e21edc33d17b057f2de2b6f46aa2e9b88081",
"test_autofit/analysis/conftest.py": "95712a522b3a8ce017bbb13fffe6937c788314cb51159fcc3e4acbc11a5d9708",
"test_autofit/conftest.py": "a6a3c2e6f4abad383a10259bfe95a3ebc56f27e0c5357f4c5cf59a8501a26491",
"test_autofit/database/conftest.py": "e2873b4d62eda9a8703735913c5ca7254ea42544ef38111399b40205b49046db",
"test_autofit/database/migration/conftest.py": "fc9a54c6c798411f35e6d8016b5164a4006521a17939f30e9007d3353323fb54",
"test_autofit/database/paths/conftest.py": "7f4875d5bc29d5f3e9ecfbfb0901988c499b9773b0cf05254752d824703a5303",
"test_autofit/database/query/internal/conftest.py": "2d3fa1ba12240e395ea4388c77f7cce09aa6bf4a365ece914419ada5f59895a2",
"test_autofit/database/query/query/conftest.py": "1288798fe779fc8a1146d721e30a1ce285459cdc4215f8b1be0bb40e72700e15",
"test_autofit/graphical/conftest.py": "c849c96fd580a1389dd7949470b45e94ab0182b4cdac42230545dd7e109e734b",
"test_autofit/graphical/gaussian/conftest.py": "1fdf23173ad6888bd93e78442c0eb19d25a0eabe7d7ba26eccdbafa2a316a0fa",
"test_autofit/graphical/global/conftest.py": "2750a96c2744ee9c36aecaff4b725f32d988abf07435a3be1b0c8d447b698f5e",
"test_autofit/graphical/hierarchical/conftest.py": "66960dc7d6b2a4d59c6d4214bd9d13ea6c553969cb65330c8cca089bc694e544",
"test_autofit/graphical/info/conftest.py": "2affc805c5024beebd2c6987bfe6f7c16f294e467f669c270fb34acd07ca705c",
"test_autofit/graphical/regression/conftest.py": "1eb70568b1b75cb4821a6f2a2fb0dcb176affbeeccc85496486e25a72a49c216",
"test_autofit/interpolator/conftest.py": "31aec003629b7141e56e2a85a86a8e79971e0fd49eeab751710e48eed00ef375",
"test_autofit/mapper/conftest.py": "b3c4eb4206df9b624b456d04ed01c3efbaa2040d0283d630e7c2ef6cbdf1125e",
"test_autofit/mapper/model/serialise/conftest.py": "29fc7cf4c507bf4fb1142e73a8ad30adceb258f39c977d685798d42ff78f8e24",
"test_autofit/mapper/with_paths/conftest.py": "6b8355134c4d86a4eb6e18cc4aa08076c8c5b38f19406ecd6f7ed3ebf8452ab0",
"test_autofit/non_linear/grid/conftest.py": "a58386eed88b836f1c5f94fe67c728e29f508fd2b991fd6d3dcd174ae2d129d2",
"test_autofit/non_linear/grid/test_paths/conftest.py": "09d34f250e131390f01086d8481cf2bcccac3a5943c1093f145eb7621ce99210",
"test_autofit/non_linear/grid/test_sensitivity/conftest.py": "61fe1b94ec19a728a05d8e07e082ccad1da56f5568489bcf3038501e207d4c8f",
"test_autofit/serialise/conftest.py": "c690179a6be4fadc1d1c329050234c657e40c5a80c43778e1157c1095b6173a4"
},
"receipts_version": "0.0.1",
"test_digests": {
"test_autofit/non_linear/grid/test_sensitivity/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"test_autofit/non_linear/grid/test_sensitivity/conftest.py": "61fe1b94ec19a728a05d8e07e082ccad1da56f5568489bcf3038501e207d4c8f",
"test_autofit/non_linear/grid/test_sensitivity/test_functionality.py": "b5d035262907de4fc40e43f16e5136ec7f897602d4725fdbd0bcf4fedcf58b7b",
"test_autofit/non_linear/grid/test_sensitivity/test_results.py": "8bb90a64b8c259f680b4516d2a964ba90d8f3eb5194fc257f695f80329081118",
"test_autofit/non_linear/grid/test_sensitivity/test_run.py": "0828e32a026962aeb8c78c2a3d345256efb3217abca9c24016495ca1ee363901"
}
}The bundle
Recorded JSON and patches. In these copies the local checkout path is removed from file paths, and the home directory is shown as ~.
- attempts/1/filtered.diff
- attempts/1/patch.diff
- attempts/1/verdict.json
- attempts/1/witness/receipts.jsonl
- baseline.json
- branches/agent1/receipts.jsonl
- branches/base/receipts.jsonl
- branches/official1/receipts.jsonl
- branches/w1/receipts.jsonl
- cost.json
- disclosure.json
- input.json
- lock.txt
- plan.json
- record.json
- result.json