Ctrl K
ComunidadGuías…

scripts/ship-gate.sh

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bash
# Parley ship gate — run before every commit (the six hard-stops the conductor/autopilot enforce).
# Bundles: tests green · zero-dependency core intact · examples smoke · published claims true.
# The redteam extraction + net hardening are covered inside the test suite (tests/test_redteam.py,
# tests/test_net.py), so a green pytest already exercises them.
#
# Usage:  scripts/ship-gate.sh        (uses ./.venv)
# Exit 0 = all gates pass; non-zero = a gate failed (with which one).
set -euo pipefail
cd "$(dirname "$0")/.."
# A worktree sharing another tree's .venv would import that tree's editable parley/ otherwise.
export PYTHONPATH="$PWD${PYTHONPATH:+:$PYTHONPATH}"

PY="${PARLEY_PY:-.venv/bin/python}"
[ -x "$PY" ] || PY="python3"
export PARLEY_PY="$PY"

fail() { echo "✗ ship-gate FAILED: $1" >&2; exit 1; }

echo "▸ 1/5 tests"
"$PY" -m pytest -q || fail "pytest not green"

echo "▸ 2/5 zero-dependency core"
# The core (parley/, minus the optional signed layer net/identity.py) must import only stdlib
# or local parley modules. Correct check via sys.stdlib_module_names — not an ad-hoc grep.
"$PY" - <<'PYCHECK' || fail "core imports a third-party package (keep it zero-dependency)"
import ast, sys, pathlib
ALLOWED_NONSTDLIB_FILE = {"parley/net/identity.py"}  # the optional Ed25519 layer may import nacl
std = set(sys.stdlib_module_names)
bad = []
for p in sorted(pathlib.Path("parley").rglob("*.py")):
    rel = p.as_posix()
    if rel in ALLOWED_NONSTDLIB_FILE:
        continue
    tree = ast.parse(p.read_text(), rel)
    for node in ast.walk(tree):
        if isinstance(node, ast.Import):
            roots = [(a.name.split(".")[0], a.name) for a in node.names]
        elif isinstance(node, ast.ImportFrom):
            if node.level:  # relative import (from . / from ..) is local — fine
                continue
            roots = [(node.module.split(".")[0], node.module)] if node.module else []
        else:
            continue
        for root, full in roots:
            if root == "parley" or root in std:
                continue
            bad.append(f"{rel}: import {full}")
if bad:
    print("\n".join(bad)); sys.exit(1)
print("  core is stdlib-only (nacl confined to net/identity.py)")
PYCHECK

echo "▸ 3/5 examples smoke"
"$PY" examples/meeting.py >/dev/null || fail "examples/meeting.py errored"

# Gates 4 and 5 exist because the site twice shipped a number or a hash that the code did not
# back. Both failures were caught by a human reading the page, not by anything mechanical.
echo "▸ 4/5 homepage tape matches a real engine run"
"$PY" landing/scripts/gen-tape.py --check >/dev/null \
  || fail "landing/src/data/tape.ts is stale — regenerate with: $PY landing/scripts/gen-tape.py"
echo "  tape hashes come from a live run"

echo "▸ 5/5 published test-count claims are current"
# Report what the checker actually found, rather than a sentence written here. The two trees
# differ — the public mirror carries no data room — so a hardcoded verdict would state
# something this gate did not verify. The detail is printed on failure too, so whoever hits
# this gate sees which file and line is at fault without re-running the checker by hand.
claims_rc=0
claims_out="$(bash scripts/claim-freshness-check.sh)" || claims_rc=$?
if [[ "$claims_rc" -ne 0 ]]; then
  echo "$claims_out"
  fail "a test count is stale or has spread beyond the data room"
fi
echo "  ${claims_out#OK }"

echo "✓ ship-gate passed — tests green · zero-dep core · examples run · claims true"