Your test should be contained in a single program ? why ?
First, I don’t recommend the use of program blocks, just use a module. See Are Program Blocks Necessary? - Verification Horizons
What this really means is that when you run a simulation, only a single process can determine when the test is over, and whether the test passed or failed. It may be easy to think when you discover an error, to shut the simulation, but the harder part is when to end the test when it is passing. That does not mean you cannot have other modules generating or responding to activity independently, but, with the UVM, only one thread can call run_test() to start the teat, ant it will end the test after collecting information from all other activities to determine when it is OK to end the test.