jcarr.dev

James Carr · systems operation and adversarial analysis

Something is probing this host right now. The interesting question is what for.

I don't get excited by building features. I get excited by the moment something is behaving strangely and nobody knows why yet – and on a machine facing the internet, the answer is usually that somebody is trying something.

What can be seen is what they asked for, how often, and whether they came back after being blocked. What cannot be seen is why. A log line will never tell you motive, and keeping those two apart – evidence on one side, judgement on the other – is most of the work.

Where they come from 36 COUNTRIES
United States – 92 detection(s) Cyprus – 34 detection(s) Canada – 22 detection(s) Andorra – 21 detection(s) Germany – 21 detection(s) Taiwan – 19 detection(s) India – 19 detection(s) The Netherlands – 18 detection(s) China – 14 detection(s) Ireland – 10 detection(s) Indonesia – 9 detection(s) Poland – 9 detection(s) Hong Kong – 8 detection(s) Italy – 8 detection(s) France – 8 detection(s) Brazil – 8 detection(s) United Kingdom – 6 detection(s) Singapore – 5 detection(s) Belgium – 5 detection(s) Vietnam – 5 detection(s) Switzerland – 4 detection(s) Mexico – 3 detection(s) Argentina – 2 detection(s) Norway – 2 detection(s) Spain – 2 detection(s) Bulgaria – 2 detection(s) Ukraine – 2 detection(s) Bangladesh – 2 detection(s) Russia – 2 detection(s) Turkey – 2 detection(s) Sweden – 2 detection(s) Pakistan – 1 detection(s) Serbia – 1 detection(s) Philippines – 1 detection(s) Czechia – 1 detection(s) Japan – 1 detection(s) This host – London, UK (declared)
US United States 92 CY Cyprus 34 CA Canada 22 AD Andorra 21 DE Germany 21 TW Taiwan 19 IN India 19 NL The Netherlands 18

391 detection(s) from 40 registered countries, since 2026-08-12 18:55Z.

How to read this A marker shows where a network is registered – where somebody rented capacity, not where they are. Colour and size follow how many detections came from that country. An arc is drawn when a request arrives: it marks the two ends of that request, not the route it took. The host marker is the one declared position here; a machine cannot read its own latitude. 20 detection(s) could not be placed – no coordinates for the country, or no country recorded – and are counted in the total rather than shown on the plot.

Ask me anything

An AI, grounded in what I've written, honest about what it doesn't know

Ask about me 🤖 Ask James

Ask about my experience, skills, or background. This is an AI answering from notes I wrote about myself; it will not make things up, and if it does not know it will say so. For anything real, the contact link is always better than a bot.

This machine, right now

Full operations view →

Read from the host at the moment you loaded the page, and updated over the open connection while you read. Nothing here is a screenshot, a mock, or a number typed into the markup. Where a reading cannot be taken, the panel says so rather than showing a plausible default.

Host vitals 22:09:41 UTC
Load 1m / 5m / 15m Load average The average number of processes running or waiting on I/O, over 1, 5 and 15 minutes. It is not a percentage – the figure only means something against the core count, which is why load per core sits beside it. Comparing the three windows tells you whether a spike is building or clearing. 0.00 / 0.02 / 0.00
Per core (2) Load per core Load average divided by the number of CPU cores. Sustained above 100% means work is queuing rather than running, and the machine is behind. 0.0%
Memory used Memory used Derived from MemAvailable – the kernel's own estimate of memory obtainable for new work, including cache it can reclaim. More honest than 'free', which counts cache as used and makes a perfectly healthy machine look full. 49.2%of 1.6 GB
Disk / 7.9% of 58.7 GB
Disk /tmp 7.9% of 58.7 GB
Disk /var/lib/jcarr-app 7.9% of 58.7 GB
Network rx / tx 24.8 B/s / 8.4 B/s
TCP established TCP established Connections currently in the ESTABLISHED state, parsed from /proc/net/tcp. Only the count is taken: remote addresses are never read into anything the page can display. 4
Host uptime Host uptime Time since the kernel booted, distinct from how long the application has been running. Together the two tell you whether a service restarted or the whole machine did – a different problem with a different cause. 26d 00:37:27
Host identity X64
Operating system AlmaLinux 9.8 (Olive Jaguar)
Kernel Kernel release The running kernel version, read from /proc/version. In a container this is the host's kernel, not the image's – containers share the kernel and only bring their own userspace. 5.14.0-687.36.1.el9_8.x86_64
CPU Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
Logical processors 2
Architecture X64
Runtime .NET 10.0.10
Application uptime 22d 13:42:02
Watched units systemd unit A service managed by systemd, the init system on most modern Linux distributions. ActiveState says whether it is running; SubState says what it is actually doing, which is the more useful of the two when something is wrong. systemctl
APPLICATION ACTIVE / running
EDGE PROXY ACTIVE / running
DATABASE ACTIVE / running
INTRUSION FILTER ACTIVE / running
IP jail Jail A fail2ban ruleset: which log to watch, which pattern counts as a failure, how many failures earn a ban, and how long the ban lasts. 0 held

No addresses currently held. Bans are actioned by fail2ban at the edge from the same access log this page reads; this panel reflects the live jail.

Node declared + measured
Provider declared Declared, not measured A configured value rather than a reading. The application cannot determine which datacentre it occupies without asking an external service where its own address is, so this is labelled rather than quietly presented alongside figures that were genuinely measured. AWS Lightsail
Region declared eu-west-2
Site declared London, UK
Node clock 22:09:42 UTC
Node timezone UTC
Host uptime 26d 00:37:26

Every timestamp on this site is UTC, to the second. A distributed log is only as good as the clocks behind it, so the node runs in UTC rather than a local zone – there is no offset to reason about during an incident, and no hour that happens twice a year.

The opposition

Real traffic, grouped by actor · nothing here is seeded
Who has been trying full assessments
Source Masked source The final octet is zeroed before anything is stored or displayed. Enough to tell two sources apart and attribute a network, without retaining data that identifies a person. The full address exists only in memory, for the moment it takes to look up its country. Country Requests Days Assessment Campaign Related activity from one source network grouped over time, rather than counted as separate requests. A single probe says nothing; what an actor went looking for, how long they persisted and whether they returned is the part with analytical value.

Ranked by significance, not recency. A row opens to show the evidence behind its verdict. The diamond flags a source that returned after a block or has been active across more than one day – the signals that separate a passing scan from something deliberate, and which only appear with time.

Watching a machine and watching an opponent are different problems. A disk filling up does not change its behaviour because you noticed. An adversary does – which is why a signature only catches what somebody already catalogued, and fails on the first day of anything new.

So detection here is built on deviation from a measured baseline rather than a list of things to look for, and the reporting keeps what was observed apart from what has been inferred, with a confidence attached to the judgement.

How each source is assessed →

Blocking an address costs an opponent almost nothing – addresses are rented by the hour. Behaviour is far more expensive to change, so the durable detection is the pattern rather than the indicator. The clearest signal available is simply whether a source came back once its block expired: indiscriminate scanning never revisits.

Not every failure has an opponent behind it

Written by the detector as it observes, not composed in advance
Packet worker NOMINAL
Queue depth Queue depth How much work is waiting to be processed. A queue climbing steadily means the consumer has fallen behind the producer, and it is usually the earliest visible symptom of trouble – before anything has actually failed or thrown an error. 0
Processed 48,104,759
CRC failures CRC (cyclic redundancy check) A checksum computed across a payload and transmitted alongside it. Recompute it on receipt and compare: if the values differ, the data changed in transit. Cheap to calculate and reliable against accidental corruption, which is why it appears in everything from Ethernet frames to tactical radio protocols. 0 since reset
Failure rate (recent) Rolling failure rate Failures across the most recent packets, not across all time. A lifetime rate looks fine and is quietly useless: the denominator grows the longer the system stays healthy, until a real fault cannot move it past any sensible threshold – the detector gets worse at its job exactly as the system gets more stable. A fixed window keeps the denominator constant. 0.0% last 250
Mean latency Mean latency An exponentially weighted moving average – recent samples count for more than older ones. It reacts quickly to a genuine shift without needing a full history buffer, and without one old outlier skewing the figure indefinitely. 0.2µs
Heartbeat Heartbeat A periodic signal a worker emits to show it is still alive. The absence is the signal: a stale heartbeat means the worker is wedged, which is precisely the failure mode that produces no error message at all. 22:09:42 UTC
Auto-resolves after 45s. One trigger per source per 10 min.
Incident timeline append-only Append-only Rows are only ever added, never edited or deleted. An incident record that can be tidied up afterwards is not evidence of anything; this one is written by the code at the moment each condition is observed. · 7 shown
20:57:06 RECOVERED CONFIRMED Post-recovery sample: queue depth 0, failure rate 0.0%, mean latency 7.2ms across 25 packets. Nominal.
20:57:05 RESTART CONFIRMED Fault cleared after 45s. Worker queue drained from 627 packets and counters reset; processing resumed at full batch size.
20:56:23 ISOLATED INFERRED Fault scoped to the packet worker: host readings show no corresponding pressure (load 0.00, memory 45.4% used, 4/4 watched units active). Failures are confined to the worker.
20:56:23 QUEUE DERIVED Queue depth 42 and climbing — consumer no longer keeping pace with a steady 25 packet/s offered rate, 3s into the event.
20:56:23 ANOMALY DERIVED Packet failure rate 6.8% exceeds 5.0% threshold across the last 250 packets processed (17 CRC mismatches since the worker last reset).
20:56:21 DEGRADED DERIVED Worker health check DEGRADED: mean processing latency 61.8ms against 40ms threshold.
20:56:20 INJECTED CONFIRMED Fault injected into the packet worker by request. The detection service is not notified and does not read this record — it observes the worker's published metrics like any other consumer.

Sometimes a system is simply broken, and that needs the same discipline. Press the button and a background worker takes a real fault – genuine CRC failures, genuine added latency. A separate detection service, which knows nothing about the trigger, records each threshold crossing as it observes it. The fault clears itself after 45 seconds, and recovery is confirmed against measurements taken afterwards rather than assumed from the fact it cleared.

The thing that watches, so I don't have to

Ambient – no interaction required
Edge detections delayed Feed delay Detections are held briefly before appearing publicly. The evidence is identical a moment later, but an attacker no longer gets a live readout of which requests trip a filter or how close they are to being blocked. The exact delay is deliberately not published – printing it would give back what the delay is there to withhold. · sources masked Masked source The final octet is zeroed before anything is stored or displayed. Enough to tell two sources apart and attribute a network, without retaining data that identifies a person. The full address exists only in memory, for the moment it takes to look up its country.
Detections 24h
1
Bans 24h
0
Currently jailed fail2ban Watches log files for patterns that indicate abuse and blocks the source at the firewall for a set period. The block happens at the packet level, so a banned host never reaches the application at all.
0
Top sources 24h Geolocation Resolving an address to a country and network. Done here against a database file held on this machine, so the address never leaves the process – sending visitor addresses to a third-party lookup service would defeat the point of masking them.
China 1
16:37:35 UNBAN 45.15.226.xxx · MD · AS207164 PRIMANET SRL
16:15:58 SSH-FAIL 47.94.227.xxx · CN China Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · AS37963 Hangzhou Alibaba Advertising Co.,Ltd.
20:07:50 SSH-FAIL 137.184.56.xxx · US United States Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · AS14061 DigitalOcean, LLC
20:07:31 SSH-FAIL 64.227.1.xxx · US United States Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · AS14061 DigitalOcean, LLC
20:05:23 SSH-FAIL 137.184.56.xxx · US United States Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · AS14061 DigitalOcean, LLC
20:04:56 SSH-FAIL 64.227.1.xxx · US United States Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · AS14061 DigitalOcean, LLC
19:04:38 SSH-FAIL 167.172.61.xxx · GB United Kingdom Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · AS14061 DigitalOcean, LLC
19:02:18 SSH-FAIL 167.172.61.xxx · GB United Kingdom Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · AS14061 DigitalOcean, LLC
16:37:35 BAN 45.15.226.xxx · MD · AS207164 PRIMANET SRL
10:18:50 UNBAN 38.49.216.xxx · CA · AS26832 Rica Web Services
23:53:56 PATH-SCAN 20.207.201.xxx · IN India Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /xmlrpc.php · 404 · AS8075 Microsoft Corporation
23:53:25 PATH-SCAN 20.207.201.xxx · IN India Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /xmlrpc.php · 404 · AS8075 Microsoft Corporation
23:43:41 PATH-SCAN 45.138.16.xxx · PL Poland Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /wp-admin/admin-ajax.php · 308 · AS210558 1337 Services GmbH
23:43:10 PATH-SCAN 45.138.16.xxx · PL Poland Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /wp-admin/admin-ajax.php · 308 · AS210558 1337 Services GmbH
23:22:56 PATH-SCAN 34.39.141.xxx · BR Brazil Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /backup.sql · 404 · AS396982 Google LLC
23:22:22 PATH-SCAN 34.39.141.xxx · BR Brazil Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /backup.sql · 404 · AS396982 Google LLC
21:46:11 PATH-SCAN 34.14.215.xxx · IN India Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /.git/config · 404 · AS396982 Google LLC
21:45:39 PATH-SCAN 34.14.215.xxx · IN India Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /.git/config · 404 · AS396982 Google LLC
21:38:36 UNBAN 136.107.102.xxx · US · AS396982 Google LLC
20:39:11 PATH-SCAN 136.107.102.xxx · US United States Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /.env.local · 404 · AS396982 Google LLC
20:38:37 BAN 136.107.102.xxx · US · AS396982 Google LLC
20:38:36 PATH-SCAN 136.107.102.xxx · US United States Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /.env.local · 404 · AS396982 Google LLC
17:08:57 PATH-SCAN 136.144.35.xxx · US United States Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /wp-login.php · 404 · AS396356 Latitude.sh
17:08:56 PATH-SCAN 136.144.35.xxx · US United States Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /wp-login.php · 308 · AS396356 Latitude.sh
15:47:59 SSH-FAIL 188.166.93.xxx · NL The Netherlands Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · AS14061 DigitalOcean, LLC
12:41:09 UNBAN 20.198.7.xxx · IN · AS8075 Microsoft Corporation
12:40:44 UNBAN 20.205.10.xxx · HK · AS8075 Microsoft Corporation
11:41:36 PATH-SCAN 20.198.7.xxx · IN India Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /wp/wp-admin/includes/ · 404 · AS8075 Microsoft Corporation
11:41:11 PATH-SCAN 20.205.10.xxx · HK Hong Kong Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /wp/wp-admin/includes/ · 404 · AS8075 Microsoft Corporation
11:41:09 BAN 20.198.7.xxx · IN · AS8075 Microsoft Corporation
11:41:05 PATH-SCAN 20.198.7.xxx · IN India Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /wp/wp-admin/includes/ · 404 · AS8075 Microsoft Corporation
11:40:45 BAN 20.205.10.xxx · HK · AS8075 Microsoft Corporation
11:40:38 PATH-SCAN 20.205.10.xxx · HK Hong Kong Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /wp/wp-admin/includes/ · 404 · AS8075 Microsoft Corporation
11:34:11 UNBAN 220.90.220.xxx · KR · AS4766 Korea Telecom
10:18:50 SSH-FAIL 38.49.216.xxx · CA Canada Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · AS26832 Rica Web Services
10:18:50 BAN 38.49.216.xxx · CA · AS26832 Rica Web Services
10:18:50 SSH-FAIL 38.49.216.xxx · CA Canada Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · AS26832 Rica Web Services
10:18:49 SSH-FAIL 38.49.216.xxx · CA Canada Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · AS26832 Rica Web Services
10:18:48 SSH-FAIL 38.49.216.xxx · CA Canada Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · AS26832 Rica Web Services
09:53:13 SSH-FAIL 171.212.114.xxx · CN China Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · AS4134 Chinanet
09:30:29 PATH-SCAN 35.229.211.xxx · TW Taiwan Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /.git/config · 404 · AS396982 Google LLC
06:29:36 PATH-SCAN 20.151.10.xxx · CA Canada Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · //cgi-bin/admin.php · 404 · AS8075 Microsoft Corporation
06:29:01 PATH-SCAN 20.151.10.xxx · CA Canada Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · //cgi-bin/admin.php · 404 · AS8075 Microsoft Corporation
06:29:01 PATH-SCAN 20.151.10.xxx · CA Canada Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /wp-content/plugins/hellopress/wp_filemanager.php · 404 · AS8075 Microsoft Corporation
06:28:26 PATH-SCAN 20.151.10.xxx · CA Canada Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /wp-content/plugins/hellopress/wp_filemanager.php · 404 · AS8075 Microsoft Corporation
05:12:57 PATH-SCAN 142.111.152.xxx · US United States Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /wp-login.php · 404 · AS212238 Datacamp Limited
05:12:56 PATH-SCAN 142.111.152.xxx · US United States Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /wp-login.php · 308 · AS212238 Datacamp Limited
03:07:59 UNBAN 34.186.61.xxx · US · AS396982 Google LLC
02:08:31 PATH-SCAN 34.186.61.xxx · US United States Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /.git/config · 404 · AS396982 Google LLC
02:07:59 BAN 34.186.61.xxx · US · AS396982 Google LLC
02:07:58 PATH-SCAN 34.186.61.xxx · US United States Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /.git/config · 404 · AS396982 Google LLC
01:28:20 UNBAN 20.151.10.xxx · CA · AS8075 Microsoft Corporation
01:28:10 SSH-FAIL 139.19.117.xxx · DE Germany Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · AS680 Verein zur Foerderung eines Deutschen Forschungsnetzes e.V.
00:28:51 PATH-SCAN 20.151.10.xxx · CA Canada Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · //cgi-bin/admin.php · 404 · AS8075 Microsoft Corporation
00:28:20 BAN 20.151.10.xxx · CA · AS8075 Microsoft Corporation
00:28:16 PATH-SCAN 20.151.10.xxx · CA Canada Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · //cgi-bin/admin.php · 404 · AS8075 Microsoft Corporation
00:28:16 PATH-SCAN 20.151.10.xxx · CA Canada Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /wp-content/plugins/hellopress/wp_filemanager.php · 308 · AS8075 Microsoft Corporation
00:27:44 PATH-SCAN 20.151.10.xxx · CA Canada Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /wp-content/plugins/hellopress/wp_filemanager.php · 308 · AS8075 Microsoft Corporation
23:19:46 PATH-SCAN 20.198.7.xxx · IN India Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /xmlrpc.php · 404 · AS8075 Microsoft Corporation
23:19:12 PATH-SCAN 20.198.7.xxx · IN India Where this network is registered. It is not where the operator is – server capacity is rented anywhere, so the network below is the more useful identifier. · /xmlrpc.php · 404 · AS8075 Microsoft Corporation

Every request reaching the edge lands in the proxy's access log. A worker tails that log, classifies what matters, enriches it against a geolocation database held on this machine, masks the source to a /24 and files it. The intrusion filter reads the same log through its own rules and blocks at the packet level. Nobody is watching any of it – the automation is the claim, not the monitoring. If you would like to appear in that feed yourself, there is a range set aside for it.

Don't take my word for any of it

Third-party verdicts · re-runnable by anyone

Everything else here is measured by this machine, which means you are trusting the machine. These are not: they are assessments by independent services, and the links re-run them live. If a grade below has slipped since it was recorded, the link will say so rather than this page.

External assessments OBSERVED 2026-08-12
Qualys SSL Labs → A+TLS 1.2 / 1.3
Certificate transparency → public logevery cert ever issued

Recorded when the link was last run, not read live – so unlike every other figure on this site, these are a claim rather than a measurement. That is exactly why each one is a link.

Get in touch

Open to operations, monitoring and incident work

If any of the above is the kind of work you need doing – running systems in real time, working out what something was actually trying to do, and building the automation that catches it next time – I'd like to hear about it.

Everything on this site runs on one small instance I own and operate. The source is public if you want to read how any of it works.

Background

Where this comes from

Years of high-responsibility operational work through long shifts, where monitoring, accurate logging and staying calm when something is wrong matter more than speed, and the cost of missing something is not a bad sprint.

Underneath it, a self-taught systems engineer who builds from bare metal up, an OS, an RTOS, this site, because understanding how something works at every layer is the point.

Current work

One of two core engineers on a B2B SaaS expense platform: owns production releases, monitors via Grafana and ELK, and investigates live incidents on systems other businesses depend on to pay people.

.NET and PostgreSQL day to day, on Linux, with the integration work that comes with talking to payroll and finance systems.

This system

Blazor Server on .NET 10, PostgreSQL, behind Caddy on RHEL-family Linux (AlmaLinux 9), running as an unprivileged service user.

The application can read a fixed, closed list of host files and commands and nothing else. No request-derived value ever reaches a command or a file path.

Connection to the server was lost. Reload 🗙

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please reload the page.