Skip to content
Open
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
12 changes: 12 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,15 @@ This project follows the [Conventional Commits](https://www.conventionalcommits.
- The `config.toml` in the repo root is the working config file; `rai-config-init` is only for pip-installed users, not developers using the repo.
- The Streamlit configurator (`rai/frontend/configurator.py`) is an optional GUI; all configuration can be done by editing `config.toml` directly.
- Many test modules import ROS 2 packages (`rclpy`, `geometry_msgs`, etc.) at module level, so ROS 2 must be sourced even to collect tests.

## Fresh clone / correct worktree (PERMANENT — Daniel 2026-07-28)

Before PR audit, main-comparison greps, salvage, rebase, or Cursor coding on this repo:

1. `git remote -v` + `git rev-parse --show-toplevel` must match the intended `org/repo` (this Bartok9 repo or the upstream you are patching).
2. Prefer a disposable clone for read-only “still needed on main?” audits: `/tmp/<repo>-review-$$` via `gh repo clone … -- --depth=1`.
3. Existing clones OK only after fetch + correct branch tip; confirm PR-touched paths exist.
4. Wrong tree once → **re-clone**. Do not keep grepping a foreign or polluted worktree (openpi 2026-07-28).
5. Never `git reset --hard` on shared/production worktrees; delete disposable `/tmp` clones instead.
6. Full law: skill `upstream-pr-engineering` **§27** · clawd `AGENTS.md`.

Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,21 @@ def __init__(
Defaults to 0.02.
"""
super().__init__(logger)
if not isinstance(obj_type, str) or not obj_type.strip():
raise ValueError("obj_type must be a non-empty string")
if (
not isinstance(target_position, tuple)
or len(target_position) != 2
or not all(isinstance(v, (int, float)) and math.isfinite(float(v)) for v in target_position)
):
raise ValueError("target_position must be a pair of finite numbers")
if not isinstance(allowable_displacement, (int, float)) or not math.isfinite(float(allowable_displacement)):
raise ValueError("allowable_displacement must be a finite number")
if float(allowable_displacement) <= 0:
raise ValueError("allowable_displacement must be positive")
self.obj_type = obj_type
self.target_position = target_position
self.allowable_displacement = allowable_displacement
self.target_position = (float(target_position[0]), float(target_position[1]))
self.allowable_displacement = float(allowable_displacement)

@property
def task_prompt(self) -> str:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,23 @@ def test_calculate_multiple_objects_none_correct() -> None:
correct, incorrect = task.calculate_correct([e1, e2])
assert correct == 0
assert incorrect == 1

import math
import pytest


def test_reject_non_positive_allowable_displacement() -> None:
with pytest.raises(ValueError):
PlaceObjectAtCoordTask("carrot", (0.5, 0.5), allowable_displacement=0.0)
with pytest.raises(ValueError):
PlaceObjectAtCoordTask("carrot", (0.5, 0.5), allowable_displacement=-0.01)


def test_reject_empty_obj_type() -> None:
with pytest.raises(ValueError):
PlaceObjectAtCoordTask("", (0.5, 0.5))


def test_reject_non_finite_target() -> None:
with pytest.raises(ValueError):
PlaceObjectAtCoordTask("carrot", (math.nan, 0.5))
Loading