Size coordination workplans by chokepoint in-degree (RAIL-FAB-WP-0029-T01).
Coordination nodes and edges now carry visualSize and edgeWidth, which the explorer styles already read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 7458@bnt-lap001 Assistant-Session: 62534cdf-8348-48a7-9c0d-46e0f74c8eae
This commit is contained in:
parent
a9e677986a
commit
7dd4b062a8
2 changed files with 27 additions and 2 deletions
|
|
@ -66,6 +66,18 @@ def _indexed_depends_targets(workplan: dict[str, Any]) -> list[str]:
|
|||
return targets
|
||||
|
||||
|
||||
TASK_NODE_SIZE = 26
|
||||
WORKPLAN_BASE_SIZE = 44
|
||||
WORKPLAN_SIZE_STEP = 10
|
||||
WORKPLAN_SIZE_CAP = 8
|
||||
|
||||
|
||||
def chokepoint_size(in_degree: int) -> int:
|
||||
"""Grow workplan nodes with the number of open items waiting on them."""
|
||||
|
||||
return WORKPLAN_BASE_SIZE + WORKPLAN_SIZE_STEP * min(max(in_degree, 0), WORKPLAN_SIZE_CAP)
|
||||
|
||||
|
||||
def coordination_graph_payload(
|
||||
workplans: list[dict[str, Any]],
|
||||
tasks: list[dict[str, Any]],
|
||||
|
|
@ -153,6 +165,7 @@ def coordination_graph_payload(
|
|||
"needsHuman": human,
|
||||
"displayState": "highlight" if status == "wait" or human else "show",
|
||||
"unresolved": status == "wait" or human,
|
||||
"visualSize": TASK_NODE_SIZE,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
@ -254,11 +267,16 @@ def coordination_graph_payload(
|
|||
indexed_pairs.add((src_wp, dst))
|
||||
|
||||
for el in elements:
|
||||
node_id = el["data"]["id"]
|
||||
data = el["data"]
|
||||
if data.get("kind") == "Edge":
|
||||
data.setdefault("edgeWidth", 3 if data.get("edgeType") in {"depends_on", "waits_on"} else 1.5)
|
||||
continue
|
||||
node_id = data["id"]
|
||||
if not node_id.startswith("workplan:"):
|
||||
continue
|
||||
wp_id = node_id.split(":", 1)[1]
|
||||
el["data"]["chokepoint"] = int(chokepoint.get(wp_id) or 0)
|
||||
data["chokepoint"] = int(chokepoint.get(wp_id) or 0)
|
||||
data["visualSize"] = chokepoint_size(data["chokepoint"])
|
||||
|
||||
generated = datetime.now(timezone.utc).isoformat()
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -158,6 +158,13 @@ def test_indexed_depends_on_outranks_citation_fallback() -> None:
|
|||
if el["data"]["id"] == "workplan:wp-b"
|
||||
)
|
||||
assert chokepoint == 1
|
||||
sizes = {
|
||||
el["data"]["id"]: el["data"]["visualSize"]
|
||||
for el in payload["elements"]
|
||||
if el["data"]["id"].startswith("workplan:")
|
||||
}
|
||||
assert sizes["workplan:wp-b"] > sizes["workplan:wp-a"]
|
||||
assert all(e["edgeWidth"] > 0 for e in edges)
|
||||
|
||||
|
||||
def test_canonical_id_depends_on_resolves_to_hub_uuid() -> None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue