Module: Ace::Assign::Atoms::CatalogLoader

Defined in:
lib/ace/assign/atoms/catalog_loader.rb

Overview

Pure functions for loading and querying the step catalog.

The step catalog is a directory of YAML files describing available step types, their prerequisites, artifacts, and metadata.

Examples:

Loading the catalog

steps = CatalogLoader.load_all("/path/to/catalog/steps")
# => [{ "name" => "onboard", "skill" => "onboard", ... }, ...]

Finding a step

step = CatalogLoader.find_by_name(steps, "work-on-task")
# => { "name" => "work-on-task", "skill" => "ace:work-on-task", ... }

Class Method Summary collapse

Class Method Details

.filter_by_tag(steps, tag) ⇒ Array<Hash>

Filter steps by tag.

Parameters:

  • steps (Array<Hash>)

    Loaded step definitions

  • tag (String)

    Tag to filter by

Returns:

  • (Array<Hash>)

    Steps matching the tag



53
54
55
# File 'lib/ace/assign/atoms/catalog_loader.rb', line 53

def self.filter_by_tag(steps, tag)
  steps.select { |p| (p["tags"] || []).include?(tag) }
end

.find_by_name(steps, name) ⇒ Hash?

Find a step definition by name.

Parameters:

  • steps (Array<Hash>)

    Loaded step definitions

  • name (String)

    Step name to find

Returns:

  • (Hash, nil)

    Step definition or nil if not found



44
45
46
# File 'lib/ace/assign/atoms/catalog_loader.rb', line 44

def self.find_by_name(steps, name)
  steps.find { |p| p["name"] == name }
end

.load_all(steps_dir, canonical_steps: :auto) ⇒ Array<Hash>

Load all step definitions from a catalog directory.

Parameters:

  • steps_dir (String)

    Path to catalog/steps/ directory

  • canonical_steps (Array<Hash>, Symbol, Boolean, nil) (defaults to: :auto)

    Canonical step metadata to merge. ‘:auto` (default) loads from skill sources. `false` disables canonical merge and returns raw YAML definitions.

Returns:

  • (Array<Hash>)

    Array of step definition hashes



28
29
30
31
32
33
34
35
36
37
# File 'lib/ace/assign/atoms/catalog_loader.rb', line 28

def self.load_all(steps_dir, canonical_steps: :auto)
  return [] unless File.directory?(steps_dir)

  yaml_steps = Dir.glob(File.join(steps_dir, "*.step.yml")).sort.filter_map do |path|
    parse_step_file(path)
  end
  return [] if yaml_steps.empty?

  merge_step_catalog(yaml_steps, resolve_canonical_steps(canonical_steps))
end

.producers_of(steps, artifact) ⇒ Array<Hash>

Find steps that produce a given artifact.

Parameters:

  • steps (Array<Hash>)

    Loaded step definitions

  • artifact (String)

    Artifact name (e.g., “code-changes”)

Returns:

  • (Array<Hash>)

    Steps that produce the artifact



62
63
64
# File 'lib/ace/assign/atoms/catalog_loader.rb', line 62

def self.producers_of(steps, artifact)
  steps.select { |p| (p["produces"] || []).include?(artifact) }
end

.validate_prerequisites(selected, catalog) ⇒ Array<Hash>

Validate that prerequisites are satisfied for a selection of steps.

Parameters:

  • selected (Array<String>)

    Names of selected steps

  • catalog (Array<Hash>)

    Full step catalog

Returns:

  • (Array<Hash>)

    Validation issues, each with :step, :prerequisite, :strength, :reason



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/ace/assign/atoms/catalog_loader.rb', line 71

def self.validate_prerequisites(selected, catalog)
  issues = []

  selected.each do |step_name|
    step_def = find_by_name(catalog, step_name)
    next unless step_def

    (step_def["prerequisites"] || []).each do |prereq|
      next if selected.include?(prereq["name"])

      issues << {
        step: step_name,
        prerequisite: prereq["name"],
        strength: prereq["strength"] || "recommended",
        reason: prereq["reason"]
      }
    end
  end

  issues
end