Class: Textus::Manifest::Policy

Inherits:
Object
  • Object
show all
Defined in:
lib/textus/manifest/policy.rb

Overview

Authority over zones and roles derived from a Manifest::Data snapshot. Encapsulates the lookups previously living on Manifest itself (zone_writers, permission_for). Write authority is derived from capabilities × zone-kind (ADR 0030): each zone-kind requires one verb (Schema::KIND_REQUIRES_VERB) and a role may write a zone iff its caps include that verb (verb_for_zone, roles_with_capability). Derived / proposal-queue status is authoritative via the declared-kind family (declared_kind, derived_zone?, queue_zone?, queue_zone).

Instance Method Summary collapse

Constructor Details

#initialize(data) ⇒ Policy

Returns a new instance of Policy.



12
13
14
# File 'lib/textus/manifest/policy.rb', line 12

def initialize(data)
  @data = data
end

Instance Method Details

#declared_kind(zone_name) ⇒ Object

The kind declared on a zone in the manifest, or nil if undeclared.



53
54
55
# File 'lib/textus/manifest/policy.rb', line 53

def declared_kind(zone_name)
  @data.declared_zone_kinds[zone_name]
end

#derived_zone?(zone_name) ⇒ Boolean

A zone is derived iff it declares kind: derived.

Returns:

  • (Boolean)


69
70
71
# File 'lib/textus/manifest/policy.rb', line 69

def derived_zone?(zone_name)
  declared_kind(zone_name) == :derived
end

#permission_for(zone_name) ⇒ Object



45
46
47
48
49
50
# File 'lib/textus/manifest/policy.rb', line 45

def permission_for(zone_name)
  Textus::Domain::Permission.new(
    zone: zone_name,
    writers: zone_writers(zone_name),
  )
end

#propose_zone_for(role) ⇒ Object

The zone a proposer role writes proposals into: the single zone that declares kind: queue, when the role can write it. Returns nil if there is no queue zone or the role cannot write it.



81
82
83
84
85
86
87
88
# File 'lib/textus/manifest/policy.rb', line 81

def propose_zone_for(role)
  return nil if role.nil?

  q = queue_zone
  return nil unless q && zone_writers(q).include?(role)

  q
end

#proposer_roleObject

The conventional automated proposer: a role that can propose but is not the author-anchor (so it resolves to ‘agent`, not `human`, under the default mapping). Falls back to the first proposer, then nil.



32
33
34
35
# File 'lib/textus/manifest/policy.rb', line 32

def proposer_role
  proposers = roles_with_capability("propose")
  (proposers - roles_with_capability("author")).first || proposers.first
end

#queue_zoneObject

The single zone declaring ‘kind: queue`, or nil. Schema guarantees <=1.



64
65
66
# File 'lib/textus/manifest/policy.rb', line 64

def queue_zone
  @data.declared_zone_kinds.key(:queue)
end

#queue_zone?(zone_name) ⇒ Boolean

A zone is a proposal queue iff it declares kind: queue.

Returns:

  • (Boolean)


74
75
76
# File 'lib/textus/manifest/policy.rb', line 74

def queue_zone?(zone_name)
  declared_kind(zone_name) == :queue
end

#roles_with_capability(verb) ⇒ Object

Names of roles whose declared caps include ‘verb`.



25
26
27
# File 'lib/textus/manifest/policy.rb', line 25

def roles_with_capability(verb)
  @data.role_caps.select { |_name, caps| caps.include?(verb) }.keys
end

#verb_for_zone(zone_name) ⇒ Object

The capability a zone’s kind requires to be written, or nil if the zone declares no kind. declared_kind returns a Symbol; the table is keyed by String.



19
20
21
22
# File 'lib/textus/manifest/policy.rb', line 19

def verb_for_zone(zone_name)
  kind = declared_kind(zone_name)
  kind && Schema::KIND_REQUIRES_VERB[kind.to_s]
end

#zone_writers(zone_name) ⇒ Object

The roles authorized to write ‘zone_name`: those holding the verb its kind requires. Raises on an undeclared zone.

Raises:



39
40
41
42
43
# File 'lib/textus/manifest/policy.rb', line 39

def zone_writers(zone_name)
  raise UsageError.new("undeclared zone '#{zone_name}'") unless @data.declared_zone_kinds.key?(zone_name)

  roles_with_capability(verb_for_zone(zone_name))
end

#zones_of_kind(kind) ⇒ Object

Zone names declaring ‘kind` (a Symbol), in manifest order. Lets callers (boot) name a kind’s live zone instance(s) instead of hardcoding names.



59
60
61
# File 'lib/textus/manifest/policy.rb', line 59

def zones_of_kind(kind)
  @data.declared_zone_kinds.select { |_name, k| k == kind }.keys
end