Try to reload like this:

set importlib = ##class(%SYS.Python).Import("importlib")
do importlib.reload(helloWorld)

Also, it not an IRIS-specific behavior, you'll get the same results in any python interpreter:

import helloWorld
helloWorld.helloWorld()
>'Hello world'
del helloWorld

# modify helloWorld.py in text editor

import helloWorld
helloWorld.helloWorld()
>'Hello world'

1. Yes. Stopping primary makes backup a new primary. Before stopping you might want to validate that backup is caught up:

set sql = "SELECT CASE WHEN DatabaseLatency=? THEN 1 ELSE 0 END IsCaughtUp FROM SYS.Mirror_MemberStatusList() WHERE CurrentRole = ?"
set rs = ##class(%SQL.Statement).%ExecDirect(,sql, "Caught up", "Backup")
do rs.%Next()
if rs.IsCaughtUp {
	write "Caught up"
	halt
} else {
	write "Not caught up"
	do $system.Process.Terminate(,1)
}

Or at least is not too far behind (check this post).

2.  No. ^MIRROR does the same.

There's a distinction between Background Jobs and Background Tasks.

Backgound job is anything you run using JOB command. Background Task is a limited set of named actions (AuditCopy, AuditExport, AuditPurge, Backup, CompactDBSpace, CopyNamespaceMappings, CreateDatabase, Compile, DatabaseIntegrityCheck, DataMigration, DefragmentDB, Delete, EnableEnsNamespace, Export, ExternalLangServers, FileMan, Import, SQLExport, SQLImport, SQLExportStatement, SQLImportStatement, QueryExport, JournalIntegrityCheck, LinkTable, LinkProcedure, MirrorActivateCatchupDB, MirrorRemoveDB, MirrorMountDB, MirrorAddDatabases, ModifyDatabaseSize, RebuildIndices, TuneTable, TuneTables, PurgeAllCachedQueries, JobShowPlan, JobSaveQuery, JobPossiblePlans, JobComparePlans, ShardActivate, ShardAssign, ShardVerify, ShardRebalance) runnable through a special interface. Docs.

You can run a Background Task (but probably should not  - it's a system action) by calling:

set parms("ClassName") = "Sample.Person"
set tSC = ##class(%CSP.UI.System.BackgroundTask).RunTask("RebuildIndices", "SAMPLES", .parms, .job)

As HIHLib.Support.GetHL7MessageStat:ISBListingQuery is not on the list you can't run it as a Background Task, but you can run it as a Job.

Next - no output. Note that you do not specify these parameters:

principal-input Principal input device for the process. The default is the null device.
principal-output
Principal output device for the process. The default is the device you specify for principal-input or the null device if neither device is specified.
UNIX®: If you do not specify either device, the process uses the default principal device for processes started with the JOB command, which is /dev/null.

Further:

Only one process can own a device at a time. This means that a job executing in a JOB Server is unable to perform input or output to your principal I/O devices even though you may close device 0.

So by default you run your job with stdio set to /dev/null and that's why there's no output.

You can either pass a device to write output to or write a wrapper which would handle the output and job that.

Users certainly should not be able access Ens_Config.Credentials table, maybe some user has permissions too broad?

What you can do additionally is to store credentials in a separate SECONDARY database. When you create a new interoperability namespace (in non HS installs), it should be created automatically. Still, you can manually create this DB and related mappings by calling CreateNewDBForSecondary.

After creating secondary db, check that no one has R on DB resouce.

Additionally you can encrypt the db file.

Sure. There are two ways:

1. Switch to another namespace to execute your query:

/// Get a list of all mirrored databases as a $lb()
ClassMethod GetMirroredDBs() As %List
{
    new $namespace
    set $namespace = "%SYS"
    set sql = "SELECT LIST(Name) dbs FROM Config.Databases_MirrorDatabaseList()"
    set rs = ##class(%SQL.Statement).%ExecDirect(,sql)
    do rs.%Next()
    set dbs = $lfs(rs.dbs)
    kill rs
    quit dbs
}

Now you can have this method in USER namespace and it would automatically swith into %SYS, execute query, iterate over the results, write results into a local variable, switch back into USER namespace and return the value back to you.

The main thing you need to remember is that result set iteration MUST happen in a target namespace.

2. Map classes and globals to your namespace. Docs. Table would be available as if it was created in your original namespace.

Say you have this query:

SELECT a, b, c
FROM mytable
WHERE d=1 AND e=2

If you want to change fields in SELECT or WHERE, you'll need to rewrite your query by adding or removing it's parts. Source control diff would also show a whole line change.

But if you write it like this:

SELECT 1
  , a 
  , b 
  , c
FROM mytable
WHERE 1=1
      AND d=1 
      AND e=2

You can comment out any field or condition simply by adding --:

SELECT 1
  --, a 
  , b 
  , c
FROM mytable
WHERE 1=1
      --AND d=1 
      AND e=2

when you have a lot of conditions and need to iterate fast, this way of writing queries is much better for debugging and source control since diff is always contianed to the one line you edit.

Ens, EnsLib and EnsPortal are system packages, developes can subclass them.

To get class count call something like this:

SELECT 
  count(ID)
FROM %Dictionary.ClassDefinition
WHERE 1=1 AND
      System = 0 AND 
      NOT (Name %STARTSWITH '%' OR 
           Name %STARTSWITH 'Ens.' OR 
           Name %STARTSWITH 'EnsLib.' OR 
           Name %STARTSWITH 'EnsPortal.' OR 
           Name %STARTSWITH 'HS.' OR 
           Name %STARTSWITH 'SchemaMap')

Missing: SQL way to filter out mapped classes.

Use a Business Service with a basic Ens.InboundAdapter:

Class test.BS Extends Ens.BusinessService
{

Parameter ADAPTER = "Ens.InboundAdapter";

Method OnProcessInput(pInput As %RegisteredObject, Output pOutput As %RegisteredObject) As %Status
{
	$$$LOGINFO("In OnProcessInput")
	Quit $$$OK
}

}

Add it to production and set Call Interval to X seconds (and Pool Size to 1). That would ensure OnProcessInput being called every X seconds after it's last completion.