mirror of
https://github.com/Heretek-AI/heretek-rigs.git
synced 2026-11-07 10:55:57 -10:00
review: robust read-only HOME in sandbox tests, rig selector on idle check, omni command-pod lookup
- Tests now use a read-only dir inside the bound workspace as HOME, so the red-proofs don't depend on where the temp dir or repo lives. - USER_GUIDE idle check passes --rig (needed outside a managed seat). - SEAT-WRITE-SCOPES maps the omni command-pod seats to their rows, generated from fleet.yaml omni.core_pod. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01VjcGdhFQxjHWWV9xxvurqs
This commit is contained in:
4 files changed
+24
-6
No files matched your search
@@ -25,6 +25,9 @@ blank conversation; queue rows and seat identity are kept.
|
||||
`*` in a glob also matches `/`, so `src/*` covers `src/a/b.c`. Rows marked
|
||||
read-only charter write reports only; they do not author code.
|
||||
|
||||
In `heretek-omni-fleet` a seat keeps the name below (`<seat>@heretek-omni-fleet`),
|
||||
except the command pod: `command-exec-director` uses the `exec-exec-director` row, `command-tpm-scrum-lead` uses the `delivery-tpm-scrum-lead` row, `command-system-architect` uses the `exec-system-architect` row.
|
||||
|
||||
| Seat | Rig | Writable (relative to the workspace) |
|
||||
|---|---|---|
|
||||
| `data-analytics-metrics-eng` | cloud-sre-and-data-platform | `migrations/clickhouse/*`, `analytics/*` |
|
||||
|
||||
+1
-1
@@ -264,7 +264,7 @@ address and identity are kept.
|
||||
python3 scripts/seed-rig.py rigs/<rig>/rig.yaml --refresh-policy-only
|
||||
|
||||
# Charter, model, MCP or skill change: re-seed, then relaunch only the
|
||||
# affected seat. Check it is idle first (rig ps --nodes --json); a fresh
|
||||
# affected seat. Check it is idle first (rig ps --nodes --json --rig <rig>); a fresh
|
||||
# launch starts a blank conversation.
|
||||
python3 scripts/seed-rig.py rigs/<rig>/rig.yaml # or members/<role>.yaml --rig <rig> --pod <pod>
|
||||
rig seat launch <seat> --fresh --stop --reason "refresh: <change>"
|
||||
|
||||
@@ -51,6 +51,9 @@ blank conversation; queue rows and seat identity are kept.
|
||||
`*` in a glob also matches `/`, so `src/*` covers `src/a/b.c`. Rows marked
|
||||
read-only charter write reports only; they do not author code.
|
||||
|
||||
In `heretek-omni-fleet` a seat keeps the name below (`<seat>@heretek-omni-fleet`),
|
||||
except the command pod: {command}.
|
||||
|
||||
| Seat | Rig | Writable (relative to the workspace) |
|
||||
|---|---|---|
|
||||
"""
|
||||
@@ -59,6 +62,11 @@ read-only charter write reports only; they do not author code.
|
||||
def render() -> str:
|
||||
fleet = yaml.safe_load(FLEET.read_text())
|
||||
roles = fleet["roles"]
|
||||
core = fleet["omni"]["core_pod"]
|
||||
command = ", ".join(
|
||||
f"`{core['id']}-{m}` uses the `{roles[m]['session'].split('@', 1)[0]}` row"
|
||||
for m in core["members"]
|
||||
)
|
||||
rows = []
|
||||
for rid, role in sorted(roles.items(), key=lambda kv: (kv[1]["rig"], kv[0])):
|
||||
seat = role["session"].split("@", 1)[0]
|
||||
@@ -67,7 +75,7 @@ def render() -> str:
|
||||
if role.get("readonly_charter"):
|
||||
scope += " (read-only charter)"
|
||||
rows.append(f"| `{seat}` | {role['rig']} | {scope} |\n")
|
||||
return HEADER + "".join(rows)
|
||||
return HEADER.format(command=command) + "".join(rows)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
|
||||
@@ -115,8 +115,13 @@ class SeatSandboxEscapes(unittest.TestCase):
|
||||
'test -d "$GOCACHE" && echo t > "$XDG_CACHE_HOME/x"'
|
||||
)
|
||||
self.assertEqual(proc.returncode, 0, proc.stderr)
|
||||
self.run_jailed('mkdir -p "$HOME/.cache/go-build"')
|
||||
self.assertFalse((self.home / ".cache").exists())
|
||||
# The workspace is bound read-only outside its write roots, like a
|
||||
# real seat's HOME on the host root (the test HOME under /tmp is not).
|
||||
ro_home = self.ws / "home"
|
||||
ro_home.mkdir()
|
||||
proc = self.run_jailed('mkdir -p "$HOME/.cache/go-build"', HOME=str(ro_home))
|
||||
self.assertNotEqual(proc.returncode, 0)
|
||||
self.assertFalse((ro_home / ".cache").exists())
|
||||
|
||||
def test_cache_does_not_survive_the_run(self):
|
||||
d = self._jail_scratch()
|
||||
@@ -134,8 +139,10 @@ class SeatSandboxEscapes(unittest.TestCase):
|
||||
'package w\nimport "testing"\nfunc TestW(t *testing.T) {}\n'
|
||||
)
|
||||
# The test HOME sits under /tmp, which the jail replaces with a
|
||||
# writable tmpfs; a real seat's HOME is on the read-only host root.
|
||||
proc = self.run_jailed("cd src && go test ./...", HOME=str(REPO_ROOT))
|
||||
# writable tmpfs; use a read-only dir in the bound workspace instead,
|
||||
# like a real seat's HOME on the read-only host root.
|
||||
(self.ws / "home").mkdir()
|
||||
proc = self.run_jailed("cd src && go test ./...", HOME=str(self.ws / "home"))
|
||||
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
|
||||
|
||||
# --- the per-command scratch dir is cleaned up ----------------------
|
||||
|
||||
Reference in new issue
Block a user