10 most recent check-ins occurring on or after 2026-05-13 20:49:36.
More ↑
|
2026-05-19
| ||
| 17:09 |
fix(hub): resolve TestNotifyCLIPairAndDevices flake (closes #170) (#186)
* fix(hub): resolve TestNotifyCLIPairAndDevices flake (closes #170) Each of the 4 tests in cmd/edgesync/notify_test.go independently invoked `go build` for the edgesync binary inside its own body. Under cold build cache or parallel test load, this build storm pushed the package's total runtime past `go test -short -timeout=30s ./...` (the pre-push hook gate) and the suite-level timeout fired — surfacing as a hang on os/exec.Wait since the inner `go build` child was still running when the supervisor killed the test process. Move the build into TestMain so the binary is built once and reused. With -timeout=30s on cold cache, cmd/edgesync drops from ~9s to ~3s and the target test from ~2.8s to ~0.07s — comfortably clear of the timeout. No production-code change. No sleep band-aids. Verified 200/200 passes (50× per test in the package) and 80/80 under -race. * fix(test): clean up temp dir before os.Exit (Ousterhout follow-up to PR 186) --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> check-in: 37780572c3 user: [email protected] tags: trunk, main | |
| 16:25 |
feat(hub): Hub.EnsureUser — idempotent user-table registration (closes #183) (#184)
Add Hub.EnsureUser(login, caps string) error as an idempotent counterpart to Hub.AddUser. Consumers (sesh, others) need "register if absent" semantics; AddUser errors on duplicate, forcing each consumer to write check-then-act + race-recheck wrappers. The user-table layer is the right place to own that idempotency. Implementation choice (a) — GetUser → CreateUser, serialized by a Repo- level mutex. Picked over (b) "catch CreateUser's already-exists error" because libfossil's CreateUser surfaces a wrapped SQLite UNIQUE-constraint error with no sentinel or typed shape — string-matching would be brittle. A defensive GetUser retry after CreateUser failure absorbs the rare cross- process race where the in-process mutex doesn't apply. Contract: existing caps are PRESERVED on duplicate (documented). Callers wanting replace-on-conflict use SetUserCaps explicitly. Tests cover first-time registration, duplicate no-op, caps-change-on- duplicate (preservation), 5-goroutine concurrent race (exactly one row lands), and empty-login rejection. Full hub package + leaf + bridge + CLI suites pass; go vet clean; gofmt clean. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> check-in: 40c9b9aff3 user: [email protected] tags: trunk, main | |
|
2026-05-17
| ||
| 18:47 |
fix(hub): address pulls to publishing peer to resolve .sync race (#162) (#181)
Three+ hubs sharing a project-code all subscribed to the same broadcast
`<prefix>. Two changes close the gap:
The receiver also drops self-notifications (a publish from this hub
round-tripping back via an upstream leaf, which NoEcho doesn't catch
across leaf links) and notifications missing a peer-id (older publisher
that pre-dates this fix — refusing rather than falling back to a
broadcast pull keeps #162 from regressing silently).
`TestCrossLeaf_ThreeHubs_CommitAnnouncePropagatesToAll` is now ungated:
it ran red under both -short and full modes before this fix, and passes
under both modes (and 10x stability check) after.
Closes #162
Closes #179
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> | |
| 17:44 |
test(hub): add 3-hub cross-leaf propagation test (#180)
Mirrors the 2-node TestCrossLeaf_SharedProjectCode_PropagatesCommit shape but with a third leaf attached to the same topology root. Asserts that a commit on any peer propagates to BOTH of the other two peers, both directions. Reproduces the cross-leaf propagation gap reported in #179 and confirms its underlying cause is the multi-responder .sync race filed as #162: with 3+ hubs subscribing to the same .sync subject every peer answers nats.Request, only the first reply wins, and a stale responder silently starves the pull. The first hop (B -> A) is already enough to surface this — A's .sync request can race against C's empty responder even though A and B are the only nodes that need to talk for that direction. Gated under -short with a skip pointing to #162 so pre-commit and CI stay green. Without -short the test fails at the 10s wait in ~10s, demonstrating the bug. Remove the skip once #162 is fixed; the test then doubles as the regression sentinel for the 3+ hub topology that production sesh relies on. No production code changes. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> check-in: 5c36d5498d user: [email protected] tags: trunk, main | |
|
2026-05-16
| ||
| 18:01 | chore: bump submodule pins (leaf/v0.0.12,bridge/v0.0.4) leaf check-in: 5070f96573 user: 41898282+github-actions[bot]@users.noreply.github.com tags: trunk, v0.0.20 | |
| 17:55 |
feat(hub): expose embedded NATS WebSocket endpoint (#177)
Adds Config.EnableWebSocket (opt-in; default off for security since no TLS/WSS is wired up here) plus Config.NATSWebSocketPort (0 = auto-pick, mirroring the sibling NATSClientPort / NATSLeafPort convention). When enabled, the embedded nats-server binds a WebSocket listener on 127.0.0.1:NNNN with NoTLS=true. Surfaces the resolved listener URL via the new Hub.NATSWebSocketURL() getter, which returns "ws://127.0.0.1:NNNN" when WebSocket is enabled and "" otherwise — same shape as NATSURL() / LeafURL(). Tests cover the disabled-by-default contract, the auto-pick URL shape, and an end-to-end round trip: a nats.go client dials the ws:// URL, subscribes to a subject, and receives a payload published by a TCP client on the same embedded server. Fixes #176 Co-authored-by: Dan Mestas <[email protected]> check-in: ae52558ba4 user: [email protected] tags: trunk, leaf/v0.0.12, bridge/v0.0.4 | |
|
2026-05-14
| ||
| 16:08 |
feat(agent): implement AutosyncCommit on libfossil v0.6.2 Checkout API (#173) (#174)
The v0.2.0 deferral premise — "Checkout type is internal to libfossil" — is stale: v0.6.2 (current dep) exposes Checkout as a public handle with Version, WouldFork, Checkin, HasChanges, plus Repo.OpenCheckout/CreateCheckout. This wires up the long-deferred autosync workflow on that public API: pull -> fork check -> checkin -> push, with AutosyncOff/On/PullOnly modes. Errors are typed: ErrWouldFork on detected fork (without creating a checkin), and *PushFailedError when the local checkin succeeds but the follow-up push fails — the latter carries the local rid/uuid so callers can decide whether to retry, abandon, or surface the partial state. Sync.Push and Sync.Pull on the input opts are now rejected (loud failure beats silent override) since AutosyncCommit drives them per-mode. ErrCkinLockHeld is removed — it was an exported sentinel that no code path ever returned, so it would have invited misleading errors.Is checks downstream. When libfossil exposes a real lock-held signal, the sentinel can come back with a return path. The four previously-skipped tests are restored as real coverage. The fork-test fixture clones a "remote" repo from local at C0 via httptest (HandleSync doesn't speak the clone protocol — CDG-148), then commits C1 on the remote so the pull genuinely brings it back to local and triggers WouldFork. Three additional tests cover OffMode's branch-tip advance, rejection of caller-set Push/Pull, and PushFailedError's unwrap/format contract. Closes #173 check-in: ebcb65b235 user: [email protected] tags: trunk | |
| 09:32 |
feat(hub): expose Ready() channel for serve-loop start barrier (#172)
Adds Hub.Ready() returning a channel closed when ServeHTTP has wired up the http.Server and is about to enter the Accept loop. Consumers that advertise hub URLs externally (e.g. sesh writing session state JSON) can wait on Ready() before publishing, closing the window where the TCP listener is bound but the goroutine running ServeHTTP hasn't started processing requests. Closes #171. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> check-in: 0f4bfb32df user: [email protected] tags: trunk | |
|
2026-05-13
| ||
| 21:03 |
fix: exclude modernc driver registration from wasm builds (#169)
The init()-based modernc registration added in #166 (v0.0.18) blocked wasm builds because modernc references syscalls unavailable under js/wasm. Adds a //go:build !js && !wasm constraint to hub/driver.go so the registration is skipped on wasm targets — wasm consumers register their own driver (libfossil's ncruces driver supports wasm via its ncruces_js.go file). Native builds are unchanged: hub still auto-registers modernc. Wasm builds: hub package now compiles successfully under GOOS=js GOARCH=wasm; consumer brings its own driver. Verified: GOOS=js GOARCH=wasm go vet ./hub/... # clean GOOS=js GOARCH=wasm go build ./hub/... # success go test ./hub/... -timeout 120s # 38/38 pass on native Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> check-in: 0fa13d595b user: [email protected] tags: trunk, v0.0.19 | |
| 20:49 |
chore: bump modernc driver to v0.2.0 (#168)
Picks up the _txlock=immediate DSN fix from libfossil#33/#34 so concurrent writers serialize at BEGIN (where busy_timeout applies) instead of racing the SHARED→RESERVED upgrade. Required upstream for sesh's --scope=project mode to remain safe after sesh drops its direct libfossil/db/driver/modernc require. Without this bump, EdgeSync's hub init() (added in v0.0.18) would register a pre-fix driver and consumers regress on contention. Closes #167. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> check-in: d5a46f76de user: [email protected] tags: trunk | |