#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" # Use an isolated cursor file so smoke runs do not mutate normal sync state. export CURSOR_FILE="${ROOT_DIR}/.cursor.smoke.$$" # shellcheck source=/dev/null source "${ROOT_DIR}/src/app_v2.sh" require_jq() { if ! command -v jq >/dev/null 2>&1; then echo "smoke_v2.sh: jq is required" >&2 exit 2 fi } fail() { echo "smoke_v2.sh: FAIL: $1" >&2 exit 1 } step() { echo "== $1 ==" } cleanup() { if [[ "${smoke_started_daemon:-0}" == "1" && -n "${smoke_daemon_pid:-}" ]]; then kill "${smoke_daemon_pid}" >/dev/null 2>&1 || true wait "${smoke_daemon_pid}" >/dev/null 2>&1 || true fi rm -f "${CURSOR_FILE}" >/dev/null 2>&1 || true if [[ "${SMOKE_USE_EXISTING_DAEMON:-0}" != "1" ]]; then rm -f "${smoke_sock:-}" >/dev/null 2>&1 || true fi } trap cleanup EXIT require_jq SMOKE_USE_EXISTING_DAEMON="${SMOKE_USE_EXISTING_DAEMON:-0}" smoke_started_daemon=0 smoke_daemon_pid="" smoke_root="${SMOKE_STORE_ROOT:-/tmp/amduat-asl-smoke-${USER:-user}}" smoke_sock="${SMOKE_SOCK:-/tmp/amduatd-smoke-${USER:-user}.sock}" smoke_backend="${SMOKE_STORE_BACKEND:-fs}" smoke_log="${SMOKE_DAEMON_LOG_PATH:-/tmp/smoke-v2-daemon.log}" if [[ "${SMOKE_USE_EXISTING_DAEMON}" != "1" ]]; then rm -f "${smoke_sock}" >/dev/null 2>&1 || true export SOCK="${smoke_sock}" STORE_BACKEND="${smoke_backend}" STORE_ROOT="${smoke_root}" SOCK="${smoke_sock}" SPACE="${SPACE:-app1}" \ nohup "${ROOT_DIR}/scripts/dev_start_daemon.sh" >"${smoke_log}" 2>&1 & smoke_daemon_pid="$!" smoke_started_daemon=1 ready=0 for _ in $(seq 1 120); do if curl --globoff --silent --show-error --unix-socket "${smoke_sock}" "http://localhost/v2/readyz" >/dev/null 2>&1; then ready=1 break fi sleep 0.1 done [[ "${ready}" == "1" ]] || fail "isolated daemon did not become ready (log: ${smoke_log})" fi app_init run_id="$(date +%s)" idempotency_key="smoke-seed-${run_id}" doc_name="smokedoc${run_id}" topic_name="smoketopic${run_id}" goal_pred="ms.within_domain" step "startup" startup_out="$(app_startup_checks)" || fail "startup checks failed" printf '%s' "${startup_out}" | grep -q '"ok":true' || fail "readyz did not report ok=true" step "ingest" payload="$(cat </dev/null || fail "tombstone call failed" post_retrieve="$(app_retrieve_with_fallback "${doc_name}" "${goal_pred}")" || fail "post-tombstone retrieve failed" post_edges_count="$(printf '%s' "${post_retrieve}" | jq '.edges | length')" [[ "${post_edges_count}" == "0" ]] || fail "tombstoned edge still visible in default retrieval" amduat_api_call GET "/v2/graph/subgraph?roots[]=${doc_name}&max_depth=2&dir=outgoing&limit_nodes=200&limit_edges=400&include_tombstoned=true&max_result_bytes=1048576" || fail "include_tombstoned subgraph failed" visible_out="${AMDUAT_LAST_BODY}" visible_has_edge="$(printf '%s' "${visible_out}" | jq --arg edge_ref "${edge_ref}" '[.edges[] | select(.edge_ref == $edge_ref)] | length')" [[ "${visible_has_edge}" != "0" ]] || fail "tombstoned edge not visible with include_tombstoned=true" echo "smoke_v2.sh: PASS"