Skip to content

Feat/contract api spine - #11

Closed
JavierGOrdonnez wants to merge 21 commits into
developfrom
feat/contract-api-spine
Closed

JavierGOrdonnez wants to merge 21 commits into
developfrom
feat/contract-api-spine

Conversation

@JavierGOrdonnez

Copy link
Copy Markdown
Collaborator

No description provided.

Javier Garcia Ordonez added 9 commits August 18, 2026 17:09
Consumers pass a table of samples plus configuration and receive typed results
in their own units. Training-file layout, Dakota configuration, preprocessing,
internal variable renaming, run directories and inverse transforms move behind
the boundary and are no longer reachable from a caller.

New package `itis_sumo.api`:
- errors.py   SumoError taxonomy (input / result / engine), so consumers stop
              classifying failures by matching on message text
- types.py    PreprocessingSpec + VariableSpec in domain vocabulary only, and
              frozen result dataclasses in original units, asdict-serializable
- _session.py internal fit-then-query engine owning validation, preprocessing
              and run-directory lifetime: discarded on success, preserved on
              failure with the path and stderr tail attached to the error
- workflows.py cross_validate() and evaluate_along_axes()

Also lands the grill outcome in SPEC: a VOCAB section (sample / variable =
parameter / response = quantity of interest), the consumer-contract goal line,
the constraints it implies with three unknowns parked rather than guessed, and
invariants V19cn-V27fq.

Supporting changes:
- export export_sumo_model/import_sumo_model and the E1 model store from the
  public package surface; they were reachable only via funs_evaluate, which
  V16qf forbids
- thread explicit seed and has_eval_id_column through the two wrapped
  evaluation functions, so the facade never relies on the filename-substring
  heuristic that caused B2
- docs: Glossary and Consumer API reference pages
- publish.yml accepts PEP 440 prerelease tags
- PORTING.md no longer claims the E1 work is unmerged

Backprops B10cs: a partial `at=` mapping raised a KeyError from
create_samples_along_axes, which requires a complete set of held values. The
API layer now materialises the default rather than assuming an internal helper
does.

302 tests pass, including 10 real unmocked Dakota runs through the new surface.
Completes the itis_sumo.api facade for all 8 workflows the mmux-vite Flask
blueprint currently duplicates internally (blueprints/dakota.py), so a real
port can proceed without discovering missing surface mid-cutover.

- evaluate_uncertainty(): draws explicit per-variable uncertainty samples,
  evaluates the surrogate once, injects its own predictive std via the
  erfinv trick, and summarizes n_histograms realizations as a histogram +
  boxplot. This logic previously existed only inline in mmux-vite's Flask
  route and as a private test helper (_manual_uq_propagate); it is now a
  real itis-sumo library primitive (propagate_manual_uq_with_uncertainty +
  summarize_uncertainty_samples in evaluate/funs_evaluate.py).
- optimize(): finds the Pareto-optimal trade-off front across one or more
  objectives. MOGA only ever supported a uniform search bound, not real
  uncertainty (get_bounds_uniform_distribution rejects anything else), so
  this introduces DomainSpec -- "where exploration is allowed" -- as a
  type distinct from DistributionSpec -- "what shape real-world
  uncertainty has" -- resolving the domain/distribution split that had
  been parked as an unknown pending real consumer evidence.
- SumoSession is single-response by construction; MOGA is inherently
  multi-objective, so it gets its own fit-then-query pair
  (optimize_pareto_front) rather than forcing that mismatch into the
  session. _validate_samples is generalized to a list of responses so
  both paths share the same validation.

Supporting: extracted _stderr_tail() to module level so both the session
and the standalone MOGA path report failing run directories the same way.
propagate_manual_uq_with_uncertainty and evaluate_sobol_indices both
sanitized input_vars/response_var/distributions at entry, then used
those (now-sanitized) names to index preprocessor.input_variables /
preprocessor.output_variables and to build DataFrame columns that
preprocessor.transform() looks up by column name. The preprocessor is
always fit on the caller's original names, so any variable name
containing characters sanitize_varnames rewrites (spaces, parens, ...)
caused a silent column-transform miss followed by a KeyError on the
mapped_name lookup. create_manual_uq_samples had the same bug
independently (it re-sanitized its own input_vars/distributions args).

Dakota-safe names are already obtained correctly further down via
preprocessor.input_variables[var].mapped_name, so the early
sanitize_varnames calls were both redundant and actively harmful.
Removed them; kept an explicit list() coercion in evaluate_sobol_indices
where the removed sanitize call had incidentally normalized a tuple
input to a list (pandas fancy-indexing needs a list, not a tuple).

Surfaced by porting itis-sumo's Sobol route in mmux-vite, whose
regression test exercises a real multi-word variable name end to end
for the first time.
Adds generate_lhs_samples and generate_grid_samples to itis_sumo.api,
wrapping the existing internal LHS design and full-factorial grid
generation so consumers can draw input samples without touching
itis-sumo internals. Needed so mmux_vite's sampling blueprint can stop
depending on the vendored dakota subpackage for sample generation.
…ntegration helpers

Now that mmux_vite's flaskapi fully consumes itis_sumo.api instead of these
job-shaped web models, they have no remaining callers inside itis-sumo (only
required_completed_jobs is used, by _session.py) and no remaining consumers
outside it. Removes:
- FunctionJob/JobVariableSelection pydantic models (preprocess/models.py)
- preprocess/data_preprocessor_integration.py (only caller was the removed
  JobVariableSelection-based training-file helper; its other helpers had no
  callers anywhere in itis-sumo)
- tests/test_data_preprocessor_integration.py

Updates docs/reference/preprocess.md to drop the now-stale description.
@JavierGOrdonnez JavierGOrdonnez added this to the Kula Ring milestone Aug 19, 2026
@JavierGOrdonnez JavierGOrdonnez self-assigned this Aug 19, 2026
@JavierGOrdonnez JavierGOrdonnez added the enhancement New feature or request label Aug 19, 2026
@JavierGOrdonnez

Copy link
Copy Markdown
Collaborator Author

Superseded by the stacked PR chain #31-#36 (gh-stack), whose combined diff is identical to this PR. See #31 for the bottom of the stack.

@JavierGOrdonnez
JavierGOrdonnez deleted the feat/contract-api-spine branch August 19, 2026 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant