| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- """The knowledge-cycle bundle (goal 24 task 6): ONE end-to-end pass
- through the understanding and discoveries cycles, cross-cutting the
- surfaces the per-repo bundles could only check in isolation.
- Understanding: press Refresh on a project → the created task's OWN
- assignment payload (what the daemon actually receives) carries the
- brief's embedded old hash / old document / project notes AND the
- `understanding` member with the current revision → the saddle POSTs
- /api/saddle/understanding → the project page shows the new current
- document and a history row → a second POST makes the page show the
- newer one.
- Discoveries: POST via the API → the /discoveries page lists it and the
- dashboard shows it → update-by-id refines it → a fresh assignment
- payload carries it.
- """
- 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 db_rows(sql, params=()):
- conn = db()
- try:
- return conn.execute(sql, params).fetchall()
- finally:
- conn.close()
- def payload_for(task_id):
- for payload in reversed(fake.start_payloads):
- if int((payload.get("task") or {}).get("id") or 0) == int(task_id):
- return payload
- return None
- # A dedicated project so the cycle owns every row it asserts on.
- state = slot_public(auth, "/projects", "projects")
- act(auth, state["create"], {"name": "cycle",
- "git_url": "https://example.com/cycle.git"})
- cycle_id = int([p["id"] for p in
- slot_public(auth, "/projects", "projects")["projects"]
- if p["name"] == "cycle"][0])
- print("== cycle: the project page ships the section and Refresh ==")
- cycle_state = slot_public(auth, "/projects/%d" % cycle_id, "project")
- check(cycle_state.get("refresh_understanding") is not None,
- "the cycle project's slot authors the Refresh action")
- page_html = http_get_page(auth, "/projects/%d" % cycle_id)
- check("Understanding" in page_html and "Refresh" in page_html,
- "the project page renders the Understanding section with its button")
- print("== cycle: seed a current document + notes, press Refresh ==")
- status, body = saddle_api("POST", "/api/saddle/understanding", fake_token,
- {"project": "cycle",
- "body": "# Cycle v1\n\nThe old map.",
- "commit_hash": "aaa1111", "task_id": 0})
- check(status == 200 and body.get("ok") is True,
- "seeding the first understanding via the API works")
- conn = db()
- conn.execute("insert into project_notes (project_id, source_task_id, body,"
- " created_at) values (?, 0, ?, strftime('%s','now'))",
- (cycle_id, "Cycle note: the fixtures live in test/bundles/."))
- conn.commit()
- conn.close()
- cycle_state = slot_public(auth, "/projects/%d" % cycle_id, "project")
- result = act(auth, cycle_state["refresh_understanding"], {})
- check(any(d.get("type") == "notify" and d.get("kind") == "success" for d in result),
- "pressing Refresh queues the explorer task")
- rows = db_rows("select id, title, status from tasks"
- " where title like 'Understanding refresh: cycle'")
- check(len(rows) == 1, "Refresh created exactly one task")
- refresh_id = rows[0][0]
- check(rows[0][1].startswith("Understanding refresh:"),
- "the refresh task's title carries the goal-24 prefix")
- check(rows[0][2] in ("queued", "assigned", "working"),
- "the refresh task is live (%s)" % rows[0][2])
- print("== cycle: the refresh task's OWN assignment payload ==")
- # The fake saddle asks when idle, so the dispatcher hands it the
- # refresh task: the payload the daemon builds from the brief AND
- # the understanding member must both be there.
- check(wait_for(lambda: payload_for(refresh_id) is not None or False,
- timeout=30, what="refresh assignment push") is not None,
- "the dispatcher assigns the refresh task to the saddle")
- payload = payload_for(refresh_id)
- brief = (payload.get("task") or {}).get("description") or ""
- check("Previous commit hash: aaa1111" in brief,
- "the assigned brief embeds the OLD commit hash")
- check("```markdown" in brief and "The old map." in brief,
- "the assigned brief embeds the OLD document")
- check("Cycle note: the fixtures live in test/bundles/." in brief,
- "the assigned brief embeds the project notes from other agents")
- check(payload.get("understanding") == "# Cycle v1\n\nThe old map.",
- "the assignment payload's understanding member is the current doc")
- check("discoveries" in payload and isinstance(payload.get("discoveries"), list),
- "the assignment payload carries the discoveries array alongside")
- print("== cycle: the explorer saves; the page flips ==")
- fake.push_results("done", summary="walked the history and updated the doc")
- check(wait_task_done(auth, refresh_id, timeout=30) is not None,
- "the refresh task completes")
- status, body = saddle_api("POST", "/api/saddle/understanding", fake_token,
- {"project": "cycle",
- "body": "# Cycle v2\n\nThe updated map.",
- "commit_hash": "bbb2222",
- "task_id": refresh_id})
- check(status == 200 and int(body.get("understanding_id", 0)) > 0,
- "the explorer's save_understanding POST lands")
- cycle_state = slot_public(auth, "/projects/%d" % cycle_id, "project")
- current = cycle_state.get("understanding_current") or {}
- check(current.get("body") == "# Cycle v2\n\nThe updated map."
- and current.get("commit_hash") == "bbb2222",
- "the page shows the NEW current document after the save")
- history = cycle_state.get("understanding_history") or []
- check([h.get("commit_hash") for h in history] == ["aaa1111"]
- and (history[0].get("body") or "").endswith("The old map."),
- "the page keeps the previous revision as a history row")
- page_html = http_get_page(auth, "/projects/%d" % cycle_id)
- check("stm-markdown=\"project.understanding_current.body\"" in page_html,
- "the rendered page binds the current document as markdown")
- print("== cycle: a second save makes the page show the newer ==")
- status, body = saddle_api("POST", "/api/saddle/understanding", fake_token,
- {"project": "cycle",
- "body": "# Cycle v3\n\nThe newest map.",
- "commit_hash": "ccc3333"})
- check(status == 200, "the second explorer POST lands")
- cycle_state = slot_public(auth, "/projects/%d" % cycle_id, "project")
- current = cycle_state.get("understanding_current") or {}
- check(current.get("body") == "# Cycle v3\n\nThe newest map.",
- "the page's current flips to the newest revision")
- check([h.get("commit_hash") for h in
- cycle_state.get("understanding_history") or []]
- == ["bbb2222", "aaa1111"],
- "the history grows newest-first with both older revisions")
- print("== cycle: the discoveries leg ==")
- status, body = saddle_api("POST", "/api/saddle/discovery", fake_token,
- {"body": "cycle fact: meson test -C builddir runs the suite",
- "task_id": refresh_id})
- check(status == 200 and int(body.get("discovery_id", 0)) > 0,
- "POST /api/saddle/discovery inserts and echoes the id")
- discovery_id = int(body["discovery_id"])
- discoveries_state = slot_public(auth, "/discoveries", "discoveries")
- listed = [r for r in discoveries_state.get("discoveries") or []
- if r.get("body") == "cycle fact: meson test -C builddir runs the suite"]
- check(len(listed) == 1, "the /discoveries page lists the new row")
- home_state = slot_public(auth, "/", "dashboard")
- dashboard = [r for r in home_state.get("discoveries") or []
- if r.get("body") == "cycle fact: meson test -C builddir runs the suite"]
- check(len(dashboard) == 1, "the dashboard shows the discovery")
- status, body = saddle_api("POST", "/api/saddle/discovery/update", fake_token,
- {"id": discovery_id,
- "body": "cycle fact: meson test -C builddir runs the suite (also task-log-js)"})
- check(status == 200 and body.get("ok") is True, "update-by-id answers ok")
- discoveries_state = slot_public(auth, "/discoveries", "discoveries")
- rows_now = [r for r in discoveries_state.get("discoveries") or []
- if r.get("id") == str(discovery_id)]
- check(len(rows_now) == 1
- and "(also task-log-js)" in rows_now[0].get("body", ""),
- "the page shows the refined body in place (no duplicate row)")
- # A fresh assignment carries the refined discovery.
- payload_count = len(fake.start_payloads)
- create_queued(auth, {"project_id": str(cycle_id),
- "title": "Cycle dispatch",
- "priority": "2"})
- check(wait_for(lambda: len(fake.start_payloads) > payload_count or False,
- timeout=30, what="cycle /start push") is not None,
- "the dispatcher pushes the cycle task")
- shipped = [r.get("body", "") for r in
- fake.start_payloads[-1].get("discoveries") or []]
- check(any("(also task-log-js)" in b for b in shipped),
- "a fresh assignment payload carries the refined discovery")
- check(fake.start_payloads[-1].get("understanding")
- == "# Cycle v3\n\nThe newest map.",
- "the fresh assignment also carries the newest understanding")
|