4. Before releasing
A change to core is safe only if mathx and app still build and pass their tests with it. check tries exactly that, before anything is committed or released: it copies each dependent into a scratch directory, puts core's working copy in place of the fetched one, and runs the dependent's checks (its fobos [ecosystem] check commands; the demo's build and run the test program).
$ fobis ecosystem check core
Checking mathx, app against the local working copy of core
==> mathx: (fobis build --quiet) && (./build/test_mathx)
Building src/test_mathx.f90
Compiling third_party/core/src/core_m.f90 serially
Compiling src/mathx_m.f90 serially
Compiling src/test_mathx.f90 serially
Linking build/test_mathx
Target src/test_mathx.f90 has been successfully built
mathx: all tests passed
==> app: (fobis build --quiet) && (./build/app)
Building src/app.f90
Compiling third_party/core/src/core_m.f90 serially
Compiling third_party/mathx/src/mathx_m.f90 serially
Compiling src/app.f90 serially
Linking build/app
Target src/app.f90 has been successfully built
twice(3) = 6.0 quadruple(3) = 12.0
Project Result Time Detail
mathx passed 0.2s
app passed 0.3s
2 passed, 0 failedNow a change that breaks the others: twice renamed double in core, not committed.
$ git -C core diff --stat
src/core_m.f90 | 6 +++---
src/test_core.f90 | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)What the change breaks
impact compares the public interface of core's modules with the last release, and finds the code of the dependents that uses what changed, without building anything:
$ fobis ecosystem impact core
core: public API changes since v1.0.0
added procedure core_m::double (src/core_m.f90:6)
added procedure core_m::halve (src/core_m.f90:12)
BREAKING removed procedure core_m::twice (src/core_m.f90:6)
mathx: affected
src/mathx_m.f90:2: use core_m, only: twice [changed: twice]
src/mathx_m.f90:10: twice: y = twice(twice(x))
app: affected
src/app.f90:2: use core_m, only: twice [changed: twice]
src/app.f90:5: twice: print '(A,F5.1,A,F5.1)', "twice(3) =", twice(3.0), " quadruple(3) =", quadruple(3.0)
1 breaking change(s); 2 of 2 dependent project(s) affected.
[exit status 1]- A removed or changed public entity is a breaking change; an added one is not.
- A dependent is affected only when its code refers to a changed name (a plain
useof the module is not enough).
Proof by building
$ fobis ecosystem check core
Checking mathx, app against the local working copy of core
==> mathx: (fobis build --quiet) && (./build/test_mathx)
Building src/test_mathx.f90
Compiling third_party/core/src/core_m.f90 serially
Compiling src/mathx_m.f90 serially
src/mathx_m.f90:2:19:
2 | use core_m, only: twice
| 1
Error: Symbol 'twice' referenced at (1) not found in module 'core_m'
src/mathx_m.f90:10:14:
10 | y = twice(twice(x))
| 1
Error: Function 'twice' at (1) has no IMPLICIT type
src/mathx_m.f90:10:14:
10 | y = twice(twice(x))
| 1
Error: Reference to impure function 'twice' at (1) within a PURE procedure
==> app: (fobis build --quiet) && (./build/app)
Building src/app.f90
Compiling third_party/core/src/core_m.f90 serially
Compiling third_party/mathx/src/mathx_m.f90 serially
third_party/mathx/src/mathx_m.f90:2:19:
2 | use core_m, only: twice
| 1
Error: Symbol 'twice' referenced at (1) not found in module 'core_m'
third_party/mathx/src/mathx_m.f90:10:14:
10 | y = twice(twice(x))
| 1
Error: Function 'twice' at (1) has no IMPLICIT type
third_party/mathx/src/mathx_m.f90:10:14:
10 | y = twice(twice(x))
| 1
Error: Reference to impure function 'twice' at (1) within a PURE procedure
Staged copies kept in ~/tmp/fobis-check-core-lsrgeosw
Project Result Time Detail
mathx failed 0.2s exit 1
app failed 0.2s exit 1
0 passed, 2 failed: mathx, app
[exit status 1]The staged copies are kept when a check fails, to look at; the projects themselves were not touched.

The demo ecosystem of this track: core, mathx, app.
What you learned
fobis ecosystem check PROJECT (dependents built against your working copy) and fobis ecosystem impact PROJECT (which public names changed, and who uses them).
Next: 5. Shared boilerplate.