General-purpose coding policy for Baruch's AI agents
74
93%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Medium
Suggest reviewing before use
"""The state and config homes move from teamlead to foreman (#501)."""
import fcntl
import io
import json
import re
import sys
import tempfile
import unittest
from unittest import mock
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from foreman import home, retrospective, runnable
from foreman.cli import main
from foreman.errors import StateError, UsageError
class HomeCase(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.TemporaryDirectory()
self.addCleanup(self.tmp.cleanup)
root = Path(self.tmp.name).resolve()
self.state_root, self.config_root = root / "state", root / "config"
self.state_root.mkdir()
self.config_root.mkdir()
self.env = {"XDG_STATE_HOME": str(self.state_root), "XDG_CONFIG_HOME": str(self.config_root)}
def legacy_home(self):
"""A legacy home whose stores name their canonical state path, and whose history quotes it."""
old = self.state_root / "teamlead"
(old / "state.json.memory").mkdir(parents=True)
(old / "supervision-bindings").mkdir()
old_state = str(old / "state.json")
(old / "state.json").write_text(json.dumps({"schema_version": 13, "assignments": []}))
(old / "state.json.lock").write_text("")
(old / "state.json.attention.json").write_text(json.dumps({
"schema_version": 1, "state_path": old_state,
"events": [{"data": {"evidence": {"ref": "teamlead measure --state " + old_state}}}]}))
(old / "state.json.memory" / "index.json").write_text(json.dumps({
"schema_version": 3, "state_path": old_state,
"records": [{"required_reads": [{"path": old_state}]}]}))
(old / "supervision-bindings" / "abc.json").write_text(json.dumps({"state_path": old_state}))
(old / "state.json.supervision.json").write_text(json.dumps({
"state_path": old_state, "binding": {"state_path": old_state}}))
(self.config_root / "teamlead").mkdir()
(self.config_root / "teamlead" / "config.json").write_text('{"schema_version": 4}')
return old_state
def read(self, *parts):
return json.loads((self.state_root / "foreman").joinpath(*parts).read_text())
class MigrateTest(HomeCase):
def retrospective_record(self, old_state):
old_home = self.state_root / "teamlead"
draft = old_home / "draft.md"
source = old_home / "source.md"
check = old_home / "check.json"
draft.write_text("# Retrospective\n" + "".join(
"\n## {}\nRecorded outcome and next action.\n".format(section)
for section in retrospective.SECTIONS), encoding="utf-8")
source.write_text("Saved task evidence.\n", encoding="utf-8")
check.write_text("{}\n", encoding="utf-8")
data = {"id": "retro-1", "note": str(draft),
"period_start": "2026-09-01T10:00:00Z", "period_end": "2026-09-01T11:00:00Z",
"triggers": ["daily"], "tasks": ["owner/repo#1"], "participants": ["worker"],
"unavailable": {}, "sources": [str(source)], "completed": True, "check": str(check)}
return data
def test_moves_both_homes_and_rewrites_only_identity_fields(self):
old_state = self.legacy_home()
new_state = str(self.state_root / "foreman" / "state.json")
result = home.migrate(self.env)
self.assertEqual([row["moved"] for row in result["homes"]], [True, True])
for parts in (("state.json.attention.json",), ("state.json.memory", "index.json"),
("supervision-bindings", "abc.json")):
with self.subTest(parts=parts):
self.assertEqual(self.read(*parts)["state_path"], new_state)
supervision = self.read("state.json.supervision.json")
self.assertEqual((supervision["state_path"], supervision["binding"]["state_path"]), (new_state, new_state))
# History that quotes the old path is not rewritten, and still resolves through the link.
self.assertIn(old_state, json.dumps(self.read("state.json.attention.json")["events"]))
self.assertEqual(self.read("state.json.memory", "index.json")["records"][0]["required_reads"][0]["path"], old_state)
self.assertTrue(Path(old_state).is_file())
self.assertTrue((self.state_root / "teamlead").is_symlink())
self.assertEqual((self.config_root / "foreman" / "config.json").read_text(), '{"schema_version": 4}')
def test_a_second_run_changes_nothing(self):
self.legacy_home()
home.migrate(self.env)
before = sorted((path, path.read_bytes()) for path in (self.state_root / "foreman").rglob("*.json"))
again = home.migrate(self.env)
self.assertEqual([row["moved"] for row in again["homes"]], [False, False])
self.assertEqual(sorted((path, path.read_bytes()) for path in (self.state_root / "foreman").rglob("*.json")), before)
def test_committed_retrospective_journal_replays_after_migration(self):
old_state = self.legacy_home()
data = self.retrospective_record(old_state)
original_unlink = Path.unlink
def fail_pending(path, *args, **kwargs):
if path.name == "pending.json":
raise OSError("injected cleanup failure")
return original_unlink(path, *args, **kwargs)
with mock.patch.object(Path, "unlink", fail_pending):
with self.assertRaisesRegex(StateError, "reconcile"):
with retrospective.lock(old_state):
retrospective.record(old_state, data, [], "2026-09-01T12:00:00Z")
home.migrate(self.env)
new_state = self.state_root / "foreman" / "state.json"
with retrospective.lock(new_state):
replay = retrospective.record(new_state, data, [], "2026-09-01T13:00:00Z")
self.assertTrue(replay["replayed"])
self.assertIn("/teamlead/", replay["note"]["path"])
self.assertFalse((retrospective.directory(new_state) / "pending.json").exists())
def test_uncommitted_retrospective_journal_resumes_after_migration(self):
old_state = self.legacy_home()
data = self.retrospective_record(old_state)
with mock.patch.object(retrospective, "_install_note", side_effect=StateError("injected install failure", {})):
with self.assertRaisesRegex(StateError, "injected install failure"):
with retrospective.lock(old_state):
retrospective.record(old_state, data, [], "2026-09-01T12:00:00Z")
home.migrate(self.env)
new_state = self.state_root / "foreman" / "state.json"
with retrospective.lock(new_state):
saved = retrospective.record(new_state, data, [], "2026-09-01T13:00:00Z")
self.assertFalse(saved["replayed"])
self.assertIn("/teamlead/", saved["note"]["path"])
self.assertEqual(retrospective.show(new_state)["record"]["id"], "retro-1")
def test_pending_rebase_survives_failure_before_index_rewrite(self):
old_state = self.legacy_home()
data = self.retrospective_record(old_state)
original_unlink = Path.unlink
def fail_pending(path, *args, **kwargs):
if path.name == "pending.json":
raise OSError("injected cleanup failure")
return original_unlink(path, *args, **kwargs)
with mock.patch.object(Path, "unlink", fail_pending):
with self.assertRaisesRegex(StateError, "reconcile"):
with retrospective.lock(old_state):
retrospective.record(old_state, data, [], "2026-09-01T12:00:00Z")
real_save = home.save_state
def fail_index(path, value):
if path.name == "index.json" and path.parent.name.endswith(".retrospectives"):
raise StateError("injected index rewrite failure", {})
return real_save(path, value)
with mock.patch.object(home, "save_state", side_effect=fail_index):
with self.assertRaisesRegex(StateError, "injected index rewrite failure"):
home.migrate(self.env)
home.migrate(self.env)
new_state = self.state_root / "foreman" / "state.json"
with retrospective.lock(new_state):
saved = retrospective.record(new_state, data, [], "2026-09-01T13:00:00Z")
self.assertEqual(saved["id"], "retro-1")
def test_a_move_interrupted_before_its_link_is_finished_by_a_rerun(self):
self.legacy_home()
(self.state_root / "teamlead").rename(self.state_root / "foreman")
home.migrate(self.env)
self.assertTrue((self.state_root / "teamlead").is_symlink())
self.assertEqual(self.read("state.json.attention.json")["state_path"], str(self.state_root / "foreman" / "state.json"))
def test_a_held_lock_refuses_and_moves_nothing(self):
self.legacy_home()
handle = (self.state_root / "teamlead" / "state.json.lock").open("a")
self.addCleanup(handle.close)
fcntl.flock(handle.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
with self.assertRaisesRegex(UsageError, "holds"):
home.migrate(self.env)
self.assertTrue((self.state_root / "teamlead").is_dir())
self.assertFalse((self.state_root / "foreman").exists())
def test_a_running_command_holding_the_guard_refuses_and_moves_nothing(self):
self.legacy_home()
with home.guard(False, self.env):
with self.assertRaisesRegex(UsageError, "Stop every foreman"):
home.migrate(self.env)
self.assertTrue((self.state_root / "teamlead").is_dir())
self.assertFalse((self.state_root / "foreman").exists())
def test_a_command_starting_mid_migration_is_refused(self):
self.legacy_home()
seen = []
real_rename = home.os.rename
def rename_then_start_a_command(src, dst):
# A foreman command starts after the homes were scanned, before the
# move lands: the guard, not the lock scan, must turn it away.
out, err = io.StringIO(), io.StringIO()
with mock.patch.dict("os.environ", self.env):
seen.append((main(["foreman-queue"], stdout=out, stderr=err), err.getvalue()))
real_rename(src, dst)
with mock.patch.object(home.os, "rename", side_effect=rename_then_start_a_command):
result = home.migrate(self.env)
self.assertEqual([row["moved"] for row in result["homes"]], [True, True])
self.assertEqual(len(seen), 2)
for code, err in seen:
self.assertEqual(code, 1)
self.assertIn("migrate-home is moving", err)
def test_a_failed_move_is_an_actionable_error_and_moves_nothing(self):
self.legacy_home()
with mock.patch.object(home.os, "rename", side_effect=PermissionError(13, "denied")):
with self.assertRaisesRegex(StateError, "Nothing was moved"):
home.migrate(self.env)
self.assertTrue((self.state_root / "teamlead").is_dir())
self.assertFalse((self.state_root / "foreman").exists())
def test_a_failed_link_names_the_partial_move_and_a_rerun_finishes_it(self):
self.legacy_home()
with mock.patch.object(home.os, "symlink", side_effect=OSError(30, "read-only")):
with self.assertRaisesRegex(StateError, re.escape("run `{}` again to finish".format(runnable.command("migrate-home")))):
home.migrate(self.env)
self.assertTrue((self.state_root / "foreman").is_dir())
self.assertFalse((self.state_root / "teamlead").exists())
home.migrate(self.env)
self.assertTrue((self.state_root / "teamlead").is_symlink())
self.assertEqual(self.read("state.json.attention.json")["state_path"], str(self.state_root / "foreman" / "state.json"))
def test_a_config_only_migration_creates_the_state_root_and_holds_the_guard(self):
self.state_root.rmdir()
(self.config_root / "teamlead").mkdir()
(self.config_root / "teamlead" / "config.json").write_text('{"schema_version": 4}')
seen = []
real_rename = home.os.rename
def rename_then_try_the_guard(src, dst):
try:
with home.guard(False, self.env):
seen.append("entered")
except UsageError as exc:
seen.append(str(exc))
real_rename(src, dst)
with mock.patch.object(home.os, "rename", side_effect=rename_then_try_the_guard):
result = home.migrate(self.env)
self.assertEqual([row["status"] for row in result["homes"]], ["absent", "current"])
self.assertEqual(len(seen), 1)
self.assertIn("migrate-home is moving", seen[0])
self.assertTrue((self.config_root / "teamlead").is_symlink())
def test_a_command_without_a_state_root_creates_nothing(self):
self.state_root.rmdir()
with home.guard(False, self.env):
pass
self.assertFalse(self.state_root.exists())
def test_a_split_home_is_refused_and_never_merged(self):
self.legacy_home()
(self.state_root / "foreman").mkdir()
with self.assertRaisesRegex(UsageError, "never merged"):
home.migrate(self.env)
self.assertEqual(list((self.state_root / "foreman").iterdir()), [])
def test_nothing_to_move_is_absent(self):
self.assertEqual([row["status"] for row in home.migrate(self.env)["homes"]], ["absent", "absent"])
class RequireCurrentTest(HomeCase):
def test_a_legacy_default_home_is_refused_before_anything_is_created(self):
self.legacy_home()
with self.assertRaisesRegex(StateError, "migrate-home"):
home.require_current({"state"}, self.env)
self.assertFalse((self.state_root / "foreman").exists())
def test_explicit_paths_are_not_checked(self):
self.legacy_home()
home.require_current(set(), self.env)
def test_the_cli_refuses_a_legacy_default_home_and_runs_migrate_home(self):
self.legacy_home()
out, err = io.StringIO(), io.StringIO()
with mock.patch.dict("os.environ", self.env):
self.assertEqual(main(["foreman-queue"], stdout=out, stderr=err), 1)
self.assertIn("migrate-home", err.getvalue())
self.assertFalse((self.state_root / "foreman").exists())
out, err = io.StringIO(), io.StringIO()
with mock.patch.dict("os.environ", self.env):
self.assertEqual(main(["migrate-home"], stdout=out, stderr=err), 0, err.getvalue())
self.assertEqual(json.loads(out.getvalue())["homes"][0]["status"], "current")
def test_a_command_with_explicit_paths_runs_during_a_migration(self):
self.legacy_home()
state, config = self.state_root / "own" / "state.json", self.config_root / "own.json"
with home.guard(True, self.env):
for argv, refused in ((["foreman-queue", "--state", str(state), "--config", str(config)], False),
(["foreman-queue", "--state", str(state)], True)):
out, err = io.StringIO(), io.StringIO()
with mock.patch.dict("os.environ", self.env):
main(argv, stdout=out, stderr=err)
with self.subTest(argv=argv):
self.assertEqual("migrate-home is moving" in err.getvalue(), refused, err.getvalue())
def test_migrate_home_refuses_explicit_paths(self):
self.legacy_home()
for flags in (["--state", str(self.state_root / "x.json")], ["--config", str(self.config_root / "c.json")]):
out, err = io.StringIO(), io.StringIO()
with mock.patch.dict("os.environ", self.env):
self.assertEqual(main(["migrate-home", *flags], stdout=out, stderr=err), 1)
self.assertIn("takes no " + flags[0], err.getvalue())
self.assertTrue((self.state_root / "teamlead").is_dir())
self.assertFalse((self.state_root / "foreman").exists())
if __name__ == "__main__":
unittest.main().tessl-plugin
hooks
rules
skills
adopt-fork-pr
herdr-foreman
classify
foreman
references
specialists
templates
tests
herdr-standup
migrate-to-plugin
onboard-repo
release
references
tests