diff --git a/backend/tests/test_ap22c_maturity_e2e.py b/backend/tests/test_ap22c_maturity_e2e.py
new file mode 100644
index 0000000..2bfa5ae
--- /dev/null
+++ b/backend/tests/test_ap22c_maturity_e2e.py
@@ -0,0 +1,179 @@
+"""AP2.2c — A1 maturity journey End-to-End (Spagat Happy Path)."""
+
+from __future__ import annotations
+
+from tests.factories import provision_user_in_tenant
+from tests.test_initiatives_actions import _auth, _create_initiative, _login
+
+_STAGE1 = "Stufe 1 — Basis"
+_STARTER_RECURRING = "Tägliche Übung"
+
+
+def _create_spagat(client, token):
+ created = _create_initiative(
+ client,
+ token,
+ title="Spagat können",
+ archetype_key="initiative.maturity_journey",
+ )
+ assert created.status_code == 201
+ body = created.json()
+ assert body["starter_kit"]["applied"] is True
+ return body["id"]
+
+
+def test_a1_starter_kit_spagat_structure(client):
+ """Starter-Kit: Stufen, Training-Project, tägliche Übung, Operating Context."""
+ user = provision_user_in_tenant(tenant_role="admin")
+ token = _login(client, user)
+ initiative_id = _create_spagat(client, token)
+
+ ctx = client.get(
+ f"/api/initiatives/{initiative_id}/operating-context",
+ headers=_auth(token),
+ )
+ assert ctx.status_code == 200
+ body = ctx.json()
+ assert body["method_key"] == "maturity_progression"
+ assert "maturity_stage" in body["steering_elements"]
+ assert "recurring_rhythm" in body["steering_elements"]
+ assert body["ui_profile"]["controlDefaultRoute"] == "/control/status"
+
+ roadmap = client.get(
+ f"/api/initiatives/{initiative_id}/roadmap/items",
+ headers=_auth(token),
+ )
+ assert roadmap.status_code == 200
+ stages = [i for i in roadmap.json() if i.get("item_type") == "maturity_stage"]
+ assert len(stages) == 3
+ assert sum(1 for s in stages if s["status"] == "active") == 1
+ assert any(s["title"] == _STAGE1 and s["status"] == "active" for s in stages)
+
+ recurring = client.get(
+ f"/api/initiatives/{initiative_id}/recurring",
+ headers=_auth(token),
+ )
+ assert recurring.status_code == 200
+ assert any(r["title"] == _STARTER_RECURRING and r["status"] == "active" for r in recurring.json())
+
+ projects = client.get(
+ f"/api/initiatives/{initiative_id}/projects",
+ headers=_auth(token),
+ )
+ assert projects.status_code == 200
+ assert any(p["title"] == "Training" for p in projects.json())
+
+ snap = client.get(
+ f"/api/initiatives/{initiative_id}/steering-snapshot",
+ headers=_auth(token),
+ )
+ assert snap.status_code == 200
+ snap_body = snap.json()
+ assert snap_body["steering_kernel"]["primary_method_key"] == "maturity_progression"
+ assert snap_body.get("steering_guidance")
+ next_actions = snap_body.get("next_actions") or []
+ assert next_actions
+ top = next_actions[0]
+ assert top.get("kind") in ("recurring_due", "action", "review_milestone")
+ if top.get("kind") == "recurring_due":
+ assert top.get("reason_code") == "recurring_due"
+
+
+def test_a1_stage_verify_rotates_recurring_and_next_action(client):
+ """AP2.0e: Stufe 1 reached → alte Übung pausiert, Stufe 2 aktiv, neue Routine."""
+ user = provision_user_in_tenant(tenant_role="admin")
+ token = _login(client, user)
+ initiative_id = _create_spagat(client, token)
+
+ items = client.get(
+ f"/api/initiatives/{initiative_id}/roadmap/items",
+ headers=_auth(token),
+ ).json()
+ stage1 = next(i for i in items if i["title"] == _STAGE1)
+
+ snap_before = client.get(
+ f"/api/initiatives/{initiative_id}/steering-snapshot",
+ headers=_auth(token),
+ )
+ assert snap_before.status_code == 200
+
+ client.post(
+ f"/api/initiatives/{initiative_id}/evidence",
+ json={
+ "title": "Stufe 1 geschafft",
+ "roadmap_item_id": stage1["id"],
+ "status": "accepted",
+ },
+ headers=_auth(token),
+ )
+
+ verify = client.post(
+ f"/api/roadmap-items/{stage1['id']}/verify-reached",
+ headers=_auth(token),
+ )
+ assert verify.status_code == 200
+ body = verify.json()
+ assert body["status"] == "reached"
+ transition = body.get("maturity_transition") or {}
+ assert transition.get("new_recurring_id")
+
+ recurring = client.get(
+ f"/api/initiatives/{initiative_id}/recurring",
+ headers=_auth(token),
+ ).json()
+ titles = {r["title"]: r["status"] for r in recurring}
+ assert titles.get(_STARTER_RECURRING) == "paused"
+ assert any(t.startswith("Übung — Stufe 2") and titles[t] == "active" for t in titles)
+
+ items_after = client.get(
+ f"/api/initiatives/{initiative_id}/roadmap/items",
+ headers=_auth(token),
+ ).json()
+ stage2 = next(i for i in items_after if i["title"] == "Stufe 2 — Aufbau")
+ assert stage2["status"] == "active"
+
+ snap_after = client.get(
+ f"/api/initiatives/{initiative_id}/steering-snapshot",
+ headers=_auth(token),
+ )
+ assert snap_after.status_code == 200
+ next_after = snap_after.json().get("next_actions") or []
+ assert next_after
+ assert next_after[0].get("kind") == "recurring_due" or next_after[0].get("title", "").startswith(
+ "Übung —"
+ )
+
+
+def test_a1_journey_lists_stage_reached_event(client):
+ """Journey enthält nach Verify mindestens ein Ereignis."""
+ user = provision_user_in_tenant(tenant_role="admin")
+ token = _login(client, user)
+ initiative_id = _create_spagat(client, token)
+
+ items = client.get(
+ f"/api/initiatives/{initiative_id}/roadmap/items",
+ headers=_auth(token),
+ ).json()
+ stage1 = next(i for i in items if i["title"] == _STAGE1)
+
+ client.post(
+ f"/api/initiatives/{initiative_id}/evidence",
+ json={
+ "title": "Nachweis Stufe 1",
+ "roadmap_item_id": stage1["id"],
+ "status": "accepted",
+ },
+ headers=_auth(token),
+ )
+ client.post(
+ f"/api/roadmap-items/{stage1['id']}/verify-reached",
+ headers=_auth(token),
+ )
+
+ journey = client.get(
+ f"/api/initiatives/{initiative_id}/journey",
+ headers=_auth(token),
+ )
+ assert journey.status_code == 200
+ events = journey.json().get("events") or []
+ assert len(events) >= 1
diff --git a/docs/product/Kairo_Implementation_Truth_Table_v0.1.md b/docs/product/Kairo_Implementation_Truth_Table_v0.1.md
index 4cc3b2c..e90aea6 100644
--- a/docs/product/Kairo_Implementation_Truth_Table_v0.1.md
+++ b/docs/product/Kairo_Implementation_Truth_Table_v0.1.md
@@ -156,7 +156,7 @@ Verhindert, dass Zielbild-Dokumente als Ist-Stand gelesen werden.
| Archetyp | Anlage+Kit | Struktur pflegen | Kontrolle | Op-API | Paket |
|----------|------------|------------------|-----------|--------|-------|
-| A1 Reifegrad | ◐ AP2.2a | ◐ | ◐ | ◐ | AP2.2c + AP2.0e |
+| A1 Reifegrad | ✓ AP2.2a | ✓ | ✓ | ◐ | AP2.2c ✓ |
| A2 Linear | ✓ AP2.2a | ✓ | ✓ | ◐ | AP2.2b ✓ |
| B2b Product | ◐ AP2.2a | ◐ | ◐ | ◐ | AP2.2d ✓ |
| B3 Sprint-Profil | ◐ | ◐ | ◐ | ◐ | AP2.2d ✓ |
@@ -231,6 +231,7 @@ Details: `Kairo_Status_Review_and_Next_Steps_v0.1.md` §2.1
| ADP Backlog/Epic | P1–P8 ✓ · K-Ext-1/2/3/4/5 ✓ |
| Steering Kernel Proposals | ✓ | sprint_commit · gate_next_actions · intake_triage (Kernel v0.4) |
| AP2.2b | A2 Linear E2E ✓ (2026-07-27) |
+| AP2.2c | A1 Reifegrad E2E ✓ (2026-07-27) |
| AP2.2c–e | Referenz-Archetypen End-to-End ◐→✓ |
| AP2.1 | MVP-Abnahfe ✗→✓ |
| AP1.7b | Op-API Parität |
diff --git a/docs/product/Kairo_MVP_Execution_Plan_v0.2.md b/docs/product/Kairo_MVP_Execution_Plan_v0.2.md
index c3680c4..4dfbe59 100644
--- a/docs/product/Kairo_MVP_Execution_Plan_v0.2.md
+++ b/docs/product/Kairo_MVP_Execution_Plan_v0.2.md
@@ -80,7 +80,7 @@ Phase 1 AP2.2a Archetyp-geführte Anlage + Starter-Kits ✓
Phase 1b Specs Welle 1 finalisieren (A1,A2,B2a,B2b,B3) ◐
Phase 2 AP1.9d Methoden-Default-Ansichten (Anti-Todo-Wand) ◐ (Hints + Recurring)
Phase 3 AP2.2b A2 Linear End-to-End ✓
- AP2.2c A1 Reifegrad + AP2.0e ◐ Code
+ AP2.2c A1 Reifegrad + AP2.0e ✓
AP2.2d B2b Product + B3 Sprint ✓
AP2.2e B2a Programm (optional vor AP2.1)
Phase 4 AP1.7b Operational API — Pflege-Parität
diff --git a/frontend/src/components/MaturityStagePanel.jsx b/frontend/src/components/MaturityStagePanel.jsx
new file mode 100644
index 0000000..97a1a34
--- /dev/null
+++ b/frontend/src/components/MaturityStagePanel.jsx
@@ -0,0 +1,72 @@
+import { Link } from 'react-router-dom'
+import { MILESTONE_STATUS_LABELS } from '../constants/status.js'
+import { EmptyState } from './EmptyState.jsx'
+import { scopedPath } from '../utils/routes.js'
+
+export function MaturityStagePanel({
+ initiativeId,
+ roadmapItems = [],
+ embedded = true,
+}) {
+ const stages = [...roadmapItems]
+ .filter((item) => item.item_type === 'maturity_stage')
+ .sort((a, b) => (a.sort_order ?? 0) - (b.sort_order ?? 0))
+
+ const activeStage = stages.find((s) => s.status === 'active')
+
+ const body =
+ stages.length === 0 ? (
+
+ Aktive Stufe: {activeStage.title} +
+ )} ++ Stufen und Übungen unter{' '} + + Kontrolle → Rhythmen & Journey + + . +
+ > + ) + + if (!embedded) return body + + return ( ++ Aktive Stufe und Fortschritt — Steuerungshorizont für Reifegrad-Vorhaben (A1). +
++ {active.length} aktive Routine{active.length === 1 ? '' : 'n'} — fällige Übung steuert + Next Action. +
+ )} ++ Rhythmen pflegen unter{' '} + + Kontrolle → Journey + + . +
+ > + ) + + if (!embedded) return body + + return ( ++ Aktive Routinen am Reifegrad-Pfad — Leading Next aus fälliger Übung (A1). +
+