Skip to content

stdlib+vm: Symbol#intern + resolv/optparse/ripper + Puppet-boot batch - #27

Merged
tannevaled merged 1 commit into
mainfrom
puppet-resolv-batch
Jun 28, 2026
Merged

tannevaled merged 1 commit into
mainfrom
puppet-resolv-batch

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Advances require "puppet" boot by clearing a chain of successive blockers, each implemented pure-Go (CGO=0) from scratch under BSD-3-Clause, with tests and 100% cross-package coverage.

Blockers cleared (in boot order)

  1. Symbol#intern — MRI alias of #to_sym (returns self). Without it :sym.intern fell through to Puppet's private arity-2 Object#intern, raising ArgumentError during require "puppet".
  2. resolv stdlib (new resolv.go) — real Resolv::IPv4/Resolv::IPv6 create/parse/validate/render plus the ::Regex constants; Resolv.getaddress/getaddresses are real for literal IPs (and raise Resolv::ResolvError for a name needing a real query). Resolv::DNS is constructable but its query methods raise NotImplementedError (real DNS sockets are a later round). Full Resolv::DNS::Resource::IN::{A,AAAA,SRV,...} constant tree + Resolv::Hosts/Resolv::DNS::Name.
  3. digest/md5 + digest/sha1 + digest/sha2 — registered as provided sub-features of the existing Digest module.
  4. Singleton-class include lookup (VM fix in lookupSMethod) — now consults a class's metaclass includes/prepends, so class << self; include M; end and extend M supply class methods, and subclasses inherit them. This is the mechanism Puppet's InstanceLoader relies on.
  5. File path coercion — new pathArg() coerces via #to_path/#to_str so File.* accept a Pathname (Puppet's FileSystem passes Pathnames), applied across the File surface.
  6. SystemExit (with status/success?), NoMemoryError, SecurityError, SignalException, Interrupt — under Exception (not StandardError), matching MRI.
  7. Singleton prelude module (require "singleton") — memoized .instance, private .new/.allocate; frozen prelude regenerated (drift test green).
  8. Kernel#load / Kernel.load — re-executes a file every call, returns true, searches $LOAD_PATH; Puppet's autoloader uses Kernel.load.
  9. $LOADED_FEATURES / $" — real mutable Array (the autoloader appends to it).
  10. File.mtime — returns a Time; Errno::ENOENT for a missing file.
  11. optparse + ripper loadable shells — classes/error trees exist so require completes and load-time references resolve; the parsing methods (OptionParser#parse!, Ripper.sexp, ...) raise NotImplementedError (real parsers are later rounds).

New current boot blocker (next round)

Puppet boot now advances to require "semantic_puppet" (from puppet/pops.rb). semantic_puppet is an external gem — not stdlib and not vendored in the Puppet checkout — so this is a missing dependency rather than a VM/stdlib gap. Characterized as a large/out-of-scope item (needs the gem on the load path), the natural target for the next round.

Verification

  • 100.0% cross-package coverage (the exact gate passes; the not-100 list is empty).
  • Full suite green (go test ./...), go vet clean, gofmt clean, go build ./cmd/rbgo succeeds.
  • Frozen-prelude drift test passes after regeneration.

🤖 Generated with Claude Code

Advances `require "puppet"` boot through a chain of successive blockers, each
fixed pure-Go (CGO=0) from scratch:

- Symbol#intern: MRI alias of #to_sym (returns self); stops :sym.intern falling
  through to Puppet's arity-2 Object#intern.
- resolv stdlib (new): real Resolv::IPv4/IPv6 parse/validate/render + ::Regex
  constants + Resolv.getaddress for literal IPs; DNS sockets raise
  NotImplementedError (Resolv::DNS constructable, query methods stubbed); full
  Resource constant tree.
- digest/md5 + digest/sha1 + digest/sha2: register as provided sub-features of
  the existing Digest module.
- Singleton-class include lookup (VM): lookupSMethod now consults a class's
  metaclass includes/prepends, so `class << self; include M; end` and `extend M`
  supply class methods (and subclasses inherit them) — Puppet's InstanceLoader.
- File path coercion: new pathArg() coerces via #to_path/#to_str so File.*
  accept a Pathname (Puppet::FileSystem); applied across the File surface.
- SystemExit (+status/success?), NoMemoryError, SecurityError, SignalException,
  Interrupt under Exception (not StandardError), matching MRI's tree.
- Singleton prelude module (require "singleton"): memoized .instance, private
  .new/.allocate; frozen prelude regenerated.
- Kernel#load / Kernel.load (new): re-executes a file every call, returns true,
  searches $LOAD_PATH; Puppet's autoloader uses Kernel.load.
- $LOADED_FEATURES / $" : real mutable Array (autoload appends to it).
- File.mtime: returns a Time; Errno::ENOENT for a missing file.
- optparse + ripper loadable shells: classes/errors exist so require completes;
  the parsing methods raise NotImplementedError (real parsers are later rounds).

Puppet boot now advances to `require "semantic_puppet"` — an external gem (not
stdlib), the next round's target. 100% cross-package coverage; full suite green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit 4ee85c3 into main Jun 28, 2026
9 checks passed
@tannevaled
tannevaled deleted the puppet-resolv-batch branch June 28, 2026 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant