Medical-Event-Data-Standard / Medical-Event-Data-Standard/MEDS-DEV

Assess PATH/environment semantics of command execution (venv exposure, bare-name resolution, -m runnability)

Open
#323 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
43
Forks
10
PR merge metrics
No merged PRs in 30d

Description

MEDS-DEV's whole run model is configured shell commands, which makes it the most PATH-semantics-sensitive repo in the ecosystem. This issue requests an assessment; below is a concrete audit (@ 60b678c) to start from. Context: this came out of the MEDS-Extract 0.7 migration work (Medical-Event-Data-Standard/MIMIC_IV_MEDS#58), where the same class of problem produced Medical-Event-Data-Standard/MIMIC_IV_MEDS#51; companion issues: mmcdermott/MEDS_transforms#398, mmcdermott/MEDS_extract#155, mmcdermott/meds-torch-data#115.

1. A latent bug found during the audit (probably wants its own fix regardless)

utils.py:385-388run_in_env appends source $VIRTUAL_ENV/bin/activate to script_lines after script has already been joined, so the activation line never lands in the written cmd.sh. Venv exposure therefore rests solely on the PATH prepend at utils.py:348. (The dead line also hardcodes POSIX /bin/activate, cf. #316.) Notably, closed issue #99 — meds-tab console scripts not found on Clalit despite existing in the venv bin/ — is field evidence that the PATH-prepend-only mechanism breaks on some server setups, and this dead code may be why the intended belt-and-suspenders never engaged.

2. Same-environment dependencies invoked via ambient PATH (activation assumed)

These are console scripts of MEDS-DEV's own pinned deps, run with no env= at all — they resolve via whatever PATH the calling shell has, i.e. they require the install env to be activated and can silently cross-resolve when multiple envs exist:

  • tasks/__main__.py:34 — bare aces-cli (es-aces==0.6.1), shell=True
  • tasks/__main__.py:40 — bare expand_shards inside $(...) command substitution (silent mis-resolution here corrupts shard lists rather than failing)
  • evaluation/__main__.py:15 — bare meds-evaluation-cli (meds-evaluation==0.0.3)
  • utils.py:284uv located by shutil.which on ambient PATH even though uv is a declared runtime dependency

Candidate directions: interpreter-pinned invocation (sys.executable -m, pending guards in those packages) or an activation-equivalent PATH (prepend sysconfig.get_path("scripts") — the approach just adopted in Medical-Event-Data-Standard/MIMIC_IV_MEDS#62, which also propagates transitively to grandchildren).

3. Cross-environment commands (the deliberate case — different trade-offs)

Per-dataset/model venvs are exposed to YAML commands: exclusively via the PATH prepend in temp_env (utils.py:348). That's intentionally cross-env, so sys.executable does not apply — but given #99, consider resolving commands against the already-computed venv_bin_path absolutely (or at minimum verifying the expected scripts exist there before running) instead of trusting prepended-PATH resolution through bash/shell=True. Also in this bucket: bare python in models/cehrbert/model.yaml:13 and models/random_predictor/model.yaml:15 (the latter has no venv at all — plain ambient env — and -ms into MEDS_DEV itself, so it only works if the PATH-first python happens to have MEDS-DEV installed).

4. -m runnability of MEDS-DEV's own six console scripts

All six entry points live in package __main__.py files with no guard and no top-level call — so python -m MEDS_DEV.datasets (etc.) currently succeeds silently having run nothing (exit 0, no output), the worst failure shape. All are @hydra.main apps, so guards are trivial and Hydra-safe. One wrinkle: results/__main__.py hosts two entry points (pack_result, validate_result), so a single guard is ambiguous — needs an argv dispatch or a module split.

Suggested outcome

A decision per bucket: (1) fix the dead activation line or delete it deliberately; (2) pick interpreter-pinned vs. activation-equivalent-PATH for same-env deps; (3) harden cross-env command resolution (absolute venv_bin_path?) with #99 as the regression case; (4) add guards + a dispatch story for results. Happy to follow up with PRs once directions are chosen.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the audit at commit 60b678c, then inspect utils.py:284, 348, and 385-388, the task entry points in tasks/main.py, evaluation/main.py, and the package main.py files. Reproduce the silent python -m behavior and review the YAML commands in the two model files. Done means one documented decision and validated outcome for each of the four command-environment buckets, including the results dispatch case.

Written by the indexing model from the issue text.

Assessment

Tech stack
bash, python
Domain
devops, tooling
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.