Class: Textus::Read::Freshness
- Inherits:
-
Object
- Object
- Textus::Read::Freshness
- Extended by:
- Contract::DSL
- Defined in:
- lib/textus/read/freshness.rb
Overview
Per-entry staleness scan (ADR 0079, 0085, 0093). Walks every entry declared in the manifest and reports a staleness verdict sourced from the two new policy slots (ADR 0093):
- intake entries: `entry.source.ttl_seconds` is the re-pull cadence;
basis = `_meta.last_fetched_at` (else file mtime). Past ttl ⇒ :expired.
- entries matched by a `retention:` rule: `retention.ttl_seconds` is the
GC age; basis = file mtime. Past ttl ⇒ :expired (:action = drop/archive).
Intake cadence wins when both apply (freshness is content currency; GC dueness shows via ‘reconcile –dry-run`). Status is one of :fresh, :expired, or :no_policy; the row also carries :action (:refresh for intake, :drop/:archive for retention).
ADR 0085 removed the public ‘freshness` verb: there is no `:cli`/`:mcp` surface. This is now a Ruby-only internal scan consumed by `pulse` (which derives `stale` + `next_due_at` from it) and the hook `Context`. Humans drill into per-entry staleness detail via `get` (last_fetched_at) + `rule_explain` (the ttl / action policy) instead of a dedicated verb.
Instance Method Summary collapse
- #call(prefix: nil, zone: nil) ⇒ Object
-
#initialize(container:, call:) ⇒ Freshness
constructor
A new instance of Freshness.
-
#soonest_due(prefix: nil, zone: nil) ⇒ Object
Returns the soonest ‘next_due_at` across all entries with a fetch policy, as an ISO-8601 string, or nil if none.
Methods included from Contract::DSL
arg, around, cli, cli_stdin, contract, contract?, summary, surfaces, verb, view
Constructor Details
#initialize(container:, call:) ⇒ Freshness
Returns a new instance of Freshness.
30 31 32 33 34 35 |
# File 'lib/textus/read/freshness.rb', line 30 def initialize(container:, call:) @container = container @call = call @manifest = container.manifest @file_store = container.file_store end |
Instance Method Details
#call(prefix: nil, zone: nil) ⇒ Object
49 50 51 52 53 54 55 56 57 58 |
# File 'lib/textus/read/freshness.rb', line 49 def call(prefix: nil, zone: nil) rows = [] @manifest.data.entries.each do |mentry| next if prefix && !mentry.key.start_with?(prefix) next if zone && mentry.zone != zone rows << row_for(mentry) end rows end |
#soonest_due(prefix: nil, zone: nil) ⇒ Object
Returns the soonest ‘next_due_at` across all entries with a fetch policy, as an ISO-8601 string, or nil if none.
39 40 41 42 43 44 45 46 47 |
# File 'lib/textus/read/freshness.rb', line 39 def soonest_due(prefix: nil, zone: nil) times = call(prefix: prefix, zone: zone) .map { |r| r[:next_due_at] } .compact .map { |t| Time.parse(t) } return nil if times.empty? times.min.utc.iso8601 end |