# Folder + Repo Rename `scadalink-design` → `ScadaBridge` Implementation Plan > **For Claude:** REQUIRED SUB-SKILL: Use superpowers-extended-cc:executing-plans to implement this plan task-by-task. **Goal:** Rename the repo folder `~/Desktop/scadalink-design` → `~/Desktop/ScadaBridge`, rename the Gitea repository `dohertj2/scadalink-design` → `dohertj2/ScadaBridge`, and scrub every residual `scadalink`/`ScadaLink` reference inside the repo to its `ScadaBridge` equivalent. **Architecture:** A scripted, most-specific-first `sed` pass over git-tracked text files does the content scrub; the folder rename is a plain OS `mv` (git tracks contents, not the repo-root directory name); the Gitea rename is a user web-UI action followed by a local `origin` URL update. Migration records (the prior rename tooling/design and the DB-rename helper) are carved out so their before→after meaning survives. Hard env-var cutover, no DB changes. **Tech Stack:** bash 3.2 (macOS), BSD `sed -i ''`, git, `git grep`, dotnet (`ZB.MOM.WW.ScadaBridge.slnx`), docker compose. **Design doc:** `docs/plans/2026-05-31-folder-repo-rename-scadabridge-design.md` > **CRITICAL — path change after Task 0:** Task 0 moves the repo. From Task 1 onward, the repo root is `/Users/dohertj2/Desktop/ScadaBridge` (NOT `scadalink-design`). Every command below `cd`s there. --- ### Task 0: Safety checkpoint, clear the collision, move the folder **Classification:** standard **Estimated implement time:** ~3 min **Parallelizable with:** none **Files:** (filesystem operations only — no file edits) - Move: `~/Desktop/ScadaBridge` → `~/Desktop/ScadaBridge-old` - Move: `~/Desktop/scadalink-design` → `~/Desktop/ScadaBridge` **Step 1: Confirm the working tree is clean and record the branch** Run: ```bash cd /Users/dohertj2/Desktop/scadalink-design && git status --short && git branch --show-current ``` Expected: no output from `git status --short` (clean tree) and a branch name (e.g. `main`). If there is uncommitted work, STOP and ask the user whether to commit or stash before proceeding. **Step 2: Verify both move endpoints are safe** Run: ```bash ls -ld /Users/dohertj2/Desktop/ScadaBridge /Users/dohertj2/Desktop/ScadaBridge-old /Users/dohertj2/Desktop/scadalink-design 2>&1 ``` Expected: `ScadaBridge` exists (the old non-git project), `scadalink-design` exists, and `ScadaBridge-old` does **not** exist (`No such file or directory`). If `ScadaBridge-old` already exists, STOP and ask the user for a different aside-name. **Step 3: Move the existing ScadaBridge aside, then move the repo into place** Run: ```bash mv /Users/dohertj2/Desktop/ScadaBridge /Users/dohertj2/Desktop/ScadaBridge-old mv /Users/dohertj2/Desktop/scadalink-design /Users/dohertj2/Desktop/ScadaBridge ``` Expected: no output (success). **Step 4: Verify the move and that git still works in the new location** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && git status --short && git log --oneline -1 ``` Expected: clean tree; the HEAD commit is the design-doc commit (`docs: add folder/repo rename design doc ...`). Confirms git history survived the folder move. **Step 5: No commit** — filesystem moves are not git changes. Proceed to Task 1. **Acceptance:** `~/Desktop/ScadaBridge` is the git repo (clean tree, intact history); `~/Desktop/ScadaBridge-old` holds the former non-git project; `~/Desktop/scadalink-design` no longer exists. --- ### Task 1: Create the scrub script **Classification:** small **Estimated implement time:** ~3 min **Parallelizable with:** none **Files:** - Create: `/Users/dohertj2/Desktop/ScadaBridge/tools/scrub-scadalink-refs.sh` **Step 1: Write the script** Create `tools/scrub-scadalink-refs.sh` with exactly this content: ```bash #!/usr/bin/env bash # One-time scrub of residual ScadaLink/scadalink references → ScadaBridge. # Operates on git-tracked TEXT files only (git grep -I skips binaries), # minus carve-out migration records whose before→after meaning must survive. # Substitutions are applied most-specific-first so a broad rule cannot # double-replace an earlier result. Idempotent: re-running is a no-op. set -euo pipefail cd "$(git rev-parse --show-toplevel)" # Carve-outs (migration records): prior rename tooling/design, the DB-rename # helper, this script itself, and the two rename design docs. EXCLUDES_RE='^(tools/rename-to-scadabridge\.sh|tools/scrub-scadalink-refs\.sh|docker/rename-databases\.sh|docs/plans/2026-05-28-scadabridge-rename-design\.md|docs/plans/2026-05-31-folder-repo-rename-scadabridge-design\.md)$' files=() while IFS= read -r f; do [[ "$f" =~ $EXCLUDES_RE ]] && continue files+=("$f") done < <(git grep -liI 'scadalink' -- .) if [[ ${#files[@]} -eq 0 ]]; then echo "No files to scrub." exit 0 fi printf 'Scrubbing %d file(s):\n' "${#files[@]}" printf ' %s\n' "${files[@]}" sed -i '' \ -e 's/ScadaLink\.Host\.exe/ZB.MOM.WW.ScadaBridge.Host.exe/g' \ -e 's/ScadaLink__/ScadaBridge__/g' \ -e 's/SCADALINK_/SCADABRIDGE_/g' \ -e 's/scadaLinkVersion/scadaBridgeVersion/g' \ -e 's/scadalink_app/scadabridge_app/g' \ -e 's/ScadaLink/ScadaBridge/g' \ -e 's/scadalink/scadabridge/g' \ "${files[@]}" echo "Done." ``` **Step 2: Make it executable** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && chmod +x tools/scrub-scadalink-refs.sh ``` Expected: no output. **Step 3: Dry-run preview (list candidate files WITHOUT editing)** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && git grep -liI 'scadalink' -- . | grep -Ev '^(tools/rename-to-scadabridge\.sh|tools/scrub-scadalink-refs\.sh|docker/rename-databases\.sh|docs/plans/2026-05-28-scadabridge-rename-design\.md|docs/plans/2026-05-31-folder-repo-rename-scadabridge-design\.md)$' ``` Expected: a list of ~27 tracked source/config/test/doc files (the same set surfaced in the design doc), and NONE of the five carve-outs. No binary files (e.g. `site_events.db`) appear. If a carve-out appears, the script's `EXCLUDES_RE` is wrong — fix before running. **Step 4: No commit yet** — the script is committed together with the scrub in Task 4. **Acceptance:** `tools/scrub-scadalink-refs.sh` exists, is executable, and the dry-run lists only the intended files. --- ### Task 2: Run the scrub and pass the completeness gate **Classification:** high-risk **Estimated implement time:** ~3 min **Parallelizable with:** none **Files:** (the script edits ~27 tracked files in place; see Task 1 dry-run) **Step 1: Run the scrub** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && bash tools/scrub-scadalink-refs.sh ``` Expected: `Scrubbing N file(s):` followed by the file list and `Done.` **Step 2: Completeness gate — only the five carve-outs may still match** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && git grep -niI 'scadalink' -- . \ ':!tools/rename-to-scadabridge.sh' \ ':!tools/scrub-scadalink-refs.sh' \ ':!docker/rename-databases.sh' \ ':!docs/plans/2026-05-28-scadabridge-rename-design.md' \ ':!docs/plans/2026-05-31-folder-repo-rename-scadabridge-design.md' ``` Expected: **no output** (zero hits outside the carve-outs). If any line prints, inspect it — it is either a new case variant the substitution list missed (add a rule and re-run) or a file that should have been carved out. **Step 3: Sanity-check the new env-var names landed** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && git grep -nE 'SCADABRIDGE_CONFIG|ScadaBridge__|scadabridge_app|ZB\.MOM\.WW\.ScadaBridge\.Host\.exe' -- src/ deploy/ docker/ docker-env2/ | head ``` Expected: hits showing `SCADABRIDGE_CONFIG` in compose/Host, `ScadaBridge__` and `ZB.MOM.WW.ScadaBridge.Host.exe` in `deploy/wonder-app-vd03/install.ps1`. **Step 4: Review the diff** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && git diff --stat ``` Expected: ~27 files changed, all content-only. Spot-check `git diff docker/docker-compose.yml src/ZB.MOM.WW.ScadaBridge.Host/Program.cs` shows clean `SCADALINK_` → `SCADABRIDGE_` swaps. **Step 5: No commit yet** — commit after the build/test gate (Task 4). **Acceptance:** completeness gate returns zero hits outside the five carve-outs; new names present in code/config; diff is content-only. --- ### Task 3: Build, run unit tests, fix any stragglers **Classification:** standard **Estimated implement time:** ~5 min **Parallelizable with:** none **Files:** (no planned edits; only stragglers surfaced by the build, if any) **Step 1: Restore + build the solution** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && dotnet build ZB.MOM.WW.ScadaBridge.slnx 2>&1 | tail -20 ``` Expected: `Build succeeded` with 0 errors. The scrub only renamed env-var string literals, a method parameter (`scadaLinkVersion` → `scadaBridgeVersion`), comments, and docs — no type/namespace changes — so the build should be clean. If an error appears (e.g. a parameter referenced by name elsewhere), fix that single reference and rebuild. **Step 2: Run the CLI + Transport + ConfigurationDatabase unit tests (the projects whose code changed)** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && dotnet test tests/ZB.MOM.WW.ScadaBridge.CLI.Tests/ tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/ 2>&1 | tail -25 ``` Expected: all tests pass. These projects assert on the env-var name string literals (`SCADABRIDGE_FORMAT`, `SCADABRIDGE_USERNAME`, …) and the `scadaBridgeVersion` parameter — they were scrubbed in lockstep with the code, so they stay consistent. If a test references an env var the code no longer sets (or vice-versa), reconcile the pair. **Step 3: No commit yet** — commit in Task 4. **Acceptance:** `dotnet build` clean; the changed projects' unit tests green. --- ### Task 4: Commit the scrub **Classification:** trivial **Estimated implement time:** ~1 min **Parallelizable with:** none **Files:** (commit only) **Step 1: Stage and commit** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && git add -A && git commit -m "refactor: scrub residual ScadaLink refs → ScadaBridge (env vars, config keys, assembly name, SQL login) Renames the 13 SCADALINK_* runtime env vars → SCADABRIDGE_*, the ScadaLink__ .NET config keys → ScadaBridge__, the stale ScadaLink.Host.exe assembly name → ZB.MOM.WW.ScadaBridge.Host.exe, the scadalink_app SQL login → scadabridge_app, and residual identifiers/comments/docs. Migration records (prior rename tooling/design, DB-rename helper, this scrub script) carved out. Adds tools/scrub-scadalink-refs.sh." ``` Expected: commit succeeds; `~28` files changed (the 27 scrubbed + the new script). **Step 2: Verify** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && git log --oneline -2 && git status --short ``` Expected: the refactor commit on top of the design-doc commit; clean tree. **Acceptance:** scrub committed; clean working tree. --- ### Task 5: Update the local Git remote after the Gitea web-UI rename **Classification:** small **Estimated implement time:** ~2 min **Parallelizable with:** Task 6 **Files:** (git remote config only) **Step 1: Manual gate — user renames the repo in the Gitea web UI** Ask the user to rename the repository at `https://gitea.dohertylan.com/dohertj2/scadalink-design` to `ScadaBridge` via **Settings → Repository Name**, and to confirm when done. Do NOT proceed until confirmed. **Step 2: Point `origin` at the new URL** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && git remote set-url origin https://gitea.dohertylan.com/dohertj2/ScadaBridge.git && git remote -v ``` Expected: both fetch and push lines show `.../dohertj2/ScadaBridge.git`. **Step 3: Verify the remote is reachable and refs match** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && git ls-remote origin HEAD ``` Expected: prints a commit SHA for `HEAD` (auth via macOS keychain succeeds). If it fails with not-found, the web-UI rename has not propagated — re-confirm with the user. **Step 4: Push the new commits** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && git push origin HEAD ``` Expected: push succeeds; the design-doc + scrub commits land on the renamed remote. **Acceptance:** `origin` points at `dohertj2/ScadaBridge`; `git ls-remote` and `git push` succeed. --- ### Task 6: Runtime cutover — rebuild + redeploy so containers read the new env vars (conditional) **Classification:** high-risk **Estimated implement time:** ~5 min **Parallelizable with:** Task 5 **Files:** (no edits — runtime only) **Step 1: Check whether a stack is running** Run: ```bash docker ps --format '{{.Names}}' | grep -E 'scadabridge|central|site' || echo "no stack running" ``` Expected: either a list of running containers, or `no stack running`. **If `no stack running`, SKIP this task** — the new env-var names apply automatically on the next `bash docker/deploy.sh`. Note this to the user and mark the task done. **Step 2: Rebuild the image and recreate the primary cluster** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && bash docker/deploy.sh 2>&1 | tail -30 ``` Expected: image rebuilds; containers recreated. (`deploy.sh` already force-recreates.) Containers now receive `SCADABRIDGE_*` from the scrubbed `docker/docker-compose.yml`. **Step 3: Recreate the second cluster (if it was running)** Run: ```bash cd /Users/dohertj2/Desktop/ScadaBridge && bash docker-env2/deploy.sh 2>&1 | tail -30 ``` Expected: env2 cluster recreated from the scrubbed `docker-env2/docker-compose.yml`. **Step 4: Smoke-test readiness + CLI** Run: ```bash sleep 20 curl -s http://localhost:9000/health/ready && echo cd /Users/dohertj2/Desktop/ScadaBridge && dotnet run --project src/ZB.MOM.WW.ScadaBridge.CLI -- --username multi-role --password password template list 2>&1 | tail -15 ``` Expected: `/health/ready` reports healthy; the CLI returns a template list (proves the Host read its config via the renamed `SCADABRIDGE_*` env vars). No DB rename/wipe is needed — database names are unchanged by this effort. **Acceptance:** either the stack is confirmed not-running (skipped), or the redeployed cluster is healthy and the CLI smoke passes against the new env-var names. --- ## Execution Notes - Tasks are strictly sequential 0 → 1 → 2 → 3 → 4, then 5 and 6 may run in parallel (both depend only on 4). - The completeness gate in Task 2 and the build/test gate in Task 3 are the safety net for a missed reference. - Rollback: `git reset --hard HEAD~1` (or `~2`) undoes the scrub commit; `mv` reverses the folder moves; `git remote set-url` reverts the remote.