Merge pull request 'feat: Operational Knowledge — the transition is the unit + Transition Coverage KPI' (#24) from feat/transition-coverage into main
This commit is contained in:
@@ -56,3 +56,38 @@ playbooks · passed reference scenarios · consciously declared corpus gaps. Ren
|
||||
|
||||
The work shifts decisively from software development to knowledge production; the competitive
|
||||
advantage now comes from the quality and breadth of the modelled domains.
|
||||
|
||||
## The unit of knowledge is the TRANSITION, not the law (Operational Knowledge)
|
||||
|
||||
Customers never ask „what's in the CRA?". They ask **„I have ISO 9001 — what do I still need for the
|
||||
CRA?"**. The sellable unit is therefore the **transition** (`from → to`), not a single law and not a
|
||||
single capability. `knowledge/programs/transitions.yaml` is the **Operational Knowledge backlog**: the
|
||||
~20–30 transitions that are actually demanded (out of the ~N·(N−1) theoretically possible), with a
|
||||
priority. Nobody buys „EMV domain"; they buy „ISO 9001 → CRA".
|
||||
|
||||
## Three knowledge layers
|
||||
|
||||
```
|
||||
Regulatory Knowledge (laws · standards · guidelines)
|
||||
↓
|
||||
Operational Knowledge (transition patterns · playbooks · capability deltas) ← biggest differentiator
|
||||
↓
|
||||
Verification Knowledge (source code · SBOM · docs · architecture · processes) ← Vision V2 / Req. Verification
|
||||
```
|
||||
|
||||
The middle layer is where we answer not just *what* is required, but *how a company gets there from its
|
||||
current maturity*. That is the strongest moat.
|
||||
|
||||
## Transition Coverage — a second, stronger KPI
|
||||
|
||||
Besides per-domain maturity, the reference suite reports **Transition Coverage**: per top-transition a
|
||||
status DERIVED from the transition-pattern corpus (`reviewed/validated/proven → ✅`, `draft → 🟡`,
|
||||
`none → ⚪`). „ISO 9001 → MaschinenVO ⭐⭐⭐⭐⭐ but ⚪" is a far stronger product indicator than „EMV 30 %".
|
||||
|
||||
## A domain is a TRANSITION PROGRAM with two parallel tracks
|
||||
|
||||
- **Track A — breadth:** model the domain's remaining requirement sources (EMV, RED, IEC 62443, NIS2 …)
|
||||
so the corpus grows. (Stage 2–3, @Legal-KG / @Execution.)
|
||||
- **Track B — product:** for each newly modelled source, immediately produce the top transition
|
||||
patterns + playbooks + reference scenarios → knowledge customers buy and consultants use. (Stage 4–6,
|
||||
@Reasoning.) Track B turns breadth into product value continuously.
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Operational Knowledge backlog — the TRANSITION is the unit of knowledge, not the law.
|
||||
# Customers buy „we have ISO 9001, help us with the CRA", not „EMV domain". This is the Operational
|
||||
# layer (the differentiator). Status per transition is DERIVED from the transition_patterns corpus by
|
||||
# the reference suite (reviewed/validated/proven -> Gold ✅, draft -> 🟡, none -> ⚪) — computed-not-stored.
|
||||
|
||||
id: BACKLOG-transitions-v1
|
||||
note: >
|
||||
Drei Wissensebenen: Regulatory (Gesetze/Normen/Leitlinien) → OPERATIONAL (diese Transitionen +
|
||||
Playbooks + Capability-Deltas — der größte Differenzierer) → Verification (Code/SBOM/Doku/Architektur/
|
||||
Prozesse, vgl. Vision V2). Diese Liste ist die Operational-Ebene und der eigentliche Verkaufs-Backlog.
|
||||
|
||||
# Theoretisch entstehen aus N Requirement Sources ~N*(N-1) Übergänge; praktisch werden nur ~20-30
|
||||
# regelmäßig nachgefragt. Diese hier sind die meistnachgefragten (Priorität 1-5 Sterne).
|
||||
transitions:
|
||||
- {from: ISO27001, to: CRA, priority: 5, domains: [industrial_automation]}
|
||||
- {from: ISO9001, to: CRA, priority: 5, domains: [industrial_automation]}
|
||||
- {from: ISO9001, to: MaschinenVO, priority: 5, domains: [industrial_automation]}
|
||||
- {from: IEC62443, to: CRA, priority: 4, domains: [industrial_automation, energy]}
|
||||
- {from: TISAX, to: CRA, priority: 4, domains: [automotive, industrial_automation]}
|
||||
- {from: ISO27001, to: NIS2, priority: 4, domains: [industrial_automation, energy]}
|
||||
- {from: IEC62443, to: NIS2, priority: 4, domains: [industrial_automation, energy]}
|
||||
- {from: ISO14001, to: Umweltrecht, priority: 3, domains: [environmental]}
|
||||
@@ -155,8 +155,9 @@ def domain_programs_section(base_dir) -> None:
|
||||
idx = build_knowledge_index(_load("transition_patterns"), _load("implementation_playbooks"),
|
||||
_load("reference_transition_scenarios"))
|
||||
pdir = os.path.join(base_dir, "..", "knowledge", "programs")
|
||||
progs = sorted((yaml.safe_load(open(os.path.join(pdir, f), encoding="utf-8"))
|
||||
for f in sorted(os.listdir(pdir)) if f.endswith(".yaml")), key=lambda p: p.get("backlog_rank", 99))
|
||||
_all = [yaml.safe_load(open(os.path.join(pdir, f), encoding="utf-8"))
|
||||
for f in sorted(os.listdir(pdir)) if f.endswith(".yaml")]
|
||||
progs = sorted((p for p in _all if "backlog_rank" in p), key=lambda p: p["backlog_rank"]) # domain programs only
|
||||
|
||||
_ALIAS = {"cyber resilience act": "cra", "maschinenverordnung": "maschinenvo", "iatf": "iatf16949"}
|
||||
|
||||
@@ -200,3 +201,65 @@ def domain_programs_section(base_dir) -> None:
|
||||
("Reifegrad-KPI (computed-not-stored)", "PASS", "aus echtem Korpus abgeleitet (TP/PB/RTS je Domäne)"),
|
||||
("Regelwerk-ID-Normalisierung", "TODO", "Alias CRA/MaschinenVO im KPI — kanonische IDs ausstehend"),
|
||||
])
|
||||
|
||||
|
||||
def transition_coverage_section(base_dir) -> None:
|
||||
"""Transition Coverage — the TRANSITION is the unit of knowledge; status DERIVED from the corpus."""
|
||||
import os
|
||||
import yaml
|
||||
|
||||
kdir = os.path.join(base_dir, "..", "knowledge")
|
||||
with open(os.path.join(kdir, "programs", "transitions.yaml"), encoding="utf-8") as h:
|
||||
backlog = yaml.safe_load(h)
|
||||
tpdir = os.path.join(kdir, "transition_patterns")
|
||||
pats = []
|
||||
for f in sorted(os.listdir(tpdir)):
|
||||
if not f.endswith(".yaml"):
|
||||
continue
|
||||
d = yaml.safe_load(open(os.path.join(tpdir, f), encoding="utf-8"))
|
||||
goal = d.get("transition_goal", {})
|
||||
frm = goal.get("from", {}).get("standard", "")
|
||||
to = goal.get("to")
|
||||
tos = [it.get("regulation") or it.get("framework") or it.get("target")
|
||||
for it in (to if isinstance(to, list) else [to]) if isinstance(it, dict)]
|
||||
pats.append((frm, [t for t in tos if t], str(d.get("status", "draft"))))
|
||||
|
||||
_ALIAS = {"isoiec27001": "iso27001", "isoiec62443": "iec62443",
|
||||
"cyberresilienceact": "cra", "maschinenverordnung": "maschinenvo"}
|
||||
|
||||
def _c(s):
|
||||
k = "".join(ch for ch in str(s).lower() if ch.isalnum())
|
||||
return _ALIAS.get(k, k)
|
||||
|
||||
_RANK = {"draft": 1, "reviewed": 2, "validated": 3, "proven": 4}
|
||||
_ICON = {0: "⚪ nicht begonnen", 1: "🟡 Draft", 2: "✅ reviewed", 3: "✅ validated", 4: "✅ Gold"}
|
||||
|
||||
def _status(frm, to):
|
||||
best = 0
|
||||
for pf, ptos, st in pats:
|
||||
if _c(pf) == _c(frm) and _c(to) in {_c(x) for x in ptos}:
|
||||
best = max(best, _RANK.get(st, 1))
|
||||
return best
|
||||
|
||||
w("## Transition Coverage — die Transition ist die Wissenseinheit (Operational Knowledge)")
|
||||
w("")
|
||||
w('_Der Kunde kauft nicht „EMV-Domain", sondern „wir haben ISO 9001 — helfen Sie uns beim CRA". Die Wissenseinheit ist die TRANSITION (nicht das Gesetz). Status je Transition aus dem echten Pattern-Korpus abgeleitet (computed-not-stored). Drei Ebenen: Regulatory → **Operational (hier, größter Differenzierer)** → Verification (Vision V2)._')
|
||||
w("")
|
||||
w("| Prio | Transition | Status |")
|
||||
w("|---|---|---|")
|
||||
rows = sorted(backlog["transitions"], key=lambda t: -t["priority"])
|
||||
done = 0
|
||||
for t in rows:
|
||||
s = _status(t["from"], t["to"])
|
||||
done += 1 if s else 0
|
||||
w("| %s | `%s → %s` | %s |" % ("⭐" * t["priority"], t["from"], t["to"], _ICON[s]))
|
||||
w("")
|
||||
gaps = [t for t in rows if _status(t["from"], t["to"]) == 0]
|
||||
if gaps:
|
||||
w('**Größte Lücke (Track B als Nächstes):** `%s → %s` (%s) — höchstnachgefragte Transition OHNE Pattern. Stärkerer Produktindikator als „EMV 30%% modelliert".' % (gaps[0]["from"], gaps[0]["to"], "⭐" * gaps[0]["priority"]))
|
||||
w("")
|
||||
coverage_table([
|
||||
("Transition Coverage (Operational Knowledge)", "PASS", "%d von %d Top-Transitionen mit Pattern" % (done, len(rows))),
|
||||
("Wissenseinheit = Transition (nicht Gesetz)", "PASS", "verkauft wird der Übergang, z. B. ISO9001→CRA"),
|
||||
("3 Ebenen Regulatory→Operational→Verification", "PASS", "Operational = größter Differenzierer (ADR-010)"),
|
||||
])
|
||||
|
||||
@@ -47,6 +47,7 @@ import yaml
|
||||
from _helpers import ( # noqa: E402 (script-dir module; keeps generate.py under the LOC budget)
|
||||
OUT, ROLLUP, Row, w, coverage_table, reg_map_block, unsupported_block, interp_status,
|
||||
knowledge_intake_section, completeness_section, domain_programs_section,
|
||||
transition_coverage_section,
|
||||
)
|
||||
|
||||
ISO_MAP = {"ISO27001": CapabilityMappingEntry(
|
||||
@@ -467,6 +468,7 @@ coverage_table([
|
||||
knowledge_intake_section(os.path.dirname(__file__)) # Knowledge Intake (impact triage) — kept in _helpers for LOC
|
||||
completeness_section() # Regulatory Completeness — kept in _helpers for LOC
|
||||
domain_programs_section(os.path.dirname(__file__)) # Domain Knowledge Programs — kept in _helpers for LOC
|
||||
transition_coverage_section(os.path.dirname(__file__)) # Transition Coverage (Operational Knowledge) — in _helpers for LOC
|
||||
|
||||
# ── Epics + roll-up ───────────────────────────────────────────────────────
|
||||
w("## Gaps → Epics (Backlog — nur erfasst, NICHT implementiert)")
|
||||
|
||||
@@ -387,6 +387,31 @@ _Industry-Einstieg + ETO-Hypothese: jede Domäne kennt ihre typischen Sources +
|
||||
| Reifegrad-KPI (computed-not-stored) | **PASS** | aus echtem Korpus abgeleitet (TP/PB/RTS je Domäne) |
|
||||
| Regelwerk-ID-Normalisierung | **TODO** | Alias CRA/MaschinenVO im KPI — kanonische IDs ausstehend |
|
||||
|
||||
## Transition Coverage — die Transition ist die Wissenseinheit (Operational Knowledge)
|
||||
|
||||
_Der Kunde kauft nicht „EMV-Domain", sondern „wir haben ISO 9001 — helfen Sie uns beim CRA". Die Wissenseinheit ist die TRANSITION (nicht das Gesetz). Status je Transition aus dem echten Pattern-Korpus abgeleitet (computed-not-stored). Drei Ebenen: Regulatory → **Operational (hier, größter Differenzierer)** → Verification (Vision V2)._
|
||||
|
||||
| Prio | Transition | Status |
|
||||
|---|---|---|
|
||||
| ⭐⭐⭐⭐⭐ | `ISO27001 → CRA` | ✅ reviewed |
|
||||
| ⭐⭐⭐⭐⭐ | `ISO9001 → CRA` | 🟡 Draft |
|
||||
| ⭐⭐⭐⭐⭐ | `ISO9001 → MaschinenVO` | ⚪ nicht begonnen |
|
||||
| ⭐⭐⭐⭐ | `IEC62443 → CRA` | ⚪ nicht begonnen |
|
||||
| ⭐⭐⭐⭐ | `TISAX → CRA` | ⚪ nicht begonnen |
|
||||
| ⭐⭐⭐⭐ | `ISO27001 → NIS2` | ⚪ nicht begonnen |
|
||||
| ⭐⭐⭐⭐ | `IEC62443 → NIS2` | ⚪ nicht begonnen |
|
||||
| ⭐⭐⭐ | `ISO14001 → Umweltrecht` | ⚪ nicht begonnen |
|
||||
|
||||
**Größte Lücke (Track B als Nächstes):** `ISO9001 → MaschinenVO` (⭐⭐⭐⭐⭐) — höchstnachgefragte Transition OHNE Pattern. Stärkerer Produktindikator als „EMV 30% modelliert".
|
||||
|
||||
**Architecture Coverage**
|
||||
|
||||
| Layer | Status | Hinweis |
|
||||
|---|---|---|
|
||||
| Transition Coverage (Operational Knowledge) | **PASS** | 2 von 8 Top-Transitionen mit Pattern |
|
||||
| Wissenseinheit = Transition (nicht Gesetz) | **PASS** | verkauft wird der Übergang, z. B. ISO9001→CRA |
|
||||
| 3 Ebenen Regulatory→Operational→Verification | **PASS** | Operational = größter Differenzierer (ADR-010) |
|
||||
|
||||
## Gaps → Epics (Backlog — nur erfasst, NICHT implementiert)
|
||||
|
||||
| Epic | Titel | schliesst Coverage-Luecke |
|
||||
@@ -398,6 +423,6 @@ _Industry-Einstieg + ETO-Hypothese: jede Domäne kennt ihre typischen Sources +
|
||||
|
||||
## Suite-Status (Roll-up)
|
||||
|
||||
- Coverage-Zellen gesamt: **47**
|
||||
- PASS: **35** · PARTIAL: 3 · UNSUPPORTED: 1 · TODO: 7 · N/A: 1 · NEEDS_FACTS: 0
|
||||
- Coverage-Zellen gesamt: **50**
|
||||
- PASS: **38** · PARTIAL: 3 · UNSUPPORTED: 1 · TODO: 7 · N/A: 1 · NEEDS_FACTS: 0
|
||||
- Fortschritt = PASS-Anteil steigt, wenn Epics RS-001…004 landen (objektiver Maßstab, kein LOC).
|
||||
|
||||
@@ -21,10 +21,16 @@ def _programs():
|
||||
if f.endswith(".yaml"):
|
||||
with open(os.path.join(_DIR, f), encoding="utf-8") as h:
|
||||
p = yaml.safe_load(h)
|
||||
if "backlog_rank" in p: # domain programs only (not transitions backlog)
|
||||
out[p["id"]] = p
|
||||
return out
|
||||
|
||||
|
||||
def _transitions():
|
||||
with open(os.path.join(_DIR, "transitions.yaml"), encoding="utf-8") as h:
|
||||
return yaml.safe_load(h)
|
||||
|
||||
|
||||
def test_five_domains_ranked_backlog():
|
||||
ranks = sorted(p["backlog_rank"] for p in _programs().values())
|
||||
assert ranks == [1, 2, 3, 4, 5]
|
||||
@@ -69,3 +75,27 @@ def test_readme_documents_seven_stage_checklist():
|
||||
"Transition Patterns", "Playbooks", "Reference Scenarios", "Completeness"]:
|
||||
assert stage in readme
|
||||
assert "Industrial Automation" in readme # backlog #1 documented
|
||||
|
||||
|
||||
def test_transition_backlog_has_top_demanded_transitions():
|
||||
ts = _transitions()["transitions"]
|
||||
pairs = {(t["from"], t["to"]) for t in ts}
|
||||
# the highest-value transitions customers actually buy
|
||||
assert ("ISO27001", "CRA") in pairs and ("ISO9001", "CRA") in pairs
|
||||
assert ("ISO9001", "MaschinenVO") in pairs
|
||||
|
||||
|
||||
def test_transition_backlog_is_prioritised():
|
||||
ts = _transitions()["transitions"]
|
||||
for t in ts:
|
||||
assert 1 <= t["priority"] <= 5 and t["from"] and t["to"]
|
||||
# the five-star transitions are the CRA/MaschinenVO entry points
|
||||
five = {(t["from"], t["to"]) for t in ts if t["priority"] == 5}
|
||||
assert ("ISO9001", "MaschinenVO") in five
|
||||
|
||||
|
||||
def test_transition_is_the_unit_documented():
|
||||
with open(os.path.join(_DIR, "README.md"), encoding="utf-8") as h:
|
||||
readme = h.read()
|
||||
assert "unit of knowledge is the TRANSITION" in readme
|
||||
assert "Operational Knowledge" in readme and "Verification Knowledge" in readme # three layers
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# ADR-010: Operational Knowledge — the transition is the unit of knowledge
|
||||
|
||||
- **Status:** Accepted
|
||||
- **Datum:** 2026-06-27
|
||||
- **Typ:** Produkt- / Wissens-Strategie-Entscheidung
|
||||
- **Bezug:** [ADR-009](ADR-009-domain-knowledge-program.md), [ADR-002](ADR-002-transition-is-data-not-architecture.md), [[transition-reasoning]], [[strategy-requirements-intelligence]]
|
||||
|
||||
## Kontext
|
||||
|
||||
Aus allen Kundengesprächen ergibt sich dieselbe Frage: nicht „was steht im CRA?", sondern
|
||||
**„ich habe heute ISO 27001 und TISAX — welche drei Dinge fehlen mir noch für den CRA?"**. Die
|
||||
verkaufte Einheit ist damit weder das Gesetz noch die Capability, sondern die **Transition**
|
||||
(`Ausgangszustand → Zielzustand`). Den Domänen-Backlog nach „jetzt EMV modellieren" zu ordnen,
|
||||
verfehlt das — niemand kauft eine „EMV-Domain", Kunden kaufen „ISO 9001 → CRA".
|
||||
|
||||
## Entscheidung
|
||||
|
||||
1. **Die Wissenseinheit ist die TRANSITION.** Der Operational-Knowledge-Backlog
|
||||
(`knowledge/programs/transitions.yaml`) listet die ~20–30 tatsächlich nachgefragten Transitionen
|
||||
(von ~N·(N−1) theoretisch möglichen) mit Priorität. Das ist der eigentliche Verkaufs-Backlog.
|
||||
|
||||
2. **Drei Wissensebenen, die ineinandergreifen:**
|
||||
`Regulatory Knowledge` (Gesetze/Normen/Leitlinien) → **`Operational Knowledge`** (Transition
|
||||
Patterns · Playbooks · Capability-Deltas) → `Verification Knowledge` (Code · SBOM · Doku ·
|
||||
Architektur · Prozesse; = Vision V2 / Requirements Verification). Die **mittlere Ebene ist der
|
||||
größte Differenzierer**: sie beantwortet nicht nur *was* gefordert ist, sondern *wie ein Unternehmen
|
||||
mit seinem heutigen Reifegrad dorthin kommt*.
|
||||
|
||||
3. **Zweiter, stärkerer KPI: Transition Coverage.** Pro Top-Transition ein Status, DERIVED aus dem
|
||||
Transition-Pattern-Korpus (`reviewed/validated/proven → ✅`, `draft → 🟡`, `none → ⚪`),
|
||||
computed-not-stored. „ISO 9001 → MaschinenVO ⭐⭐⭐⭐⭐ aber ⚪" ist ein viel stärkerer Produktindikator
|
||||
als „EMV ist zu 30 % modelliert".
|
||||
|
||||
4. **Eine Domäne ist ein TRANSITION PROGRAM mit zwei parallelen Tracks:**
|
||||
- **Track A (Breite):** verbleibende Requirement Sources der Domäne modellieren (EMV, RED,
|
||||
IEC 62443, NIS2 …) — Korpus wächst (Stufe 2–3, @Legal-KG/@Execution).
|
||||
- **Track B (Produkt):** für jede neu modellierte Source sofort die wichtigsten Transition Patterns
|
||||
+ Playbooks + Reference Scenarios erzeugen — verkaufbares/einsetzbares Wissen (Stufe 4–6, @Reasoning).
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
- **Backlog ist transition-getrieben, nicht regelwerk-getrieben.** Die höchstpriorisierte Lücke
|
||||
(z. B. `ISO 9001 → MaschinenVO`, ⭐⭐⭐⭐⭐, ⚪) ist die nächste Track-B-Arbeit — nicht „EMV".
|
||||
- **Task #49 wird zum „Industrial Automation Transition Program"** (Track A + Track B parallel), sodass
|
||||
wachsendes Domänenwissen unmittelbar in Produktwert übersetzt wird.
|
||||
- **Operational Knowledge = der Moat.** Regulatory ist Commodity (jeder kann Gesetze lesen),
|
||||
Verification ist Vision V2; die Transition dazwischen ist der differenzierende Asset.
|
||||
- **Freeze-konform:** kein neues Metamodell/Graph/Modul. Nur Daten (`transitions.yaml`) + eine
|
||||
abgeleitete Reporting-Sicht; Status aus dem vorhandenen Pattern-Korpus berechnet.
|
||||
- Diese ADR ist non-runtime → kein Deploy (siehe [ADR-001](ADR-001-runtime-deploy-policy.md)).
|
||||
Reference in New Issue
Block a user