141 lines
6.6 KiB
Python
141 lines
6.6 KiB
Python
"""Coverage vocabulary derived from role, family, artifact and workflow contracts."""
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from typing import Any
|
|
|
|
RISK_ROLE_HINTS = {
|
|
"security": {"SEC-ENGINEER", "SEC-APPSEC", "SEC-CHAMPION", "SEC-DEVSECOPS"},
|
|
"privacy": {"SEC-APPSEC", "GTM-LEGAL"},
|
|
"legal": {"GTM-LEGAL"},
|
|
"reliability": {"SRE", "INFRA-PLATFORM", "EXEC-VPENG"},
|
|
"quality": {"QA", "EXEC-VPENG"},
|
|
"financial": {"EXEC-CFO", "GTM-PRICING", "CONSULT-FIN"},
|
|
"user-harm": {"QA", "EXEC-CPO", "SEC-APPSEC"},
|
|
}
|
|
|
|
# Workload-profile.required-capabilities is an executable coverage contract.
|
|
# Keep the mapping concrete: a family label by itself must not satisfy a role
|
|
# specific need such as competitive intelligence.
|
|
CAPABILITY_ROLE_HINTS = {
|
|
"product": {"EXEC-CPO", "PROD-PM", "PROD-PO", "PROD-TPO", "PROD-PPO"},
|
|
"product-delivery": {"PROD-PM", "PROD-PO", "PROD-TPO", "PROD-PPO", "EXEC-VPENG"},
|
|
"customer-research": {"UX-RESEARCHER", "DATA-ANALYST"},
|
|
"competitive-intelligence": {"GTM-CI"},
|
|
"revenue": {"GTM-REVOPS", "GTM-PRICING", "GTM-SALES", "GTM-GROWTHPM"},
|
|
"gtm": {"GTM-CI", "GTM-PMM", "GTM-DEMANDGEN", "GTM-SALES", "GTM-REVOPS"},
|
|
"finance": {"EXEC-CFO", "CONSULT-FIN", "GTM-PRICING"},
|
|
"strategy": {"STR-ANALYST", "CONSULT-STRAT"},
|
|
"operations": {"EXEC-COO", "OPS-CH", "OPS-CREW", "CONSULT-OPS"},
|
|
"design": {"DES-DIRECTOR", "DES-PROD", "DES-PLATFORM", "DES-INTERNAL", "DES-VISUAL"},
|
|
"information-architecture": {"DOC-IA"},
|
|
"technical": {"EXEC-CTO", "EXEC-CPTO", "ARCH-TECH", "ARCH-SOLUTION"},
|
|
"architecture": {"ARCH-EA", "ARCH-SOLUTION", "ARCH-APP", "ARCH-TECH", "ARCH-SWAT"},
|
|
"engineering": {"EXEC-VPENG", "ENG-FE", "ENG-BE", "ENG-SW"},
|
|
"frontend": {"ENG-FE", "ENG-FEPLAT", "ENG-FEUX"},
|
|
"backend": {"ENG-BE", "ENG-BEGEN", "ENG-PRODSERVER", "ENG-PLATSERVER", "ENG-SW"},
|
|
"public-api": {"ARCH-APP", "ARCH-TECH", "ENG-BE", "ENG-PRODSERVER"},
|
|
"persistence": {"ARCH-DATA", "DATA-ENGINEER", "ENG-BE"},
|
|
"platform": {"INFRA-PLATFORM", "ENG-FEPLAT", "ENG-PLATSERVER", "PROD-PPO"},
|
|
"data": {"ARCH-DATA", "DATA-ENGINEER", "DATA-BIGDATA", "DATA-ANALYST"},
|
|
"security": {"SEC-ENGINEER", "SEC-APPSEC", "SEC-CHAMPION", "SEC-DEVSECOPS"},
|
|
"privacy": {"SEC-APPSEC", "GTM-LEGAL"},
|
|
"legal": {"GTM-LEGAL"},
|
|
"quality": {"QA", "EXEC-VPENG"},
|
|
"kpi-test": {"DATA-ANALYST", "QA"},
|
|
"infrastructure": {"INFRA-DEV", "INFRA-PLATFORM", "INFRA-DEVOPS", "SRE"},
|
|
"documentation": {"DOC-LEAD", "DOC-WRITER", "DOC-IA", "DOC-VISUAL", "DOC-EDU"},
|
|
}
|
|
|
|
|
|
def tokens(value: Any) -> set[str]:
|
|
if value is None:
|
|
return set()
|
|
if isinstance(value, dict):
|
|
value = " ".join(f"{key} {item}" for key, item in value.items())
|
|
elif isinstance(value, (list, tuple, set)):
|
|
value = " ".join(str(item) for item in value)
|
|
return {part for part in re.split(r"[^\w]+", str(value).lower(), flags=re.UNICODE)
|
|
if len(part) > 1 and part != "_"}
|
|
|
|
|
|
def artifact_maps(artifact_registry: dict[str, Any]) -> tuple[dict[str, set[str]], dict[str, set[str]]]:
|
|
producer: dict[str, set[str]] = {}
|
|
reviewer: dict[str, set[str]] = {}
|
|
for kind, definition in (artifact_registry.get("artifact-kinds") or {}).items():
|
|
for role in definition.get("producer-roles", []) or []:
|
|
producer.setdefault(str(role), set()).add(str(kind))
|
|
capability = definition.get("reviewer-capability")
|
|
if capability:
|
|
reviewer.setdefault(str(capability), set()).add(str(kind))
|
|
return producer, reviewer
|
|
|
|
|
|
def role_coverage(
|
|
role: dict[str, Any],
|
|
family: dict[str, Any],
|
|
profile: dict[str, Any] | None,
|
|
artifact_registry: dict[str, Any],
|
|
role_capabilities: dict[str, list[str]],
|
|
) -> set[str]:
|
|
role_id = str(role.get("role-id"))
|
|
family_id = str(family.get("family-id"))
|
|
producer, reviewer_kinds = artifact_maps(artifact_registry)
|
|
coverage = {"owner", f"family:{family_id}", f"owner:{family_id}", f"role:{role_id}"}
|
|
coverage |= {f"lens:{lens}" for lens in family.get("carries-lenses", []) or []}
|
|
if family.get("audit-capable"):
|
|
coverage.add("lens:LENS-CONTRARIAN")
|
|
coverage |= {f"artifact:{kind}" for kind in producer.get(role_id, set())}
|
|
for capability, roles in role_capabilities.items():
|
|
if role_id in set(roles or []):
|
|
coverage.add(f"capability:{capability}")
|
|
coverage |= {f"review:{kind}" for kind in reviewer_kinds.get(capability, set())}
|
|
for capability, role_ids in CAPABILITY_ROLE_HINTS.items():
|
|
if role_id in role_ids:
|
|
coverage.add(f"capability:{capability}")
|
|
if role.get("is-decision-maker"):
|
|
coverage.add("authority")
|
|
if role.get("role-type") in {"auditor", "reviewer"} or family.get("audit-capable"):
|
|
coverage.add("independent-review")
|
|
if role.get("is-execution-agent"):
|
|
coverage.add("implementation")
|
|
for risk, role_ids in RISK_ROLE_HINTS.items():
|
|
if role_id in role_ids:
|
|
coverage.add(f"risk:{risk}")
|
|
searchable = " ".join([
|
|
role_id,
|
|
str(role.get("role-name") or ""),
|
|
str((profile or {}).get("perspective") or ""),
|
|
str((profile or {}).get("scope") or ""),
|
|
" ".join((profile or {}).get("responsibilities", []) or []),
|
|
])
|
|
coverage |= {f"keyword:{token}" for token in tokens(searchable)}
|
|
return coverage
|
|
|
|
|
|
def required_coverage(profile: dict[str, Any], candidate_family_ids: list[str]) -> set[str]:
|
|
required = {str(item) for item in profile.get("required-coverage", []) or []}
|
|
required_families = profile.get("required-families", []) or []
|
|
if isinstance(required_families, str):
|
|
required_families = [required_families]
|
|
required |= {f"owner:{family_id}" for family_id in required_families}
|
|
if candidate_family_ids:
|
|
required.add("owner")
|
|
required |= {f"artifact:{kind}" for kind in profile.get("required-artifacts", []) or []}
|
|
capabilities = profile.get("required-capabilities", []) or []
|
|
if isinstance(capabilities, str):
|
|
capabilities = [capabilities]
|
|
required |= {f"capability:{str(capability).strip().lower()}"
|
|
for capability in capabilities if str(capability or "").strip()}
|
|
risks = profile.get("risks", []) or []
|
|
if isinstance(risks, dict):
|
|
risks = [key for key, value in risks.items() if value]
|
|
required |= {f"risk:{str(risk).lower()}" for risk in risks}
|
|
if profile.get("authority-required"):
|
|
required.add("authority")
|
|
if profile.get("implementation-required") or profile.get("workflow-stage") in {"build", "run"}:
|
|
required.add("implementation")
|
|
if profile.get("independent-review-required"):
|
|
required.add("independent-review")
|
|
return required
|