Class: Textus::Manifest::Policy

Inherits:
Object
  • Object
show all
Defined in:
lib/textus/manifest/policy.rb,
lib/textus/manifest/policy/react.rb,
lib/textus/manifest/policy/source.rb,
lib/textus/manifest/policy/matcher.rb,
lib/textus/manifest/policy/retention.rb,
lib/textus/manifest/policy/handler_permit.rb,
lib/textus/manifest/policy/publish_target.rb

Overview

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

Defined Under Namespace

Modules: Matcher Classes: HandlerPermit, PublishTarget, React, Retention, Source

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

#actor_for(verb) ⇒ Object

The role textus acts AS for a system-initiated operation requiring ‘verb` (no human passed –as). Capability-derived — a role name that exists in the manifest, or nil. Never a hardcoded literal (ADR 0044).



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

def actor_for(verb)
  roles_with_capability(verb).first
end

#declared_kind(lane_name) ⇒ Object

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



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

def declared_kind(lane_name)
  @data.declared_lane_kinds[lane_name]
end

#derived_entry?(key) ⇒ Boolean

ADR 0091: derived-ness is a property of the ENTRY, not its lane (one machine lane holds both intake and derived entries). Resolve the entry and ask it directly. Returns false if entries are not yet built (validator phase during Data#initialize) — validators must not rely on cross-entry state during construction.

Returns:

  • (Boolean)


65
66
67
68
69
70
# File 'lib/textus/manifest/policy.rb', line 65

def derived_entry?(key)
  return false if @data.entries.nil?

  entry = @data.entries.find { |e| e.key == key } or return false
  entry.derived?
end

#lanes_of_kind(kind) ⇒ Object

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



51
52
53
# File 'lib/textus/manifest/policy.rb', line 51

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

#machine_laneObject

The single lane declaring kind: machine, or nil.



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

def machine_lane
  @data.declared_lane_kinds.key(:machine)
end

#propose_lane_for(role) ⇒ Object

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



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/textus/manifest/policy.rb', line 85

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

  q = queue_lane
  return nil unless q

  q_verb = verb_for_lane(q)
  return nil unless roles_with_capability(q_verb).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_laneObject

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



56
57
58
# File 'lib/textus/manifest/policy.rb', line 56

def queue_lane
  @data.declared_lane_kinds.key(:queue)
end

#queue_lane?(lane_name) ⇒ Boolean

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

Returns:

  • (Boolean)


78
79
80
# File 'lib/textus/manifest/policy.rb', line 78

def queue_lane?(lane_name)
  declared_kind(lane_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_lane(lane_name) ⇒ Object

The capability a lane’s kind requires to be written, or nil if the lane 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_lane(lane_name)
  kind = declared_kind(lane_name)
  kind && Schema::KIND_REQUIRES_VERB[kind.to_s]
end