Skip to content

Commit c67a481

Browse files
authored
bridge: fix stale runtime slack-bridge path references (#160)
1 parent fc4fb6e commit c67a481

5 files changed

Lines changed: 49 additions & 17 deletions

File tree

bin/ci/smoke-agent-runtime.sh

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@ wait_for_control_socket() {
6868

6969
probe_rpc_get_message() {
7070
local socket_path="$1"
71-
sudo -u "$AGENT_USER" python3 - "$socket_path" <<'PY'
71+
local attempts=8
72+
local delay_seconds=1
73+
74+
for ((i = 1; i <= attempts; i++)); do
75+
if sudo -u "$AGENT_USER" python3 - "$socket_path" <<'PY'
7276
import json
7377
import socket
7478
import sys
@@ -103,6 +107,15 @@ try:
103107
finally:
104108
client.close()
105109
PY
110+
then
111+
return 0
112+
fi
113+
114+
log "rpc probe attempt ${i}/${attempts} failed; retrying in ${delay_seconds}s"
115+
sleep "$delay_seconds"
116+
done
117+
118+
return 1
106119
}
107120

108121
main() {

bin/deploy.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,14 @@ deploy_runtime_asset_entry() {
293293

294294
bb_manifest_for_each RUNTIME_ASSET_MANIFEST deploy_runtime_asset_entry
295295

296+
# Clean up legacy bridge runtime path; bridge now runs from /opt release only.
297+
if [ "$DRY_RUN" -eq 0 ]; then
298+
as_agent bash -c "rm -rf '$BAUDBOT_HOME/runtime/slack-bridge'"
299+
log "✓ removed legacy runtime/slack-bridge"
300+
else
301+
log "would remove: runtime/slack-bridge (legacy path)"
302+
fi
303+
296304
# ── Memory Seeds ─────────────────────────────────────────────────────────────
297305

298306
MEMORY_SEED_DIR="$STAGE_DIR/skills/control-agent/memory"

pi/extensions/tool-guard.test.mjs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const BASH_DENY_RULES = [
4646
{ id: "chmod-baudbot-source", pattern: new RegExp(`chmod\\b.*${escapeRegex(BAUDBOT_SOURCE_DIR)}`), label: "chmod on baudbot source repo", severity: "block" },
4747
{ id: "chown-baudbot-source", pattern: new RegExp(`chown\\b.*${escapeRegex(BAUDBOT_SOURCE_DIR)}`), label: "chown on baudbot source repo", severity: "block" },
4848
{ id: "tee-baudbot-source", pattern: new RegExp(`tee\\s+.*${escapeRegex(BAUDBOT_SOURCE_DIR)}/`), label: "tee write to baudbot source repo", severity: "block" },
49-
{ id: "chmod-runtime-security", pattern: /chmod\b.*\/(\.pi\/agent\/extensions\/tool-guard|runtime\/slack-bridge\/security)\./, label: "chmod on protected runtime security file", severity: "block" },
49+
{ id: "chmod-runtime-security", pattern: /chmod\b.*\/(\.pi\/agent\/extensions\/tool-guard|runtime\/slack-bridge\/security|opt\/baudbot\/current\/slack-bridge\/security)\./, label: "chmod on protected runtime security file", severity: "block" },
5050
// Credential exfiltration
5151
{ id: "env-exfil-curl", pattern: /\benv\b.*\|\s*(curl|wget|nc)\b/, label: "Piping environment to network tool", severity: "block" },
5252
{ id: "cat-env-curl", pattern: /cat\s+.*\.env.*\|\s*(curl|wget|nc)\b/, label: "Exfiltrating .env via network", severity: "block" },
@@ -77,8 +77,8 @@ function isAllowedWritePath(filePath) {
7777
const PROTECTED_RUNTIME_FILES = [
7878
`${AGENT_HOME}/.pi/agent/extensions/tool-guard.ts`,
7979
`${AGENT_HOME}/.pi/agent/extensions/tool-guard.test.mjs`,
80-
`${AGENT_HOME}/runtime/slack-bridge/security.mjs`,
81-
`${AGENT_HOME}/runtime/slack-bridge/security.test.mjs`,
80+
`/opt/baudbot/current/slack-bridge/security.mjs`,
81+
`/opt/baudbot/current/slack-bridge/security.test.mjs`,
8282
];
8383

8484
function isProtectedPath(filePath) {
@@ -307,7 +307,7 @@ describe("tool-guard: source repo protection (bash)", () => {
307307
assert.equal(checkBashCommand(`chmod a+w ${AGENT_HOME}/.pi/agent/extensions/tool-guard.ts`).blocked, true);
308308
});
309309
it("blocks chmod on runtime security.mjs", () => {
310-
assert.equal(checkBashCommand(`chmod 777 ${AGENT_HOME}/runtime/slack-bridge/security.mjs`).blocked, true);
310+
assert.equal(checkBashCommand("chmod 777 /opt/baudbot/current/slack-bridge/security.mjs").blocked, true);
311311
});
312312
});
313313

@@ -358,8 +358,8 @@ describe("tool-guard: workspace confinement (allow-list)", () => {
358358
it(`allows write to ${AGENT_HOME}/.pi/agent/skills/new-skill/SKILL.md`, () => {
359359
assert.equal(checkWritePath(`${AGENT_HOME}/.pi/agent/skills/new-skill/SKILL.md`), false);
360360
});
361-
it(`allows write to ${AGENT_HOME}/runtime/slack-bridge/bridge.mjs`, () => {
362-
assert.equal(checkWritePath(`${AGENT_HOME}/runtime/slack-bridge/bridge.mjs`), false);
361+
it("blocks write to /opt/baudbot/current/slack-bridge/bridge.mjs", () => {
362+
assert.equal(checkWritePath("/opt/baudbot/current/slack-bridge/bridge.mjs"), true);
363363
});
364364

365365
// BLOCKED: outside agent home
@@ -430,13 +430,13 @@ describe("tool-guard: protected runtime security files", () => {
430430
assert.equal(checkWritePath(`${AGENT_HOME}/.pi/agent/extensions/tool-guard.test.mjs`), true);
431431
});
432432
it("blocks write to runtime security.mjs", () => {
433-
assert.equal(checkWritePath(`${AGENT_HOME}/runtime/slack-bridge/security.mjs`), true);
433+
assert.equal(checkWritePath("/opt/baudbot/current/slack-bridge/security.mjs"), true);
434434
});
435435
it("blocks write to runtime security.test.mjs", () => {
436-
assert.equal(checkWritePath(`${AGENT_HOME}/runtime/slack-bridge/security.test.mjs`), true);
436+
assert.equal(checkWritePath("/opt/baudbot/current/slack-bridge/security.test.mjs"), true);
437437
});
438-
it("allows write to runtime bridge.mjs (agent-modifiable)", () => {
439-
assert.equal(checkWritePath(`${AGENT_HOME}/runtime/slack-bridge/bridge.mjs`), false);
438+
it("blocks write to runtime bridge.mjs (immutable release path)", () => {
439+
assert.equal(checkWritePath("/opt/baudbot/current/slack-bridge/bridge.mjs"), true);
440440
});
441441
it("allows write to runtime non-security extensions", () => {
442442
assert.equal(checkWritePath(`${AGENT_HOME}/.pi/agent/extensions/auto-name.ts`), false);

pi/extensions/tool-guard.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ const BASH_DENY_RULES: DenyRule[] = [
253253
] : []),
254254
{
255255
id: "chmod-runtime-security",
256-
pattern: /chmod\b.*\/(\.pi\/agent\/extensions\/tool-guard|runtime\/slack-bridge\/security)\./,
256+
pattern: /chmod\b.*\/(\.pi\/agent\/extensions\/tool-guard|runtime\/slack-bridge\/security|opt\/baudbot\/current\/slack-bridge\/security)\./,
257257
label: "chmod on protected runtime security file",
258258
severity: "block" as const,
259259
tier: "high" as const,
@@ -311,8 +311,8 @@ function isAllowedWritePath(filePath: string): boolean {
311311
const PROTECTED_RUNTIME_FILES = [
312312
`${AGENT_HOME}/.pi/agent/extensions/tool-guard.ts`,
313313
`${AGENT_HOME}/.pi/agent/extensions/tool-guard.test.mjs`,
314-
`${AGENT_HOME}/runtime/slack-bridge/security.mjs`,
315-
`${AGENT_HOME}/runtime/slack-bridge/security.test.mjs`,
314+
`/opt/baudbot/current/slack-bridge/security.mjs`,
315+
`/opt/baudbot/current/slack-bridge/security.test.mjs`,
316316
];
317317

318318
function isProtectedPath(filePath: string): boolean {

pi/skills/control-agent/startup-cleanup.sh

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ set -euo pipefail
1616
# processes and causes `varlock run` to treat subcommands as Node module paths).
1717
unset PKG_EXECPATH 2>/dev/null || true
1818

19+
RUNTIME_NODE_HELPER="$HOME/runtime/bin/lib/runtime-node.sh"
20+
if [ -r "$RUNTIME_NODE_HELPER" ]; then
21+
# shellcheck source=bin/lib/runtime-node.sh
22+
source "$RUNTIME_NODE_HELPER"
23+
fi
24+
1925
SOCKET_DIR="$HOME/.pi/session-control"
2026

2127
if [ $# -eq 0 ]; then
@@ -123,20 +129,25 @@ fi
123129
# The tmux session stays alive independently of this script (same pattern as
124130
# sentry-agent). If the bridge crashes, the loop restarts it after 5 seconds.
125131
echo "Starting slack-bridge ($BRIDGE_SCRIPT) via tmux..."
126-
NODE_BIN_DIR="$HOME/opt/node/bin"
132+
NODE_BIN_DIR="${NODE_BIN_DIR:-$HOME/opt/node/bin}"
133+
if command -v bb_resolve_runtime_node_bin_dir >/dev/null 2>&1; then
134+
NODE_BIN_DIR="$(bb_resolve_runtime_node_bin_dir "$HOME")"
135+
fi
127136
if [ ! -d "$NODE_BIN_DIR" ]; then
128137
# Fallback: resolve versioned node dir
129138
NODE_BIN_DIR="$(echo "$HOME"/opt/node-v*-linux-x64/bin | awk '{print $1}')"
130139
fi
131140

132141
tmux new-session -d -s "$BRIDGE_TMUX_SESSION" "\
133142
unset PKG_EXECPATH; \
134-
export PATH=\$HOME/.varlock/bin:$NODE_BIN_DIR:\$PATH; \
143+
export PATH=$NODE_BIN_DIR:\$PATH; \
135144
export PI_SESSION_ID=$MY_UUID; \
136145
cd $BRIDGE_DIR; \
137146
while true; do \
138147
echo \"[\$(date -Is)] bridge: starting $BRIDGE_SCRIPT\" >> $BRIDGE_LOG_FILE; \
139-
varlock run --path \$HOME/.config/ -- node $BRIDGE_SCRIPT >> $BRIDGE_LOG_FILE 2>&1; \
148+
for v in \$(env | grep ^SLACK_BROKER_ | cut -d= -f1 || true); do unset \$v; done; \
149+
set -a; source \$HOME/.config/.env; set +a; \
150+
node $BRIDGE_SCRIPT >> $BRIDGE_LOG_FILE 2>&1; \
140151
exit_code=\$?; \
141152
echo \"[\$(date -Is)] bridge: exited with code \$exit_code, restarting in 5s\" >> $BRIDGE_LOG_FILE; \
142153
sleep 5; \

0 commit comments

Comments
 (0)