"""The stacks bundle (goal 8 task 2): the goal link pre-fill from the primary project's project_links, and the stacks feature — a named collection of reference projects applied one-click to a project's or a goal's link set (stacks/stack_projects tables, /stacks pages, the apply actions with exact-duplicate skipping).""" 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 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"]) def stack_state(stack_id): return slot_public(auth, "/stacks/%d" % stack_id, "stack") def link_rows(goal_id): conn = db() try: return conn.execute( "select gl.project_id, gl.relationship from goal_links gl" " where gl.goal_id = ? order by gl.id", (goal_id,)).fetchall() finally: conn.close() def project_link_rows(parent_id): conn = db() try: return conn.execute( "select linked_project_id, relationship from project_links" " where parent_project_id = ? order by id", (parent_id,)).fetchall() finally: conn.close() print("== goal 8 task 2 A: goal links pre-fill from the project ==") # Two satellites around the demo project: one co-developed, one # reference. The goal created on demo must inherit both. conn = db() conn.execute("insert into projects (name, git_url, default_branch, created_at)" " values ('stacks-codev', 'https://example.com/codev.git', 'main'," " strftime('%s','now'))") conn.execute("insert into projects (name, git_url, default_branch, created_at)" " values ('stacks-ref', 'https://example.com/ref.git', 'main'," " strftime('%s','now'))") conn.commit() codev_id = int(conn.execute( "select id from projects where name = 'stacks-codev'").fetchone()[0]) ref_id = int(conn.execute( "select id from projects where name = 'stacks-ref'").fetchone()[0]) # A third project linked to the project but AFTER goal creation — # it must NOT propagate (the pre-fill is a one-time snapshot). conn.execute("insert into projects (name, git_url, default_branch, created_at)" " values ('stacks-late', 'https://example.com/late.git', 'main'," " strftime('%s','now'))") conn.commit() late_id = int(conn.execute( "select id from projects where name = 'stacks-late'").fetchone()[0]) conn.execute("insert into project_links (parent_project_id, linked_project_id," " relationship) values (1, ?, 'co-developed')", (codev_id,)) conn.execute("insert into project_links (parent_project_id, linked_project_id," " relationship) values (1, ?, 'reference')", (ref_id,)) conn.commit() conn.close() goal = create_goal({"project_id": "1", "title": "Prefill probe", "brief": "Check the link pre-fill.", "branch_name": "goal/prefill", "priority": "3"}) check(set(link_rows(goal)) == {(codev_id, "co-developed"), (ref_id, "reference")}, "a goal created on a linked project pre-fills goal_links from" " project_links (same targets, same relationships)") state = goal_state(goal) check(sorted(link["name"] for link in state["links"]) == ["stacks-codev", "stacks-ref"], "the goal page lists the pre-filled links") check(state["links"][0].get("remove") is not None, "the pre-filled links are prunable like manual ones") # The late link must not propagate into the existing goal. conn = db() conn.execute("insert into project_links (parent_project_id, linked_project_id," " relationship) values (1, ?, 'reference')", (late_id,)) conn.commit() conn.close() check(all(row[0] != late_id for row in link_rows(goal)), "a project link added AFTER creation never propagates (snapshot)") # A NEW goal created after the late link lands DOES carry it. goal2 = create_goal({"project_id": "1", "title": "Prefill probe 2", "brief": "Snapshot at creation time.", "branch_name": "goal/prefill2", "priority": "3"}) check(set(link_rows(goal2)) == {(codev_id, "co-developed"), (ref_id, "reference"), (late_id, "reference")}, "a goal created after a new project link snapshots that link too") # Self-links in the project graph are never copied (a project link # to the goal's own primary is redundant — it is implicit). conn = db() conn.execute("insert into projects (name, git_url, default_branch, created_at)" " values ('stacks-self', 'https://example.com/self.git', 'main'," " strftime('%s','now'))") conn.commit() conn.close() goal3 = create_goal({"project_id": "1", "title": "No self links", "brief": "The primary is implicit.", "branch_name": "goal/prefill3", "priority": "3"}) check(all(row[0] != 1 for row in link_rows(goal3)), "the primary project is never duplicated as an explicit link") print("== the pre-filled links ride the assignment payload ==") # Removing one pre-filled link must remove it from the payload — # goal_links stays the single source of truth after the snapshot. state = goal_state(goal) codev_link = [link for link in state["links"] if link["name"] == "stacks-codev"][0] act(auth, codev_link["remove"], {"link_id": str(codev_link["id"])}) check(set(link_rows(goal)) == {(ref_id, "reference")}, "removing a pre-filled goal link removes the row") fake.goal_script = [("suspend",)] act(auth, goal_state(goal)["start"], {}) check(wait_for(lambda: next( (True for row in db().execute( "select id from tasks where goal_id = ? and kind = 'goal_run'", (goal,)).fetchall()), False) or False, timeout=30, what="goal run task creation") is not None, "start creates the goal-run task") conn = db() run_task = int(conn.execute( "select id from tasks where goal_id = ? and kind = 'goal_run'", (goal,)).fetchone()[0]) conn.close() def assigned_payload(): for payload in reversed(fake.goal_assignments): if (payload.get("task") or {}).get("id") == run_task: return payload return None check(wait_for(lambda: assigned_payload() is not None or False, timeout=60, what="goal run assignment") is not None, "the fake saddle captures the goal-run assignment") payload = assigned_payload() codev_names = [p["name"] for p in payload["task"]["co_developed"]] ref_names = [p["name"] for p in payload["task"]["reference"]] check("demo" in codev_names and "stacks-codev" not in codev_names, "the assignment payload's co-developed carries the primary and the" " surviving pre-filled link (the removed one is gone)") check(ref_names == ["stacks-ref"], "the assignment payload's reference set comes from the goal's links") print("== stacks: CRUD ==") stacks_state = slot_public(auth, "/stacks", "stacks") check(stacks_state.get("create") is not None and stacks_state["stacks"] == [], "the stacks page starts empty with a create action") act(auth, stacks_state["create"], {"name": "web-stack-refs", "summary": "The usual reference collection"}) stacks = slot_public(auth, "/stacks", "stacks")["stacks"] check(len(stacks) == 1 and stacks[0]["name"] == "web-stack-refs" and int(stacks[0]["member_count"]) == 0, "a stack lands in the list with its (empty) member count") stack_id = int(stacks[0]["id"]) detail = stack_state(stack_id) check(detail["exists"] and detail["name"] == "web-stack-refs" and detail["members"] == [] and detail.get("update") is not None and detail.get("add_member") is not None and detail.get("delete") is not None, "the stack page exposes edit, add-member and delete actions") check(any(option["name"] == "demo" for option in detail["options"]), "every project is offerable as a stack member") # Duplicate name refused. dup = act(auth, slot_public(auth, "/stacks", "stacks")["create"], {"name": "web-stack-refs"}) check(any(d.get("type") == "notify" and d.get("kind") == "error" for d in dup), "a duplicate stack name refuses") # Rename + summary clear. act(auth, detail["update"], {"name": "web-stack-refs-2", "summary": ""}) detail = stack_state(stack_id) check(detail["name"] == "web-stack-refs-2" and detail["summary"] == "", "a stack renames and its summary clears") print("== stacks: members ==") detail = stack_state(stack_id) act(auth, detail["add_member"], {"project_id": str(codev_id), "relationship": "co-developed"}) act(auth, stack_state(stack_id)["add_member"], {"project_id": str(ref_id), "relationship": "reference"}) detail = stack_state(stack_id) member_names = [(m["name"], m["relationship"]) for m in detail["members"]] check(member_names == [("stacks-codev", "co-developed"), ("stacks-ref", "reference")], "members land with their relationships") dup = act(auth, stack_state(stack_id)["add_member"], {"project_id": str(ref_id), "relationship": "reference"}) check(any(d.get("type") == "notify" and d.get("kind") == "error" and "already" in (d.get("message") or "") for d in dup), "adding the same project twice refuses") bad = act(auth, stack_state(stack_id)["add_member"], {"project_id": str(late_id), "relationship": "sponsor"}) check(any(d.get("type") == "notify" and d.get("kind") == "error" for d in bad), "an unknown relationship refuses") detail = stack_state(stack_id) check(len(detail["members"]) == 2, "the refused additions left the stack untouched") print("== stacks: apply to a project ==") conn = db() conn.execute("insert into projects (name, git_url, default_branch, created_at)" " values ('stacks-target', 'https://example.com/target.git', 'main'," " strftime('%s','now'))") conn.commit() conn.close() target_id = int(db().execute( "select id from projects where name = 'stacks-target'" ).fetchone()[0]) project_state = slot_public(auth, "/projects/%d" % target_id, "project") check(project_state.get("apply_stack") is not None and any(opt["name"] == "web-stack-refs-2" for opt in project_state["stack_options"]), "the project page offers Apply stack with the stacks as options") result = act(auth, project_state["apply_stack"], {"stack_id": str(stack_id)}) check("2 link" in (action_notify(result) or ""), "applying reports how many links landed") check(set(project_link_rows(target_id)) == {(codev_id, "co-developed"), (ref_id, "reference")}, "the stack's members became project_links rows") # Re-apply: exact duplicates skipped, nothing duplicated. result = act(auth, slot_public(auth, "/projects/%d" % target_id, "project")["apply_stack"], {"stack_id": str(stack_id)}) check("nothing new" in (action_notify(result) or ""), "re-applying skips exact duplicates") check(set(project_link_rows(target_id)) == {(codev_id, "co-developed"), (ref_id, "reference")}, "no duplicate project_links rows appear") # A pre-existing DIFFERENT relationship on the same target is not a # duplicate: applying adds the stack's own relationship alongside. conn = db() conn.execute("insert into project_links (parent_project_id, linked_project_id," " relationship) values (?, ?, 'co-developed')", (target_id, ref_id)) conn.commit() conn.close() act(auth, slot_public(auth, "/projects/%d" % target_id, "project")["apply_stack"], {"stack_id": str(stack_id)}) check((ref_id, "reference") in project_link_rows(target_id) and project_link_rows(target_id).count((ref_id, "co-developed")) == 1, "a different relationship on the same target coexists (exact pairs skip)") print("== stacks: apply to a goal ==") # A goal on a LINK-FREE host project — the pre-fill seeds nothing, # so the stack's members are exactly what applying must land. conn = db() conn.execute("insert into projects (name, git_url, default_branch, created_at)" " values ('stacks-goalhost', 'https://example.com/goalhost.git'," " 'main', strftime('%s','now'))") conn.commit() conn.close() host_id = int(db().execute( "select id from projects where name = 'stacks-goalhost'").fetchone()[0]) goal4 = create_goal({"project_id": str(host_id), "title": "Stack target", "brief": "Apply a stack here.", "branch_name": "goal/stacktarget", "priority": "3"}) check(link_rows(goal4) == [], "a goal on a link-free project pre-fills nothing") gstate = goal_state(goal4) check(gstate.get("apply_stack") is not None and any(opt["name"] == "web-stack-refs-2" for opt in gstate["stack_options"]), "the goal page offers Apply stack with the stacks as options") result = act(auth, gstate["apply_stack"], {"stack_id": str(stack_id)}) check("2 link" in (action_notify(result) or ""), "applying to the goal reports the links landed") check(set(link_rows(goal4)) == {(codev_id, "co-developed"), (ref_id, "reference")}, "the stack's members became goal_links rows") # Re-apply: idempotent. result = act(auth, goal_state(goal4)["apply_stack"], {"stack_id": str(stack_id)}) check("nothing new" in (action_notify(result) or ""), "re-applying to the goal skips exact duplicates") check(set(link_rows(goal4)) == {(codev_id, "co-developed"), (ref_id, "reference")}, "no duplicate goal_links rows appear") # Removing a stack member then re-applying adds only the newcomer. detail = stack_state(stack_id) ref_view = [m for m in detail["members"] if int(m["project_id"]) == ref_id][0] act(auth, ref_view["remove"], {}) check(len(stack_state(stack_id)["members"]) == 1, "removing a member shrinks the stack") act(auth, goal_state(goal4)["apply_stack"], {"stack_id": str(stack_id)}) check(set(link_rows(goal4)) == {(codev_id, "co-developed"), (ref_id, "reference")}, "removing a stack member never unlinks what was already applied") print("== stacks: delete ==") conn = db() act(auth, slot_public(auth, "/stacks/%d" % stack_id, "stack")["delete"], {}) conn.close() check(slot_public(auth, "/stacks", "stacks")["stacks"] == [], "deleting a stack empties the list") conn = db() leftover = conn.execute("select count(*) from stack_projects").fetchone()[0] conn.close() check(leftover == 0, "the stack's member rows die with it") check(set(link_rows(goal4)) == {(codev_id, "co-developed"), (ref_id, "reference")}, "deleting a stack keeps every link it already applied")