| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- """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",)]
- # (Goal 27 refinements — the parking guard: the scripted park
- # needs a live wake source under the goal.)
- conn = db()
- conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
- " priority, mode, creator, created_at) values (1, ?, 'task',"
- " 'Parity live worker', 'blocked', 5, 'implement', 'goal',"
- " strftime('%s','now'))", (goal_a,))
- conn.commit()
- conn.close()
- 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)
- # The badge classes and kind handling live in the compiled
- # task_log.js resource (plan 17 b3+), not the page HTML.
- status_js, log_js = http("GET", "/_statum/resource/task_log.js", timeout=15)
- check(status == 200 and "data-log-feed" in page,
- "yeehaw: the task log page renders")
- check(status_js == 200 and "badge-yeehaw" in log_js,
- "yeehaw: the page ships the festive badge class")
- check("'yeehaw'" in log_js or '"yeehaw"' in log_js,
- "yeehaw: the page's client script knows the kind")
|