Everything this site says about me comes out of a single file: src/lib/profile.ts, 596 lines. My title is in there, the topics I supposedly know are in there, my projects are in there, and so is the list that tells you where else to find me on the internet. That list is called sameAs and it holds 12 addresses.
I opened the file today for an unrelated job, read the comment I had written above the sameAs block, and stopped:
// Wikidata — knowledge graph icin EN GUCLU sinyal. Google bu link'i
// gorunce "bu kisi Wikidata'da kayitli, ayri entity" der → knowledge
// panel + indeksleme suresi yariya iner.
'https://www.wikidata.org/wiki/Q139679043',
Translated: Wikidata is the strongest signal for the knowledge graph; when Google sees this link it decides I am a separate entity, and indexing time is halved. Two claims in three lines — one about a mechanism, one about a result. I wrote both, and I cited neither. Reading further, I noticed something else: I declare the same identity in other places too. On Wikidata, on ORCID, in my YouTube channel description. Four separate ledgers.
So I sat down and measured it. I put the ledgers side by side, asked every address whether it points back at me, and carried that comment in my code over to Google's current documentation. None of them gave me the answer I expected.
Four ledgers, thirteen identities
The count: sameAs in profile.ts holds 12 entries (one is this site itself, the other 11 are external). My Wikidata item lists Bluesky, X, GitHub and LinkedIn as social identities, plus an official website and a "described at" address. My ORCID profile holds five addresses. My YouTube channel description holds five as well.
Merge the four and you get 13 unique identities. Each row below is one identity, each column one ledger:
| Identity | profile.ts | Wikidata | ORCID | YouTube |
|---|---|---|---|---|
| this site | ✓ | ✓ | ✓ | ✓ |
| Bluesky | ✓ | ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ | ✓ | |
| GitHub (merbay-erp) | ✓ | ✓ | ✓ | — |
| X | ✓ | ✓ | — | ✓ |
| Wikidata | ✓ | — | ✓ | — |
| ORCID | ✓ | — | — | — |
| YouTube | ✓ | — | — | — |
| dev.to | ✓ | — | — | — |
| Hashnode | ✓ | — | — | — |
| GitHub (esclips) | ✓ | — | — | — |
| Bridgy Fed | ✓ | — | — | — |
| Mastodon | — | — | — | ✓ |
Three identities appear in all four ledgers: this site, Bluesky and LinkedIn. Seven appear in exactly one.
But in those three rows I am saying "same identity", not "same address" — and the gap between the two turned out to be exactly what I was looking for. Two of the three shared identities change address from ledger to ledger. The Bluesky row is mustafaerbay.bsky.social in my code and mustafaerbay.com.tr in my YouTube description; as you will see shortly, the second one resolves to no account at all. The LinkedIn row is /in/mustafa-e-6a891370/ in my code and /in/mustafaerbay in the description. Which of those two is my profile, this measurement cannot say, because LinkedIn turns automated requests away at the door — but for both to be right, the profile would need two addresses at once.
So the two best-looking rows in the table carry a disagreement once you look closely. The only thing all four ledgers truly share is this site itself.
And the bottom row marks a hole: my Mastodon account lives only in the YouTube description, nowhere in the code.
There is no architectural error here — each ledger has its own purpose, and one of them being shorter is not a defect. What bothers me is different. I checked the repo history: the identity file's first version is 1 May 2026, the Wikidata line went in on 9 May, the YouTube description was written on 15 May. Three separate days, two weeks, and on none of them did I ask which of these lists was the right one. I thought identity declaration lived in one place — right up until I found the fourth ledger.
The addresses that look back
The real question is not how long the list is. Putting an address in sameAs means saying "this one is mine too" — and so far the only party saying it is me. Does the other side say the same thing?
I fetched each of the 11 external addresses and checked whether the page links back to this site:
| Address | Reachable | Points back |
|---|---|---|
| Wikidata | 200 | Yes — official website + described-at |
| ORCID | 200 | Yes — but only in the API response |
| GitHub / merbay-erp | 200 | Yes — profile website field |
| GitHub / esclips | 200 | Yes — but via my second domain |
| YouTube | 200 | Yes — plain text in the channel description |
| X | 200 | Yes — profile link field |
| dev.to | 200 | Yes — profile website field |
| Bridgy Fed | 200 | Yes — and with rel="me"
|
| Bluesky | 200 | No — no address on the profile |
| Hashnode | 200 | No — only inside one post's body |
| 999 | Could not measure — request blocked |
Eight point back, two do not, one I could not measure. The ratio is not bad. But two rows of that table say more about the measurement than about the addresses.
The first is ORCID. I fetched the HTML and this site's name did not appear anywhere: zero. I noted "so my ORCID profile has no website" and moved on. Then I got uneasy — if something is missing from a page's HTML, that does not mean it is absent, it may mean the browser fills it in afterwards. I asked ORCID's public API: five addresses came back, the first one this site. So my first measurement was wrong, and wrong in the direction of "missing".
The second is Hashnode. There too I found nothing in the HTML, but when I tried to confirm it through the API, the GraphQL endpoint redirected me to an HTML page; adding -L got me Next.js output, not JSON. So for Hashnode I have exactly one method, and I know that method already misled me once on ORCID. The honest way to read that "no" is "could not confirm".
LinkedIn's 999 is not a measurement at all. The server did not hand me a page, it handed me a door. If I wrote it down as "no address on the profile" I would be inventing a result; writing "yes" would be inventing one too. The third option is to leave it empty.
Then there is the esclips row, my favourite. That profile lists mustafaerbay.com — while this site is mustafaerbay.com.tr. It looks like the wrong address. I followed it: a 301 lands exactly here, the domain is mine, registered in April 2026. So the declaration is correct; it is my own sameAs list that never mentions that domain. My scan called it missing, and reality turned out to be a surplus.
Two dead addresses that return 200
My YouTube channel description is the least inspected of the four ledgers. It lists five addresses. Two of them do not work.
The first is Bluesky. The description says bsky.app/profile/mustafaerbay.com.tr — my own domain standing in as the handle. I opened it and got HTTP 200 — and stopping right there, reassured, would be the easiest thing in the world. But that 200 is the empty shell of Bluesky's single-page app; ask it for any address at all and you get 200. What actually determines the account is handle resolution, and its answer is unambiguous: Unable to resolve handle. My real account sits under mustafaerbay.bsky.social, and it works.
Turning a domain into a Bluesky handle is possible, but not free. The protocol's handle specification recognises two routes: either a DNS TXT record under the _atproto subdomain whose value starts with did=, or an endpoint at /.well-known/atproto-did on your domain. I checked both — no TXT record, no endpoint: the request is first redirected (301) to its own trailing-slash form, and that returns 404. For comparison I asked Bluesky's own domain, where the TXT record is right there. So I wrote this address on top of a verification I never set up, and HTTP 200 has been telling me I was right all along.
One sentence from that same specification sums up this entire article: "Handles should not be trusted or considered valid until the DID is also resolved and the current DID document is confirmed to link back to the handle." The protocol says: do not trust the handle until you have confirmed it links back. That is exactly the step I skipped in my own sameAs list — I wrote the declaration and never asked about the link back.
The second is Mastodon. The description says mastodon.social/@mustafaerbay. The page returns 410 — "something was here, it is gone now". The server's API, however, still shows the account and explains it with a single field: suspended: true.
I was about to treat the rest of that response as data. Empty display name, empty bio, empty profile fields, post counter at zero — and yet the same response carries 16 May 2026 as the date of the last post. An account with no posts has no last-post date. So suspension cleared some fields and left others.
Rather than guess which was which, I ran a control: I asked the same endpoint about two accounts that are not suspended. Both of them had a creation timestamp rounded neatly to midnight too. So "a timestamp rounded to midnight" is not a trace of suspension, it is the shape this server hands everybody — I was about to use it as evidence, and I cannot. That leaves two readable things: the suspended field itself, and the last-post date that survived the suspension. The counter reading zero sits on the other side, among the cleared fields. Why the account was suspended is not something I can read here; the only thing I can read is that the line sitting in my own file now leads nowhere.
While writing these two rows I had a sentence ready: the YouTube description is just a text box, nobody reads it. Then I checked, and deleted the sentence. The description is not a text box, it is a file in my repository — a fixed string inside scripts/youtube-channel-setup.ts, one single commit since 15 May 2026, uploaded to the channel from there.
And that is the genuinely irritating part. Both files live in the same repository, the same compiler reads both, both go through the same build. Even so, no test compares the Bluesky address in one with the Bluesky address in the other. I keep the same identity in two places and there is not a line of code asking whether the two agree. My identity declaration does not sit in an unguarded area; it sits exactly where the guards never look.
What the comment in my code promises
Now for those three lines. "Knowledge panel + indexing time halved," they say. Let us ask Google.
I started with the standard itself. schema.org's definition of sameAs reads: "URL of a reference Web page that unambiguously indicates the item's identity." The examples given are a Wikipedia page, a Wikidata entry and an official website. The definition mentions no search engine, and sets no condition about the target page linking back. So sameAs is not a verification mechanism; it is a way of pointing.
Then I went to Google's current documentation. sameAs is still there, among the recommended properties of Organization markup, and its description is modest: the URL of a page on another website with additional information about your organization. The page does contain a sentence saying that some properties are used behind the scenes to disambiguate your organization from others — but the examples it gives there are iso6523 and naics, not sameAs. The same sentence then turns to visual elements, and the example offered there is logo. Nowhere does it mention indexing speed. Google's general structured data policy is blunter still: "Using structured data enables a feature to be present, it does not guarantee that it will be present."
The actual answer was on another page. In Google's list of documentation updates, the 11 May 2020 entry says:
Removed the following documentation that has been deprecated since June 2019: […] Social Profile structured data: We now automatically discover social profiles to include in Google knowledge panels.
(The bracketed ellipsis is mine: the same entry lists two other removed documents.) So social profile markup was abandoned in June 2019 and its documentation removed on 11 May 2020. The old URL still responds — but as an answer in its own right: a 301 to a page about submitting feedback on content about you. That page explains that the knowledge panel is generated automatically from publicly available information, and that once you verify your identity you can suggest social profiles.
This is worse than my comment being wrong. My comment describes the effect of a mechanism Google abandoned back in 2019, and then puts a number on it that nobody ever offered: halved. The file itself passes type checking; those three lines do not. Comments are the one region the build does not care about, and that is precisely where I put my boldest claim.
The standard that says "does not imply expertise"
The same file holds another list, knowsAbout, with 10 entries: system architecture, network engineering, zero trust, cloud platforms, and so on. My intent when writing it was obvious: to say I know about these things.
Read schema.org's Person definition and you learn what knowsAbout actually is: "to indicate a topic that is known about - suggesting possible expertise but not implying it." The standard adds, in its own sentence, that it draws no distinction between skill levels. So the field does not say "I am an expert"; it says "this topic is familiar to me" — and declines to call even that an implication.
That showed me I had not done something wrong, but had expected something wrong. I had treated ten entries as a shop window; the standard treats them as a footnote. Understanding the difference took a few minutes of reading. I wrote the first version of that file on 1 May 2026; in the six months since, I never spent those few minutes.
Where nothing was broken
Writing this up as nothing but bad news would be dishonest, because part of it came out solid.
The project list in profile.ts holds 14 projects, seven of them with addresses. I called all seven: all seven returned 200, no redirects, no parking pages, no expired domains. Eight projects are marked "live", and six of those are among the seven; the remaining two (köprü and Project Portal) have no address written down at all, so I could not even call them. No live project that has an address turned out to be hollow — about the two without one, this measurement says nothing.
The Wikidata side is genuinely two-way as well: the item's official website and described-at fields point here, and I point there from my code. And it is not the only such address — the Bridgy Fed page links back too, and it does so with rel="me".
Which led me to the last finding — and that finding put me face to face with my own warning.
The oldest and simplest way of binding an identity in both directions is rel="me": two pages point at each other with that marker and no third party is needed. I fetched my own home page, searched for rel="me", and got zero. I had already written "so I never set it up". Then I remembered the slap ORCID had given me and loosened the search: four links came back that start with rel="me. All four read rel="me noopener noreferrer".
The exact string I searched for was not there, because rel is a space-separated list; a browser reads it as three separate values, while my search took it for a single word. I had produced the same false negative twice in one article — this time after writing my own warning about it. When I counted the internal links in my archive I asked exactly this question and checked the alternative syntaxes one by one; what I did there, I failed to do here.
So: the mechanism is set up, but on only four of the twelve addresses — GitHub, LinkedIn, Bluesky and X. Wikidata, ORCID, YouTube, dev.to, Hashnode and Bridgy Fed are outside it. The answer to the rel="me" question is not "none at all", it is "on a third of them".
Before you add one: every address creates a link
One discomfort stayed with me as I finished this, and I would rather not swallow it. What I have done here is compile and publish a map of my own identity. sameAs is already a public declaration and so is a Wikidata item — but gathering scattered things into a single table does nothing useful in the cases where the scattering was itself the protection.
The longer an identity list gets, the more verifiable it becomes and the less private. The two do not rise together; there is a trade between them. My reason for accepting that trade is plain: I already write under my own name, I run a signed blog, my projects carry my name. That arithmetic does not come out the same for everyone. If you write under a pseudonym, if you want a wall between your work life and your hobby, or if one account being linked to another is a security matter for you, the right move may not be to verify the address but to keep it off the list entirely.
So there is a question zero before the five below: do I want this address publicly tied to me? If the answer is no, the rest of the questions do not apply.
Five questions for your own profile
- In how many separate places does your identity list live? The
sameAsin your code, your Wikidata item, platform profiles, channel descriptions, your email signature — count them all. If you believe you keep that list in one file, you will keep believing it until you run this count. - How many of those addresses point back at you? A declaration is one-way; verification is the two-way kind.
- By what method did you look for the backlink? Not finding it in HTML does not mean it is absent. If a platform has an API, ask a second time — that is exactly how I misread ORCID.
- Which address has real verification behind it? HTTP 200 proves the server is polite, not that the account exists. Wherever you turned a domain into a handle, go look for the verification record too.
- How many uncited claims are sitting in your code comments, in the places no test reads? They go stale, and nothing will tell you they did.
I wrote the fourth question for myself. What misled me most in this audit was not a broken record but a polite server.
Conclusion
Three items go down here as open work, so that six months from now I can be held to them: fix the two dead addresses in the YouTube description (swap in the real Bluesky handle, drop the suspended Mastodon line), rewrite those three comment lines in profile.ts against Google's current documentation, and turn this four-ledger comparison into a periodic check. A fourth item was born while this article was being written: extending the rel="me" marker from those four addresses to the remaining eight. I had been about to decide to add it, believing there was none; once I searched properly, the job turned out to be finishing it, not starting it.
The thought I am left with is this. When we manage a professional identity, we try to lengthen the list: one more platform, one more profile, one more entry. But adding an address is making a claim, and a claim's worth lies not in its length but in whether the other side acknowledges it. Behind my 12-line list sat four separate ledgers, two dead addresses and one uncited SEO promise I had written to myself.
And the work it produced does not point one way either: the suspended Mastodon line and the unresolvable Bluesky address can only be fixed by deletion, while the rel="me" marker and my second domain can only be fixed by addition. No rule of "shorten" or "lengthen" falls out of this. The only rule that does is that every line should have an answer coming back from the other side.
When I learned my sitemap was declaring the wrong language, the problem sat in a field machines read. Here the problem sits in fields that say something about me and that nobody reads back. What they have in common is the answer to one question — who last audited what I declared — and that answer was "nobody".
Tonight, go look at your own sameAs list. Don't count its length; count how many of them look back at you.
Official Sources
- schema.org — sameAs: the property's definition, "URL of a reference Web page that unambiguously indicates the item's identity", and its expected value type.
-
schema.org — Person: the definition of
knowsAboutand its "suggesting possible expertise but not implying it" wording. - Google Search Central — Latest documentation updates: the 11 May 2020 entry removing the Social Profile structured data documentation deprecated since June 2019, and the note that social profiles are now discovered automatically.
-
Google Search Central — Organization structured data: the description of
sameAsamong the recommended properties, and the behind-the-scenes disambiguation sentence namingiso6523andnaics. - Google Search Central — Structured data general guidelines: that structured data enables a feature but does not guarantee it.
Top comments (0)