"""The parity bundle (goal 9): the agent-facing wire the restored tool surface reads — GET /api/saddle/goals behind list_goals (bearer auth, project scoping over primary AND linked projects, the goal_id detail shape) and the yeehaw ledger event rendering in the task log page.""" from harness import * # noqa: F401,F403 — the shared wire helpers def run(ctx): auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token print("== goals endpoint: auth ==") status, body = saddle_api("GET", "/api/saddle/goals", None) check(status == 401, "goals: no bearer token is 401 (%s)" % status) status, body = saddle_api("GET", "/api/saddle/goals", "not-a-token") check(status == 401, "goals: an unknown token is 401 (%s)" % status) print("== goals endpoint: rows and project scoping ==") # a second project so scoping is observable conn = db() conn.execute("insert into projects (name, git_url, default_branch, created_at)" " values ('parity-repo', 'https://example.com/parity.git', 'main'," " strftime('%s','now'))") conn.commit() conn.close() def create_goal(fields): act(auth, slot_public(auth, "/goals", "goals")["create"], fields) rows = [g for g in slot_public(auth, "/goals", "goals")["goals"] if g["title"] == fields["title"]] return int(rows[0]["id"]) goal_a = create_goal({"project_id": "1", "title": "Parity alpha", "brief": "First parity goal.", "branch_name": "goal/parity-a", "priority": "3"}) goal_b = create_goal({"project_id": "2", "title": "Parity beta", "brief": "Second parity goal.", "branch_name": "goal/parity-b", "priority": "3"}) # link goal_a -> parity-repo (project 2) as reference: linked projects # count for scoping too state = goal_state(goal_a) act(auth, state["add_link"], {"linked_project_id": "2", "relationship": "reference"}) status, body = saddle_api("GET", "/api/saddle/goals", fake_token) check(status == 200 and body.get("ok") is True and isinstance(body.get("goals"), list), "goals: unfiltered GET returns the rows envelope (%s)" % status) ids = [row.get("id") for row in body.get("goals", [])] check(goal_a in ids and goal_b in ids, "goals: both goals appear unfiltered") row_a = [row for row in body.get("goals", []) if row.get("id") == goal_a][0] check(row_a.get("status") in ("draft", "planning") and row_a.get("branch") == "goal/parity-a" and len(row_a.get("updated_at", "")) > 0 and row_a.get("title") == "Parity alpha", "goals: a row carries id/title/status/branch/updated_at (%s)" % row_a) # project=demo lists goal_a (primary) but NOT goal_b (disjoint) status, body = saddle_api("GET", "/api/saddle/goals?project=demo", fake_token) scoped_ids = [row.get("id") for row in body.get("goals", [])] check(goal_a in scoped_ids and goal_b not in scoped_ids, "goals: project=demo scopes to the primary project") # project=parity-repo lists goal_a (LINKED) and goal_b (primary) status, body = saddle_api("GET", "/api/saddle/goals?project=parity-repo", fake_token) scoped_ids = [row.get("id") for row in body.get("goals", [])] check(goal_a in scoped_ids and goal_b in scoped_ids, "goals: linked (reference) projects scope too") # unknown project: an empty view, not an error status, body = saddle_api("GET", "/api/saddle/goals?project=ghost", fake_token) check(status == 200 and body.get("goals") == [], "goals: an unknown project is an empty view (%s)" % status) print("== goals endpoint: goal_id detail ==") status, body = saddle_api("GET", "/api/saddle/goals?goal_id=%d" % goal_a, fake_token) check(status == 200 and body.get("ok") is True and "goal" in body, "goals: goal_id returns the detail envelope (%s)" % status) detail = body.get("goal") or {} check(detail.get("id") == goal_a and detail.get("brief") == "First parity goal." and detail.get("has_plan") is False and detail.get("has_report") is False, "goals: the detail carries brief + has_plan/has_report (%s)" % detail) status, body = saddle_api("GET", "/api/saddle/goals?goal_id=99999", fake_token) check(status == 404, "goals: an unknown goal_id is 404 (%s)" % status) # a plan makes has_plan true: start the goal, wait for the plan # review (the PENDING block alone must NOT flip it — only the # accept-gated goals.plan column does), approve, then re-read fake.goal_script = [("plan", "# Parity plan\n\n1. Check the goals wire")] act(auth, goal_state(goal_a)["start"], {}) check(wait_for(lambda: goal_state(goal_a)["status"] == "plan_review" or False, timeout=120, what="parity goal enters plan review") is not None, "goals: the goal agent submitted its plan") status, body = saddle_api("GET", "/api/saddle/goals?goal_id=%d" % goal_a, fake_token) check((body.get("goal") or {}).get("has_plan") is False, "goals: a PENDING plan review leaves has_plan false (accept-gated)") fake.goal_script = [("suspend",)] pending = goal_state(goal_a)["plan_pending_block"] act(auth, pending["answer_action"], {"verdict": "accept"}) check(wait_for(lambda: goal_state(goal_a)["status"] == "active" or False, timeout=60, what="parity plan approved") is not None, "goals: the approved plan activates the goal") status, body = saddle_api("GET", "/api/saddle/goals?goal_id=%d" % goal_a, fake_token) check((body.get("goal") or {}).get("has_plan") is True, "goals: a stored plan flips has_plan (%s)" % (body.get("goal") or {})) check((body.get("goal") or {}).get("status") == "active", "goals: the detail reflects the live status") print("== yeehaw: the celebration renders in the task log ==") task_id = create_queued(auth, {"project_id": "1", "title": "Parity yeehaw run", "priority": "3", "description": "Push a yeehaw."}) check(wait_for(lambda: fake.running_task == task_id or False, timeout=60, what="yeehaw task dispatches") is not None, "yeehaw: the task reaches the fake saddle") fake.push_events([{"kind": "yeehaw", "actor": "model", "payload": {"message": "shipped the parity wire — delightful task"}}]) status, page = http("GET", "/tasks/%d/log" % task_id, timeout=15) check(status == 200 and "data-log-feed" in page, "yeehaw: the task log page renders") check("badge-yeehaw" in page, "yeehaw: the page ships the festive badge class") check("'yeehaw'" in page or '"yeehaw"' in page, "yeehaw: the page's client script knows the kind")