from harness import * # noqa: F401,F403 — the shared wire helpers """Goal 8 task 6 (web side): the register handshake stores the daemon's reported `workspace_root`, and assignment project paths are addressed on the ASKING saddle's filesystem — the saddle row's root first, then the SADDLE_PROJECTS_ROOT environment override, then the historical "/workspace" default. The web app needs NO access to saddle workspaces: paths are advisory and multi-saddle goals coordinate through origin.""" def run(ctx): auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token print("== origin decoupling: the handshake stores the reported root ==") # The primary fake reports /workspace by default; the row carries it # once registration completes (the stacks bundle's demo project is # project 1 in every shard). def saddle_row(name): return next((s for s in slot_public(auth, "/saddles", "saddles")["saddles"] if s["name"] == name), None) primary = saddle_row("fake-saddle") check(primary is not None, "the primary fake saddle is registered") if primary is not None: check(primary.get("workspace_root") == "/workspace", "the register handshake stores the daemon-reported workspace_root (%r)" % primary.get("workspace_root")) print("== origin decoupling: assignment paths follow the ASKING saddle ==") # A second saddle on its own volume: its daemon reports a DIFFERENT # workspace root — the fleet's separate-mount deployment shape. other = FakeSaddle() other.workspace_root = "/volumes/saddle-b" other.serve(port=free_port()) saddles_state = slot_public(auth, "/saddles", "saddles") act(auth, saddles_state["register"], {"name": "volume-b", "host": "127.0.0.1:%d" % other.port}) check(wait_for(lambda: len(other.register_log) > 0 or False, timeout=15, what="volume-b /register delivery") is not None, "the second saddle received /register") row_b = saddle_row("volume-b") check(row_b is not None and row_b.get("workspace_root") == "/volumes/saddle-b", "the second saddle's reported root lands on its row (%r)" % ((row_b or {}).get("workspace_root"))) # One task on the demo project, dispatched to EACH saddle in turn: # the assignment's project `path` must sit under the ASKING saddle's # root, not a shared default. def path_of(saddle_fake, title): payloads = [p for p in saddle_fake.start_payloads if (p.get("task") or {}).get("title") == title] if not payloads: return None co = payloads[-1]["task"].get("co_developed") or [] return co[0].get("path") if co else None # deterministic routing: a capability each saddle alone carries saddles_state = slot_public(auth, "/saddles", "saddles") act(auth, saddles_state["create_capability"], {"name": "primary-vol"}) act(auth, slot_public(auth, "/saddles", "saddles")["create_capability"], {"name": "volume-b-vol"}) caps = {c["name"]: int(c["id"]) for c in slot_public(auth, "/saddles", "saddles")["capabilities"]} act(auth, saddle_card(auth, "fake-saddle")["attach_capability"], {"capability_id": str(caps["primary-vol"])}) act(auth, saddle_card(auth, "volume-b")["attach_capability"], {"capability_id": str(caps["volume-b-vol"])}) def create_routed(title, cap_name, description): task_id = create_queued(auth, {"project_id": "1", "title": title, "description": description, "priority": "2"}) act(auth, task_state(auth, task_id)["attach_capability"], {"capability_id": str(caps[cap_name])}) wait_for(lambda: [c["name"] for c in task_state(auth, task_id)["capabilities"]] == [cap_name] or False, timeout=30, what="%s attached" % cap_name) return task_id first = create_routed("Path probe A", "primary-vol", "Dispatch to the primary volume.") check(wait_for(lambda: path_of(fake, "Path probe A") is not None, timeout=40, what="primary-saddle assignment") is not None, "the primary saddle receives the task") path_a = path_of(fake, "Path probe A") check(path_a is not None and path_a.startswith("/workspace/task-"), "the primary saddle's paths sit under its reported /workspace (%r)" % path_a) second = create_routed("Path probe B", "volume-b-vol", "Dispatch to the second volume.") check(wait_for(lambda: path_of(other, "Path probe B") is not None, timeout=40, what="volume-b assignment") is not None, "the volume-b saddle receives the task") path_b = path_of(other, "Path probe B") check(path_b is not None and path_b.startswith("/volumes/saddle-b/task-"), "the volume-b saddle's paths sit under ITS OWN reported root (%r)" % path_b) check(path_a is not None and path_b is not None and path_a.split("/task-")[0] != path_b.split("/task-")[0], "the two saddles' assignments address different volumes") print("== origin decoupling: the compat fallback chain ==") # A daemon that does NOT report a workspace_root (pre-task-6 daemon) # keeps a null root; its paths fall back to SADDLE_PROJECTS_ROOT # (the harness runs the app with it pointed at the scratch dir). # The probe task REQUIRES a capability only this saddle carries, so # the dispatcher deterministically targets it (tag routing). legacy = FakeSaddle() legacy.workspace_root = "" legacy.serve(port=free_port()) saddles_state = slot_public(auth, "/saddles", "saddles") act(auth, saddles_state["register"], {"name": "legacy-daemon", "host": "127.0.0.1:%d" % legacy.port}) check(wait_for(lambda: len(legacy.register_log) > 0 or False, timeout=15, what="legacy /register delivery") is not None, "the legacy daemon received /register") row_legacy = saddle_row("legacy-daemon") check(row_legacy is not None and not row_legacy.get("workspace_root"), "a daemon reporting no root keeps the column empty (%r)" % ((row_legacy or {}).get("workspace_root"))) act(auth, slot_public(auth, "/saddles", "saddles")["create_capability"], {"name": "legacy-only"}) saddles_state = slot_public(auth, "/saddles", "saddles") legacy_cap = int([c["id"] for c in saddles_state["capabilities"] if c["name"] == "legacy-only"][0]) legacy_card = saddle_card(auth, "legacy-daemon") act(auth, legacy_card["attach_capability"], {"capability_id": str(legacy_cap)}) # Create as a DRAFT, attach the capability, THEN enqueue: a queued # task races the idle-awake primary fake's ask (the dispatch can # win before the attach lands, and the routed probe then completes # unrouted — a flake the parking-guard timing shifts exposed). act(auth, slot_public(auth, "/tasks", "tasks")["create"], {"project_id": "1", "title": "Path probe C", "description": "Dispatch to the legacy daemon.", "priority": "4"}) third = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"] if t["title"] == "Path probe C"][0]) act(auth, task_state(auth, third)["attach_capability"], {"capability_id": str(legacy_cap)}) check(wait_for(lambda: [c["name"] for c in task_state(auth, third)["capabilities"]] == ["legacy-only"] or False, timeout=30, what="capability attached") is not None, "the probe task requires the legacy-only capability") enqueue_task(auth, third) check(wait_for(lambda: path_of(legacy, "Path probe C") is not None, timeout=60, what="legacy-saddle assignment") is not None, "the legacy saddle receives the task") path_c = path_of(legacy, "Path probe C") harness_root = os.path.join(WORK, "workspace") check(path_c is not None and path_c.startswith(harness_root + "/task-"), "a null root falls back to SADDLE_PROJECTS_ROOT, not /workspace (%r)" % path_c)