Files
ForgeFlow/reports/architecture-audit.md
T
NuklearRabbitandClaude Opus 5 cb9bdcd713 perf: reuse SSH connections per server, with a retry rule that never repeats work
Every ssh.exec opened its own connection: a TCP handshake, a key exchange and an
authentication round trip per command. A key rotation paid for that eight times,
a deployment six, and refreshing M profile states M times.

Connections are now kept per server. The three risks that made this worth doing
carefully are handled explicitly:

- Staleness. A pooled connection can be dead exactly when it matters. Liveness is
  tracked through error, close and end, and a lease that finds a dead entry opens
  a new one. The remaining race, where the connection dies between the check and
  the command, is caught by the retry rule below.
- Retrying. Only a failure that proves the command never reached the server is
  retried, and only once, and only on a connection that was already established
  before this call. execClient marks exactly that case, when the channel fails to
  open. A command that opened a stream is never repeated, because the server may
  already be acting on it - repeating a deployment is not this layer's decision.
  Two tests hold that line: widening the rule to any failure fails both.
- Lifetime. Idle connections close after a minute, the pool is reference counted
  so a shared connection survives until its last user is done, closeAll runs
  during quit, and every pooled client keeps a standing error listener so an
  error while idle cannot reach the uncaughtException handler.

A trust-on-first-use connection is never pooled: it was established without
verifying the fingerprint, so it must not serve a later verified call. A change
to host, port, user, auth type, key path or trusted fingerprint invalidates the
pooled connection.

ssh-service coverage rises from 61% to 90% of lines and 97% of functions.

Also in this commit, the smaller items from the same review:

- Diagnostics batched records that queue up while a write is in flight into one
  append, and chmod runs once per file instead of once per record. At the debug
  level every IPC call writes a line, which is exactly when troubleshooting.
- The set that suppresses duplicate deployment notifications is trimmed instead
  of growing for the lifetime of the process.
- The updater kept the same once('error') pattern on its spawned helper that
  took the app down through the SSH client.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 15:06:38 +02:00

1.3 KiB

ForgeFlow architecture audit

Generated 2026-08-23T13:06:16.630Z. Complexity is a deterministic decision-point count used for hotspot ranking, not a claim of exact McCabe complexity.

Files above 750 lines

File Lines Decisions Functions IPC handlers Responsibilities
No findings.

Files above 1,000 lines

File Lines Decisions Functions IPC handlers Responsibilities
No findings.

Cyclomatic hotspots

File Lines Decisions Functions IPC handlers Responsibilities
src/renderer/actions/shell.js 518 101 86 0 inventory, deployment, git, renderer, updates
src/renderer/app.js 732 80 124 0 inventory, deployment, git, renderer, security, updates
src/main/server-inventory.cjs 578 89 104 0 inventory, deployment, git, security, updates
src/main/git-service.cjs 687 111 118 0 git, security
src/main/unraid-inventory-methods.cjs 708 76 93 0 inventory, deployment, git, security, updates

Interpretation

Files above 750 lines require decomposition. Files above 1,000 lines are release blockers unless a concrete technical exception is documented. Mixed responsibility and IPC hotspot lists are available in the JSON report.