Skip to content

Approvals and Evidence Design

Ed Mozley edited this page Oct 15, 2026 · 1 revision

Approvals and evidence - design (#180)

Status: proposal, not built. This page and its three parts set out what I plan to change, why, and how, so the logic can be checked before any code is written. Nothing described here exists yet unless it says today. Comments are welcome on issue #180.

The request, from issue #180 (raised by Dr4inder after evaluating 3.7.0 for a small IT team):

"Three functional gaps currently prevent us from using FreeITSM as the sole record of these decisions and their supporting evidence."

  1. A configured change approval should be enforceable. Today an analyst can set a change straight to Approved without the approval having happened.
  2. The long text on a change should keep its history. Today a test plan or rollback plan can be overwritten, and the previous text is gone.
  3. Approving, reviewing and configuring should be separate permissions. Today a Forms approver can also redesign the form, and the only way to let somebody read change records is to let them edit them too. The issue puts this in terms of roles: it was not possible to configure "an approval-only role" or "a useful read-only reviewer role".

The three parts:

Part Page In one line
1 Enforceable change approvals Approval becomes a recorded event tied to the exact content that was reviewed, and, when switched on, a rule the status cannot get past
2 Change text history Every saved version of the eight long-text fields is kept in full, with who and when, in the same transaction as the save
3 Approver and reviewer access Roles gain everyday-work permissions (design forms, choose approvers), module access gains a Read only level, and an approver can approve without being given the module

Related pages: Change Management Β· REST API: Changes Β· Catalogue Request Approvals Β· Roles & Permissions Β· Module Access Control Β· Service Layer


1. The principle: nothing changes until you choose it

FreeITSM has real installs, and plenty of teams use Change Management happily as a lightweight record. Some of what #180 asks for would be disruptive if it were simply switched on: a team of two cannot have "nobody may approve their own change", and a team that edits the test plan after approval would suddenly find its changes sent back for re-approval.

So every rule that takes something away from somebody is a setting, and the default is today's behaviour. Upgrading changes nothing anybody can see, apart from the bug fixes in Β§3 and some new history that starts being kept.

What does happen on upgrade, quietly: records start being kept. Approval rounds and text revisions are recorded from the first day, whichever settings are chosen. A team that switches enforcement on six months later then has six months of evidence already, rather than none.


2. Every new setting, in one table

Where Setting Choices Default (= today) Part
Change Management β†’ Settings β†’ Approvals (new tab) Approval rules Record approvals / Enforce approvals Record 1
↳ same tab Approving your own change Not allowed / Allowed Not allowed - in Record mode this only flags the approval as not independent; it refuses nothing 1
↳ same tab Who counts as the change's own people ticks: Requester, Assigned to, Created by all three ticked 1
↳ same tab Administrator override Off / On, with a written reason Off 1
↳ same tab Edits that need a fresh approval ticks, one per field description, reason, risk evaluation, risk likelihood, risk impact, test plan, rollback plan, type, impact 1
↳ same tab When a required CAB member rejects a status (Draft-stage or Stopped-stage only) Draft 1
↳ same tab Who can choose a change's approvers Anyone with Change Management / Only people with "Choose approvers" Anyone 1
Change Management β†’ Settings β†’ Statuses Stage of each status Draft Β· Awaiting approval Β· Approved Β· Implementing Β· Done Β· Stopped filled in from today's names on upgrade 1
Change Management β†’ Settings β†’ Types How it is approved Needs review / Pre-authorised / Emergency - approve afterwards Needs review, for every existing type 1
Forms β†’ Settings β†’ Access (new tab) Who can design forms Everyone with Forms / Only people with "Design forms" Everyone 3
System β†’ Modules Access level of each module grant Full / Read only (only on modules that support it - Changes and Forms first) Full 3

All of them are dropdowns and tick boxes. None of them is typed.

The new tab is guarded by a new capability, changes.approvals, marked sensitive, because it governs the audit trail. Two new everyday-work permissions appear in System β†’ Roles: Choose approvers (Change Management) and Design forms (Forms). How Roles learns to hold permissions that are not settings tabs is in Part 3 Β§2.


3. What I found while mapping it

Reading the code for this turned up faults that are worth fixing whatever is decided about the settings. Some are bugs that would bite anybody, today.

# Found Effect today Fixed by
F1 A manual move to Approved does not stamp changes.approval_datetime; only a CAB vote does Watchtower counts a hand-approved change as awaiting approval for ever, and a Projects gate item "Change approved" never ticks for it Part 1 - every approval stamps it
F2 CAB votes are kept on the member row across resubmissions After a required member rejects and the change is resubmitted, that old Reject is still counted, so the next vote by anybody sends it straight back to Draft. The only way out is to remove and re-add the member Part 1 - votes belong to a round; a new round starts clean
F3 The code finds Approved, Pending Approval and Draft by name (ChangesService, api/change-management/get_approvals.php, assets/js/change-management.js), but names are editable in Settings Rename Approved to Authorised and the CAB's deciding vote sets the change's status to nothing (status_id = NULL - the name lookup finds no row); rename Pending Approval and votes never transition at all, and the Approvals page goes empty Part 1 - a stage column
F4 Anybody with Change Management can edit a CAB roster at any time, including after votes, including on their own change Somebody can add themselves as the only required member and approve their own change by vote, without touching the status Part 1 - roster locked outside Draft; independence
F5 No beginTransaction anywhere in includes/services/changes.php A vote, its audit row and the resulting status change are three separate writes; two last votes landing together can both tip the threshold and fire change.approved twice Part 1 / 2 - one transaction, row lock
F6 Two security issues in code this work touches Details withheld until they are fixed Separately, as a patch - see Β§5
F7 api/v1 never consults the acting analyst's module access A key keeps working for a module its analyst has since lost. Only administrators create keys, so this is a decision rather than a hole - but it matters for read-only access Part 3 - service-level backstop
F8 Nothing is dispatched when a change goes to Pending Approval The help page says "reviewers are notified to vote"; nothing notifies them, and no workflow could, because there is no event to hang it on Part 1 - new events
F9 Attachment upload/delete and comment delete write nothing to change_audit The help page tells people to attach "approval emails" as evidence; deleting one leaves no trace Part 2

Documentation that is wrong today

Where Says Reality
In-app help, Quick tips "Every field change is automatically tracked" The eight long-text fields are deliberately not audited (ChangesService::updateChange, the comment "Longtext bodies - updated but NOT audited")
In-app help, Lifecycle "If CAB is enabled, reviewers are notified to vote" No notification exists (F8)
In-app help, Lifecycle "Approver or CAB signs off" The named Approver has no action; only the CAB can approve
In-app help, Change types Standard = "Pre-approved… No CAB review needed"; Emergency = "approved after the fact" A type has no behaviour at all; nothing in the code branches on it
Change Management wiki, Post-Implementation Review "These are mandatory before a change can move to a fully-closed state" Nothing enforces it
Module Access Control, Enforcement "read-only endpoints are not yet individually gated" Out of date since 2.10.2, when reads were gated (Module-Access-Reads-Were-Open)

Each of these gets corrected in the same commit as the code that makes it true, or now if nothing is going to change.


4. The order to build it in

Each slice ships on its own and leaves the product working.

Slice What Setting needed? Release
0 F6 (the two security fixes); F1 (stamp approval on a manual move); F2 (clear votes when a change is resubmitted); the documentation fixes in Β§3 No - bug fixes 3.7.1 patch, now (F6 is security)
A Status stages - replaces every name literal (F3) No - filled in on upgrade 3.8.0
B Part 2: text revisions, transactions (F5), attachment and comment audit (F9) No - records only 3.8.0
C Part 1 in Record mode: approval rounds, snapshots, the approver's own Approve/Reject, new events (F8), the Approvals tab No - Record is the default 3.8.0
D Part 1 Enforce mode, independence, routes per type, override Yes - off by default 3.8.0
E Part 3: Roles everyday-work permissions, Design forms, the approver's own way into Forms Yes - off by default 3.9.0
F Part 3: Read only module level for Changes and Forms Yes - nobody has it until given it 3.9.0

Slice B comes before C on purpose: an approval has to be able to point at the exact revision it approved, so the revisions have to exist first.


5. Open decisions, before anything is built

  1. Split #180 into three issues, as the requester offered? I'd say yes. The parts are independent and each needs its own changelog trail and reply.
  2. F6 now? Security fixes, so under the release rule they are a same-day patch, separate from all of this.
  3. "Own change" - requester, assigned-to and created-by all ticked by default. Fewer?
  4. Administrator override - off by default. On a two-person team the administrator may be the only independent person; the setting exists for them.
  5. Record mode and edits after approval - I propose the approval is kept but shown as "approved against an earlier version", so Record mode really changes nothing. The alternative is to clear it, which would put the change back on Watchtower as awaiting approval. See Part 1 Β§6.
  6. Standard changes - pre-authorised by type now. The schema already has an unused change_templates table; a proper catalogue of pre-approved templates is the better long-term shape, as a later step. See Part 1 Β§8.
  7. Emergency changes - may they reach Done while the retrospective approval is still open? I propose yes, with the change flagged on Watchtower until it is decided.
  8. Deleting a change wipes its audit trail today. With approval records in play, should Enforce mode refuse to delete a change that has ever been approved? Not asked for in #180; it is the obvious next gap.
  9. Read only - Changes and Forms first, because they are what #180 evaluated. Which modules next?

6. What is deliberately out of scope

  • Report Pack blocks for changes or forms. The issue asks that a reviewer can read "corresponding reports/exports". Report Packs have no Change or Forms blocks today, so the reviewer's reports are the Changes table view with its CSV export, the new evidence export (Part 2 Β§6) and the Forms submissions export. New blocks are a separate piece of work.
  • Reconstructing history that was never recorded. Text edited before the upgrade cannot be recovered. The first revision of each field is marked as "as found when history began", and is never presented as the original (Part 2 Β§4).
  • Multi-stage approval chains (manager, then CAB, then change manager). One round, decided by a CAB or by one named approver, is what exists today and what #180 asks to enforce.
  • Approval by people who are not analysts. Approvers are analysts, as today.

Related pages

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Blue sky thinking

Bugs resolved

Links

Clone this wiki locally