Skip to content

Commit a4da65b

Browse files
AlexgodorojaAlex Godoroja
andauthored
fix: update python and js pilot clients to 1.9-* (#90)
Co-authored-by: Alex Godoroja <alex@vulturelabs.io>
1 parent 8db99d9 commit a4da65b

97 files changed

Lines changed: 4072 additions & 645 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,31 @@ project uses [Semantic Versioning](https://semver.org/).
77
Detailed per-release notes for tagged versions are published on the
88
[GitHub Releases page](https://github.com/TeoSlayer/pilotprotocol/releases).
99

10-
## [Unreleased]
10+
## [1.9.2] - 2026-05-05
11+
12+
### Changed
13+
- **SDK: updated sdk clients and cgo bindings to the latest version**
14+
15+
- **SDK: removed polo-score surface from Node and Python bindings.**
16+
Dropped `PilotMyPolo` from the CGO export layer (`sdk/cgo/bindings.go`)
17+
and the corresponding `Driver.myPoloScore()` / `Driver.my_polo_score()`
18+
wrappers, fake-lib hooks, and tests in both SDKs. The driver-level
19+
`MyPoloScore()` and the underlying registry/daemon machinery are
20+
untouched — this only narrows what the language SDKs expose. Removed
21+
the now-stale `polo.pilotprotocol.network` "Live Dashboard" project
22+
URL from `sdk/python/pyproject.toml` and a stray polo mention from
23+
the Python SDK README.
24+
25+
### Fixed
26+
27+
- **SDK: macOS binaries shipped via npm/pip codesign parity.**
28+
`sdk/{node,python}/scripts/build-binaries.sh` now mirror the main
29+
release workflow — after building `pilot-daemon`, `pilotctl`,
30+
`pilot-gateway`, `pilot-updater`, and `libpilot.dylib` on darwin,
31+
each artifact is codesigned (`codesign --force --deep --sign -`)
32+
and stripped of the quarantine xattr. Without this, npm/pip-installed
33+
binaries triggered Gatekeeper "killed: 9" / "cannot be opened
34+
because Apple cannot check it for malicious software" on first run.
1135

1236
## [1.9.1] - 2026-05-05
1337

cmd/pilotctl/main.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,12 +1281,12 @@ func cmdContext() {
12811281
"enable-tasks": map[string]interface{}{"args": []string{}, "description": "Advertise task-execution capability on port 1003"},
12821282
"disable-tasks": map[string]interface{}{"args": []string{}, "description": "Stop advertising task-execution capability"},
12831283
// Low-level / plumbing
1284-
"connect": map[string]interface{}{"args": []string{"<address|hostname>", "[port]", "[--message <msg>]"}, "description": "Open a raw stream connection"},
1285-
"send": map[string]interface{}{"args": []string{"<address|hostname>", "<port>", "--data <msg>"}, "description": "Send a single raw message to a port"},
1286-
"recv": map[string]interface{}{"args": []string{"<port>", "[--count <n>]"}, "description": "Accept and print incoming stream messages"},
1287-
"dgram": map[string]interface{}{"args": []string{"<address|hostname>", "<port>", "--data <msg>"}, "description": "Send a UDP-style datagram"},
1288-
"listen": map[string]interface{}{"args": []string{"<port>", "[--count <n>]"}, "description": "Listen for incoming datagrams"},
1289-
"broadcast": map[string]interface{}{"args": []string{"<network_id>", "<message>"}, "description": "Broadcast a datagram to all network members"},
1284+
"connect": map[string]interface{}{"args": []string{"<address|hostname>", "[port]", "[--message <msg>]"}, "description": "Open a raw stream connection"},
1285+
"send": map[string]interface{}{"args": []string{"<address|hostname>", "<port>", "--data <msg>"}, "description": "Send a single raw message to a port"},
1286+
"recv": map[string]interface{}{"args": []string{"<port>", "[--count <n>]"}, "description": "Accept and print incoming stream messages"},
1287+
"dgram": map[string]interface{}{"args": []string{"<address|hostname>", "<port>", "--data <msg>"}, "description": "Send a UDP-style datagram"},
1288+
"listen": map[string]interface{}{"args": []string{"<port>", "[--count <n>]"}, "description": "Listen for incoming datagrams"},
1289+
"broadcast": map[string]interface{}{"args": []string{"<network_id>", "<message>"}, "description": "Broadcast a datagram to all network members"},
12901290
// Connection management
12911291
"connections": map[string]interface{}{"args": []string{}, "description": "List active daemon connections"},
12921292
"disconnect": map[string]interface{}{"args": []string{"<conn_id>"}, "description": "Close a connection by ID"},

cmd/pilotctl/redact_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,24 @@ func TestRedactPeerEndpointsRemovesIPFields(t *testing.T) {
1717
"node_id": 42,
1818
"address": "0:0000.0000.002A",
1919
"hostname": "agent-test",
20-
"endpoint": "203.0.113.5:4000", // must go
21-
"real_addr": "203.0.113.5:4000", // must go
22-
"public_addr": "203.0.113.5:4000", // must go
20+
"endpoint": "203.0.113.5:4000", // must go
21+
"real_addr": "203.0.113.5:4000", // must go
22+
"public_addr": "203.0.113.5:4000", // must go
2323
"lan_addrs": []interface{}{"10.0.0.5:4000"}, // must go
24-
"observed_addr": "203.0.113.5:4000", // must go
25-
"stun_addr": "203.0.113.5:4000", // must go
24+
"observed_addr": "203.0.113.5:4000", // must go
25+
"stun_addr": "203.0.113.5:4000", // must go
2626
"peers": 7,
2727
"encrypted_peers": 7,
2828
"peer_list": []interface{}{
2929
map[string]interface{}{
30-
"node_id": 10,
31-
"endpoint": "198.51.100.10:4000",
30+
"node_id": 10,
31+
"endpoint": "198.51.100.10:4000",
3232
"real_addr": "198.51.100.10:4000",
3333
"encrypted": true,
3434
},
3535
map[string]interface{}{
36-
"node_id": 11,
37-
"endpoint": "198.51.100.11:4000",
36+
"node_id": 11,
37+
"endpoint": "198.51.100.11:4000",
3838
"encrypted": false,
3939
},
4040
},

cmd/pilotctl/updates.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ var changelogFeedURL = "https://teoslayer.github.io/pilot-changelog/feed.xml"
2525
// for the human-readable + JSON output are decoded; unknown elements are
2626
// ignored by encoding/xml.
2727
type rssDoc struct {
28-
XMLName xml.Name `xml:"rss"`
29-
Channel rssChan `xml:"channel"`
28+
XMLName xml.Name `xml:"rss"`
29+
Channel rssChan `xml:"channel"`
3030
}
3131

3232
type rssChan struct {

pkg/daemon/accept_queue_bug_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ import (
1717
// to call Accept and the queue has filled to AcceptQueueLen=64), the
1818
// SYN handler at pkg/daemon/daemon.go:1841 currently:
1919
//
20-
// 1. Sends the SYN-ACK back to the dialer
21-
// 2. Marks the connection StateEstablished
22-
// 3. Tries to push to AcceptCh
23-
// 4. On full: hits the `default` branch, sends a RST, removes the
24-
// Connection, logs WARN
20+
// 1. Sends the SYN-ACK back to the dialer
21+
// 2. Marks the connection StateEstablished
22+
// 3. Tries to push to AcceptCh
23+
// 4. On full: hits the `default` branch, sends a RST, removes the
24+
// Connection, logs WARN
2525
//
2626
// The RST is good — peer learns immediately. But:
2727
// - No Daemon-level counter is incremented (no AcceptQueueDrops)

pkg/daemon/beacon_discovery_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
type fakeRegistry struct {
1919
mu sync.Mutex
2020
beacons []string
21-
failNext int // if >0, the next N Send() calls error
21+
failNext int // if >0, the next N Send() calls error
2222
calls atomic.Int64
2323
lastError error
2424
}

pkg/daemon/beacon_select_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,15 @@ func TestPickBeaconStableAcrossSeparateListInstances(t *testing.T) {
156156
// are kept because they may resolve to public IPs.
157157
func TestFilterUnreachableDropsPrivateAndLoopback(t *testing.T) {
158158
in := []string{
159-
"34.71.57.205:9001", // public — kept
160-
"10.128.0.78:9001", // private RFC1918 — dropped
161-
"192.168.1.5:9001", // private RFC1918 — dropped
162-
"172.16.0.5:9001", // private RFC1918 — dropped
163-
"127.0.0.1:9001", // loopback — dropped
164-
"169.254.1.1:9001", // link-local — dropped
165-
"0.0.0.0:9001", // unspecified — dropped
159+
"34.71.57.205:9001", // public — kept
160+
"10.128.0.78:9001", // private RFC1918 — dropped
161+
"192.168.1.5:9001", // private RFC1918 — dropped
162+
"172.16.0.5:9001", // private RFC1918 — dropped
163+
"127.0.0.1:9001", // loopback — dropped
164+
"169.254.1.1:9001", // link-local — dropped
165+
"0.0.0.0:9001", // unspecified — dropped
166166
"beacon.example.com:9001", // DNS hostname — kept
167-
"8.8.8.8:9001", // public — kept
167+
"8.8.8.8:9001", // public — kept
168168
}
169169
got := filterUnreachable(in)
170170
want := []string{

pkg/daemon/ca_growth_abc_cap_bug_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ func TestCAGrowthCapsIncrementAtSMSS(t *testing.T) {
7070
// SMSS*SMSS/cwnd = 4096*4096/40960 = 409.
7171
// Bug: SMSS*bytes_acked/cwnd = 4096*8192/40960 = 819.
7272
const (
73-
wantIncrement = MaxSegmentSize * MaxSegmentSize / initialCongWin // 409
73+
wantIncrement = MaxSegmentSize * MaxSegmentSize / initialCongWin // 409
7474
bugIncrement = MaxSegmentSize * (2 * MaxSegmentSize) / initialCongWin // 819
75-
wantCongWin = initialCongWin + wantIncrement // 41369
75+
wantCongWin = initialCongWin + wantIncrement // 41369
7676
)
7777
if c.CongWin != wantCongWin {
7878
t.Errorf("CA growth with bytes_acked=2*SMSS: CongWin=%d, want %d "+

pkg/daemon/daemon.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,10 @@ const (
140140

141141
// Dial and retransmission constants.
142142
const (
143-
DialDirectRetries = 3 // direct connection attempts before relay
144-
DialMaxRetries = 7 // total attempts (direct + relay). 3 direct + 4 relay. With DialInitialRTO=250ms exponential-backoff capped at DialMaxRTO=8s, the relay phase is ~7.75s — covers cold-start handshake (key_exchange + flushPending + SYN/SYN-ACK round trip) for typical peers while keeping bad dials from blocking longer than the user's --timeout. The probe-and-adapt machinery (see srttHistory below) will let us shorten this for peers we've successfully dialed before.
145-
DialInitialRTO = 250 * time.Millisecond // initial SYN retransmission timeout. Lowered from 1s — modern relay RTT is <200ms; waiting a full second before assuming loss makes cold dials feel like a stall. Three direct retries with exponential backoff (250→500→1000) still cover up to 1.75s of jitter before flipping to relay; that's plenty for an unhealthy direct path while letting the common case (peer is reachable, single retry needed) feel snappy.
146-
DialMaxRTO = 8 * time.Second // max backoff for SYN retransmission
143+
DialDirectRetries = 3 // direct connection attempts before relay
144+
DialMaxRetries = 7 // total attempts (direct + relay). 3 direct + 4 relay. With DialInitialRTO=250ms exponential-backoff capped at DialMaxRTO=8s, the relay phase is ~7.75s — covers cold-start handshake (key_exchange + flushPending + SYN/SYN-ACK round trip) for typical peers while keeping bad dials from blocking longer than the user's --timeout. The probe-and-adapt machinery (see srttHistory below) will let us shorten this for peers we've successfully dialed before.
145+
DialInitialRTO = 250 * time.Millisecond // initial SYN retransmission timeout. Lowered from 1s — modern relay RTT is <200ms; waiting a full second before assuming loss makes cold dials feel like a stall. Three direct retries with exponential backoff (250→500→1000) still cover up to 1.75s of jitter before flipping to relay; that's plenty for an unhealthy direct path while letting the common case (peer is reachable, single retry needed) feel snappy.
146+
DialMaxRTO = 8 * time.Second // max backoff for SYN retransmission
147147
DialCheckInterval = 10 * time.Millisecond // poll interval for state changes during dial
148148
RetxCheckInterval = 100 * time.Millisecond // retransmission check ticker
149149
MaxRetxAttempts = 8 // abandon connection after this many retransmissions
@@ -3368,8 +3368,8 @@ func (d *Daemon) hostnameCachePath() string {
33683368

33693369
// hostnameCacheDisk is the on-disk format for the hostname cache.
33703370
type hostnameCacheDisk struct {
3371-
SavedAt time.Time `json:"saved_at"`
3372-
Hostnames map[string]hostnameCacheDiskEntry `json:"hostnames"`
3371+
SavedAt time.Time `json:"saved_at"`
3372+
Hostnames map[string]hostnameCacheDiskEntry `json:"hostnames"`
33733373
}
33743374

33753375
type hostnameCacheDiskEntry struct {

pkg/daemon/daemon_ipc_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ func TestHandleBindDoubleBindSendsError(t *testing.T) {
122122
}
123123
ic, client := newIPCTestConn(t)
124124
reply := runHandler(t, client, func() { s.handleBind(ic, []byte{0x23, 0x28}) }) // port 9000
125-
assertErrorReply(t, reply, "port") // "already bound" or similar
125+
assertErrorReply(t, reply, "port") // "already bound" or similar
126126
}
127127

128128
// --- handleDial ---

0 commit comments

Comments
 (0)