Repository navigation
[Wave 4] Low/info — Docs: docs/design/gdpr_erasure.md #719
Description
Wave 4 · 10 finding(s) in 10 fix package(s). One pass over this document; keep the Turkish mirror in sync.
Findings
-
DOC-D2B02-041 (docs, Low) — docs/design/gdpr_erasure.md: wrong detail — 'ForgeLM only needs to act on three' Art. 17(1) triggers.
severity Low
Where.docs/design/gdpr_erasure.md:35· type: wrong detail
The document says. 'ForgeLM only needs to act on three' Art. 17(1) triggers.
What the code does. The table marks four triggers (a-d) as in scope. This is an internal count inconsistency, not a legal judgement.
Code references.docs/design/gdpr_erasure.md:37-44
Proposed correction. "…act on four…" (or adjust the table). -
DOC-D2B02-042 (docs, Low) — docs/design/gdpr_erasure.md: false claim — data_audit_report.json has a
lang_samplefield carrying snippets of up to 512 characters.
severity Low
Where.docs/design/gdpr_erasure.md:63· type: false claim
The document says. data_audit_report.json has alang_samplefield carrying snippets of up to 512 characters.
What the code does. lang_sample is internal aggregator state used only to compute the top-3 languages. It is not written to the report.
Code references.forgelm/data_audit/_aggregator.py:78,forgelm/data_audit/_aggregator.py:128-135,forgelm/data_audit/_aggregator.py:287
Proposed correction. Remove the lang_sample claim, or name the report fields that can actually carry text. -
DOC-D2B02-043 (docs, Low) — docs/design/gdpr_erasure.md: wrong detail — The retention check uses filesystem mtime as its primary age signal (also L165), and logs a
data.retention_age_source=mtimenote for stand-alone JSONL co…
severity Low
Where.docs/design/gdpr_erasure.md:147-150· type: wrong detail
The document says. The retention check uses filesystem mtime as its primary age signal (also L165), and logs adata.retention_age_source=mtimenote for stand-alone JSONL corpora.
What the code does. Age comes from the audit log first (the per-run first event, else global genesis) and falls back to mtime. The fallback is a per-violationage_sourcefield. No audit note/event is emitted, and corpora are not scanned at all.
Code references.forgelm/cli/subcommands/_purge.py:1171-1237,forgelm/cli/subcommands/_purge.py:1372-1400
Proposed correction. Describe audit-first age resolution with theage_sourcefield, and note that corpora are not scanned. -
DOC-D2B02-044 (docs, Low) — docs/design/gdpr_erasure.md: wrong detail — --run-id matches the top-level run_id in <output_dir>/audit_log.jsonl. §5.3/§5.4 list target_kind
policy_check.
severity Low
Where.docs/design/gdpr_erasure.md:192· type: wrong detail
The document says. --run-id matches the top-level run_id in <output_dir>/audit_log.jsonl. §5.3/§5.4 list target_kindpolicy_check.
What the code does. Run mode never consults the audit log for the run_id; it only resolves paths. --check-policy emits no events, so target_kind 'policy_check' never occurs.
Code references.forgelm/cli/subcommands/_purge.py:821-866,forgelm/cli/subcommands/_purge.py:1108-1168
Proposed correction. Drop the audit-log match claim and thepolicy_checkvalue. -
DOC-D2B02-045 (docs, Low) — docs/design/gdpr_erasure.md: wrong detail — --dry-run is mutually exclusive with --check-policy, and combining them is a ConfigError. L183: 'Combining flags is a ConfigError'.
severity Low
Where.docs/design/gdpr_erasure.md:198· type: wrong detail
The document says. --dry-run is mutually exclusive with --check-policy, and combining them is a ConfigError. L183: 'Combining flags is a ConfigError'.
What the code does. --dry-run is outside the mutually-exclusive group.--check-policy --dry-runruns the report and exits 0 (reproduced). Mode-flag combinations are rejected by argparse with exit 2, not ConfigError (1).
Code references.forgelm/cli/_parser.py:1096-1115,forgelm/cli/_parser.py:1158-1162
Proposed correction. "--dry-runis ignored by--check-policy; mode flags are argparse-exclusive (exit 2)." -
DOC-D2B02-046 (docs, Low) — docs/design/gdpr_erasure.md: stale — 'Standard ForgeLM 0/1/2/3/4 contract' plus code 5 (L204, L214), and '--check-policy always exits 0' (L214).
severity Low · already tracked: KNOWN-OPEN C31-EXIT-CODE-PROSE — docs/roadmap/phase-16-trust-surface-hardening.md:782-785
Where.docs/design/gdpr_erasure.md:204· type: stale
The document says. 'Standard ForgeLM 0/1/2/3/4 contract' plus code 5 (L204, L214), and '--check-policy always exits 0' (L214).
What the code does. The contract is 0-6. --check-policy exits 1 when an explicit --config fails to load.
Code references.forgelm/cli/_exit_codes.py:42-52,forgelm/cli/subcommands/_purge.py:1126-1140
Proposed correction. Cite the 0–6 contract; "--check-policy exits 0 on a successful report and 1 when--configcannot be loaded". -
DOC-D2B02-047 (docs, Low) — docs/design/gdpr_erasure.md: wrong detail — Exit 1 covers '--row-id directory mode without --row-matches=all', and the consent model is described in '§3.5'.
severity Low
Where.docs/design/gdpr_erasure.md:209· type: wrong detail
The document says. Exit 1 covers '--row-id directory mode without --row-matches=all', and the consent model is described in '§3.5'.
What the code does. Directory corpora are always rejected (isfile check), whatever --row-matches says. The consent model is in §10 Q4, not §3.5.
Code references.forgelm/cli/subcommands/_purge.py:262-269,docs/design/gdpr_erasure.md:441-443
Proposed correction. "directory--corpus(always rejected)"; change the xref to §10 Q4. -
DOC-D2B02-048 (docs, Low) — docs/design/gdpr_erasure.md: false claim — On a step-5 rename failure the temp file is left on disk for forensic inspection.
severity Low
Where.docs/design/gdpr_erasure.md:227· type: false claim
The document says. On a step-5 rename failure the temp file is left on disk for forensic inspection.
What the code does. On OSError or UnicodeDecodeError the temp file is unlinked before re-raising.
Code references.forgelm/cli/subcommands/_purge.py:354-366
Proposed correction. "…the temp file is removed and adata.erasure_failedevent is appended; the original corpus is unchanged." -
DOC-D2B02-049 (docs, Low) — docs/design/gdpr_erasure.md: stale — §7 lists the named tests that ship. #10 asserts dry-run leaves the corpus AND the audit log byte-identical; #11 says a second concurrent purge 'sees a row already…
severity Low
Where.docs/design/gdpr_erasure.md:375-386· type: stale
The document says. §7 lists the named tests that ship. #10 asserts dry-run leaves the corpus AND the audit log byte-identical; #11 says a second concurrent purge 'sees a row already erased notice and exits 0'. Also L88, L229 and L302 name specific tests.
What the code does. None of the named tests exist under those names (the actual suite uses class-based names, e.g. test_row_erasure_target_id_is_hashed_not_cleartext). Dry-run appends audit events by design (test_dry_run_creates_salt_and_audit_intent_by_design). A second purge of an erased row finds no match, emits data.erasure_failed (NoMatchingRow) and exits 1.
Code references.tests/test_gdpr_erasure.py:87-1430,forgelm/cli/subcommands/_purge.py:556-567,forgelm/cli/subcommands/_purge.py:702-713
Proposed correction. Replace the §7 table with the shipped test classes, and correct #10 and #11 to the implemented behaviour. -
DOC-D2B02-050 (docs, Low) — docs/design/gdpr_erasure.md: stale — The file map lists compliance.py record_erasure_event(...), trainer.py pre-flight retention check, a sop_data_management.md 'Retention + erasure procedure' subsec…
severity Low
Where.docs/design/gdpr_erasure.md:400-407· type: stale
The document says. The file map lists compliance.py record_erasure_event(...), trainer.py pre-flight retention check, a sop_data_management.md 'Retention + erasure procedure' subsection, and (L405/L310) a new GDPR section in safety_compliance.md.
What the code does. None of these exist: no record_erasure_event, no trainer retention code, no erasure subsection in the SOP, no GDPR section in safety_compliance.md (only the example prompt at L227).
Code references.forgelm/compliance.py,forgelm/trainer.py,docs/qms/sop_data_management.md:110-115,docs/guides/safety_compliance.md:227
Proposed correction. Mark these rows "not implemented" or remove them.
Done when
- Every finding above is fixed or closed with a reason (tick it here).
- Code fixes carry a test; doc fixes update the Turkish mirror in the same PR.
Found by the October 2026 ForgeLM code and documentation review against commit cab2947. Code links point at that commit; line numbers may have moved since. Finding IDs (CR-…, DOC-…, TECH-…) are stable references for this backlog.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTodo
Activity