From 18f5d0cb05c1ab2ac0b7e4584b84bff28d13cc88 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Sat, 27 Jun 2026 23:48:45 +0200 Subject: [PATCH] =?UTF-8?q?feat(programs):=20Operational=20Knowledge=20?= =?UTF-8?q?=E2=80=94=20the=20transition=20is=20the=20unit=20+=20Transition?= =?UTF-8?q?=20Coverage=20KPI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Customers don't buy "EMV domain"; they buy "we have ISO 9001, help us with the CRA". The sellable unit of knowledge is the TRANSITION (from -> to), not the law and not the capability. This reframes the backlog from "model EMV next" to "the top demanded transitions". No new runtime framework (ADR-010). - knowledge/programs/transitions.yaml: the Operational Knowledge backlog — the ~20-30 actually demanded transitions (of ~N*(N-1) possible) with priority. ISO27001->CRA, ISO9001->CRA, ISO9001->MaschinenVO (all 5-star), IEC62443->CRA, TISAX->CRA, ISO27001/IEC62443->NIS2, ISO14001->Umweltrecht. - Transition Coverage KPI (reference suite, computed-not-stored): per transition a status DERIVED from the transition-pattern corpus (reviewed/validated/proven -> Gold, draft -> 🟡, none -> ⚪). Honest current state: ISO27001->CRA ✅ reviewed, ISO9001->CRA 🟡 draft, rest ⚪. Highest-priority gap = ISO9001->MaschinenVO (the next Track-B work) — a far stronger product indicator than "EMV 30% modelled". - Three knowledge layers documented: Regulatory -> Operational (transitions/playbooks/deltas, the biggest differentiator) -> Verification (Vision V2). A domain is a TRANSITION PROGRAM with two tracks: Track A breadth (model sources, @Legal-KG/@Execution) + Track B product (transitions/playbooks/RTS per source, @Reasoning). - ADR-010: the transition is the unit of knowledge; Transition Coverage KPI; three layers; two tracks. 10 program/transition-contract tests, check-loc 0. Knowledge data + ADR + reference harness = non-runtime -> no deploy (ADR-001). No new module, no runtime change. Co-Authored-By: Claude Opus 4.7 --- .../knowledge/programs/README.md | 35 ++++++++++ .../knowledge/programs/transitions.yaml | 22 ++++++ .../reference_scenarios/_helpers.py | 67 ++++++++++++++++++- .../reference_scenarios/generate.py | 2 + .../reference_scenario_suite_v1.md | 29 +++++++- .../tests/test_domain_programs.py | 32 ++++++++- ...0-operational-knowledge-transition-unit.md | 50 ++++++++++++++ 7 files changed, 232 insertions(+), 5 deletions(-) create mode 100644 backend-compliance/knowledge/programs/transitions.yaml create mode 100644 docs-src/architecture/adr/ADR-010-operational-knowledge-transition-unit.md diff --git a/backend-compliance/knowledge/programs/README.md b/backend-compliance/knowledge/programs/README.md index 39dfdc60..a9780d82 100644 --- a/backend-compliance/knowledge/programs/README.md +++ b/backend-compliance/knowledge/programs/README.md @@ -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. diff --git a/backend-compliance/knowledge/programs/transitions.yaml b/backend-compliance/knowledge/programs/transitions.yaml new file mode 100644 index 00000000..55f255ab --- /dev/null +++ b/backend-compliance/knowledge/programs/transitions.yaml @@ -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]} diff --git a/backend-compliance/reference_scenarios/_helpers.py b/backend-compliance/reference_scenarios/_helpers.py index 86d813a0..f135c7f8 100644 --- a/backend-compliance/reference_scenarios/_helpers.py +++ b/backend-compliance/reference_scenarios/_helpers.py @@ -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)"), + ]) diff --git a/backend-compliance/reference_scenarios/generate.py b/backend-compliance/reference_scenarios/generate.py index 5f966ddd..77be2392 100644 --- a/backend-compliance/reference_scenarios/generate.py +++ b/backend-compliance/reference_scenarios/generate.py @@ -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)") diff --git a/backend-compliance/reference_scenarios/reference_scenario_suite_v1.md b/backend-compliance/reference_scenarios/reference_scenario_suite_v1.md index c9411f64..b36883ad 100644 --- a/backend-compliance/reference_scenarios/reference_scenario_suite_v1.md +++ b/backend-compliance/reference_scenarios/reference_scenario_suite_v1.md @@ -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). diff --git a/backend-compliance/tests/test_domain_programs.py b/backend-compliance/tests/test_domain_programs.py index 40ff71ec..8880ad3f 100644 --- a/backend-compliance/tests/test_domain_programs.py +++ b/backend-compliance/tests/test_domain_programs.py @@ -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) - out[p["id"]] = p + 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 diff --git a/docs-src/architecture/adr/ADR-010-operational-knowledge-transition-unit.md b/docs-src/architecture/adr/ADR-010-operational-knowledge-transition-unit.md new file mode 100644 index 00000000..95ab7861 --- /dev/null +++ b/docs-src/architecture/adr/ADR-010-operational-knowledge-transition-unit.md @@ -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)).