Ruby Analyzer Parity Design (SCANNER-ENG-0009)

Status: Implemented • Owner: Ruby Analyzer Guild • Updated: 2025-11-10

1. Goals & Non-Goals

2. Scope & Inputs

InputLocationNotes
Gemfile / Gemfile.lockSource tree, layer filesystemHandle multiple apps per repo; honour Bundler groups.
Vendor bundles (vendor/bundle, .bundle/config)Layer filesystemNeeded for offline/built images; avoid double-counting platform-specific gems.
.gemspec files / cached specs~/.bundle/cache, vendor/cache, gems in layersSupport deterministic parsing without executing gem metadata.
Framework configsconfig/application.rb, config/routes.rb, config/sidekiq.yml, etc.Feed framework surface mapper.
Container metadataLayer digests via RustFS CASSupport incremental composition per layer.

3. High-Level Architecture

┌─────────────────────────┐        ┌────────────────────┐
│  Bundler Lock Collector │───────▶│  Package Graph     │
└─────────────────────────┘        │  Aggregator        │
                                   └─────────┬──────────┘
┌─────────────────────────┐                │
│  Gemspec Inspector      │───────────────▶│
└─────────────────────────┘                │
                                           ▼
                                   ┌────────────────────┐
┌─────────────────────────┐        │ Runtime Graph      │
│  Require/Autoload Scan  │───────▶│ Builder (Zeitwerk) │
└─────────────────────────┘        └─────────┬──────────┘
                                           │
                                           ▼
                                   ┌────────────────────┐
                                   │ Capability Emitter │
                                   └─────────┬──────────┘
                                           │
                                           ▼
                                   ┌────────────────────┐
                                   │ SBOM Writer        │
                                   │ + Policy Signals   │
                                   └────────────────────┘

4. Detailed Components

4.1 Bundler Lock Collector

4.2 Gemspec Inspector

4.3 Package Aggregator

4.4 Runtime Graph Builder

4.5 Capability & Surface Signals

4.6 CLI & Offline Integration

5. Data Contracts

ArtifactShapeConsumer
ruby_packages.jsonRubyPackageInventory { scanId, imageDigest, generatedAt, packages[] } where each package mirrors {id, name, version, source, provenance, groups[], platform, runtime.*}SBOM Composer, Policy Engine

ruby_packages.json records are persisted in PostgreSQL’s scanner.ruby_packages table via the RubyPackageInventoryStore. Scanner.WebService exposes the same payload through GET /api/scans/{scanId}/ruby-packages so Policy, CLI, and Offline Kit consumers can reuse the canonical inventory without re-running the analyzer. Each record is keyed by scanId and includes the resolved imageDigest plus the UTC timestamp recorded by the Worker. | ruby_runtime_edges.json | Edges {from, to, reason, confidence} | EntryTrace overlay, Policy explain traces | | ruby_capabilities.json | Capability {kind, location, evidenceHash, params} | Policy Engine (capability predicates) | | ruby_observation.json | Summary document (packages, runtime edges, capability flags) | Surface manifest, Policy explain traces |

All records follow AOC appender rules (immutable, tenant-scoped) and include hash, layerDigest, and timestamp normalized to UTC ISO-8601.

6. Testing Strategy

7. Rollout Plan & Dependencies

  1. Implement collectors and aggregators (SCANNER-ANALYZERS-RUBY-28-001…004).
  2. Add capability analyzer and observations (SCANNER-ANALYZERS-RUBY-28-005…008).
  3. Wire CLI commands and Offline Kit packaging (SCANNER-ANALYZERS-RUBY-28-011).
  4. Update docs (DOCS-SCANNER-BENCH-62-009 follow-up) once analyzer alpha ready.

Dependencies

8. Open Questions

9. Licensing & Offline Packaging (SCANNER-LIC-0001)


References: