Specify prj- drivers and cross-owner wait mode.
Some checks failed
CI Smoke / host-smoke (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run
check / test (push) Has been cancelled

COORDINATION-WP-0005: map project-repository workplans onto
CoordinationCase, refuse residual as a driver, and document the wait
mode without enabling live worker injection.

Assistant: grok
Assistant-Session: 01a09dc1-b21e-77e1-919e-fcad2f82b267
This commit is contained in:
tegwick 2026-09-14 16:46:45 +02:00
parent b69839b5ef
commit d2802fc55d
9 changed files with 582 additions and 6 deletions

View file

@ -0,0 +1,205 @@
"""Derive a project-driver CoordinationCase from hub-shaped JSON.
Does not author workplans, wake workers, or treat residual flavor as demand.
"""
from __future__ import annotations
from typing import Any
RESIDUAL = "residual"
PROJECT_CATEGORIES = frozenset({"project"})
OPEN_PLANS = frozenset({"proposed", "ready", "active", "blocked", "backlog"})
SATISFIED = frozenset({"done", "finished", "archived", "cancel"})
def repo_is_project(repo: dict[str, Any] | None) -> bool:
if not repo:
return False
slug = str(repo.get("slug") or "")
category = str(
repo.get("category")
or (repo.get("repo_classification") or {}).get("category")
or ""
)
flavor = str(repo.get("repo_flavor") or "")
return slug.startswith("prj-") or category in PROJECT_CATEGORIES or flavor == "project"
def workplan_is_residual(plan: dict[str, Any] | None) -> bool:
if not plan:
return False
return str(plan.get("flavor") or "").strip().lower() == RESIDUAL
def _index_repos(snapshot: dict[str, Any]) -> dict[str, dict[str, Any]]:
repos = snapshot.get("repos") or {}
if isinstance(repos, dict):
# Hub adapter snapshot uses {repo_id: slug}. Tests may pass full rows.
out: dict[str, dict[str, Any]] = {}
for key, value in repos.items():
if isinstance(value, dict):
out[str(value.get("id") or key)] = value
else:
out[str(key)] = {"id": key, "slug": value}
return out
return {str(row.get("id")): row for row in repos if isinstance(row, dict) and row.get("id")}
def _plans(snapshot: dict[str, Any]) -> dict[str, dict[str, Any]]:
rows = snapshot.get("plans") or snapshot.get("workplans") or []
return {str(row["id"]): row for row in rows if isinstance(row, dict) and row.get("id")}
def _depends_targets(plan: dict[str, Any]) -> list[str]:
raw = plan.get("depends_on")
if raw is None:
raw = plan.get("depends_on_workplans")
if raw is None:
return []
if not isinstance(raw, list):
raw = [raw]
out: list[str] = []
for item in raw:
if isinstance(item, dict):
target = item.get("workplan_id") or item.get("workstream_id") or item.get("id")
else:
target = item
if target:
out.append(str(target))
return out
def _related_ids(plan: dict[str, Any]) -> list[str]:
raw = plan.get("related") or plan.get("related_workplans") or []
if isinstance(raw, str):
return [raw]
return [str(item) for item in raw]
def _canonical(plan: dict[str, Any]) -> str:
return str(plan.get("record_id") or plan.get("slug") or plan.get("id") or "")
def _match_plan(plans: dict[str, dict[str, Any]], token: str) -> dict[str, Any] | None:
if token in plans:
return plans[token]
needle = token.lower().replace("_", "-")
for plan in plans.values():
slug = str(plan.get("slug") or "").lower().replace("_", "-")
record = str(plan.get("record_id") or "").lower()
if slug == needle or record == needle or slug.upper() == token.upper():
return plan
if str(plan.get("id")) == token:
return plan
return None
class ResidualDriverError(ValueError):
"""Raised when a residual workplan is asked to drive a case."""
class NotProjectDriverError(ValueError):
"""Raised when the selected workplan is not in a project repository."""
def build_driver_case(
snapshot: dict[str, Any],
workplan_id: str | None = None,
) -> dict[str, Any]:
"""Build a derived CoordinationCase from hub JSON.
Residual flavor is refused as a driver. Non-project workplans are refused
as drivers (use cross_owner_wait instead).
"""
repos = _index_repos(snapshot)
plans = _plans(snapshot)
if workplan_id:
plan = _match_plan(plans, workplan_id)
if plan is None:
raise KeyError(f"workplan not in snapshot: {workplan_id}")
else:
plan = next(
(
row
for row in plans.values()
if str(row.get("status") or "") in OPEN_PLANS
and repo_is_project(repos.get(str(row.get("repo_id"))))
and not workplan_is_residual(row)
),
None,
)
if plan is None:
raise NotProjectDriverError("no open project-repository workplan in snapshot")
if workplan_is_residual(plan):
raise ResidualDriverError("residual flavor is not a coordination driver")
repo = repos.get(str(plan.get("repo_id")))
if not repo_is_project(repo):
raise NotProjectDriverError("workplan repo is not a project repository")
repo_slug = str((repo or {}).get("slug") or "")
driver_id = str(plan["id"])
implementers = []
seen_repos: set[str] = set()
commitments = []
for token in _depends_targets(plan):
target = _match_plan(plans, token)
commitments.append(
{
"kind": "completion",
"obligor_workplan_id": str(target["id"]) if target else token,
"beneficiary_workplan_id": driver_id,
"state": (
"satisfied"
if target and str(target.get("status") or "") in SATISFIED
else "active"
),
}
)
if target:
t_repo = repos.get(str(target.get("repo_id")))
slug = str((t_repo or {}).get("slug") or "")
if slug and slug not in seen_repos and slug != repo_slug:
seen_repos.add(slug)
implementers.append(
{
"repo": slug,
"workplan_id": str(target["id"]),
"role": "implementer",
}
)
for token in _related_ids(plan):
target = _match_plan(plans, token)
if not target:
continue
t_repo = repos.get(str(target.get("repo_id")))
slug = str((t_repo or {}).get("slug") or "")
if slug and slug not in seen_repos and slug != repo_slug:
seen_repos.add(slug)
implementers.append(
{
"repo": slug,
"workplan_id": str(target["id"]),
"role": "implementer",
}
)
flavor = str(plan.get("flavor") or "").strip().lower() or None
return {
"id": f"case:prj:{repo_slug}:{driver_id}",
"scenario_type": "project_driver",
"driver_workplan_id": driver_id,
"driver_repo": repo_slug,
"flavor": flavor,
"goal": plan.get("title"),
"implementers": implementers,
"commitments": commitments,
"actionable": True,
}
def actionable_demand(plan: dict[str, Any]) -> bool:
"""False for residual flavor. Unspecified flavor is relevant."""
return not workplan_is_residual(plan)