Rolls up theta-directory v2.4.0, jump-host v2.1.0, theta-agent v2.1.2.
Multi-site directory sync stops being a one-time snapshot (live
fire-and-forget replication, identical agent-signing keys, coordinated
master promotion), and site-to-site networking becomes real
infrastructure (gateway-to-gateway WireGuard mesh, kernel-first with a
userspace wireguard-go fallback, real two-container-verified tunnels)
instead of a documented-but-unbuilt design. Linux mDNS local-discovery
also lands end to end (announcer + agent listener).
See CHANGELOG.md for the full rollup and docs/MULTI_SITE_SPEC.md for
the architecture + explicit TODO list of what's still open.
Announce (theta-gateway) + discover/apply/revert (theta-agent) confirmed
working end-to-end over real multicast between real containers, including
two real bugs found and fixed along the way (IPv6 query abort, EBUSY on
rename over a bind-mounted /etc/hosts).
Windows/macOS mDNS is now the ONLY unbuilt piece of the original design
this session set out to implement -- and it's blocked on platform access
this environment doesn't have, not on missing design or effort.
Confirmed the core idea (master terminates a connection, relays over a
spoke's WG mesh IP to a spoke with zero published/inbound ports of its
own) with a standalone test: an external client hit the master's public
port and got a response that could only have come from the spoke,
which had no reachable port except over the tunnel.
Deliberately did NOT wire this into theta-proxy's actual Lua/Redis
routing engine -- that needs its own dedicated pass to do safely, plus a
real service-to-service credential between sso-manager-node and
theta-proxy/theta-gateway that doesn't exist yet. Recorded as verified
mechanism / unbuilt automation, not conflated with either "done" or
"unknown whether it would even work."
Updates the status table and top-of-doc callout to reflect what actually
shipped this pass: live catalog replication, identical-directory signing
key, coordinated master promotion (with two real bugs found + fixed along
the way), and a real, tested gateway-to-gateway WireGuard mesh.
Explicitly calls out what's still NOT true despite all of the above: the
mesh exists as its own transport layer but sso-manager-node's join/
replicate traffic doesn't route over it yet, so the no-inbound-spoke
relay scenario still isn't solved end-to-end. mDNS remains unbuilt.
Extends the shipped CFG_MASTER_DIRECTORY_URL/JOIN_KEY join flow with the
selfUrl a spoke needs to register itself for live catalog replication
(theta-directory v2.4.0's POST /api/site/spokes) -- without this, every
spoke was permanently limited to the one-time join snapshot even after
the master gained the ability to push live updates.
setup.sh already computes CFG_SSO_HOST before this point in the script;
passes https://$CFG_SSO_HOST as bootstrap/site-join.js's third argument,
which forwards it as `selfUrl` in the POST /api/site/join body.
MULTI_SITE_SPEC.md described a WireGuard-mesh + live-replication design as
if unbuilt-but-planned; meanwhile theta-directory v2.2.0-v2.3.0 (rolled up
in theta-suite v2.2.0) already shipped a simpler, real join mechanism
(one-time LDIF/catalog export over a site join key, read-only spoke
enforcement, setup.sh wiring) that this doc didn't mention at all. Added a
callout pointing at docs/site-join.md as the actual current behavior, and
corrected the status table so it no longer implies unbuilt features are
implemented.
Also adds AGENT_LOCAL_DISCOVERY_SPEC.md, a standalone handoff spec for the
mDNS "prefer local discovered directory" optimization -- confirmed not
implemented anywhere in theta-agent. Needs Windows/Mac-native investigation
this environment can't do; written so it can be picked up independently.
Renaming the job broke the master protection rule, which requires a check
named exactly 'Syntax check bootstrap.js'. The job still checks both bootstrap
scripts, just under the protected name.
Multi-site join wiring (server + UI landed in theta-directory v2.3.0):
- bootstrap/site-join.js: runs inside the sso-manager container (same
self-contained rule as bootstrap.js); logs in as the bootstrap admin and calls
/api/site/join. Idempotent: an already-joined node reports 'already a spoke'.
- setup.sh step 5b: if setup.env sets CFG_MASTER_DIRECTORY_URL +
CFG_MASTER_DIRECTORY_JOIN_KEY, run the join after the bootstrap. Only honored
on first run (ensure_config reads setup.env once and ignores it once
./config/ exists), so an already-populated directory can never be merged.
- setup.env.example documents both vars.
- lint.yml also node --check's site-join.js.
- CFG_ORG default was 'SSO Manager', which became the browser tab title / app
name on fresh installs. Default is now 'Theta Directory' (existing deployments
keep their operator-owned ./config/sso-secrets.js name).
- Records theta-agent d937f8d (silent-install server_url + tray autostart +
self-update 404 fixes).
Dockerfile.openldap now pulls ghcr.io/theta42/openldap-nestgroup instead of
compiling from source on every build (~5-6min -> ~1.5min per CI matrix run,
and removes the runtime dependency on git.openldap.org).
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Directory tab admitted every kind:'host' resource regardless of promotion
status (every discovery plugin creates its finds as kind:'host'), and
site-status 500'd on a nonexistent Resource.subType column.
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Unifies the GitHub Pages docs site: the SSO/Proxy/Jump Host pages, their
nav labels, and each component's own README now consistently say Theta
Directory / Theta Proxy / Theta Gateway, drop marketing sections ("Why this
over the alternatives", "Get it", "Related projects") that don't apply to a
suite component, remove every standalone/bare-metal install path, and link
to theta42.github.io/theta-suite/... instead of the old per-repo Pages sites.
Bumps submodules: theta-directory v2.0.2, proxy v2.0.1, jump-host v2.0.1.
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
- Theta Gateway: Add WireGuard peer management UI (/wireguard) with QR code generator, .conf download, and per-client exit node selection
- Theta Agent: Add desktop tray companion app (theta-agent-tray) with Theta 42 logo, color-coded status (red, yellow, green, blue), and home LAN detection
- Suite Rebuild: Local stack initialized with CFG_DOMAIN=suite.vm42.us and CFG_SITE_NAME=718it