And to answer your question, when you simply restart the Primary Linux server, the Backup member is automatically switching to become primary.

Below the messages.log from the Backup member while the Primary is restarting.

07/09/24-12:05:49:781 (6502) 0 [Utility.Event] DejournalProcessor: Applying journal data for mirror "MIRROR" starting at 0 in file #7(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.007)
07/09/24-12:05:50:953 (6508) 0 [Utility.Event] Applying journal data for mirror "MIRROR" starting at 200088 in file #7(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.007)
07/09/24-12:05:51:076 (6362) 0 [Utility.Event] Retrieving journal file #7 for mirror MIRROR from 192.168.102.130|2188...(repeated 1 times)
07/09/24-12:05:51:076 (6362) 0 [Utility.Event] GetECPSessionData: Got ECP data from agent len=1
07/09/24-12:05:51:076 (6362) 0 [Utility.Event] Manager initialized for MIRROR
07/09/24-12:05:51:185 (6362) 0 [Utility.Event] Found UBUNTU/IRIS as primary, becoming backup
07/09/24-12:05:51:186 (6362) 0 [Utility.Event] (MIRROR) Becoming a backup mirror member
07/09/24-12:05:51:445 (6510) 0 [Utility.Event] (MIRROR) Starting Mirror.Client("MIRROR-MIRROR-20240709.007",200088,7)
07/09/24-12:05:51:448 (6510) 0 [Generic.Event] MirrorClient: Connected to primary: UBUNTU/IRIS (ver 4)
07/09/24-12:05:51:458 (6512) 0 [Utility.Event] Arbiter connection established (192.168.102.1:2188)
07/09/24-12:05:52:737 (6510) 0 [Generic.Event] MirrorClient: Switched from Agent Controlled to Arbiter Controlled failover on request from primary
07/09/24-12:05:56:740 (6510) 0 [Generic.Event] MirrorClient: The backup node has become active from a status query
07/09/24-12:05:59:766 (6517) 0 [Utility.Event] Journal File Compression: Compressed /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.006 from 262144 bytes to 81920 bytes, compression ratio = 3.2
07/09/24-12:06:17:920 (6377) 0 [Utility.Event] [SYSTEM MONITOR] Mirror status changed. Member type = Failover, Status = Backup
07/09/24-14:31:54:643 (6512) 2 [Utility.Event] Arbiter connection lost
07/09/24-14:31:55:304 (6362) 0 [Utility.Event] Skipping connection to arbiter while still in Arbiter Controlled failover mode.
07/09/24-14:31:55:419 (6510) 0 [Generic.Event] MirrorClient: Switched from Arbiter Controlled to Agent Controlled failover on request from primary
07/09/24-14:32:25:437 (6584) 0 [Utility.Event] Arbiter connection established (192.168.102.1:2188)
07/09/24-14:32:28:235 (6510) 0 [Generic.Event] MirrorClient: Switched from Agent Controlled to Arbiter Controlled failover on request from primary
07/09/24-14:33:11:438 (6510) 1 [Generic.Event] MirrorClient: Primary AckDaemon failed to answer status request.
07/09/24-14:33:11:438 (6510) 0 [Generic.Event] MirrorClient: Backup waiting for old Dejournal Reader (pid: 6511, job #28) to exit
07/09/24-14:33:12:250 (6510) 0 [Generic.Event] MirrorClient: Set status for MIRROR to Transition
07/09/24-14:33:12:254 (6362) 0 [Utility.Event] Backup taking over for primary in arbiter controlled mode
07/09/24-14:33:12:304 (6589) 0 [Utility.Event] Applying journal data for mirror "MIRROR" starting at 356088 in file #7(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.007)
07/09/24-14:33:12:330 (6362) 0 [Utility.Event] Manager initialized for MIRROR
07/09/24-14:33:12:362 (6362) 0 [Generic.Event] INTERSYSTEMS IRIS JOURNALING SYSTEM MESSAGE
Journaling switched to: /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.008
07/09/24-14:33:12:368 (6362) 0 [Utility.Event]   Scanning /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.007
07/09/24-14:33:12:388 (6362) 0 [Utility.Event] No open transactions to roll back
07/09/24-14:33:12:391 (6362) 0 [Generic.Event] MirrorServer: New primary activating databases which are current as of 356088 (0x00056ef8) in mirror journal file #7
07/09/24-14:33:12:391 (6362) 0 [Generic.Event] Changed database /usr/iris/mgr/user/ (SFN 4) to read-write due to becoming primary.
07/09/24-14:33:12:391 (6362) 0 [Generic.Event] MirrorServer: Primary startup reset to Agent Controlled failover
07/09/24-14:33:12:406 (6362) 0 [Utility.Event] Initializing Interoperability during mirror initialization
07/09/24-14:33:12:410 (6362) 2 [Utility.Event] Becoming primary mirror server
07/09/24-14:33:13:141 (6590) 0 [Utility.Event] Journal File Compression: Compressed /usr/iris/mgr/journal/20240709.010 from 196608 bytes to 73728 bytes, compression ratio = 2.7
07/09/24-14:33:13:166 (6590) 0 [Utility.Event] Journal File Compression: Compressed /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.007 from 393216 bytes to 77824 bytes, compression ratio = 5.1
07/09/24-14:33:26:097 (6377) 0 [Utility.Event] [SYSTEM MONITOR] Mirror status changed. Member type = Failover, Status = Primary
07/09/24-14:36:51:766 (6651) 0 [Generic.Event] MirrorServer: Starting connection for: UBUNTU/IRIS (failover member) (ver 4) at offset 0x00030d98 (200088) in  file #8
07/09/24-14:36:52:875 (6651) 0 [Generic.Event] MirrorServer: Client up to date, linking with journal daemon @ 0x000310a4
07/09/24-14:36:52:878 (6651) 0 [Generic.Event] MirrorServer: Switched from Agent Controlled to Arbiter Controlled failover

And from the side of the former primary who's now restarted as backup :
 

07/09/24-14:36:45:825 (1689) 0 [Utility.Event] Mirror manager for MIRROR starting
07/09/24-14:36:45:842 (1697) 0 [Utility.Event] Starting TASKMGR
07/09/24-14:36:45:860 (1704) 0 [Utility.Event] [SYSTEM MONITOR] System Monitor started in %SYS
07/09/24-14:36:45:909 (1690) 0 [Utility.Event] Shard license: 1
07/09/24-14:36:45:910 (1711) 0 [Utility.Event] WorkQueue: Starting work queue daemon parent=1690
07/09/24-14:36:46:058 (1704) 0 [Utility.Event] [SYSTEM MONITOR] Mirror state: Member type = Failover, Status = Transition
07/09/24-14:36:46:319 (1568) 0 [Generic.Event] Auditing to /usr/iris/mgr/irisaudit/
07/09/24-14:36:46:421 (1568) 0 [Utility.Event] Enabling logons
07/09/24-14:36:46:429 (1568) 0 [Utility.Event] Initializing Interoperability during system startup
07/09/24-14:36:47:653 (1682) 0 [Utility.Event] LMF Info:  Connected to license server 127.0.0.1,4002
07/09/24-14:36:47:930 (1830) 0 [Utility.Event] DejournalProcessor: Applying journal data for mirror "MIRROR" starting at 356088 in file #7(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.007)
07/09/24-14:36:47:930 (1689) 0 [Utility.Event] Retrieving journal file #8 for mirror MIRROR from 192.168.102.131|2188
07/09/24-14:36:48:968 (1830) 0 [Utility.Event] DejournalProcessor: Applying journal data for mirror "MIRROR" starting at 0 in file #8(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.008)
07/09/24-14:36:50:285 (1833) 0 [Utility.Event] Applying journal data for mirror "MIRROR" starting at 200088 in file #8(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.008)
07/09/24-14:36:50:523 (1689) 0 [Utility.Event] Retrieving journal file #8 for mirror MIRROR from 192.168.102.131|2188...(repeated 1 times)
07/09/24-14:36:50:523 (1689) 0 [Utility.Event] GetECPSessionData: Got ECP data from agent len=1
07/09/24-14:36:50:523 (1689) 0 [Utility.Event] Manager initialized for MIRROR
07/09/24-14:36:50:712 (1689) 0 [Utility.Event] Found UBUNTU-2/IRIS as primary, becoming backup
07/09/24-14:36:50:713 (1689) 0 [Utility.Event] (MIRROR) Becoming a backup mirror member
07/09/24-14:36:51:239 (1835) 0 [Utility.Event] (MIRROR) Starting Mirror.Client("MIRROR-MIRROR-20240709.008",200088,8)
07/09/24-14:36:51:242 (1835) 0 [Generic.Event] MirrorClient: Connected to primary: UBUNTU-2/IRIS (ver 4)
07/09/24-14:36:51:266 (1837) 0 [Utility.Event] Arbiter connection established (192.168.102.1:2188)
07/09/24-14:36:52:353 (1835) 0 [Generic.Event] MirrorClient: Switched from Agent Controlled to Arbiter Controlled failover on request from primary
07/09/24-14:36:56:358 (1835) 0 [Generic.Event] MirrorClient: The backup node has become active from a status query
07/09/24-14:36:57:774 (1850) 0 [Utility.Event] Journal File Compression: Compressed /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.007 from 393216 bytes to 77824 bytes, compression ratio = 5.1
07/09/24-14:37:16:627 (1704) 0 [Utility.Event] [SYSTEM MONITOR] Mirror status changed. Member type = Failover, Status = Backup

Hi @Kamal Suri 
below my results in a mirror env.

After stopping the Primary Linux server, the IRIS instance on the Backup Linux server becomes Primary and forces the previous Primary IRIS to shutdown when it comes back (as expected).

When you restart the IRIS instance in the previous Primary Linux, it becomes Backup.

Below the messages.log from the previous Backup who became Primary :

07/09/24-11:47:15:808 (5427) 0 [Database.MountedRO] Mounted database /usr/iris/mgr/user/ (SFN 5) read-only. Mirrored DB needs activation. 
07/09/24-11:47:29:355 (5312) 0 [Database.MirrorActivated] Activated database /usr/iris/mgr/user/ (SFN 5) in mirror 'MIRROR' for use on this mirror member; mounted read-only.
07/09/24-11:47:34:176 (5552) 0 [Utility.Event] Mirror 'MIRROR' catchup started for 1 database.
07/09/24-11:47:34:883 (5552) 1 [Utility.Event] :mirror:MIRROR:USER (sfn 5) remains inactive because it is not active on the primary
07/09/24-11:51:14:822 (5465) 1 [Generic.Event] MirrorClient: Primary AckDaemon failed to answer status request.
07/09/24-11:51:14:823 (5465) 0 [Generic.Event] MirrorClient: Backup waiting for old Dejournal Reader (pid: 5466, job #33) to exit
07/09/24-11:51:15:698 (5465) 0 [Generic.Event] MirrorClient: Set status for MIRROR to Transition
07/09/24-11:51:18:705 (5449) 0 [Utility.Event] Backup taking over for primary in arbiter controlled mode
07/09/24-11:51:18:752 (5649) 0 [Utility.Event] Applying journal data for mirror "MIRROR" starting at 382140 in file #5(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.005)
07/09/24-11:51:18:784 (5449) 0 [Utility.Event] Manager initialized for MIRROR
07/09/24-11:51:18:812 (5449) 0 [Generic.Event] INTERSYSTEMS IRIS JOURNALING SYSTEM MESSAGE
Journaling switched to: /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.006
07/09/24-11:51:18:822 (5449) 0 [Utility.Event]   Scanning /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.005
07/09/24-11:51:18:853 (5449) 0 [Utility.Event] No open transactions to roll back
07/09/24-11:51:18:855 (5449) 0 [Generic.Event] MirrorServer: New primary activating databases which are current as of 382140 (0x0005d4bc) in mirror journal file #5
07/09/24-11:51:18:855 (5449) 0 [Generic.Event] Changed database /usr/iris/mgr/user/ (SFN 5) to read-write due to becoming primary.
07/09/24-11:51:18:855 (5449) 0 [Generic.Event] MirrorServer: Primary startup reset to Agent Controlled failover
07/09/24-11:51:19:012 (5449) 0 [Utility.Event] Initializing Interoperability during mirror initialization
07/09/24-11:51:19:013 (5449) 2 [Utility.Event] Becoming primary mirror server
07/09/24-11:51:28:743 (5192) 0 [Utility.Event] [SYSTEM MONITOR] Mirror status changed. Member type = Failover, Status = Primary
07/09/24-11:51:29:683 (5652) 0 [Utility.Event] Journal File Compression: Compressed /usr/iris/mgr/journal/20240709.009 from 327680 bytes to 102400 bytes, compression ratio = 3.2
07/09/24-11:51:29:705 (5652) 0 [Utility.Event] Journal File Compression: Compressed /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.005 from 393216 bytes to 106496 bytes, compression ratio = 3.7
07/09/24-11:51:54:196 (5449) 0 [Utility.Event] Forcing down old primary ("UBUNTU/IRIS") which is currently in a trouble state
07/09/24-11:53:53:566 (5687) 0 [Generic.Event] MirrorServer: Starting connection for: UBUNTU/IRIS (failover member) (ver 4) at offset 0x00031e68 (204392) in  file #6
07/09/24-11:53:54:669 (5687) 0 [Generic.Event] MirrorServer: Client up to date, linking with journal daemon @ 0x00031e68
07/09/24-11:53:54:858 (5687) 0 [Generic.Event] MirrorServer: Switched from Agent Controlled to Arbiter Controlled failover

and the messages.log from the previous Primary who is now Backup :

07/09/24-11:53:50:157 (6577) 0 [Utility.Event] [SYSTEM MONITOR] Mirror state: Member type = Failover, Status = Transition
07/09/24-11:53:50:236 (6543) 0 [Generic.Event] Auditing to /usr/iris/mgr/irisaudit/
07/09/24-11:53:50:274 (6543) 0 [Utility.Event] Enabling logons
07/09/24-11:53:50:282 (6543) 0 [Utility.Event] Initializing Interoperability during system startup
07/09/24-11:53:50:877 (6695) 0 [Utility.Event] DejournalProcessor: Applying journal data for mirror "MIRROR" starting at 382140 in file #5(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.005)
07/09/24-11:53:50:877 (6557) 0 [Utility.Event] Retrieving journal file #6 for mirror MIRROR from 192.168.102.131|2188
07/09/24-11:53:51:905 (6695) 0 [Utility.Event] DejournalProcessor: Applying journal data for mirror "MIRROR" starting at 0 in file #6(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.006)
07/09/24-11:53:51:919 (6550) 0 [Utility.Event] LMF Info:  Connected to license server 127.0.0.1,4002
07/09/24-11:53:53:071 (6697) 0 [Utility.Event] Applying journal data for mirror "MIRROR" starting at 204392 in file #6(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.006)
07/09/24-11:53:53:200 (6557) 0 [Utility.Event] Retrieving journal file #6 for mirror MIRROR from 192.168.102.131|2188...(repeated 1 times)
07/09/24-11:53:53:200 (6557) 0 [Utility.Event] GetECPSessionData: Got ECP data from agent len=1
07/09/24-11:53:53:200 (6557) 0 [Utility.Event] Manager initialized for MIRROR
07/09/24-11:53:53:302 (6557) 0 [Utility.Event] Found UBUNTU-2/IRIS as primary, becoming backup
07/09/24-11:53:53:303 (6557) 0 [Utility.Event] (MIRROR) Becoming a backup mirror member
07/09/24-11:53:53:567 (6699) 0 [Utility.Event] (MIRROR) Starting Mirror.Client("MIRROR-MIRROR-20240709.006",204392,6)
07/09/24-11:53:53:569 (6699) 0 [Generic.Event] MirrorClient: Connected to primary: UBUNTU-2/IRIS (ver 4)
07/09/24-11:53:53:582 (6701) 0 [Utility.Event] Arbiter connection established (192.168.102.1:2188)
07/09/24-11:53:54:861 (6699) 0 [Generic.Event] MirrorClient: Switched from Agent Controlled to Arbiter Controlled failover on request from primary
07/09/24-11:53:54:916 (6699) 0 [Generic.Event] MirrorClient: The backup node has become active
07/09/24-11:54:01:989 (6718) 0 [Utility.Event] Journal File Compression: Compressed /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.005 from 393216 bytes to 106496 bytes, compression ratio = 3.7
07/09/24-11:54:20:174 (6577) 0 [Utility.Event] [SYSTEM MONITOR] Mirror status changed. Member type = Failover, Status = Backup

Thank you @Jeffrey Drumm 

I've made several tests with User option and actually, even without this parameter, IRIS is started under the account provided during the installation :

guilbaud    1776       1  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb -s/usr/irissys/mgr/ -w/usr/irissys/mgr/ -cc -B -C/usr/irissys/iris.cpf*IRIS
guilbaud    1885    1776  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb WD                                                                         
guilbaud    1886    1776  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb GC                                                                         
guilbaud    1887    1776  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb JD                                                                         
guilbaud    1888    1776  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb AUX1                                                                       
guilbaud    1889    1776  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb AUX3                                                                       
guilbaud    1890    1776  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb AUX2                                                                       
guilbaud    1891    1776  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb AUX5                                                                       
guilbaud    1892    1776  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb AUX4                                                                       
guilbaud    1893    1776  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb AUX6                                                                       
guilbaud    1894    1776  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb AUX7                                                                       
guilbaud    1895    1776  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb DBXD                                                                       
irisusr     2033       1  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb -s/usr/irissys/mgr -cj -p13 START^MONITOR
irisusr     2041       1  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb -s/usr/irissys/mgr -cj -p13 START^CLNDMN
irisusr     2106       1  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb -s/usr/irissys/mgr -cj -p13 START^LMFMON
irisusr     2133       1  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb -s/usr/irissys/mgr -cj -p13 ^RECEIVE
irisusr     2146       1  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb -s/usr/irissys/mgr -cj -p19 Master^%SYS.SERVER
irisusr     2153       1  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb -s/usr/irissys/mgr -cj -p19 RunManager^%SYS.Task
irisusr     2157       1  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb -s/usr/irissys/mgr -cj -p19 Start^%SYS.Monitor.Control
irisusr     2178       1  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb -s/usr/irissys/mgr -cj -p19 RunDaemon^%SYS.WorkQueueMgr
irisusr     2191       1  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb -s/usr/irissys/mgr -cj -p19 RunRemoteQueueDaemon^%SYS.WorkQueueMgr
irisusr     2205    2178  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb -s/usr/irissys/mgr -cj -p24 startWork^%SYS.WorkQueueMgr
irisusr     2213    2178  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb -s/usr/irissys/mgr -cj -p24 startWork^%SYS.WorkQueueMgr
irisusr     2420    2178  0 13:26 ?        00:00:00 /usr/irissys/bin/irisdb -s/usr/irissys/mgr -cj -p24 startWork^%SYS.WorkQueueMgr

You can also use classes instead of routines.

For instance :

Class test.a Extends %RegisteredObject
{

ClassMethod run() As %Status
{
    Set sc = $$$OK
    read !,"Enter the hour: ",hr  
    read !,"Enter the minute: ",min 
    read !,"Enter the second: ",sec     
    do ..getInternalTime(hr,min,sec)

     /// Display some other internal time values :
    for a = 0,3600,43200,45296,86399 {
        w !,"Equivalent M time: ",a," (Time:",$zt(a),")",!
    }
    Return sc
}

ClassMethod getInternalTime(hr As %Integer, min As %Integer, sec As %Integer) As %Status
{
    set sc=$$$OK
    set Mtime=$$ConvertToMTime(hr,min,sec)
    write !,"Equivalent M time: ",Mtime," (Time:",$zt(Mtime),")",!
    return sc
}

ClassMethod ConvertToMTime(h, m, s) As %Integer
{
        Return (h*3600)+(m*60)+(s)
}

}

Will give : 

USER>w ##class(test.a).run()

Enter the hour: 12
Enter the minute: 34
Enter the second: 45
Equivalent M time: 45285 (Time:12:34:45)

Equivalent M time: 0 (Time:00:00:00)

Equivalent M time: 3600 (Time:01:00:00)

Equivalent M time: 43200 (Time:12:00:00)

Equivalent M time: 45296 (Time:12:34:56)

Equivalent M time: 86399 (Time:23:59:59)
1

Hi @James Rutledge 

welcome in our world !

Using this ROUTINE below :

ROUTINE test.1
    r !,"Enter the hour: ",hr  
    r !,"Enter the minute: ",min 
    r !,"Enter the second: ",sec 
    s Mtime=$$ConvertToMTime(hr,min,sec)
    w !,"Equivalent M time: ",Mtime," (Time:",$zt(Mtime),")",!

    /// Display some other internal time values :
    for a = 0,3600,43200,45296,86399 {
        w !,"Equivalent M time: ",a," (Time:",$zt(a),")",!
    }
    q
ConvertToMTime(h,m,s)
    q (h*3600)+(m*60)+(s)

Will display the following result :

USER>d ^test.1

Enter the hour: 12
Enter the minute: 34
Enter the second: 45
Equivalent M time: 45285 (Time:12:34:45)

Equivalent M time: 0 (Time:00:00:00)

Equivalent M time: 3600 (Time:01:00:00)

Equivalent M time: 43200 (Time:12:00:00)

Equivalent M time: 45296 (Time:12:34:56)

Equivalent M time: 86399 (Time:23:59:59)

Simply by using the Resource option in a CreateDatabase instruction of [Actions] section in a merge.cpf file :

[Actions]
CreateResource:Name=%DB_IRISAPP_DATA,Description="IRISAPP_DATA database"
CreateDatabase:Name=IRISAPP_DATA,Directory=/usr/irissys/mgr/IRISAPP_DATA,Resource=%DB_IRISAPP_DATA
CreateResource:Name=%DB_IRISAPP_CODE,Description="IRISAPP_CODE database"
CreateDatabase:Name=IRISAPP_CODE,Directory=/usr/irissys/mgr/IRISAPP_CODE,Resource=%DB_IRISAPP_CODE
CreateNamespace:Name=IRISAPP,Globals=IRISAPP_DATA,Routines=IRISAPP_CODE,Interop=1

Hi @Otto Medin 
very good point.

In order to get links visible on the production configuration, you can add this method :

/// Return an array of connections for drawing lines on the config diagram
ClassMethod OnGetConnections(Output pArray As %String, pItem As Ens.Config.Item)
{
	Do ##super(.pArray,pItem)
	If pItem.GetModifiedSetting("TargetConfigNames",.tValue) {
		For i=1:1:$L(tValue,",") { Set tOne=$ZStrip($P(tValue,",",i),"<>W")  Continue:""=tOne  Set pArray(tOne)="" }
	}
}

With the following results :

python account.py 
Deposit succeeded: Balance after deposit: 100
Deposit of negative amount failed as expected: Deposit amount must be non-negative
Withdrawal succeeded: Balance after withdrawal: 50
Withdrawal of more than available balance failed as expected: Insufficient funds
Balance invariant holds true
Balance invariant violated as expected: Balance invariant violated: Balance is negative
Account operations completed successfully

In Python :
 

class Account:
    def __init__(self):
        self.balance = 0

    def deposit(self, amount):
        if amount < 0:
            raise ValueError("Deposit amount must be non-negative")
        
        old_balance = self.balance
        self.balance += amount
        
        # Postconditions
        if self.balance != old_balance + amount:
            raise ValueError("Postcondition failed: Balance calculation error")

    def withdraw(self, amount):
        if amount < 0:
            raise ValueError("Withdrawal amount must be non-negative")
        if self.balance < amount:
            raise ValueError("Insufficient funds")

        old_balance = self.balance
        self.balance -= amount
        
        # Postconditions
        if self.balance != old_balance - amount:
            raise ValueError("Postcondition failed: Balance calculation error")

    def check_balance_invariant(self):
        if self.balance < 0:
            raise ValueError("Balance invariant violated: Balance is negative")

    @classmethod
    def test_account(cls):
        account = cls()
        
        try:
            # Test depositing a positive amount
            account.deposit(100)
            print("Deposit succeeded: Balance after deposit:", account.balance)
            
            # Test depositing a negative amount (should fail)
            account.deposit(-50)
        except ValueError as e:
            print("Deposit of negative amount failed as expected:", e)
        else:
            raise ValueError("Deposit of negative amount unexpectedly succeeded")
        
        try:
            # Test withdrawing a valid amount
            account.withdraw(50)
            print("Withdrawal succeeded: Balance after withdrawal:", account.balance)
            
            # Test withdrawing more than the available balance (should fail)
            account.withdraw(200)
        except ValueError as e:
            print("Withdrawal of more than available balance failed as expected:", e)
        else:
            raise ValueError("Withdrawal of more than available balance unexpectedly succeeded")
        
        try:
            # Check balance invariant (should succeed)
            account.check_balance_invariant()
            print("Balance invariant holds true")
        except ValueError as e:
            print("Balance invariant violated:", e)
        
        # Intentionally set balance to negative value to trigger balance invariant failure
        account.balance = -10
        
        try:
            # Check balance invariant (should fail)
            account.check_balance_invariant()
        except ValueError as e:
            print("Balance invariant violated as expected:", e)
        else:
            raise ValueError("Balance invariant unexpectedly held true")
        
        print("Account operations completed successfully")

# Run the test
Account.test_account()