-
-
Notifications
You must be signed in to change notification settings - Fork 1
feat: v0.6.0 standards alignment + legibility #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
64b180d
0687457
75a16a2
5211933
fdc7b33
dfc0e20
8bfb83f
b0e9545
4c3e3c4
902c5d5
11f0d11
422f4d5
a784831
e4d8d69
b569556
95bb0f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,3 +15,5 @@ venv/ | |
| docs/blog/ | ||
| docs/grant/ | ||
| dist_verify/ | ||
| research/ | ||
| .claude/ | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -4,6 +4,37 @@ All notable changes to this project are documented here. | |||||
| The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) | ||||||
| and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||||||
|
|
||||||
| ## [0.6.0] - 2026-04-27 | ||||||
|
|
||||||
| **Theme: standards alignment + legibility.** v0.5.x was the capability axis (jailbreak coverage closed, classifier rebalanced). v0.6 is the legibility axis: policies become readable, audit records become standards-aligned, adversarial numbers become honest, architecture contribution becomes documented. | ||||||
|
|
||||||
| ### Added | ||||||
| - **`vaara.policy` package — JSON-native policy loader plus optional YAML via `vaara[yaml]` extra.** Frozen dataclasses for action classes, threshold curves, sequence patterns, and escalation routes. Hand-rolled validation with field-path error messages. Reuses existing `vaara.taxonomy.actions` enums verbatim. Threshold partial-overrides supported (set just `deny`, inherit default `escalate`). Implements Sketch A from the v0.6 DSL design exploration; embedded Python DSL (Sketch B) and standalone DSL (Sketch C) stay deferred to v0.7+ pending external pull. | ||||||
| - **`vaara trail purge --db PATH --retention-days N [--dry-run]` CLI subcommand** plus `SQLiteAuditBackend.purge_older_than(seconds, *, dry_run=False)` Python API. Article 12(2) retention enforcement. Tenant-scoped. Hash-chain integrity: surviving records still reference deleted predecessors via `previous_hash`, so `vaara trail verify` reports a chain break at the retention boundary. Intended workflow: export a signed handoff zip BEFORE purging, archive externally, then purge. The signed zip remains self-consistent forever; the live DB chain has a documented seam. | ||||||
| - **prEN ISO/IEC 12792 four-axis transparency taxonomy on `AuditRecord`.** Four optional fields (`system_operation`, `data_usage`, `decision_making`, `limitations`) with default-classification heuristic per `EventType`. Per-record override via construction kwargs. NOT tamper-evident in v0.6 — fields are metadata annotations excluded from `record_hash` so pre-v0.6 chains stay valid. v0.7+ may add a separate signing mechanism if compliance requires. | ||||||
| - **`scripts/eval_distribution_shift.py`** — runs the full Vaara stack against the adversarial corpus with per-source tagging (hand-curated vs LLM-generated). Reports recall and FPR per source/class. | ||||||
| - **`scripts/eval_stack_ablation.py`** — runs three configurations (heuristic-only, classifier-only, full-stack) against the same corpus. Quantifies the independent contribution of each layer. | ||||||
| - **`scripts/eval_pair_attack.py`** — PAIR (Chao et al. 2023) iterative adaptive attacker. Uses an OpenAI-compatible vLLM endpoint for both attacker and judge roles. Zero new runtime deps (uses `urllib.request`). | ||||||
| - **`[yaml]` optional extra in `pyproject.toml`** (`pyyaml>=6.0`). Core `dependencies = []` preserved. | ||||||
| - **`examples/policies/minimal.json` and `full.yaml`** as reference policies. | ||||||
| - **COMPLIANCE.md gains "EU AI Act Annex IV evidence sections"** (maps Vaara contribution per §1–§9; direct fill on §3, §5, §9; contributes on §2, §4, §6, §7; out of scope for §1, §8) **and "CEN-CENELEC harmonised standards alignment"** (per-standard table for ISO/IEC 42001, prEN 18286, prEN 18228, ISO/IEC 42006, prEN ISO/IEC 24970, prEN 18229-1, prEN ISO/IEC 12792). | ||||||
|
|
||||||
| ### Changed | ||||||
| - **Audit DB schema v2 → v3.** Migration `_MIGRATIONS[2]` adds four nullable transparency columns to `audit_records`. Pre-v0.6 records get NULL for the new columns; their stored `record_hash` is preserved (NOT re-hashed on load), so chain verification of historical records continues to work. | ||||||
| - **COMPLIANCE.md "Current limits"** replaced placeholder bullets with v0.6 measurement results: | ||||||
| - **Distribution-shift split.** Hand-curated (held-out, 250): attack recall 97.1% / benign FPR 70.0%. LLM-generated (in-sample, 5,705): attack recall 95.2% / benign FPR 87.5%. The 18pp benign-FPR gap is the dominant distribution-shift signal. | ||||||
| - **Stack composition.** `heuristic_only` recall 35% / 63%. `classifier_only` recall 94% / 86%. `full_stack` recall 97% / 98%. Layers not redundant — heuristic catches a small set of attacks the classifier misses (justifies the ensemble). Most full-stack benign FPR comes from heuristic ESCALATEs, not classifier upgrades. | ||||||
| - **PAIR adaptive-attacker calibration.** Qwen2.5-32B-Instruct as both attacker and judge, 25 hand-curated jailbreak seeds, max 5 iterations: **ASR 0.0% (0/25)**. NOT a claim of impervence to all adaptive attackers — stronger attacker (70B+), longer iteration budgets, or alternate strategies (multi-turn drift, language-switch, obfuscation) might produce non-zero ASR. | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix typo: "impervence" → "imperviousness". Same spelling error as in COMPLIANCE.md. ✏️ Proposed fix- **ASR 0.0% (0/25)**. NOT a claim of impervence to all adaptive attackers — stronger at...
+ **ASR 0.0% (0/25)**. NOT a claim of imperviousness to all adaptive attackers — stronger at...📝 Committable suggestion
Suggested change
🧰 Tools🪛 LanguageTool[grammar] ~27-~27: Ensure spelling is correct (QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1) 🤖 Prompt for AI Agents |
||||||
|
|
||||||
| ### Deferred to v0.7+ | ||||||
| - **prEN ISO/IEC 24970 field-alias layer** — pending public final of the standard. Will land when 24970 publishes. | ||||||
| - **DORA mapping refinement** — pending deployer-side signal. Conservative defaults shipped in v0.5.3 stay until a financial deployer's input refines them. | ||||||
|
|
||||||
| ### Reproducible artifacts | ||||||
| - `tests/adversarial/distribution_shift_v0_5_3.json` | ||||||
| - `tests/adversarial/stack_ablation_v0_5_3.json` | ||||||
| - `tests/adversarial/pair_v0_5_3.json` | ||||||
|
|
||||||
| ## [0.5.3] - 2026-04-26 | ||||||
|
|
||||||
| ### Fixed | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| # Vaara policy — comprehensive example. | ||
| # Loaded via vaara.policy.from_yaml() (requires the [yaml] extra). | ||
| # JSON Schema lives at docs/policy_schema.json. | ||
|
|
||
| version: "0.1" | ||
| domains: [eu_ai_act, dora] | ||
|
|
||
| # Action-class taxonomy. Each tool name classifies into one entry here. | ||
| # Enum values mirror vaara.taxonomy.actions: | ||
| # category: financial | data | communication | infrastructure | identity | governance | physical | unknown | ||
| # reversibility: fully_reversible | partially_reversible | irreversible | ||
| # blast_radius: self | local | shared | global | ||
| # urgency: deferrable | timely | immediate | irrevocable | ||
| action_classes: | ||
| fs.write_file: | ||
| category: data | ||
| reversibility: partially_reversible | ||
| blast_radius: local | ||
| urgency: timely | ||
| regulatory: ["aiact:9", "aiact:12"] | ||
|
|
||
| tx.sign: | ||
| category: financial | ||
| reversibility: irreversible | ||
| blast_radius: shared | ||
| urgency: irrevocable | ||
| regulatory: ["aiact:14", "dora:10"] | ||
|
|
||
| email.send: | ||
| category: communication | ||
| reversibility: irreversible | ||
| blast_radius: global | ||
| urgency: timely | ||
| regulatory: ["aiact:13"] | ||
|
|
||
| # Risk-score thresholds. Below escalate = allow. Above deny = deny. | ||
| # Per-action-class entries override the default. Partial overrides supported: | ||
| # `fs.write_file` below tightens `deny` while inheriting the default `escalate`. | ||
| thresholds: | ||
| default: | ||
| escalate: 0.55 | ||
| deny: 0.85 | ||
| fs.write_file: | ||
| deny: 0.75 | ||
| tx.sign: | ||
| escalate: 0.40 | ||
| deny: 0.65 | ||
|
|
||
| # Sequence patterns. If matched in the sliding window, risk gets boosted. | ||
| sequences: | ||
| data_exfiltration: | ||
| pattern: [read_data, export_data, delete_data] | ||
| risk_boost: 0.4 | ||
| window_seconds: 300 | ||
| regulatory: ["aiact:9(2)(a)"] | ||
|
|
||
| config_then_signal: | ||
| pattern: [config.write, tx.sign] | ||
| risk_boost: 0.3 | ||
| window_seconds: 60 | ||
| regulatory: ["aiact:14"] | ||
|
|
||
| # Escalation routing. First matching route wins. The entry with no `if` | ||
| # is the default fallback. If none defined, "on_call" is the implicit fallback. | ||
| escalation: | ||
| routes: | ||
| - if: ["aiact:14"] | ||
| operator_group: ai_oversight_team | ||
| - if: ["dora:10"] | ||
| operator_group: ict_risk_team | ||
| - default: on_call |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "version": "0.1", | ||
| "domains": ["eu_ai_act"], | ||
| "action_classes": {}, | ||
| "thresholds": { | ||
| "default": {"escalate": 0.55, "deny": 0.85} | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.