#!/bin/sh
# harkaq-policy — deriva la política de la clausura declarada (SDD 16, D1).
#
#   harkaq-policy.sh <dir-dep> [<dir-dep>...] > politica
#
# D1: la política NO se escribe, se DERIVA. La receta ya declara sus `deps` por hash; cada dep
# es un artefacto sellado del store (`store/<hash>-<name>/usr/...`). La clausura es, exactamente,
# el conjunto de ficheros que esas deps aportan — ni uno más.
#
# El sandbox de hammer apila cada dep con `--overlay-src` sobre el rootfs Alpine, así que el
# fichero `store/<hash>-zlib/usr/include/zlib.h` aparece dentro como `/usr/include/zlib.h`. La
# traducción es sólo quitar el prefijo del store: el resto del path YA es el path del sandbox.
#
# Por qué fichero a fichero y no por directorio: adentro, la dep declarada y el rootfs Alpine
# comparten `/usr` (medido: /usr/include/zlib.h y /usr/include/stdio.h son el mismo directorio
# overlayfs). Una regla sobre /usr concede los dos y la evidencia deja de significar algo. Los
# `list` de los directorios se emiten para que las herramientas puedan ESCANEAR (pkgconf, los
# tests de configure) sin poder LEER lo no declarado — Landlock separa READ_DIR de READ_FILE.
set -eu

emit_dirs() {
    # Los directorios que contienen ficheros de la clausura: listables, no legibles.
    # Se emiten deduplicados y con sus ancestros, porque un `ls /usr` también es un escaneo
    # legítimo y su denegación sería un falso positivo, no deuda de de-Alpinización.
    while IFS= read -r d; do
        while [ "$d" != "/" ] && [ -n "$d" ]; do
            echo "list $d"
            d=$(dirname "$d")
        done
    done | sort -u
}

TMP="$(mktemp)"
trap 'rm -f "$TMP" "$TMP.d"' EXIT
: > "$TMP"
: > "$TMP.d"

for dep in "$@"; do
    real=$(readlink -f "$dep")
    # `.hammer/` es metadata del artefacto (recipe.toml), no parte de la clausura que el build
    # consume: si el build lo leyera sería una denegación legítima que queremos ver.
    find "$real" -type f -o -type l | grep -v "/\.hammer/" | while IFS= read -r f; do
        inside="${f#$real}"
        echo "ro $inside" >> "$TMP"
        dirname "$inside" >> "$TMP.d"
    done
done

echo "# harkaq-policy: clausura derivada de $# dep(s)"
sort -u "$TMP.d" | emit_dirs
sort -u "$TMP"
