Skip to content

BL-32: Contributor environment preflight check (dincli system doctor / scripts/preflight.sh) #245

Closed

Description

@robertocarlous

Summary

There is no single command that checks a developer's machine before they start work. Each of the following has already caused lost time:

  1. Python < 3.12 installed (repo requires >=3.12).
  2. forge / anvil not installed, or the wrong solc version (0.8.28 required).
  3. foundry/node_modules absent — without npm ci, forge test's parallel jobs race to fetch @openzeppelin/upgrades-core over npx into a shared cache, causing both test flakiness and unnecessary supply-chain exposure at test time (documented in CLAUDE.md).
  4. eth-account or py-multibase not importable in the active venv.
  5. torch not importable (needed by tests/ full run and the reference service files).
  6. .env / .env.<network> missing, the configured RPC endpoint unreachable, or resolve_ipfs_config() unable to resolve.

Proposal

A read-only preflight check — dincli system doctor (preferred, fits the existing subcommand structure in dincli/cli/system.py) or scripts/preflight.sh as a fallback — that runs one check per line:

[OK]      Python 3.12.6
[OK]      forge 0.3.2 / anvil 0.3.2
[OK]      solc 0.8.28 (via solc-select)
[OK]      foundry/node_modules present
[OK]      eth-account 6.3.0
[OK]      py-multibase 2.0.1
[MISSING] torch — run: pip install torch
[OK]      .env.sepolia_op_devnet found
[OK]      RPC https://... → chainId 11155420
[MISSING] IPFS_API_URL not set and no Filebase credentials — see Documentation/public/guides/ipfs.md

Exits non-zero on any MISSING or ERROR row. Never installs anything itself — reports and exits.

Usage

  • Primary: first command in the onboarding docs (Documentation/public/guides/getting-started.md).
  • Secondary: first step in ci.yml's unit-test job (can replace the current ad-hoc pip install + forge --version calls).
  • Optional local alias: make doctor.

Acceptance

  • All six check categories above pass on a clean machine.
  • Exits 0 when everything is OK, non-zero when any check fails.
  • Output is plain text, one line per check, usable in CI without color codes (--no-color flag or auto-detect).
  • Documentation/public/guides/getting-started.md references the command.

References

  • Developer/BACK_LOG.md BL-32
  • CLAUDE.md — npm ci warning (§ Solidity)
  • Preflight pattern reviewed in Osomudeya/devops-scripting-labs (2026-10-02)

Activity

  1. umeradl commented on Oct 14, 2026

    @umeradl
    Member

    Approval review: Approved with amendments

    Verified against origin/develop @ 6e361cb.

    Claims

    Claim Result Evidence
    Repo requires Python >= 3.12 ✅ pyproject.toml requires-python
    npm ci race in foundry/ ✅ CLAUDE.md § Solidity
    No existing doctor/preflight ✅ The only "preflight" in dincli/cli/system.py is the bridge tx preflight
    eth-account / py-multibase may be missing ⚠️ Both are declared in pyproject.toml dependencies on develop, so pip install -e . installs them. They can only be missing from a broken venv
    solc via solc-select ❌ Foundry manages solc itself (solc = "0.8.28" in foundry.toml, auto-installed by forge). solc-select isn't part of the toolchain
    Onboarding doc at Documentation/public/guides/getting-started.md ❌ The file is Documentation/public/getting-started.md
    CI's unit-test job has ad-hoc pip install + forge --version that this can replace ❌ .github/workflows/ci.yml: forge --version (:51) is in the Solidity job and records the toolchain. The Python job (:107) has no forge. The pip install steps install things, and a read-only check can't replace that

    Merit

    This is useful, small, and saves onboarding time. One design point first: a dincli system doctor command can't run in the cases it's meant to catch. If the Python version is wrong or the venv is broken, dincli itself won't import.

    Amendments

    1. Write it as a stdlib-only scripts/preflight.py (or .sh) that runs before pip install, not as a dincli subcommand. It can optionally call into dincli for the network checks once the import works.
    2. Mark torch as WARN (optional), not MISSING. It's in the test extra, and the torch tests skip without it.
    3. Put the network checks (.env.<network>, RPC chainId, resolve_ipfs_config()) behind a --network flag. A fresh clone and CI have no .env, so by default they would always fail.
    4. Drop "replace CI steps". At most, add it as an advisory step after install, or leave CI out of scope.
    5. Fix the doc path (amendment target: Documentation/public/getting-started.md). Add a short test that runs the script with a missing tool on PATH and asserts a non-zero exit.

    Conflicts

    PR No. 72 touches Documentation/public/getting-started.md (your own PR). That's a small overlap, and none if the script stays out of dincli/cli/system.py.

  2. added
    ApprovedIssue plan verified and approved by maintainer (din-approve-issue)
    on Oct 14, 2026
  3. added a commit that references this issue on Oct 27, 2026
  4. umeradl commented on Oct 29, 2026

    @umeradl
    Member

    Status update: implemented vs pending

    PR #255 (scripts/preflight.py, merge commit 06c0af5) delivered most of this issue. #275 was closed as a duplicate of this issue, so its spec is folded in here. Checked against develop @ f2cff58.

    Implemented

    Item Where / how
    Stdlib-only scripts/preflight.py that runs before pip install (amendment 1) scripts/preflight.py
    Python ≥ 3.12 [MISSING] + exit 1
    forge / anvil on PATH [MISSING] + exit 1, with a foundryup hint
    foundry/node_modules present checked, [WARN] + npm ci hint
    eth-account / py-multibase / web3 importable checked, [WARN] + pip install -e . hint; import-time OSError doesn't abort the run
    torch optional (amendment 2) [WARN] + pip install -e .[test] hint
    Network checks behind --network (amendment 3) <NETWORK>_RPC_URL read from os.environ then .env in the current directory (same lookup as dincli); eth_chainId call with chain-ID mismatch warning; resolve_ipfs_config() validated per provider; unknown provider warns
    Credential-safe output RPC URLs sanitised, exception text never printed
    Read-only, plain one-line-per-check output [OK] / [WARN] / [MISSING], no colour codes
    CI left out of scope (amendment 4) —
    Docs (amendment 5) Preflight section in Documentation/public/getting-started.md
    Regression tests (amendment 5) tests/test_preflight.py, including missing-tool → exit 1

    Not needed (decided in the reviews): a solc 0.8.28 check, because forge installs solc itself (approval review); a .env.<network> existence check, dropped in the PR 255 review because dincli reads .env from the current directory.

    Pending

    The spec says any failed check exits non-zero. Today only Python and forge/anvil do. These print [WARN] and still exit 0:

    1. foundry/node_modules missing (forge test then races fetching @openzeppelin/upgrades-core over npx)
    2. eth-account / py-multibase not importable. Both are core dependencies, so a failure means a broken venv
    3. With --network: RPC unreachable (the code currently says "never a hard failure"), and resolve_ipfs_config() unresolved. A --network run means the user asked for these checks, so a failure should fail the run.

    Keep the import-error handling that lets the run continue, and keep torch optional. Only the exit code changes for these items, plus the "Exits 0 when…" line in getting-started.md. Add a regression test for each.

    Optional: full dotenv parity with dincli's .env parsing (follow-up noted in the PR 255 merge proposal).

    Leaving this open for the pending items. They're small and suit a first contribution.

  5. added a commit that references this issue on Oct 29, 2026
  6. umeradl commented on Nov 2, 2026

    @umeradl
    Member

    Done by PR No. 255, merged into develop as 06c0af5, and PR No. 303, which closed the remaining exit-code items, merged as e25df81 (develop CI green). PR No. 303 said "Part of" this issue, so nothing closed it automatically.

    Checked on origin/develop @ cf80216:

    • Amendment 1 (stdlib-only script that runs before pip install): scripts/preflight.py, not a dincli subcommand.
    • Six check categories: Python ≥ 3.12, forge/anvil on PATH, foundry/node_modules, core imports (eth-account, py-multibase, web3), torch, and with --network the RPC eth_chainId and resolve_ipfs_config().
    • Exits non-zero on any failed check (the three items pending in the Oct 29 status update): all fixed by PR No. 303.
      • A missing foundry/node_modules now prints [MISSING] and fails (_check_node_modules returns 1).
      • A core package that won't import now fails (_check_importable returns 1 unless the package is optional). An import OSError still doesn't abort the run.
      • With --network, an unreachable RPC or an invalid response fails, and so does missing or incomplete IPFS config. An unexpected chain ID stays a warning.
      • main exits 1 when failures is non-zero.
    • Amendment 2 (torch optional): [WARN] with an pip install -e .[test] hint, and it doesn't fail the run.
    • Amendment 3 (network checks opt-in): they run only with --network.
    • Amendment 4 (CI out of scope): ci.yml doesn't call it.
    • Amendment 5 (docs and test): Documentation/public/getting-started.md has the "Environment Preflight Check" section, and its exit-code text matches the new behaviour. tests/test_preflight.py (26 test functions) covers the missing-tool → exit 1 case and each new required check.
    • Plain output: [OK] / [WARN] / [MISSING], one line per check, no colour codes. RPC URLs are sanitised in the output.

    Dropped in the reviews, not gaps: a solc check (forge installs solc itself) and a .env.<network> existence check (dincli reads .env from the current directory). Optional follow-up from the PR No. 255 merge proposal, not tracked in an issue yet: full dotenv parity with dincli's .env parsing. Issue No. 275 was closed as a duplicate of this one, and its spec is covered by the items above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

ApprovedIssue plan verified and approved by maintainer (din-approve-issue)enhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions