Module: Textus::Value::Etag

Defined in:
lib/textus/value/etag.rb

Class Method Summary collapse

Class Method Details

.contract_files(root) ⇒ Object

manifest.yaml, then every hook and schema file. Dir.glob already returns sorted paths (Ruby 3.0+), keeping the digest independent of FS order.



29
30
31
32
33
34
35
36
# File 'lib/textus/value/etag.rb', line 29

def self.contract_files(root)
  geom = Textus::Store::Geometry.new(root)
  [
    geom.manifest_path,
    *Dir.glob(File.join(geom.hooks_dir, "**", "*.rb")),
    *Dir.glob(geom.schemas_glob).select { |f| File.file?(f) },
  ]
end

.for_bytes(bytes) ⇒ Object



6
7
8
# File 'lib/textus/value/etag.rb', line 6

def self.for_bytes(bytes)
  "sha256:#{Digest::SHA256.hexdigest(bytes)}"
end

.for_contract(root) ⇒ Object

The fingerprint of everything an agent’s boot orientation depends on: the manifest PLUS the executable contract — hooks and schemas. A mid-session edit to any of these makes the cached orientation stale, so the session must re-boot (ADR 0074). The composite is one digest over the sorted per-file listing, so it is order-stable.



19
20
21
22
23
24
25
# File 'lib/textus/value/etag.rb', line 19

def self.for_contract(root)
  listing = contract_files(root).map do |path|
    rel = path.delete_prefix(root).delete_prefix("/")
    "#{rel}:#{for_file(path)}"
  end.join("\n")
  for_bytes(listing)
end

.for_file(path) ⇒ Object



10
11
12
# File 'lib/textus/value/etag.rb', line 10

def self.for_file(path)
  for_bytes(File.binread(path))
end