nirs4all-core → dag-ml migration — war room

Status: groundwork / prep phase (no code migration started). Production nirs4all is untouched and stays untouched. This folder is the consolidated study + plan so it never gets lost again. Assembled 2026-06-23 from a full multi-agent recon of every migration doc across the ecosystem (15 clusters, 83 docs classified).

Goal of the chantier: make dag-ml (Rust + C-ABI reproducible DAG coordinator) the real execution core of the production Python library nirs4all, without breaking the frozen 0.9.x/0.10.x public surface and without disturbing the production main.

This is an index + synthesis, not a copy dump. Every source doc is referenced at its canonical home (cross-repo docs use repo:path notation, dag-ml docs use relative links) so nothing drifts. Companion proposals live next to this file:

  • WORKING_STRATEGY.md — how to develop the migration while keeping prod alive (repo / branch / worktree / backend-selector). Answers ask #3.

  • PARITY_AND_PERF_HARNESS.md — how to guarantee non-regression (parity) and measure performance, automated. Answers ask #4.


TL;DR readiness verdict

dag-ml 0.2.0 is ready to back the nirs4all control plane, not yet to run production numerics. It is a closed, CI-gated, contract-frozen Rust coordinator built for exactly this problem (reproducible, OOF/leakage-safe, identity-keyed DAG coordination). It already implements every coordination capability the migration needs. By deliberate design it never touches feature matrices — all NIRS numerics must be supplied by nirs4all as host controllers, and today the only production host adapter is sklearn.

The migration is therefore mostly a nirs4all-side decoupling + bridging job, not a “finish dag-ml” job.


The map — where the prepared study actually lives

Read these three tiers in order. Tier 3 is a trap: it is parallel design, not the plan.

Tier 1 — Authoritative migration design (dag-ml side) — plan against these

Doc

Rel.

Status

Why it matters

../COORDINATOR_SPEC.md

★★★

current

Normative product contract; has an explicit “Confrontation With Current nirs4all Pipeline” + migration map. The alignment source of truth.

../CAPABILITY_MATRIX.md

★★★

current

States outright the goal is to replace the nirs4all core engine; per-feature responsibility map + 4-stage MVP→replacement path.

../design/DSL_NIRS4ALL_PARITY.md

★★★

local design-source

Live acceptance criterion: maps every nirs4all construct → dag-ml NodeKind, importer status, gaps/regression list.

../STATUS.md

★★★

local-only current*

Authoritative ledger of what’s implemented in 0.2.0 vs backlog.

../SUPPORTED.md

★★★

current

Per-area Supported / Conformance / Experimental / Backlog — what you may depend on as production.

../HOST_ADAPTER_BACKLOG.md

★★★

local-only current*

Defines the process-adapter JSONL wire protocol nirs4all must implement; confirms sklearn adapter shipped.

../MVP_ACCEPTANCE.md

★★★

local-only current*

dag-ml ↔ dag-ml-data ownership boundary + UC6/UC11 acceptance the MVP must satisfy.

../TEST_PLAN.md

★★★

local-only current*

Most complete inventory of what dag-ml validates today; the ledger to diff nirs4all behaviour against.

../ABI.md

★★★

current

Full C-ABI surface (vtables, ownership, Arrow boundaries) — the in-process/WASM host path.

../ROADMAP.md / ../FINAL_RELEASE_AUDIT.md

★★

local-only current*

Phase status + 0.2.0 release verdict + green-gate command sequence.

../HETEROGENEOUS_MULTISOURCE_REPETITIONS_ROADMAP.md

★★★

local-only current*

Phased D0–D10 roadmap for the NIRS-critical shared-target-multi-spectra feature.

../PERFORMANCE.md

★★

current

Perf is only sanity-probed, not benchmarked — a named cutover risk (see harness doc).

../ARCHITECTURE.md / ../AGGREGATION_INTEROP.md / ../OOF_FIXTURES.md / ../STUDIO_LITE_WASM_GAPS.md

★★

mixed

Crate map, reducer interop, canonical OOF fixtures, remaining execution gaps. STUDIO_LITE_WASM_GAPS.md is local-only.

ADRs — framed as Phase-0 of the nirs4all integration (../adr/README.md):

ADR

Role in the migration

ADR-17 cutover-rollback

The migration-strategy ADR: backend selector (legacy | dag-ml | dual), dual-run diff within tolerance, zero-cost rollback.

ADR-01 compatibility-ledger

Defines “no regression” = the compatibility ledger + per-model-class numeric tolerance table the dual-run must satisfy.

ADR-02 schema-evolution-sla

Additive-then-promote SLA + bundle-readability guarantee → never orphan existing .n4a.

ADR-14 deprecation-policy

Managed-debt exception legitimizing legacy-path / dual-read shims during the window (⚠ conflicts with nirs4all’s no-shims rule — see open decisions).

ADR-10 release-train

Scripted dag-ml-data → dag-ml → nirs4all release ordering the rollout rides.

ADR-05 repetition-cv-invariant · ADR-11 error-taxonomy

Leakage invariant the bridge can’t drop · typed error substrate.

ADR-03/04/06/07/08/13/15/16/19

Per-feature semantics the bridge must reproduce (branches, tag/exclude masks, signal-type, reducers, sessions, process-adapter security, GIL/async, artifact security, multisource units).

Archived design-source (historical but richest code-level orders) — ../design/source/_archive/: dag_ml_specification_v1.md §19 = 10-step migration plan; dag_ml_externalization_from_code.md = 9-step extraction order from the live nirs4all engine; dag_ml_use_cases.md = Annexe-A DSL→NodeKind acceptance table.

*current* = the doc is part of the “kept-locally / untracked” set in dag-ml/.gitignore (lines 23–32). It exists on disk here but is not committed to dag-ml. See open decision #7.

Tier 2 — nirs4all side: what we migrate from + the executable gate

Doc (repo:path)

Rel.

Why it matters

nirs4all:docs/_internal/specifications/heterogeneous_multisource_repetitions.md

★★★

The single most migration-relevant nirs4all-side doc: reviewed cross-repo co-design with shared contracts, ownership split, phased N0–N8 / D0–D6 roadmaps.

nirs4all:docs/_internal/god_classes_modularization.md

★★★

Decomposition backlog for the 12 >2k-line god classes (orchestrator / merge / branch / base_model / workspace_store / predictions / dataset) that own OOF/refit/branch-merge/storage — prerequisite to crossing the ABI.

nirs4all:docs/_internal/prediction_to_pipeline.md

★★★

Existing replay / chain / expanded_config / trace / bundle round-trip + its gaps — maps onto dag-ml’s replay/lineage mandate.

nirs4all:docs/source/developer/architecture.md

★★★

Canonical description of the production core being migrated FROM: Orchestrator→Executor→StepRunner→controllers over a mutable SpectroDataset.

nirs4all:docs/_internal/lib_ML/NIRS4ALL_porting.md

★★

File-by-file generic-vs-NIRS boundary map; names the SpectroDataset.x() / wavelength-injection hotspots any core swap must solve. (Targets “pipeforge”, not dag-ml — boundary input only.)

nirs4all:tests/integration/parity/ (README + _registry.py + cases_*.py + test_parity_smoke.py)

★★★

The executable gate — see PARITY_AND_PERF_HARNESS.md. ~35 frozen cases; explicitly “the contract the future dag-ml backend must reproduce”.

Tier 3 — Parallel designs — donor/parity input only, NOT the plan

These never reference dag-ml; they independently reinvent large parts of it. Treat as a requirements / parity inventory (“what must be preserved”), never as the architecture to build.

Doc (repo:path)

What to harvest

Why it’s not the plan

nirs4all:docs/_internal/nirs4all_v2_design/00..05 + virtual_data_management_design.md

Feature-Preservation Matrix, identity schema, node taxonomy, leakage edge cases, numerical-equivalence harness (r²±0.001), public-surface checklist

A Dec-2025 pure-Python ground-up rewrite. Keys folds by row position (dag-ml rejects this). Internally self-contradictory on backward-compat.

nirs4all:docs/_internal/lib_ML/ML_lib_design.md

Generic-core stays/moves boundary map

A third parallel design (“pipeforge”, generic Python core).

Cross-repo integration contracts (adjacent, not core)

dag-ml-data:docs/ADR-0001-nirs4all-connector-ownership.md · nirs4all-methods:docs/nirs4all_integration_map.md (per-class PLS/model → libn4m swap; largely blocked today) · nirs4all-core:docs/PARITY.md (full-Python nirs4all = oracle of record) · nirs4all-formats:docs/INTEGRATION_NIRS4ALL.md (leaf readers, no dag-ml content).


Suggested reading order (first day on the chantier)

  1. ../CAPABILITY_MATRIX.mdwhat dag-ml takes over, feature by feature.

  2. ../COORDINATOR_SPEC.md (the nirs4all confrontation section) — how it maps.

  3. ../design/DSL_NIRS4ALL_PARITY.mdexactly which DSL constructs are covered / gapped.

  4. ../adr/ADR-17-cutover-rollback.md + ../adr/ADR-01-compatibility-ledger.md — the safety strategy.

  5. ../STATUS.md + ../SUPPORTED.md + ../HOST_ADAPTER_BACKLOG.md — what’s real today + the wire protocol.

  6. nirs4all:tests/integration/parity/README.md + _registry.py — the gate.

  7. nirs4all:docs/_internal/god_classes_modularization.md — the decoupling work.

  8. ../design/source/_archive/dag_ml_externalization_from_code.md §(9-step) + dag_ml_specification_v1.md §19 — the detailed extraction order.


dag-ml readiness (the honest ledger)

Ready (control plane): full COMPILE→PLAN→FIT_CV→SELECT→REFIT→PREDICT→EXPLAIN with deterministic scheduling; nirs4all-compatible JSON DSL importer (list/dict pipelines, _or_/_cartesian_/_chain_/_grid_/_range_/_log_range_/_zip_/_sample_, branch/merge/split/sources); identity-keyed FoldSet + OOF-join-by-sample-id + leakage refusal by default (UC6/UC11 as conformance fixtures); deterministic variant generation/selection with fingerprints; replay bundles + provenance (RO-Crate / PROV / OpenLineage); C-ABI + process-adapter JSONL path with a shipped sklearn adapter; heterogeneous multisource conformance pack (D8/D9).

Gaps blocking core migration:

  1. No Python-object/YAML frontend — the Rust importer eats serialized JSON; nirs4all must serialize live pipeline objects / splitters / sklearn instances to portable descriptors (today operator_class is a short name, lossy for live instances).

  2. No production host controllers beyond sklearn — all 42 nirs4all model estimators currently route through process adapters; the nirs4all-methods/libn4m swap is a separate, largely-blocked effort.

  3. Production data-provider path incomplete — multi-node graphs need per-node dag-ml-data provider wiring; host-filtered branch_view modes (by_metadata/by_tag/by_filter) not yet production.

  4. Performance unmeasured — only two ignored ~1.5 s sanity probes; no throughput/memory/end-to-end campaign benchmarks; per-task JSONL process-adapter overhead is the biggest unknown at nirs4all scale.

  5. nirs4all-side decoupling not doneSpectroDataset.x() + TransformerMixinController wavelength injection hotspots + the 12 god classes must be split along the dag-ml ownership seam.

  6. Parity oracle is a scaffold — no captured gold baseline, tolerances recorded but unenforced, no dag-ml backend hook wired in yet.

  7. Cross-repo reducer-vocabulary driftrobust_mean/exclude_outliers exist data-side only; must reconcile on the ADR-10 release train.


Open decisions — only the maintainer can make these (see proposals for recommendations)

  1. Destination — dag-ml directly as the new core (recommended; per CAPABILITY_MATRIX/COORDINATOR_SPEC) vs the intermediate generic “pipeforge” Python lib vs the v2_design pure-Python rewrite. Pick one; retire the other two (or mark parity-input-only) before any decomposition.

  2. Mechanism — process-adapter JSONL (only stable cross-language path today, per-task overhead) vs in-process C-ABI / a future PyO3 binding. Gates the GIL/async (ADR-15) + perf work.

  3. Backward-compat posture — sanction ADR-14 “managed-debt” shims for the migration window (conflicts with nirs4all/CLAUDE.md’s absolute no-shims rule)?

  4. Sequencing — god-class decomposition + gold-baseline capture before the bridge, or in parallel? (Externalization notes recommend extract-protocols-first.)

  5. v1 scope — basic surface (baseline + linear/branch/merge/stacking/generators) only, or include heterogeneous multi-source repetitions (N0–N8/D0–D6) from day one?

  6. Numerics ownership — run nirs4all operators as-is via the sklearn process adapter, or pursue the nirs4all-methods/libn4m swap concurrently?

  7. Tracked vs local docs — several dag-ml core docs are gitignored/local-only (.gitignore 23–32). Commit them (so the migration plan is versioned), or keep local?

  8. Perf gate — acceptable end-to-end overhead vs legacy (ADR-17 dual-run) before flipping the default backend?


Recon provenance: 5f20f507…/tasks/w3tix7niq.output (full structured synthesis), 2026-06-23.