›
byrcsc/laravel-checklist · 1.x
Every checklist action joins an append-only SHA-256 chain that exposes later edits or deletions.
Every checklist change leaves an action behind. Read the action history when you need to show what changed, who acted, or whether someone altered the stored record later.
Checklist-level actions record creation, schedule generation, assignment, submission, review, and reopening.
Item-level actions record the first answer, corrections, notes, evidence addition and removal, and visibility changes. Item actions point at the item and, where available, its response.
foreach ($checklist->actions as $action) {
$action->action; // ActionType
$action->actor_label; // frozen display label
$action->payload; // action-specific before and after data
$action->hash;
$action->previous_hash;
}The relation returns actions oldest first.
An action stores an optional polymorphic actor and a required actor_label
snapshot. Display the label when rendering history. The relation is useful for
linking to an actor that still exists, but a renamed or deleted model must not
rewrite the historical name.
Engine actions use the label System.
The recorder calculates a canonical SHA-256 hash from the row's contents and the previous row's hash. It then stores the new head hash on the checklist.
Editing, inserting, deleting, or reordering a row breaks either its content hash, the next row's predecessor, or the checklist head. The chain is tamper-evident: it detects a change, but it does not prevent direct database access from making one.
The recorder locks the checklist row while reading and replacing its head. Concurrent answers therefore append one after another instead of creating two rows with the same predecessor.
Action model events reject updates and deletes through Eloquent. Application
code should not write actions directly. Audit\RecordAction is the package's
single write path.
use ByRcsc\LaravelChecklist\Audit\ChainVerifier;
$result = ChainVerifier::verify($checklist);
$result->intact;
$result->rows;
$result->brokenAt;
$result->reason;
$result->describe();The verifier streams actions in order and compares the final hash with
action_head_hash. Exports run this verification when they are built.
The chain shows whether rows and their recorded head still agree. It does not prove that the original actor was authorized, that an uploaded file still matches its recorded evidence hash, or that an external database administrator could not rewrite the entire chain and head together.