Module: Textus::Etag
- Defined in:
- lib/textus/etag.rb
Class Method Summary collapse
-
.contract_files(root) ⇒ Object
manifest.yaml, then every hook and schema file.
- .for_bytes(bytes) ⇒ Object
-
.for_contract(root) ⇒ Object
The fingerprint of everything an agent’s boot orientation depends on: the manifest PLUS the executable contract — hooks and schemas.
- .for_file(path) ⇒ Object
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.
28 29 30 31 32 33 34 |
# File 'lib/textus/etag.rb', line 28 def self.contract_files(root) [ File.join(root, "manifest.yaml"), *Dir.glob(File.join(root, "hooks", "**", "*.rb")), *Dir.glob(File.join(root, "schemas", "**", "*")).select { |f| File.file?(f) }, ] end |
.for_bytes(bytes) ⇒ Object
5 6 7 |
# File 'lib/textus/etag.rb', line 5 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.
18 19 20 21 22 23 24 |
# File 'lib/textus/etag.rb', line 18 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
9 10 11 |
# File 'lib/textus/etag.rb', line 9 def self.for_file(path) for_bytes(File.binread(path)) end |