Module: Legion::Extensions::Audit::Helpers::VerifiedWrite

Includes:
Helpers::Lex
Defined in:
lib/legion/extensions/audit/helpers/verified_write.rb

Overview

Combines file write/edit operations with post-write SHA-256 verification and optional audit trail recording via AuditRecord.

Include this module in any class or extension that modifies files and needs tamper-evident confirmation that the write succeeded.

Instance Method Summary collapse

Instance Method Details

#verified_edit(path, old_content, new_content, agent_id: nil, chain_id: 'file_edits') ⇒ Hash

Apply a string-replacement edit to path, with a staleness check before writing and SHA-256 verification after writing.

Parameters:

  • path (String)

    absolute or relative filesystem path

  • old_content (String)

    expected current file content (used for staleness check)

  • new_content (String)

    desired file content after edit

  • agent_id (String, nil) (defaults to: nil)

    identity recorded in the audit trail

  • chain_id (String) (defaults to: 'file_edits')

    audit chain identifier

Returns:

  • (Hash)

    { path:, before_hash:, after_hash:, verified: true }

Raises:



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/legion/extensions/audit/helpers/verified_write.rb', line 63

def verified_edit(path, old_content, new_content, agent_id: nil, chain_id: 'file_edits')
  before_hash   = sha256_string(old_content)
  on_disk_hash  = sha256_file(path)

  unless on_disk_hash == before_hash
    raise StaleEditError,
          "stale edit detected for #{path}: disk content has changed since old_content was read"
  end

  verified_write(path, new_content, agent_id: agent_id, chain_id: chain_id)
end

#verified_write(path, content, agent_id: nil, chain_id: 'file_edits') ⇒ Hash

Write content to path, then re-read and compare SHA-256 digests.

Parameters:

  • path (String)

    absolute or relative filesystem path

  • content (String)

    content to write

  • agent_id (String, nil) (defaults to: nil)

    identity recorded in the audit trail

  • chain_id (String) (defaults to: 'file_edits')

    audit chain identifier

Returns:

  • (Hash)

    { path:, before_hash:, after_hash:, verified: true }

Raises:



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/legion/extensions/audit/helpers/verified_write.rb', line 27

def verified_write(path, content, agent_id: nil, chain_id: 'file_edits')
  before_hash = ::File.exist?(path) ? sha256_file(path) : nil
  expected    = sha256_string(content)

  ::File.write(path, content)

  actual = sha256_file(path)
  unless actual == expected
    raise WriteVerificationError,
          "write verification failed for #{path}: expected #{expected}, got #{actual}"
  end

  record_audit(
    path:        path,
    action:      'verified_write',
    agent_id:    agent_id,
    chain_id:    chain_id,
    before_hash: before_hash,
    after_hash:  actual
  )

  { path: path, before_hash: before_hash, after_hash: actual, verified: true }
end