Clank Together: coordinator, sandboxed verifier and agent client

Coordinator (accounts with approval, API tokens, tasks with leases, sandboxed MSVC verification against
the original exe, peer review by three agents for non-identical code, human review, serial merge queue),
the `td` contributor CLI with an MCP server for agents, pinned Ghidra integration, deployment (Caddy,
systemd, nftables, Forgejo) and the wowdecomp 15890 migration tools.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNwtXPYqFu3oKaaXwYwNWW
This commit is contained in:
Clank Together 2026-10-18 01:29:16 +02:00
commit 836610da8f
67 changed files with 19284 additions and 0 deletions

View file

@ -0,0 +1,33 @@
# VS2010 SP1 x64 compiler (cl 16.00.40219.01 for x64) under 64-bit Wine, for compiling untrusted
# submissions of wowdecomp15890. Build context: this directory plus toolchain.tar from pack.sh.
#
# sh pack.sh "<re/toolchain>" . (on the machine that has the toolchain)
# docker build -t togetherdecomp/msvc2010-x64:1 .
#
# The image is for the coordinator only: the Microsoft files in it are not redistributable.
FROM debian:13-slim
RUN dpkg --add-architecture i386 \
&& apt-get update \
&& apt-get install -y --no-install-recommends wine wine64 libwine ca-certificates coreutils \
&& rm -rf /var/lib/apt/lists/*
# ${TC} of config/compile.json is Z:\opt\toolchain.
ADD toolchain.tar /opt/toolchain/
RUN cp "/opt/toolchain/vs2010sp1/vc_stdamd64/Win/System64/msvcr100.dll" \
"/opt/toolchain/vs2010sp1/vc_stdamd64/Program Files(64)/Microsoft Visual Studio 10.0/VC/bin/amd64/" \
&& chmod -R a+rX /opt/toolchain
COPY env.sh /opt/td/env.sh
RUN mkdir -p /opt/td/wineprefix && chmod 777 /opt/td/wineprefix
ENV WINEPREFIX=/opt/td/wineprefix WINEDEBUG=-all WINEARCH=win64 HOME=/tmp
# Create the prefix at build time; each run copies it to tmpfs (the root filesystem is read-only).
# cl.exe writes intermediate files to %TEMP%; point it at the container's tmpfs instead of the
# build user's profile (the registry value wins over the Unix environment).
RUN wineboot --init && wineserver -w \
&& wine reg add 'HKCU\Environment' /v TEMP /t REG_SZ /d 'Z:\tmp' /f \
&& wine reg add 'HKCU\Environment' /v TMP /t REG_SZ /d 'Z:\tmp' /f \
&& wineserver -w && chmod -R a+rwX /opt/td/wineprefix
WORKDIR /job

View file

@ -0,0 +1,21 @@
# Sourced by the generated job scripts inside the sandbox. The root filesystem is read-only, so
# each container gets its own Wine prefix in tmpfs: a symlink farm of the baked one (cp -rs, ~60 KB
# instead of ~770 MB). Its directories belong to the sandbox user, which Wine requires; Wine
# replaces a link with a real file only where it writes (registry). build.sh sources this first,
# before the units run in parallel.
export WINEPREFIX=/tmp/wineprefix
export WINEDEBUG=-all
export WINEARCH=win64
export HOME=/tmp
# cl.exe writes its intermediate files to %TMP%; the prefix's profile belongs to the image's build user.
export TMP='Z:\tmp' TEMP='Z:\tmp'
if [ ! -d "$WINEPREFIX" ]; then
cp -rs /opt/td/wineprefix "$WINEPREFIX"
# One persistent wineserver for all parallel compiles of this container.
wineserver -p >/dev/null 2>&1 || true
fi
TD_CL="/opt/toolchain/vs2010sp1/vc_stdamd64/Program Files(64)/Microsoft Visual Studio 10.0/VC/bin/amd64/cl.exe"
td_cl() {
wine "$TD_CL" "$@"
}

View file

@ -0,0 +1,33 @@
#!/bin/sh
# Packs the parts of re/toolchain that compile wowdecomp15890 (VS2010 SP1 x64 compiler, its CRT
# headers, Windows SDK 7.1 headers, DirectX SDK headers, compat overlays) into toolchain.tar,
# keeping their layout so the ${TC}\... paths of config/compile.json resolve inside the image.
#
# sh pack.sh "<path to re/toolchain>" <out dir>
#
# The Microsoft files are not redistributable: the tarball is for your own build server only.
set -eu
TC="${1:?usage: pack.sh <re/toolchain dir> <out dir>}"
OUT="${2:?usage: pack.sh <re/toolchain dir> <out dir>}"
mkdir -p "$OUT"
cd "$TC"
# --force-local: "C:/..." is a path, not a remote host (Git Bash on Windows).
# --owner/--group: Docker with userns-remap cannot map the packing machine's user IDs.
tar --force-local --owner=0 --group=0 --numeric-owner -cf "$OUT/toolchain.tar" \
"vs2010sp1/vc_stdamd64/Program Files(64)/Microsoft Visual Studio 10.0/VC/bin/amd64/cl.exe" \
"vs2010sp1/vc_stdamd64/Program Files(64)/Microsoft Visual Studio 10.0/VC/bin/amd64/c1.dll" \
"vs2010sp1/vc_stdamd64/Program Files(64)/Microsoft Visual Studio 10.0/VC/bin/amd64/c1xx.dll" \
"vs2010sp1/vc_stdamd64/Program Files(64)/Microsoft Visual Studio 10.0/VC/bin/amd64/c2.dll" \
"vs2010sp1/vc_stdamd64/Program Files(64)/Microsoft Visual Studio 10.0/VC/bin/amd64/mspdb100.dll" \
"vs2010sp1/vc_stdamd64/Program Files(64)/Microsoft Visual Studio 10.0/VC/bin/amd64/msobj100.dll" \
"vs2010sp1/vc_stdamd64/Program Files(64)/Microsoft Visual Studio 10.0/VC/bin/amd64/mspdbcore.dll" \
"vs2010sp1/vc_stdamd64/Program Files(64)/Microsoft Visual Studio 10.0/VC/bin/amd64/mspdbsrv.exe" \
"vs2010sp1/vc_stdamd64/Program Files(64)/Microsoft Visual Studio 10.0/VC/bin/amd64/1033/clui.dll" \
"vs2010sp1/vc_stdamd64/Win/System64/msvcr100.dll" \
"vs2010sp1/vc_stdx86/Program Files/Microsoft Visual Studio 10.0/VC/include" \
"vs2010sp1/sdk71/Program Files/Microsoft SDKs/Windows/v7.1/Include" \
vs2010sp1/compat \
vs2008/compat \
dxsdk/DXSDK/Include
sha256sum "vs2010sp1/vc_stdamd64/Program Files(64)/Microsoft Visual Studio 10.0/VC/bin/amd64/cl.exe" | cut -d' ' -f1 > "$OUT/cl.sha256"
echo "wrote $OUT/toolchain.tar (cl.exe sha256 $(cat "$OUT/cl.sha256"))"

View file

@ -0,0 +1,35 @@
# MSVC 2010 (cl.exe 16.00) under Wine, used to compile untrusted submissions.
#
# The Microsoft compiler is NOT redistributable, so it is not in this repo.
# Before building, copy these from a licensed Visual Studio 2010 install
# into ./msvc (next to this Dockerfile):
#
# msvc/bin/ cl.exe c1.dll c1xx.dll c2.dll mspdb100.dll msobj100.dll
# mspdbcore.dll mspdbsrv.exe msvcr100.dll msvcp100.dll 1033/clui.dll
# msvc/include/ VC\include
# msvc/sdk/ Windows SDK 7.0A Include (only if the code includes windows.h)
#
# Build: docker build -t togetherdecomp/msvc2010:1 toolchain/msvc2010
# Then pin the resulting digest and cl.exe hash in the repo's toolchain.lock.json.
FROM debian:12-slim
RUN dpkg --add-architecture i386 \
&& apt-get update \
&& apt-get install -y --no-install-recommends wine wine32:i386 ca-certificates coreutils \
&& rm -rf /var/lib/apt/lists/*
COPY msvc/ /opt/msvc/
COPY env.sh /opt/td/env.sh
RUN useradd -u 1000 -m builder \
&& mkdir -p /opt/td/wineprefix \
&& chown builder /opt/td/wineprefix
USER builder
ENV WINEPREFIX=/opt/td/wineprefix WINEDEBUG=-all WINEARCH=win32
# Create the prefix at build time; each run copies it to tmpfs because the
# container root filesystem is read-only.
RUN wineboot --init && wineserver -w
WORKDIR /job

11
toolchain/msvc2010/env.sh Normal file
View file

@ -0,0 +1,11 @@
# Sourced by the generated /job/build.sh inside the sandbox.
# The root filesystem is read-only, so the baked Wine prefix is copied to tmpfs.
cp -a /opt/td/wineprefix /tmp/wineprefix
export WINEPREFIX=/tmp/wineprefix
export WINEDEBUG=-all
export INCLUDE='Z:\opt\msvc\include;Z:\opt\msvc\sdk\Include'
export HOME=/tmp
td_cl() {
wine /opt/msvc/bin/cl.exe "$@"
}