Skip to content
This repository was archived by the owner on Aug 4, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2ce9c13
refactor(coupling): enforce server-only materialization
Yeusepe Jul 24, 2026
d843b84
refactor(coupling): own local master initialization
Yeusepe Jul 24, 2026
a9e80a6
feat(coupling): complete verified Linux materialization
Yeusepe Jul 25, 2026
9aaaa6f
feat(coupling): support compact protected assets
Yeusepe Jul 26, 2026
63c978a
feat(coupling): finalize Linux materialization service
Yeusepe Jul 27, 2026
5fbb079
fix(coupling): address materialization review findings
Yeusepe Jul 27, 2026
b7e21dc
fix(coupling): harden Linux materialization sandbox
Yeusepe Jul 27, 2026
487917f
fix(coupling): fence materialization build identity
Yeusepe Jul 27, 2026
c44aba3
fix(coupling): address Linux boundary review findings
Yeusepe Jul 27, 2026
aee1162
fix(coupling): harden reviewed runtime boundaries
Yeusepe Jul 27, 2026
9dd4025
fix(coupling): fence materialization side effects
Yeusepe Jul 27, 2026
0af8d9d
fix(coupling): close reviewed security boundaries
Yeusepe Jul 27, 2026
0720c01
fix(coupling): close Linux materialization review gaps
Yeusepe Jul 27, 2026
6fa1cbe
fix(coupling): enforce reviewed Linux boundaries
Yeusepe Jul 27, 2026
63f4faf
fix(coupling): abort work at lease deadline
Yeusepe Jul 27, 2026
466a58a
fix(coupling): canonicalize protected file derivation
Yeusepe Jul 27, 2026
4e8dff9
fix(coupling): bound Linux materialization resources
Yeusepe Jul 27, 2026
18c1821
fix(coupling): harden Linux deployment boundaries
Yeusepe Jul 27, 2026
db09c1f
fix(coupling): close materialization lifecycle races
Yeusepe Jul 27, 2026
da882e6
fix(coupling): enforce sandbox lease limits
Yeusepe Jul 27, 2026
85a36c4
fix(coupling): harden materialization boundaries
Yeusepe Jul 27, 2026
86491e2
fix(coupling): settle materialization cleanup
Yeusepe Jul 27, 2026
013f149
fix(coupling): harden Linux materialization runtime
Yeusepe Jul 27, 2026
fa9994a
fix(coupling): preserve Linux sandbox ownership
Yeusepe Jul 27, 2026
dd9caec
fix(coupling): harden Linux runtime boundaries
Yeusepe Jul 27, 2026
595bbf4
fix(coupling): bound chunk cache leases
Yeusepe Jul 27, 2026
0b96749
fix(coupling): enforce materialization safety bounds
Yeusepe Jul 27, 2026
d1a2d2a
fix(coupling): canonicalize empty cache chunks
Yeusepe Jul 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 22 additions & 36 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,36 +1,22 @@
COUPLING_SERVICE_SECRET=change-me
COUPLING_SERVICE_HOST=0.0.0.0
COUPLING_SERVICE_PORT=8788
COUPLING_PUBLIC_BASE_URL=http://127.0.0.1:8788
COUPLING_CONTROL_PLANE_BASE_URL=http://127.0.0.1:3210
COUPLING_BROKER_SHARED_SECRET=change-me-too
YUCP_ROOT_PUBLIC_KEY=
# Optional Infisical-backed aliases:
# - YUCP_COUPLING_SERVICE_SHARED_SECRET can supply the local service auth secret.
# - YUCP_BROKER_SHARED_SECRET can supply the broker auth secret for Convex redeem/receipt.
# - API_BASE_URL or SITE_URL can supply the control plane base URL when COUPLING_CONTROL_PLANE_BASE_URL is unset.
# Prefer COUPLING_RUNTIME_LIBRARY_PATH and COUPLING_RUNTIME_LIBRARY_SHA256.
# The older COUPLING_RUNTIME_DLL_* names are still accepted for compatibility.
# Host-native defaults resolve to:
# - Windows x64: .\yucp_coupling\out\win-x64\Release\yucp_coupling.dll
# - Linux x64: .\yucp_coupling\out\linux-x64\Release\yucp_coupling.so
# - macOS arm64: .\yucp_coupling\out\darwin-arm64\Release\yucp_coupling.dylib
COUPLING_RUNTIME_LIBRARY_PATH=
COUPLING_RUNTIME_LIBRARY_SHA256=
COUPLING_RUNTIME_ARTIFACT_PATH=.\yucp_coupling\out\win-x64\Release\runtime-helper\yucp_coupling.dll
COUPLING_RUNTIME_ARTIFACT_VERSION=
COUPLING_RUNTIME_ARTIFACT_CHANNEL=stable
COUPLING_RUNTIME_ARTIFACT_PLATFORM=win-x64
COUPLING_RUNTIME_ARTIFACT_METADATA_VERSION=1
COUPLING_RUNTIME_ARTIFACT_DELIVERY_NAME=yucp_coupling.dll
COUPLING_RUNTIME_ARTIFACT_CODE_SIGNING_SUBJECT=
COUPLING_RUNTIME_ARTIFACT_CODE_SIGNING_THUMBPRINT=
COUPLING_RUNTIME_PACKAGE_ARTIFACT_PATH=
COUPLING_RUNTIME_PACKAGE_ARTIFACT_VERSION=
COUPLING_RUNTIME_PACKAGE_ARTIFACT_DELIVERY_NAME=yucp-coupling-runtime-package.zip
COUPLING_RUNTIME_PACKAGE_ARTIFACT_CODE_SIGNING_SUBJECT=
COUPLING_RUNTIME_PACKAGE_ARTIFACT_CODE_SIGNING_THUMBPRINT=
COUPLING_WORK_ROOT=.\runtime-data
COUPLING_MAX_ASSETS_PER_REQUEST=512
COUPLING_MAX_FILE_BYTES=67108864
# The service accepts either COUPLING_SERVICE_PORT or the generic PORT env.
NODE_ENV=production
MATERIALIZATION_CONTROL_PLANE_BASE_URL=https://api.example.com
MATERIALIZATION_DPOP_PRIVATE_KEY_PKCS8=
MATERIALIZATION_HEALTH_HOST=127.0.0.1
MATERIALIZATION_HEALTH_PORT=8788
MATERIALIZATION_LANE=large
MATERIALIZATION_LEASE_DURATION_MS=600000
MATERIALIZATION_MATERIALIZER_SHARED_SECRET=
MATERIALIZATION_POLL_INTERVAL_MS=1000
MATERIALIZATION_RUNTIME_LIBRARY_PATH=/home/yucp/ca-coupling/yucp_coupling/out/linux-x64/Release/yucp_coupling.so
Comment thread
Yeusepe marked this conversation as resolved.
Outdated
MATERIALIZATION_SERVICE_ID=materializer-large-01
MATERIALIZATION_WORK_ROOT=/var/lib/yucp-materializer
Comment thread
Yeusepe marked this conversation as resolved.
Comment thread
Yeusepe marked this conversation as resolved.
MATERIALIZATION_KEY_BROKER_SHARED_SECRET=
MATERIALIZATION_MASTER_EPOCH_KEYS_FILE=/run/credentials/materialization-master-epochs
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
YUCP_COUPLING_SERVICE_SHARED_SECRET=

# Infisical can load the canonical variables above.
INFISICAL_CLIENT_ID=
INFISICAL_CLIENT_SECRET=
INFISICAL_ENV=production
INFISICAL_PROJECT_ID=
INFISICAL_URL=https://app.infisical.com
24 changes: 23 additions & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 63 additions & 0 deletions deploy/initialize-local-master-credential.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env bash

set -euo pipefail

target="${HOME}/.config/yucp-materializer/materialization-master-epochs"
epoch="${MATERIALIZATION_KEY_EPOCH:-1}"

if [[ ! "${epoch}" =~ ^(0|[1-9][0-9]*)$ ]]; then
echo "The local materialization key epoch is invalid." >&2
exit 64
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.

install -d -m 700 "$(dirname "${target}")"
umask 077
exec 9>"${target}.lock"
flock 9

if [[ -e "${target}" ]]; then
if [[ -L "${target}" || ! -f "${target}" ]]; then
echo "The local materialization credential path is invalid." >&2
exit 78
fi
if [[ "$(stat -c '%u:%a' "${target}")" != "$(id -u):600" ]]; then
echo "The local materialization credential permissions are invalid." >&2
exit 78
fi
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.

temporary="$(mktemp "${target}.tmp.XXXXXX")"
trap 'rm -f "${temporary}"' EXIT

TARGET="${target}" EPOCH="${epoch}" bun --eval '
import { randomBytes } from "node:crypto";
import { readFileSync } from "node:fs";
const target = process.env.TARGET;
const epoch = process.env.EPOCH;
if (!target || !epoch) throw new Error("Credential target is incomplete");
let parsed = {};
try {
parsed = JSON.parse(readFileSync(target, "utf8"));
} catch (error) {
if (error?.code !== "ENOENT") throw error;
}
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
throw new Error("Existing credential is invalid");
}
for (const [key, value] of Object.entries(parsed)) {
if (!/^(0|[1-9][0-9]*)$/.test(key) || typeof value !== "string" ||
!/^[A-Za-z0-9_-]{43}$/.test(value)) {
throw new Error("Existing credential is invalid");
}
}
if (parsed[epoch] === undefined) {
parsed[epoch] = randomBytes(32).toString("base64url");
}
const ordered = Object.fromEntries(
Object.entries(parsed).sort(([left], [right]) => Number(left) - Number(right))
);
process.stdout.write(`${JSON.stringify(ordered)}\n`);
' >"${temporary}"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
chmod 600 "${temporary}"
mv -f "${temporary}" "${target}"
trap - EXIT
26 changes: 26 additions & 0 deletions deploy/initialize-local-master-credential.test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash

set -euo pipefail

repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
run_root="$(mktemp -d)"
trap 'rm -rf -- "${run_root}"' EXIT
export HOME="${run_root}"
export PATH="/home/yucp/.bun/bin:/usr/local/bin:/usr/bin:/bin"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

MATERIALIZATION_KEY_EPOCH=1 \
bash "${repo_root}/deploy/initialize-local-master-credential.sh" &
first_pid=$!
MATERIALIZATION_KEY_EPOCH=2 \
bash "${repo_root}/deploy/initialize-local-master-credential.sh" &
second_pid=$!
wait "${first_pid}"
wait "${second_pid}"
Comment thread
Yeusepe marked this conversation as resolved.
Outdated

target="${HOME}/.config/yucp-materializer/materialization-master-epochs"
grep -q '"1":' "${target}"
grep -q '"2":' "${target}"
test "$(stat -c '%a' "${target}")" = "600"
test -z "$(find "${HOME}" -name '*.tmp.*' -print -quit)"

printf 'Concurrent credential initialization passed.\n'
39 changes: 39 additions & 0 deletions deploy/prepare-local-wsl-materializer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash

set -euo pipefail

source_root="${1:?The coupling source root is required.}"
target="/home/yucp/ca-coupling"

case "${source_root}" in
/mnt/*)
;;
*)
echo "The coupling source root must use a mounted Windows drive." >&2
exit 64
;;
esac
Comment thread
coderabbitai[bot] marked this conversation as resolved.

command -v rsync >/dev/null
command -v socat >/dev/null
command -v /home/yucp/.bun/bin/bun >/dev/null

install -d -m 700 "${target}"
rsync \
-a \
--chmod=Du=rwx,Dgo=,Fu=rw,Fgo= \
--delete \
--exclude=.env \
--exclude=.git \
--exclude=.idea \
--exclude=node_modules \
"${source_root}/" \
"${target}/"

cd "${target}"
chmod 700 deploy/*.sh
/home/yucp/.bun/bin/bun install --frozen-lockfile

test -f deploy/run-local-wsl-materializer.sh
test -f deploy/initialize-local-master-credential.sh
test -f yucp_coupling/out/linux-x64/Release/yucp_coupling.so
Comment thread
coderabbitai[bot] marked this conversation as resolved.
98 changes: 98 additions & 0 deletions deploy/run-local-wsl-materializer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env bash

set -euo pipefail

export PATH="/home/yucp/.bun/bin:/usr/bin:/bin"
export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/1001}"

windows_host="${YUCP_WINDOWS_HOST_IP:?YUCP_WINDOWS_HOST_IP is required}"
source_proxy_port="${MATERIALIZATION_SOURCE_PROXY_PORT:?MATERIALIZATION_SOURCE_PROXY_PORT is required}"
control_proxy_port="${MATERIALIZATION_CONTROL_PLANE_PROXY_PORT:?MATERIALIZATION_CONTROL_PLANE_PROXY_PORT is required}"

if [[ ! "${windows_host}" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "The Windows WSL host address is invalid." >&2
exit 64
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.
IFS=. read -r octet1 octet2 octet3 octet4 <<<"${windows_host}"
for octet in "${octet1}" "${octet2}" "${octet3}" "${octet4}"; do
if (( 10#${octet} > 255 )); then
echo "The Windows WSL host address is invalid." >&2
exit 64
fi
done
if [[ ! "${source_proxy_port}" =~ ^[0-9]+$ ]] || (( source_proxy_port < 1 || source_proxy_port > 65535 )); then
echo "The materialization source proxy port is invalid." >&2
exit 64
fi
if [[ ! "${control_proxy_port}" =~ ^[0-9]+$ ]] || (( control_proxy_port < 1 || control_proxy_port > 65535 )); then
echo "The materialization control proxy port is invalid." >&2
exit 64
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
fi
if [[ "${source_proxy_port}" == "${control_proxy_port}" ]]; then
echo "The materialization proxy ports must be different." >&2
exit 64
Comment thread
Yeusepe marked this conversation as resolved.
Outdated
fi

command -v bun >/dev/null
command -v docker >/dev/null
command -v flock >/dev/null
command -v socat >/dev/null

docker_info="$(docker info --format '{{json .SecurityOptions}}|{{.OSType}}|{{.Architecture}}|{{.CgroupDriver}}')"
if [[ "${docker_info}" != *'"name=rootless"'*'|linux|x86_64|systemd' ]]; then
echo "The rootless Linux Docker isolation gate failed." >&2
exit 78
fi

work_root="${MATERIALIZATION_WORK_ROOT:-/home/yucp/.local/share/yucp-materializer}"
install -d -m 700 "${work_root}"
export MATERIALIZATION_WORK_ROOT="${work_root}"
exec 9>"${work_root}/local-materializer.lock"
if ! flock -n 9; then
echo "Another local materializer owns the WSL worker lock." >&2
exit 75
fi

/home/yucp/ca-coupling/deploy/initialize-local-master-credential.sh
Comment thread
coderabbitai[bot] marked this conversation as resolved.
export MATERIALIZATION_MASTER_EPOCH_KEYS_FILE="$HOME/.config/yucp-materializer/materialization-master-epochs"

declare -a proxy_pids=()
server_pid=""

cleanup() {
local status=$?
trap - EXIT INT TERM
if [[ -n "${server_pid}" ]]; then
kill "${server_pid}" 2>/dev/null || true
fi
for proxy_pid in "${proxy_pids[@]}"; do
kill "${proxy_pid}" 2>/dev/null || true
done
if [[ -n "${server_pid}" ]]; then
wait "${server_pid}" 2>/dev/null || true
fi
for proxy_pid in "${proxy_pids[@]}"; do
wait "${proxy_pid}" 2>/dev/null || true
done
exit "${status}"
}

trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM

start_loopback_proxy() {
local port=$1
socat \
"TCP4-LISTEN:${port},bind=127.0.0.1,reuseaddr,fork" \
"TCP4:${windows_host}:${port}" &
proxy_pids+=("$!")
}

start_loopback_proxy "${source_proxy_port}"
start_loopback_proxy "${control_proxy_port}"

cd /home/yucp/ca-coupling
bun src/materializationServer.ts &
server_pid=$!
wait "${server_pid}"
Comment thread
Yeusepe marked this conversation as resolved.
Outdated
38 changes: 38 additions & 0 deletions deploy/run-local-wsl-materializer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { describe, expect, test } from 'bun:test';
import { readFile } from 'node:fs/promises';
import path from 'node:path';

describe('local WSL materializer entry point', () => {
test('uses the isolated runtime proxy ports instead of fixed shared ports', async () => {
const source = await readFile(
path.join(import.meta.dir, 'run-local-wsl-materializer.sh'),
'utf8'
);

expect(source).toContain(
`source_proxy_port="\${MATERIALIZATION_SOURCE_PROXY_PORT:?MATERIALIZATION_SOURCE_PROXY_PORT is required}"`
);
expect(source).toContain(
`control_proxy_port="\${MATERIALIZATION_CONTROL_PLANE_PROXY_PORT:?MATERIALIZATION_CONTROL_PLANE_PROXY_PORT is required}"`
);
expect(source).toContain(`start_loopback_proxy "\${source_proxy_port}"`);
expect(source).toContain(`start_loopback_proxy "\${control_proxy_port}"`);
expect(source).not.toContain('start_loopback_proxy 3005');
expect(source).not.toContain('start_loopback_proxy 3012');
});

test('validates proxy topology and exports the resolved work root', async () => {
const source = await readFile(
path.join(import.meta.dir, 'run-local-wsl-materializer.sh'),
'utf8'
);

expect(source).toContain(`10#\${octet} > 255`);
expect(source).toContain(
`[[ "\${source_proxy_port}" == "\${control_proxy_port}" ]]`
);
expect(source).toContain(
`export MATERIALIZATION_WORK_ROOT="\${work_root}"`
);
});
});
Loading