hub v0.137.0 source + burn-down round 2 in felhom.eu: R-277 R-581 R-600 R-544 R-855 R-134 R-92 R-292 R-599 R-725 R-728 (hub), R-819 R-857 R-555 R-364 R-587 (gates/tools), R-571 R-129 R-124-runbook (docs); 28 rows closed incl. catalog + agent v0.147.0 rows, R-350 merged into R-132, R-888 opened, R-887 mechanism (249 -> 222)
gates / gates (push) Successful in 2m3s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-05 19:43:37 +02:00
parent e0d884565f
commit 557629d2bf
65 changed files with 2680 additions and 122 deletions
+27
View File
@@ -111,6 +111,19 @@ type Server struct {
// only — see the constant's comment for why this must never become a database row.
artifactCache map[string]artifactChoiceCacheEntry
artifactCacheMu sync.Mutex
// wgPeerSync asks the WG peer-sync reconciler for an immediate full-list push (R-600). nil when
// peer-sync is not configured on this hub. Non-blocking: the push itself is asynchronous.
wgPeerSync func()
// creating holds the customer IDs whose create is in flight (R-728): one press produced TWO creates
// and two self-bind mints in the same second, and the first mail's link answered "expired". The
// duplicate check reads the store, and the row is written only after the slow provisioning legs, so
// a second submit inside that window passed it. Pinned by TestConfigCreate_ConcurrentSubmitCreatesOnce.
creating sync.Map
// beforeCreateSave is a TEST seam: called in handleConfigCreate after the duplicate check, before the
// save. nil in production.
beforeCreateSave func(customerID string)
}
// New creates a new web server.
@@ -247,6 +260,20 @@ func (s *Server) SetOffsiteBox(fn func() (monitor.BoxSnapshot, bool)) { s.offsit
// carries its own state (ok/unavailable/degraded); the web layer never polls ep0.
func (s *Server) SetPBSDRBox(fn func() (monitor.PBSBoxSnapshot, bool)) { s.pbsdrBox = fn }
// SetWGPeerSync wires the WG peer-sync reconciler's Trigger (R-600): the customer delete cascade asks
// for an immediate push so the deleted box's peer leaves the endpoint now, not on the next 5-minute tick.
func (s *Server) SetWGPeerSync(trigger func()) { s.wgPeerSync = trigger }
// requestWGPeerPush triggers the peer-sync push and returns the operator-facing phrase for the log:
// the push is asynchronous, so the line says "requested", never "removed" (R-600).
func (s *Server) requestWGPeerPush() string {
if s.wgPeerSync == nil {
return "WG peer-sync is not configured on this hub, so the endpoint's peer list was NOT updated"
}
s.wgPeerSync()
return "WG peer removal push requested (asynchronous — the endpoint drops the peer on that push, check `wg show` before calling the box gone)"
}
// SetClaimEngine wires the customer-claim code engine for the Setup-tab resend button (v0.50.0).
func (s *Server) SetClaimEngine(e *claim.Engine) { s.claimEngine = e }