The README Verifier
The README Verifier: every ruby code fence in the README is a promise. This extracts them all, syntax-checks each with Prism, and verifies that every Agentic constant a snippet mentions actually exists in the loaded gem. Docs rot silently; this makes the rot loud.
Patterns
Round 4
Andrew Kane
exit 0
bundle exec ruby examples/readme_verifier.rb
a real captured run
README VERIFIER: README.md 21 ruby snippets, 430 lines of promised code every snippet parses and every Agentic constant it names exists. the README keeps its promises.
source
# frozen_string_literal: true # The README Verifier: every ruby code fence in the README is a promise. # This extracts them all, syntax-checks each with Prism, and verifies # that every Agentic constant a snippet mentions actually exists in the # loaded gem. Docs rot silently; this makes the rot loud. # # bundle exec ruby examples/readme_verifier.rb [markdown_file] # # Runs offline. Exit 1 if the README promises anything the gem can't keep. require class="s">"bundler/setup" require class="s">"agentic" require class="s">"prism" README = ARGV.first ? File.expand_path(ARGV.first) : File.join(Gem:class="y">:Specification.find_by_name(class="s">"agentic").gem_dir, class="s">"README.md") # the installed gem, wherever bundler put it # Pull ruby code fences with their line numbers snippets = [] current = nil File.readlines(README, encoding: class="s">"UTF-8").each_with_index do |line, index| if current if line.start_with?(class="s">"```") snippets << current current = nil else current[class="y">:code] << line end elsif line.start_with?(class="s">"```ruby") current = {line: index + 2, code: +class="s">""} end end orchestrator = Agentic:class="y">:PlanOrchestrator.new(concurrency_limit: 8) checks = snippets.map do |snippet| task = Agentic:class="y">:Task.new( description: class="s">"snippet at line #{snippet[class="y">:line]}", agent_spec: {class="s">"name" => class="s">"Verifier", class="s">"instructions" => class="s">"verify the snippet"}, payload: snippet ) orchestrator.add_task(task, agent: ->(t) { code = t.payload[class="y">:code] parsed = Prism.parse(code) missing = code.scan(/Agentic(?:::[A-Z]\w*)+/).uniq.reject { |const| begin Object.const_get(const) true rescue NameError false end } { line: t.payload[class="y">:line], lines: code.lines.size, syntax_errors: parsed.errors.map { |e| class="s">"#{e.message} (snippet line #{e.location.start_line})" }, missing_constants: missing } }) task end verdict = Agentic:class="y">:Task.new( description: class="s">"the verdict", agent_spec: {class="s">"name" => class="s">"Editor", class="s">"instructions" => class="s">"sum it up"} ) orchestrator.add_task(verdict, checks, agent: ->(t) { reports = checks.map { |c| t.output_of(c) } { total: reports.size, total_lines: reports.sum { |r| r[class="y">:lines] }, broken: reports.select { |r| r[class="y">:syntax_errors].any? || r[class="y">:missing_constants].any? } } }) result = orchestrator.execute_plan report = result.results[verdict.id].output puts class="s">"README VERIFIER: #{File.basename(README)}" puts class="s">" #{report[class="y">:total]} ruby snippets, #{report[class="y">:total_lines]} lines of promised code" puts if report[class="y">:total].zero? puts class="s">" zero snippets found - a promise-free README can't keep promises." exit 1 elsif report[class="y">:broken].empty? puts class="s">" every snippet parses and every Agentic constant it names exists." puts class="s">" the README keeps its promises." else report[class="y">:broken].each do |broken| puts class="s">" BROKEN: snippet at README line #{broken[class="y">:line]}" broken[class="y">:syntax_errors].each { |e| puts class="s">" syntax: #{e}" } broken[class="y">:missing_constants].each { |c| puts class="s">" missing constant: #{c}" } end exit 1 end