www_archline_hu/build-baseline.sh
LÁZÁR Imre AI Agent 32cb5b765b build(baseline): constituents+generator skeleton
Re-architect the baseline as constituents + a generator script (build-baseline.sh)
instead of a checked-out deployed tree: a deployed Joomla docroot differs from the
repo/source layout, so the script manifest-maps packaged extensions (lib/jmap.py),
places no-source and Cadline files, applies core overrides, excludes malware/data,
and emits out/ = the code baseline the operator HIDS verifier consumes.

Adds RUNBOOK.md (recipe+inventory), PROVENANCE.md (upstream map), malware-iocs.

Signed-off-by: LÁZÁR Imre <imre@illusion.hu>
Assisted-by: claude-code@claude-opus-4-8
2026-07-16 09:40:46 +02:00

80 lines
3.1 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# build-baseline.sh — reproducibly assemble the www.archline.hu clean CODE baseline.
#
# Output (out/) = the deployed docroot (code only), which the illusion/hids
# baseline-diff (imrcli vanilla_ref) verifies the live server against.
#
# The repo stores the baseline CONSTITUENTS, not the deployed tree; this script
# performs the deterministic "deployment" (Joomla manifest-mapping for packaged
# extensions, direct placement for no-source ones), per RUNBOOK.md.
#
# Usage: ./build-baseline.sh [OUT_DIR] (default: ./out)
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
OUT="${1:-$ROOT/out}"
JMAP="$ROOT/lib/jmap.py"
log(){ printf '[build] %s\n' "$*"; }
rm -rf "$OUT"; mkdir -p "$OUT"
# 1) Joomla core — official 3.8.11 package (deployed form), minus demo assets and
# runtime data dirs (cache/tmp/logs/images are data, not verified code).
log "core: Joomla 3.8.11 (official package)"
rsync -a \
--exclude='cache/' --exclude='tmp/' --exclude='logs/' \
--exclude='images/sampledata/' --exclude='images/banners/' --exclude='images/headers/' \
--exclude='images/joomla_black.png' --exclude='images/powered_by.png' \
"$ROOT/core/" "$OUT/"
# 2) Upstream-package extensions — map the pristine package to deployed paths via
# the Joomla manifest, then apply the Cadline delta patch (if the module was
# legitimately modified). git diff pristine<->patch documents our delta.
for pkg in "$ROOT"/packages/*/; do
[ -d "$pkg" ] || continue
name="$(basename "$pkg")"
log "package: $name (manifest-map)"
python3 "$JMAP" --package "$pkg/pristine" --out "$OUT"
if [ -f "$pkg/cadline.patch" ]; then
log "package: $name (apply Cadline delta)"
( cd "$OUT" && patch -p1 --no-backup-if-mismatch < "$pkg/cadline.patch" )
fi
done
# 3) No-source extensions — vetted deployed files (no obtainable package),
# placed directly (already in deployed layout).
for d in "$ROOT"/deployed/*/; do
[ -d "$d" ] || continue
log "deployed: $(basename "$d")"
rsync -a --exclude='.provenance' "$d" "$OUT/"
done
# 4) Cadline own-code (components/modules/plugins/templates/docroot apps).
for d in "$ROOT"/cadline/*/; do
[ -d "$d" ] || continue
log "cadline: $(basename "$d")"
rsync -a --exclude='.provenance' "$d" "$OUT/"
done
# 5) Cadline core modifications — patches applied on the vanilla core.
for p in "$ROOT"/overrides/*.patch; do
[ -f "$p" ] || continue
log "override: $(basename "$p")"
( cd "$OUT" && patch -p1 --no-backup-if-mismatch < "$p" )
done
# 6) Safety net — malware IOC + scan artifacts must never appear in the baseline
# (the sources above already exclude them; this is defensive, documented in
# malware-iocs.md / malware-iocs.paths).
log "exclude: malware IOC + scan artifacts"
find "$OUT" \( -name '*.php.json' -o -name '*.phtml.json' -o -name 'h3x_*' -o -name '_h3x_*' \) -delete 2>/dev/null || true
if [ -f "$ROOT/malware-iocs.paths" ]; then
while IFS= read -r ioc; do
[ -z "$ioc" ] && continue
case "$ioc" in \#*) continue;; esac
rm -rf "${OUT:?}/$ioc"
done < "$ROOT/malware-iocs.paths"
fi
log "baseline built at: $OUT ($(find "$OUT" -type f | wc -l) files)"