Skip to content

Add Evaluator.evaluate_constant to read a single constant fact - #16

Open
dfl wants to merge 1 commit into
mainfrom
add-constant-reader
Open

Add Evaluator.evaluate_constant to read a single constant fact#16
dfl wants to merge 1 commit into
mainfrom
add-constant-reader

Conversation

@dfl

@dfl dfl commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

What

Adds FactGraph::Evaluator.evaluate_constant(name, graph_class:, module_filter:) — reads a single constant fact's value (a fact with no inputs and no dependencies) without building or evaluating the rest of the graph.

FactGraph::Evaluator.evaluate_constant(:pi)                                  # => 3.14
FactGraph::Evaluator.evaluate_constant(:tax_year, graph_class: Ty2024Graph)  # => 2024

Why

Today the only way to read a constant is Evaluator.evaluate(input, module_filter: [...]), which instantiates and runs every fact in the filtered module(s) — building Dry::Schema validators for facts you don't care about. Downstream apps (e.g. Gyraffe) have per-context constants like state_code, max_age, tax_year defined as constant(...) in the graph, but reading them on the request path meant a full filing-context evaluation. This gives a cheap, single-source read so those values don't have to be duplicated as literals in application models.

evaluate_constant builds only the single matching Fact and returns its resolver. It raises ArgumentError when:

  • no fact has that name,
  • the fact has inputs or dependencies (it isn't a constant), or
  • the name is ambiguous across modules — pass module_filter: to disambiguate.

Tests

New #evaluate_constant specs in evaluator_spec.rb cover: reading a constant, not touching prepare_fact_objects, unknown name, non-constant (has input), and cross-module ambiguity + module_filter disambiguation. Full suite green (62 examples) and RuboCop clean.

🤖 Generated with Claude Code

Constant facts (no inputs, no dependencies) previously could only be
read by evaluating the whole filtered graph. `evaluate_constant` builds
just the one Fact and returns its resolver, so callers can read a graph
constant (e.g. a per-context tax_year or state_code) without paying for
a full graph evaluation on the request path.

Raises ArgumentError for an unknown name, a fact that has inputs or
dependencies, or an ambiguous name across modules (disambiguate with
module_filter:).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dfl dfl self-assigned this Jul 21, 2026
@dfl
dfl marked this pull request as ready for review July 21, 2026 00:44
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