Metadata-Version: 2.4
Name: presidio-hardened-ikigov-assess
Version: 0.21.1
Summary: IKI-Gov Assessment Tool — operationalises the Integrated KI-Governance Reference Model for AI use-case governance.
Project-URL: Repository, https://github.com/presidio-v/presidio-hardened-ikigov-assess
License: MIT License
        
        Copyright (c) 2026 Vladimir Stantchev
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: ai-governance,compliance,iki-gov,iso42001
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Requires-Dist: prompt-toolkit>=3.0.52
Requires-Dist: rich>=14.3.4
Requires-Dist: typer>=0.23.2
Provides-Extra: audit
Requires-Dist: pip-audit>=2.6.0; extra == 'audit'
Provides-Extra: crypto
Requires-Dist: cryptography>=42; extra == 'crypto'
Provides-Extra: dev
Requires-Dist: cryptography>=42; extra == 'dev'
Requires-Dist: mcp>=1.2.0; (python_version >= '3.10') and extra == 'dev'
Requires-Dist: pip-audit>=2.6.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=8.4.2; extra == 'dev'
Requires-Dist: ruff>=0.15.10; extra == 'dev'
Provides-Extra: mcp
Requires-Dist: mcp>=1.2.0; (python_version >= '3.10') and extra == 'mcp'
Description-Content-Type: text/markdown

# presidio-hardened-ikigov-assess

**IKI-Gov Assessment Tool** — operationalises the IKI-Gov-Referenzmodell (Integrated KI-Governance Reference Model) as a practical CLI tool for assessing AI use cases against a structured governance framework.

The IKI-Gov framework structures AI governance along a central lifecycle
(Kontext → Konzeption → Entwicklung → Freigabe → Betrieb → Anpassung → Außerbetriebnahme)
surrounded by six domains and measured across six dimensions (M1–M6) with six quality gates
(G0–G5).

Reference: Stantchev, V. *IKI-Gov-Referenzmodell* — Integrated KI-Governance Reference Model.

---

## The book

This tool implements the **IKI-Gov reference model**, introduced in the forthcoming
Springer monograph by Vladimir Stantchev — published in two editions:

- **AI and IT-Governance** (English)
- **KI und IT-Governance** (German)

The book works from classical IT governance (COBIT, ITIL, ISO/IEC 38500) toward AI
governance across ethics, law, risk, and data, then assembles IKI-Gov: the lifecycle,
six domains, six measurement dimensions (M1–M6), and six quality gates (G0–G5). The 25
checklist items scored here are drawn from the book's framework chapter and its
workshop/approval-gate appendix; the ISO/IEC 42001 and EU AI Act mappings follow its
orientation tables.

The book presents the model as a reasoned synthesis and a working heuristic for
orientation — not legal advice and not a conformity assessment. This tool holds the same
line (see the disclaimers on the `euaiact-gap` and `iso-gap` commands). Publication
details (ISBN, dates, Springer link) are finalised at the publisher and will be added
here once they are public.

---

## Installation

```bash
pip install presidio-hardened-ikigov-assess

# With dependency CVE checking
pip install "presidio-hardened-ikigov-assess[audit]"

# With Ed25519 public-key evidence verification
pip install "presidio-hardened-ikigov-assess[crypto]"
```

---

## Quick Start

```bash
# Parameter-driven assessment
iga assess --use-case "fraud-scoring" --risk-class high --lang en \
    --affirm S1,S2,S3,D1,D2,T1,T4,O1,I1

# Interactive wizard (step-by-step)
iga assess --interactive --lang de --risk-class high --use-case "kredit-scoring"

# Gate readiness check
iga gate --gate G2 --risk-class high \
    --affirm S1,S2,S3,D1,D2,T1,T4,O1,I1 --lang en

# CI pipeline gate assertion (exit 0 OPEN / 2 PARTIAL / 3 BLOCKED)
iga gate --gate G1 --risk-class high --affirm S1,S2,D1,D2 --assert-gate G1

# Strict mode: skipped gate-critical items count as blocking
iga gate --gate G2 --risk-class high --affirm S1,S2 --skip D3 --strict --assert-gate G2

# Machine-readable JSON (scriptable, no progress bars)
iga assess --affirm S1,S2,S3 --quiet
iga gate --gate G0 --affirm S1,S2 --skip S3 --quiet

# Export report to Markdown (stdout)
iga report --use-case "fraud-scoring" --risk-class high \
    --affirm S1,S2,S3,D1,D2,T1 --format markdown

# Export report to JSON
iga report --use-case "fraud-scoring" --affirm S1,S2 --format json

# Write the report to a file (Markdown or JSON)
iga report --use-case "fraud-scoring" --affirm S1,S2,T4 --output audit/fraud-scoring.md
iga report --use-case "fraud-scoring" --affirm S1,S2 -f json -o fraud-scoring.json

# ISO/IEC 42001 clause-level coverage gap analysis
iga iso-gap --use-case "fraud-scoring" --risk-class high --affirm S1,S2,S3,I1,I2
iga iso-gap --affirm S2,S3,I1,I2 --quiet   # machine-readable JSON

# EU AI Act high-risk obligations (Art. 9–17) — high-risk systems only
iga euaiact-gap --use-case "fraud-scoring" --affirm S1,S2,S3,S4,S5,D1,D5
iga euaiact-gap --affirm S1,S2 --quiet

# Persist assessments and view the portfolio (SQLite at ~/.iga/assessments.db)
iga assess --use-case "fraud-scoring" --risk-class high --affirm S1,S2,S3 --save
iga list                                   # table of saved assessments
iga portfolio                              # aggregated M1–M6 + blocked gates
iga trend --use-case "fraud-scoring"       # delta vs the previous saved run
iga delete --use-case "fraud-scoring"      # hard-delete

# List saved assessments (persistence in v0.6.0)
iga list
```

### Example output

```
IKI-Gov Assessment — fraud-scoring  [risk: HIGH]

Measurement Dimensions
  M1  Strategie & Ownership          ████████░░   80.0 %
  M2  Data Quality & Lineage         ██████░░░░   60.0 %
  M3  Validation & Fairness          ████░░░░░░   40.0 %
  M4  Security & Robustness          █████████░   90.0 %
  M5  Compliance Evidence            ███░░░░░░░   30.0 %
  M6  Operations, Drift & Incidents  ██████░░░░   60.0 %
  ──────────────────────────────────────────────────────
       Overall maturity                           60.0 %

Gate Readiness
  G0  OPEN
  G1  OPEN
  G2  PARTIAL  [skipped: D3]
  G3  BLOCKED  — blocking: T5 (A security review of the model pipeline…)
  G4  BLOCKED
  G5  BLOCKED
```

---

## Checklist

25 items derived from the five appendix sections of the IKI-Gov framework:

| Prefix | Section | M-Dimension |
|--------|---------|-------------|
| S1–S5 | Strategie & Geschäftsfall | M1 Strategie & Ownership |
| D1–D5 | Daten, Recht & Ethik | M2 Datenqualität & Lineage |
| T1–T3 | Modell, Sicherheit & Technik | M3 Validierung & Fairness |
| T4–T5 | Modell, Sicherheit & Technik | M4 Sicherheit & Robustheit |
| O1–O5 | Betrieb, Monitoring & Aufsicht | M6 Betrieb, Drift & Vorfälle |
| I1–I5 | ISO/IEC 42001 Abgleich | M5 Compliance-Nachweise |

---

## Scoring

```
score_m(dim) = sum(weight_i for affirmed items in dim)
               / sum(weight_i for non-skipped items in dim) × 100

overall = arithmetic mean(M1, M2, M3, M4, M5, M6)
```

Risk-class multipliers: `low` = 1.0 · `medium` = 1.5 · `high` = 2.0.
Skipped items are excluded from both numerator and denominator (conservative).

---

## Gates

| Gate | Lifecycle transition |
|------|---------------------|
| G0 | Kontext → Konzeption |
| G1 | Konzeption → Entwicklung |
| G2 | Entwicklung → Freigabe |
| G3 | Freigabe → Betrieb |
| G4 | Betrieb → Anpassung |
| G5 | Anpassung → Außerbetriebnahme |

**Status:** **OPEN** (all affirmed) · **PARTIAL** (some skipped, none denied) · **BLOCKED** (≥1 denied)

### Risk-class-aware thresholds (v0.3.0)

How skips are treated depends on the active risk class:

| Risk class | Skipped gate-critical items |
|------------|-----------------------------|
| `low` | forgiven — a gate with skips but no denials is **OPEN** |
| `medium` | tolerated — the gate is **PARTIAL** until they are affirmed |
| `high` | not permitted — skips **BLOCK** the gate (strict by default) |

`--strict` forces high-risk behaviour at any risk class. When a skip blocks a gate,
it is reported separately (`blocking_skips`) so the reason for a BLOCKED-not-PARTIAL
gate is explicit.

### CI exit codes

`--assert-gate Gn` exits with a status-specific code so pipelines can branch without
parsing output:

| Exit code | Meaning |
|-----------|---------|
| `0` | gate OPEN |
| `2` | gate PARTIAL |
| `3` | gate BLOCKED |
| `1` | general error (invalid input, gate mismatch) |

`--quiet` (`-q`) on `assess` and `gate` emits machine-readable JSON only.

---

## Regulatory-Content Packs (v0.16.0)

The ISO/IEC 42001 and EU AI Act mappings are versioned **content packs** behind a generic
coverage engine, so new frameworks are added as data:

```bash
iga content-list                              # built-in + external packs (versions, hashes)
iga framework-gap --framework iso42001 --affirm S1,S2,D1
iga framework-gap --framework euaiact --risk-class high --affirm S1,S2,D5 --quiet
iga framework-gap --framework nist-ai-rmf --affirm S1,S2,S3   # NIST AI RMF (Govern/Map/Measure/Manage)
```

A pack maps each target (clause/article) to the checklist items or gates that evidence it.
Drop a JSON pack into `IGA_CONTENT_PATH` (or `~/.iga/content/`) to add or override a
framework; an external pack with the same `framework_id` overrides the built-in. The
legacy `iso-gap` / `euaiact-gap` commands are unchanged.

## ISO/IEC 42001 Coverage

`iga iso-gap` maps the assessment to ISO/IEC 42001 clause-level coverage. Each
clause group (clauses 4–10 and Annex A controls) is reported as **covered** (all
mapped checklist items affirmed), **partial**, or **gap**, with the outstanding
items listed per incompletely-covered clause:

```
ISO/IEC 42001 Coverage Gap Analysis — fraud-scoring  [risk: HIGH]

  4   Context of the organization      PARTIAL    (1/2)  — Outstanding items: S4
  5   Leadership                       COVERED    (4/4)
  8   Operation                        GAP        (0/13) — Outstanding items: D1, D2, …
  A   Annex A (Controls)               GAP        (0/12) — Outstanding items: …
```

Skipped and denied items count as *not affirmed* (no coverage credit). The
item→clause matrix is derived from the IKI-Gov orientation table
(`tab:framework-iso42001-matrix`) and centralised in `checklist.ISO_CLAUSES_BY_ITEM`.
Use `--quiet` for machine-readable JSON.

---

## EU AI Act (High-Risk Systems)

`iga euaiact-gap` maps gate readiness to the EU AI Act obligations for high-risk
systems (Title III Ch. 2, Articles 9–17). Each article is reported OPEN / PARTIAL /
BLOCKED based on the readiness of the gates that generate its evidence:

```
EU AI Act High-Risk Compliance Gap — fraud-scoring  [risk: HIGH]

  Art. 9   Risk management system     G0, G1, G2, G4   PARTIAL  — G2 BLOCKED, G4 BLOCKED
  Art. 10  Data and data governance   G1               OPEN
  Art. 11  Technical documentation    G2, G3, G5       BLOCKED  — G2/G3/G5 BLOCKED
```

The gate→article mapping is transcribed verbatim from the IKI-Gov book
(`tab:framework-euaiact-gates`) and lives in `euaiact.EU_AI_ACT_ARTICLE_GATES`.
The command is for high-risk systems only (exits with a warning for low/medium
risk); `--quiet` emits JSON.

> This tool does not constitute legal advice or a conformity assessment.

---

## Persistence & Portfolio

`iga assess --save` persists an assessment to a local SQLite database at
`~/.iga/assessments.db` (override with the `IGA_DB_PATH` env var). The portfolio
commands then work across saved use cases:

| Command | Purpose |
|---------|---------|
| `iga list` | Table of all saved assessments (use case, risk, overall, timestamp) |
| `iga portfolio` | Mean M1–M6 and overall maturity across the latest assessment per use case, plus a count of use cases with each gate BLOCKED |
| `iga trend --use-case X` | Per-dimension delta (▲/▼/=), overall maturity change, and gate transitions between two saved runs (latest vs previous, or a `--from`/`--to` window) |
| `iga delete --use-case X` | Hard-delete all saved assessments for a use case |

`list` and `portfolio` support `--quiet` for JSON. Only what you provide is stored
(use-case name, risk class, language, answers/scores/gates); the database file is
created with `0600` permissions and the `~/.iga` directory with `0700`. `delete` is
a hard delete; no soft-delete log is retained.

---

## External Evidence

Affirmations can be backed by **signed evidence** emitted by peer `presidio-hardened-*`
controls (first producer: `presidio-hardened-ai`), upgrading an item from *self-attested*
to *evidence-backed* — or cryptographically **verified** against a local trust store.
Verification is fail-closed: a missing, malformed, or wrong signature never counts as verified.

```bash
# Affirm items from an evidence document, verifying signatures against a trust store
iga assess --use-case "fraud-scoring" --risk-class high \
    --evidence evidence.json --trust trust.json

# Fail-closed: only references that verify against --trust affirm their item
iga assess --use-case "fraud-scoring" --risk-class high \
    --evidence evidence.json --trust trust.json --require-evidence

# Verify a document on its own (exit 0 only if every reference verifies)
iga verify-evidence --evidence evidence.json --trust trust.json
```

An **evidence document** is the producer's `EvidenceRef` JSON:

```json
{
  "schema": "presidio-hardened/evidence-ref@1",
  "use_case": "fraud-scoring",
  "evidence": [
    {
      "item_id": "D1",
      "source": "presidio-hardened-ai",
      "source_version": "0.2.0",
      "ledger_ref": "pai-ledger:seq/0",
      "content_hash": "abc123def456",
      "signer": "presidio-hardened-ai",
      "signature": "2e7af6d2…",
      "claimed_at": "2026-06-08T00:00:00+00:00"
    }
  ]
}
```

A **trust store** maps each signer to its key. An entry is either a bare HMAC secret
(back-compat) or an object declaring the algorithm and key material:

```json
{
  "presidio-hardened-ai": "shared-hmac-secret",
  "peer-control": { "alg": "ed25519", "public_key": "<64-hex-char public key>" }
}
```

For **key rotation**, `public_key` (or `key` for HMAC) may be a **list** — a signature
verifies if it matches any listed key, so a new key can run alongside the old one during an
overlap window; revoke by removing the key from the store:

```json
{
  "peer-control": { "alg": "ed25519", "public_key": ["<new public key>", "<retiring key>"] }
}
```

Ed25519 (RFC 8032) public-key verification lets a verifier hold **only public keys** (no
shared secret with the producer) and requires the `[crypto]` extra. Signatures are over the
canonical `{content_hash, signer}` message; signer keys are resolved from the local trust
store only (no network). Evidence references carry hashes and opaque ledger URIs, never PII.

> **How this fits the wider suite:** ikigov-assess is the governance *spine* that consumes
> evidence from peer `presidio-hardened-*` controls. For the cross-repo overview (how the
> family interlocks and an end-to-end demo), see
> [presidio-hardened-* Suite Architecture](https://github.com/presidio-v/presidio-hardened-ai/blob/main/docs/ARCHITECTURE.md)
> (in `presidio-hardened-ai`).

---

## MCP Server

The assessment engine is also available as a [Model Context Protocol](https://modelcontextprotocol.io)
server, so MCP-capable LLM agents and clients can run IKI-Gov assessments as tools.

```bash
# Install with the MCP extra (requires Python 3.10+)
pip install "presidio-hardened-ikigov-assess[mcp]"

# Run the server over stdio
iga-mcp
```

Register it with an MCP client (e.g. Claude Desktop) by adding to the client's config:

```json
{
  "mcpServers": {
    "iki-gov-assess": {
      "command": "iga-mcp"
    }
  }
}
```

### Tools

| Tool | Purpose |
|------|---------|
| `iga_framework_info` | Describe the model: lifecycle phases, dimensions M1–M6, gates G0–G5, sections, risk classes (de/en) |
| `iga_list_checklist` | Return all 25 checklist items with IDs, text, dimension, gates, and section |
| `iga_assess` | Score a use case from affirmed/skipped item IDs → M1–M6 scores, overall maturity, gate readiness |
| `iga_assess_with_evidence` | Score a use case from signed `EvidenceRef` documents, verifying signatures against a trust store (HMAC or Ed25519) |
| `iga_check_gate` | Evaluate readiness for a single gate G0–G5 with blocking/skipped items |
| `iga_iso_gap` | Map affirmed items to ISO/IEC 42001 clause coverage (covered / partial / gap) |
| `iga_euaiact_gap` | Map to EU AI Act high-risk obligations Art. 9–17 (OPEN / PARTIAL / BLOCKED) |

All tools share the CLI's input validation and output sanitisation, return the same
structured JSON schema as `iga report --format json`, and respect the per-session
abuse guard (returning a tool error rather than terminating the server when exceeded).

---

## Evidence-Pack Export (v0.15.0)

Export a signed, audit-ready bundle of an assessment and verify it later:

```bash
# Write report.md + report.json + manifest.json (sha256 of each artifact + framework hash).
# Seal the manifest with an HMAC key read from a file (kept off argv / shell history).
iga export --use-case fraud-scoring --risk-class high --affirm S1,S2,D1 \
    --bundle audit/fraud-scoring/ --sign-key-file ~/.iga/seal.key

# Re-hash artifacts against the manifest (and check the optional HMAC seal).
iga verify-bundle --bundle audit/fraud-scoring/ --sign-key-file ~/.iga/seal.key
```

The `manifest.json` content-hashes every artifact and records a `framework_content_hash`
pinning the checklist + ISO/EU AI Act mappings that produced the assessment, so any later
edit is detected by `verify-bundle`. Use `--zip` to emit a `.zip`. (PDF rendering and a
public-key manifest signature are deferred; the hash manifest + optional HMAC seal are the
integrity baseline.)

The seal key is resolved from `--sign-key-file <path>` (preferred), then `--sign-key <key>`
(inline; avoid — visible in shell history and the process list), then the `$IGA_SIGN_KEY`
environment variable. Use the same source for `export` and `verify-bundle`.

## Classificator Bridge (eai-classification/v1)

> v0.20.0 — producer-agnostic interchange layer between the Enterprise AI
> Classification Framework and the IKI-Gov assessment engine.

The bridge accepts documents from **any producer** that conforms to the
`eai-classification/v1` schema — the research eai-classificator tool, partner
survey tooling, or hand-crafted JSON. The schema is keyed to the
*model* (6×6 matrix: types T1–T6 × autonomy levels L1–L6), not to any one
tool's output format.

### Example classification document

```json
{
  "schema": "eai-classification/v1",
  "producer": {"tool": "eai-classificator", "version": "1.0.0"},
  "use_cases": [
    {
      "id": "fraud-scoring",
      "type": "T1",
      "level": "L4",
      "name": {"de": "Betrugserkennung", "en": "Fraud Scoring"},
      "confidence": 0.92,
      "tags": ["finance", "high-risk"]
    },
    {
      "id": "customer-chat",
      "type": "T4",
      "level": "L3",
      "ecosystem": true
    }
  ]
}
```

**L6 / ecosystem regime:** level L6 is the non-ordinal ecosystem/multi-system
coordination overlay. Set `"ecosystem": true` on any L1–L5 use case to indicate
it participates in a multi-system coordination regime — the parser normalises the
effective cell level to L6 and retains `base_level` for the record.
`level=L6` combined with `ecosystem=false` is a contradiction and is rejected.

### Ingest a classification document

```bash
# Human table: use case, cell, risk presumption, strict, obligations, note
iga classify ingest --file classification.json --lang de

# Machine JSON: includes pack content_hash and producer echo
iga classify ingest --file classification.json --quiet
```

### Run a profiled assessment from a classification document

```bash
# Resolve the selected use case's profile, then run the full assess pipeline
iga classify assess \
    --file classification.json \
    --select fraud-scoring \
    --affirm S1,S2,D1,D2,T1 \
    --lang de \
    --quiet \
    --save

# The profile's risk_class and strict flag are pre-set from the classification
# pack. --strict may further tighten; profile strict=true cannot be loosened.
```

The `classify assess` command reuses the full existing pipeline
(`compute_scores`, `evaluate_all_gates`, `render_json`, `store.save_assessment`,
`log_security_event`) and logs a `iga-classify-assess` security event including
the cell id and the profile pack `content_hash`.

### Classification-profile pack override

The built-in pack (`eai-classification-default`, **DRAFT semantics**) is
automatically loaded. To override it, drop a JSON file with
`"pack_kind": "classification-profile"` into `IGA_CONTENT_PATH`
(default `~/.iga/content/`). The file must cover all 36 cells; a pack with the
same `framework_id` overrides the built-in.

```json
{
  "pack_kind": "classification-profile",
  "framework_id": "eai-classification-default",
  "version": "my-org-1.0",
  "profiles": {
    "T1.L1": {"risk_presumption": "low", "strict": false,
               "obligations": ["iso42001", "euaiact"],
               "notes": {"en": "Minimal oversight required."}},
    "T1.L2": { "..." : "..." }
  }
}
```

ContentPacks (regulatory framework gap mappings) and ProfilePacks coexist in the
same directory; the loader discriminates by `pack_kind`.

### JSON Schema for external producers

`schemas/eai-classification.v1.schema.json` (repo root) provides a JSON Schema
draft/2020-12 definition that partner producers can use for
pre-publication validation. The Python parser in `classification.py` is the
authoritative source; `jsonschema` is not a declared project dependency.

---

## Workshop Mode (T-B3)

`iga workshop run` is the live **customer-workshop tool**: run it on a laptop
connected to a projector, point it at a classification document, and it renders
each use case in large-format, high-contrast rich output while simultaneously
writing a signed leave-behind artifact (the "Übergabeunterlage") per use case to
disk.  The whole cycle (projector rendering plus artifact generation) targets
**under 2 minutes per use case**.

### Offline-capable

Workshop mode is designed for **air-gapped customer sites**.  It explicitly
bypasses the startup CVE / dependency check (`pip-audit` requires network access;
on an air-gapped site it would hang, time out, and emit a noisy "inconclusive"
warning). The dep-check bypass is automatic when the `workshop` subcommand is
detected; no `--no-dep-check` flag required.  Security posture is maintained by
running `pip-audit` on the founder's machine before the session.

### Example

```bash
# Generate signed leave-behind artifacts for all use cases in a classification
# document, in German (default), writing to ./workshop-out/<date>/.
iga workshop run \
    --file classification.json \
    --sign-key ~/.iga/workshop.key \
    --signer "Presidio Group" \
    --lang de

# Generate for selected use cases only.
iga workshop run \
    --file medical.json \
    --select infusion-pump-dosing \
    --select surgical-robotics \
    --sign-key ~/.iga/workshop.key \
    --out /tmp/workshop-2026/

# Pre-populate answers (assessor filled a form earlier).
iga workshop run \
    --file classification.json \
    --answers answers.json \
    --sign-key ~/.iga/workshop.key

# Quiet: write artifacts only, no projector output.
iga workshop run --file classification.json --quiet
```

The `answers.json` format is:

```json
{
  "fraud-scoring": {
    "affirm": ["S1", "S2", "S3", "D1", "D2"],
    "skip":   ["I4", "I5"]
  }
}
```

### Artifact layout per use case

```
workshop-out/<date>/<use_case_id>/
  report.de.md       Markdown leave-behind (localised)
  report.json        Full assessment JSON + classification provenance block
  manifest.json      Content-hashed manifest (presidio-hardened/workshop-leavebehind@1)
  manifest.sig       Ed25519 detached signature (UNSIGNED marker if no key provided)
```

`manifest.json` records: tool version, cell id, risk class, language, profile-pack
content hash, SHA-256 of every artifact, and whether the artifact is signed.

### Key generation (founder setup)

Generate a **dedicated** Ed25519 keypair for workshop use.  Keep the private key
at mode `0600`; distribute only the public key to customers for verification:

```bash
# Python one-liner — generates a 32-byte private key and the matching public key
python3 - <<'EOF'
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
sk = Ed25519PrivateKey.generate()
priv = sk.private_bytes_raw().hex()
pub  = sk.public_key().public_bytes_raw().hex()
print("private (keep secret, chmod 600):", priv)
print("public  (share with customers):  ", pub)
EOF

# Write the private key to a file and lock it.
echo "<private-hex>" > ~/.iga/workshop.key
chmod 600 ~/.iga/workshop.key
```

Key can also be provided via `$IGA_WORKSHOP_SIGN_KEY` to keep it out of the
process list entirely:

```bash
export IGA_WORKSHOP_SIGN_KEY="<private-hex>"
iga workshop run --file classification.json
```

### Verify a leave-behind (customer side)

The customer can verify the artifact using the public key the founder provided:

```bash
# Verify the artifact in the infusion-pump-dosing/ directory.
iga workshop verify \
    --dir workshop-out/2026-06-11/infusion-pump-dosing/ \
    --pubkey <64-hex-char-public-key>

# Machine-readable JSON result.
iga workshop verify \
    --dir workshop-out/2026-06-11/infusion-pump-dosing/ \
    --pubkey <public-key> \
    --quiet
```

Exit 0 if all artifact hashes and the signature verify; exit 1 otherwise
(fail-closed).

---

## Security

See [SECURITY.md](SECURITY.md) for the full security policy.

Security controls built into the tool:
- Input validation for all CLI parameters (type, bounds, allow-list)
- HTML-escaping of all user-supplied strings in report output
- Structured security event log at `~/.iga/security.log` (no content logged, structural metadata only)
- On-startup CVE check via `pip-audit` (suppress with `--no-dep-check`)
- Session rate limiting (default: 100 assessments; override via `IGA_MAX_ASSESSMENTS`)

---

## Roadmap

| Version | Theme | Status |
|---------|-------|--------|
| v0.1.0 | MVP — interactive + parameter-driven assessment, M1–M6 scoring, bilingual | Released |
| v0.2.0 | MCP server — agent-accessible assessment engine (`iga-mcp`) | Released |
| v0.3.0 | Gate readiness refinement, CI exit codes 0/2/3, `--strict` flag | Released |
| v0.4.0 | Report export to file (`--output`) with per-item answers | Released |
| v0.5.0 | ISO/IEC 42001 clause-level gap mapping (`iga iso-gap`) | Released |
| v0.6.0 | Portfolio mode: persistence, `list`, `portfolio`, `delete` | Released |
| v0.7.0 | Maturity trending: delta between saved runs (`iga trend`) | Released |
| v0.8.0 | EU AI Act gate→article mapping for high-risk systems (`iga euaiact-gap`) | Released |
| v0.13.0 | External evidence-backed affirmation: `iga assess --evidence` / `verify-evidence` + `iga_assess_with_evidence` (first producer: `presidio-hardened-ai`) | Released |
| v0.14.0 | Public-key (Ed25519) evidence verification: trust-store `{alg, public_key}` entries + `verify_ref` dispatch (`[crypto]` extra) | Released |
| v0.20.0 | Classificator bridge (eai-classification/v1), 36-cell profile pack, `iga classify` | Released |
| v0.21.0 T-B3 | `iga workshop` — offline customer-workshop tool, Ed25519 signed leave-behind artifacts, `workshop verify` | Released |
| v0.21.0 T1.4 | Full German localisation sweep: all runtime output through `t()`, no English-only sentinels under `--lang de` | Released |

Full version deliberation log: [PRESIDIO-REQ.md](PRESIDIO-REQ.md)

---

## Development

```bash
# Install in editable mode with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Lint and format
ruff format .
ruff check . --fix
```

---

## License

MIT. See [LICENSE](LICENSE).

---

## SDLC

This repository is developed under the Presidio hardened-family SDLC:
<https://github.com/presidio-v/presidio-hardened-docs/blob/main/sdlc/sdlc-report.md>.
