Repository navigation
Code does not match site/compliance.html: forgelm approve / reject + forgelm approvals drive the dual-controlled sign-off ... every model promotion is dual-controlled and forensic… (CR-A01-009) #94
Description
Wave 0 · theme D0-5: Documented controls that are not implemented · highest severity Critical · 6 finding(s) · effort small
Summary
The document states: forgelm approve / reject + forgelm approvals drive the dual-controlled sign-off ... every model promotion is dual-controlled and forensically attributed.. Observed in the code: The approval gate is opt-in (evaluation.require_human_approval defaults to False, forgelm/config.py:1220-1223), so by default no promotion is gated at all. When the gate is on, the approver identity is just the unauthenticated FORGELM_OPERATOR value or the getpass username (forgelm/cli/subcommands/_approve.py:121-170, 603). No check makes the approver differ from the trainer, so one person can train and approve.
Primary finding
CR-A01-009 — Code does not match site/compliance.html: forgelm approve / reject + forgelm approvals drive the dual-controlled sign-off ... every model promotion is dual-controlled and forensicall
severity High · reachability default · intent contract-violation · confidence confirmed · independently confirmed
What happens. This is a C1 promise (F-114) that the code does not deliver. The approved threat model (TM-v1) puts approver authentication and approver-differs-from-trainer checks out of scope, so the realistic fix is probably the document. The project owner should decide whether to implement separation of duties or withdraw the claim.
Where.
forgelm/config.py:1220-1223forgelm/cli/subcommands/_approve.py:121-170forgelm/cli/subcommands/_approve.py:603-610forgelm/trainer.py:1537-1539site/compliance.html:177site/compliance.html:239site/js/translations.js:3880site/js/translations.js:3939site/js/translations.js:3981site/js/translations.js:4024
Evidence.
- forgelm/config.py:1220-1223; forgelm/cli/subcommands/_approve.py:121-170; forgelm/cli/subcommands/_approve.py:587-620
Recommended fix. Reword: 'Optional (opt-in) staging gate: when evaluation.require_human_approval: true, promotion requires an explicit forgelm approve, recorded with the approver identity (FORGELM_OPERATOR / OS user; not authenticated). Enforcing that approver and trainer differ is the deployer's responsibility.' Remove 'every model promotion is dual-controlled'.
Other findings with the same root cause
These close with the same fix; update them in the same pull request.
-
CR-A10-005 (code, High) — Docs claim the approval gate is 'dual-controlled' and 'enforces trainer != approver', but approver identity is a self-asserted string and nothing compares it
severity High · reachabilitydocumented-opt-in· intentcontract-violation· confidence confirmed · independently confirmed · not reproduced (code trace)
Failure scenario. An auditor relies on 'dual-controlled' and finds a single operator can train, then approve with the same FORGELM_OPERATOR.
Where.forgelm/cli/subcommands/_approve.py:603and 613-620 (approve: approver resolved and logged, no comparison),tests/test_human_approval_gate.py:1112-1180(TestGrantedOperatorApproverFields; it asserts collapse, not a test-gap against the honest docs),site/compliance.html:239,docs/guides/iso_soc2_deployer_guide.md:29and docs/qms/sop_change_management.md:108 ("dual-controlled")
Recommended fix. Reword to 'human-approval gate with attributed (self-asserted) approver', or add an optional approver != operator check with tests. -
DOC-D2B03-001 (docs, Critical) — docs/design/iso27001_soc2_alignment.md: false claim — A.5.3: '
forgelm approverequires ≠ trainer operator-id'; A.8.2: 'approval gate requires explicit non-trainer operator'; CC1.2: 'Approval gate o…
severity Critical
Where.docs/design/iso27001_soc2_alignment.md:155,233,293,545-546 · type: false claim
The document says. A.5.3: 'forgelm approverequires ≠ trainer operator-id'; A.8.2: 'approval gate requires explicit non-trainer operator'; CC1.2: 'Approval gate operator ≠ trainer'; §8.2: 'trainer ≠ approver enforced byforgelm approve'.
What the code does.forgelm approvenever compares the approver or operator with the trainer's identity. docs/qms/access_control.md §6 states 'ForgeLM does not enforce that the two identities differ'. The A.5.3 row's own note column ('doesn't enforce IdP-level separation') contradicts its evidence column.
Code references.forgelm/cli/subcommands/_approve.py:512-629,forgelm/cli/subcommands/_approve.py:121-182,docs/qms/access_control.md:177-200
Proposed correction. Preferred: implement the check inforgelm approve(refuse, or require an audited override, when the approver identity equals the operator on the run'straining.started/human_approval.requiredevent). Otherwise rewrite each row as: "human_approval.*events record trainer and approver identities; ForgeLM does not enforce that they differ (… -
DOC-D2B03-002 (docs, Critical) — docs/guides/iso_soc2_deployer_guide.md: false claim — 'Every model promotion is dual-controlled and forensically attributed.'
severity Critical
Where.docs/guides/iso_soc2_deployer_guide.md:28-29(Turkish mirror:docs/guides/iso_soc2_deployer_guide-tr.md:29-30) · type: false claim
The document says. 'Every model promotion is dual-controlled and forensically attributed.'
What the code does.forgelm approvechecks the staging path and the required event, then promotes. It never compares the approver/operator identity with the identity that trained the run, so the same identity can train and approve. The project's own QMS doc says 'ForgeLM does not enforce that the two identities differ'. Promotions are attributed (operator plus approver fields), not dual-controlled.
Code references.forgelm/cli/subcommands/_approve.py:512-629,forgelm/cli/subcommands/_approve.py:151-182,docs/qms/access_control.md:177-200
Proposed correction. Preferred: fix the code so thatforgelm approvecompares the resolved approver/operator with the operator on the run'straining.started/human_approval.requiredevent and refuses (or requires an audited override) when they match. Interim doc text: "Every model promotion is recorded with the approving identity (operator,approver). Forge…
Turkish mirror. the Turkish page has the same error; fix both in the same PR -
DOC-D4B08-001 (docs, Critical) — site/compliance.html: false claim — forgelm approve / reject + forgelm approvals drive the dual-controlled sign-off ... every model promotion is dual-controlled and forensically attributed.
severity Critical
Where.site/compliance.html:177, site/compliance.html:239; site/js/translations.js:3863, 3880 · type: false claim
The document says. forgelm approve / reject + forgelm approvals drive the dual-controlled sign-off ... every model promotion is dual-controlled and forensically attributed.
What the code does. The approval gate is opt-in (evaluation.require_human_approval defaults to False, forgelm/config.py:1220-1223), so by default no promotion is gated at all. When the gate is on, the approver identity is just the unauthenticated FORGELM_OPERATOR value or the getpass username (forgelm/cli/subcommands/_approve.py:121-170, 603). No check makes the approver differ from the trainer, so one person can tr…
Code references.forgelm/config.py:1220-1223,forgelm/cli/subcommands/_approve.py:121-170,forgelm/cli/subcommands/_approve.py:587-620
Proposed correction. Reword: 'Optional (opt-in) staging gate: when evaluation.require_human_approval: true, promotion requires an explicit forgelm approve, recorded with the approver identity (FORGELM_OPERATOR / OS user; not authenticated). Enforcing that approver and trainer differ is the deployer's responsibility.' Remove 'every model promotion is dual-controlled'. -
DOC-D4B09-001 (docs, Critical) — site/js/translations.js: false claim — forgelm approve/reject drive a 'dual-controlled sign-off'; 'every model promotion is dual-controlled and forensically attributed'
severity Critical
Where.site/js/translations.js:3863(compliance.art14.body), :3880 (compliance.iso.change.body) · type: false claim
The document says. forgelm approve/reject drive a 'dual-controlled sign-off'; 'every model promotion is dual-controlled and forensically attributed'
What the code does. ForgeLM does not enforce segregation of duties and does not authenticate the approver. The approver is the string in FORGELM_OPERATOR or getpass.getuser() (forgelm/cli/subcommands/_approve.py:121-175). The project's own guide says it neither verifies the reviewer is human nor enforces that trainer and approver differ (docs/guides/human_approval_gate.md:24-25). The same person who trained can run…
Code references.forgelm/cli/subcommands/_approve.py:121-175,docs/guides/human_approval_gate.md:24-25
Proposed correction. Replace with: 'forgelm approve / reject record the approver identity (taken from FORGELM_OPERATOR or the OS user) and an optional comment in the audit log. ForgeLM does not authenticate the approver or enforce that the approver differs from the trainer; enforce that with your IdP and process.' Replace 'dual-controlled and forensically attributed'…
Acceptance criteria
- A regression test reproduces the failure scenario and asserts the corrected behaviour.
- Documentation listed above is corrected in English and in its Turkish mirror in the same PR.
- Every finding in this issue is resolved or explicitly closed with a reason.
- The release note names the contract this fix restores.
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
docs: compliance and privacy wording, SBOM and Article 12/14, and the…