Two path/scope corrections before anyone starts
src/config/case-variants.ts is not a tracked file. It does not exist in the repo; it is a
per-run fixture written by the harness itself at tests/rebrand/test-rebrand.sh:150 and read back
at :790 as $TEMP_DIR/src/config/case-variants.ts. Anyone taking this ticket will hunt for a
source file that was never there.
Do not change CASE_TARGET_DISPLAY in place. It has 12 references across six test functions
(:779, 871, 928, 959, 1001, 1029). Swapping the shared value to a multi-token name moves far more
than the case-variants assertions and will produce failures unrelated to this defect. Add a
second, multi-token case alongside the existing single-token one.
Assert validity, not equality. The current assertion compares against a computed expected
string, which still passes when both sides are wrong in the same way. Every export const <name>
in the rebranded fixture should match ^[A-Za-z_$][A-Za-z0-9_$]*$ — a syntax assertion cannot be
satisfied by a matching mistake.
Sequencing: land this before #926, which will extend this same harness. Landing a fixture under
a vacuous guard repeats the #396 pattern. And #956 touches the same 1000-line file — serialise the
two rather than running them concurrently.
The regression guard for #933/#952 cannot fail on the input class that produced the bug. It only ever runs with a single-token target name, and the branch it is meant to protect is only reachable with a multi-token one.
#396-class: a gate that could not fail. Not listed in #396's body (its latest entries are 2026-08-21 and cover the payment-queue docblock guard, the REVOKE, doc citations, #575's exit criterion, connection-listener.ts and a wait-loop).
The defect it is supposed to guard
#952 was right and the fix is real. scripts/rebrand-case.mjs:143-147:
if (match === identity.sourceSlug && match !== identity.sourceDisplay) {
return identifierAdjacent
? asciiLower(identity.targetComponent) // "communitypaws"
: identity.targetSlug; // "community-paws"
}
Without the identifierAdjacent branch, __scripthammer_syncQueue rebrands to __community-paws_syncQueue — not a valid identifier. Prettier then reparses the hyphen as subtraction and rewrites it to .__community - paws_syncQueue, so the token no longer exists as a contiguous string and only the type-checker notices. The live consumer is tests/e2e/messaging/offline-queue.spec.ts:374.
Why the guard is vacuous
tests/rebrand/test-rebrand.sh:157 seeds the right fixture:
export const __scripthammer_syncQueue = true;
and test_case_preserving_rebrand() asserts it at :799 / :802:
expected="export const __${CASE_TARGET_SLUG}_syncQueue = true;"
if grep -Fqx "$expected" "$variants"; then
But CASE_TARGET_DISPLAY is set at :232-236 to "CaseProbe" or "GeoLarp" — both single-token. For a single-token name targetSlug === asciiLower(targetComponent), so both branches of the ternary produce identical output and the assertion passes either way.
Mutation test: delete the identifierAdjacent ? branch from rebrand-case.mjs:144-146 and the suite stays green.
test_component_identifiers_are_valid() (:453) does use the hostile two-word "geo LARP" (:459), but its identifier check at :499-503 greps only $logo (src/components/*Logo.tsx, resolved at :471), whose fixture carries component-cased identifiers only. It never reads src/config/case-variants.ts. The residual sweep at :845+ only checks that no old brand text survives; it has no notion of identifier validity.
So no test anywhere runs a space- or hyphen-bearing target against case-variants.ts.
Suggested fix
Run the case-variants assertions with a multi-token target as well as the current single-token one — "Widget Works" or the existing "geo LARP" — so targetSlug (widget-works) and asciiLower(targetComponent) (widgetworks) differ and the branch becomes observable.
Then make the assertion about validity, not just equality: every export const <name> in the rebranded case-variants.ts must match ^[A-Za-z_$][A-Za-z0-9_$]*$. Equality against a computed expected string still passes if both sides are wrong in the same way; a syntax assertion cannot.
Test
The change is the test. Verify it the way this file already verifies #911 and the residual gate: mutate rebrand-case.mjs:144-146 to always return identity.targetSlug, confirm the suite goes red, then restore. If it stays green, the new case is not reaching the branch either.
Two path/scope corrections before anyone starts
src/config/case-variants.tsis not a tracked file. It does not exist in the repo; it is aper-run fixture written by the harness itself at
tests/rebrand/test-rebrand.sh:150and read backat
:790as$TEMP_DIR/src/config/case-variants.ts. Anyone taking this ticket will hunt for asource file that was never there.
Do not change
CASE_TARGET_DISPLAYin place. It has 12 references across six test functions(
:779, 871, 928, 959, 1001, 1029). Swapping the shared value to a multi-token name moves far morethan the case-variants assertions and will produce failures unrelated to this defect. Add a
second, multi-token case alongside the existing single-token one.
Assert validity, not equality. The current assertion compares against a computed expected
string, which still passes when both sides are wrong in the same way. Every
export const <name>in the rebranded fixture should match
^[A-Za-z_$][A-Za-z0-9_$]*$— a syntax assertion cannot besatisfied by a matching mistake.
Sequencing: land this before #926, which will extend this same harness. Landing a fixture under
a vacuous guard repeats the #396 pattern. And #956 touches the same 1000-line file — serialise the
two rather than running them concurrently.
The regression guard for #933/#952 cannot fail on the input class that produced the bug. It only ever runs with a single-token target name, and the branch it is meant to protect is only reachable with a multi-token one.
#396-class: a gate that could not fail. Not listed in #396's body (its latest entries are 2026-08-21 and cover the payment-queue docblock guard, the REVOKE, doc citations, #575's exit criterion,connection-listener.tsand a wait-loop).The defect it is supposed to guard
#952was right and the fix is real.scripts/rebrand-case.mjs:143-147:Without the
identifierAdjacentbranch,__scripthammer_syncQueuerebrands to__community-paws_syncQueue— not a valid identifier. Prettier then reparses the hyphen as subtraction and rewrites it to.__community - paws_syncQueue, so the token no longer exists as a contiguous string and only the type-checker notices. The live consumer istests/e2e/messaging/offline-queue.spec.ts:374.Why the guard is vacuous
tests/rebrand/test-rebrand.sh:157seeds the right fixture:and
test_case_preserving_rebrand()asserts it at:799/:802:But
CASE_TARGET_DISPLAYis set at:232-236to"CaseProbe"or"GeoLarp"— both single-token. For a single-token nametargetSlug === asciiLower(targetComponent), so both branches of the ternary produce identical output and the assertion passes either way.Mutation test: delete the
identifierAdjacent ?branch fromrebrand-case.mjs:144-146and the suite stays green.test_component_identifiers_are_valid()(:453) does use the hostile two-word"geo LARP"(:459), but its identifier check at:499-503greps only$logo(src/components/*Logo.tsx, resolved at:471), whose fixture carries component-cased identifiers only. It never readssrc/config/case-variants.ts. The residual sweep at:845+only checks that no old brand text survives; it has no notion of identifier validity.So no test anywhere runs a space- or hyphen-bearing target against
case-variants.ts.Suggested fix
Run the case-variants assertions with a multi-token target as well as the current single-token one —
"Widget Works"or the existing"geo LARP"— sotargetSlug(widget-works) andasciiLower(targetComponent)(widgetworks) differ and the branch becomes observable.Then make the assertion about validity, not just equality: every
export const <name>in the rebrandedcase-variants.tsmust match^[A-Za-z_$][A-Za-z0-9_$]*$. Equality against a computed expected string still passes if both sides are wrong in the same way; a syntax assertion cannot.Test
The change is the test. Verify it the way this file already verifies #911 and the residual gate: mutate
rebrand-case.mjs:144-146to always returnidentity.targetSlug, confirm the suite goes red, then restore. If it stays green, the new case is not reaching the branch either.