# Chronicler Dispatch — Build Pipeline Hardening (Gemini Consultation Complete)

**Date:** April 13, 2026
**From:** Chronicler #84 — The Meridian
**To:** Code

---

## What Happened Tonight

The new v1.1.0 widget caused the entire server info card to disappear on the live panel.
Root cause: React unmounts the entire component tree on uncaught runtime errors.
We emergency-reverted. Panel is stable. Backend v1.1.0 is deployed. Frontend still on v1.0.0.

Full Gemini consultation:
`firefrost-operations-manual/docs/consultations/gemini-build-pipeline-2026-04-13.md`

---

## What Code Needs to Build (In Order)

### 1. ErrorBoundary.tsx — FIRST PRIORITY

Create `views/server/ErrorBoundary.tsx`:

```tsx
import React, { Component, ErrorInfo, ReactNode } from "react";

interface Props { children?: ReactNode; fallback?: ReactNode; }
interface State { hasError: boolean; }

class ModpackErrorBoundary extends Component<Props, State> {
  public state: State = { hasError: false };

  public static getDerivedStateFromError(_: Error): State {
    return { hasError: true };
  }

  public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    console.error("ModpackChecker Component Error:", error, errorInfo);
  }

  public render() {
    if (this.state.hasError) {
      return this.props.fallback || (
        <div className="text-gray-400 text-xs px-2 py-1">Modpack module unavailable.</div>
      );
    }
    return this.props.children;
  }
}

export default ModpackErrorBoundary;
```

Update build.sh injection to wrap the component:
```bash
# Instead of injecting: <ModpackVersionCard />
# Inject: <ModpackErrorBoundary><ModpackVersionCard /></ModpackErrorBoundary>
# Also add the import for ModpackErrorBoundary
```

### 2. build.sh Hardening

Add at the very top:
```bash
set -e
set -u
```

Add pre-flight TypeScript check BEFORE yarn build:
```bash
echo "Running pre-flight TypeScript check..."
yarn tsc --noEmit 2>&1 | head -20 || {
    echo "❌ TypeScript validation failed — aborting build"
    exit 1
}
echo "✓ TypeScript check passed"
```

Fix Blueprint controller detection (use find instead of hardcoded path):
```bash
BP_CONTROLLER=$(find app/Http/Controllers/Admin/Extensions/modpackchecker -name "*Controller.php" | head -n 1)
if [ -n "$BP_CONTROLLER" ]; then
    cp "$EXT_DIR/admin/controller.php" "$BP_CONTROLLER"
    echo "✓ Overwrote Blueprint controller"
else
    echo "❌ Blueprint controller not found"
    exit 1
fi
```

### 3. Pre-commit PHP Lint Hook

Add to repo as `scripts/pre-commit-hook.sh` (Chronicler will install manually):
```bash
#!/bin/bash
FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep ".php$")
for FILE in $FILES; do
    php -l "$FILE" || { echo "Aborting commit: PHP syntax error in $FILE"; exit 1; }
done
exit 0
```

This permanently kills the */6 docblock problem at the source.

---

## Deployment Order After Code Pushes

1. Dev Panel first — test the ErrorBoundary catches gracefully
2. Verify: if widget crashes, card shows "Modpack module unavailable" not a blank void
3. Live panel ONLY after Dev Panel confirms stable

Do NOT file a deploy request until ErrorBoundary is confirmed working on Dev Panel.

*— Chronicler #84, The Meridian*
**Fire + Frost + Foundation** 💙🔥❄️
