Skip to content

release: 0.1.0 — first real-PyPI release (T56xx) - #60

Merged
JavierGOrdonnez merged 68 commits into
mainfrom
release/0.1.0
Oct 15, 2026
Merged

JavierGOrdonnez merged 68 commits into
mainfrom
release/0.1.0

Conversation

@JavierGOrdonnez

Copy link
Copy Markdown
Collaborator

What this is

The first real-PyPI release: 0.1.0 stable. PyPI name itis-sumo is free (JSON endpoint 404-verified). Nothing has ever been published to real PyPI or GitHub Releases.

What is IN

  • the full develop-lineage library through the a10 era (T1–T53xx state, minus a11), i.e. what 0.1.0a10 carried
  • T55kd: engine itis-dakota==6.24.13 (Windows wheels) + Python 3.12–3.14 — the release ships with the Windows support and modern Python matrix
  • main-lineage ancestry merged with -s ours (content unchanged: tests/test_ci_workflow.py stays retired per B6nr; this lineage's CI/dependabot/publish files are strictly newer)

What is deliberately OUT

0.1.0a11's single squash commit (44093a1) is reverted on this branch only: the report façade + NIH-incubator diagnostics (T48np/T49np/T54rp, V49rp) are still incubating on the CONFIDENTIAL NIH branches — owner call 2026-10-14. They stay on develop and ship in a later release.

⚠️ ⊥ ever merge main → develop without an owner call: this branch's revert would travel onto develop.

Verification (local, this branch)

  • suite 391/391 green on py3.13 and py3.14 with real 6.24.13 wheels; ruff/ty clean; mkdocs build --strict clean
  • uv build → itis_sumo-0.1.0 wheel+sdist, twine check PASSED; wheel installed into a clean py3.14 venv passes the suite (mirrors publish.yml verify)

⚠️ Before merging — read this

Merging this PR is the publish action: auto-tag.yml will push tag v0.1.0 and auto-dispatch publish.yml {registry: pypi} → upload to real PyPI + create the GitHub Release (irreversible). Prereqs that must exist first (one-time, manual):

  1. PyPI project itis-sumo + Trusted Publisher config for repo ITISFoundation/itis-sumo, workflow publish.yml (pypi.org → managing project → publishing)
  2. GitHub environment pypi on the repo (publish.yml's environment: target) — plus testpypi environment if not yet present

Do not merge until both are in place, full CI (incl. the new tests-windows leg) is green, and the owner OKs the publish. See SPEC T56xx for the full flow.

Javier Garcia Ordonez and others added 30 commits August 7, 2026 17:27
Persists exported Dakota surrogate models (archive files + verbatim conf
block + a reference copy of the training data) under a server-generated
sumo_model_id, and reloads them via import_model. Falls back to a
synthesized header-only points file with a loud warning if a model's
stored training-data copy is missing, since Dakota's import_model never
reads the points file's row values back (verified against Dakota source
and empirical round-trip tests) -- only text_archive/binary_archive
formats are re-importable.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Single-sources the version via hatch-vcs (git-tag driven, falls back to
0.1.0), completes pyproject.toml PyPI metadata (LICENSE, authors,
classifiers, project.urls), and adds GitHub Actions for test/lint on
every PR and a tag-triggered build+publish pipeline using PyPI Trusted
Publisher (OIDC, no stored tokens) plus git-cliff changelog generation
for GitHub Releases.

Verified: uv build + twine check dist/* pass; 123 tests green;
itis-sumo confirmed unclaimed on PyPI. ty check left non-blocking in CI
for now — 22 pre-existing type errors in tests/lhs.py predate this
change and are out of scope here.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ux_vite

Ports Tier 1 (unit), Tier 2 (property invariants), and Tier 3 (real-Dakota
analytical) test suites from mmux_vite's feat/vv-unit-and-property-tests
branch, rewriting imports from mmux_flaskapi.* to itis_sumo.*. Test logic
and assertions are unchanged. Also ports the two V&V planning docs,
re-branded for itis-sumo, and registers the new `analytical` pytest marker.

All 122 tests pass (96 Tier 1/2, 26 Tier 3).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ce/explanation/about)

Splits the previously provenance-heavy docs into Diátaxis quadrants:
new Tutorials (getting-started, worked examples), How-to guides
(cross-validate, sensitivity analysis, MOGA, preprocessing) written
against API signatures verified against source, Reference (renamed
from algorithms/), Explanation (renamed from theory/), and a demoted
About section for provenance/spec. docs/index.md becomes a short
router page. Fixes all relative cross-links left stale by the move
and the docstring in examples/generate_docs_figures.py; mkdocs build
--strict now passes with zero warnings.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Diataxis MkDocs restructure + V&V report, consolidating docs onto
develop instead of only living on feature branches.
Serves MkDocs via a container instead of a bare host process --
under WSL2, a plain `mkdocs serve` bound to 0.0.0.0 isn't reliably
reachable from a Windows browser without manual netsh portproxy;
Docker Desktop's WSL2 integration forwards published container
ports to Windows localhost automatically.
E1: SuMo model export/import persistence (SPEC T12-T14, all done).

# Conflicts:
#	SPEC.md
#	src/itis_sumo/config/funs_create_dakota_conf.py
…ogate_model call

The E1 merge left this call site behind when has_eval_id_column became a
required keyword-only arg (T17bq) on the vv-port-tests-and-docs branch;
add_surrogate_model() call sites via create_sumo_evaluation_conffile already
had it, this direct call didn't.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…d instead

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Haiku subagent invented a GitHub link for mmux_documentation that doesn't
appear in the source (about/index.md references it as plain text, no URL).
Removed the unverified link to avoid distributing a guessed URL.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…gent-fabricated-URL bug

Records the 7 UX-review findings that drove TD1ef-TD9uv (each traced to its
fix commit) plus the Haiku subagent's fabricated mmux_documentation URL
caught during TD7qr review. Adds two invariants: V3hd (shipped pages must be
landing-page-reachable, no orphans) and V4lc (subagents must not invent
external URLs; mkdocs --strict doesn't catch this, parent must diff-check).
…gated

V&V report stays a built page (linkable, just not in Nav) since the intended
final format is a standalone downloadable PDF, not a browsable site section.
Landing-page copy now offers it as "available on request" instead of "see
the report" -- reads as a deliberate offering, not a defensive plea for
trust. Link still points at the in-progress HTML report for now; TD11zb
(DOCS_SPEC.md, not started) tracks swapping that to a support@sim4life.io
contact flow once a real PDF deliverable exists.
Codifies the flaskapi/mmux_vite call-surface design decision as §C
constraint + V16qf invariant, plus T18ry tracking the analyze_dataset()
diagnostics entrypoint (blocked pending promotion of scale/distribution
logic off the confidential nih-in-silico-example incubator branch).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Preserves the 2026-08-13/14 branch-sprawl diagnosis/plan (previously only
in an ephemeral plan-mode file) and adds a living inventory of what's on
the confidential feat/nih-in-silico-example branch, per-piece test/proof
status, to inform future individual-promotion decisions (SPEC.md's
promotion rule, T18ry in particular).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Schema-only per SPEC.md T18ry/V16qf: DatasetDiagnostics/VariableDiagnostics/
OutlierSummary dataclasses + analyze_dataset() signature, raising
NotImplementedError until the underlying scale/distribution/outlier
detection logic is promoted off the confidential incubator branch (see
BRANCH_CONSOLIDATION.md §3 for per-piece readiness).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
fix(ci): handle unavailable push base commits
JavierGOrdonnez and others added 20 commits August 27, 2026 14:22
fix(ci): pass GITHUB_TOKEN to auto-tag gh dispatch (B15tg)
…16mo rung 2

Rung 2 of the engine modernization: move off the 1.5.x line (Dakota 6.20) to
itis-dakota==6.24.7 (Dakota 6.24). 6.24.7 is the latest 6.24.x still shipping
cp311 wheels, so itis-sumo keeps its Python 3.11 primary (parity with mmux/vite);
6.24.8+ dropped cp311 and would force a 3.12 migration of both repos (deferred).

The 6.23+ `Interface::interface_cache()` regression (SPEC §R5) is still present
in 6.24.7: `dakota.environment.study()`'s ctor throws `map::at` for itis-sumo's
pure data-fit surrogate confs (no interface block), which broke all 45 real-Dakota
surrogate tests. Shimmed in itis-sumo rather than waiting on the upstream
get-or-create fix: `add_r5_interface_cache_workaround()` (appended to every conf
via `start_dakota_file()`) declares an unused `single` model wired to a no-op
`fork` interface (`analysis_drivers='true'`) and points each surrogate model at
it via `truth_model_pointer='R5_WA_MODEL'`, forcing the Interface to be constructed
(populating the cache) without ever executing it. 318-test suite green.

Bumps itis-sumo version 0.1.0a3 -> 0.1.0a4. See SPEC §B B16mo, T16mo.
feat(engine): bump itis-dakota 1.5.11->6.24.7 (Dakota 6.20->6.24) — T16mo rung 2
* ci: auto-publish releases by branch channel

* ci: dispatch publishing from release branch

* docs: align visual identity with TIP/S4L family

Add IT'IS-family branding to the MkDocs site: SuMo logo + favicon,
Inter font, TIP blue/indigo custom palette, TIP-style workflow diagram
component, card-grid landing hero, and IT'IS footer via theme override.
Rename nav to Quick Start/Workflows/Background/Reference/About, apply
admonition vocabulary to top pages, and record invariants in DOCS_SPEC §W.

Verified with 'make docs-build' (--strict, exit 0; nav warnings are
intentional for the linkable-but-unnavigated V&V report and the
dev-facing style guide).

---------

Co-authored-by: Javier Garcia Ordonez <ordonez@zmt.swiss>
* backprop §B.8hm + §V.19nd: schedule grouped dependency updates

* test: require Dependabot develop target

* chore: bump alpha version to 0.1.0a5

---------

Co-authored-by: Javier Garcia Ordonez <ordonez@zmt.swiss>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* feat(api): support log-scale variables in the itis-sumo backend (T27fr)

Port the mmux_vite fullstack-logscale backend transforms into the library.

DataPreprocessor (V21pf/V22rs):
- add log_transform to VariableConfig + setup_log_transform/_configure_log_transform
- natural-log applied in _fit/_transform_variable_group, exp restored in
  inverse_transform (both input and output groups)
- inverse_transform_output_std: delta-method std_orig ~= |y_hat_orig| * std_log,
  with normalization-aware scaling; falls back unchanged + warns without points

api._session:
- honour PreprocessingSpec scale: drop the "log not supported yet" rejection,
  drive setup_log_transform from the effective per-column scale in fit()
- route predicted std through the delta-method inverse in cross_validate and
  along_axes (linear path is a plain remap, unchanged)
- reject non-positive log columns and non-positive held log values as
  SumoInputError before Dakota runs (V23er taxonomy, not the raw ValueError)

Tests: preprocessor round-trip / mixed-scale / positivity / delta-method
(unit) + real-Dakota cross_validate/along_axes/grid original-space units and
the rejection guards (integration); replace the obsolete "unsupported scale"
api-contract test with honour + reject cases. 332 passed, ruff/ty clean.

T27fr stays ~: UQ/MOGA log paths inherit via the preprocessor but are
untested here, and the domain/distribution config split is the other half.

* feat(api): log-scale UQ manual sampling + CV metrics (T27fr)

Log now reaches the uncertainty sampler and accuracy metrics, not just the
surrogate fit.

- data.create_manual_uq_samples: add the log_scale branch — a log-scale uniform
  is drawn uniformly in log10 space and returned in the caller's original units
  (log-uniform); log_scale with a non-uniform distribution or a non-positive
  bound raises. Faithful to the mmux_vite source.
- api._session._uq_engine_distributions: flag log-scale variables as log_scale for
  the sampler, and reject log-scale + non-uniform / non-positive-lower-bound at
  the boundary as SumoInputError (V23er) instead of the sampler's raw ValueError.
- evaluate_cv_metrics already composes cross_validate (now log-aware), so a
  log-scale response flows to the metrics through the preprocessor.

Tests: create_manual_uq_samples log-uniform / reject cases (unit) + real-Dakota
evaluate_uncertainty log input skews response low, log+normal and log+min<=0
rejections, and cv_metrics honouring / rejecting log (integration).

* feat(api): log-scale variables and objectives in MOGA (T27fr)

Complete "log everywhere" for the optimizer.

- api._session.optimize_pareto_front: accept a PreprocessingSpec; a log-scale
  variable is trained and explored in log space (its search domain is mapped into
  ln space and must be strictly positive -> else SumoInputError), a log-scale
  objective is fitted on ln(y) with the Pareto front exp-restored to original
  units via the preprocessor inverse.
- api.optimize: forward the preprocessing spec.

Tests: real-Dakota MOGA with a log objective returns an original-units front, and
a log variable with a non-positive domain bound is rejected.

* feat(api): log-scale sampling in Sobol indices (T27fr)

Complete "log everywhere" for the sensitivity workflow.

- api._session.sobol: route distributions through _uq_engine_distributions, so a
  log-scale variable is flagged log_scale and rejected (SumoInputError) unless it
  carries a strictly-positive uniform -- same contract as uncertainty.
- evaluate.evaluate_sobol_indices: build the Saltelli ppf in log space for a
  log-scale variable (scipy.stats.loguniform -> log-uniform in the caller's
  original units); the surrogate's preprocessor re-applies the log downstream.
- Reword the shared guard as "distribution" not "uncertainty" so it reads right
  for both UQ and Sobol.

Test: real-Dakota Sobol with a log input shifts the variance decomposition in the
expected direction (compressed width explains less, height's share rises), plus
log+normal and log+min<=0 rejections.

* docs(spec): honour log-scale in every workflow (T27fr / V44ls / B17sc)

Record the "log everywhere" behaviour just shipped in code.

- V44ls: a scale="log" override must be honoured by every scale-consuming api
  workflow (surrogate fit, UQ/Sobol sampling, MOGA search domain, CV metric), never
  silently ignored outside the surrogate fit.
- B17sc (backprop): log reached the surrogate but was a near-no-op for
  UQ/MOGA/cv-metrics/Sobol after the initial port; the fix wires log-space into each
  path, guarded by V44ls.
- T27fr note: backend log-scale now complete end-to-end; remaining scope narrowed
  to the domain⊥distribution split (V26dd) + mmux_vite frontend consumer migration.

* chore(release): 0.1.0a5 -> 0.1.0a6

version-check (V28tz) requires a develop PR's version to be strictly newer than
every existing tag; v0.1.0a5 is already tagged at develop's tip, so this PR must
carry a6. pyproject + uv.lock self-version moved together (uv lock --locked clean).

* docs(spec): V45ls scale-is-first-class + V21pf amendment, T46ls opened

scale must reach every value-producing entry point (samplers + correlations
included), enforced structurally (required-arg helpers) + behaviourally
(linear<->log flip-test). Decisions locked in review discussion.

* fix(tests): narrow Optional match in dependabot ecosystem test

Pre-existing ty diagnostic (unguarded .group on re.search) reding prek on
every PR into develop, incl. #47. Walrus + assert keeps the test strict
(silently skipping a block would hide config drift).

* feat(api): scale first-class on samplers + correlations (T46ls)

V45ls: every value-producing api entry point takes scale and applies it.

- data.funs_data_processing: one unit->value map scale_distribution(min,max,*,scale)
  (uniform vs scipy.loguniform) + resolve_log_scale + scale_values; scale is a
  REQUIRED arg -- unwired value producers break at call with TypeError, never
  silently default. Absorbs the log10-power hand-roll and the duplicated log
  guards in manual-UQ sampling and the Sobol ppf path.
- api.generate_lhs_samples / generate_grid_samples: accept preprocessing; log
  domains fill log-uniform/geometric (linear default bit-identical);
  non-positive log domain -> SumoInputError.
- api.compute_correlations: accepts preprocessing; compute_correlation_indices
  requires input_scales/output_scale (Pearson moves under log, Spearman is
  monotone-invariant, asserted).
- api._session: _is_log closure + method getter collapse into module-level
  column_scale(spec, column).

Tests: correlator unit tests adopt required scales + new scale-shift/invariance
and TypeError-tripwire cases. 359-pass suite, ruff/ty clean.

* test(api): V45ls flip matrix + log-scale gap tests (T46ls)

- TestScaleFlipMatrix: all 10 public value-producing entry points' outputs must
  move when width turns log -- the machine guard against silent scale-ignore,
  shipped or future.
- TestScaleAwareSamplers: log LHS/grid fill log-uniform, linear default
  unchanged, non-positive log domains refused, correlations honour log
  (Pearson moves, Spearman bit-identical, untouched column identical).
- TestScaleGapCoverage: MOGA log objective + maximize (sign-after-log inverse
  order), log-variable sweep geometric in original units, log-response
  uncertainty multiplicative spread, Sobol mixed log+constant partition.
- Existing grid test: cast result.data for repo-wide ty (fixes the prek red on
  #47).

* docs: V&V Category I scale semantics + tier-1 scale contracts (T46ls)

verification-validation.md: new Category I (I1-I8, incl. H6 preprocessor log
round-trip), status counts 245->359 / 26->30, engine refs 1.5.9/6.20 -> 6.24.7,
summary A-H -> A-I. TIER plan: section 7 documents the scale helper contracts
(required-scale tripwires, log guards, delta-method std inverse). SPEC: T46ls x.

* feat(api): evaluate_correlations -- MC-through-surrogate correlation (T47mt)

The 11th value-producing entry point. The web UI's correlation workflow
(/compute_correlation_indices, #470) draws Monte Carlo samples from caller
distributions, predicts them through the fitted surrogate, and correlates
each input against the prediction over the SHARED sample set. Until now the
api only offered table-mode compute_correlations, so a consumer migration
would either keep the computation in flaskapi or silently degrade to
correlating the training table (what superseded branch #537 did unnoticed).

- evaluate/funs_evaluate: correlate_manual_uq_samples -- the endpoint's
  sampling chain, with input_scales/output_scale REQUIRED (V45ls tripwire;
  no erfinv noise -- Pearson/Spearman run on the surrogate's own prediction).
- SumoSession.correlations: exact-cover guard + log flags via the existing
  _uq_engine_distributions (log requires uniform with min > 0).
- api.evaluate_correlations: one-shot workflow mirroring evaluate_uncertainty.
- CorrelationResult gains seed (default None; table mode unchanged).

Tests: dominant-variable recovery, seed reproducibility, log-mode movement,
guard rejections, TypeError tripwire, __all__ surface, flip matrix now over
all 11 entry points. Suite 365 passed; ruff/ty clean.

* docs(spec): T47mt + B18mt, V45ls entry count 11, V&V Category I9

B18mt records why the surface had a hole (T25dp landed only table-mode
correlation) so no future consumer migration re-degrades the endpoint.
V&V report: flip-matrix row says 11, new I9 for evaluate_correlations,
counts 359->365. TIER plan documents the new producer's contracts.

---------

Co-authored-by: Javier Garcia Ordonez <ordonez@zmt.swiss>
…ds (T48kw-T50vb) (#49)

* docs(spec): V46rn log-compose-normal + V47st boundary guards, B19ps, T48kw-T50vb opened

PR#47 review verdict: log scale must compose with normal distributions
(ln-space mu/sigma, lognormal raw draws) instead of being rejected, and
four scale-boundary guards shipped weaker than their docstrings claim.

Spec: V46rn, V47st, B19ps, tasks T48kw/T49dr/T50vb.

* T48kw: honour log scale with normal distributions (V46rn)

A log-scale normal now keeps its mean/std in ln space: raw draws are
exp(N(mu,sigma)) (lognormal, positive by construction) and the surrogate
sees exactly N(mu,sigma) in its training space -- the same contract the
log-uniform branch already honors. Reaching create_manual_uq_samples, the
Sobol ppf map (lognorm(s=sigma, scale=e^mu)) and the session boundary;
log+constant stays rejected.

Tests: 3 rejections flipped to behavior tests (Jensen direction on UQ
mean, Sobol decomposition shift, Pearson move), engine-level lognormal
draw test, flip matrix extended with a log-normal column over all 3
distributions-taking entry points. V&V I4/I7/I8/I9 + TIER plan wording
amended.

Closes T48kw (V46rn, V45ls, B19ps).

* T49dr: tighten scale/spec boundary guards (V47st)

Four fixes from the PR#47 review, all confirmed against the code:
- compute_correlation_indices now requires an input_scales entry per
  correlated variable (membership ValueError instead of the silent
  per-variable linear default that contradicted its docstring)
- compute_correlations / generate_lhs_samples / generate_grid_samples
  reject preprocessing overrides for columns not in play, matching the
  session path's exact-cover rule
- _uq_engine_distributions validates the log-uniform upper bound (present
  and above the lower bound) so the failure is a SumoInputError at the
  boundary, not a SumoEngineError surfacing from the engine
- optimize Pareto docstring corrected: a log objective fits in ln space
  but the front is reported exp-restored in original units

Closes T49dr (V47st, V45ls, V23er, B19ps).

* T50vb: reject inverted/degenerate spec bounds at construction (V47st)

DomainSpec and DistributionSpec now refuse maximum <= minimum in
__post_init__ with a SumoInputError, instead of letting an inverted box
surface as a silently descending log grid axis or a mid-engine MOGA
failure. One-sided DistributionSpec bounds stay constructible; shape-
specific requirements remain where the shape is interpreted.

Adds TestSpecValidation (contract tests) and V&V Category I row I10
covering the full V47st guard set.

Closes T50vb (V47st, V23er).

* chore(release): 0.1.0a6 -> 0.1.0a7

---------

Co-authored-by: Javier Garcia Ordonez <ordonez@zmt.swiss>
…51pq, T52xx) → 0.1.0a8 (#50)

* feat(api): exact arbitrary-d 2nd-order Sobol' pairs + order masses (T51pq)

Port mmux_vite T31rb (PR#649) replacing the v1 closed-form second-order
identity, which mmux_vite B26nc proved underdetermined for d>=4 (pair sums
collapse to 0/negative - B20qt) and non-invariant under f->f+c (B28pp).

- _saltelli_abc: A/B/C blocks from one 3*d scrambled stream (C feeds pairs)
- _saltelli_pair_designs: exact U^ij/V^ij mixed designs, cost n*(2+d+d(d-1))
- _sobol_algebra: scipy saltelli_2010 parity pinned by test; pooled mean/var,
  centered products -> translation-invariant; single estimator for all d
  (retires the d==1 branch and the runtime scipy call)
- _sobol_joint_bootstrap: ONE shared-row resample recomputes every index AND
  the M1/M2/R masses per replicate (covariance + closure preserved)
- api: OrderMasses dataclass + SobolResult.order_contributions, null exactly
  at zero sample variance (undefined fractions, not fake 0/0/0)
- tests: production-helper analytic benchmarks (additive d=8, pair-interaction
  d=5, Ishigami, pair-quadratic d=10) with 3xCI-scaled tolerances + B26nc
  degeneracy regression; SPEC V48tr/T51pq/B20qt, V9gh amended

Co-Authored-By: Qwen3.8 Flash Next NVFP4 (AWS vLLM) <noreply@anthropic.com>

* feat(api)!: domain⊥distribution split — evaluate_sobol samples the domain (T52xx)

V26dd landed early (owner call 2026-09-30: no defer). The Saltelli box
was being derived from modeller distributions — the exact conflation the
SPEC scope calls out. Sobol now speaks DOMAIN vocabulary end to end;
distributions stay the exclusive input of evaluate_uncertainty.

BREAKING CHANGE: evaluate_sobol(distributions=...) is gone; pass
domains: Mapping[str, DomainSpec] instead (or omit for the auto box).
SobolResult.distributions -> domains + fixed + effective_config.

- api: domains optional; unknown names -> SumoInputError; omitted boxes
  auto-inferred from observed bounds + detected scale; a column
  constant in the samples is pinned (never a fabricated box, V47st);
  log-scale domains positivity-guarded; draws uniform / log-uniform
  (V44ls) via the shared scale_distribution — normal-parameterized
  Sobol sampling dies with the mean±3σ artifact it descended from
- engine: evaluate_sobol_indices consumes the domain-sampling map
  ({minimum, maximum, log_scale?} | {value}); stale resolve_log_scale
  import dropped
- tests: explicit/auto/ghost-domain + narrow-box concentration +
  constant-column-pinned (real Dakota); NORMAL flip matrix loses its
  Sobol row by design (2 distribution entry points remain, asserted)
- docs: how-to/tutorials/reference rewritten to domain semantics; V&V
  gains I11 + estimator tier + M1/M2 gate rows; counts 387/26/14
- SPEC: V26dd enforced, T52xx, T27fr remaining = FE migration only

Co-Authored-By: Qwen3.8 Flash Next NVFP4 (AWS vLLM) <noreply@anthropic.com>

---------

Co-authored-by: Javier Garcia Ordonez <ordonez@zmt.swiss>
Co-authored-by: Qwen3.8 Flash Next NVFP4 (AWS vLLM) <noreply@anthropic.com>
…ocabulary (T53xx) (#51)

V26dd made the Sobol box domain-only, but the domain vocabulary had no way
to FREEZE a factor at a caller-stated value: constants existed only as
auto-inferred columns (constant in the samples). A consumer holding a
"pin this variable" UX (mmux_vite's Sobol panel migration) otherwise has no
faithful mapping — reusing a distribution's `constant` param is exactly the
conflation V26dd retires, a degenerate DomainSpec is V47st-rejected, and
pinning the caller's samples would silently change the surrogate fit.

- evaluate_sobol / SumoSession.sobol gain fixed: Mapping[str, float]:
  unknown names rejected, boxed∧fixed overlap per variable rejected,
  values guarded finite ∧ log-positive; the surrogate keeps the factor's
  real spread (pin applies to the sampling design only — legacy semantics)
- SobolResult.fixed now echoes explicit pins beside auto-inferred
  constants (inspectable, V21pf)
- SPEC: V26dd clause (explicit freeze ! fixed-value domain vocabulary),
  T53xx; V&V I11 extended
- version 0.1.0a8 -> 0.1.0a9

Co-authored-by: Javier Garcia Ordonez <ordonez@zmt.swiss>
Co-authored-by: Qwen3.8 Flash Next NVFP4 (AWS vLLM) <noreply@anthropic.com>
#52)

SumoSession.grid inverse-mapped the response key but not its companion:
the engine hangs the predicted-std column off the MAPPED response name
(y1_std), which passed the inverse mapping's unknown-key passthrough --
so GridResult.data carried y1_std for an underscored QoI. Consumers
look gridData[qoi + "_std"] up; the leak camelCases on the wire and the
lookup silently misses (caught by mmux_vite's V47pk route test).

- grid loop renames {mapped_response}_* companions to {response}_*
  (suffix kept) beside the plain response rename (V21pf)
- regression test: QoI renamed to max_abs_stress asserts no y1* leak
  and std companions subset of {max_abs_stress_std}
- SPEC B21ru; version 0.1.0a9 -> 0.1.0a10

Co-authored-by: Javier Garcia Ordonez <ordonez@zmt.swiss>
Co-authored-by: Qwen3.8 Flash Next NVFP4 (AWS vLLM) <noreply@anthropic.com>
…on → 0.1.0a11 (#54)

* feat(data+evaluate): port incubator CV diagnostics, coverage, convergence fits, scale selection (T48np)

Clean re-port of the still-unpromoted NIH-incubator tooling
(CONFIDENTIAL/nih-merck-validation) onto the log-scale/api era:
- data: select_variable_scale, auto_select_distributions
- evaluate: compute_coverage, compute_cv_diagnostics,
  fit_convergence_exponential(_asymptotic), bootstrap+draws+diagnostics
  redesign of compute_cv_convergence, mean_signed_error in CV metrics
- api CVAccuracyMetrics absorbs mean_signed_error
- propagate_uq_with_uncertainty deliberately NOT ported: the api-era
  propagate_manual_uq_with_uncertainty already covers it

Tests: NIH versions of test_funs_evaluate_cv_stats.py (superset) and
test_dakota_funs_data_processing.py additions, ruff-normalized.

(cherry picked from commit 35d2b9933aa26bffdbcc65ed1878eeac9a5313a3)

* feat(data): raw-value Tukey outlier detector + real analyze_dataset (T49np)

The 'does not exist yet, anywhere' gap from BRANCH_CONSOLIDATION.md §3:
- detect_raw_outliers: Tukey fence computed in the variable's SELECTED
  scale (geometric fence for log-selected variables -- arithmetic fences
  over-flag the benign right tail of multiplicative data), flag-only,
  NaN-excluded, fences reported in the values' own units
- analyze_dataset wired for real (was T18ry scaffold): auto scale/
  distribution + per-column outliers + optional candidate detail,
  dataclasses.asdict() JSON round-trip for the flaskapi boundary

Flip tests: geometric-vs-arithmetic over-flagging guard; ln<->log10
affine log-basis moves zero flags (V46np).

(cherry picked from commit 21a5a233e5e90f30f5a4da56dd6ab2adbd35d027)

* feat(report): itis_sumo.report facade for automated report notebooks (T54rp)

Report code (marimo report notebooks, tissue-conductivity LHS instance)
reached into itis_sumo.{api,data,evaluate.funs_evaluate} internals in
parallel; every engine refactor then forced coordinated report edits --
the report-authoring class of V16qf violations.

- new itis_sumo.report: flat curated surface (diagnostics, CV
  validation/calibration incl. T48np coverage/bootstrap/convergence
  fits, sensitivity/correlation, manual-UQ propagation); re-exports
  only, no logic
- contract test pins __all__ completeness + object identity to the
  source modules (tests/test_report_surface.py)
- SPEC: V49rp facade rule; T48np/T49np/T54rp land rows; T18ry unblocked
  (analyze_dataset real w/ this promotion); §I report row

Co-authored-by: Qwen3.8 Flash Next NVFP4 (AWS vLLM) <noreply@anthropic.com>

* chore: bump alpha version to 0.1.0a11

---------

Co-authored-by: Javier Garcia Ordonez <ordonez@zmt.swiss>
Co-authored-by: Qwen3.8 Flash Next NVFP4 (AWS vLLM) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…0, B22wk py3.14 fork-default, V50gm mp_context, V20qx/channel-policy amendments
…etire 3.10/3.11 (T55kd)

- first 6.24.x with win_amd64 wheels -> Windows becomes a supported platform
  (CI gains tests-windows leg, py3.14); crosses the 6.24.8 cp311 drop:
  requires-python >=3.12,<3.15, .python-version 3.13, CI matrix 3.12/3.13/3.14
  with the resolve warning-skip retired (broken lock now REDS)
- verified on real wheels BEFORE pinning: full 454-test suite green on
  3.12.10/3.13.7/3.14.8 incl. 26 analytical real-Dakota tests -> R5
  no-op-fork-interface shim (B16mo) holds on 6.24.13, no upstream fix needed
- B22wk: py3.14 flipped Linux multiprocessing default fork->forkserver;
  future_exec now pins an explicit mp_context (fork on POSIX, spawn on
  Windows) + requires_fork marker on the 3 mock-inheritance runner tests
  (V50gm)
- floor-flip cleanups V41hp predicted: datetime.UTC x2, PEP695 overload
  type params, typing_extensions/tomli fallbacks removed (deps + scripts +
  call sites --with tomli dropped)
- docs/README engine+py version sweep (had lagged two bumps at 1.5.9);
  dependabot ignore reason re-pointed at T55kd (V20qx guard updated)
- uv.lock re-resolved (uv 0.13.1, lock revision 5)
… promotion → 0.1.0a11 (#54)"

This reverts commit 44093a1.
Content stays the develop lineage: the 8 main-only commits are the diverged
old line — tests/test_ci_workflow.py was retired BY DESIGN there-equivalent
(SPEC B6nr, replaced by CI-side validation), dependabot/ci/publish files are
strictly newer here, setup-uv pins follow this lane's dependabot.
The verify job installs the built wheel; since T55kd the package requires
>=3.12, so the 3.11 pin made the a12 TestPyPI publish die at install.
@JavierGOrdonnez
JavierGOrdonnez merged commit 91fecc5 into main Oct 15, 2026
8 checks passed
@JavierGOrdonnez
JavierGOrdonnez deleted the release/0.1.0 branch October 15, 2026 09:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant