agentic examples

The Stdlib Census

The Stdlib Census: "it's in the standard library" is a statement with a shelf life. Default gems become bundled gems on a published schedule, and every `require` your gem makes is either covered by ruby itself, covered by your gemspec, or a warning that hasn't fired yet. This census reads lib/'s requires, cross-checks the gemspec, and flags everything the next Ruby will bill you for.

Data & Pipelines Round 13 Hiroshi Shibata exit 0

source on github

bundle exec ruby examples/stdlib_census.rb

a real captured run

THE STDLIB CENSUS (27 distinct requires across lib/)

     zeitwerk           DECLARED   gemspec: zeitwerk
     tty-table          DECLARED   gemspec: tty-table
     tty-spinner        DECLARED   gemspec: tty-spinner
     tty-progressbar    DECLARED   gemspec: tty-progressbar
     tty-cursor         DECLARED   gemspec: tty-cursor
     tty-box            DECLARED   gemspec: tty-box
     thor               DECLARED   gemspec: thor
     pastel             DECLARED   gemspec: pastel
     ostruct            DECLARED   gemspec: ostruct
     openai             DECLARED   gemspec: ruby-openai
     async              DECLARED   gemspec: async
     logger             DECLARED   gemspec: logger
     async/barrier      DECLARED   gemspec: async
     async/semaphore    DECLARED   gemspec: async
     cgi                DECLARED   gemspec: cgi
     dry/schema         DECLARED   gemspec: dry-schema
     yaml               CORE       default gem, no promotion scheduled
     uri                CORE       default gem, no promotion scheduled
     date               CORE       default gem, no promotion scheduled
     digest             CORE       default gem, no promotion scheduled
     time               CORE       default gem, no promotion scheduled
     singleton          CORE       default gem, no promotion scheduled
     set                CORE       default gem, no promotion scheduled
     securerandom       CORE       default gem, no promotion scheduled
     fileutils          CORE       default gem, no promotion scheduled
     json               CORE       default gem, no promotion scheduled
     net/http           CORE       default gem, no promotion scheduled

  the receipts: ostruct was declared during the 3.4 warning wave,
  and this census's own first run caught TWO more - logger
  (promoted to bundled in 3.5) and cgi (trimmed to a bundled gem
  in 3.5, used here for CGI.escape) - both now declared in the
  gemspec with comments saying why. the round-11 'time' bug was
  the same lesson at file scope: require what you use; a
  transitive require is a loan, and rubies refinance.
  release engineering isn't glamorous: it's reading the NEWS file
  of every ruby release AS IF your gem's install matrix depends
  on it, because it does. this census is 60 lines; run it in CI
  and the 3.5 upgrade becomes a non-event instead of an issue
  tracker full of LoadErrors.

source

# frozen_string_literal: true

# The Stdlib Census: "it's in the standard library" is a statement
# with a shelf life. Default gems become bundled gems on a published
# schedule, and every `require` your gem makes is either covered by
# ruby itself, covered by your gemspec, or a warning that hasn't
# fired yet. This census reads lib/'s requires, cross-checks the
# gemspec, and flags everything the next Ruby will bill you for.
#
#   bundle exec ruby examples/stdlib_census.rb
#
# Runs offline; exits 1 if any require is covered by nobody.

require class="s">"bundler/setup"

# The census reads the agentic SOURCE - resolve the installed gem.
# Dependencies are asked of RubyGems as DATA, not regexed from the
# gemspec text: bundler NORMALIZES gemspecs in git checkouts (the
# authored `add_dependency "x"` becomes a serialized
# `add_runtime_dependency(%q<x>...)`), so text-scanning "the
# gemspec" gives different answers for path, git, and packaged
# installs of the very same commit. The spec object tells one truth.
AGENTIC_SPEC = Gem:class="y">:Specification.find_by_name(class="s">"agentic")
LIB = File.join(AGENTIC_SPEC.gem_dir, class="s">"lib")

# require name -> gem name, where they differ
GEM_FOR = {
  class="s">"dry/schema" => class="s">"dry-schema", class="s">"openai" => class="s">"ruby-openai",
  class="s">"async/semaphore" => class="s">"async", class="s">"async" => class="s">"async"
}.freeze

# Default gems already promoted to bundled (3.4 wave) or announced
# for promotion (3.5 wave) - require them without declaring them and
# a future ruby upgrade breaks your users' bundle
GEMIFIED = %w[
  ostruct pstore benchmark logger rdoc fiddle irb reline win32ole
  csv drb mutex_m base64 bigdecimal getoptlong observer rinda
  resolv-replace syslog abbrev nkf
].freeze

# Genuinely-safe stdlib for the foreseeable schedule
CORE_SAFE = %w[
  json fileutils time date yaml securerandom set singleton net/http
  uri open3 stringio tmpdir digest erb forwardable
].freeze

requires = Dir[File.join(LIB, class="s">"**/*.rb")].flat_map { |file|
  File.readlines(file, encoding: class="s">"UTF-8").filter_map { |line|
    name = line[/\Arequire class="s">"([^"]+)"/, 1]
    [name, File.basename(file)] if name
  }
}.group_by(&class="y">:first).transform_values { |rows| rows.map(&class="y">:last).uniq }

declared = AGENTIC_SPEC.runtime_dependencies.map(&class="y">:name)

verdicts = requires.keys.sort.map do |name|
  gem_name = GEM_FOR[name] || name.split(class="s">"/").first
  verdict = if declared.include?(gem_name) || declared.any? { |d| gem_name.start_with?(d) }
    [class="y">:declared, class="s">"gemspec: #{gem_name}"]
  elsif GEMIFIED.include?(name)
    declared.include?(name) ? [class="y">:declared, class="s">"gemspec: #{name}"] : [class="y">:gemified, class="s">"PROMOTED to bundled gem - declare it or a ruby upgrade breaks the bundle"]
  elsif CORE_SAFE.include?(name)
    [class="y">:core, class="s">"default gem, no promotion scheduled"]
  else
    [class="y">:uncovered, class="s">"COVERED BY NOBODY - works today by accident"]
  end
  [name, verdict]
end

puts class="s">"THE STDLIB CENSUS (#{requires.size} distinct requires across lib/)"
puts
order = {uncovered: 0, gemified: 1, declared: 2, core: 3}
verdicts.sort_by { |_, (kind, _)| order[kind] }.each do |name, (kind, note)|
  marker = {uncovered: class="s">"!!", gemified: class="s">" !", declared: class="s">"  ", core: class="s">"  "}[kind]
  puts format(class="s">"  %s %-18s %-10s %s", marker, name, kind.to_s.upcase, note)
end

uncovered = verdicts.count { |_, (kind, _)| kind == class="y">:uncovered }
gemified = verdicts.select { |_, (kind, _)| kind == class="y">:gemified }.map(&class="y">:first)

puts
puts class="s">"  the receipts: ostruct was declared during the 3.4 warning wave,"
puts class="s">"  and this census's own first run caught TWO more - logger"
puts class="s">"  (promoted to bundled in 3.5) and cgi (trimmed to a bundled gem"
puts class="s">"  in 3.5, used here for CGI.escape) - both now declared in the"
puts class="s">"  gemspec with comments saying why. the round-11 'time' bug was"
puts class="s">"  the same lesson at file scope: require what you use; a"
puts class="s">"  transitive require is a loan, and rubies refinance."
if gemified.any?
  puts class="s">"  still to declare before the next ruby: #{gemified.join(", class="s">")}."
end
puts class="s">"  release engineering isn't glamorous: it's reading the NEWS file"
puts class="s">"  of every ruby release AS IF your gem's install matrix depends"
puts class="s">"  on it, because it does. this census is 60 lines; run it in CI"
puts class="s">"  and the 3.5 upgrade becomes a non-event instead of an issue"
puts class="s">"  tracker full of LoadErrors."

exit(uncovered.zero? ? 0 : 1)