Repository navigation
Commit 61c0798
docs(site): objectstack.ai becomes the developer site — one-line positioning, start command, docs entry points, "Run it" strip; blog redirects to objectos.ai (#26165)
Fixes #26140
objectstack.ai is the developer site; www.objectos.ai is the product
site and the one blog (maintainer ruling 2026-10-26, 「同意」「立卡派发」 13:24Z).
This PR makes the landing read that way and sends the blog to the
product site.
## What changed
**Landing (`apps/docs/app/[lang]/page.tsx`)** — the product hero
(display headline, four-verb line, the 90-second video, the prose block,
and the idea / loop / gates / vocabulary sections in full) is replaced
by:
- the slogan as a kicker above one line of positioning: "ObjectStack is
the open protocol and SDK that ObjectOS is built on: one typed business
ontology, and the database, API, Console and MCP tools derive from it."
— the page heading, the document title, the description, the Open Graph
card and the JSON-LD headline all read the same two constants;
- the start command block: `npm create objectstack@latest my-app` · `cd
my-app` · `npx os dev --ui` — the spelling
`content/docs/getting-started` teaches;
- five docs entry points: Getting started (`/docs/getting-started`),
Concepts (`/docs/concepts`), Spec (`/docs/protocol`), CLI
(`/docs/deployment/cli`), Build with Claude Code
(`/docs/getting-started/build-with-claude-code`) — every route exists
under `content/docs`;
- the GitHub link;
- the former four sections shrunk to one four-link row into the docs
pages that already carry that content: The idea →
`/docs/concepts/ontology`; The loop →
`/docs/getting-started/build-with-claude-code`; The gates →
`/docs/getting-started/how-ai-development-works` (its "Why it's safe"
section is the guardrail story); The vocabulary → `/docs/capabilities`.
All four pages exist, so no section stays in compact form and no docs
page was created;
- the "Run it" strip: ObjectOS Community (this repository's runtime
image, self-hosted, free → `/docs/deployment/self-hosting`), ObjectOS
Cloud and ObjectOS Enterprise (→ https://www.objectos.ai). It replaces
the closing sentence "Rather build & ask online? Try ObjectOS";
- a footer line labelling the two sites by role: `objectstack.ai —
Developer docs & protocol` · `www.objectos.ai — Product, editions &
blog`. Both hosts are read from the constants that own them
(`SITE_ORIGIN`, `PRODUCT_SITE_URL`), never spelled twice.
**Navigation (`apps/docs/lib/layout.shared.tsx`)** — the header gains
`Product` (external, → https://www.objectos.ai) beside `Why` and `Blog`.
`PRODUCT_SITE_URL` is exported for the landing; the origin itself is
declared once, in `redirects.mjs` (the dependency-free module the
redirect gate imports), and re-exported here.
**Blog redirects (`apps/docs/redirects.mjs`, the second commit,
fb85c54)** — a `blogRedirects` table beside `docsRedirects`: `/blog` →
`https://www.objectos.ai/en/blog/`, and each of the four posts
(`context-window-is-the-constraint`, `metadata-driven-architecture`,
`protocol-first-development`, `the-ontology-is-the-software`) at
`/blog/SLUG` and at the prerendered `/en/blog/SLUG` →
`https://www.objectos.ai/en/blog/SLUG/`, all permanent (308). A second
table on purpose: `check:docs-redirects` resolves every `docsRedirects`
destination against `content/docs` and reports an off-site destination
as UNRESOLVABLE — right for a docs redirect, meaningless for a
cross-site one. The `.mdx` sources under `content/blog` and the
`app/[lang]/blog` route stay in the tree; removing them is the follow-up
once the redirects are measured on production.
**Removed** — `apps/docs/components/youtube-embed.tsx`: its only
consumer was the retired hero.
### Sequencing — this PR lands after www.objectos.ai#286
The redirect commit points at the posts www.objectos.ai#286 imports
under the same slugs at `/en/blog/SLUG/`. The seat lands this PR after
that import is live on the product site, so no redirect ever answers
into a 404. Until then the posts stay served here, and nothing in this
PR needs to land before #286.
Clause-②: no
Metadata-protocol: none
## How it was verified
All readings on head `fb85c546` (the final commit; nothing was pushed
after the union ran). The live sites are not reachable from this
container, so every reading is source-level or against the locally built
app.
- `pnpm --filter '@objectstack/docs^...' build` (the closure:
`@objectstack/spec`) under the verify lock — `VERDICT command-exit 0`.
- `pnpm --filter @objectstack/docs typecheck` (`fumadocs-mdx && next
typegen && tsc --noEmit`) under the lock — `VERDICT command-exit 0`.
- `pnpm --filter @objectstack/docs build` (= `pnpm docs:build`:
`gen:schema`, `gen:docs`, `gen:upgrade-guide`, `build-llms-full`, `next
build`) under the lock — `✓ Compiled successfully in 3.8min`, `✓
Generating static pages using 2 workers (1287/1287) in 68s`, `VERDICT
command-exit 0`; `git status` clean afterwards.
- The built app served with `next start` on a random port and probed
with curl (status + redirect URL):
- `/blog` → `308 https://www.objectos.ai/en/blog/`
- `/blog/the-ontology-is-the-software` → `308
https://www.objectos.ai/en/blog/the-ontology-is-the-software/`
- `/en/blog/the-ontology-is-the-software` → `308
https://www.objectos.ai/en/blog/the-ontology-is-the-software/` (no 307
hop through the locale proxy: `redirects()` runs before it)
- the other three posts and `/en/blog` → 308 to their counterparts;
`/blog/not-a-post` → 404 (unchanged);
`/docs/guides/cheatsheets/quick-reference` → 308 to
`/docs/getting-started/quick-reference` (an existing docs redirect,
unchanged)
- `.next/routes-manifest.json` carries 10 redirects whose destination
names `objectos.ai`
- `/` renders the positioning sentence (heading, title, description,
Open Graph, JSON-LD), the three start commands, the five entry points,
the four-link row, `ObjectOS Community` / `ObjectOS Cloud` / `ObjectOS
Enterprise` under "Run it", the `Product` nav entry and the two role
labels — each confirmed by `grep -c` on the served HTML; the document
title reads `The open protocol and SDK ObjectOS is built on |
ObjectStack`
- the server was stopped by its recorded PID; the port probe afterwards
answered nothing.
- `npx eslint --no-inline-config` on the three edited files — exit 0.
- Derived gate subset (`node scripts/pm/dispatch-gates.mjs --commands
--repo objectstack-ai/objectstack`, 31 commands) run with each exit code
captured before any pipe — all 31 exit 0; `--ran` reconciliation: `31
derived, 31 run, 0 NOT-MEASURED, 0 UNRUN`. Among them `pnpm
check:docs-redirects` (`98 entries … 0 outside the /docs route space`),
`pnpm check:published-readme-links`, `pnpm check:docs-locale-catch-all`,
`check-docs-nav-label`, `check-doc-frontmatter`, `pnpm check:nul-bytes`.
- CI families not re-run locally, read from this PR's check-runs: `pnpm
lint` (repo-wide eslint, inside `Lint & Repo Gates`), `TypeScript Type
Check`, `Build Core`, `Test Core`, `Check Documentation Links` (lychee
over `content/**`), and the docs production-build job in `ci.yml` (its
`apps/docs/**` path filter fires on this diff).
## Acceptance notes
- No changeset: `apps/docs` is private and nothing under a published
package's `files[]` moved — `skip-changeset` is declared on this PR.
- The header's `Why` and `Blog` entries stay site-relative
(`/blog/the-ontology-is-the-software`, `/blog`); after this PR they
resolve through the new redirects to the product site's blog.
Re-pointing or dropping them belongs to the follow-up that deletes the
blog route and sources.
- `app/sitemap.ts` still lists `/blog` and the four posts (it derives
them from the `blog` loader); once the redirects are live those entries
point at redirecting URLs. They disappear with the same follow-up (the
loader's collection goes with `content/blog`); `sitemap.ts` is outside
this card's file surface and is not touched here.
- Four in-content links to `/blog/...`
(`content/blog/metadata-driven-architecture.mdx:9`,
`content/blog/protocol-first-development.mdx:9`,
`content/blog/the-ontology-is-the-software.mdx:124`,
`content/docs/concepts/compare.mdx:124`) are relative links to
redirected pages — they keep working through the redirect; none is an
in-page embed. Docs content is out of scope here.
- `HERO_COVER.alt` (`lib/site.ts`) still reads the slogan; the cover
remains the site's Open Graph image, which the ruling keeps ("the slogan
lives on").
- `apps/docs/app/[lang]/layout.tsx` carries a `cn: '中文'` entry in
`LANGUAGE_NAMES` with no such locale declared in `lib/i18n.ts` —
pre-existing dead entry, observation only, not touched.
- The two hosted-edition descriptions (Cloud, Enterprise) are one
neutral sentence each and link to the product site root; the product
site's edition pages (www.objectos.ai#286, objectos#338) own the detail,
and #26136 owns the hosted product's name — nothing here pins a name
beyond the three edition labels the ruling gives.
- Commit trailers follow the repository's model-free pair
(`.claude/agents/os-dev.md`, enforced by the pre-push hook): both
commits were reworded before their first push; no published history was
rewritten.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01FMuBZmssbfQkVrKRtxNvng)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent d677879 commit 61c0798
4 files changed
Lines changed: 230 additions & 400 deletions
0 commit comments