feat: new skill new-project-naming-check

Trademark + domain clearance procedure for any new product/project
name, established while naming the Turnero job-board project. Covers:
querying OEPM's real live trademark search (consultas2.oepm.es) rather
than any partial local mirror -- confirmed Vixilia's own bopi_records
backfill is still incomplete (only reached 2012 as of 2026-08-23) and
would give false-clean results for anything registered 2015-2025; and
checking domain availability separately, since a clean trademark result
doesn't imply an available domain (confirmed real case: "Turnero" had
zero trademark hits but both turnero.com and turnero.es were already
taken by unrelated parties).
This commit is contained in:
2026-08-23 20:10:53 +02:00
parent 8dd10ed81c
commit fa824ed4e0
+130
View File
@@ -0,0 +1,130 @@
---
name: new-project-naming-check
description: Use whenever a new product/project name is being proposed, shortlisted, or locked in — before writing it into a project brief, before a design pass starts, before any domain purchase or trademark filing. Covers checking Spanish trademark conflicts (via OEPM's real live search, not any partial local mirror) and domain availability across relevant TLDs.
---
# New Project Naming Check
A candidate name for a new product/project is not "clear" just because it
sounds original or because a quick web search didn't surface a competitor.
Two concrete things need checking before a name is locked in, a design
pass starts, or money is spent on a domain/filing: **trademark
conflicts** and **domain availability**. Both are cheap, fast checks —
do them every time, for every new project name, before it goes into a
brief as more than a placeholder.
Confirmed working procedure, established 2026-08-23 while naming the
Turnero job-board project (`docs/project-briefs/turnero.md`) — also used
that same pass to spot-check several already-shipped product names
(Bauxa, Mequeda, Pragmatiq, Vixilia, Mobiwoo, Tracelead, Pesiq, Apuntiq,
El Cupo, Mareta), which is worth doing retroactively for any product name
that's never actually been checked, not just brand-new ones.
## 1. Trademark check — use OEPM's real live search, not a local mirror
**Live tool**: `https://consultas2.oepm.es/LocalizadorWeb/busquedaDenominacion`
— OEPM's own "Localizador de Marcas y Nombres Comerciales." Free, no
registration needed, searches the complete, current Spanish trademark +
trade-name register directly.
**Do not substitute a local database mirror for this**, even if one
exists in the fleet (e.g. Vixilia's `bopi_records`, built by walking
historical OEPM bulletins) — a mirror built from a backfill can be
genuinely incomplete for a large date range while still returning "0
results" and looking clean. Confirmed: as of 2026-08-23, Vixilia's own
historical backfill had only reached 2012, leaving 2015-2025 entirely
unfilled — a name-conflict check against that table would have missed
anything registered in that gap. Always go to the live OEPM tool for an
actual naming decision; a local mirror (if one exists for other reasons)
is not a substitute source of truth here.
**How to query it** — plain `fetch`/`curl`/WebFetch gets a 403 (bot-
blocked); it needs a real browser session:
```js
const { chromium } = require('playwright'); // use whatever local Playwright install is available, e.g. find one under /tmp/*/node_modules/playwright
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://consultas2.oepm.es/LocalizadorWeb/busquedaDenominacion', { waitUntil: 'networkidle', timeout: 30000 });
const inputs = await page.$$('input[type="text"]');
await inputs[0].fill(candidateName); // first input = national marks/trade names section
await page.click('#btnLocalizar1');
await page.waitForTimeout(3000);
await page.waitForLoadState('networkidle', { timeout: 20000 }).catch(() => {});
const resultsText = await page.evaluate(() => document.body.innerText);
```
The page has two independent search sections — national marks/trade
names (first `input[type="text"]`, button `#btnLocalizar1`) and
international marks with effect in Spain (second `input[type="text"]`,
button `#btnLocalizarInt`) — check both for a thorough pass; the national
section alone is usually sufficient for a first read. Default search mode
is "Contenga" (contains), which is the right broad setting for a
conflict-check pass.
**Reading results — exact match vs. compound-mark clutter**: a search
for a short/common word will often return dozens of hits, almost all of
which are compound marks (e.g. searching "Curro" returns "CURRO
JIMENEZ", "CURRO-VISION", "CA CURRO" — 80 results, zero of them a
standalone "CURRO" mark). These are low real risk. What actually matters
is an **exact, standalone match** — e.g. a search for "Mareta" returned
a genuine `MARETA` mark (denominativo, standard characters, no compound
words) in class 32. That's a real finding worth flagging even if the
registered class differs from the product's own field, since it's
categorically different from the compound-mark noise around it — call
it out explicitly in whatever brief/report this feeds into, don't bury
it in a list of harmless partial matches.
## 2. Domain availability — check this even if the trademark search is clean
A clean trademark search does not mean the name is available as a
domain. Confirmed real case: "Turnero" came back with **zero** OEPM
trademark hits, but both `turnero.com` (registered since 2012, active
through 2030) and `turnero.es` (actively hosting a real, unrelated,
Google-Analytics-tracked facility-queue system, not a parked domain)
were already taken. Always check domains as a separate step, don't infer
availability from a clean trademark result.
```bash
# .com and most gTLDs have a public whois server
whois <name>.com
# .es has no public whois server — check via DNS + a live fetch instead
dig +short NS <name>.es
dig +short A <name>.es
curl -s -o /dev/null -w "%{http_code}\n" -L "http://<name>.es"
# If it returns NS records or a 200, it's taken — fetch the page itself
# to see what's actually there (parked/for-sale vs. a real active site)
# before concluding anything about how "available" it really is.
curl -s -L "http://<name>.es" | grep -o '<title>[^<]*</title>'
```
Check every TLD actually relevant to the launch (typically `.es` and
`.com` for a Spain-first product; add `.app`/`.io`/others only if the
brief calls for them). If the primary TLDs are taken, check realistic
variants (`el<name>.es`, `<name>app.com`, etc.) before concluding the
name itself needs to be dropped — but report the conflict clearly either
way rather than silently substituting a variant without flagging it.
## When to run this
- Before writing a candidate name into a project brief as more than an
explicitly-labeled placeholder.
- Before any domain purchase or trademark filing is proposed as a next
step.
- Retroactively, once, for any existing shipped product name that was
never actually checked — cheap to do in the same pass as a new check,
and has already surfaced one real finding in this fleet (see the
Pragmatiq/Mareta findings in `docs/project-briefs/turnero.md`).
## What NOT to do
- Don't treat a clean OEPM result as a green light without also checking
domains — the two checks are independent and a name can pass one and
fail the other.
- Don't register a domain or file anything based on this check alone
without the user's explicit go-ahead — this skill covers the
diagnostic check itself, not the purchase/filing decision.
- Don't skip the check because a name "sounds original" — several
candidates in this fleet's own naming passes that sounded clearly
available turned out to have real conflicts once actually checked.