Files
Miles WardandClaude Fable 5 76112eadf6
Sync upstream and build images / sync-and-build (push) Successful in 2m4s
Track the newest release candidate: :latest alias, current-version freshness, on-demand revisions
Operating model change, at the operator's request: the deployment follows
the newest release candidate rather than a hand-pinned version.

- :latest is now published, as a manifest copy (identical digest) of the
  newest build of the newest RC version. It is the ONLY tag that moves;
  every <version>[-rN] tag stays immutable for anyone who wants to pin.
- Freshness (pnpm / base image / recipe hash) now applies to the current
  version derived from the registry, not to a Dockerfile constant, so an
  image fix reaches the deployed line automatically. The `revise` dispatch
  input rebuilds any older versions with the current recipe on demand.
- Smoke test now runs on a fresh named volume (root-owned, like a new Unraid
  appdata dir) and asserts pid 1 is uid 1000 - the ownership fix is exercised
  on every build, not just locally.
- Releases: `latest` gets no release; the "pinned deployment" callout is gone
  (the README and the alias are the source of truth now).
- 0.1.1-rc.2 is deprecated; its -r2/-r49/-r52 revisions were removed
  (images, tags, releases). The original tag remains as history.
- README/template: :latest in the Repository field, auto-update warning,
  versions table and upgrade procedure rewritten for the new model.
  Forensic workflow's trusted default -> :latest. inspect-deployment default
  container name -> Deepseek.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-09-11 12:35:40 -04:00

101 lines
5.1 KiB
YAML

name: Validate suspect image
# Manual-only forensic comparison of a third-party deepseek-harness image
# already present on the runner host's docker daemon against the trusted image
# built by this repository. The suspect image is NEVER executed: `docker
# create` only materializes a container's filesystem, and every inspection
# happens on exported tar content.
on:
workflow_dispatch:
inputs:
suspect:
description: Suspect image reference (must already be present locally)
default: runzhliu/deepseek-harness:0.1.1-rc.2
trusted:
description: Trusted image reference
default: gitea.milesward.dev/mward4/deepseek-harness:latest
jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Locate suspect image (never pulled, never run)
run: |
set -eu
SUSPECT="${{ inputs.suspect || 'runzhliu/deepseek-harness:0.1.1-rc.2' }}"
if ! docker image inspect "$SUSPECT" > /tmp/suspect-inspect.json 2>/dev/null; then
echo "::error::suspect image $SUSPECT is not present on this daemon"
docker images | grep -i deepseek || true
exit 1
fi
echo "== suspect config (entrypoint/cmd/env/user) =="
docker image inspect --format \
'Entrypoint={{json .Config.Entrypoint}} Cmd={{json .Config.Cmd}} User={{json .Config.User}} Env={{json .Config.Env}} Labels={{json .Config.Labels}}' \
"$SUSPECT"
echo "== suspect digests =="
docker image inspect --format '{{json .RepoDigests}} id={{.Id}}' "$SUSPECT"
echo "== containers using the suspect image on this host =="
docker ps -a --filter "ancestor=$SUSPECT" --format '{{.ID}} {{.Names}} {{.Status}} {{.Ports}}' || true
- name: Export both filesystems
run: |
set -eu
SUSPECT="${{ inputs.suspect || 'runzhliu/deepseek-harness:0.1.1-rc.2' }}"
TRUSTED="${{ inputs.trusted || 'gitea.milesward.dev/mward4/deepseek-harness:latest' }}"
docker pull -q "$TRUSTED"
mkdir -p /tmp/suspect /tmp/trusted
s=$(docker create "$SUSPECT")
t=$(docker create "$TRUSTED")
docker export "$s" | tar -x -C /tmp/suspect
docker export "$t" | tar -x -C /tmp/trusted
docker rm "$s" "$t" > /dev/null
- name: Compare installed dsh package against trusted build
run: |
set -eu
echo "== dsh install locations in suspect =="
find /tmp/suspect -maxdepth 6 -type d -name dsh -path '*@deepseek-ai*' | tee /tmp/suspect-dsh-dirs
SDIR=$(head -1 /tmp/suspect-dsh-dirs || true)
TDIR=/tmp/trusted/usr/local/lib/node_modules/@deepseek-ai/dsh
if [ -z "${SDIR}" ]; then
echo "::warning::no @deepseek-ai/dsh install found in suspect image"
else
echo "== package.json versions =="
grep -E '"(name|version)"' "$SDIR/package.json" "$TDIR/package.json" | head -8
echo "== dsh's OWN code (node_modules excluded) =="
if diff -r --exclude=node_modules "$SDIR" "$TDIR" > /tmp/dsh-own-diff.txt 2>&1; then
echo "IDENTICAL: suspect's dsh code matches the official npm release byte-for-byte"
else
echo "DSH CODE DIFFERENCES FOUND:"
cat /tmp/dsh-own-diff.txt
fi
echo "== dependency tree (node_modules) summary =="
if diff -r "$SDIR/node_modules" "$TDIR/node_modules" > /tmp/dsh-dep-diff.txt 2>&1; then
echo "dependencies identical"
else
echo "$(grep -c '^diff -r\|^Only in' /tmp/dsh-dep-diff.txt) differing/unique dependency files"
echo "-- packages with version changes --"
grep -A0 'package.json$' /tmp/dsh-dep-diff.txt | sed 's|.*node_modules/||; s|/package.json.*||' | sort -u | head -30
fi
fi
- name: Scan suspect for tampering red flags
run: |
set -eu
cd /tmp/suspect
echo "== world-reachable startup hooks =="
ls -la etc/cron* etc/init.d 2>/dev/null || true
find . -maxdepth 3 -name "*.sh" -newer usr/local 2>/dev/null | head || true
echo "== 0.0.0.0 safety check still present? =="
grep -rl "intentionally not supported yet for safety" \
usr/local/lib/node_modules 2>/dev/null \
&& echo "OK: upstream 0.0.0.0 refusal intact" \
|| echo "SUSPICIOUS: upstream 0.0.0.0 safety refusal NOT found (patched out?)"
echo "== network callouts baked into image config =="
grep -rEo "https?://[a-zA-Z0-9./_-]+" usr/local/lib/node_modules/@deepseek-ai/dsh/package.json 2>/dev/null | sort -u | head
echo "== extra npm packages not in trusted image =="
(cd /tmp/suspect && find usr -maxdepth 5 -type d -path '*node_modules/*' ! -path '*node_modules/*/node_modules*' 2>/dev/null | sort) > /tmp/s.pkgs || true
(cd /tmp/trusted && find usr -maxdepth 5 -type d -path '*node_modules/*' ! -path '*node_modules/*/node_modules*' 2>/dev/null | sort) > /tmp/t.pkgs || true
diff /tmp/s.pkgs /tmp/t.pkgs | head -40 || true