#!/usr/bin/env bash
set -Eeuo pipefail

HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
FIXTURES="$HERE/fixtures/lot6"
MARKER=".soria-hardening-assurance-project"
DECISION="READY_WITH_ACTIONS"
REFERENCE_DATE="2026-08-07"

die(){ echo "ERROR: $*" >&2; exit 1; }

safe_root(){
  local r="${1:-}"
  [[ "$r" = /* ]] || die "root must be absolute"
  case "$r" in
    /tmp/soria-hardening-assurance-project-*|"$HOME"/soria-hardening-assurance-project-*) ;;
    *) die "unsafe root: $r" ;;
  esac
}

marked(){ [[ -f "$1/$MARKER" ]] || die "missing safety marker"; }
file_count(){ find "$1" -type f | wc -l | tr -d ' '; }
manifest(){
  (cd "$1"; find . -type f -print | sort | sed 's#^\./##' | while read -r f; do
    printf '%s,%s\n' "$f" "$(sha256sum "$f" | awk '{print $1}')"
  done)
}

check_step(){
  local name="$1"
  shift
  local rc=0
  "$@" || rc=$?
  if (( rc != 0 )); then
    die "fixture validation failed: ${name} (status=${rc})"
  fi
}

check_fixture_count(){ [[ "$(file_count "$1")" = 18 ]] || return 2; }

check_assets(){
  awk -F, 'NR>1{
    for(i=1;i<=7;i++) if($i=="") exit 2
    if($2!="baseline" && $2!="identity" && $2!="linux" && $2!="windows-ad" && $2!="network" && $2!="endpoint" && $2!="container" && $2!="kubernetes" && $2!="backup-recovery") exit 3
    if($5!="medium" && $5!="high" && $5!="critical") exit 4
    if($7 !~ /SYNTHETIC-SORIA-Distribution/) exit 5
    seen[$1]++
  } END{for(a in seen) if(seen[a]!=1) exit 6}' "$1/portfolio/assets.csv"
}

check_requirements(){
  awk -F, '
    FILENAME==ARGV[1] && FNR>1 {asset[$1]=1; next}
    FILENAME==ARGV[2] && FNR>1 {evidence[$1]=1; next}
    FILENAME==ARGV[3] && FNR>1 {test[$1]=1; next}
    FILENAME==ARGV[4] && FNR>1 {rollback[$1]=1; next}
    FILENAME==ARGV[5] && FNR>1 {pb[$1]=1; next}
    FILENAME==ARGV[6] && FNR>1 {
      for(i=1;i<=12;i++) if($i=="") exit 2
      if(!asset[$3]) exit 3
      if(!evidence[$7]) exit 4
      if(!test[$8] || !test[$9] || !test[$10]) exit 5
      if(!rollback[$11]) exit 6
      if(!pb[$12]) exit 7
      req[$1]++
    }
    END{for(r in req) if(req[r]!=1) exit 8}
  ' \
    "$1/portfolio/assets.csv" \
    "$1/portfolio/control-evidence.csv" \
    "$1/tests/test-catalog.csv" \
    "$1/change/rollback.csv" \
    "$1/assurance/proof-boundaries.csv" \
    "$1/portfolio/requirements.csv"
}

check_evidence(){
  awk -F, '
    FILENAME==ARGV[1] && FNR>1 {req[$1]=1; next}
    FILENAME==ARGV[2] && FNR>1 {
      for(i=1;i<=9;i++) if($i=="") exit 2
      if(!req[$2]) exit 3
      if($4!="AVAILABLE") exit 4
      if($5!="SYNTHETIC" && $5!="DECLARED" && $5!="EXECUTED" && $5!="OBSERVED") exit 5
      if(($5=="SYNTHETIC" || $5=="DECLARED") && $9 !~ /proof-boundary/) exit 6
      ev[$1]++
    }
    END{for(e in ev) if(ev[e]!=1) exit 7}
  ' "$1/portfolio/requirements.csv" "$1/portfolio/control-evidence.csv"
}

check_tests(){
  awk -F, '
    FILENAME==ARGV[1] && FNR>1 {
      for(i=1;i<=9;i++) if($i=="") exit 2
      if($2!="positive" && $2!="negative" && $2!="functional") exit 3
      cat[$1]=$2; required[$1]=$9; next
    }
    FILENAME==ARGV[2] && FNR>1 {
      for(i=1;i<=5;i++) if($i=="") exit 4
      if(!($1 in cat)) exit 5
      if(cat[$1]=="positive" && required[$1]=="true" && $2!="PASS") exit 6
      if(cat[$1]=="negative" && required[$1]=="true" && $2!="BLOCKED") exit 7
      if(cat[$1]=="functional" && required[$1]=="true" && $2!="PASS") exit 8
      if($5!="SYNTHETIC" && $5!="DECLARED" && $5!="EXECUTED" && $5!="OBSERVED") exit 9
      result[$1]++
    }
    END{
      for(t in cat) if(required[t]=="true" && result[t]!=1) exit 10
    }
  ' "$1/tests/test-catalog.csv" "$1/tests/test-results.csv"
}

check_business_flows(){
  awk -F, '
    FILENAME==ARGV[1] && FNR>1 {test[$1]=1; next}
    FILENAME==ARGV[2] && FNR>1 {
      for(i=1;i<=8;i++) if($i=="") exit 2
      if($5!="true" || $8!="REQUIRED") exit 3
      if(!test[$7]) exit 4
      n++
    }
    END{if(n<5) exit 5}
  ' "$1/tests/test-catalog.csv" "$1/portfolio/business-flows.csv"
}

check_exceptions(){
  awk -F, 'NR>1{
    for(i=1;i<=8;i++) if($i=="") exit 2
    if($3!="low" && $3!="medium" && $3!="high" && $3!="critical") exit 3
    if($7 < "2026-08-07") exit 4
    gap[$1]=1
  }' "$1/exceptions/gaps.csv" || return 2

  awk -F, -v today="$REFERENCE_DATE" '
    FILENAME==ARGV[1] && FNR>1 {gap[$1]=1; next}
    FILENAME==ARGV[2] && FNR>1 {
      for(i=1;i<=10;i++) if($i=="") exit 2
      if(!gap[$2]) exit 3
      if($10=="ACTIVE" && $8 < today) exit 4
      if($10=="ACTIVE" && $9 < today) exit 5
      ex[$1]=1
    }
  ' "$1/exceptions/gaps.csv" "$1/exceptions/exceptions.csv" || return 3

  awk -F, '
    FILENAME==ARGV[1] && FNR>1 {ex[$1]=1; next}
    FILENAME==ARGV[2] && FNR>1 {test[$1]=1; next}
    FILENAME==ARGV[3] && FNR>1 {ev[$1]=1; next}
    FILENAME==ARGV[4] && FNR>1 {
      for(i=1;i<=8;i++) if($i=="") exit 2
      if(!ex[$2] || !test[$5] || !ev[$6]) exit 3
      if($7!="EFFECTIVE") exit 4
    }
  ' "$1/exceptions/exceptions.csv" "$1/tests/test-catalog.csv" "$1/portfolio/control-evidence.csv" "$1/exceptions/compensating-controls.csv"
}

check_drift(){
  awk -F, -v today="$REFERENCE_DATE" '
    FILENAME==ARGV[1] && FNR>1 {ex[$1]=1; next}
    FILENAME==ARGV[2] && FNR>1 {
      for(i=1;i<=10;i++) if($i=="") exit 2
      if($7 < today) exit 3
      if($9=="OPEN" && ($8=="" || $8=="none-required")) exit 4
      if($9=="ACCEPTED" && ($10=="NONE" || !ex[$10])) exit 5
    }
  ' "$1/exceptions/exceptions.csv" "$1/exceptions/drift.csv"
}

check_change(){
  awk -F, '
    FILENAME==ARGV[1] && FNR>1 {pre[$1]=$5; next}
    FILENAME==ARGV[2] && FNR>1 {rb[$1]=$7; next}
    FILENAME==ARGV[3] && FNR>1 {
      for(i=1;i<=8;i++) if($i=="") exit 2
      if(!($4 in pre) || pre[$4]!="PASS") exit 3
      if(!($6 in rb) || rb[$6]!="READY") exit 4
      if($5=="") exit 5
    }
  ' "$1/change/prechecks.csv" "$1/change/rollback.csv" "$1/change/waves.csv" || return 2

  awk -F, '
    FILENAME==ARGV[1] && FNR>1 {wave[$1]=1; next}
    FILENAME==ARGV[2] && FNR>1 {
      for(i=1;i<=6;i++) if($i=="") exit 2
      if(!wave[$2] || $5!="PASS") exit 3
    }
  ' "$1/change/waves.csv" "$1/change/prechecks.csv" || return 3

  awk -F, '
    FILENAME==ARGV[1] && FNR>1 {wave[$1]=1; next}
    FILENAME==ARGV[2] && FNR>1 {test[$1]=1; next}
    FILENAME==ARGV[3] && FNR>1 {
      for(i=1;i<=7;i++) if($i=="") exit 2
      if(!wave[$2] || !test[$6] || $7!="READY") exit 3
    }
  ' "$1/change/waves.csv" "$1/tests/test-catalog.csv" "$1/change/rollback.csv"
}

check_recovery(){
  awk -F, '
    FILENAME==ARGV[1] && FNR>1 {asset[$1]=1; next}
    FILENAME==ARGV[2] && FNR>1 {pb[$1]=1; next}
    FILENAME==ARGV[3] && FNR>1 {restore[$1]=$3; next}
    FILENAME==ARGV[4] && FNR>1 {
      for(i=1;i<=11;i++) if($i=="") exit 2
      if(!asset[$2] || !pb[$11]) exit 3
      if($4=="" || $5=="" || $6=="" || $7=="") exit 4
      if(!($10 in restore) || restore[$10]!="PASS") exit 5
    }
  ' "$1/portfolio/assets.csv" "$1/assurance/proof-boundaries.csv" "$1/recovery/restore-tests.csv" "$1/recovery/backup-controls.csv" || return 2

  awk -F, 'NR>1{
    for(i=1;i<=7;i++) if($i=="") exit 2
    if($3!="PASS") exit 3
    if($5!="SYNTHETIC" && $5!="EXECUTED" && $5!="OBSERVED") exit 4
  }' "$1/recovery/restore-tests.csv"
}

check_assurance(){
  awk -F, 'NR>1{
    for(i=1;i<=5;i++) if($i=="") exit 2
    if($3=="" || $4=="") exit 3
    pb[$1]=1
  } END{if(length(pb)<7) exit 4}' "$1/assurance/proof-boundaries.csv" || return 2

  awk -F, 'NR>1{
    for(i=1;i<=3;i++) if($i=="") exit 2
    d[$1]=1
  } END{if(!d["READY"] || !d["READY_WITH_ACTIONS"] || !d["BLOCKED"]) exit 3}' "$1/assurance/decision-criteria.csv" || return 3

  awk -F, 'NR>1{
    for(i=1;i<=7;i++) if($i=="") exit 2
    if($6!="false" || $7!="REQUIRED") exit 3
    n++
  } END{if(n<6) exit 4}' "$1/assurance/real-evidence-required.csv"
}

check_decision(){
  local source="$1" decision_file="$2" decision
  decision="$(cat "$decision_file")"
  case "$decision" in
    READY)
      if awk -F, 'NR>1 && ($6=="false" || $7=="REQUIRED"){found=1} END{exit found?0:1}' "$source/assurance/real-evidence-required.csv"; then
        return 2
      fi
      ;;
    READY_WITH_ACTIONS)
      awk -F, 'NR>1 && $6=="false" && $7=="REQUIRED"{n++} END{exit n>0?0:1}' "$source/assurance/real-evidence-required.csv" || return 3
      ;;
    BLOCKED) return 0 ;;
    *) return 4 ;;
  esac
}

check_all(){
  check_step fixture-count check_fixture_count "$1"
  check_step assets check_assets "$1"
  check_step requirements check_requirements "$1"
  check_step evidence check_evidence "$1"
  check_step tests check_tests "$1"
  check_step business-flows check_business_flows "$1"
  check_step gaps-exceptions-compensating check_exceptions "$1"
  check_step drift check_drift "$1"
  check_step change-rollback check_change "$1"
  check_step recovery check_recovery "$1"
  check_step assurance check_assurance "$1"
}

negative_case(){
  local id="$1" reason="$2" report="$3"
  printf '%s,%s,%s,BLOCKED\n' "$id" "$reason" "$reason" >> "$report"
}

run_negatives(){
  local r="$1" s="$1/source" n="$1/negative" report="$1/output/negative-test-report.csv" d claim
  rm -rf "$n"; mkdir -p "$n"
  echo 'case_id,expected_reason,observed_reason,result' > "$report"

  d="$n/NEG-01"; cp -R "$s" "$d"; chmod -R u+w "$d"
  awk -F, 'BEGIN{OFS=","} NR==1{print;next} NR==2{$3="ghost-asset"} {print}' "$d/portfolio/requirements.csv" > "$d/x"; mv "$d/x" "$d/portfolio/requirements.csv"
  if check_requirements "$d"; then die "NEG-01 accepted"; else negative_case NEG-01 critical-requirement-evidence-or-reference-invalid "$report"; fi

  d="$n/NEG-02"; cp -R "$s" "$d"; chmod -R u+w "$d"
  awk -F, 'BEGIN{OFS=","} NR==1{print;next} $1=="POS-BASE-01"{$2="FAIL"} {print}' "$d/tests/test-results.csv" > "$d/x"; mv "$d/x" "$d/tests/test-results.csv"
  if check_tests "$d"; then die "NEG-02 accepted"; else negative_case NEG-02 positive-test-missing-or-failed "$report"; fi

  d="$n/NEG-03"; cp -R "$s" "$d"; chmod -R u+w "$d"
  awk -F, 'BEGIN{OFS=","} NR==1{print;next} $1=="NEG-NET-01"{$2="PASS"} {print}' "$d/tests/test-results.csv" > "$d/x"; mv "$d/x" "$d/tests/test-results.csv"
  if check_tests "$d"; then die "NEG-03 accepted"; else negative_case NEG-03 negative-test-not-blocked "$report"; fi

  d="$n/NEG-04"; cp -R "$s" "$d"; chmod -R u+w "$d"
  awk -F, 'BEGIN{OFS=","} NR==1{print;next} $1=="FUN-K8S-01"{$2="FAIL"} {print}' "$d/tests/test-results.csv" > "$d/x"; mv "$d/x" "$d/tests/test-results.csv"
  if check_tests "$d"; then die "NEG-04 accepted"; else negative_case NEG-04 functional-test-missing-or-regression "$report"; fi

  d="$n/NEG-05"; cp -R "$s" "$d"; chmod -R u+w "$d"
  awk -F, 'BEGIN{OFS=","} NR==1{print;next} NR==2{$5=""} {print}' "$d/exceptions/gaps.csv" > "$d/x"; mv "$d/x" "$d/exceptions/gaps.csv"
  if check_exceptions "$d"; then die "NEG-05 accepted"; else negative_case NEG-05 gap-owner-remediation-or-due-date-missing "$report"; fi

  d="$n/NEG-06"; cp -R "$s" "$d"; chmod -R u+w "$d"
  awk -F, 'BEGIN{OFS=","} NR==1{print;next} NR==2{$5="";$8="2026-08-01"} {print}' "$d/exceptions/exceptions.csv" > "$d/x"; mv "$d/x" "$d/exceptions/exceptions.csv"
  if check_exceptions "$d"; then die "NEG-06 accepted"; else negative_case NEG-06 exception-expired-unapproved-or-unreviewed "$report"; fi

  d="$n/NEG-07"; cp -R "$s" "$d"; chmod -R u+w "$d"
  awk -F, 'BEGIN{OFS=","} NR==1{print;next} NR==2{$7="INEFFECTIVE"} {print}' "$d/exceptions/compensating-controls.csv" > "$d/x"; mv "$d/x" "$d/exceptions/compensating-controls.csv"
  if check_exceptions "$d"; then die "NEG-07 accepted"; else negative_case NEG-07 compensating-control-unproven-or-ineffective "$report"; fi

  d="$n/NEG-08"; cp -R "$s" "$d"; chmod -R u+w "$d"
  awk -F, 'BEGIN{OFS=","} NR==1{print;next} NR==3{$7="2026-08-01";$8="none-required";$9="OPEN"} {print}' "$d/exceptions/drift.csv" > "$d/x"; mv "$d/x" "$d/exceptions/drift.csv"
  if check_drift "$d"; then die "NEG-08 accepted"; else negative_case NEG-08 critical-drift-unhandled-or-review-overdue "$report"; fi

  d="$n/NEG-09"; cp -R "$s" "$d"; chmod -R u+w "$d"
  awk -F, 'BEGIN{OFS=","} NR==1{print;next} NR==2{$6=""} {print}' "$d/change/waves.csv" > "$d/x"; mv "$d/x" "$d/change/waves.csv"
  if check_change "$d"; then die "NEG-09 accepted"; else negative_case NEG-09 wave-precheck-stop-rollback-or-restore-invalid "$report"; fi

  d="$n/NEG-10"; cp -R "$s" "$d"; chmod -R u+w "$d"; claim="$d/decision.txt"; echo READY > "$claim"
  if check_decision "$d" "$claim"; then die "NEG-10 accepted"; else negative_case NEG-10 ready-overclaim-or-proof-boundary-invalid "$report"; fi

  [[ "$(awk -F, 'NR>1&&$4=="BLOCKED"{n++} END{print n+0}' "$report")" = 10 ]] || die "expected ten blocked negative cases"
}

write_reports(){
  local r="$1" s="$1/source" o="$1/output"

  awk -F, 'BEGIN{OFS=","}
    NR==FNR && FNR>1 {ev[$1]=$3","$4","$5","$6; next}
    FNR==1 {print "requirement_id,domain,asset_id,criticality,evidence_id,evidence_type,evidence_status,proof_level,artifact,positive_test,negative_test,functional_test,rollback_id,proof_boundary_id"; next}
    {split(ev[$7],e,","); print $1,$2,$3,$6,$7,e[1],e[2],e[3],e[4],$8,$9,$10,$11,$12}
  ' "$s/portfolio/control-evidence.csv" "$s/portfolio/requirements.csv" > "$o/evidence-matrix.csv"

  awk -F, 'BEGIN{OFS=","}
    NR==FNR && FNR>1 {type[$1]=$2; next}
    FNR==1 {print "test_id,type,result,evidence,proof_level"; next}
    {print $1,type[$1],$2,$3,$5}
  ' "$s/tests/test-catalog.csv" "$s/tests/test-results.csv" > "$o/test-summary.csv"

  awk -F, 'BEGIN{OFS=","}
    NR==FNR && FNR>1 {type[$1]=$2; next}
    FNR==1 {print "test_id,result,evidence,proof_level"; next}
    type[$1]=="positive" {print $1,$2,$3,$5}
  ' "$s/tests/test-catalog.csv" "$s/tests/test-results.csv" > "$o/positive-test-report.csv"

  awk -F, 'BEGIN{OFS=","}
    NR==FNR && FNR>1 {type[$1]=$2; next}
    FNR==1 {print "test_id,result,evidence,proof_level"; next}
    type[$1]=="functional" {print $1,$2,$3,$5}
  ' "$s/tests/test-catalog.csv" "$s/tests/test-results.csv" > "$o/functional-test-report.csv"

  cp "$s/exceptions/gaps.csv" "$o/gap-register.csv"
  cp "$s/exceptions/exceptions.csv" "$o/exception-register.csv"
  cp "$s/exceptions/compensating-controls.csv" "$o/compensating-controls-review.csv"
  cp "$s/exceptions/drift.csv" "$o/drift-review.csv"
  cp "$s/change/waves.csv" "$o/wave-readiness.csv"
  cp "$s/change/rollback.csv" "$o/rollback-readiness.csv"
  cp "$s/recovery/restore-tests.csv" "$o/recovery-review.csv"

  awk -F, 'BEGIN{print "metric,value"}
    FNR==NR && NR>1 {req++ ; next}
    NR>1 {if($2=="PASS") pass++; else if($2=="BLOCKED") blocked++}
    END{print "requirements,"req; print "test_pass,"pass; print "negative_blocked,"blocked}
  ' "$s/portfolio/requirements.csv" "$s/tests/test-results.csv" > "$o/coverage-summary.csv"

  cat > "$o/decision-rationale.csv" <<'EOF_DECISION'
factor,result,evidence
fixture-coherence,PASS,all-reference-fixtures-valid
mandatory-tests,PASS,positive-negative-functional-results-coherent
exceptions,PASS,active-exception-owned-approved-time-bounded
compensating-controls,PASS,control-effective-with-test-and-evidence
drift,PASS,review-dates-and-actions-valid
change-rollback,PASS,prechecks-stop-conditions-and-rollback-present
recovery,PASS,represented-restore-test-passes
real-evidence,ACTIONS_REQUIRED,authorized-real-system-evidence-outstanding
EOF_DECISION

  printf '%s\n' "$DECISION" > "$o/final-decision.txt"

  cat > "$o/proof-boundaries.md" <<'EOF_BOUNDARY'
# Lot 6 proof boundaries
Established: synthetic fixture integrity, evidence-reference coherence, represented positive/negative/functional tests, gap/exception/compensating-control governance, drift review, wave/precheck/rollback structure, represented recovery test, ten blocked negative cases and exact synthetic rollback.
Not established: real Linux or Windows state, real GPO/LAPS/Defender/Firewall behavior, real OPNsense/WireGuard state, endpoint/runtime/Kubernetes enforcement, immutable backup state, real restoration, real drift absence, real business exception approval, complete NIST/CIS/ANSSI compliance or production READY status.
EOF_BOUNDARY

  cat > "$o/final-dossier.md" <<'EOF_DOSSIER'
# SORIA Distribution — dossier final de durcissement synthétique

Decision: READY_WITH_ACTIONS

This dossier connects the six hardening lots across baselines, privileged paths, Linux, Windows/AD, network, endpoints, containers, Kubernetes and backup/recovery.

Evidence: synthetic and declared artifacts are linked to requirements and tests. Positive, negative and functional tests are represented and validated by the lab.

Gaps and exceptions: remaining real-system evidence is explicit, owned, time-bounded where excepted and paired with compensating controls when applicable.

Change safety: waves include prechecks, stop conditions and rollback identifiers. The lab proves only rollback of its own synthetic fixture state.

Recovery: a represented restore test is present. No real immutable backup or real restore is claimed.

Proof boundary: CI validates the dossier structure and synthetic evidence only. Authorized real-system observations are still required before READY can be considered.
EOF_DOSSIER
}

decide(){
  local source="$1"
  check_all "$source"
  if awk -F, 'NR>1 && $6=="false" && $7=="REQUIRED"{n++} END{exit n>0?0:1}' "$source/assurance/real-evidence-required.csv"; then
    printf '%s\n' READY_WITH_ACTIONS
  else
    printf '%s\n' READY
  fi
}

setup(){
  safe_root "$1"
  [[ ! -e "$1" ]] || die "root already exists"
  check_all "$FIXTURES"
  mkdir -p "$1"/{source,work,rollback,negative,output}
  printf '%s\n' "SORIA_HARDENING_ASSURANCE_PROJECT" > "$1/$MARKER"
  cp -R "$FIXTURES"/. "$1/source"
  manifest "$FIXTURES" > "$1/output/source-manifest.csv"
  chmod -R a-w "$1/source"
  printf 'state=SETUP\nfixtures=18\n' > "$1/output/status.txt"
  echo "Lot 6 setup complete: $1"
}

status(){
  safe_root "$1"; marked "$1"
  echo "root=$1"
  echo "fixtures=$(file_count "$1/source")"
  if [[ -f "$1/output/final-decision.txt" ]]; then echo "decision=$(cat "$1/output/final-decision.txt")"; else echo "decision=NOT_RUN"; fi
}

run(){
  safe_root "$1"; marked "$1"; [[ ! -d "$1/work/before" ]] || die "already run"
  check_all "$1/source"
  cp -R "$1/source" "$1/work/before"
  cp -R "$1/source" "$1/work/reviewed"
  chmod -R u+w "$1/work"
  write_reports "$1"
  run_negatives "$1"
  manifest "$1/work/before" > "$1/output/rollback-manifest-before.csv"
  mkdir -p "$1/rollback/restored"
  cp -R "$1/work/before"/. "$1/rollback/restored"
  manifest "$1/rollback/restored" > "$1/output/rollback-manifest-restored.csv"
  cmp -s "$1/output/rollback-manifest-before.csv" "$1/output/rollback-manifest-restored.csv" || die "rollback manifest mismatch"
  printf 'result=PASS\nverification=manifest-match\n' > "$1/output/rollback-report.txt"
  local decision
  decision="$(decide "$1/source")"
  [[ "$decision" = "$DECISION" ]] || die "unexpected decision: $decision"
  printf '%s\n' "$decision" > "$1/output/final-decision.txt"
  cat > "$1/output/validation-summary.txt" <<EOF_SUMMARY
decision=$decision
fixtures=18
requirements=9
negative_cases=10
negative_blocked=10
rollback=PASS
real_evidence_outstanding=6
proof_scope=SYNTHETIC_AND_LAB_EXECUTION_ONLY
EOF_SUMMARY
  echo "Lot 6 run complete: $decision"
}

validate(){
  safe_root "$1"; marked "$1"; check_all "$1/source"
  cmp -s "$1/output/source-manifest.csv" <(manifest "$FIXTURES") || die "source fixtures changed"
  [[ "$(awk -F, 'NR>1&&$4=="BLOCKED"{n++} END{print n+0}' "$1/output/negative-test-report.csv")" = 10 ]] || die "negative count"
  cmp -s "$1/output/rollback-manifest-before.csv" "$1/output/rollback-manifest-restored.csv" || die "rollback mismatch"
  grep -Fxq "$DECISION" "$1/output/final-decision.txt"
  check_decision "$1/source" "$1/output/final-decision.txt" || die "decision invalid"
  for f in evidence-matrix.csv test-summary.csv positive-test-report.csv functional-test-report.csv gap-register.csv exception-register.csv compensating-controls-review.csv drift-review.csv wave-readiness.csv rollback-readiness.csv recovery-review.csv coverage-summary.csv decision-rationale.csv final-dossier.md proof-boundaries.md validation-summary.txt; do
    [[ -s "$1/output/$f" ]] || die "missing output: $f"
  done
  grep -Fq 'SORIA Distribution' "$1/output/final-dossier.md"
  grep -Fqi 'proof boundary' "$1/output/final-dossier.md"
  grep -Fq 'real_evidence_outstanding=6' "$1/output/validation-summary.txt"
  echo "Lot 6 validation PASS: $DECISION"
}

reset(){
  safe_root "$1"; marked "$1"
  chmod -R u+w "$1" 2>/dev/null || true
  rm -rf "$1"
  [[ ! -e "$1" ]] || die "reset failed"
  echo "Lot 6 reset complete: $1"
}

case "${1:-}" in
  setup) setup "${2:-}" ;;
  status) status "${2:-}" ;;
  run) run "${2:-}" ;;
  validate) validate "${2:-}" ;;
  reset) reset "${2:-}" ;;
  *) echo "Usage: $0 {setup|status|run|validate|reset} <absolute-root>" >&2; exit 2 ;;
esac
