fix(branding) [BRNS-DESK-017]: stop sending feedback and exports to the upstream fork - #84
fix(branding) [BRNS-DESK-017]: stop sending feedback and exports to the upstream fork#84sebastian-ssvlabs wants to merge 1 commit into
Conversation
…he upstream fork /feedback opened https://github.com/AnyiWang/OpenCovibe/issues — every bug report a user filed from the app landed in an unrelated third party's public tracker. It now points at ssvlabs/brains-desktop, and package.json's homepage / repository / bugs plus the issue-template config follow the same target so the constant and its stated source of truth stay in agreement. HTML export embedded upstream branding and an outbound link to that fork into content users share: the generator meta, the <title> suffix, the "Generated by" footer link, and the downloaded filename prefix are now brains. Remaining user-visible copy: the eight locale strings in both en and zh-CN (including layout_appName, rendered as a heading), the About modal version line, the command-palette and /feedback descriptions, and the remote-access login page's title and heading. settings_general_apiKeyStored also claimed the key lived in ~/.opencovibe/settings.json; the data dir is ~/.brains, so the string was wrong as well as misbranded. About's copyright keeps upstream credit rather than erasing it — this is an Apache-2.0 fork and NOTICE still carries the upstream notice. scripts/branding-check.sh guards only the surfaces cleaned here. The rebrand is partial by design: data-dir paths, OPENCOVIBE_* env vars, the Codex handshake identity, the crate name, historical comments, and the attribution files must keep the upstream name, so a repo-wide grep could never be green.
| status=0 | ||
|
|
||
| # 1. Zero-tolerance surfaces: user-facing copy, exported content, repo metadata. | ||
| strict_paths=( |
There was a problem hiding this comment.
🟡 BRNS-DESK-017: gate omits static/ although the ticket names it explicitly — static/architecture.svg and static/architecture-zh.svg still contain ~/.opencovibe/ at head, and architecture-zh.svg renders user-facing in AboutModal.svelte via the README.zh-CN.md embed, so the regression the ticket calls out is neither fixed nor catchable. Fix the two SVG labels and add static to strict_paths.
| package-lock.json | ||
| .github/ISSUE_TEMPLATE/config.yml | ||
| ) | ||
| if hits=$(grep -rniE "$pattern" "${strict_paths[@]}"); then |
There was a problem hiding this comment.
🟡 Gate fails open on grep error: if any path in strict_paths is renamed or deleted, grep exits 2 (error) even when other listed files contain real hits, if hits=$(...) takes the else branch, and the script exits 0 printing success — the whole rule is silently disabled. Capture the exit code and treat anything other than 1 as failure (e.g. hits=$(grep ...); rc=$?; [ "$rc" -ne 1 ] && status=1), or pre-check that every listed path exists.
nir-ssvlabs
left a comment
There was a problem hiding this comment.
The gate is the part I'd have been most sceptical of and it holds up: branding:check is genuinely wired into ci.yml as a blocking step (line 86), not just committed — which is the failure mode a sibling guard in the brains repo hit — it passes clean here, and scoping it explicitly rather than grepping repo-wide is right, since LICENSE / NOTICE / CODE_OF_CONDUCT / the README's "Forked from" are attribution that has to stay. The grep -rniE 'anyiwang' src arm covers the whole app surface, so the fix can't rot back in where it matters.
🟡 Medium · the documented reporting route still points at the fork (non-blocking): @sebastian-ssvlabs CONTRIBUTING.md:7-8 sends Bug reports and Feature requests to https://github.com/AnyiWang/OpenCovibe/issues/new, and line 16 clones from there. That is the same class this PR closes — user-authored report content reaching a repo we don't control — just via the documented path rather than /feedback. The gate can't catch it because the anyiwang arm is scoped to src. Repoint those three lines and add CONTRIBUTING.md to strict_paths, and the whole reporting surface is closed rather than the in-app half.
Checked: every remaining anyiwang/opencovibe hit in the tree triaged into attribution vs live routing, the gate's scope and its CI wiring, and that it exits 0 on this branch. Not read: the eight locale strings one by one — i18n-check covers alignment and the visible ones are named in the description.
Merge: ✅ into main — the in-app leak is the urgent half and it's fixed. The CONTRIBUTING.md route is worth folding in before this closes the ticket.
Summary
/feedbackfiled user bug reports to a third party. It openedhttps://github.com/AnyiWang/OpenCovibe/issues— the upstream fork's public tracker. Anything a user typed into a bug report (paths, project names, whatever they pasted) went to a repo we don't control and can't delete from. Nowhttps://github.com/ssvlabs/brains-desktop/issues.<meta name="generator" content="OpenCovibe">, a… — OpenCovibe<title>, a live outbound<a href>to the fork in the footer, and anopencovibe-*.htmlfilename on the recipient's disk. All four are brains / ssvlabs now.enandzh-CN, includinglayout_appName— which renders as a visible<h2>heading in the chat empty state (chat/+page.svelte:4862,5524).settings_general_apiKeyStoredwas factually wrong as well as misbranded: it told users their API key was in~/.opencovibe/settings.json.data_dir()is~/.brains(src-tauri/src/storage/mod.rs:28) and the settings file is~/.brains/settings.json(src-tauri/src/storage/settings.rs:6), so anyone following that string looked in a directory that does not exist. Fixed to the real path./feedbackslash-command description, the remote-access login page,package.jsonmetadata, and the issue-template config.What changed, by surface
src/routes/chat/+page.svelteopen-feedbackURL →ssvlabs/brains-desktop/issuessrc/lib/utils/html-export.tsgeneratormeta,<title>suffix, footer link + label, download filename prefixbrains-messages/en.json,messages/zh-CN.jsonlayout_appName,feedback_opening,settings_general_webEnabledDesc,settings_codexFlags_title,settings_codexFlags_subtitle,history_totalCost,cmd_versionContent,settings_general_apiKeyStoredsrc/lib/components/AboutModal.sveltet("layout_appName")instead of a hardcoded name; copyright reworked (below)src/lib/commands.tssrc/lib/utils/slash-commands.ts/feedback→ "Open the brains issue tracker" (hardcoded description, same user-visible list as the palette)src-tauri/src/web_server/auth.rsLOGIN_HTML<title>and<h1>package.json,package-lock.jsonname→brains-desktop;homepage/repository/bugs→ ssvlabs.versionuntouched; the lock's twonamefields follow sonpm cistays consistent.github/ISSUE_TEMPLATE/config.ymlscripts/branding-check.sh(new),.github/workflows/ci.yml,package.jsonnpm run branding:check, also added toverifyThe copyright line
This is an Apache-2.0 fork, so §4(d) means the upstream notice has to survive in the derivative work — erasing it would be a licence violation, and
NOTICE(untouched) still carries it. The About footer now reads:brains is presented as the product; upstream keeps accurate credit for the portions it wrote. Same shape as the
NOTICEfile, one line so the flex footer layout is unchanged.What this deliberately does NOT rename
The most important part of this review: ~100 occurrences of the upstream name legitimately remain. Renaming any of these changes runtime behaviour or breaks installed users.
~/.opencovibe/…paths in code,opencovibe-uploads/opencovibe-attachmentstemp dirsOPENCOVIBE_TASK_ID,OPENCOVIBE_RUN_ID"name": "opencovibe"/"title": "OpenCovibe"inagent/codex_appserver.rs,agent/codex_control.rsopencovibe_desktop_libinsrc-tauri/Cargo.tomlDB_NAME = "opencovibe-snapshot"insrc/lib/utils/snapshot-cache.tsLICENSE,NOTICE,CODE_OF_CONDUCT.mdREADME.md,README.zh-CN.md,CONTRIBUTING.mdThe CI gate and why it is narrow
scripts/branding-check.sh, wired in as a blocking step after the i18n check. Because so much of the upstream name is load-bearing, a repo-wide grep would fail on the first run and stay red forever — so the gate names the cleaned surfaces instead, in three rules:opencovibe|anyiwang(case-insensitive) inmessages/,src/lib/commands.ts,src/lib/utils/html-export.ts,src-tauri/src/web_server/auth.rs,package.json,package-lock.json,.github/ISSUE_TEMPLATE/config.yml. Those files are now completely clean, so any hit is a regression.anyiwanganywhere undersrc/— the real invariant behind this ticket: nothing the frontend ships may link a user to the upstream fork. This catches a reintroduced/feedbackURL or export footer even in a file that legitimately keeps the name in a comment.AboutModal.sveltemay keep exactly one upstream mention — the line carryingportions Copyright. Anything else there means the product started naming itself after the fork again.Rule 2 is intentionally scoped to
src/and notsrc-tauri/, becausesrc-tauri/src/commands/updates.rsstill contains upstream URLs (follow-up 1 below). Widening rule 2 to the Rust tree is the natural second commit once that is resolved.Follow-ups found but not done here
src-tauri/src/commands/updates.rs:7— I would prioritise this above the bug I just fixed.GITHUB_API_URLishttps://api.github.com/repos/AnyiWang/OpenCovibe/releases/latest, and the About modal's "Update to latest" button resolvesdownloadUrlfrom that response and hands it toplugin-shell::open. The app therefore offers users an unrelated third party's binary as its own update. Left untouched because it is outside this ticket's stated scope and it is behaviour-changing: flipping the constant needs the brains-desktop release channel to actually publish releases, or the updater simply breaks. Needs its own ticket and a decision about where releases live.SECURITY.md:18points vulnerability reports athttps://github.com/AnyiWang/OpenCovibe/security/advisories/new— exactly the same misrouting class as/feedback, for the reports that matter most.README.zh-CN.mdleaks into the UI.AboutModalimports both READMEs with?rawand renders one per locale.README.md(en) is already brains-branded, but the zh-CN one is still the upstream document, so Chinese users' About tab shows upstream releases / clone / issues links (lines 87, 94, 132, 237).scripts/clean-dmg.mjs:19matches/^OpenCovibe_.*\.dmg$/whiletauri.conf.jsonproductNameis alreadybrains— theprebuild:dmgcleanup is dead code today.scripts/release.mjs:100prints upstream's Actions URL;scripts/setup.shandscripts/check-serde-sync.shstill identify as OpenCovibe;docs/UI-REFERENCE.mdis titled "OpenCovibe UI Reference";src/routes/_opencovibe_layout.svelte.txtcarries the name in its filename.package.jsondescriptionis still upstream's "Local-first desktop app for AI-assisted vibe coding".Verification
node scripts/i18n-check.mjs— 0 errors, 18 warnings, byte-identical to the baseline onmain(all warnings are pre-existing "same as en" on unrelated keys).cmd_versionContentstays covered by the script's untranslated-allowlist;layout_appName: "brains"is classified technical, so no new warning.npx prettier --checkon all 8 changed frontend files — clean. OnlyAboutModal.svelteneeded--write, and the reflow is confined to the two lines I touched.npx eslinton the 5 changedsrc/files — 0 errors. One pre-existingIS_WEBKITunused-var warning inchat/+page.svelte, untouched by this diff.cargo fmt --manifest-path src-tauri/Cargo.toml --check— exit 0, no reformatting (the change is inside a raw string literal).npm run branding:check— passes. Negative-tested: revertinglayout_appNameto"OpenCovibe"makes it exit 1 and print the offending file:line, then restoring it goes green again.slash-commands.test.tsasserts_action/name, neverdescription; no test referencesbuildExportFilename's output orLOGIN_HTML's body; the/feedbackURL had no test.npm run build,npm run check, vitest,cargo test,cargo clippy. CI owns all five.--no-verify: the pre-commit hook'ssvelte-checkstep needs the missing local.svelte-kit. Its ESLint step did run first and reported 0 errors.Review notes
Possible collisions with sibling DESK PRs: BRNS-DESK-026 adds Terms/Privacy links to
AboutModal.svelte(same footer region), and 022 / 027 / 028 / 030 touch the locale files. Whichever lands second needs a rebase; both conflicts are mechanical.