# inciclass — Changelog

## v1.0.0 — 2026-06-22

Initial release. Phase 3a of the cli.johlem.net consulting layer
(jfind → complymap → dossier → **inciclass** → roigen → tiberscope).

### Purpose

Classify an ICT incident against DORA major-incident criteria
(RTS 2024/1772) and run the regulatory notification countdown for
DORA (4h / 72h / 1 month) AND NIS2 (24h / 72h / 1 month). Recurring
IR-retainer functionality.

### Subcommands

```
inciclass assess --input incident.json [-F human|json|jfind] [-o out]
inciclass clock  --detected <RFC3339> --regime dora,nis2 [-F human|json]
inciclass report --input incident.json --stage initial|intermediate|final [-F jfind|json]
```

`assess` accepts stdin if `--input` is omitted, so
`cat incident.json | inciclass assess -F jfind | complymap gap` is
the canonical pipeline.

### DORA classification (RTS 2024/1772)

Seven criteria, each scored Below / Met / Critical:

| ID | Tier      | Criterion                                                              | Materiality bar                     | Critical threshold                    |
|----|-----------|------------------------------------------------------------------------|-------------------------------------|---------------------------------------|
| C1 | primary   | Clients / financial counterparts / transactions affected               | ≥ 10% clients OR ≥ 100k tx          | ≥ 30% OR ≥ 500k tx                    |
| C2 | secondary | Reputational impact                                                    | media / regulator / complaints      | sustained adverse press / outflows    |
| C3 | primary   | Duration and service downtime                                          | ≥ 120 min (2h)                      | ≥ 1440 min (24h)                      |
| C4 | primary   | Geographical spread (Member States)                                    | ≥ 2 MS                              | ≥ 4 MS                                |
| C5 | primary   | Data losses (availability / authenticity / integrity / confidentiality)| any AAIC property impacted          | personal data / client-financial      |
| C6 | secondary | Critical or important functions affected                               | partial impairment                  | unavailable to clients                |
| C7 | primary   | Economic impact (EUR)                                                  | ≥ €100k                             | ≥ €1m                                 |

Verdict logic:

* `critical` — ≥ 2 criteria scored `Critical`, OR materiality count
  ≥ 2 AND at least one criterion scored `Critical`.
* `major` — primary materiality count ≥ 2, OR a secondary criterion
  (C2 / C6) scored `Critical`.
* `minor` — otherwise.

Thresholds are vendored as `data/dora_thresholds.json` (auditable
and bumpable when an updated RTS or CSSF guidance lands).

### Notification clocks

* **DORA** Art. 19 / RTS 2025/301 / ITS 2025/302: initial ≤ 4h,
  intermediate ≤ 72h, final ≤ 1 month.
* **NIS2** Art. 23: early warning ≤ 24h, incident notification ≤ 72h,
  final report ≤ 1 month.

"1 month" deadlines use `chrono::Months::new(1)` so they cross
month-boundaries correctly (e.g. 2026-01-31 + 1 month = 2026-02-28;
2028-01-31 + 1 month = 2028-02-29 in a leap year).

### jfind output

`inciclass assess -F jfind` and `inciclass report -F jfind` emit a
single `jfind/v1` finding with:

* `category = "ict-incident"`
* `severity = Low` (minor) / `High` (major) / `Critical` (critical)
* `confidence = High`
* `controls` pre-filled with DORA Art. 17 (always), plus Art. 18 +
  Art. 19 + NIS2 Art. 23 for major/critical
* `raw` carrying the case_id, criterion scores, rationale, and the
  full deadline list

The pre-filled `controls[]` means `complymap` doesn't have to
keyword-match its way back to the incident-management cluster.

### Suite integration

- Library crate + CLI binary.
- 17 unit tests (data load, criterion scoring per-criterion, verdict
  computation, clock-month-boundary correctness) + 12 integration
  tests (CLI behaviour, acceptance gate, full pipeline). Zero
  compiler warnings.
- Suite-standard exit codes per `SUITE_STANDARDS.md` §1:
  0 ok / minor · 1 major/critical or breached deadline · 2 usage ·
  3 runtime / parse / unknown regime / unknown stage.
- Mandatory tagline footer on every `--help`:
  `[ inciclass ] ─ an independent project by johlem.net`.
- `--full` extended help (suite convention).
- Reads from `--input <PATH>` OR stdin so it composes with
  `cat incident.json | inciclass assess -F jfind | jfind sign --key ...`.

### Acceptance gate (Phase 3a)

> A fixture incident that crosses two thresholds is classified
> "major" with both thresholds cited; clocks compute the 4h/72h/1m
> (DORA) and 24h/72h/1m (NIS2) deadlines correctly across a month
> boundary.

**PASSED.** Pinned by:

* `acceptance_gate_two_thresholds_is_major_with_citations` in
  `tests/integration/cli_tests.rs` — exercises C3 + C4 → major,
  asserts each rationale string mentions the crossed threshold.
* `clock_crosses_month_boundary_correctly` — 2026-01-31 + 1 month =
  2026-02-28 (not 2026-03-03).
* `one_month_crosses_leap_february_correctly` (unit) — 2028-01-31 +
  1 month = 2028-02-29.

### Deferred to v1.1+

- Interactive prompted assess mode (currently `--input PATH` or stdin).
- `inciclass clock --case <ID> --watch` live countdown with colour
  ticker on stderr.
- DORA proportionality lookup (entity-type-driven thresholds —
  same blocker as complymap v1.0).
- Threshold tuning hooks via env-var overrides for forks /
  white-label deployments.
