Skip to content

Rename the fork's identity from t3x to coil (everything except the landing site) #71

Description

@radroid

The landing site is being rebranded to Coil in PR #69. That PR deliberately stops at the site. Everything else in the fork still says t3x, and this issue tracks moving it.

Scope

Roughly 108 tracked paths contain t3x. Grouped by blast radius:

Release identity

  • Release tags t3x-build-<sha> → coil-build-<sha>
  • Version strings 0.0.33-t3x.N → 0.0.33-coil.N
  • .github/workflows/t3x-release.yml

Update relay — read the hazard below before touching this

  • Worker t3x-update-relay (infra/t3x-update-relay/)
  • DEFAULT_RELAY_URL / RELAY_URL_ENV_VAR in apps/desktop/src/t3x/updateDelivery/config.ts
  • Repo variable T3X_UPDATE_RELAY_URL, secret T3X_UPDATE_HMAC_SECRET

Source directories

  • apps/desktop/src/t3x/, apps/server/src/t3x/, apps/web/src/t3x/, apps/web/src/components/t3x/, packages/contracts/src/t3x/
  • IPC surface: t3xUpdate method, channel constants

Automation — these strings are matched by running workflows, so renaming them is a cutover, not a find-and-replace

  • Workflows t3x-ci.yml, t3x-upstream-sync.yml, t3x-sync-resolve.yml, t3x-weekly-verify.yml, t3x-deploy-home.yml
  • Label t3x-sync (the sync + resolver workflows gate on it)
  • Branch prefixes t3x/sync-*, recovery tags t3x/pre-sync-* / t3x/last-good-*

Docs

  • docs/t3x/ — SEAMS.md, sync-agent-runbook.md, agents/, evidence/

Hazard 1 — renaming the relay strands every installed build

apps/desktop/src/t3x/updateDelivery/config.ts:24 bakes the hostname in at compile time:

export const DEFAULT_RELAY_URL = "https://t3x-update-relay.businesses.workers.dev";

The env override exists but no normal install sets it. So every already-shipped build polls that exact hostname forever. If the worker is renamed, those installs go silent — no error, they just never see another update, and there is no channel left to tell them.

Therefore: the t3x-update-relay worker must keep serving indefinitely, even after a coil-update-relay exists. Cheapest correct path is to keep the old worker deployed and have it proxy or 302 to the new one, and only retire it once telemetry shows no old clients polling. Renaming it in one shot is not an option.

Hazard 2 — do not reset the build counter

Good news, and it narrows the work: the updater does not compare version strings. decision.ts:118 compares a monotonic integer:

if (manifest.buildNumber <= installed.buildNumber) {
  return { kind: "skip", reason: "not-newer" };
}

So changing the version suffix -t3x.N → -coil.N is safe on its own — semver prerelease ordering never enters into it. (Worth stating explicitly, because coil sorts before t3x alphabetically, so a semver-based updater would have rejected every new build as a downgrade. This one won't.)

The actual constraint is that buildNumber must keep incrementing across the rename. If it resets to 1, every installed client sees 1 <= 22 and skips forever.

Suggested order

  1. Docs and source directories — no runtime effect, largest diff, do it while it is cheap.
  2. Release tags and version strings — verify buildNumber continuity on the first coil-* release.
  3. Automation strings — cut over label and branch prefixes together, since the workflows match on them.
  4. Relay last, as an additive migration per Hazard 1, never a rename.

Out of scope

The landing site (apps/t3x-home, worker t3x-home, .github/workflows/t3x-deploy-home.yml) — PR #69.

Activity

  1. radroid commented on Aug 12, 2026

    @radroid
    OwnerAuthor

    The macOS identity work landed ahead of this issue — read before renaming anything

    PR #85 (issue #70, permission prompts) had to touch app identity to fix TCC re-prompting, so part of
    this rename is already done and part of it is now more expensive than it looks. Both are worth
    knowing before someone runs a find-and-replace over t3x.

    Already done: the bundle id

    The fork's desktop app is now dev.curlycloud.coil, not com.t3tools.t3code. It had to change
    for #70: macOS stores one TCC permission row per (service, bundle id), and the fork shared its id
    with upstream's T3 Code (Nightly), so whichever app launched last owned the Screen Recording /
    Accessibility / Files & Folders grants and the other was re-prompted.

    It is set through T3X_DESKTOP_APP_ID, read by DESKTOP_APP_ID in scripts/build-desktop-artifact.ts
    (the one upstream-owned line this cost — see SEAMS.md). Four places must agree, and
    scripts/t3x/mac-signature.test.ts fails if they drift:

    • DESKTOP_BUNDLE_IDENTIFIER in scripts/t3x/mac-signature.ts (source of truth)
    • T3X_DESKTOP_APP_ID in .github/workflows/t3x-release.yml
    • DESKTOP_APP_ID in scripts/t3x/auto-build-desktop.sh
    • BUNDLE_ID in scripts/t3x/setup-mac-signing.sh

    Do not change it again. Every change to the bundle id costs the user one full round of permission
    dialogs, and docs/t3x/mac-signing/designated-requirement.txt has to be re-recorded with it. If the id
    is already the name we want, this issue gets that part for free.

    The good news: renaming the app does NOT reset permissions

    Grants are keyed to the designated requirement — identifier "<bundle id>" and certificate leaf = … —
    which mentions the bundle id and the signing certificate, and not productName. So renaming the
    visible app is free in TCC terms, as long as neither of those two moves.

    Trap 1: renaming the certificate would reset permissions

    The signing identity is called T3X Code Signing (scripts/t3x/setup-mac-signing.sh,
    MAC_SIGNING_IDENTITY_NAME, and the committed docs/t3x/mac-signing/certificate.pem). It contains
    T3X, so a sweep of that string will find it — and the certificate's identity is inside the
    designated requirement.

    Renaming it means a new certificate, which means one more round of prompts for every permission, plus:
    setup-mac-signing.sh --rotate, re-recording designated-requirement.txt, re-committing
    certificate.pem, and re-setting the T3X_MAC_CSC_P12_BASE64 / T3X_MAC_CSC_PASSWORD secrets. The
    runbook has the sequence. Recommendation: leave the certificate name alone, or fold it into the same
    release as any other identity change so the cost is one reset rather than two.

    By contrast the secret names and T3X_DESKTOP_APP_ID itself are invisible to macOS and can be renamed
    freely — they just have to move in lockstep across the workflow, the scripts and the test.

    Trap 2: renaming productName breaks the in-app update path, by design

    resolveMacInstallTarget (apps/desktop/src/t3x/updateDelivery/installTarget.ts:92) refuses an install
    when the .app name inside the dmg differs from the installed one:

    The downloaded build is named "Coil" but the running app is "T3 Code (Alpha)". Installing it would
    create a second app and leave this one untouched, so it was refused.

    That refusal is correct — it is what stops a rename producing two installed apps — which means the
    first renamed build cannot arrive through the updater
    . scripts/t3x/auto-build-desktop.sh has the same
    hazard from the other direction: its --install would create a new app and leave the one you actually
    run untouched (its own dry-run warning covers this).

    So this issue needs to pick one, explicitly:

    1. A documented one-time manual install — ship the renamed build, tell the user the toast will refuse
      it once, have them drag the dmg. Cheapest, and the refusal message should probably say so.
    2. A rename migration in the updater — accept a name change when the bundle ids match, install under
      the new name, remove the old bundle. Real work in stager.ts / installTarget.ts, and it needs the
      post-install verification to check the new path.

    Before renaming name: "t3code" in the staged package.json (build-desktop-artifact.ts:1925)

    Two things to verify rather than assume:

    • safeStorage. apps/desktop/src/settings/DesktopSavedEnvironments.ts:372 encrypts saved
      environment secrets with Electron's safeStorage, whose macOS keychain item is named after
      app.getName(). If that name changes, previously encrypted secrets may become undecryptable — check
      before renaming, and plan a re-encrypt if so.
    • User data. userDataDirName = "t3code" and legacyUserDataDirName = "T3 Code (Alpha)"
      (apps/desktop/src/app/DesktopEnvironment.ts:171-172) are hardcoded literals, independent of both the
      bundle id and productName — which is why fix(t3x): sign the macOS build with a stable identity so permission grants survive updates (#70) #85 did not move anyone's threads. Renaming those would
      orphan every thread, setting and session, so either leave them or write the migration.

    Docs this issue should update

  2. 47 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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