Compare commits

..

No commits in common. "0c536c5b91d3e2e2808a8b58e4ac0cee56b65289" and "312d47ddfcd7069719ae41cbb40d55d5618ad7ff" have entirely different histories.

11 changed files with 95 additions and 102 deletions

View file

@ -178,18 +178,18 @@ angreifbar und wertlos. Code zweitrangig.
│ ABI chain:platform │ │ │
├──────────────────────────────┼─────────┼──────────────────────────┤
│ chain-modules/ (generisch): │ │ http.request │
│ text.akoma-normalize │ │ text.extract (PDF/DOCX) │
│ text.deontic-extract │ │ text.anonymize (DSGVO) │
│ graph.citation-extract │ │ text.translate (DE↔EN) │
│ text.readability-score │ │ text.summarize │
│ stats.cohort-size │ │ llm.chat (Ollama-kompat.)│
│ graph.shapley-attribution │ │ system.approval@^0 │
│ text.akoma_normalize │ │ text.extract (PDF/DOCX) │
│ text.deontic_extract │ │ text.anonymize (DSGVO) │
│ graph.citation_extract │ │ text.translate (DE↔EN) │
│ text.readability_score │ │ text.summarize │
│ stats.cohort_size │ │ llm.chat (Ollama-kompat.)│
│ graph.shapley_attribution │ │ system.approval@^0 │
│ │ │ debug.echo (Referenz) │
│ chain-modules-econ/: │ │ │
│ econ.skm-score │ │ │
│ econ.skm_score │ │ │
│ │ │ │
│ chain-modules-law/ (domain): │ │ │
│ law.benefit-score │ │ │
│ law.benefit_score │ │ │
└──────────────────────────────┘ └──────────────────────────┘
Heatmap rendert der **Client** (Flutter, CustomPainter) — kein
@ -200,14 +200,14 @@ angreifbar und wertlos. Code zweitrangig.
**Begründung — Reuse-Lens:** Module-Naming reflektiert Wiederverwend­
barkeit. Was kein juristisches Domänen-Wissen braucht, geht in
`chain-modules/` (generisches Org) und ist damit auch in anderen
F∆I-Projekten und für externe Nutzer wertvoll: `text.akoma-normalize`
F∆I-Projekten und für externe Nutzer wertvoll: `text.akoma_normalize`
ist relevant für jeden, der Rechtsdokumente parst (EU-Parlament,
Italien, Brasilien); `text.deontic-extract` für Verträge, ISO-Normen,
Policies; `graph.citation-extract` für wiss. Paper, Patente, Spezi­
Italien, Brasilien); `text.deontic_extract` für Verträge, ISO-Normen,
Policies; `graph.citation_extract` für wiss. Paper, Patente, Spezi­
fikationen. Damit ist `chain-modules-law/` am Ende sehr klein —
nur `law.benefit-score`, weil die 7 Bewertungs-Dimensionen
nur `law.benefit_score`, weil die 7 Bewertungs-Dimensionen
(Schutz/Markt/Rechtssicherheit/EU-Binnenmarkt/…) genuin juristisch-
politisch konventioniert sind. **`text.akoma-normalize` ist der
politisch konventioniert sind. **`text.akoma_normalize` ist der
Pflicht-Eingang**: heterogene Quellen (gesetze-im-internet XML,
landesrecht-berlin HTML, EUR-Lex FORMEX) werden in Akoma-Ntoso-XML
normalisiert — ab da nur noch ein Datenformat. Alles Generische
@ -231,24 +231,24 @@ steps:
method: GET
etag_cache: true
- id: normalize
use: text.akoma-normalize@^0 # XML | HTML | FORMEX → Akoma Ntoso
use: text.akoma_normalize@^0 # XML | HTML | FORMEX → Akoma Ntoso
with: { content: ${{ pull.body }}, mime: ${{ pull.content_type }} }
- id: graph
use: graph.citation-extract@^0
use: graph.citation_extract@^0
with: { norm: ${{ normalize.norm }} }
- id: duties
use: text.deontic-extract@^0
use: text.deontic_extract@^0
with: { norm: ${{ normalize.norm }} }
- id: skm
use: econ.skm-score@^0
use: econ.skm_score@^0
with:
duties: ${{ duties.list }}
population_table: "destatis://unternehmensregister/berlin-kmu"
- id: nutzen
use: law.benefit-score@^0
use: law.benefit_score@^0
with: { norm: ${{ normalize.norm }}, duties: ${{ duties.list }} }
- id: frust
use: text.readability-score@^0
use: text.readability_score@^0
with: { norm: ${{ normalize.norm }}, graph: ${{ graph.edges }} }
- id: review
use: system.approval@^0
@ -780,7 +780,7 @@ Juristen-Approval und PDF-Ausgabe.
- [ ] Modul `law.graph_extract` (Verweisextraktion, sehr eingeschränkt:
„§X i.V.m. §Y", „Artikel Z DSGVO" usw.)
- [ ] Modul `law.skm_score` mit *manuell* gepflegten Aufwand-Schätzungen
- [ ] Modul `law.benefit-score` mit RAG + Approval
- [ ] Modul `law.benefit_score` mit RAG + Approval
- [ ] Modul `law.frust_score` (deterministisch, kein LLM)
- [ ] Flow `bewerten-eine-norm.yaml`
- [ ] PDF-Export-Modul (für AG-Sitzungen)
@ -874,7 +874,7 @@ liegt dann woanders.
Vendor-Namespace `fai/`), Lizenz Apache 2.0, DCO an, CI-Pipeline analog
`fai/chain` (DCO-Sign-off, Conventional Commits, SBOM, sigstore).
`law.*`-Module später in `chain-modules-law/` als product-scoped Org.
6. **Modul-Stub `text.akoma-normalize`** in `chain-modules/text-akoma-normalize/`
6. **Modul-Stub `text.akoma_normalize`** in `chain-modules/text-akoma-normalize/`
als ersten Code-Commit (vertikaler Durchstich beginnt mit dem Pflicht-Eingang;
HTTP-Pull macht `http.request` aus Bestand). Parallel **Flutter-App-Skelett**
in `fai_reclaim/app/` (Theme nach fai_web-Palette, Hub-Connect-Seite).

10
RUN.md
View file

@ -121,10 +121,10 @@ Selber Aufruf für die anderen sieben Verzeichnisse.
```bash
chain serve &
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 \
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
chain run flows/durchstich-gewo-14.yaml \
--input norm_url=https://www.gesetze-im-internet.de/gewo/__14.xml \
@ -144,4 +144,4 @@ keine UI-Änderung nötig.
- DESTATIS GENESIS-API-Adapter (Woche 4)
- Juristen-Approval-Backend-Anbindung (Woche 5)
- Volle Akoma-Ntoso-Konvertierung (v0.2)
- HTML- und FORMEX-Adapter für `text.akoma-normalize` (v0.2/0.3)
- HTML- und FORMEX-Adapter für `text.akoma_normalize` (v0.2/0.3)

View file

@ -13,33 +13,33 @@ inputs:
ratings: json
steps:
- id: normalize
use: text.akoma-normalize@^0
use: text.akoma_normalize@^0
with:
content: $inputs.content
mime: "application/xml"
- id: deontic
use: text.deontic-extract@^0
use: text.deontic_extract@^0
with:
norm: $normalize.norm
- id: citations
use: graph.citation-extract@^0
use: graph.citation_extract@^0
with:
norm: $normalize.norm
- id: cohort
use: stats.cohort-size@^0
use: stats.cohort_size@^0
with:
cohort_id: $inputs.cohort_id
- id: frust
use: text.readability-score@^0
use: text.readability_score@^0
with:
norm: $normalize.norm
graph: $citations.citations
- id: skm
use: econ.skm-score@^0
use: econ.skm_score@^0
with:
duties: $inputs.duties
- id: benefit
use: law.benefit-score@^0
use: law.benefit_score@^0
with:
ratings: $inputs.ratings
outputs:
@ -73,11 +73,11 @@ class NormLiveInput {
final String cohortId;
/// `{ duties: [ { population, frequency, tariff_eur_per_hour,
/// time_hours_per_case, source_norm, tier } ] }` for econ.skm-score.
/// time_hours_per_case, source_norm, tier } ] }` for econ.skm_score.
final Map<String, Object?> duties;
/// `{ schutz, markt, rechtssicherheit, eu_binnenmarkt, sicherheit,
/// umwelt, einnahmen }` (each 0..5) for law.benefit-score.
/// umwelt, einnahmen }` (each 0..5) for law.benefit_score.
final Map<String, Object?> ratings;
final Jurisdiction jurisdiction;

View file

@ -270,7 +270,7 @@ class Norm {
final String? supersededNote;
/// The actual paragraphs of the norm text, normalised by
/// `text.akoma-normalize` in live mode. In demo mode the
/// `text.akoma_normalize` in live mode. In demo mode the
/// fixture quotes the public source verbatim under §5 UrhG
/// (amtliche Werke).
final List<NormParagraph> paragraphs;

View file

@ -68,7 +68,7 @@ class NormTextCard extends StatelessWidget {
if (paragraphs.isEmpty)
Text(
'Für diese Norm ist noch kein normalisierter Text '
'eingebunden. Wenn Ch∆In mit `text.akoma-normalize@^0` '
'eingebunden. Wenn Ch∆In mit `text.akoma_normalize@^0` '
'gegen die Quell-URL läuft, erscheinen die Absätze hier.',
style: t.bodyLarge?.copyWith(color: ReclaimColors.mute),
)

View file

@ -18,13 +18,13 @@ inputs:
steps:
- id: normalize
use: text.akoma-normalize@^0
use: text.akoma_normalize@^0
with:
content: $inputs.content
mime: "application/xml"
- id: cohort
use: stats.cohort-size@^0
use: stats.cohort_size@^0
with:
cohort_id: $inputs.cohort_id

View file

@ -7,7 +7,7 @@
# + frust + cohort, also die Form, die HubRepository.list() in der
# Recl∆Im-App in Evaluation-Objekte übersetzt.
#
# NICHT enthalten: econ.skm-score und law.benefit-score. Beide
# NICHT enthalten: econ.skm_score und law.benefit_score. Beide
# Module lesen ihren Tupel-/Ratings-Input über `require_json`,
# d.h. sie erwarten ein Payload::Json. In einem Flow lässt sich
# ein Json-Wert aber nur aus einem vorhergehenden Step-Output
@ -35,28 +35,28 @@ inputs:
steps:
- id: normalize
use: text.akoma-normalize@^0
use: text.akoma_normalize@^0
with:
content: $inputs.content
mime: "application/xml"
- id: deontic
use: text.deontic-extract@^0
use: text.deontic_extract@^0
with:
norm: $normalize.norm
- id: citations
use: graph.citation-extract@^0
use: graph.citation_extract@^0
with:
norm: $normalize.norm
- id: cohort
use: stats.cohort-size@^0
use: stats.cohort_size@^0
with:
cohort_id: $inputs.cohort_id
- id: frust
use: text.readability-score@^0
use: text.readability_score@^0
with:
norm: $normalize.norm
graph: $citations.citations
@ -65,11 +65,11 @@ steps:
# nach dem Fix gilt — `inputs:` oben um `duties: json` /
# `ratings: json` ergänzen und mit --input duties=… speisen:
# - id: skm
# use: econ.skm-score@^0
# use: econ.skm_score@^0
# with:
# duties: $inputs.duties
# - id: benefit
# use: law.benefit-score@^0
# use: law.benefit_score@^0
# with:
# ratings: $inputs.ratings

View file

@ -1,11 +1,11 @@
# Phase-0 vertikaler Durchstich für GewO §14.
#
# Minimaler Pfad zum ersten echten flow.completed-Event im
# Audit-Log — http.request → text.akoma-normalize →
# stats.cohort-size → system.approval. Beweist, dass die
# 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
# 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:
@ -31,13 +31,13 @@ steps:
method: "GET"
- id: normalize
use: text.akoma-normalize@^0
use: text.akoma_normalize@^0
with:
content: $pull.body
mime: "application/xml"
- id: cohort
use: stats.cohort-size@^0
use: stats.cohort_size@^0
with:
cohort_id: $inputs.cohort_id

View file

@ -1,4 +1,4 @@
# Minimal-Test: nur stats.cohort-size, ohne externe Calls.
# Minimal-Test: nur stats.cohort_size, ohne externe Calls.
# Beweist, dass meine Module mit dem Hub-ABI kompatibel sind.
name: test-cohort
@ -8,7 +8,7 @@ inputs:
steps:
- id: cohort
use: stats.cohort-size@^0
use: stats.cohort_size@^0
with:
cohort_id: $inputs.cohort_id

View file

@ -1,10 +1,9 @@
# .chain bundle sha256 (unsigned, chain pack 0.17.2; bundles include STORE.yaml/MODULE.md/icon)
# capability IDs use the dash form (chain catalog charset [a-z0-9-]); repacked 2026-06-20.
1c17771f632a5562534afc0e2420f8d05009cd988bf05899e8d53b3e550bf826 text-akoma-normalize-0.1.0.chain
decf49eb8098a202ab858e868b122620eb55b58e2cc464ba0bbb61025defca4b text-deontic-extract-0.1.0.chain
dd1e9bd7c45d29804f5ab4360f6ff9d8d2ab608299633dff438eaa5f81807463 graph-citation-extract-0.1.0.chain
382d470f3243dd02b2da6f210fee9573f5ab64e9439358a74af34a0f8167a5b6 text-readability-score-0.1.0.chain
321458faa4e8c7a2c016409052b00f89a22a3486c28ec4dccd3586426ef7037c stats-cohort-size-0.1.0.chain
0d776294f86d8e397149efb18100543ea3951129780fed85ad9d1243ec146800 graph-shapley-attribution-0.1.0.chain
dda50b045ab3b054fe71c81c8510a15e58a4da1a8218a7961e7b014854f0d125 econ-skm-score-0.1.0.chain
4f02c2695640ba92fe7cd8dc263bcdd024ceeaa1c1ef29848286ec16135e0f50 law-benefit-score-0.1.0.chain
# .fai bundle sha256 (unsigned, chain pack 0.17.2; bundles include STORE.yaml/MODULE.md/icon)
fdf4f6e369280fc91608d4e7de78cdd0d6d399a75512a10765b2c632df41bed2 text-akoma-normalize-0.1.0.fai
c944d60f9a6a562dd6cbd03b9709a662a60c764a7ea81a1c98f2bd077e356d79 text-deontic-extract-0.1.0.fai
e8d70e322f1df83ebaea36676ec42f27c26b4fac78eedf23499f25225318c9f4 graph-citation-extract-0.1.0.fai
1427f101cf56ac58b1a10efc9a63e3e4cf2292841b214d533869b9504019bb73 text-readability-score-0.1.0.fai
6bc1ee5862728d218f2e40060146099f05eb67cc9e9c4c7a2eec5928c0a0b6fe stats-cohort-size-0.1.0.fai
93507cba5c4e819ce755f0e89cc79a4350363fb4aa96132cefd0eeb966b320a4 graph-shapley-attribution-0.1.0.fai
57e6c6a855f6e542e1045a0c9b0c0d484a2e7297de084ae4d7865173771e7493 econ-skm-score-0.1.0.fai
2781518744e6b1048216b2fc4b784ab3f18e55cb3fc9e77cb640e302b9ed7bb2 law-benefit-score-0.1.0.fai

View file

@ -1,34 +1,28 @@
# Recl∆Im module store index — source of truth before publish.
#
# Canonical host (chain Studio's "Recl∆Im hinzufügen" button + hub fetch):
# https://git.flemming.ai/chain-modules/reclaim/raw/branch/main/store.yaml
# Decision by chain 2026-06-19: Forgejo-raw is canonical (Studio was already
# wired to it; reclaim publishes via plain `git push`, no SSH to the mirror).
# Target host (chain Studio's one-click "Recl∆Im hinzufügen" button
# points here): https://releases.chain.flemming.ai/reclaim/store.yaml
#
# STATUS (2026-06-20). Per chain: publish UNSIGNED for now —
# STATUS (2026-06-19). Per chain: publish UNSIGNED for now —
# `require_signatures` is off by default; FAI_SIGNING_KEY untouched;
# a Recl∆Im-own signing key + per-store pinning come later.
# * sha256 — REAL, from local `chain pack` of each module.
# Bundles staged in store/bundles/, hashes mirrored
# in store/SHA256.txt. Bundles are UNSIGNED.
# * signature — intentionally absent for now (see above).
# * wasm_url — Forgejo raw URLs in this repo under bundles/.
# Publish = commit store.yaml + bundles/*.chain and
# `git push` to chain-modules/reclaim (main).
# * wasm_url — points at the intended mirror path. The ONLY
# remaining step is HOSTING the 8 .fai + this
# store.yaml at releases.chain.flemming.ai/reclaim/
# — the mirror push is chain infra (scp to the
# Hetzner host); reclaim has no SSH access. Confirm
# the canonical wasm_url host (mirror vs Forgejo
# release) with chain.
#
# NAMING NOTE (2026-06-20): capability IDs are the source of truth and the
# store `name:` must match the bundled `provides.capability` EXACTLY
# (resolution is string-exact). chain's catalog charset (`naming.rs`
# `check_segment`, `capability-namespaces.yaml`) allows only `[a-z0-9-]`
# per dot-segment — NO underscore. So all 8 modules were repacked with the
# DASH form (`econ.skm-score`, `law.benefit-score`, …) and this index
# mirrors that. (The `chain validate` lint enforces dash; pack/install do
# not — but we conform to the catalog rather than rely on lax gates.)
#
# EXTENSION NOTE (2026-06-20): bundles use the `.chain` extension (current
# convention, `bundle.rs` BUNDLE_EXT). Bundles are content-addressed by
# sha256, so the extension is cosmetic and legacy `.fai` would also
# install — but we match the current convention.
# NAMING NOTE for chain: every module's `provides.capability` uses an
# UNDERSCORE (`econ.skm_score`), but this index + the Studio button use
# the DASH form (`econ.skm-score`) per the handoff. install resolution
# must map dash↔underscore, or the modules must be renamed. Flagging —
# this is a chain naming-convention decision.
schema_version: 1
@ -37,8 +31,8 @@ modules:
versions:
- version: 0.1.0
status: published
wasm_url: https://git.flemming.ai/chain-modules/reclaim/raw/branch/main/bundles/text-akoma-normalize-0.1.0.chain
sha256: 1c17771f632a5562534afc0e2420f8d05009cd988bf05899e8d53b3e550bf826
wasm_url: https://releases.chain.flemming.ai/reclaim/text-akoma-normalize/v0.1.0/text-akoma-normalize-0.1.0.fai
sha256: fdf4f6e369280fc91608d4e7de78cdd0d6d399a75512a10765b2c632df41bed2
tagline:
en: "Normalize legal documents to Akoma Ntoso"
de: "Rechtsdokumente nach Akoma Ntoso normalisieren"
@ -54,8 +48,8 @@ modules:
versions:
- version: 0.1.0
status: published
wasm_url: https://git.flemming.ai/chain-modules/reclaim/raw/branch/main/bundles/text-deontic-extract-0.1.0.chain
sha256: decf49eb8098a202ab858e868b122620eb55b58e2cc464ba0bbb61025defca4b
wasm_url: https://releases.chain.flemming.ai/reclaim/text-deontic-extract/v0.1.0/text-deontic-extract-0.1.0.fai
sha256: c944d60f9a6a562dd6cbd03b9709a662a60c764a7ea81a1c98f2bd077e356d79
tagline:
en: "Extract duties, prohibitions and permissions from norms"
de: "Pflichten, Verbote und Erlaubnisse aus Normen extrahieren"
@ -71,8 +65,8 @@ modules:
versions:
- version: 0.1.0
status: published
wasm_url: https://git.flemming.ai/chain-modules/reclaim/raw/branch/main/bundles/graph-citation-extract-0.1.0.chain
sha256: dd1e9bd7c45d29804f5ab4360f6ff9d8d2ab608299633dff438eaa5f81807463
wasm_url: https://releases.chain.flemming.ai/reclaim/graph-citation-extract/v0.1.0/graph-citation-extract-0.1.0.fai
sha256: e8d70e322f1df83ebaea36676ec42f27c26b4fac78eedf23499f25225318c9f4
tagline:
en: "Build typed citation graphs from legal text"
de: "Typisierte Zitationsgraphen aus Rechtstext bauen"
@ -88,8 +82,8 @@ modules:
versions:
- version: 0.1.0
status: published
wasm_url: https://git.flemming.ai/chain-modules/reclaim/raw/branch/main/bundles/text-readability-score-0.1.0.chain
sha256: 382d470f3243dd02b2da6f210fee9573f5ab64e9439358a74af34a0f8167a5b6
wasm_url: https://releases.chain.flemming.ai/reclaim/text-readability-score/v0.1.0/text-readability-score-0.1.0.fai
sha256: 1427f101cf56ac58b1a10efc9a63e3e4cf2292841b214d533869b9504019bb73
tagline:
en: "Composite readability and complexity score"
de: "Komposit-Score für Lesbarkeit und Komplexität"
@ -105,8 +99,8 @@ modules:
versions:
- version: 0.1.0
status: published
wasm_url: https://git.flemming.ai/chain-modules/reclaim/raw/branch/main/bundles/stats-cohort-size-0.1.0.chain
sha256: 321458faa4e8c7a2c016409052b00f89a22a3486c28ec4dccd3586426ef7037c
wasm_url: https://releases.chain.flemming.ai/reclaim/stats-cohort-size/v0.1.0/stats-cohort-size-0.1.0.fai
sha256: 6bc1ee5862728d218f2e40060146099f05eb67cc9e9c4c7a2eec5928c0a0b6fe
tagline:
en: "Resolve addressee cohort sizes"
de: "Größe von Adressaten-Kohorten ermitteln"
@ -122,8 +116,8 @@ modules:
versions:
- version: 0.1.0
status: published
wasm_url: https://git.flemming.ai/chain-modules/reclaim/raw/branch/main/bundles/graph-shapley-attribution-0.1.0.chain
sha256: 0d776294f86d8e397149efb18100543ea3951129780fed85ad9d1243ec146800
wasm_url: https://releases.chain.flemming.ai/reclaim/graph-shapley-attribution/v0.1.0/graph-shapley-attribution-0.1.0.fai
sha256: 93507cba5c4e819ce755f0e89cc79a4350363fb4aa96132cefd0eeb966b320a4
tagline:
en: "Shapley-style attribution on weighted graphs"
de: "Shapley-Attribution auf gewichteten Graphen"
@ -139,8 +133,8 @@ modules:
versions:
- version: 0.1.0
status: published
wasm_url: https://git.flemming.ai/chain-modules/reclaim/raw/branch/main/bundles/econ-skm-score-0.1.0.chain
sha256: dda50b045ab3b054fe71c81c8510a15e58a4da1a8218a7961e7b014854f0d125
wasm_url: https://releases.chain.flemming.ai/reclaim/econ-skm-score/v0.1.0/econ-skm-score-0.1.0.fai
sha256: 57e6c6a855f6e542e1045a0c9b0c0d484a2e7297de084ae4d7865173771e7493
tagline:
en: "Standard Cost Model (SKM) bureaucracy cost"
de: "Standardkostenmodell (SKM) — Bürokratiekosten"
@ -156,8 +150,8 @@ modules:
versions:
- version: 0.1.0
status: published
wasm_url: https://git.flemming.ai/chain-modules/reclaim/raw/branch/main/bundles/law-benefit-score-0.1.0.chain
sha256: 4f02c2695640ba92fe7cd8dc263bcdd024ceeaa1c1ef29848286ec16135e0f50
wasm_url: https://releases.chain.flemming.ai/reclaim/law-benefit-score/v0.1.0/law-benefit-score-0.1.0.fai
sha256: 2781518744e6b1048216b2fc4b784ab3f18e55cb3fc9e77cb640e302b9ed7bb2
tagline:
en: "7-dimensional regulatory benefit score"
de: "7-dimensionaler Nutzen-Score für Regulierung"