Skip to content

The #952 case-preserving guard cannot fail: it only tests single-token names, where both branches agree #958

Description

@TortoiseWolfe

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions