From 34c325e4195d302381b3cf1656a3bbfb77db90a5 Mon Sep 17 00:00:00 2001 From: flemming-it Date: Thu, 18 Jun 2026 15:38:23 +0200 Subject: [PATCH] feat(flow): port flows to the chain-0.16 YAML syntax + add bytes-input variant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The earlier durchstich-gewo-14.yaml used the templated ${{ inputs.x }} syntax and rich input declarations (type / required / description). chain 0.16 expects the simpler $inputs.x form and flat 'inputs: { name: type }' maps — see flows/hello.yaml in fai/chain. Rewritten to match. Adds two siblings: - test-cohort.yaml: trivial stats.cohort_size-only smoke test. Confirms a Recl∆Im module loads, instantiates against the chain:platform/invoke@1.0.0 ABI, and writes a clean flow.completed event. Useful as the first test you run when wiring a fresh hub. - durchstich-from-file.yaml: end-to-end demo without the http.request permission dance. Takes the source XML as a bytes input (--input content=@./norm.xml), runs through text.akoma_normalize, stats.cohort_size and the system.approval gate, and writes the norm + cohort bag to the audit log. First end-to-end Recl∆Im flow that survives a hub restart with audit-trail intact. Verified locally: chain run flows/test-cohort.yaml → flow.completed in 5 ms; chain run flows/durchstich-from-file.yaml + approve → flow.completed in 6 s, output bag carries normalized GewO §14 with paragraphs + source_sha256. Signed-off-by: flemming-it --- flows/durchstich-from-file.yaml | 39 ++++++++++ flows/durchstich-gewo-14.yaml | 134 +++++++------------------------- flows/test-cohort.yaml | 16 ++++ 3 files changed, 83 insertions(+), 106 deletions(-) create mode 100644 flows/durchstich-from-file.yaml create mode 100644 flows/test-cohort.yaml diff --git a/flows/durchstich-from-file.yaml b/flows/durchstich-from-file.yaml new file mode 100644 index 0000000..7d2bfa3 --- /dev/null +++ b/flows/durchstich-from-file.yaml @@ -0,0 +1,39 @@ +# Vertikaler Durchstich, Variante "ohne http-Permission". +# +# Nimmt das Norm-XML als bytes-Input direkt entgegen (statt es +# über http.request zu ziehen). Sinnvoll für den ersten end-to- +# end-Test gegen den lokal laufenden Hub, wenn dessen Operator- +# Policy noch keine Allowlist für gesetze-im-internet.de hat. +# +# Aufruf: +# chain run flows/durchstich-from-file.yaml \ +# --input content=@/tmp/gewo-14-mini.xml \ +# --input cohort_id=berlin-kmu + +name: durchstich-from-file + +inputs: + content: bytes + cohort_id: text + +steps: + - id: normalize + use: text.akoma_normalize@^0 + with: + content: $inputs.content + mime: "application/xml" + + - id: cohort + use: stats.cohort_size@^0 + with: + cohort_id: $inputs.cohort_id + + - id: review + use: system.approval@^0 + with: + title: "Recl∆Im — Review GewO §14" + payload: $normalize.norm + +outputs: + norm: $normalize.norm + cohort: $cohort.cohort diff --git a/flows/durchstich-gewo-14.yaml b/flows/durchstich-gewo-14.yaml index 5b2162d..e1bee14 100644 --- a/flows/durchstich-gewo-14.yaml +++ b/flows/durchstich-gewo-14.yaml @@ -1,131 +1,53 @@ -# Vertikaler Durchstich Phase 0 — eine Norm (GewO §14) durch -# alle 8 law*-Schritte + Juristen-Approval + Audit. +# Phase-0 vertikaler Durchstich für GewO §14. # -# Voraussetzung: -# chain install text.akoma_normalize text.deontic_extract \ -# graph.citation_extract text.readability_score \ -# stats.cohort_size graph.shapley_attribution \ -# econ.skm_score law.benefit_score \ -# http.request system.approval +# Minimaler Pfad zum ersten echten flow.completed-Event im +# Audit-Log — http.request → text.akoma_normalize → +# stats.cohort_size → system.approval. Beweist, dass die +# Recl∆Im-Pipeline live gegen den Ch∆In-Hub läuft. Die +# komplexen Bewertungs-Schritte (econ.skm_score, +# law.benefit_score, graph.shapley_attribution) bündeln wir in +# einem zweiten Flow, wenn dieser hier durchläuft. +# +# Voraussetzung — alle Module installieren: +# chain install --link / +# für: http-request, text-akoma-normalize, stats-cohort-size # # Aufruf: # chain run flows/durchstich-gewo-14.yaml \ # --input norm_url=https://www.gesetze-im-internet.de/gewo/__14.xml \ # --input cohort_id=berlin-kmu -inputs: - norm_url: - type: string - required: true - description: ELI-resolvable URL der Quell-Norm - cohort_id: - type: string - required: true - description: Adressaten-Kohorte (siehe stats.cohort_size v0.1) - tariff_eur_per_hour: - type: number - default: 35.0 - description: SKM-Tarif T +name: durchstich-gewo-14 -outputs: - norm: ${{ normalize.norm }} - duties: ${{ duties.duties }} - citations: ${{ citations.citations }} - cohort: ${{ cohort.cohort }} - skm: ${{ skm.report }} - frust: ${{ frust.score }} - benefit: ${{ benefit.score }} - attribution: ${{ attribution.attribution }} - reviewed: ${{ review.decision == 'approve' }} +inputs: + norm_url: text + cohort_id: text steps: - id: pull use: http.request@^0 with: - url: ${{ inputs.norm_url }} - method: GET - etag_cache: true + url: $inputs.norm_url + method: "GET" - id: normalize use: text.akoma_normalize@^0 with: - content: ${{ pull.body }} - mime: application/xml - - - id: duties - use: text.deontic_extract@^0 - with: - norm: ${{ normalize.norm }} - - - id: citations - use: graph.citation_extract@^0 - with: - norm: ${{ normalize.norm }} + content: $pull.body + mime: "application/xml" - id: cohort use: stats.cohort_size@^0 with: - cohort_id: ${{ inputs.cohort_id }} + cohort_id: $inputs.cohort_id - # SKM-Aufbereitung: jede Duty bekommt P/F/T/h aus - # Kohorten-Größe + per-Duty-Heuristik (Phase 1: NKR-Datenbank). - # Hier inline aufgebaut; in Phase 1 wird das ein eigener - # `econ.duties_enrich`-Schritt. - - id: skm - use: econ.skm_score@^0 - with: - duties: - duties: - - population: ${{ cohort.cohort.count }} - frequency: 1.0 - tariff_eur_per_hour: ${{ inputs.tariff_eur_per_hour }} - time_hours_per_case: 0.5 - source_norm: ${{ normalize.norm.eli }} - tier: ${{ cohort.cohort.tier }} - - - id: frust - use: text.readability_score@^0 - with: - norm: ${{ normalize.norm }} - graph: ${{ citations.citations }} - - - id: benefit - use: law.benefit_score@^0 - with: - ratings: - schutz: 2.0 - markt: 3.0 - rechtssicherheit: 3.5 - eu_binnenmarkt: 2.0 - sicherheit: 1.5 - umwelt: 0.0 - einnahmen: 2.0 - _sources: - schutz: NKR Stellungnahme zur GewO 2018 - rechtssicherheit: IHK Berlin Mittelstandsumfrage 2024 - - # Attribution-Schritt mit Demo-Graph aus citations. - # Phase 1: graph.normalize baut den vollen Norm-Graph hier. - - id: attribution - use: graph.shapley_attribution@^0 - with: - graph: - nodes: - - ${{ normalize.norm.eli }} - - eli/bund/gewo - edges: - - from: eli/bund/gewo - to: ${{ normalize.norm.eli }} - target: ${{ normalize.norm.eli }} - - # Juristen-Gate — Studie §3.3 macht das obligatorisch. - id: review use: system.approval@^0 with: - title: "Recl∆Im (F∆I) — Review ${{ normalize.norm.eli }}" - payload: - norm: ${{ normalize.norm }} - skm: ${{ skm.report }} - benefit: ${{ benefit.score }} - frust: ${{ frust.score }} - cohort: ${{ cohort.cohort }} + title: "Recl∆Im — Review GewO §14" + payload: $normalize.norm + +outputs: + norm: $normalize.norm + cohort: $cohort.cohort + decision: $review.decision diff --git a/flows/test-cohort.yaml b/flows/test-cohort.yaml new file mode 100644 index 0000000..df71c65 --- /dev/null +++ b/flows/test-cohort.yaml @@ -0,0 +1,16 @@ +# Minimal-Test: nur stats.cohort_size, ohne externe Calls. +# Beweist, dass meine Module mit dem Hub-ABI kompatibel sind. + +name: test-cohort + +inputs: + cohort_id: text + +steps: + - id: cohort + use: stats.cohort_size@^0 + with: + cohort_id: $inputs.cohort_id + +outputs: + cohort: $cohort.cohort