feat(playbook): Implementation Playbooks — the Berater renderer ("wie komme ich dort hin?")

Roadmap item 4. After WHAT applies / WHAT is missing / WHICH first, the GF asks HOW. The
Implementation Playbook renders, for one capability, the full journey — why / which regulations
it closes / tools / process / evidence / controls — and chains the Optimization Roadmap into
per-measure playbooks. Another renderer over the same Capability spine (ADR-003/004), not a new
engine: ~95% of the data already exists, it just needs a different rendering.

- compliance/playbook/: build_playbook() + playbooks_for_plan() (chains optimization -> playbook,
  acyclic; reuses leverage for "closes which regulations"). Capabilities without curated content
  render as honest status:missing stubs — the content-owed signal.
- knowledge/implementation_playbooks/: curated knowledge layer (Reasoning Knowledge Acquisition),
  two deep expert drafts (SBOM, CVD/PSIRT, status draft, expert-draft-not-normative) + README.
  The bottleneck is now CONTENT, not software; Playbook (own knowledge) != regulatory domain.
- ADR-004: Implementation Playbooks = renderer + knowledge layer; content is the bottleneck.
- reference suite: "Implementation Playbook" section renders the SBOM journey + Roadmap->Playbook
  table (high-leverage caps flagged "fehlt (Inhalt)" — content backlog, highest leverage first).
- refactor: extracted markdown helpers to reference_scenarios/_helpers.py to keep generate.py
  under the 500-LOC budget.

9 playbook tests (40 with optimization+transition+company), mypy --strict clean, check-loc 0.
Product code with no app caller + knowledge/ADR/reference = non-runtime -> no deploy (ADR-001).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-27 10:38:13 +02:00
parent 50d88d611d
commit 78f0ffa9de
11 changed files with 610 additions and 52 deletions
@@ -0,0 +1,20 @@
"""Implementation Playbook — the Berater renderer ("wie komme ich dort hin?").
For one capability it assembles the full implementation journey (why / closes which regulations /
tools / process / evidence / controls) from curated playbook knowledge + regulatory leverage +
injected Execution links. `playbooks_for_plan` chains the Optimization Roadmap into per-measure
playbooks. Pure, deterministic, computed-not-stored. No new corpus, no new meta-model class
(freeze v1.0). Curated content = expert draft, never normative.
"""
from __future__ import annotations
from .engine import build_playbook, playbooks_for_plan
from .schemas import Playbook, PlaybookStep
__all__ = [
"build_playbook",
"playbooks_for_plan",
"Playbook",
"PlaybookStep",
]
@@ -0,0 +1,96 @@
"""Implementation Playbook — the Berater renderer ("wie komme ich dort hin?").
After the Capability Delta Engine says WHAT is missing and the Optimization renderer says WHICH
measure first, the Playbook renderer says HOW to implement it. For one capability it assembles the
full journey from three sources:
- curated playbook KNOWLEDGE (why / tools / process steps / evidence / how others do it) — the
Reasoning Knowledge Acquisition layer under `knowledge/implementation_playbooks/`,
- the regulatory LEVERAGE (which regulations a delivered capability closes) — reused from the
Optimization renderer,
- injected Procedure/Control/Evidence links (Execution-owned; empty until linked).
Pure, deterministic, computed-not-stored. Chains optimization -> playbook (acyclic). No new corpus,
no new meta-model class (freeze v1.0). Python 3.9 compatible.
The curated content is an EXPERT DRAFT, never a normative requirement. When no playbook knowledge
exists for a capability yet, the renderer emits a `status: missing` stub — the honest signal that
the bottleneck is CONTENT (Knowledge Acquisition), not software.
"""
from __future__ import annotations
from typing import Any, Dict, List, Optional
from ..optimization import OptimizationPlan
from .schemas import Playbook, PlaybookStep
_MISSING_WHY = "(Playbook-Inhalt fehlt — Knowledge Acquisition offen.)"
_DRAFT_DISCLAIMER = (
"Kuratiertes Experten-Wissen (Erstentwurf), KEINE normative Anforderung. Tools/Schritte sind "
"Empfehlungen, kein Pflichtkatalog; Controls werden aus der Execution-Schicht injiziert."
)
def _steps(raw: Any) -> List[PlaybookStep]:
steps: List[PlaybookStep] = []
for i, s in enumerate(raw or [], 1):
steps.append(PlaybookStep(order=i, title=str(s.get("title", "")), detail=str(s.get("detail", ""))))
return steps
def build_playbook(
capability_id: str,
knowledge: Optional[Dict[str, Any]] = None,
closes_regulations: Optional[List[str]] = None,
control_links: Optional[List[str]] = None,
) -> Playbook:
"""Assemble the implementation journey for ONE capability.
`knowledge`: the curated playbook dict (None/empty -> a `missing` stub). `closes_regulations`:
the regulations a delivered capability closes (leverage, from `covers_targets`). `control_links`:
Execution-owned control refs, injected (default empty — no Execution data in Reasoning code).
"""
closes = sorted(set(closes_regulations or []))
if not knowledge:
return Playbook(
capability_id=capability_id, title=capability_id, why=_MISSING_WHY,
closes_regulations=closes, leverage=len(closes), controls=list(control_links or []),
status="missing", disclaimer=_DRAFT_DISCLAIMER,
)
return Playbook(
capability_id=capability_id,
title=str(knowledge.get("title", capability_id)),
why=str(knowledge.get("why", "")),
closes_regulations=closes,
leverage=len(closes),
tools=list(knowledge.get("tools", [])),
process_steps=_steps(knowledge.get("process_steps")),
expected_evidence=list(knowledge.get("expected_evidence", [])),
controls=list(control_links or []),
how_others_do_it=str(knowledge.get("how_others_do_it", "")),
status=str(knowledge.get("status", "draft")),
disclaimer=str(knowledge.get("disclaimer", _DRAFT_DISCLAIMER)),
)
def playbooks_for_plan(
plan: OptimizationPlan,
knowledge_by_cap: Dict[str, Dict[str, Any]],
top_k: Optional[int] = None,
control_links_by_cap: Optional[Dict[str, List[str]]] = None,
) -> List[Playbook]:
"""Render playbooks for the highest-leverage measures of an OptimizationPlan (Roadmap -> How).
Walks the ranked measures (top_k, or all) and builds each capability's playbook, using the
measure's own `covers` as the regulations it closes. Measures without curated knowledge become
`missing` stubs — surfacing exactly where playbook content is still owed.
"""
links = control_links_by_cap or {}
measures = plan.ranked_measures if top_k is None else plan.ranked_measures[: max(0, top_k)]
return [
build_playbook(
m.capability_id, knowledge_by_cap.get(m.capability_id),
closes_regulations=m.covers, control_links=links.get(m.capability_id),
)
for m in measures
]
@@ -0,0 +1,45 @@
"""Schemas for the Implementation Playbook renderer.
A Playbook is a *derived view* (computed-not-stored): it assembles, for one capability, the full
"wie komme ich dort hin?" journey from (a) curated playbook KNOWLEDGE, (b) the regulatory leverage
(which regulations a delivered capability closes), and (c) injected Procedure/Control/Evidence links
(Execution-owned). Nothing here is persisted. No new meta-model class, no graph (freeze v1.0).
Python 3.9 compatible (no `|` unions).
"""
from __future__ import annotations
from typing import List
from pydantic import BaseModel, Field
class PlaybookStep(BaseModel):
"""One step in the recommended way to stand up a capability."""
order: int
title: str
detail: str = ""
class Playbook(BaseModel):
"""The complete implementation journey for ONE capability — the Berater view.
Answers, in order: Warum? -> Welche Regelwerke schliesst das? -> Welche Tools? -> Welche
Prozesse? -> Welche Nachweise? -> Welche Controls? The curated parts (why/tools/steps/evidence/
how-others) are an EXPERT DRAFT, not a normative requirement; controls are injected from
Execution (may be empty until linked).
"""
capability_id: str
title: str = ""
why: str = "" # why this is required (regulatory rationale)
closes_regulations: List[str] = Field(default_factory=list) # leverage: regulations a delivered cap closes
leverage: int = 0 # = len(closes_regulations)
tools: List[str] = Field(default_factory=list) # typical tooling (curated knowledge)
process_steps: List[PlaybookStep] = Field(default_factory=list) # how to stand it up
expected_evidence: List[str] = Field(default_factory=list) # artifacts that prove it
controls: List[str] = Field(default_factory=list) # control refs (injected from Execution; may be empty)
how_others_do_it: str = "" # "wie machen das andere?" (curated)
status: str = "draft" # draft -> reviewed -> validated -> proven
disclaimer: str = "" # expert draft, not a normative requirement