generated from coulomb/repo-seed
feat(classification-spine): implement STATE-WP-0065 repo-anchored model
Replace the ad-hoc coordination-domain spine with the Repo Classification Standard: 14 market domains, classification columns on managed_repos, and workplans anchored by repo_id (topic_id optional). - Add Alembic migration d8e9f0a1b2c3 with data backfill and workstream→workplan rename - Add api/classification.py validation and register-from-classification tooling - Expose workplan-first REST/MCP surface with legacy workstream aliases - Add C-24 consistency rule and legacy domain frontmatter mapping - Update dashboard repos page with category/capability/stake filters - Update orientation docs; mark STATE-WP-0065 finished
This commit is contained in:
@@ -7,7 +7,7 @@ from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
CANONICAL_WORKSTREAM_STATUSES: tuple[str, ...] = (
|
||||
CANONICAL_WORKPLAN_STATUSES: tuple[str, ...] = (
|
||||
"proposed",
|
||||
"ready",
|
||||
"active",
|
||||
@@ -17,22 +17,31 @@ CANONICAL_WORKSTREAM_STATUSES: tuple[str, ...] = (
|
||||
"archived",
|
||||
)
|
||||
|
||||
LEGACY_WORKSTREAM_STATUS_ALIASES: dict[str, str] = {
|
||||
LEGACY_WORKPLAN_STATUS_ALIASES: dict[str, str] = {
|
||||
"todo": "ready",
|
||||
"done": "finished",
|
||||
"completed": "finished",
|
||||
"accepted": "finished",
|
||||
}
|
||||
|
||||
SUPPORTED_WORKSTREAM_STATUSES: tuple[str, ...] = (
|
||||
*CANONICAL_WORKSTREAM_STATUSES,
|
||||
*LEGACY_WORKSTREAM_STATUS_ALIASES.keys(),
|
||||
SUPPORTED_WORKPLAN_STATUSES: tuple[str, ...] = (
|
||||
*CANONICAL_WORKPLAN_STATUSES,
|
||||
*LEGACY_WORKPLAN_STATUS_ALIASES.keys(),
|
||||
)
|
||||
|
||||
OPEN_WORKSTREAM_STATUSES: tuple[str, ...] = ("ready", "active", "blocked")
|
||||
CURRENT_WORKSTREAM_STATUSES: tuple[str, ...] = ("active", "blocked")
|
||||
CLOSED_WORKSTREAM_STATUSES: tuple[str, ...] = ("finished", "archived")
|
||||
PLANNING_WORKSTREAM_STATUSES: tuple[str, ...] = ("proposed", "ready", "backlog")
|
||||
OPEN_WORKPLAN_STATUSES: tuple[str, ...] = ("ready", "active", "blocked")
|
||||
CURRENT_WORKPLAN_STATUSES: tuple[str, ...] = ("active", "blocked")
|
||||
CLOSED_WORKPLAN_STATUSES: tuple[str, ...] = ("finished", "archived")
|
||||
PLANNING_WORKPLAN_STATUSES: tuple[str, ...] = ("proposed", "ready", "backlog")
|
||||
|
||||
# Legacy aliases (workstream terminology)
|
||||
CANONICAL_WORKSTREAM_STATUSES = CANONICAL_WORKPLAN_STATUSES
|
||||
LEGACY_WORKSTREAM_STATUS_ALIASES = LEGACY_WORKPLAN_STATUS_ALIASES
|
||||
SUPPORTED_WORKSTREAM_STATUSES = SUPPORTED_WORKPLAN_STATUSES
|
||||
OPEN_WORKSTREAM_STATUSES = OPEN_WORKPLAN_STATUSES
|
||||
CURRENT_WORKSTREAM_STATUSES = CURRENT_WORKPLAN_STATUSES
|
||||
CLOSED_WORKSTREAM_STATUSES = CLOSED_WORKPLAN_STATUSES
|
||||
PLANNING_WORKSTREAM_STATUSES = PLANNING_WORKPLAN_STATUSES
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -42,26 +51,38 @@ class ReadyReviewStatus:
|
||||
changed_paths: tuple[str, ...] = ()
|
||||
|
||||
|
||||
def normalize_workstream_status(status: Any, *, has_started: bool | None = None) -> str:
|
||||
def normalize_workplan_status(status: Any, *, has_started: bool | None = None) -> str:
|
||||
"""Return the canonical lifecycle status for a stored or legacy value."""
|
||||
value = _status_value(status)
|
||||
if value == "todo" and has_started:
|
||||
return "active"
|
||||
return LEGACY_WORKSTREAM_STATUS_ALIASES.get(value, value)
|
||||
return LEGACY_WORKPLAN_STATUS_ALIASES.get(value, value)
|
||||
|
||||
|
||||
def is_canonical_workstream_status(status: Any) -> bool:
|
||||
return _status_value(status) in CANONICAL_WORKSTREAM_STATUSES
|
||||
normalize_workstream_status = normalize_workplan_status
|
||||
|
||||
|
||||
def is_supported_workstream_status(status: Any) -> bool:
|
||||
return _status_value(status) in SUPPORTED_WORKSTREAM_STATUSES
|
||||
def is_canonical_workplan_status(status: Any) -> bool:
|
||||
return _status_value(status) in CANONICAL_WORKPLAN_STATUSES
|
||||
|
||||
|
||||
def workstream_has_started(task_statuses: list[Any] | tuple[Any, ...]) -> bool:
|
||||
is_canonical_workstream_status = is_canonical_workplan_status
|
||||
|
||||
|
||||
def is_supported_workplan_status(status: Any) -> bool:
|
||||
return _status_value(status) in SUPPORTED_WORKPLAN_STATUSES
|
||||
|
||||
|
||||
is_supported_workstream_status = is_supported_workplan_status
|
||||
|
||||
|
||||
def workplan_has_started(task_statuses: list[Any] | tuple[Any, ...]) -> bool:
|
||||
return any(_status_value(status) not in {"", "todo"} for status in task_statuses)
|
||||
|
||||
|
||||
workstream_has_started = workplan_has_started
|
||||
|
||||
|
||||
def ready_review_status(
|
||||
repo_dir: str | Path,
|
||||
reviewed_against_commit: Any,
|
||||
|
||||
Reference in New Issue
Block a user