cursus.step_catalog.spec_discovery

Specification discovery for the unified step catalog system.

Interface-first: every step specification is a view onto a validated StepInterface loaded from the step’s .step.yaml. The StepInterface is a drop-in for the legacy StepSpecification — it exposes step_type, node_type, dependencies and outputs, so serialize_spec() (kept verbatim) reads it unchanged. Discovery is driven by the registry’s canonical step names + the per-step variants block; there is no directory scan, no AST parse and no per-file import. The former steps/specs/ folder scan is gone.

class SpecAutoDiscovery(package_root, workspace_dirs)[source]

Bases: object

Specification discovery sourced from step interfaces + the step registry.

discover_spec_classes(project_id=None)[source]

Discover all step specifications from the registry + interfaces.

Parameters:

project_id (str | None) – Optional project ID (accepted for signature stability; the registry + interface loader are the source of truth)

Returns:

Dictionary mapping PascalCase canonical step name to its StepInterface (a view onto the step’s validated interface, a StepSpecification drop-in). Steps without an interface file are skipped.

Return type:

Dict[str, Any]

load_spec_class(step_name)[source]

Load the specification for a specific step.

Parameters:

step_name (str) – PascalCase canonical step name

Returns:

The step’s StepInterface (a StepSpecification drop-in), or None if the step has no interface file.

Return type:

Any | None

find_specs_by_contract(contract_name)[source]

Find all specifications (across job-type variants) for a step.

This method enables contract-specification alignment validation by finding the specifications associated with a given step name. Under interface-first discovery every variant of a step lives in one .step.yaml variants block, so this returns one serialized-spec dict per variant (plus the base interface when the step declares no variants), keyed by {StepName}_{variant} so _extract_job_type_from_spec_name_registry() can classify each entry by job type.

Parameters:

contract_name (str) – Name of the step / contract to find specifications for. Accepts a PascalCase canonical name or a file-stem-ish name (e.g. "tabular_preprocessing" / "tabular_preprocessing_contract").

Returns:

Dictionary mapping {StepName}_{variant} (or the bare step name for a variant-less step) to its serialized specification dictionary.

Return type:

Dict[str, Any]

serialize_spec(spec_instance)[source]

Convert specification instance to dictionary format.

This method provides standardized serialization of StepSpecification objects for use in validation and alignment testing.

Parameters:

spec_instance (Any) – StepSpecification instance to serialize

Returns:

Dictionary representation of the specification

Return type:

Dict[str, Any]

load_all_specifications()[source]

Load and serialize every step specification from the interfaces.

This method provides comprehensive specification loading for validation frameworks and dependency analysis tools. It discovers every step interface and serializes each to dictionary format for easy consumption.

Returns:

Dictionary mapping PascalCase canonical step name to its serialized specification dictionary.

Return type:

Dict[str, Dict[str, Any]]

get_job_type_variants(base_step_name)[source]

Get all job type variant keys for a base step name.

Job-type variants (training, validation, testing, calibration, …) are declared in the step’s .step.yaml variants block. This returns the variant KEYS from that block (not the VariantDecl values).

Parameters:

base_step_name (str) – Base name of the step (PascalCase canonical or file-stem-ish)

Returns:

List of job type variant keys found (empty if the step has none or has no interface file).

Return type:

List[str]

create_unified_specification(contract_name)[source]

Create unified specification from multiple variants using smart selection.

Integrates SmartSpecificationSelector logic: - Multi-variant specification discovery using existing find_specs_by_contract() - Union of dependencies and outputs from all variants - Smart validation logic with detailed feedback - Primary specification selection (training > generic > first available)

Parameters:

contract_name (str) – Name of the contract to find specifications for

Returns:

Unified specification model with metadata

Return type:

Dict[str, Any]

validate_logical_names_smart(contract, contract_name)[source]

Smart validation using multi-variant specification logic.

Implements the core Smart Specification Selection validation: - Contract input is valid if it exists in ANY variant - Contract must cover intersection of REQUIRED dependencies - Provides detailed feedback about which variants need what

Parameters:
  • contract (Dict[str, Any]) – Contract dictionary

  • contract_name (str) – Name of the contract

Returns:

List of validation issues

Return type:

List[Dict[str, Any]]