#!/usr/bin/env bash set -euo pipefail if [[ $# -ne 1 ]]; then printf 'Usage: %s \n' "${0##*/}" >&2 exit 2 fi change=$1 if [[ ! "$change" =~ ^[a-z0-9]+(-[a-z0-9]+)*$ ]]; then printf 'Invalid OpenSpec change name: %s\n' "$change" >&2 exit 2 fi script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P) workspace=$(cd "$script_dir/../.." && pwd -P) change_dir="$workspace/specs/openspec/changes/$change" metadata_file="$change_dir/.openspec.yaml" design_file="$change_dir/design.md" for required_file in "$metadata_file" "$design_file"; do if [[ ! -f "$required_file" ]]; then printf 'Missing canonical change input: %s\n' "${required_file#$workspace/}" >&2 exit 1 fi done areas=(frontend backend specs docs) affected_flags=(0 0 0 0) map_statuses=('' '' '' '') map_reasons=('' '' '' '') contract_status='' contract_reason='' area_index() { case "$1" in frontend) printf '0' ;; backend) printf '1' ;; specs) printf '2' ;; docs) printf '3' ;; *) return 1 ;; esac } while IFS= read -r area; do [[ -n "$area" ]] || continue if ! index=$(area_index "$area"); then printf 'Unknown affected area in %s: %s\n' "${metadata_file#$workspace/}" "$area" >&2 exit 1 fi if [[ "${affected_flags[$index]}" -eq 1 ]]; then printf 'Duplicate affected area in %s: %s\n' "${metadata_file#$workspace/}" "$area" >&2 exit 1 fi affected_flags[$index]=1 done < <( awk ' $0 == "affected_areas:" { in_areas = 1; next } in_areas && /^ - / { sub(/^ - /, ""); print; next } in_areas { exit } ' "$metadata_file" ) if [[ "${affected_flags[2]}" -ne 1 ]]; then printf 'Delivery Map violation: specs must be affected for every versioned change.\n' >&2 exit 1 fi trim() { local value=$1 value=${value#"${value%%[![:space:]]*}"} value=${value%"${value##*[![:space:]]}"} printf '%s' "$value" } while IFS='|' read -r _ raw_area raw_status raw_reason _; do area=$(trim "$raw_area") case "$area" in frontend|backend|specs|docs) ;; *) continue ;; esac index=$(area_index "$area") if [[ -n "${map_statuses[$index]}" ]]; then printf 'Delivery Map contains duplicate row for %s.\n' "$area" >&2 exit 1 fi status=$(trim "$raw_status") status=${status//\`/} reason=$(trim "$raw_reason") map_statuses[$index]=$status map_reasons[$index]=$reason done < "$design_file" while IFS='|' read -r _ raw_gate raw_status raw_reason _; do gate=$(trim "$raw_gate") [[ "$gate" == "runtime-openapi" ]] || continue if [[ -n "$contract_status" ]]; then printf 'Contract Gate Decision contains duplicate runtime-openapi row.\n' >&2 exit 1 fi contract_status=$(trim "$raw_status") contract_status=${contract_status//\`/} contract_reason=$(trim "$raw_reason") done < "$design_file" for index in 0 1 2 3; do area=${areas[$index]} status=${map_statuses[$index]} reason=${map_reasons[$index]} if [[ -z "$status" ]]; then printf 'Delivery Map is missing area: %s\n' "$area" >&2 exit 1 fi if [[ "${affected_flags[$index]}" -eq 1 ]]; then if [[ "$status" != "affected" ]]; then printf 'Delivery Map mismatch: %s is listed as affected in metadata but has status %s.\n' "$area" "$status" >&2 exit 1 fi if [[ -z "$reason" || "$reason" == "-" || "$reason" == "—" || "$reason" == *"