Repository navigation
[Decision] What does docs.objectos.ai target — the root URL is a redirect, the index title is "ObjectOS | ObjectOS", and the brand is spelled three ways #171
Description
Ruled: 5989541136 · letter A · 2026-10-05T06:48Z
Every other card in this keyword pass (#166 #167 #168 #169 #170) is mechanical. This one is not: it asks what this domain is supposed to rank for, and the answer changes how #167 is written.
The four readings behind it
1. The strongest URL on the domain has no content. apps/docs/app/page.tsx is a bare redirect('/docs'), and app/[lang]/page.tsx does the same per locale. Meanwhile app/sitemap.ts:13 submits that redirecting root at priority: 1 — the highest priority entry in the sitemap points at a URL that serves nothing.
2. The page it redirects to titles itself with the brand twice. content/docs/index.mdx has title: ObjectOS, and app/layout.tsx:7-10 appends the template %s | ObjectOS. The landing page of the documentation site emits <title>ObjectOS | ObjectOS</title>.
3. The brand is spelled three different ways in the shipped output. ObjectOS in the title template and the nav (lib/layout.shared.tsx:21-31); ObjectStack Protocol in the Open Graph card (app/og/docs/[...slug]/route.tsx:19); ObjectStack Documentation in the i18n docblock (lib/i18n.ts:4). Brand queries are normally the highest-converting class of query a docs site gets, and the entity signal here is split across three names.
4. The index page pitches what README says is the other product. content/docs/index.mdx opens with "ObjectOS is a self-hosted runtime for building internal tools … All running in your network, on your database", then npm i -g @objectstack/cli and os start. But README.md draws the line the other way: ObjectOS is the commercial Cloud / Enterprise product, and ObjectStack is "the open-source framework … everything you need to build, run, and self-host your own applications". So the highest-authority page on docs.objectos.ai is currently competing for the self-host keyword cluster that README assigns to ObjectStack — and lib/layout.shared.tsx:11 shows there is already a separate marketing site at www.objectos.ai that may be the intended owner of those terms.
Whichever way this resolves, it resolves in one place and the rest follows.
Options
A — Docs stays documentation. Marketing owns head terms.
Leave / redirecting; drop the empty path from the sitemap so it stops advertising a redirect; give content/docs/index.mdx a real title instead of the brand; unify the brand string to ObjectOS everywhere; rewrite the index opening so it describes ObjectOS as README defines it and links to ObjectStack for the self-host story. Head terms are www.objectos.ai's job and this repo does not chase them.
Cheapest, and it keeps one product story in one place.
B — Docs also carries a real landing page at /.
Everything in A, plus replace the root redirect with an actual page targeting the head cluster, with Organization and SoftwareApplication JSON-LD to anchor the entity.
Developer docs domains often outrank their own marketing domain on product queries, so this can win. It also means two pages in two repos now compete for the same terms, and both have to be kept in sync forever.
C — Fix the signals, defer the positioning.
Do the mechanical half of A only — sitemap, brand string, index title — and leave the ObjectOS / ObjectStack keyword split alone for now.
Unblocks #167 on everything except the pages where the two products overlap, and defers the part that needs a real product answer.
四维分析
实际业务需求。 有实测支撑的只有一件事:README 与 index.mdx 对同一个产品给出两套说法,这不是 SEO 口味问题,是文档首页在替兄弟产品打广告。真实来访者读到 os start 会以为买的是自托管运行时,而 README 说那是 ObjectStack。这条轴支持 A/B 里"重写首页定位"那一半,且与排名无关也该做。至于 docs 域名要不要抢 head term——目前没有任何读数(无 Search Console 数据、无当前排名基线),谁在搜什么是假设不是事实。这条轴因此不支持 B:为一个没有测量过的流量假设去开第二个落地页,是投机性能力面。
项目长远合理性。 一个词一个所有者、一个产品一套说法,是可持续的信息架构;B 制造的是两个仓、两个页面、同一组关键词的长期同步义务,正是 contract-first 要避免的那种双写。A 把"ObjectOS 是什么"收敛到单一来源,下游(#170 的 llms.txt 摘要、#166 的 entity JSON-LD、www 站文案)都从那里取值。C 是 A 的真子集,不制造新债,但把最贵的那半留在原地。
防 AI 写代码犯错。 这条轴在这里的落点是:定位漂移是怎么进来的?是散文写在 79 个 MDX 页面里、没有任何机制说"这句话和 README 矛盾"。选 A/B 时如果只是手改一遍首页文案,半年后同样的漂移会以同样的方式回来(三个品牌串就是这么攒出来的)。真正的修法是把品牌名与一句话定位变成代码里的单一常量 + 一条门禁,让下一个写文档的人(或 agent)改不动、或者改了会红。这条轴要求:无论选哪个选项,都把品牌串收敛成一个常量,否则三种拼写还会变成第四种。
创业阶段不扩散需求。 明确指向 A 或 C,反对 B。B 是新增一个需要长期维护的落地页与一套 entity 标记,去博一个未经测量的渠道;创业阶段该做的是先把已经付了成本却在漏的东西补上(#166 的 OG 生成器已构建但无人引用、#170 的 llms.txt 已生成却被 robots 挡住),而不是开新面。A 相对 C 只多了"重写首页定位"这一件事,而那件事第一条轴已经独立支持了。
倾向 A,并把"品牌串收敛为单一常量"作为 A 的必含项。B 留到有真实排名基线之后再谈;C 只在你希望把产品定位这一半再放一放时选。
Not blocking #166 #168 #169 #170 — those four are independent of this and can land in any order. #167 is partly blocked: the pages where ObjectOS and ObjectStack overlap cannot get final titles until this resolves.
Activity
hotlong commentedon Aug 25, 2026
Repair note — one phrase in reading 2 above was eaten by the issue sanitizer (it was written with angle-bracket markup). The sentence should read:
Nothing else in the card was affected.
Generated by Claude Code
hotlong commentedon Aug 25, 2026
Evidence update — the marketing site answers most of this card
The maintainer has pointed at
objectstack-ai/www.objectos.aias the ObjectOS site proper. I had only inferred its existence fromapps/docs/lib/layout.shared.tsx:11when this card was written. Having now read it, four of the open questions above are already answered by work that shipped there, and option B is close to falsified.1. www is already running the head-term and competitor-comparison play, deliberately. 46 blog posts, and the slugs are query-shaped by policy, not by accident:
airtable-omni-vs-governed-ai-app-platform,is-lovable-safe-for-production,low-code-vs-ai-native-app-platform,beyond-agentforce-copilot-open-runtime. The titles match — "AI Contract Review: Build an App That Flags Clause and Obligation Risk First", "AI Expense Audit: Build a Finance App That Understands Policy, Not Just OCR".2. That repo carries a written keyword and GEO charter.
www.objectos.ai/AGENTS.mdstates as standing rules, among others:This reframes the whole keyword pass on the docs site. #166, #167, #169 and #170 are not a new strategy needing approval — they are the docs site being brought into line with policy this organization already wrote down and already executes next door. The docs site is currently in violation of all four of those lines.
3. The positioning half of this card already has an authoritative answer.
www.objectos.ai/src/pages/llms.txt.tsopens its output with a one-line definition of both products and how they relate — ObjectStack as the open target format and runtime for AI-written enterprise software, ObjectOS as the commercial production platform where teams build, review, deploy and operate ObjectStack applications. That string is current, shipped, and consistent withobjectos/README.md.So "rewrite the index opening so it describes ObjectOS as README defines it" is no longer an open drafting question. There is a canonical string to adopt.
content/docs/index.mdxcontradicts it; the fix is to converge on the shipped wording, not to invent new copy. (#170's dev has already been redirected to source from there rather than fromindex.mdx.)4. www handles the redirecting root correctly, and docs does the opposite.
www.objectos.ai/src/pages/index.astrois anoindexlanguage-dispatch page, andastro.config.mjsfilters it out of the sitemap. The docs site submits its equally-redirecting root atpriority: 1(apps/docs/app/sitemap.ts:13). There is an in-house precedent for the correct handling.What this does to the options
Option B is close to falsified. Its case was "developer docs domains often outrank their own marketing domain." But the marketing domain here is not a thin brochure — it is 46 keyword-targeted long-form posts, eight locales, complete Open Graph and JSON-LD, a curated
llms.txt, and a written charter. Standing up a competing landing page on docs would put two properties from one small team against each other for the same terms, and the weaker one would be the new one. The fourth axis (创业阶段不扩散需求) already argued against B; this makes it concrete rather than precautionary.Option A stands, and shrinks. Three of its four parts are now mechanical: drop the redirecting root from the sitemap (precedent next door), give
index.mdxa real title, unify the brand string. The fourth — the positioning rewrite — has a canonical source string to adopt rather than a decision to make.Option C loses its reason to exist. It was "defer the positioning question because it needs a real product answer." The product answer is already written down.
补充四维分析(仅针对新证据)
实际业务需求。 上一版我写"没有任何读数,谁在搜什么是假设不是事实"——这条现在部分推翻了:www 的 46 篇文章和成文宪章就是这个组织对"谁在搜什么"的既有答案,而且已经投产。docs 站要做的不是重新回答这个问题,是停止与那个答案相矛盾。
index.mdx用os start打自托管词群,恰好是 www 划给 ObjectStack 的那一半——两个自家站在互相稀释。项目长远合理性。 新证据强化了原判断:权威定位串已经存在于
llms.txt.ts,正确的架构是让它成为单一来源,docs 的index.mdx、#170 的 llms.txt 头、#166 的 entity JSON-LD 全部从它派生。选 B 等于新增第二个权威源。防 AI 写代码犯错。 这条轴的要求(品牌串收敛成单一常量 + 门禁)现在有了更强的落点:不只是常量,而是跨仓的单一定位源。三种品牌拼法之所以能长出来,正是因为没有任何机制说"这三个串应该是同一个"。www 那边已经把定位写成代码里的字符串了;docs 这边还散在 79 个 MDX 的散文里。
创业阶段不扩散需求。 结论不变且更硬:B 是开新面,A 是把已付成本的漏补上。www 已经证明这个团队能把一个站做到位;把第二个站做到同样水准的边际成本,远低于把 docs 站从违反宪章拉回合规。
仍需你裁的,只剩一个问题
前面四条都收敛了。真正留给你的是:docs.objectos.ai 是否应该完全不争 head term,把所有产品级查询让给 www?
推荐 是(即选项 A)。docs 站的关键词目标应该收窄为文档意图查询——"objectos 权限配置怎么做"、"objectstack kanban view"、"objectos docker 部署"这类已经知道产品名、在找具体做法的长尾。这正是 #167 的 42 个标题该瞄准的方向,而不是 head term。
如果你同意,#171 可以直接转成执行卡(三件机械事 + 采用
llms.txt.ts的定位串),不必再走决策箱。Generated by Claude Code
fix(docs): make llms.txt crawlable and give it a real header (#179)
feat(docs): give docs pages an SEO title, Open Graph, and structured …
hotlong commentedon Sep 8, 2026
Decided by the maintainer: Option A
docs.objectos.ai cedes head terms to www.objectos.ai. This site stays documentation and does not chase the head cluster.
Recorded so the next reader does not have to reconstruct it from a chat log. Removing
needs-user-decision; this card is now implementable.What A comprises
From the option as written above:
/redirecting.priority: 1.content/docs/index.mdxa real title instead of the bare brand.README.mddefines it, and links to ObjectStack for the self-host story.Mandatory, not optional: the brand string becomes one constant
The 四维分析 in this card made this a required part of A rather than a nice-to-have, and the decision carries it:
Three spellings (
ObjectOS,ObjectStack Protocol,ObjectStack Documentation) did not arrive by anyone deciding on them — they accumulated because nothing stopped them. Hand-editing the three occurrences and stopping there reproduces the defect on a six-month delay. One constant, and a gate that fails when a fourth spelling appears.The same applies to the one-line positioning: the drift got in because prose lives in 79 MDX pages with nothing asserting that a sentence contradicts
README.md.B is rejected, and the reason should survive with the decision
Not "not now" for scheduling reasons — for lack of a baseline. There is no Search Console data and no current ranking measurement, so a second landing page competing for the same terms would be built on an assumption about traffic that has never been read. Revisit only with real ranking data in hand; until then it is two repos, two pages and a permanent synchronisation obligation bought with a guess.
Consequences
#167 is unblocked. The 42 one-word English title tags can now be authored: docs targets documentation-intent and long-tail queries, not brand or category head terms. Where ObjectOS and ObjectStack overlap, the title follows
README.md's split — ObjectOS is the commercial Cloud/Enterprise product, ObjectStack is the open framework.I have deliberately not edited #167's labels — it still carries
pm:blocked, which is now false. My lane has been handed over and I am scoped to these two cards, so clearing it belongs to whoever holds the queue. Flagging it rather than leaving it silently stale.One caution for whoever implements this
This card's checklist predates 29 merged cards. It was written against the tree at
ee74379; since then #166, #168, #169, #170 and the rest have rewrittenapp/sitemap.ts,lib/seo.ts,app/layout.tsx,middleware.tsand thellmsroutes, and shipped an eighth locale. Some of the mechanical items above may already be done, partly done, or done differently.Check each against current
mainbefore acting on it. Do not take the four readings in the body as current measurements — re-measure them.Generated by Claude Code
objectstack-fleet commentedon Oct 5, 2026
Ruling: batch #1 item 1 · letter A · maintainer 「同意」 2026-10-05T06:47Z
The
repo:objectosseat (objectstack-ai/objectstack#9831, sessionsession_01FeA1nwBz1ohH65dvffUGKr) presented this card in the director batch format, at the maintainer's request, in the session chat. The maintainer answered the whole batch of five with 「同意」, which accepts the recommended letter on every card.A is confirmed: the 2026-09-08 decision (
5586186890) stands. docs.objectos.ai cedes head terms to www.objectos.ai and stays documentation. The brand string becomes one constant, with a gate that fails when a fourth spelling appears. B stays rejected for lack of a ranking baseline.Re-measured on objectos
main@7612ffe:SITE_NAME = 'ObjectOS'(apps/docs/lib/source.ts:25) feeds the OG card and the page metadata.ObjectStack Protocolno longer ships;lib/i18n.ts:4keepsObjectStack Documentationonly in a code comment.apps/docs/app/sitemap.ts:17still submits the redirecting root atpriority: 1.content/docs/index.mdxis still titled with the bare brand.README.md:5("the commercial runtime environment").Next, in this pass:
needs-user-decision→pm:queue. The four remaining items go out as one dispatch.Generated by Claude Code
objectstack-fleet commentedon Oct 5, 2026
Ruling: positioning follow-up · maintainer 「ObjectOS 仍然有自管(Enterprise)」 · 「Cloud 租户可以导出本体,拿到开源运行时上跑」 · 「其他同意」 · 2026-10-05T10:55Z
Recorded by the
repo:objectosseat (objectstack-ai/objectstack#9831), sessionsession_01FeA1nwBz1ohH65dvffUGKr.Context. objectstack adopted a new positioning on 2026-10-03 (
cc645f23,d2e687fd): "The ontology is the software. One executable business ontology. AI writes it, the runtime runs it, agents operate it, you own it." It defines ObjectOS as "the commercial runtime environment built on this stack", that is, "the same loop hosted, in the browser, nothing to install". The maintainer asked whether objectos needs adjusting. The seat presented a read-only gap analysis with five questions, and the maintainer answered them in the session chat. The answers become this card's execution parameters, settled in one stroke.deploy/*,air-gapped, the licence table).apps/docs/app/[lang]/terms/page.tsx:12says "ObjectOS is distributed under the Apache License 2.0"README.md:19-29andresources/license.mdx. The PR is shown to the maintainer before it merges.objectstack/README.mdis the single source. objectos and www.objectos.ai both quote it. One constant in this repo feeds the layout description, thellmssummary and the index, and a gate compares the copies.cc645f23). This mostly lands on www.objectos.ai.What this widens on this card. #171 already covered the index opening, the index title, the sitemap root and the brand constant. The rulings add the rows the gap analysis measured on
main@7612ffe:resources/glossary.mdx:136-139calls ObjectOS "Open source, Apache-2.0".README.md:29says "There is no open-source edition of ObjectOS".index.mdx:66says "never phones home… No license server".license.mdx:150says Self-Managed validates its licence online.app/layout.tsx:12reads "Customer-hosted runtime…".quickstart.mdx's "You're running ObjectOS" after booting the open-source CLI;why.mdx;architecture.mdx,reference/security.mdxandresources/faq.mdx, rewritten as the Cloud/Enterprise split;build/ai-skills.mdx.Execution. The work runs at the ceiling tier, on the maintainer's instruction that positioning content goes out that way, as two PRs:
Both follow #291's PR on the single push branch. #167's titles follow PR 1, because they depend on its positioning.
Generated by Claude Code
5 remaining items
objectstack-fleet commentedon Oct 5, 2026
ACCEPT: PR #293 (positioning PR 1 of #171) · 2026-10-05T12:06Z. Landing terminal: human merge or authorized approval. The PR changes 9060 lines (+1299/−7761, mostly the 41 deleted locale siblings), which is over the 5000-line human-merge line. No governed path is touched.
Checklist, read from GitHub:
main@b2975fd, first linePart of #171, no closing keyword.apps/docs/lib/positioning.tsand.github/scripts/check-positioning.mjs), 41 locale siblings deleted.f78053616fe83eed9e2e613e7ff056044e41efde:buildsuccess (every step, including the newPositioningstep and the preview smoke check),Ownership & freshnesssuccess,Node floorsuccess,Deploy docsskipped.Canonical text, checked string by string.
positioning.tsholds T1 and T2 verbatim from objectstackREADME.md:7-10. It holds T4 verbatim fromREADME.md:26-30, with "this stack" spelled "ObjectStack" asCANONICAL.mdallows. It holds E1 exactly as fixed from rulings Q1 and Q2. www.objectos.ai PR #210 renders the identical four strings.Docs prose, sentence by sentence (#21192). Each new factual sentence was checked against the repo's own authority pages on
main:license.mdx:38-41(Free tier).license.mdx:62-72,deploy/index.mdx:6.license.mdx:35,:56-58.license.mdx:150-151,deploy/air-gapped.mdx:7-18.reference/security.mdx:25(telemetry "None collected") plus the licence FAQ.5993036810).license.mdx("ObjectOS adds the embedded in-UI AI").◆ ObjectStack.extend-existing-systems.mdxadopts "read-only by default and early": objectstackREADME.md:83-84.README.md:19-29("There is no open-source edition of ObjectOS").Stale-claim sweep at the head. The English sources have 0 hits for "never phones home", "does not call home", "never calls home", "no license check" (except
license.mdx:152, which correctly describes the open ObjectStack runtime), "ObjectOS is a self-hosted runtime", "fully self-contained", "inside your firewall" and "Open source, Apache-2.0".#141's surface is untouched. The
quickstart.mdxdiff stays outside both transcribed blocks. The file still has 2 occurrences of17.5.0, plusPlugins: 31/36 loaded,Build complete (175ms)and thesys_migrationsentences.Sibling deletions under ruling
5989567068. 41 files,zh-Hans/zh-Hantpairs together. Each page's trigger in the PR body is a reversed assertion:build/ai-skillssiblings were left alone, correctly, since that change is attribution wording.gen-zh-hant --checkpasses with 65 files.Browser check. The seat viewed
/docsat 1440 and 390 from the dev's screenshots: titleIntroduction | ObjectOS, the lead is the canonical positioning, the Start table offers three rows (Cloud, Enterprise, open runtime), no overflow at 390, and the tables stack and read.Deviations accepted:
content/docssources only.app/[lang]/privacy/page.tsx:20still carries the stale sentence, and PR 2 widens the scan when it corrects that page.check-locale-surface.mjswas adapted to the root-free sitemap, with a new regression case.smoke-docs.mjsroot targets now expect H1Introduction. Without that, the post-deploy smoke check and its roll-back would fire.Next:
needs-user-decisionon the PR, the final 维护者速读, and review requested fromos-zhuangandhotlong. PR 2 (terms/privacy) and #167 wait behind it on the single push branch.Generated by Claude Code
objectstack-fleet commentedon Oct 5, 2026
Ruling: PR #293 scope · maintainer 「293 同意」 · 2026-10-05T13:30Z
Recorded by the
repo:objectosseat (objectstack-ai/objectstack#9831), sessionsession_01FeA1nwBz1ohH65dvffUGKr.Context. The maintainer asked why PR #293 changes so much: 「293 什么情况,怎么修改这么多代码」. The seat measured it:
README.mdcheck-positioning.mjsand the constantThe gate alone is 896 lines for three rules. The seat recommended A: slim the gate to about 150 lines, keep the docs changes, as against B (split the gate out) or C (approve as is). The maintainer answered 「293 同意」, read as A, in line with how 「同意」 has accepted the seat's recommendation throughout.
Execution.
os-zhuangorhotlong, or the maintainer's own merge. A chat 「同意」 is not that approval.Generated by Claude Code
ci(positioning): slim the gate to its three rules, 895 lines to 173
objectstack-fleet commentedon Oct 5, 2026
os-dev-report
{ "issue": 171, "status": "done", "branch": "claude/pm-dispatch-objectos-ju9td1", "pr": "https://github.com/objectstack-ai/objectos/pull/293", "session": "session_01FeA1nwBz1ohH65dvffUGKr", "premise_still_valid": true, "final_commit": "d56f2487b22d9c08ac43603a35cac3222195e86b", "summary": "Rewrote .github/scripts/check-positioning.mjs from 895 to 173 lines (comments and self-test included), keeping only the three rules the card mandates: (a) the copies equal the constant, (b) brand spelling in shipped output, (c) the stale sentences stay out of English content/docs sources. The self-test is six inline cases, one good and one bad fixture per rule, each bad one pinned to an exact finding count. One fast-forward commit d56f248 on top of f780536; no docs file, no positioning.ts, no other gate touched. CI on the new head is all green, and the PR now reads +576/-7761 (was +1299/-7761).", "gate_lines_before": 895, "gate_lines_after": 173, "rules_kept": [ "(a) copies equal the constant: POSITIONING is composed from apps/docs/lib/positioning.ts by regex (its export const literals, joined as its own POSITIONING = [...].join(...) line says; no TS parser, no import), then compared byte for byte with: content/docs/index.mdx frontmatter description; the site-wide meta description as the built _not-found.html carries it (that route overrides only its title, so its description is the root layout one); and the built /llms.txt summary line. A missing file is a finding.", "(b) brand spelling: every built .html under apps/docs/.next/server/app (659 today) plus llms.txt.body and llms-full.txt.body must not contain ObjectStack Protocol, ObjectStack Documentation, Object OS, objectOS or ObjectOs (case-sensitive, so the host objectos.ai and the @objectos/ scope pass). Reading the build is the allowlist that keeps the accepted lib/i18n.ts comment out of scope; no other allowlist is needed on this tree. A missing llms body is a finding, a missing build dir exits 1.", "(c) stale sentences in the 79 English content/docs sources (locale siblings excluded; code fences and MDX comments blanked with line numbers kept; wrapped sentences still match): ObjectOS is a self-hosted runtime, never phones home, does not call home, never calls home, No license server (capital N, licence spelling accepted), fully self-contained, inside your firewall; and 'Open source, Apache-2.0' inside the ### ObjectOS entry of content/docs/resources/glossary.mdx (a missing entry is a finding)." ], "self_test_cases": [ "(a) good: stub constant with a multi-line join and a double-quoted literal; index, built site meta (with an HTML-escaped apostrophe) and llms line all equal it → expects 0, got 0", "(a) bad: index paraphrased, site meta stale, llms line split across two lines → expects 3, got 3", "(b) good: ObjectOS, docs.objectos.ai, @objectos/docs → expects 0, got 0", "(b) bad: the five wrong spellings, one file each → expects 5, got 5", "(c) good: lowercase list form no license server, the question Does ObjectOS phone home?, a fenced quote, an MDX comment, and Open source, Apache-2.0 under the ObjectStack entry → expects 0, got 0", "(c) bad: the eight stale sentences, three of them wrapped across lines → expects 8, got 8" ], "tests": "All on final commit d56f248. Under the lock (OS_VERIFY_LOCK_SLOT=os-dev-171-slim): 'pnpm turbo run build --force && pnpm turbo run test --force' → VERDICT command-exit 0, held 66s, waited 0s; build 'Tasks: 1 successful, 1 total / Cached: 0 cached'; test '@objectos/ci-scripts:test: ✓ 9 self-test(s) passed', 'Cached: 0 cached'. Ablation (one-time, on scratchpad copies of the script, never the worktree; each mutation read back from disk as landed): (a) good fixture made wrong → only that case red, 1 finding vs 0, exit 1; (a) bad fixture made right → 2 vs 3, exit 1; (b) good made wrong → 1 vs 0; (b) bad made right → 4 vs 5; (c) good made wrong (comment marker removed) → 1 vs 0; (c) bad made right (firewall to network) → 7 vs 8; every one exit 1 with exactly its own case red. Gate mode on a copied real tree (constant, content/docs, the built app dir): clean exit 0; index description drift exit 1 with the (a) diff; Object OS injected into en/docs/quickstart.html exit 1 (b), plus objectOS in llms-full.txt.body exit 1 with 2 findings; never phones home appended to why.mdx exit 1 reported as why.mdx:157; the same sentence only in why.ja.mdx exit 0 (sibling not scanned); glossary ObjectOS entry rewritten to Open source, Apache-2.0 exit 1; build dir removed exit 1. The first brand injection was a no-op (its anchor, the closing main tag, is not in that page; landed=0 read back), so it was re-anchored on the closing body tag and re-run; the void run is not counted.", "gates": [ { "command": "node .github/scripts/check-positioning.mjs", "exit": 0, "verdict": "✓ positioning: 3 copies equal the constant; the brand is right in 659 pages and 2 llms bodies; no stale sentence in 79 English sources" }, { "command": "node .github/scripts/check-positioning.mjs --self-test", "exit": 0, "verdict": "✓ self-test: every rule fails its bad fixture and passes its good one" }, { "command": "node .github/scripts/check-locale-surface.mjs", "exit": 0, "verdict": "✓ every advertised URL has a source file and every source file is advertised; both `llms` bodies carry every en-only page title and none from the other locales; no page slug in the content tree contains a dot; and neither `llms` consumer carries a numeric character reference or a malformed link target" }, { "command": "pnpm run check:positioning", "exit": 0, "verdict": "same verdict line as the direct run (wiring intact)" }, { "command": "pnpm turbo run build --force && pnpm turbo run test --force (os-verify-lock)", "exit": 0, "verdict": "os-verify-lock: VERDICT command-exit 0; ✓ 9 self-test(s) passed" } ], "ci": { "head": "d56f2487b22d9c08ac43603a35cac3222195e86b", "check_runs": { "build": "success", "Ownership & freshness": "success", "Node floor": "success", "Deploy docs": "skipped (same four checks as on f780536)" }, "workflows": { "CI": "success (run 37318736232)", "Translations": "success (run 37318735948)" }, "build_job_steps": { "pnpm turbo run type-check": "success", "pnpm turbo run build": "success", "Locale surface": "success", "Positioning": "success", "pnpm turbo run test": "success" }, "logs": "NOT MEASURED: log text, reason: the built-in gh refuses the blob-host redirect for job logs; conclusions above are read from the check-runs and jobs APIs" }, "pr_totals_after": { "additions": 576, "deletions": 7761, "changed_files": 61, "before": "additions 1299, deletions 7761, changed_files 61 at f780536" }, "files_changed": [ ".github/scripts/check-positioning.mjs (rewritten, 895 to 173 lines)", "tools/ci-scripts/run-self-tests.mjs (comment only: 6 lines to 5, so it describes inline fixtures instead of temporary trees; the SELF_TESTED entry is unchanged)" ], "deviations": [ "173 lines, not about 150 (inside the 200 ceiling). What the extra lines buy: six inline fixtures (~23 lines, including a stub constant whose multi-line join exercises the composition reader); reading the composition from positioning.ts own join line instead of hard-coding the four part names (~10 lines); and HTML entity decoding of the built site meta description (5 lines; the built tag escapes the apostrophe in \"That's\"). Squeezing further meant 200-plus-character lines.", "Extra file: tools/ci-scripts/run-self-tests.mjs comment edited (not in the dispatch ban list; inside the claim surface under wiring) because it described the old fixture trees. ci.yml and package.json untouched.", "(a) reads the site-wide meta description off the built _not-found.html rather than layout.tsx source. Dropped as not among the three rules: layout/llms-route import checks, the no-import check on positioning.ts, the built index og:description check, SITE_NAME, title-suffix, og:site_name and llms-title.", "(b) list is exactly the five the ruling names; the old gate also flagged Object-OS, Objectos and OBJECTOS, which are dropped.", "(c) list is the ruling's eight. Two were not in the old gate and are added (fully self-contained, inside your firewall; zero hits in the 79 English sources today). Trimmed from the old gate: doesn't/do not/don't/won't/will not phone or call home, No license check, does not check a license server, and the ObjectOS, a/the self-hosted runtime variants. Kept sentence-initial capitals and the licence spelling. No license server stays case-sensitive so the open-runtime list form (index.mdx:111, faq.mdx:184, license.mdx:98) stays green.", "Locale siblings are excluded by a BCP-47 suffix pattern instead of parsing lib/i18n.ts; it selects the same 79 English sources the old gate scanned.", "gate_lines_before is 895 by wc -l (the file ends with a newline; a viewer that shows 896 counts the empty line after it). The dispatch said 896.", "Commit message: the subject describes the change and 'Part of #171' is its own body line (not a git trailer). Trailers are model-free (Co-Authored-By: Claude, Claude-Session URL), as on fece8b1 and f780536; the harness reminder's model-named Co-Authored-By yields to the agent contract.", "Waited for CI in the foreground as the dispatch asked (a node loop polling every 30s, no background watcher); about 2.5 minutes.", "Note for PR 2 of #171: the earlier report's carrier note said to widen STALE_SOURCE_DIRS. That constant no longer exists; the scan root is the list('content/docs') call in gate()." ], "open_questions": [], "out_of_scope_findings": [], "api_writes": "1 relay write: post-stamped --comment=171 on objectstack-ai/objectos (this report). 1 git push: f780536..d56f248 fast-forward to claude/pm-dispatch-objectos-ju9td1, no force. 0 PR writes, 0 PR body edits, 0 labels. Reads only via gh api: issue 171 and its comments, comment 5993095775, pull 293, check-runs, workflow runs and jobs on d56f248 and f780536.", "mcp_calls": "0 — no MCP tool was called" }Generated by Claude Code
objectstack-fleet commentedon Oct 5, 2026
Re-ACCEPT: PR #293 on head
d56f2487b22d9c08ac43603a35cac3222195e86b(gate slimmed per ruling5995485057) · 2026-10-05T13:47Z. The landing terminal is unchanged: a GitHub Approve fromos-zhuangorhotlong, or the maintainer's own merge.What changed since ACCEPT
5994103855: one fast-forward commit,d56f248, on top off780536..github/scripts/check-positioning.mjsis rewritten from 895 lines to 173.tools/ci-scripts/run-self-tests.mjshas a one-line comment edit.positioning.ts, and no other gate was touched. The sentence-by-sentence docs check in5994103855therefore still covers every prose line on this head.Gate code, read by the seat line by line. It has exactly the three mandated rules:
POSITIONINGfrompositioning.ts's own literals and join line, by regex. It byte-compares that with theindex.mdxdescription, the built site-wide meta description (HTML entities decoded) and the builtllms.txtsummary line. A missing file is a finding.llmsbodies for the five wrong brand spellings. The match is case-sensitive, soobjectos.aiand@objectos/pass.### ObjectOSentry. The lowercase open-runtime list form "no license server" stays green by design.Checks on
d56f248:buildsuccess (type-check, build, Locale surface, Positioning, test),Ownership & freshnesssuccess,Node floorsuccess,Deploy docsskipped. PR totals are now +576/−7761 (they were +1299/−7761). 7584 of the deletions are the 41 locale siblings.Deviations accepted:
Generated by Claude Code
docs: one positioning constant, one gate, ObjectOS as Cloud or Enterp…
objectstack-fleet commentedon Oct 6, 2026
PR 1 landed · 2026-10-06T00:06Z
os-zhuangat 2026-10-05T23:51Z on headd56f248and merged by the maintainer one second later. It is squashb754364onmain.mainis run 37390886469:build,Node floor,Deploy docs / Publish the tested WorkerandDeploy docs / Smoke-check the live sitesucceeded;✓ deploy: 25ff1fee-a1e4-490c-bf10-4af2cd6392e0 is serving, replacing ecb4d4a6-148c-42e7-b229-29e1e56f2ace.✓ smoke: 4 page(s) rendered against https://docs.objectos.ai, negative control demonstrated red.needs-user-decisionis removed from the PR, because the approval has been given.What remains on this card:
PR 1(done).The card stays
pm:dispatchedfor PR 2.Generated by Claude Code
objectstack-fleet commentedon Oct 6, 2026
Claim: PM loop,
repo:objectosseat, R3 (PR 2 of #171)Session:
session_01FeA1nwBz1ohH65dvffUGKrAccount:
hotlong(the seat's linked user, asGET /useranswers it; always the card's assignee)Branch:
claude/pm-dispatch-objectos-ju9td1, the session's one designated push branch. Its remote headd56f2487b22d9c08ac43603a35cac3222195e86bis PR #293, already squash-merged asb754364, so the branch is restarted fromorigin/main.Worktree:
objectos-issue-171-pr2Domain: n/a (single-lane repo)
Seat:
repo:objectos(objectstack-ai/objectstack#9831)File surface:
apps/docs/app/[lang]/terms/page.tsxandapps/docs/app/[lang]/privacy/page.tsx, theenentries and theirzh-Hanssiblings..github/scripts/check-positioning.mjs, only to widen rule (c) to those two pages' English text, plus its self-test cases.Stop on breach and explain in the report.
Container & model: M,
mode:subagent,model: CONTRACT_REVIEW_TIER, reason: the maintainer's instruction in the session chat on 2026-10-05 that positioning content is dispatched at the ceiling tier.Clause-②: no
Thread-read: 6006089310
Ruling followed:
5993036810, Q3. The seat corrects the licence facts, and the PR is shown to the maintainer before it merges.Landing terminal: shown to the maintainer before merge (ruling Q3). The seat ACCEPTs, then posts a maintainer brief and requests review from
os-zhuangandhotlong. The PR stays a draft until the maintainer approves or merges it.Serial constraints cleared: PR 1 (docs: one positioning constant, one gate, ObjectOS as Cloud or Enterprise (PR 1 of #171) #293) has landed. The only open PRs are dependabot bumps, which touch neither surface. Author SEO titles for the 42 English pages whose title tag is a single word #167 waits for this PR.
Generated by Claude Code
docs(legal): correct the terms and privacy pages to ObjectOS's editio…
objectstack-fleet commentedon Oct 6, 2026
os-dev-report
{ "issue": 171, "status": "done", "branch": "claude/pm-dispatch-objectos-ju9td1", "pr": "https://github.com/objectstack-ai/objectos/pull/294", "session": "session_01FeA1nwBz1ohH65dvffUGKr", "premise_still_valid": true, "final_commit": "d5cbe48b4c25c7642d687f5602d608312ec40c0d", "summary": "PR 2 of #171 (ruling 5993036810, Q3), draft #294 on the designated branch restarted from main b754364, held for the maintainer. Premise re-measured on main @ b754364 before editing: all five contradicted statements were still there and nowhere else (terms:12 'distributed under the Apache License 2.0', terms:16 warranty on Apache-2.0, terms:20 'optional control plane or future SaaS offering', privacy:12 'customer-hosted runtime', privacy:20 'does not phone home'); the facts in README.md:19,28-29,86-87, license.mdx:8-11,94-95,129-130,150-152 and positioning.ts OBJECTOS_EDITIONS read as the dispatch quoted them. Both pages' en entries and their zh-Hans siblings now say: ObjectOS is a commercial product with no open-source edition, used under the licence or service agreement of the edition (Cloud or Enterprise); only this repository's contents and the open-source ObjectStack framework/runtime are Apache-2.0; self-managed warranty follows the commercial agreement, self-hosting the open runtime follows Apache-2.0; the hosted-services example is ObjectOS Cloud; the privacy overview states both editions, scopes 'we do not collect' to self-managed ObjectOS and the open runtime, quotes license.mdx:150-152 verbatim on licence validation, and says only that Cloud's data handling is governed by its sign-up agreement. Trademark sentence, covered-property list and contact addresses unchanged; Last updated moved to October 6, 2026 (en + zh-Hans). check-positioning.mjs rule (c) also reads the en entry of the two pages (rest blanked so path:line holds; a page with no entry is a finding) and gains the three removed sentences; two self-test cases pinned at 0 and 4; 173 to 189 lines; wiring untouched.", "files": [ "apps/docs/app/[lang]/terms/page.tsx (en + zh-Hans: updated, License, Self-hosted deployments, Hosted services)", "apps/docs/app/[lang]/privacy/page.tsx (en + zh-Hans: updated, Overview, What we do not collect)", ".github/scripts/check-positioning.mjs (rule (c) widened: LEGAL, englishEntry(), three STALE patterns, undefined-text guard, verdict line, LEGAL_OK/LEGAL_BAD fixtures, two cases; +19/-3, 173 to 189 lines)" ], "tests": "All on the tree committed as d5cbe48 (build and renders taken on the working tree before the commit; the commit added no bytes, git status clean after). Under scripts/pm/os-verify-lock.sh (OS_VERIFY_LOCK_SLOT=os-dev-171-pr2, NODE_OPTIONS=--max-old-space-size=4096): 'pnpm turbo run type-check --continue --force --filter=@objectos/docs && pnpm turbo run build --force' gave 'VERDICT command-exit 0 · held the lock 77s · waited 0s'; type-check printed '✓ Types generated successfully' and 'Tasks: 1 successful, 1 total', zero 'error TS' lines; build 'Tasks: 1 successful, 1 total, Cached: 0 cached' (OG font-fetch TLS warnings are the container proxy, same as PR 1). 'pnpm turbo run test --force' under the lock: 'VERDICT command-exit 0 · held the lock 3s', '✓ 9 self-test(s) passed' including check-positioning '✓ self-test: every rule fails its bad fixture and passes its good one' (8 cases). Gates in gate mode after the build: check-positioning.mjs direct and via pnpm run check:positioning both '✓ positioning: 3 copies equal the constant; the brand is right in 659 pages and 2 llms bodies; no stale sentence in 79 English sources and the en entry of 2 legal pages'; check-locale-surface.mjs '✓ every advertised URL has a source file and every source file is advertised; …'; gen-zh-hant.mjs --check '✓ zh-Hant: 65 generated file(s) match the zh-Hans sources byte for byte.'; check-translations.mjs '✓ translations gate passed'; ownership with the workflow argv (git diff --name-status --no-renames origin/main...HEAD, --actor objectstack-fleet[bot]): unset exit 0 'touches 0 translation artifact(s) and 3 other file(s)', set exit 0 '✓ 3 file(s) changed, no translation artifacts touched.'; C0/DEL byte scan on the three files: none. Browser: next start from this build (pid-tracked, port 3172, freed afterwards), Playwright Chromium at /opt/pw-browsers/chromium, /terms /privacy /zh-Hans/terms /zh-Hans/privacy at 1440x900 and 390x844: all eight 200, expected h1 and Last updated line, corrected paragraphs served, scrollWidth equal to the viewport on every one; all eight screenshots viewed, no layout regression. Ablation (one-time, nothing left in the tree): self-test flips on scratch copies, each read back from disk (anchor 1 to 0, injected 1): good legal fixture given 'ObjectOS is a customer-hosted runtime.' turned only its case red (1 vs 0, exit 1); bad fixture's 'does not phone home' changed to 'does not ring home' turned only its case red (3 vs 4, exit 1). Gate mode on the committed worktree with both pages swapped to their origin/main bytes (blob hashes differed from HEAD; the three removed sentences counted once each on disk): the ORIGINAL gate (origin/main's script copied beside the new one) stayed green, exit 0; the WIDENED gate exit 1 with exactly three (c) findings at terms/page.tsx:12, privacy/page.tsx:20, privacy/page.tsx:12. Restore via git checkout HEAD -- path under a trap: git diff HEAD empty, git status clean, both blob hashes equal to HEAD's, gate green again on the restored tree.", "gates": [ { "command": "pnpm turbo run type-check --continue --force --filter=@objectos/docs (os-verify-lock)", "exit": 0, "verdict": "✓ Types generated successfully · Tasks: 1 successful, 1 total · 0 error TS" }, { "command": "pnpm turbo run build --force (os-verify-lock)", "exit": 0, "verdict": "os-verify-lock: VERDICT command-exit 0 · held the lock 77s · Tasks: 1 successful, 1 total" }, { "command": "pnpm turbo run test --force (os-verify-lock)", "exit": 0, "verdict": "os-verify-lock: VERDICT command-exit 0 · ✓ 9 self-test(s) passed" }, { "command": "node .github/scripts/check-positioning.mjs --self-test", "exit": 0, "verdict": "✓ self-test: every rule fails its bad fixture and passes its good one (8 cases; new ones 0 and 4)" }, { "command": "node .github/scripts/check-positioning.mjs", "exit": 0, "verdict": "✓ positioning: 3 copies equal the constant; the brand is right in 659 pages and 2 llms bodies; no stale sentence in 79 English sources and the en entry of 2 legal pages" }, { "command": "pnpm run check:positioning", "exit": 0, "verdict": "same verdict line as the direct run (wiring intact)" }, { "command": "node .github/scripts/check-locale-surface.mjs", "exit": 0, "verdict": "✓ every advertised URL has a source file and every source file is advertised; both llms bodies carry every en-only page title and none from the other locales; no page slug in the content tree contains a dot; and neither llms consumer carries a numeric character reference or a malformed link target" }, { "command": "node apps/docs/scripts/gen-zh-hant.mjs --check", "exit": 0, "verdict": "✓ zh-Hant: 65 generated file(s) match the zh-Hans sources byte for byte." }, { "command": "node .github/scripts/check-translations.mjs", "exit": 0, "verdict": "✓ translations gate passed" }, { "command": "node .github/scripts/check-translation-ownership.mjs --actor objectstack-fleet[bot] --files changed.txt (unset / set)", "exit": 0, "verdict": "unset: touches 0 translation artifact(s) and 3 other file(s) · set: ✓ 3 file(s) changed, no translation artifacts touched." }, { "command": "grep -naP C0/DEL on the three files", "exit": 1, "verdict": "no control bytes (grep exit 1 = no match)" }, { "command": "render.cjs (next start + Playwright Chromium, 4 pages x 2 viewports)", "exit": 0, "verdict": "✓ render: 4 pages × 2 viewports served 200 with no horizontal overflow" }, { "command": "ablation.sh (fixture flips, old-vs-widened gate on origin/main pages, hash-proven restore)", "exit": 0, "verdict": "✓ ablation: both fixture flips turned only their own case red; the widened gate catches the removed text (3 findings) where the original gate stayed green; restore proven by blob hash" } ], "ci": { "head": "d5cbe48b4c25c7642d687f5602d608312ec40c0d", "check_runs_at_report_time": { "Ownership & freshness": "success", "Node floor": "success", "build": "in_progress" }, "workflows": { "Translations": "success (run 37394300974)", "CI": "in_progress (run 37394300004)" }, "note": "not waited on, per the agent contract; the in_progress build job is the honest reading at report time" }, "screenshots": [ "/tmp/claude-0/-home-user/2224823d-3484-535e-94a5-c071ba6af395/scratchpad/issue-171/shots/terms-1440x900.png", "/tmp/claude-0/-home-user/2224823d-3484-535e-94a5-c071ba6af395/scratchpad/issue-171/shots/privacy-1440x900.png", "/tmp/claude-0/-home-user/2224823d-3484-535e-94a5-c071ba6af395/scratchpad/issue-171/shots/zh-Hans-terms-1440x900.png", "/tmp/claude-0/-home-user/2224823d-3484-535e-94a5-c071ba6af395/scratchpad/issue-171/shots/zh-Hans-privacy-1440x900.png", "/tmp/claude-0/-home-user/2224823d-3484-535e-94a5-c071ba6af395/scratchpad/issue-171/shots/terms-390x844.png", "/tmp/claude-0/-home-user/2224823d-3484-535e-94a5-c071ba6af395/scratchpad/issue-171/shots/privacy-390x844.png", "/tmp/claude-0/-home-user/2224823d-3484-535e-94a5-c071ba6af395/scratchpad/issue-171/shots/zh-Hans-terms-390x844.png", "/tmp/claude-0/-home-user/2224823d-3484-535e-94a5-c071ba6af395/scratchpad/issue-171/shots/zh-Hans-privacy-390x844.png" ], "deviations": [ "Commit trailers are model-free (Co-Authored-By: Claude, Claude-Session URL), as on every PR 1 commit: the agent contract requires model-free trailer pairs and the dispatch itself bans model identifiers elsewhere, so its model-named Co-Authored-By line yields to the contract.", "PR footer is the agent contract's session-URL form (a rule line, then _Generated by [Claude Code](https://claude.ai/code/session_…)_), the same form PR 1's body used, instead of the dispatch's 'Generated with' two-liner; the contract names itself the precedence rule and asks that the conflict be reported here.", "Local branch name: the shared checkout /home/user/objectos has claude/pm-dispatch-objectos-ju9td1 checked out (at the stale 2e6f0e6), so the worktree could not check out the same name without force-moving a ref another checkout holds; the worktree used claude/pm-dispatch-objectos-ju9td1-pr2-local and every push named refs/heads/claude/pm-dispatch-objectos-ju9td1 by refspec (first the --force-with-lease reset d56f248 to b754364 exactly as instructed, then the fast-forward b754364..d5cbe48). Remote branch unchanged, no other branch pushed, the local helper branch deleted at cleanup, the shared checkout untouched.", "PR assignee: label-write --assign hotlong on #294 (one relay write, read back MATCHES) was not named by the dispatch; done per the agent contract (PR assignee = the card's), as on PR 1.", "Gate list hand-derived from objectos package.json, ci.yml and translations.yml: dispatch-gates.mjs --commands derives objectstack's families and refuses a sister-repo diff.", "The build and renders were taken on the working tree immediately before the commit; the commit added no bytes (git status clean before and after), so they measure d5cbe48.", "CI build job on d5cbe48 was in_progress at report time and was not waited on.", "No HTML comment anywhere; the PR body was read back from GitHub to its footer and is intact." ], "open_questions": [ { "question": "ObjectOS Cloud's data handling: the repository states nothing about what Cloud collects, stores or processes. The privacy page now says only that it is governed by the service agreement presented at sign-up.", "options": ["A keep that sentence as the whole statement", "B the maintainer supplies the Cloud data-handling facts and a follow-up PR states them"], "recommendation": "A for this PR, because every added word would be invented; B only if the maintainer has the facts." }, { "question": "Covered web properties: the privacy page names objectstack.ai and docs.objectstack.ai, while apps/docs/wrangler.jsonc routes this site at docs.objectos.ai and www.objectos.app. Left unchanged by instruction.", "options": ["A leave as is", "B add or replace with docs.objectos.ai / www.objectos.app in a follow-up"], "recommendation": "Maintainer's call; the seat should not guess which legal entity's property list applies." } ], "out_of_scope_findings": [ "carrier: none · noted, not filed: the ci.yml comment above the Positioning step still says rule (c) reads the sources under content/docs/; it now also reads the two legal pages. ci.yml is outside this PR's file surface; one-line comment fix for whoever next touches it.", "observation, not filed (zero reach on the legal text): both legal pages ship the page title as the bare brand 'ObjectOS' (root template, no page title), the shape ruling A fixed for the index.", "observation, not filed: license.mdx also sells Business Self-Managed (single node) as a self-managed delivery; the pages follow ruling Q1's two-edition naming and hang the licence on 'the edition you use', which covers it; PR 1 took the same line." ], "api_writes": "0 direct REST writes. 3 relay writes as objectstack-fleet[bot] via scripts/pm from the objectstack checkout: pr_create objectstack-ai/objectos#294 (fleet-write run 37394259971, 17155-byte body, draft forced by the relay, read back intact to the footer); label-write --assign hotlong on #294 (run 37394358759, read back MATCHES); post-stamped --comment=171 for this report (run id in the comment's own log). Git: 2 pushes to claude/pm-dispatch-objectos-ju9td1 (the --force-with-lease reset d56f248 to b754364 as instructed; then fast-forward b754364..d5cbe48). Reads only via gh api: issue 171 and its comments, pull 293 body, pull 294, check-runs and workflow runs on d5cbe48. No PR body edit, no label, no ready flip, no reviewer request.", "mcp_calls": "0 — no MCP tool was called" }Generated by Claude Code
objectstack-fleet commentedon Oct 6, 2026
ACCEPT: PR #294 (PR 2 of #171, the terms and privacy pages) · 2026-10-06T00:37Z, on head
d5cbe48b4c25c7642d687f5602d608312ec40c0d.Landing terminal (ruling Q3): the maintainer sees it before it merges. The PR stays a draft and is labelled
needs-user-decision. Review is requested fromos-zhuangandhotlong. It lands on their GitHub Approve or their own merge.Path surface, read from
get_files: three files, +33/−17.apps/docs/app/[lang]/terms/page.tsx(+8/−8)apps/docs/app/[lang]/privacy/page.tsx(+6/−6).github/scripts/check-positioning.mjs(+19/−3)No governed path is touched, and the PR is inside the claimed surface.
Checks on
d5cbe48:build,Ownership & freshnessandNode floorsucceeded;Deploy docswas skipped;mergeable_stateis clean.Terms page, checked sentence by sentence against the repo:
README.md:28-29andlicense.mdx:11,:129-130.OBJECTOS_EDITIONS.README.md:86-89.license.mdx:93-104.The old Apache basis for ObjectOS is gone.
Privacy page, checked sentence by sentence:
license.mdx:150-152verbatim: online validation, air-gapped Enterprise validated offline, and the open runtime with no telemetry, no license check and no update ping.objectstack.ai, docs.objectstack.ai), the contact addresses, and "What we collect".zh-Hans: each changed entry makes the same claims as its English sentence. The licence sentence is
license.zh-Hans.mdx:130-132verbatim, including 隔离网络 and 更新探活. Both "Last updated" lines move to 2026-10-06 in both languages.Gate code, read line by line:
en:entry. The rest of the file is blanked sopath:lineholds, and a page without anen:entry is a finding rather than a silent pass.Seat note for the maintainer, not a blocker:
README.md:38andlicense.mdxalso sell Business Self-Managed (single node) under "ObjectOS Self-Managed".Open questions carried to the maintainer:
objectstack.ai, docs.objectstack.ai, whileapps/docs/wrangler.jsoncserves this site atdocs.objectos.aiandwww.objectos.app.Deviations accepted:
hotlongis assigned to the PR, as on PR 1.Out-of-scope notes:
ci.ymlcomment above the Positioning step still says rule (c) readscontent/docs/only. It is a one-line fix for the next touch, so it is not filed.ObjectOSas their<title>. This is carried to Author SEO titles for the 42 English pages whose title tag is a single word #167, which owns page titles.Generated by Claude Code
docs(legal): correct the terms and privacy pages to ObjectOS's editio…
objectstack-fleet commentedon Oct 6, 2026
PR 2 landed: card complete · 2026-10-06T08:57Z
os-zhuangon headd5cbe48. The seat squash-merged it at 2026-10-06T08:50Zas6b0e9a5.Fixes [Decision] What does docs.objectos.ai target — the root URL is a redirect, the index title is "ObjectOS | ObjectOS", and the brand is spelled three ways #171` closed this card.main, run 37438750800:build,Node floor,Deploy docs / Publish the tested WorkerandDeploy docs / Smoke-check the live sitesucceeded; roll back was skipped. Deploy verdict, quoted:✓ deploy: 40cdffef-bd81-44a3-8742-baee807b321e is serving, replacing 25ff1fee-a1e4-490c-bf10-4af2cd6392e0.license.mdxdoes. Cloud data handling is governed by the sign-up agreement.pm:dispatchedhere andneeds-user-decisionfrom PR docs(legal): correct the terms and privacy pages to ObjectOS's editions and licence facts (PR 2 of #171) #294.6010721523.Generated by Claude Code