state-hub/api/schemas/managed_repo.py

179 lines
5.1 KiB
Python
Raw Normal View History

feat(state-hub): implement v0.5 — dynamic domains & multi-repo Replaces the hardcoded 6-domain PostgreSQL ENUM with a first-class `domains` DB table, and adds a `managed_repos` table for multi-repo support per domain. P1 — Domain as a DB entity: - Migration b1c2d3e4f5a6: creates `domains` table, migrates topics.domain ENUM column to domain_id FK, drops the domain ENUM type - Domain ORM model (api/models/domain.py) + Pydantic schemas - Domain API router: GET/POST /domains/, GET/PATCH /domains/{slug}/, rename and archive endpoints with EP/TD cascade on rename - Topic model updated: domain_id FK + @property domain_slug for backwards-compatible JSON serialization (field renamed domain → domain_slug) - TopicCreate/TopicRead updated; seed.py rewritten to use FK lookup P2 — Multi-repo support: - ManagedRepo ORM model (api/models/managed_repo.py) + schemas - Repo API router: GET/POST /repos/, GET/PATCH /repos/{slug}/, archive - Makefile: add-domain, rename-domain, add-repo, list-repos targets - register_project.sh: verify domain via /domains/ API + POST /repos/ P3 — MCP tools & live validation: - 6 new MCP tools: list_domains, create_domain, rename_domain, archive_domain, list_domain_repos, register_repo - EP/TD routers: replace hardcoded VALID_DOMAINS set with per-request DB lookup — returns 422 with list of valid slugs on unknown domain - State summary: adds domains: list[DomainSummary] (slug, name, repo_count, active_workstream_count, ep_count, td_count) - TOOLS.md updated with domain management section P4 — Dashboard: - New domains.md page with KPI row + domain cards + repo lists - domains.json.py + repos.json.py data loaders - Domains page added to observablehq.config.js nav - workstreams.md, extensions.md, techdept.md: domain_slug fix + dynamic domain list loaded from /domains/ API (no longer hardcoded) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:20:15 +01:00
import uuid
from datetime import date, datetime
2026-05-04 19:18:10 +02:00
from typing import Any, Literal
feat(state-hub): implement v0.5 — dynamic domains & multi-repo Replaces the hardcoded 6-domain PostgreSQL ENUM with a first-class `domains` DB table, and adds a `managed_repos` table for multi-repo support per domain. P1 — Domain as a DB entity: - Migration b1c2d3e4f5a6: creates `domains` table, migrates topics.domain ENUM column to domain_id FK, drops the domain ENUM type - Domain ORM model (api/models/domain.py) + Pydantic schemas - Domain API router: GET/POST /domains/, GET/PATCH /domains/{slug}/, rename and archive endpoints with EP/TD cascade on rename - Topic model updated: domain_id FK + @property domain_slug for backwards-compatible JSON serialization (field renamed domain → domain_slug) - TopicCreate/TopicRead updated; seed.py rewritten to use FK lookup P2 — Multi-repo support: - ManagedRepo ORM model (api/models/managed_repo.py) + schemas - Repo API router: GET/POST /repos/, GET/PATCH /repos/{slug}/, archive - Makefile: add-domain, rename-domain, add-repo, list-repos targets - register_project.sh: verify domain via /domains/ API + POST /repos/ P3 — MCP tools & live validation: - 6 new MCP tools: list_domains, create_domain, rename_domain, archive_domain, list_domain_repos, register_repo - EP/TD routers: replace hardcoded VALID_DOMAINS set with per-request DB lookup — returns 422 with list of valid slugs on unknown domain - State summary: adds domains: list[DomainSummary] (slug, name, repo_count, active_workstream_count, ep_count, td_count) - TOOLS.md updated with domain management section P4 — Dashboard: - New domains.md page with KPI row + domain cards + repo lists - domains.json.py + repos.json.py data loaders - Domains page added to observablehq.config.js nav - workstreams.md, extensions.md, techdept.md: domain_slug fix + dynamic domain list loaded from /domains/ API (no longer hardcoded) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:20:15 +01:00
from fastapi import HTTPException
from pydantic import BaseModel, Field, model_validator
feat(state-hub): implement v0.5 — dynamic domains & multi-repo Replaces the hardcoded 6-domain PostgreSQL ENUM with a first-class `domains` DB table, and adds a `managed_repos` table for multi-repo support per domain. P1 — Domain as a DB entity: - Migration b1c2d3e4f5a6: creates `domains` table, migrates topics.domain ENUM column to domain_id FK, drops the domain ENUM type - Domain ORM model (api/models/domain.py) + Pydantic schemas - Domain API router: GET/POST /domains/, GET/PATCH /domains/{slug}/, rename and archive endpoints with EP/TD cascade on rename - Topic model updated: domain_id FK + @property domain_slug for backwards-compatible JSON serialization (field renamed domain → domain_slug) - TopicCreate/TopicRead updated; seed.py rewritten to use FK lookup P2 — Multi-repo support: - ManagedRepo ORM model (api/models/managed_repo.py) + schemas - Repo API router: GET/POST /repos/, GET/PATCH /repos/{slug}/, archive - Makefile: add-domain, rename-domain, add-repo, list-repos targets - register_project.sh: verify domain via /domains/ API + POST /repos/ P3 — MCP tools & live validation: - 6 new MCP tools: list_domains, create_domain, rename_domain, archive_domain, list_domain_repos, register_repo - EP/TD routers: replace hardcoded VALID_DOMAINS set with per-request DB lookup — returns 422 with list of valid slugs on unknown domain - State summary: adds domains: list[DomainSummary] (slug, name, repo_count, active_workstream_count, ep_count, td_count) - TOOLS.md updated with domain management section P4 — Dashboard: - New domains.md page with KPI row + domain cards + repo lists - domains.json.py + repos.json.py data loaders - Domains page added to observablehq.config.js nav - workstreams.md, extensions.md, techdept.md: domain_slug fix + dynamic domain list loaded from /domains/ API (no longer hardcoded) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:20:15 +01:00
from api.classification import validate_classification
2026-06-07 16:32:16 +02:00
from hub_core.schemas.managed_repo import (
RepoCreate as CoreRepoCreate,
RepoPathRegister,
RepoRead as CoreRepoRead,
)
feat(state-hub): implement v0.5 — dynamic domains & multi-repo Replaces the hardcoded 6-domain PostgreSQL ENUM with a first-class `domains` DB table, and adds a `managed_repos` table for multi-repo support per domain. P1 — Domain as a DB entity: - Migration b1c2d3e4f5a6: creates `domains` table, migrates topics.domain ENUM column to domain_id FK, drops the domain ENUM type - Domain ORM model (api/models/domain.py) + Pydantic schemas - Domain API router: GET/POST /domains/, GET/PATCH /domains/{slug}/, rename and archive endpoints with EP/TD cascade on rename - Topic model updated: domain_id FK + @property domain_slug for backwards-compatible JSON serialization (field renamed domain → domain_slug) - TopicCreate/TopicRead updated; seed.py rewritten to use FK lookup P2 — Multi-repo support: - ManagedRepo ORM model (api/models/managed_repo.py) + schemas - Repo API router: GET/POST /repos/, GET/PATCH /repos/{slug}/, archive - Makefile: add-domain, rename-domain, add-repo, list-repos targets - register_project.sh: verify domain via /domains/ API + POST /repos/ P3 — MCP tools & live validation: - 6 new MCP tools: list_domains, create_domain, rename_domain, archive_domain, list_domain_repos, register_repo - EP/TD routers: replace hardcoded VALID_DOMAINS set with per-request DB lookup — returns 422 with list of valid slugs on unknown domain - State summary: adds domains: list[DomainSummary] (slug, name, repo_count, active_workstream_count, ep_count, td_count) - TOOLS.md updated with domain management section P4 — Dashboard: - New domains.md page with KPI row + domain cards + repo lists - domains.json.py + repos.json.py data loaders - Domains page added to observablehq.config.js nav - workstreams.md, extensions.md, techdept.md: domain_slug fix + dynamic domain list loaded from /domains/ API (no longer hardcoded) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:20:15 +01:00
2026-06-07 16:32:16 +02:00
class ClassificationFields(BaseModel):
category: str | None = None
secondary_domains: list[str] | None = None
capability_tags: list[str] | None = None
business_stake: list[str] | None = None
business_mechanics: list[str] | None = None
classified_at: date | None = None
classified_by: str | None = None
standard_version: str | None = None
def classification_fields_set(data: dict[str, Any]) -> bool:
keys = (
"category",
"secondary_domains",
"capability_tags",
"business_stake",
"business_mechanics",
"classified_at",
"classified_by",
"standard_version",
)
return any(data.get(key) is not None for key in keys)
def validate_repo_classification_fields(
*,
domain_slug: str,
fields: dict[str, Any],
require_complete: bool = False,
) -> dict[str, Any]:
"""Validate classification fields and return normalized values for persistence."""
if not classification_fields_set(fields) and not require_complete:
return fields
block = {
"category": fields.get("category"),
"domain": domain_slug,
"secondary_domains": fields.get("secondary_domains") or [],
"capability_tags": fields.get("capability_tags") or [],
"business_stake": fields.get("business_stake") or [],
"business_mechanics": fields.get("business_mechanics") or [],
}
if require_complete or fields.get("category") is not None:
if block["category"] is None:
raise HTTPException(status_code=422, detail="`category` is required when classification is provided")
if classification_fields_set(fields) and block["category"] is not None:
errors, warnings = validate_classification(block)
if errors:
raise HTTPException(status_code=422, detail={"classification_errors": errors, "warnings": warnings})
return fields
class RepoCreate(CoreRepoCreate, ClassificationFields):
feat(state-hub): implement v0.5 — dynamic domains & multi-repo Replaces the hardcoded 6-domain PostgreSQL ENUM with a first-class `domains` DB table, and adds a `managed_repos` table for multi-repo support per domain. P1 — Domain as a DB entity: - Migration b1c2d3e4f5a6: creates `domains` table, migrates topics.domain ENUM column to domain_id FK, drops the domain ENUM type - Domain ORM model (api/models/domain.py) + Pydantic schemas - Domain API router: GET/POST /domains/, GET/PATCH /domains/{slug}/, rename and archive endpoints with EP/TD cascade on rename - Topic model updated: domain_id FK + @property domain_slug for backwards-compatible JSON serialization (field renamed domain → domain_slug) - TopicCreate/TopicRead updated; seed.py rewritten to use FK lookup P2 — Multi-repo support: - ManagedRepo ORM model (api/models/managed_repo.py) + schemas - Repo API router: GET/POST /repos/, GET/PATCH /repos/{slug}/, archive - Makefile: add-domain, rename-domain, add-repo, list-repos targets - register_project.sh: verify domain via /domains/ API + POST /repos/ P3 — MCP tools & live validation: - 6 new MCP tools: list_domains, create_domain, rename_domain, archive_domain, list_domain_repos, register_repo - EP/TD routers: replace hardcoded VALID_DOMAINS set with per-request DB lookup — returns 422 with list of valid slugs on unknown domain - State summary: adds domains: list[DomainSummary] (slug, name, repo_count, active_workstream_count, ep_count, td_count) - TOOLS.md updated with domain management section P4 — Dashboard: - New domains.md page with KPI row + domain cards + repo lists - domains.json.py + repos.json.py data loaders - Domains page added to observablehq.config.js nav - workstreams.md, extensions.md, techdept.md: domain_slug fix + dynamic domain list loaded from /domains/ API (no longer hardcoded) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:20:15 +01:00
topic_id: uuid.UUID | None = None
@model_validator(mode="after")
def validate_classification_on_create(self) -> "RepoCreate":
validate_repo_classification_fields(
domain_slug=self.domain_slug,
fields=self.model_dump(),
require_complete=classification_fields_set(self.model_dump()),
)
return self
feat(state-hub): implement v0.5 — dynamic domains & multi-repo Replaces the hardcoded 6-domain PostgreSQL ENUM with a first-class `domains` DB table, and adds a `managed_repos` table for multi-repo support per domain. P1 — Domain as a DB entity: - Migration b1c2d3e4f5a6: creates `domains` table, migrates topics.domain ENUM column to domain_id FK, drops the domain ENUM type - Domain ORM model (api/models/domain.py) + Pydantic schemas - Domain API router: GET/POST /domains/, GET/PATCH /domains/{slug}/, rename and archive endpoints with EP/TD cascade on rename - Topic model updated: domain_id FK + @property domain_slug for backwards-compatible JSON serialization (field renamed domain → domain_slug) - TopicCreate/TopicRead updated; seed.py rewritten to use FK lookup P2 — Multi-repo support: - ManagedRepo ORM model (api/models/managed_repo.py) + schemas - Repo API router: GET/POST /repos/, GET/PATCH /repos/{slug}/, archive - Makefile: add-domain, rename-domain, add-repo, list-repos targets - register_project.sh: verify domain via /domains/ API + POST /repos/ P3 — MCP tools & live validation: - 6 new MCP tools: list_domains, create_domain, rename_domain, archive_domain, list_domain_repos, register_repo - EP/TD routers: replace hardcoded VALID_DOMAINS set with per-request DB lookup — returns 422 with list of valid slugs on unknown domain - State summary: adds domains: list[DomainSummary] (slug, name, repo_count, active_workstream_count, ep_count, td_count) - TOOLS.md updated with domain management section P4 — Dashboard: - New domains.md page with KPI row + domain cards + repo lists - domains.json.py + repos.json.py data loaders - Domains page added to observablehq.config.js nav - workstreams.md, extensions.md, techdept.md: domain_slug fix + dynamic domain list loaded from /domains/ API (no longer hardcoded) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:20:15 +01:00
class RepoUpdate(ClassificationFields):
feat(state-hub): implement v0.5 — dynamic domains & multi-repo Replaces the hardcoded 6-domain PostgreSQL ENUM with a first-class `domains` DB table, and adds a `managed_repos` table for multi-repo support per domain. P1 — Domain as a DB entity: - Migration b1c2d3e4f5a6: creates `domains` table, migrates topics.domain ENUM column to domain_id FK, drops the domain ENUM type - Domain ORM model (api/models/domain.py) + Pydantic schemas - Domain API router: GET/POST /domains/, GET/PATCH /domains/{slug}/, rename and archive endpoints with EP/TD cascade on rename - Topic model updated: domain_id FK + @property domain_slug for backwards-compatible JSON serialization (field renamed domain → domain_slug) - TopicCreate/TopicRead updated; seed.py rewritten to use FK lookup P2 — Multi-repo support: - ManagedRepo ORM model (api/models/managed_repo.py) + schemas - Repo API router: GET/POST /repos/, GET/PATCH /repos/{slug}/, archive - Makefile: add-domain, rename-domain, add-repo, list-repos targets - register_project.sh: verify domain via /domains/ API + POST /repos/ P3 — MCP tools & live validation: - 6 new MCP tools: list_domains, create_domain, rename_domain, archive_domain, list_domain_repos, register_repo - EP/TD routers: replace hardcoded VALID_DOMAINS set with per-request DB lookup — returns 422 with list of valid slugs on unknown domain - State summary: adds domains: list[DomainSummary] (slug, name, repo_count, active_workstream_count, ep_count, td_count) - TOOLS.md updated with domain management section P4 — Dashboard: - New domains.md page with KPI row + domain cards + repo lists - domains.json.py + repos.json.py data loaders - Domains page added to observablehq.config.js nav - workstreams.md, extensions.md, techdept.md: domain_slug fix + dynamic domain list loaded from /domains/ API (no longer hardcoded) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:20:15 +01:00
name: str | None = None
local_path: str | None = None
remote_url: str | None = None
git_fingerprint: str | None = None
feat(state-hub): implement v0.5 — dynamic domains & multi-repo Replaces the hardcoded 6-domain PostgreSQL ENUM with a first-class `domains` DB table, and adds a `managed_repos` table for multi-repo support per domain. P1 — Domain as a DB entity: - Migration b1c2d3e4f5a6: creates `domains` table, migrates topics.domain ENUM column to domain_id FK, drops the domain ENUM type - Domain ORM model (api/models/domain.py) + Pydantic schemas - Domain API router: GET/POST /domains/, GET/PATCH /domains/{slug}/, rename and archive endpoints with EP/TD cascade on rename - Topic model updated: domain_id FK + @property domain_slug for backwards-compatible JSON serialization (field renamed domain → domain_slug) - TopicCreate/TopicRead updated; seed.py rewritten to use FK lookup P2 — Multi-repo support: - ManagedRepo ORM model (api/models/managed_repo.py) + schemas - Repo API router: GET/POST /repos/, GET/PATCH /repos/{slug}/, archive - Makefile: add-domain, rename-domain, add-repo, list-repos targets - register_project.sh: verify domain via /domains/ API + POST /repos/ P3 — MCP tools & live validation: - 6 new MCP tools: list_domains, create_domain, rename_domain, archive_domain, list_domain_repos, register_repo - EP/TD routers: replace hardcoded VALID_DOMAINS set with per-request DB lookup — returns 422 with list of valid slugs on unknown domain - State summary: adds domains: list[DomainSummary] (slug, name, repo_count, active_workstream_count, ep_count, td_count) - TOOLS.md updated with domain management section P4 — Dashboard: - New domains.md page with KPI row + domain cards + repo lists - domains.json.py + repos.json.py data loaders - Domains page added to observablehq.config.js nav - workstreams.md, extensions.md, techdept.md: domain_slug fix + dynamic domain list loaded from /domains/ API (no longer hardcoded) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:20:15 +01:00
description: str | None = None
topic_id: uuid.UUID | None = None
last_state_synced_at: datetime | None = None
feat(state-hub): implement v0.5 — dynamic domains & multi-repo Replaces the hardcoded 6-domain PostgreSQL ENUM with a first-class `domains` DB table, and adds a `managed_repos` table for multi-repo support per domain. P1 — Domain as a DB entity: - Migration b1c2d3e4f5a6: creates `domains` table, migrates topics.domain ENUM column to domain_id FK, drops the domain ENUM type - Domain ORM model (api/models/domain.py) + Pydantic schemas - Domain API router: GET/POST /domains/, GET/PATCH /domains/{slug}/, rename and archive endpoints with EP/TD cascade on rename - Topic model updated: domain_id FK + @property domain_slug for backwards-compatible JSON serialization (field renamed domain → domain_slug) - TopicCreate/TopicRead updated; seed.py rewritten to use FK lookup P2 — Multi-repo support: - ManagedRepo ORM model (api/models/managed_repo.py) + schemas - Repo API router: GET/POST /repos/, GET/PATCH /repos/{slug}/, archive - Makefile: add-domain, rename-domain, add-repo, list-repos targets - register_project.sh: verify domain via /domains/ API + POST /repos/ P3 — MCP tools & live validation: - 6 new MCP tools: list_domains, create_domain, rename_domain, archive_domain, list_domain_repos, register_repo - EP/TD routers: replace hardcoded VALID_DOMAINS set with per-request DB lookup — returns 422 with list of valid slugs on unknown domain - State summary: adds domains: list[DomainSummary] (slug, name, repo_count, active_workstream_count, ep_count, td_count) - TOOLS.md updated with domain management section P4 — Dashboard: - New domains.md page with KPI row + domain cards + repo lists - domains.json.py + repos.json.py data loaders - Domains page added to observablehq.config.js nav - workstreams.md, extensions.md, techdept.md: domain_slug fix + dynamic domain list loaded from /domains/ API (no longer hardcoded) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:20:15 +01:00
2026-05-04 19:18:10 +02:00
class RepoOnboardRequest(BaseModel):
"""Start scripted onboarding for a working copy that is visible to State Hub."""
domain_slug: str
project_path: str
agent_profile: Literal["claude-code", "codex"] = "codex"
additional: bool = False
class RepoOnboardResult(BaseModel):
ok: bool
repo_slug: str | None = None
agent_profile: str
command: list[str]
stdout: str = ""
stderr: str = ""
class RepoRead(CoreRepoRead, ClassificationFields):
feat(state-hub): implement v0.5 — dynamic domains & multi-repo Replaces the hardcoded 6-domain PostgreSQL ENUM with a first-class `domains` DB table, and adds a `managed_repos` table for multi-repo support per domain. P1 — Domain as a DB entity: - Migration b1c2d3e4f5a6: creates `domains` table, migrates topics.domain ENUM column to domain_id FK, drops the domain ENUM type - Domain ORM model (api/models/domain.py) + Pydantic schemas - Domain API router: GET/POST /domains/, GET/PATCH /domains/{slug}/, rename and archive endpoints with EP/TD cascade on rename - Topic model updated: domain_id FK + @property domain_slug for backwards-compatible JSON serialization (field renamed domain → domain_slug) - TopicCreate/TopicRead updated; seed.py rewritten to use FK lookup P2 — Multi-repo support: - ManagedRepo ORM model (api/models/managed_repo.py) + schemas - Repo API router: GET/POST /repos/, GET/PATCH /repos/{slug}/, archive - Makefile: add-domain, rename-domain, add-repo, list-repos targets - register_project.sh: verify domain via /domains/ API + POST /repos/ P3 — MCP tools & live validation: - 6 new MCP tools: list_domains, create_domain, rename_domain, archive_domain, list_domain_repos, register_repo - EP/TD routers: replace hardcoded VALID_DOMAINS set with per-request DB lookup — returns 422 with list of valid slugs on unknown domain - State summary: adds domains: list[DomainSummary] (slug, name, repo_count, active_workstream_count, ep_count, td_count) - TOOLS.md updated with domain management section P4 — Dashboard: - New domains.md page with KPI row + domain cards + repo lists - domains.json.py + repos.json.py data loaders - Domains page added to observablehq.config.js nav - workstreams.md, extensions.md, techdept.md: domain_slug fix + dynamic domain list loaded from /domains/ API (no longer hardcoded) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:20:15 +01:00
topic_id: uuid.UUID | None = None
sbom_source: str | None = None
last_sbom_at: datetime | None = None
last_state_synced_at: datetime | None = None
feat(state-hub): implement v0.5 — dynamic domains & multi-repo Replaces the hardcoded 6-domain PostgreSQL ENUM with a first-class `domains` DB table, and adds a `managed_repos` table for multi-repo support per domain. P1 — Domain as a DB entity: - Migration b1c2d3e4f5a6: creates `domains` table, migrates topics.domain ENUM column to domain_id FK, drops the domain ENUM type - Domain ORM model (api/models/domain.py) + Pydantic schemas - Domain API router: GET/POST /domains/, GET/PATCH /domains/{slug}/, rename and archive endpoints with EP/TD cascade on rename - Topic model updated: domain_id FK + @property domain_slug for backwards-compatible JSON serialization (field renamed domain → domain_slug) - TopicCreate/TopicRead updated; seed.py rewritten to use FK lookup P2 — Multi-repo support: - ManagedRepo ORM model (api/models/managed_repo.py) + schemas - Repo API router: GET/POST /repos/, GET/PATCH /repos/{slug}/, archive - Makefile: add-domain, rename-domain, add-repo, list-repos targets - register_project.sh: verify domain via /domains/ API + POST /repos/ P3 — MCP tools & live validation: - 6 new MCP tools: list_domains, create_domain, rename_domain, archive_domain, list_domain_repos, register_repo - EP/TD routers: replace hardcoded VALID_DOMAINS set with per-request DB lookup — returns 422 with list of valid slugs on unknown domain - State summary: adds domains: list[DomainSummary] (slug, name, repo_count, active_workstream_count, ep_count, td_count) - TOOLS.md updated with domain management section P4 — Dashboard: - New domains.md page with KPI row + domain cards + repo lists - domains.json.py + repos.json.py data loaders - Domains page added to observablehq.config.js nav - workstreams.md, extensions.md, techdept.md: domain_slug fix + dynamic domain list loaded from /domains/ API (no longer hardcoded) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:20:15 +01:00
created_at: datetime
updated_at: datetime
class DispatchTask(BaseModel):
id: uuid.UUID
title: str
priority: str
status: str
needs_human: bool
class DispatchWorkplan(BaseModel):
id: uuid.UUID
title: str
status: str
pending_tasks: list[DispatchTask]
# Legacy alias
DispatchWorkstream = DispatchWorkplan
class PendingInterfaceChange(BaseModel):
id: uuid.UUID
title: str
change_type: str
interface_type: str
origin_repo_slug: str
affected_paths: list[str]
planned_for: date | None
published_at: datetime | None
2026-05-01 01:33:15 +02:00
class ScopeIssueDetail(BaseModel):
id: str
label: str
status: str
detail: str
missing_sections: list[str] = Field(default_factory=list)
invalid_capability_blocks: list[dict[str, Any]] = Field(default_factory=list)
needs_refresh_sections: list[str] = Field(default_factory=list)
class RepoDispatch(BaseModel):
repo_slug: str
active_goal: dict[str, Any] | None
active_workplans: list[DispatchWorkplan]
human_interventions: list[DispatchTask]
pending_interface_changes: list[PendingInterfaceChange]
2026-05-01 01:33:15 +02:00
scope_needs_review: bool
scope_issue_details: list[ScopeIssueDetail]
last_state_synced_at: datetime | None
2026-05-01 01:47:14 +02:00
@property
def active_workstreams(self) -> list[DispatchWorkplan]:
return self.active_workplans
2026-05-01 01:47:14 +02:00
class RepoScopeHealth(BaseModel):
repo_slug: str
domain_slug: str | None = None
local_path: str | None = None
path_available: bool
scope_needs_review: bool
scope_issue_details: list[ScopeIssueDetail]