From 5743568bf19fe11535fe4d9e78c8bee6e95ee690 Mon Sep 17 00:00:00 2001 From: Neuron Date: Sun, 9 Aug 2026 11:38:01 -0500 Subject: [PATCH] chore(engine): deploys build from the committed input, not a second lineage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until now deploys were built by build-soul.sh from a scratch amalgam while CI compiled the committed dist/soul.c. Two lineages — 'what runs' and 'what the repo says builds' were different artifacts. That is #133/#111 in another costume, and it is how a round-9.1 brain shipped matching no committed source at all. build-soul-from-dist.sh asserts dist/soul.c matches the .el sources, compiles it with CI's own flags (-O2 -DHAVE_CURL -rdynamic; the CI comment explains -rdynamic — without it the runtime cannot resolve its HTTP handler by name and the binary serves nothing on every route), and writes a .provenance sidecar recording the dist/soul.c hash, the stamp hash and the commit. deploy_binary.sh gains GATE 0: refuse any soul without provenance, or built from a dist/soul.c other than the one in the repo now. The override (NEURON_DEPLOY_UNSTAMPED=i-accept-two-lineages) exists deliberately — a gate with no escape hatch gets bypassed by disabling the gate, which is worse than one that announces itself. Verified before enforcing, so the sanctioned path is not a broken one: interface parity with the deployed binary 108 routes in, 108 out boots and serves 2s carries today's work 24 self-neighbours, 17 identity records GATE 0 refuses an unstamped binary exit 10 GATE 0 accepts the stamped one, deployed durability PASS Production now runs 4845db3d, built from dist/soul.c at 9fd8c11. After the swap: identity in context 17, connections still form on write, semantic recall intact, mind and store at delta 0. Refs #133, #111 Co-Authored-By: Claude Opus 5 (1M context) --- tools/build-soul-from-dist.sh | 59 +++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100755 tools/build-soul-from-dist.sh diff --git a/tools/build-soul-from-dist.sh b/tools/build-soul-from-dist.sh new file mode 100755 index 0000000..9841d60 --- /dev/null +++ b/tools/build-soul-from-dist.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# build-soul-from-dist.sh — build a deployable soul from the SAME input CI compiles. +# +# THE PROBLEM THIS CLOSES: until now, deploys were built by build-soul.sh, which +# compiles a scratch amalgam and never touches dist/soul.c. CI compiles dist/soul.c. +# Two lineages. On 2026-08-09 the committed input fell 2,761 bytes behind the sources +# while three binaries built the other way were installed on the operator machine — +# so "what runs" and "what the repo says builds" were different artifacts again, +# which is the whole of #133 and #111 wearing new clothes. +# +# This builds from dist/soul.c with CI's own flags, after asserting that dist/soul.c +# actually matches the .el sources, and writes a provenance sidecar so a deployer can +# refuse anything of unknown origin. +# +# -rdynamic and -DHAVE_CURL are copied from .gitea/workflows/ci.yaml deliberately. +# The CI comment explains -rdynamic: without it the runtime cannot resolve its HTTP +# handler by name via dlsym and the binary serves nothing on every route. +# +# usage: build-soul-from-dist.sh +set -u +OUT="${1:?usage: build-soul-from-dist.sh }" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +RUNTIME="$ROOT/vendor/el-runtime/v1.0.0-20260501" + +cd "$ROOT" || exit 2 + +echo "[build-from-dist] GATE: does dist/soul.c match the sources?" +if ! ./tools/soulc-stamp.sh --check; then + echo "[build-from-dist] REFUSING — the build input is stale. Regenerate and stamp first." >&2 + exit 9 +fi + +[ -f "$RUNTIME/el_runtime.c" ] || { echo "pinned runtime missing at $RUNTIME" >&2; exit 2; } + +echo "[build-from-dist] compiling dist/soul.c with CI's flags" +cc -O2 -DHAVE_CURL -rdynamic \ + -I"$RUNTIME" \ + dist/soul.c \ + "$RUNTIME/el_runtime.c" \ + -lcurl -lpthread -lm \ + -o "$OUT" || { echo "[build-from-dist] COMPILE FAILED" >&2; exit 3; } + +# Provenance sidecar: what a deployer checks before installing anything. +SRC_SHA="$(shasum -a 256 dist/soul.c | awk '{print $1}')" +STAMP_SHA="$(shasum -a 256 dist/soul.c.stamp | awk '{print $1}')" +COMMIT="$(git rev-parse HEAD 2>/dev/null || echo unknown)" +DIRTY="clean"; [ -n "$(git status --porcelain -- '*.el' dist/soul.c 2>/dev/null)" ] && DIRTY="DIRTY" +cat > "$OUT.provenance" < $OUT ($(wc -c < "$OUT" | tr -d ' ') bytes)" +echo "[build-from-dist] provenance -> $OUT.provenance (commit ${COMMIT:0:8}, worktree $DIRTY)"