seo: stop emitting a second, @id-less Organization - #11
Merged
Conversation
The homepage rendered two Organization nodes. src/app/layout.tsx defines the real one under SUEDE_ORG_ID; src/lib/seo.ts separately emitted an inline publisher with a name and a url but no @id at all. An Organization with no @id cannot join the graph, so the homepage described the company twice and let a reconciler merge neither. The publisher in seo.ts is now a reference to the canonical @id, which is what a publisher should be. The definition in layout.tsx gains foundingDate 2024 and the canonical sameAs set, including the Wikidata item Q141169484 -- present on only four of thirty-four hosts when the estate was measured on 2026-08-31. Both files verified brace- and bracket-balanced. No local toolchain in this checkout, so typecheck and tests run in CI.
JasonColapietro
added a commit
that referenced
this pull request
Sep 3, 2026
…12) * ci: fail the deploy when it cannot deploy, and prove the alias moved dna.suedeai.ai has not been serving main. Live right now, the Organization node carries no foundingDate and the page ships two JSON-LD blocks; main sets foundingDate '2024' and consolidated the graph in #11 (77b6721, 2026-08-31). The commit merged, the Actions tab went green, and nothing shipped. Two causes, both fixed here. 1. The credential check set `ready=false` when VERCEL_TOKEN was missing and every later step carried `if: steps.creds.outputs.ready == 'true'`. So the job skipped its way to success. A deploy workflow that cannot deploy is a failure, not a skip. It now checks all three secrets, writes which are missing to the step summary, emits ::error:: and exits 1. The nine dead per-step guards are gone with it. 2. "Verify production is serving" only asserted a 200. The host answered 200 throughout the entire period when main was never deployed, so that check could never have caught this. Next chunk filenames are content-hashed, so the step now pulls the chunk set from both the deployment just created and from dna.suedeai.ai and requires them to match - which is the thing we actually care about: did the production alias move to this build. If the deployment URL cannot be read it warns rather than failing, so a genuine deploy is never failed by a flaky fetch. Verified: the workflow parses as YAML, the new verify step passes `bash -n`, and the chunk-extraction logic was dry-run against the live site (7 chunks, self-comparison matches). This does not by itself put main on production - the repository still has no VERCEL_TOKEN, VERCEL_ORG_ID or VERCEL_PROJECT_ID. That needs someone with admin on Suede-AI/dna to add them under Settings -> Secrets and variables -> Actions, then run this workflow via workflow_dispatch. The difference is that until that happens the workflow will say so in red instead of green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * seo: point the LinkedIn sameAs at the URL LinkedIn redirects to https://www.linkedin.com/company/suede-labs-ai 301s to https://www.linkedin.com/company/suede-labs. LinkedIn only redirects a vanity slug within the same company page, so the destination is the current canonical URL for the page this estate already claims. It matters more than an ordinary redirect because most of these occurrences are in JSON-LD `sameAs`, the field search and answer engines use to decide which accounts belong to the same entity. An entity's identity links should resolve directly rather than through a hop. Confirmed with the owner (2026-09-03) that the destination page is theirs. Part of an estate-wide sweep: 82 occurrences across 16 repos, verified to be the only line changed in every file. Occurrences inside JasonColapietro/suede-geo's docs/seo-audits/ are deliberately left alone - those are dated records of what an earlier audit saw, and they are not published. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The homepage described the company twice, and neither could merge
src/app/layout.tsxdefines the real Organization underSUEDE_ORG_ID.src/lib/seo.tsseparately emitted an inline publisher with a name and url but no@idat all:An Organization with no
@idcannot join the graph. So the page asserted the company twice and gave a reconciler nothing to merge on — this is why an estate sweep readdna.suedeai.aias having an Organization with a missing@id.The publisher is now a reference to the canonical node, which is what a publisher should be:
And the real definition is now complete
layout.tsx's Organization gainsfoundingDate: "2024"and the canonicalsameAsset including WikidataQ141169484— present on only 4 of 34 hosts when the estate was measured on 2026-08-31.Checks
Both files verified brace- and bracket-balanced. There's no
node_modulesin this checkout, sotypecheckandtestrun in CI rather than locally — flagging that rather than implying I ran them.