diff --git a/content/pages/en/compare.ts b/content/pages/en/compare.ts new file mode 100644 index 0000000..d3c6e4f --- /dev/null +++ b/content/pages/en/compare.ts @@ -0,0 +1,245 @@ +import type { MarketingPage } from '../../../src/content-pages/types'; +import { positioning } from '../../../src/lib/positioning'; + +const p = positioning.en; + +// The comparison and the "when not to use it" page. Every factual sentence is +// taken from objectstack `origin/main`: `content/docs/concepts/compare.mdx` +// (the five categories, the side-by-side table, where the others are stronger) +// and `content/docs/concepts/when-to-use.mdx` (a good fit, not a fit today, the +// five questions). The positioning is quoted from `src/lib/positioning.ts`. +// The mapping of this site's own comparison posts onto the five categories is +// this page's, not objectstack's. +const page = { + slug: 'compare', + navLabel: 'How it compares', + title: 'How ObjectStack Compares, and When Not to Use It', + description: + 'ObjectStack beside knowledge ontologies, semantic and context layers, operational ontologies, metadata-driven platforms and AI code generation: what each is good at, the one difference that matters, where the others are stronger, and the workloads that are not a fit today.', + eyebrow: 'How it compares', + heroTitle: 'Five things it is weighed against. It is none of them.', + lead: + `The word ontology covers several different kinds of thing in 2026, and the products that use it solve different problems. This page sets ObjectStack beside the five a reader is most likely to weigh it against — three that use the word and two that answer the same question without it — then says where each of them is stronger and where ObjectStack is not a fit today. What it is instead: ${p.t2}`, + primary: { label: 'Point your agent at ObjectStack', href: '/en/agent-developer/' }, + secondary: { label: 'What the ontology is', href: '/en/ontology/' }, + metrics: [ + { value: '5 kinds', label: 'of thing it is weighed against — three that use the word ontology, and two that answer the same question without it' }, + { value: '4 places', label: 'where another category is stronger, stated on this page: existing data estates, reasoning, algorithm-heavy work, ecosystem maturity' }, + { value: '5 workloads', label: 'that are not a fit today, from the core ERP of a large enterprise to anything that must run on a certified platform' }, + ], + artifact: { + eyebrow: 'A good fit', + title: 'Where it fits today', + body: + 'ObjectStack is for business applications whose definition you want to own, that AI writes and agents operate. Five shapes of work fit that today. The section on what is not a fit follows the comparison, and the five questions to answer before you start are at the end.', + steps: [ + 'New business applications — CRM, ticketing, approvals, operations and internal tools. Objects, relations, actions, permissions and flows are most of what these apps are, and they are exactly what the ontology declares.', + 'Teams small enough that one person, or a few, can define the business. An agent writes the definition; someone still has to know what it should say. The fewer people who must agree on it, the faster the loop runs.', + 'ISVs shipping many vertical apps. Each vertical is a definition on the same runtime; what differs between them is the definition, not the stack underneath it.', + 'The long tail of departmental apps around a core ERP — vendor onboarding, inspections, internal requests. Each one becomes a typed definition in a repository instead of a file that gets emailed around.', + 'Back offices meant to be operated by agents from day one. Every deployment is an MCP server, on by default: objects are tools, the actions an author exposes are tools, and permissions decide what an agent may call.', + ], + }, + sections: [ + { + id: 'categories', + eyebrow: 'Five categories', + title: 'What each is, what it is good at, the one difference', + copy: + 'Each entry reads a category as a whole; individual products vary. The one difference named for each is the one that decides whether it answers your question.', + items: [ + { + title: 'Knowledge ontologies', + body: 'RDF and OWL, the W3C standards for describing a domain as statements, classes, properties and axioms, and the tools built on them, such as the Protégé editor; a reasoner infers facts nobody stored and checks that the whole description is consistent. Good at shared vocabularies across organisations, integrating data that was never designed to fit together, and answering questions by inference. The difference: a knowledge ontology describes a domain; nothing runs it as an application. ObjectStack’s ontology has no axioms and no reasoner — it is validated, then run.', + meta: 'Uses the word', + }, + { + title: 'Semantic and context layers over existing data', + body: 'A layer that makes data living elsewhere legible to agents and analysts: business names, metrics, relationships and context over warehouses, lakehouses and operational databases. As of late 2026 the category includes the ontology item in Microsoft Fabric IQ (in preview), Databricks Genie with Unity Catalog metric views, Snowflake semantic views, AWS Context and Google Cloud Knowledge Catalog; in open source, metric semantic layers and agent memory graphs. Good at consistent meaning over a large existing estate without moving the data; read-mostly, some add rules and actions on top. The difference: the system of record stays where it was. ObjectStack’s ontology is the system — the database, API, UI and agent tools are derived from it.', + meta: 'Uses the word', + }, + { + title: 'Operational ontologies over existing systems', + body: 'Objects, links, actions and permissions defined over data integrated from other systems, with edits written back. The Palantir Ontology is the reference: an action type packages edits to objects and links with its validation and side effects, and writeback keeps those edits in sync with the underlying data. Good at one governed model of objects and actions across many large systems that stay where they are. The difference: it is still a layer over systems that live elsewhere and, in Palantir’s case, a proprietary platform. ObjectStack derives the database schema, API, UI and MCP tools from the definition, and it is Apache-2.0.', + meta: 'Uses the word', + }, + { + title: 'Metadata-driven application platforms', + body: 'Platforms where metadata generates tables, APIs and UI — the closest relatives. Salesforce’s metadata is the ancestor; open-source cousins include Frappe Framework with ERPNext, Odoo, NocoBase, Payload and Twenty, and several now offer MCP servers. Good at building business applications quickly on a proven runtime, with packaged apps, modules and integrations to start from. The difference: where the definition lives, and who it is written for. In most of these platforms metadata is configuration stored in the platform’s database and edited through its UI; where it is code, it is framework code. ObjectStack’s definition is typed, declarative TypeScript in your repository — versioned and reviewed as a diff, checked by os validate before it runs, and shaped for an AI to write.', + meta: 'Same question', + }, + { + title: 'AI code generation', + body: 'An agent writes a conventional codebase from a prompt: a schema, handlers, components, the glue between them. What it is good at: it has no runtime ceiling — anything code can do, it can produce. The difference: the output is still code. It grows, its layers drift apart, and past a certain size no agent can hold it whole. Tests and type-checkers check the code against itself; nothing checks it against a definition of the business, because there is none. ObjectStack keeps the definition and moves the code into the runtime, and its gate rejects a wrong definition when it is written, not when it fails in production.', + meta: 'Same question', + }, + ], + }, + { + id: 'stronger', + eyebrow: 'Where the others are stronger', + title: 'Four cases to choose something else', + copy: + 'A comparison that only lists wins is an advertisement. These are the four cases where another category starts ahead, in objectstack’s own words.', + items: [ + { + title: 'Existing data and legacy systems', + body: 'Semantic and context layers, operational ontologies. When the data already lives in a warehouse, a lakehouse and a dozen operational systems, these start where you are. ObjectStack’s federation is early and read-only by default; it is not a way to put one model over an existing estate.', + }, + { + title: 'Reasoning over heterogeneous data', + body: 'Knowledge ontologies. Inferring facts nobody stored, classifying by axioms, checking consistency, aligning vocabularies across organisations: a reasoner does this, and ObjectStack has none.', + }, + { + title: 'Algorithm-heavy work and unusual interfaces', + body: 'Code. An optimiser, a simulation, a canvas editor, a game: write code. ObjectStack can wrap an algorithm as an action, but its interface is server-driven from metadata, and an interface unlike any business app is easier to build directly.', + }, + { + title: 'Ecosystem maturity and integrations', + body: 'The metadata platforms. Salesforce, Odoo and ERPNext bring years of production use, packaged applications, app marketplaces and implementation partners. ObjectStack is younger; expect to build more of it yourself.', + }, + ], + }, + { + id: 'not-a-fit', + eyebrow: 'When not to use it', + title: 'Not a fit today', + copy: + 'ObjectStack is open-source software you deploy and operate for business applications whose definition you want to own. These five workloads are outside that today, and the honest answer is to build around them or choose something else.', + items: [ + { + title: 'Replacing the core ERP or finance system of a large enterprise', + body: 'A general ledger, consolidation, tax and payroll carry regulation and edge cases that packaged systems already encode. Build around that core, not instead of it.', + }, + { + title: 'Workloads whose value is integrating many existing systems', + body: 'ObjectStack can federate an external database as a datasource, but federation is early and read-only by default; writes need an explicit opt-in on both the datasource and the object. When the job is mostly making existing systems legible to agents, a layer over those systems fits better.', + }, + { + title: 'Analytics over data lakes', + body: 'The analytics layer defines metrics over the app’s own objects for its reports and dashboards. It is not built to query a lake.', + }, + { + title: 'Algorithm-heavy domains, such as pricing or scheduling', + body: 'Unless the algorithm is wrapped as an action. The ontology declares what can be done; it does not express an optimiser. Write the algorithm as code behind an action, and permissions, audit and agent access apply to it like any other action.', + }, + { + title: 'Workloads that require a certified platform', + body: 'ObjectStack carries no compliance certification of its own. Where a workload must run on a certified platform, certifying your deployment is work you own.', + }, + ], + }, + { + id: 'in-depth', + eyebrow: 'In depth', + title: 'The comparisons, one product at a time', + copy: + 'Category by category above; product by product here. Each post states the other side’s strengths first, then the one thing to compare. The label is the category the product falls under on this page.', + items: [ + { + title: 'Ontology vs semantic layer vs knowledge graph', + body: 'A semantic layer defines what a number means; a knowledge graph stores what connects to what; only an ontology carries actions and permissions. With a decision table.', + meta: 'Knowledge ontologies', + href: '/en/blog/ontology-vs-semantic-layer-vs-knowledge-graph/', + }, + { + title: 'Fabric IQ vs Palantir vs Unity Catalog vs Snowflake vs Looker', + body: 'Five vendors shipped an enterprise ontology or semantic layer between November 2025 and August 2026, compared cell by cell on objects, relationships, actions, permissions and agent interfaces.', + meta: 'Semantic layers · operational ontologies', + href: '/en/blog/enterprise-ontology-platform-comparison/', + }, + { + title: 'Open vs closed enterprise ontologies', + body: 'The protocol is open and the definition stays inside the platform: who owns the business semantic layer after the five launches.', + meta: 'Semantic layers', + href: '/en/blog/enterprise-ontology-race-open-vs-closed/', + }, + { + title: 'Airtable Omni vs governed AI app platforms', + body: 'Natural language over a table workspace is strong. The question for a system of record is whether an AI change to permissions, fields and flows becomes a reviewable diff before it ships.', + meta: 'Metadata-driven platforms', + href: '/en/blog/airtable-omni-vs-governed-ai-app-platform/', + }, + { + title: 'Retool vs governed AI app platforms', + body: 'Retool’s RBAC, audit log, SSO and self-hosting are strong. The layer to compare is business authority: refunds, approvals and writes scattered across JavaScript bindings cannot be reviewed as a diff.', + meta: 'Metadata-driven platforms', + href: '/en/blog/retool-vs-ai-native-app-platform/', + }, + { + title: 'Power Platform lock-in: Dataverse, Azure and the self-host tradeoff', + body: 'Identity, Teams, Dynamics and billing in one tenant is a real advantage. Sovereignty, cost at scale and AI-change review are the boundaries to price in first.', + meta: 'Metadata-driven platforms', + href: '/en/blog/power-platform-lock-in-dataverse-self-host/', + }, + { + title: 'Agentforce vs an open self-hosted runtime', + body: 'Agentforce, Copilot Studio and ServiceNow agents are strong inside their ecosystems. The question is whether your data, processes and permissions are in the same one.', + meta: 'Metadata-driven platforms', + href: '/en/blog/beyond-agentforce-copilot-open-runtime/', + }, + { + title: 'Is Lovable safe for production?', + body: 'Fine for prototypes. For production the question is who can review access control: the boundary has to be visible, enforced and signed off on the server.', + meta: 'AI code generation', + href: '/en/blog/is-lovable-safe-for-production/', + }, + { + title: 'Vibe coding technical debt', + body: 'AI-generated code ships a prototype fast; the problem arrives months later when nobody has read the implementation whole and nobody can explain the business trade-offs in it.', + meta: 'AI code generation', + href: '/en/blog/vibe-coding-technical-debt-2026/', + }, + ], + }, + ], + table: { + eyebrow: 'Side by side', + title: 'Each category as a whole, against the four promises', + columns: ['Category', `${p.t3[0]} · ${p.t3[1]} · ${p.t3[2]}`, `${p.t3[3]} · Is the system itself`], + rows: [ + ['Knowledge ontologies', 'No — reasoned over · Possible · Query only', 'Yes — open standards · No'], + ['Semantic and context layers', 'No — queried · Possible · Read-mostly', 'Varies · No — a layer'], + ['Operational ontologies', 'Actions only · Possible · Yes', 'Mostly vendor-held · No — a layer'], + ['Metadata-driven platforms', 'Yes · Varies · Often, via MCP', 'Varies · Yes'], + ['AI code generation', 'Yes · Yes · If you build it', 'Yes · Yes'], + ['ObjectStack', 'Yes · Yes — gated · Yes — by default', 'Yes — Apache-2.0 · Yes'], + ], + }, + checklistTitle: 'Five questions before you start', + checklist: [ + 'What we have — the objects and their fields.', + 'How it relates — the lookups and master-detail links between them.', + 'What can be done — the actions a user or an agent may take on a record.', + 'Who may do it — permission sets, row-level and field-level security, sharing.', + 'What happens when — record triggers, scheduled jobs, approvals, workflows.', + ], + faqs: [ + { + question: 'Is ObjectStack a semantic layer?', + answer: + 'No. A semantic layer is a read-only mapping over existing systems: it describes the business but does not run it. ObjectStack’s ontology is the system — the database, API, UI and agent tools are derived from it. Federating an external datasource is possible, read-only by default and early. ObjectStack does not replace a warehouse semantic layer either; a company doing serious BI will still want one.', + }, + { + question: 'Is it a low-code platform?', + answer: + 'The metadata-driven platforms are its closest relatives, so the family resemblance is real. The difference is where the definition lives and who it is written for: in most of those platforms metadata is configuration stored in the platform’s database and edited through its UI, while ObjectStack’s definition is typed, declarative TypeScript in your repository — versioned and reviewed as a diff, checked by os validate before it runs, and shaped for an AI to write.', + }, + { + question: 'Why not just let the agent write the code?', + answer: + 'Sometimes you should: code has no runtime ceiling, and an optimiser, a simulation, a canvas editor or a game is easier to build directly. For a business application the output is still code — it grows, its layers drift apart, past a certain size no agent can hold it whole, and nothing checks it against a definition of the business because there is none. ObjectStack keeps the definition, moves the code into the runtime, and rejects a wrong definition when it is written.', + }, + { + question: 'How long does the first ontology take?', + answer: + 'If the team can answer the five questions above, the ontology is a day’s work, because an agent does the writing. If it cannot, no tool helps yet, this one included. The first investment is answering those five questions, not installing anything.', + }, + { + question: 'Where does ObjectOS sit in this comparison?', + answer: `It is not a sixth category. ${p.t4} ${p.e1}`, + }, + ], + } satisfies MarketingPage; + +export default page; diff --git a/content/pages/en/ontology.ts b/content/pages/en/ontology.ts new file mode 100644 index 0000000..0be525d --- /dev/null +++ b/content/pages/en/ontology.ts @@ -0,0 +1,212 @@ +import type { MarketingPage } from '../../../src/content-pages/types'; +import { positioning } from '../../../src/lib/positioning'; + +const p = positioning.en; + +// The pillar for the positioning line. Every factual sentence below is taken +// from objectstack `origin/main`: `content/docs/concepts/ontology.mdx` (the +// authority on the word), `README.md` ("What we mean by ontology" through "You +// own it") and `content/docs/concepts/compare.mdx`. The positioning itself is +// quoted from `src/lib/positioning.ts`, never paraphrased. +const page = { + slug: 'ontology', + navLabel: 'Ontology', + title: 'What Is an Executable Business Ontology? ObjectStack’s Definition', + description: + `${p.t1} ${p.t2} What that means: a six-kind core the runtime executes, four projections that are not part of it, four guardrails on the word, and the mechanism behind each of the four promises.`, + eyebrow: 'Ontology', + heroTitle: p.t1, + lead: + `${p.t2} This page is what the word means here. The ontology is the definition of your business that the runtime executes: authored as typed metadata in your repository, compiled into one artifact, and run — the database, API, UI and agent tools are derived from it, and the definition is enforced on every call. Written for the person who chooses and for the agent that writes.`, + primary: { label: 'Point your agent at ObjectStack', href: '/en/agent-developer/' }, + secondary: { label: 'See how it compares', href: '/en/compare/' }, + metrics: [ + { value: '6 kinds', label: 'of thing in the core: objects and fields, relations, actions, permissions, flows, and agent and tool definitions' }, + { value: '4 projections', label: 'Views, dashboards, apps and translations — authored in metadata and validated by the same gate, but not part of the ontology' }, + { value: '4 gates', label: 'Typed, validated, reviewed, governed — between the agent and your users' }, + ], + artifact: { + eyebrow: 'How the runtime executes it', + title: 'One definition in. Everything else is derived.', + body: + 'The ontology is authored as typed metadata in objectstack.config.ts and compiled into the objectstack.json artifact. From that artifact the runtime derives the database schema on an interchangeable driver, a generated REST and realtime API, server-driven UI for the Console, and an MCP server — and it enforces the definition on every call. RBAC, row-level and field-level security, sharing and audit apply to a REST request, a Console click and an agent’s tool call alike. Nothing is reasoned over at runtime: what runs is what was validated.', + code: `objectstack.config.ts + # the ontology, as typed metadata + │ compiled + ▼ +objectstack.json + # the artifact the runtime loads + │ derives + ▼ +database schema · REST and realtime API +server-driven UI · MCP server + │ enforces, on every call + ▼ +RBAC · row- and field-level security +sharing · audit`, + }, + sections: [ + { + id: 'core', + eyebrow: 'The core', + title: 'Six kinds of thing, one definition', + copy: + 'The ontology is one definition, open and versioned. It lives in your repository as ordinary TypeScript, is reviewable as a diff, and is specified and licensed Apache-2.0 — not a graph held inside a vendor’s system and reachable only through that vendor’s console. The runtime derives everything else from it.', + items: [ + { + title: 'Objects and fields', + body: 'The entities of the business and their typed attributes — validation, formulas, defaults, files.', + meta: 'Guide', + href: '/en/data-modeling/', + }, + { + title: 'Relations', + body: 'Lookups and master-detail links between objects.', + }, + { + title: 'Actions', + body: 'The operations a user or an agent may invoke on a record, and the conditions under which they show.', + }, + { + title: 'Permissions', + body: 'Who may read, create, edit and delete what — RBAC, row-level and field-level security, sharing.', + meta: 'Guide', + href: '/en/permissions/', + }, + { + title: 'Flows', + body: 'The business processes — DAG flows, record triggers, scheduled jobs, approvals, workflows.', + meta: 'Guide', + href: '/en/automation/', + }, + { + title: 'Agent and tool definitions', + body: 'The AI agents the app ships with, the tools they may call, and the skills that shape them.', + meta: 'Guide', + href: '/en/mcp/', + }, + ], + }, + { + id: 'projections', + eyebrow: 'Projections', + title: 'Views, dashboards, apps and translations project it', + copy: + 'Projections are authored in metadata too, validated by the same gate, but they are not part of the ontology. Change the core and the projections follow; remove a projection and the business it showed is unchanged. The distinction bounds what an agent must hold to reason about the business: the core, not every screen.', + items: [ + { + title: 'A view', + body: 'Projects an object’s fields and permissions onto a grid.', + meta: 'Projection', + }, + { + title: 'A dashboard', + body: 'Projects queries over objects onto charts.', + meta: 'Projection', + }, + { + title: 'An app', + body: 'Groups objects, views and actions into a navigable product.', + meta: 'Projection', + }, + { + title: 'A translation', + body: 'Projects every label into a locale.', + meta: 'Projection', + }, + ], + }, + { + id: 'not', + eyebrow: 'What it is not', + title: 'Four guardrails on the word', + copy: + 'The word ontology covers several different kinds of thing, and two habits of thought travel with it. None of the four applies here; what ObjectStack is weighed against, side by side, is on the comparison page.', + items: [ + { + title: 'Not a knowledge ontology', + body: 'OWL, RDF and knowledge graphs describe a domain, carry class inheritance and axioms, and are reasoned over by an inference engine. ObjectStack has no object inheritance, no axioms and no reasoner: the definition is validated — by Zod schemas and os validate — and then run. The abstract key was removed from the spec for exactly that reason.', + }, + { + title: 'Not the industry’s semantic layer', + body: 'A semantic layer is a read-only mapping over existing systems: it describes the business but does not run it. ObjectStack’s ontology is the system — the database, API, UI and agent tools are derived from it. Federating an external datasource is possible, read-only by default and early.', + }, + { + title: 'Not a formal ontology in the philosophical sense', + body: 'It makes no claim about what exists in general. It is one business’s application, defined precisely enough to run.', + }, + { + title: 'Not code that disappears', + body: 'Code moves into the runtime. Hooks, action bodies, and the CEL expressions in formulas, predicates and policies run inside the runtime’s permission and audit fence; constrained JSX in pages is parsed into a server-driven UI tree, never executed as code. None of it is scattered across a codebase the ontology would then have to describe.', + }, + ], + }, + { + id: 'promises', + eyebrow: 'The four promises', + title: 'Each promise names the mechanism that keeps it', + copy: + 'The four words after the positioning line are not adjectives. Each one is kept by something specific in the runtime, the toolchain or the licence, and each is listed here with that thing.', + items: [ + { + title: p.t3[0], + body: 'The definition is the thing that runs. From the compiled artifact the runtime derives the database, the REST and realtime API, the Console UI and the MCP server, and enforces permissions and audit on every call — a REST request, a Console click and an agent’s tool call alike.', + meta: 'Guide', + href: '/en/platform/', + }, + { + title: p.t3[1], + body: 'The scaffolder installs the AI skills bundle and writes an AGENTS.md, so a coding agent starts with the protocol’s rules loaded. Strict TypeScript and Zod reject shape errors in the editor; os validate rejects metadata that type-checks but would fail silently at runtime — dangling bindings, bad CEL predicates, a missing security posture — as located, corrective text the agent reads and fixes itself. You approve a small, readable diff.', + meta: 'Guide', + href: '/en/agent-developer/', + }, + { + title: p.t3[2], + body: 'The running app is an MCP server, on by default: every object is a tool, every exposed action is a tool, permissions decide what an agent may call, and audit records what it did. An agent operates the app through the same typed, permission-aware surface as a human — never raw SQL or scraped UI.', + meta: 'Guide', + href: '/en/mcp/', + }, + { + title: p.t3[3], + body: 'The definition lives in your repository as ordinary TypeScript, versioned in your VCS and reviewable as a diff — not a graph held inside a vendor’s system. Everything in the ObjectStack repository is the open stack — protocol, microkernel, SDK, CLI and the production runtime — Apache-2.0 with no open-core asterisks, and the scaffolded project is container-ready for self-hosting.', + meta: 'Source', + href: 'https://github.com/objectstack-ai/objectstack', + }, + ], + }, + ], + table: { + columns: ['You declare', 'The runtime derives', 'The runtime enforces'], + rows: [ + ['Objects, fields, relations', 'The database schema on an interchangeable driver; a generated REST and realtime API', 'Validation, formulas and defaults, as declared on the field'], + ['Actions', 'Permission-checked buttons and server operations; every exposed action doubles as an MCP tool', 'The conditions under which an action shows, and who may invoke it'], + ['Permissions', 'Nothing to generate — the fence itself', 'RBAC, row-level and field-level security, sharing and audit, on a REST request, a Console click and an agent’s tool call alike'], + ['Flows', 'DAG flows, record triggers, scheduled jobs, approvals with queues', 'Multi-step approval chains with a full audit trail'], + ['Agent and tool definitions', 'The MCP server the app serves, on by default', 'Permissions decide what an agent may call; audit records what it did'], + ['Views, dashboards, apps, translations', 'Server-driven UI for the Console', 'A view projects an object’s fields and its permissions — remove it and the business is unchanged'], + ], + }, + faqs: [ + { + question: 'Is this the same thing as a Palantir-style ontology?', + answer: + 'Close in vocabulary, different in where it lives. An operational ontology defines objects, links, actions and permissions over data integrated from other systems, with edits written back; the Palantir Ontology is the reference. It is still a layer over systems that live elsewhere and, in Palantir’s case, a proprietary platform. ObjectStack derives the database schema, API, UI and MCP tools from the definition itself, and it is Apache-2.0.', + }, + { + question: 'Does an ontology mean nobody writes code any more?', + answer: + 'No. Code does not disappear — it moves into the runtime. Hooks, action bodies and the CEL expressions in formulas, predicates and policies run inside the runtime’s permission and audit fence; constrained JSX in pages is parsed into a server-driven UI tree rather than executed. What changes is that none of it is scattered across a codebase the ontology would then have to describe.', + }, + { + question: 'Why does size matter so much?', + answer: + 'Because both halves of the loop depend on it. An agent writing the definition and an agent operating the app both need to hold the whole thing: apps small enough for AI to hold whole can be read whole, reasoned about whole and refactored whole. The bundled example CRM — objects, views, a dashboard, a lead-conversion flow, permission sets, actions, translations — is small enough for an agent to load end to end and answer what breaks if this changes.', + }, + { + question: 'Where does ObjectOS come in?', + answer: `${p.t4} ${p.e1}`, + }, + ], + } satisfies MarketingPage; + +export default page; diff --git a/content/pages/zh-Hans/compare.ts b/content/pages/zh-Hans/compare.ts new file mode 100644 index 0000000..54e6734 --- /dev/null +++ b/content/pages/zh-Hans/compare.ts @@ -0,0 +1,243 @@ +import type { MarketingPage } from '../../../src/content-pages/types'; +import { positioning } from '../../../src/lib/positioning'; + +const p = positioning['zh-Hans']; + +// 对比页,含「什么时候不该用它」。每一句事实都取自 objectstack `origin/main`: +// `content/docs/concepts/compare.mdx`(五类、并排表、别人更强的地方)和 +// `content/docs/concepts/when-to-use.mdx`(适合、今天不适合、开工前的五个问题)。 +// 定位句引自 `src/lib/positioning.ts`。把本站的对比文章归入五类,是本页自己的归类, +// 不是 objectstack 的。中文按来源重新推导,不是英文页的翻译。 +const page = { + slug: 'compare', + navLabel: '对比', + title: 'ObjectStack 与其他方案的对比,以及什么时候不该用它', + description: + '把 ObjectStack 放到知识本体、语义层与上下文层、运营本体、元数据驱动平台和 AI 代码生成旁边:各自擅长什么、真正的差别在哪、别人在哪些地方更强,以及今天哪些工作负载不适合它。', + eyebrow: '对比', + heroTitle: '常被拿来比的五类东西,它一类都不是。', + lead: + `2026 年,「本体」这个词指好几种不同的东西,用这个词的产品解决的也是不同的问题。这一页把 ObjectStack 放到读者最可能拿来比较的五类旁边——三类用这个词,两类不用这个词却回答同一个问题——然后说清每一类在哪里更强,以及 ObjectStack 今天在哪些场景不适合。它是什么:${p.t2}`, + primary: { label: '把你的 Agent 指向 ObjectStack', href: '/en/agent-developer/' }, + secondary: { label: '本体是什么', href: '/en/ontology/' }, + metrics: [ + { value: '5 类', label: '常被拿来比较的东西——三类用「本体」这个词,两类不用这个词却回答同一个问题' }, + { value: '4 处', label: '别的类别更强的地方,本页直说:现有数据资产、推理、算法密集的工作、生态成熟度' }, + { value: '5 种', label: '今天不适合的工作负载,从大企业的核心 ERP 到必须跑在认证平台上的任何东西' }, + ], + artifact: { + eyebrow: '适合的场景', + title: '今天它适合放在哪里', + body: + 'ObjectStack 面向的是定义归你所有、由 AI 编写、由 Agent 操作的业务应用。今天有五种形状的工作符合这个描述。不适合的场景在对比之后,开工前要回答的五个问题在页末。', + steps: [ + '新建的业务应用——CRM、工单、审批、运营和内部工具。对象、关系、动作、权限和流程就是这些应用的大部分,也正是本体所声明的东西。', + '小到一个人或几个人就能定义业务的团队。Agent 来写定义,但总得有人知道它该写什么;需要达成一致的人越少,闭环跑得越快。', + '要交付许多垂直应用的 ISV。每个垂直行业都是同一个运行时上的一份定义;它们之间不同的是定义,不是底下的栈。', + '围绕核心 ERP 的长尾部门应用——供应商准入、巡检、内部申请。每一个都变成仓库里的一份类型化定义,而不是一个靠邮件传来传去的文件。', + '从第一天起就打算交给 Agent 操作的后台。每一个部署都是一个 MCP 服务器,默认开启:对象是工具,作者暴露的动作是工具,权限决定 Agent 可以调用什么。', + ], + }, + sections: [ + { + id: 'categories', + eyebrow: '五个类别', + title: '各自是什么、擅长什么、唯一要紧的差别', + copy: + '每一条读的是整个类别;具体产品各有差异。每一类点出的那一个差别,决定它是否回答你的问题。', + items: [ + { + title: '知识本体', + body: 'RDF 和 OWL,W3C 用来把一个领域描述为陈述、类、属性和公理的标准,以及建在它们之上的工具,比如 Protégé 编辑器;推理器推断出没人存过的事实,并检查整套描述是否一致。擅长跨组织的共享词汇、整合从未设计成能拼在一起的数据,以及靠推理回答问题。差别:知识本体描述一个领域,没有东西把它当作应用来运行。ObjectStack 的本体没有公理、没有推理器——先校验,再运行。', + meta: '用这个词', + }, + { + title: '架在现有数据之上的语义层与上下文层', + body: '让住在别处的数据对 Agent 和分析师可读的一层:数据仓库、湖仓和业务数据库之上的业务名称、指标、关系和上下文。到 2026 年下半年,这一类包括 Microsoft Fabric IQ 里的 ontology 项目(预览中)、Databricks Genie 配合 Unity Catalog 的指标视图、Snowflake 语义视图、AWS Context 和 Google Cloud Knowledge Catalog;开源侧则有指标语义层和 Agent 记忆图。擅长在一大片既有数据资产上保持一致的语义,而不搬动数据;以读为主,有些在上面加了规则和动作。差别:记录系统还留在原地。ObjectStack 的本体就是系统——数据库、API、界面和 Agent 工具都从它派生。', + meta: '用这个词', + }, + { + title: '架在现有系统之上的运营本体', + body: '在从其他系统集成来的数据之上定义对象、链接、动作和权限,并把编辑写回去。Palantir Ontology 是这一类的参照:一个动作类型把对象与链接的编辑连同其校验和副作用打包在一起,写回机制让这些编辑与底层数据保持同步。擅长在许多留在原地的大型系统之上建立一个受治理的对象与动作模型,让人和 Agent 在一个地方做运营决策。差别:它仍然是架在别处系统之上的一层,而且在 Palantir 这里是一个专有平台。ObjectStack 从定义派生数据库结构、API、界面和 MCP 工具,而且是 Apache-2.0。', + meta: '用这个词', + }, + { + title: '元数据驱动的应用平台', + body: '由元数据生成表、API 和界面的平台——最近的亲戚。Salesforce 的元数据是它们的祖先;开源的同族有 Frappe Framework 与 ERPNext、Odoo、NocoBase、Payload 和 Twenty,其中几家现在也提供 MCP 服务器。擅长在一个经过验证的运行时上快速搭建业务应用,有打包好的应用、模块和集成可以起步。差别:定义住在哪里、为谁而写。在这些平台里,元数据大多是存在平台数据库中、通过它的界面编辑的配置;是代码的地方,也是框架代码。ObjectStack 的定义是你仓库里类型化、声明式的 TypeScript——带版本、当作 diff 审阅、运行前由 os validate 检查,而且是为 AI 来写而设计的。', + meta: '同一个问题', + }, + { + title: 'AI 代码生成', + body: 'Agent 根据提示写出一个常规代码库:schema、处理函数、组件,以及把它们粘在一起的胶水。它擅长的地方:没有运行时天花板,代码能做的它都能产出。差别:产出仍然是代码。它会长大,各层会彼此漂移,超过某个规模就没有 Agent 能把它整体装下。测试和类型检查器拿代码对照代码自己;没有东西拿它对照一份业务定义,因为根本没有这份定义。ObjectStack 保留定义、把代码搬进运行时,它的门禁在定义写下时就拒掉错的,而不是等它在生产中失败。', + meta: '同一个问题', + }, + ], + }, + { + id: 'stronger', + eyebrow: '别人更强的地方', + title: '四种该选别的东西的情况', + copy: + '只列优点的对比是广告。下面四种情况,别的类别一上来就领先,用的是 objectstack 自己的原话。', + items: [ + { + title: '既有数据与遗留系统', + body: '语义层与上下文层、运营本体。当数据已经住在一个数据仓库、一个湖仓和十几个业务系统里时,它们从你所在的地方出发。ObjectStack 的联邦接入还早、默认只读;它不是把一个模型盖在既有资产之上的办法。', + }, + { + title: '对异构数据做推理', + body: '知识本体。推断没人存过的事实、按公理分类、检查一致性、跨组织对齐词汇:这是推理器干的活,而 ObjectStack 没有推理器。', + }, + { + title: '算法密集的工作与非常规界面', + body: '代码。优化器、仿真、画布编辑器、游戏:写代码。ObjectStack 可以把一个算法包成动作,但它的界面是由元数据服务端驱动的,一个不像任何业务应用的界面直接写更容易。', + }, + { + title: '生态成熟度与集成', + body: '元数据平台。Salesforce、Odoo 和 ERPNext 带着多年的生产使用、打包好的应用、应用市场和实施伙伴。ObjectStack 更年轻;要有更多东西自己搭的准备。', + }, + ], + }, + { + id: 'not-a-fit', + eyebrow: '什么时候不该用它', + title: '今天不适合的场景', + copy: + 'ObjectStack 是你自己部署、自己运营的开源软件,面向定义归你所有的业务应用。下面五种工作负载今天在这个范围之外,诚实的答案是绕着它们建,或者选别的东西。', + items: [ + { + title: '替换大企业的核心 ERP 或财务系统', + body: '总账、合并、税务和薪资承载的法规和边角情况,套装系统已经编码进去了。围绕那个核心去建,而不是取而代之。', + }, + { + title: '价值在于集成许多既有系统的工作', + body: 'ObjectStack 可以把一个外部数据库作为数据源联邦接入,但联邦还早、默认只读;写入需要在数据源和对象两边显式开启。当工作主要是让既有系统对 Agent 可读时,架在那些系统之上的一层更合适。', + }, + { + title: '数据湖之上的分析', + body: '分析层在应用自己的对象之上为它的报表和仪表盘定义指标。它不是为查询数据湖而建的。', + }, + { + title: '算法密集的领域,比如定价或排程', + body: '除非把算法包成一个动作。本体声明可以做什么,它不表达一个优化器。把算法写成动作背后的代码,权限、审计和 Agent 访问就像对待其他任何动作一样作用于它。', + }, + { + title: '要求认证平台的工作负载', + body: 'ObjectStack 自身不带任何合规认证。工作负载必须跑在认证平台上的地方,给你的部署做认证是你自己的活。', + }, + ], + }, + { + id: 'in-depth', + eyebrow: '深入阅读', + title: '逐个产品的对比', + copy: + '上面按类别,这里按产品。每篇都先说对方的强项,再说真正要比的那一件事。标签是该产品在本页归入的类别;标注「英文」的文章只有英文版。', + items: [ + { + title: '本体 vs 语义层 vs 知识图谱(英文)', + body: '语义层定义一个数字意味着什么;知识图谱存储什么与什么相连;只有本体带着动作和权限。附决策表。', + meta: '知识本体', + href: '/en/blog/ontology-vs-semantic-layer-vs-knowledge-graph/', + }, + { + title: 'Fabric IQ、Palantir、Unity Catalog、Snowflake、Looker 五方对比(英文)', + body: '2025 年 11 月到 2026 年 8 月,五家厂商各自交付了企业本体或语义层,逐格对比对象、关系、动作、权限和 Agent 接口。', + meta: '语义层 · 运营本体', + href: '/en/blog/enterprise-ontology-platform-comparison/', + }, + { + title: '开放与封闭企业本体', + body: '协议开放,定义却留在平台里:五次发布之后,谁拥有业务语义层。', + meta: '语义层', + href: '/en/blog/enterprise-ontology-race-open-vs-closed/', + }, + { + title: 'Airtable Omni 与受治理 AI 应用平台', + body: '自然语言加表格式工作区很强。记录系统真正要比的,是 AI 改动权限、字段和流程时,能否在上线前形成可审阅的 diff。', + meta: '元数据驱动平台', + href: '/en/blog/airtable-omni-vs-governed-ai-app-platform/', + }, + { + title: 'Retool 与受治理 AI 应用平台', + body: 'Retool 的 RBAC、审计日志、SSO 和自托管很强。要比的是业务权限层:散落在 JavaScript 绑定里的退款、审批和写入,没法当作 diff 审查。', + meta: '元数据驱动平台', + href: '/en/blog/retool-vs-ai-native-app-platform/', + }, + { + title: 'Power Platform 锁定:Dataverse、Azure 与自托管取舍', + body: '身份、Teams、Dynamics 和账单在同一个租户里是真实的优势。主权、规模化成本和 AI 改动审查,是要先算清的边界。', + meta: '元数据驱动平台', + href: '/en/blog/power-platform-lock-in-dataverse-self-host/', + }, + { + title: 'Agentforce 与开放自托管运行时', + body: 'Agentforce、Copilot Studio 和 ServiceNow 的 Agent 在各自生态内都很强。问题是你的数据、流程和权限是否也在同一个生态里。', + meta: '元数据驱动平台', + href: '/en/blog/beyond-agentforce-copilot-open-runtime/', + }, + { + title: 'Lovable 上生产安全吗', + body: '做原型没问题。上生产的问题是谁能审查访问控制:边界必须在服务端可见、可强制、可签字。', + meta: 'AI 代码生成', + href: '/en/blog/is-lovable-safe-for-production/', + }, + { + title: 'Vibe Coding 技术债', + body: 'AI 生成的代码能让原型很快上线;问题在几个月后出现:没人完整读过那份实现,也没人能解释里面的业务取舍。', + meta: 'AI 代码生成', + href: '/en/blog/vibe-coding-technical-debt-2026/', + }, + ], + }, + ], + table: { + eyebrow: '并排对比', + title: '每个类别作为整体,对照四个承诺', + columns: ['类别', `${p.t3[0]} · ${p.t3[1]} · ${p.t3[2]}`, `${p.t3[3]} · 它就是系统本身`], + rows: [ + ['知识本体', '否——被推理 · 可能 · 仅查询', '是——开放标准 · 否'], + ['语义层与上下文层', '否——被查询 · 可能 · 以读为主', '不一定 · 否——是一层'], + ['运营本体', '仅动作 · 可能 · 是', '多数由厂商持有 · 否——是一层'], + ['元数据驱动平台', '是 · 不一定 · 常见,经 MCP', '不一定 · 是'], + ['AI 代码生成', '是 · 是 · 自己搭就有', '是 · 是'], + ['ObjectStack', '是 · 是——有门禁 · 是——默认开启', '是——Apache-2.0 · 是'], + ], + }, + checklistTitle: '开工前的五个问题', + checklist: [ + '我们有什么——对象及其字段。', + '它们如何关联——对象之间的查找与主从关联。', + '可以做什么——用户或 Agent 可以对一条记录采取的动作。', + '谁可以做——权限集、行级与字段级安全、共享。', + '什么时候发生什么——记录触发器、定时任务、审批、工作流。', + ], + faqs: [ + { + question: 'ObjectStack 是语义层吗?', + answer: + '不是。语义层是架在现有系统之上的一层只读映射:它描述业务,但不运行业务。ObjectStack 的本体就是系统——数据库、API、界面和 Agent 工具都从它派生。联邦接入外部数据源是可以的,默认只读,而且还处于早期。它也不替代数据仓库的语义层;认真做 BI 的公司仍然会想要一个。', + }, + { + question: '它是低代码平台吗?', + answer: + '元数据驱动的平台是它最近的亲戚,所以家族相似是真实的。差别在定义住在哪里、为谁而写:那些平台里的元数据大多是存在平台数据库中、通过它的界面编辑的配置;ObjectStack 的定义是你仓库里类型化、声明式的 TypeScript——带版本、当作 diff 审阅、运行前由 os validate 检查,而且是为 AI 来写而设计的。', + }, + { + question: '为什么不直接让 Agent 写代码?', + answer: + '有时候就该这样:代码没有运行时天花板,优化器、仿真、画布编辑器或游戏直接写更容易。但对业务应用来说,产出仍然是代码——它会长大,各层会漂移,超过某个规模就没有 Agent 能整体装下,而且没有东西拿它对照一份业务定义,因为根本没有这份定义。ObjectStack 保留定义、把代码搬进运行时,并在定义写下时就拒掉错的。', + }, + { + question: '第一份本体要多久?', + answer: + '如果团队答得出上面五个问题,本体是一天的活,因为写的是 Agent。答不出,那还没有工具帮得上忙,这一个也不例外。第一笔投入是回答这五个问题,不是安装任何东西。', + }, + { + question: 'ObjectOS 在这张对比里的位置?', + answer: `它不是第六个类别。${p.t4}${p.e1}`, + }, + ], + } satisfies MarketingPage; + +export default page; diff --git a/content/pages/zh-Hans/ontology.ts b/content/pages/zh-Hans/ontology.ts new file mode 100644 index 0000000..6a3390f --- /dev/null +++ b/content/pages/zh-Hans/ontology.ts @@ -0,0 +1,210 @@ +import type { MarketingPage } from '../../../src/content-pages/types'; +import { positioning } from '../../../src/lib/positioning'; + +const p = positioning['zh-Hans']; + +// 定位句的支柱页。下面每一句事实都取自 objectstack `origin/main`: +// `content/docs/concepts/ontology.mdx`(这个词的权威定义)、`README.md` +// (「What we mean by ontology」到「You own it」)和 `content/docs/concepts/compare.mdx`。 +// 定位句本身引自 `src/lib/positioning.ts`,从不转述。中文按来源重新推导,不是英文页的翻译。 +const page = { + slug: 'ontology', + navLabel: '本体', + title: '什么是可执行的业务本体?ObjectStack 的定义', + description: + `${p.t1}${p.t2}这句话的意思:由运行时执行的六类核心、不属于本体的四种投影、关于这个词的四道护栏,以及四个承诺各自靠什么兑现。`, + eyebrow: '本体', + heroTitle: p.t1, + lead: + `${p.t2}这一页说清这个词在这里指什么。本体是你的业务里那份由运行时直接执行的定义:以类型化元数据写在你的仓库里,编译成一个工件,然后运行——数据库、API、界面和 Agent 工具都从它派生,定义本身在每一次调用时被强制执行。同时写给做选择的人和写定义的 Agent。`, + primary: { label: '把你的 Agent 指向 ObjectStack', href: '/en/agent-developer/' }, + secondary: { label: '看它与其他方案的对比', href: '/en/compare/' }, + metrics: [ + { value: '6 类', label: '核心由六类东西构成:对象与字段、关系、动作、权限、流程、Agent 与工具定义' }, + { value: '4 种投影', label: '视图、仪表盘、应用和翻译——同样用元数据编写、过同一道门禁,但不是本体的一部分' }, + { value: '4 道闸门', label: '类型化、校验、审阅、治理——横在 Agent 与你的用户之间' }, + ], + artifact: { + eyebrow: '运行时如何执行它', + title: '一份定义进去,其余全部派生。', + body: + '本体以类型化元数据写在 objectstack.config.ts 里,编译成 objectstack.json 工件。运行时从这个工件派生可更换驱动之上的数据库结构、生成的 REST 与实时 API、Console 的服务端驱动界面,以及一个 MCP 服务器——并在每一次调用时强制执行这份定义。RBAC、行级与字段级安全、共享和审计,对一次 REST 请求、一次 Console 点击和一次 Agent 工具调用一视同仁。运行时不做任何推理:跑的就是被校验过的东西。', + code: `objectstack.config.ts + # 本体:用类型化元数据写下的定义 + │ 编译 + ▼ +objectstack.json + # 运行时加载的工件 + │ 派生 + ▼ +数据库结构 · REST 与实时 API +服务端驱动界面 · MCP 服务器 + │ 每一次调用都强制执行 + ▼ +RBAC · 行级与字段级安全 · 共享 · 审计`, + }, + sections: [ + { + id: 'core', + eyebrow: '核心', + title: '六类东西,一份定义', + copy: + '本体是一份定义,开放、带版本。它以普通 TypeScript 的形式住在你的仓库里,可以当作一个 diff 来审阅,规范与许可证都是 Apache-2.0——而不是一张锁在厂商系统里、只能通过那家厂商的控制台触达的图。其余一切都由运行时从它派生。', + items: [ + { + title: '对象与字段', + body: '业务里的实体及其类型化属性——校验、公式、默认值、文件。', + meta: '指南', + href: '/en/data-modeling/', + }, + { + title: '关系', + body: '对象之间的查找与主从关联。', + }, + { + title: '动作', + body: '用户或 Agent 可以对一条记录发起的操作,以及它们显示的条件。', + }, + { + title: '权限', + body: '谁可以读取、创建、编辑和删除什么——RBAC、行级与字段级安全、共享。', + meta: '指南', + href: '/en/permissions/', + }, + { + title: '流程', + body: '业务过程——DAG 流程、记录触发器、定时任务、审批、工作流。', + meta: '指南', + href: '/en/automation/', + }, + { + title: 'Agent 与工具定义', + body: '应用自带的 AI Agent、它们可以调用的工具,以及塑造它们的技能。', + meta: '指南', + href: '/en/mcp/', + }, + ], + }, + { + id: 'projections', + eyebrow: '投影', + title: '视图、仪表盘、应用和翻译是它的投影', + copy: + '投影同样用元数据编写、由同一道门禁校验,但它们不是本体的一部分。改动核心,投影跟着变;删掉一个投影,它所展示的业务不变。这个区分划定了 Agent 为了推理业务必须装下的范围:是核心,而不是每一个屏幕。', + items: [ + { + title: '视图', + body: '把一个对象的字段和权限投影到一张网格上。', + meta: '投影', + }, + { + title: '仪表盘', + body: '把对象上的查询投影到图表上。', + meta: '投影', + }, + { + title: '应用', + body: '把对象、视图和动作组合成一个可导航的产品。', + meta: '投影', + }, + { + title: '翻译', + body: '把每一个标签投影到一种语言。', + meta: '投影', + }, + ], + }, + { + id: 'not', + eyebrow: '它不是什么', + title: '关于这个词的四道护栏', + copy: + '「本体」这个词涵盖好几种不同的东西,还有两种思维习惯随它一起出现。四者在这里都不成立;ObjectStack 与它们的逐项对比在对比页。', + items: [ + { + title: '不是知识本体', + body: 'OWL、RDF 和知识图谱描述一个领域,带有类继承和公理,并由推理引擎推理。ObjectStack 没有对象继承、没有公理、没有推理器:定义先被校验——由 Zod schema 和 os validate——然后被运行。abstract 这个键正是因此从规范中移除。', + }, + { + title: '不是业界所说的语义层', + body: '语义层是架在现有系统之上的一层只读映射:它描述业务,但不运行业务。ObjectStack 的本体就是系统——数据库、API、界面和 Agent 工具都从它派生。联邦接入外部数据源是可以的,默认只读,而且还处于早期。', + }, + { + title: '不是哲学意义上的形式本体', + body: '它不对「什么东西普遍存在」做任何断言。它是一家企业的一个应用,定义得精确到足以运行。', + }, + { + title: '不是「代码消失了」', + body: '代码搬进了运行时。钩子、动作体,以及公式、谓词和策略里的 CEL 表达式,都在运行时的权限与审计围栏内运行;页面里的受限 JSX 被解析成服务端驱动的界面树,从不当作代码执行。没有一样散落在一个本体随后还得去描述的代码库里。', + }, + ], + }, + { + id: 'promises', + eyebrow: '四个承诺', + title: '每个承诺都点名兑现它的机制', + copy: + '定位句后面的四个词不是形容词。每一个都由运行时、工具链或许可证里某个具体的东西兑现,这里把那个东西逐一列出。', + items: [ + { + title: p.t3[0], + body: '定义就是在跑的那个东西。运行时从编译后的工件派生数据库、REST 与实时 API、Console 界面和 MCP 服务器,并在每一次调用时强制执行权限与审计——REST 请求、Console 点击和 Agent 工具调用一视同仁。', + meta: '指南', + href: '/en/platform/', + }, + { + title: p.t3[1], + body: '脚手架安装 AI 技能包并写入一份 AGENTS.md,编码 Agent 一开始就带着协议的规则。Strict TypeScript 和 Zod 在编辑器里拒掉形状错误;os validate 拒掉类型检查能过、运行时却会静默失败的元数据——悬空绑定、错误的 CEL 谓词、缺失的安全姿态——并以定位到位置、可据以修正的文字返回,Agent 自己读、自己改。你审批一个小而可读的 diff。', + meta: '指南', + href: '/en/agent-developer/', + }, + { + title: p.t3[2], + body: '跑起来的应用就是一个 MCP 服务器,默认开启:每个对象是一个工具,每个暴露出来的动作是一个工具,权限决定 Agent 可以调用什么,审计记录它做了什么。Agent 通过与人相同的类型化、权限感知的表面操作应用——从不是裸 SQL 或抓取界面。', + meta: '指南', + href: '/en/mcp/', + }, + { + title: p.t3[3], + body: '定义以普通 TypeScript 的形式住在你的仓库里,在你的版本控制里带版本、可以当作 diff 审阅——不是一张锁在厂商系统里的图。ObjectStack 仓库里的一切都是开放栈——协议、微内核、SDK、CLI 和生产运行时——Apache-2.0,没有 open-core 的星号;脚手架生成的项目开箱即可容器化自托管。', + meta: '源码', + href: 'https://github.com/objectstack-ai/objectstack', + }, + ], + }, + ], + table: { + columns: ['你声明', '运行时派生', '运行时强制执行'], + rows: [ + ['对象、字段、关系', '可更换驱动之上的数据库结构;生成的 REST 与实时 API', '字段上声明的校验、公式与默认值'], + ['动作', '带权限检查的按钮与服务端操作;每个暴露的动作同时是一个 MCP 工具', '动作显示的条件,以及谁可以发起它'], + ['权限', '无需生成——它本身就是围栏', 'RBAC、行级与字段级安全、共享和审计,对 REST 请求、Console 点击和 Agent 工具调用一视同仁'], + ['流程', 'DAG 流程、记录触发器、定时任务、带队列的审批', '多级审批链与完整的审计轨迹'], + ['Agent 与工具定义', '应用对外提供的 MCP 服务器,默认开启', '权限决定 Agent 可以调用什么;审计记录它做了什么'], + ['视图、仪表盘、应用、翻译', 'Console 的服务端驱动界面', '视图投影的是对象的字段和权限——删掉它,业务不变'], + ], + }, + faqs: [ + { + question: '它和 Palantir 那种本体是一回事吗?', + answer: + '词汇相近,住的地方不同。运营本体在从其他系统集成来的数据之上定义对象、链接、动作和权限,并把编辑写回去;Palantir Ontology 是这一类的参照。它仍然是架在别处系统之上的一层,而且在 Palantir 这里是一个专有平台。ObjectStack 从定义本身派生数据库结构、API、界面和 MCP 工具,而且是 Apache-2.0。', + }, + { + question: '有了本体,是不是就没人写代码了?', + answer: + '不是。代码不会消失——它搬进了运行时。钩子、动作体,以及公式、谓词和策略里的 CEL 表达式,在运行时的权限与审计围栏内运行;页面里的受限 JSX 被解析成服务端驱动的界面树,而不是被执行。变化在于:没有一样散落在一个本体随后还得去描述的代码库里。', + }, + { + question: '为什么大小这么重要?', + answer: + '因为闭环的两半都依赖它。写定义的 Agent 和操作应用的 Agent 都需要把整件东西装下:小到 AI 能一次读全的应用,才能被整体阅读、整体推理、整体重构。自带的示例 CRM——对象、视图、一个仪表盘、一条线索转化流程、权限集、动作、翻译——小到 Agent 可以端到端加载,回答得出「改这里会弄坏什么」。', + }, + { + question: 'ObjectOS 在哪里?', + answer: `${p.t4}${p.e1}`, + }, + ], + } satisfies MarketingPage; + +export default page; diff --git a/src/components/Header.astro b/src/components/Header.astro index 428a45c..7ec78d4 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -38,6 +38,7 @@ const pathname = Astro.url.pathname; const homeHref = homePath(locale); const blogHref = blogPath(locale); const pricingHref = pricingPath(locale); +const ontologyHref = marketingPagePath(locale, 'ontology'); const productTourHref = marketingPagePath(locale, 'product-tour'); const platformHref = marketingPagePath(locale, 'platform'); const aiHref = marketingPagePath(locale, 'ai'); @@ -90,6 +91,7 @@ const groups: NavGroup[] = [ id: 'product', label: t.siteNav.product, active: + pathname === ontologyHref || pathname === productTourHref || pathname === platformHref || pathname === trustCenterHref || @@ -98,6 +100,7 @@ const groups: NavGroup[] = [ { label: t.siteNav.groupEvaluate, items: [ + { label: t.siteNav.ontology, href: ontologyHref, active: pathname === ontologyHref }, { label: t.siteNav.productTour, href: productTourHref, active: pathname === productTourHref }, { label: t.siteNav.platform, href: platformHref, active: pathname === platformHref }, { label: t.siteNav.whyObjectOs, href: `${homeHref}#compare`, active: false }, diff --git a/src/components/MarketingEvidencePage.astro b/src/components/MarketingEvidencePage.astro index 6258107..ce7eae0 100644 --- a/src/components/MarketingEvidencePage.astro +++ b/src/components/MarketingEvidencePage.astro @@ -6,7 +6,8 @@ import type { MarketingPage } from '../content-pages/types'; import { marketingPageUi } from '../content-pages/ui'; import { cardSpans } from '../lib/card-rows'; import { phraseHtml } from '../../scripts/lib/cjk-phrases.mjs'; -import { pricingPath, securityPath, type Locale } from '../lib/i18n'; +import { postPath, pricingPath, securityPath, type Locale } from '../lib/i18n'; +import { getPostsInLocale } from '../lib/posts'; interface Props { page: MarketingPage; @@ -18,7 +19,17 @@ const pages = getMarketingPages(locale); const ui = marketingPageUi(locale); const relatedPages = pages.filter((item) => item.slug !== page.slug); const marketingSlugs = new Set(pages.map((item) => item.slug)); +// Blog posts are built only for the locales that have a file, so a post link +// is localized only where that locale's post exists; otherwise the English +// post is the right target, not a 404. Same rule as content-lint's +// cross-locale check and gen-zh-hant's link rewrite. +const localePostSlugs = new Set((await getPostsInLocale(locale)).map((post) => post.slug)); const localizeHref = (href: string): string => { + const post = href.match(/^\/en\/blog\/([^/#]+)\/?(#.*)?$/); + if (post) { + const [, slug, hash = ''] = post; + return localePostSlugs.has(slug) ? `${postPath(locale, slug)}${hash}` : href; + } const match = href.match(/^\/en\/([^/#]+)\/?(#.*)?$/); if (!match) return href; const [, slug, hash = ''] = match; @@ -145,8 +156,8 @@ const ph = (text: string): string => phraseHtml(text, locale); page.table && (
-

{ui.decisionEyebrow}

-

+

{page.table.eyebrow ?? ui.decisionEyebrow}

+

diff --git a/src/components/MarketingHome.astro b/src/components/MarketingHome.astro index f730717..2815989 100644 --- a/src/components/MarketingHome.astro +++ b/src/components/MarketingHome.astro @@ -41,6 +41,8 @@ const productTourHref = marketingPagePath(locale, 'product-tour'); const templatesHref = `${marketingPagePath(locale, 'templates')}#catalog`; const agentDeveloperHref = marketingPagePath(locale, 'agent-developer'); const trustCenterHref = marketingPagePath(locale, 'trust-center'); +const ontologyHref = marketingPagePath(locale, 'ontology'); +const compareHref = marketingPagePath(locale, 'compare'); // Capability and AI cards deep-link into the capability pages. Index-based: // every locale translates the same arrays in the same order. @@ -88,11 +90,11 @@ const insightTerms = [ .map((slug) => termBySlug(slug)) .filter(Boolean); const clusterLinks = CLUSTERS; -const compareLinks = [ - { slug: 'airtable-omni-vs-governed-ai-app-platform', tone: 'green' }, - { slug: 'retool-vs-ai-native-app-platform', tone: 'blue' }, - { slug: 'is-lovable-safe-for-production', tone: 'amber' }, -]; +// The three "vs" chips land on the comparison page's product-by-product +// section, where each named product has its post; the section's text link +// goes to the page itself. Index-based tones, like the template cards. +const compareTones = ['green', 'blue', 'amber']; +const compareInDepthHref = `${compareHref}#in-depth`; // A raster post cover is served as WebP at the card's width, not as the // 1.5-1.9 MB original: one of three columns (about 345px) on a desktop, one of @@ -155,6 +157,7 @@ const HERO_SIZES = '(min-width: 898px) 910px, calc(120vw - 2.4rem)';

{copy.positioningKicker}

{lineJoin}

{copy.positioningCopy}

+ {copy.positioningLink} {/* The product diagram used to open the hero. The overview video is the page's first visual now, so this sits below it, illustrating the positioning it belongs to. */} @@ -295,13 +298,13 @@ const HERO_SIZES = '(min-width: 898px) 910px, calc(120vw - 2.4rem)';

{copy.compareKicker}

{lineJoin}

- {copy.compareLink} → + {copy.compareLink} →
{copy.comparisons.map((c, index) => (

{c.title}

@@ -733,6 +736,12 @@ const HERO_SIZES = '(min-width: 898px) 910px, calc(120vw - 2.4rem)'; font-size: 1.03rem; line-height: 1.9; } + /* The positioning section is a block, not a flex head, so the shared + text-link needs its own vertical spacing here. */ + .positioning-link { + display: inline-block; + margin-top: 0.5rem; + } .capability-section, .ai-section, .workflow, diff --git a/src/content-pages/registry.ts b/src/content-pages/registry.ts index 5d51f2d..38860b9 100644 --- a/src/content-pages/registry.ts +++ b/src/content-pages/registry.ts @@ -3,8 +3,10 @@ import { s2t } from '../lib/zhconvert'; import type { MarketingPage } from './types'; const PAGE_ORDER = [ + 'ontology', 'product-tour', 'platform', + 'compare', 'ai', 'mcp', 'permissions', diff --git a/src/content-pages/types.ts b/src/content-pages/types.ts index 386d5d4..36b70f8 100644 --- a/src/content-pages/types.ts +++ b/src/content-pages/types.ts @@ -25,6 +25,13 @@ export interface MarketingPageSection { } export interface MarketingPageTable { + /** + * Heading over the table. Absent, the shared "decision surface" heading in + * `ui.ts` renders; a page whose table is not a decision surface (the + * side-by-side comparison on /compare/) names its own. + */ + eyebrow?: string; + title?: string; columns: [string, string, string]; rows: [string, string, string][]; } diff --git a/src/lib/home.ts b/src/lib/home.ts index c70c2b1..731e6fe 100644 --- a/src/lib/home.ts +++ b/src/lib/home.ts @@ -51,6 +51,8 @@ interface HomeCopy { positioningKicker: string; positioningTitle: [string, string]; positioningCopy: string; + /** The text link under the positioning copy, to the /[lang]/ontology/ pillar. */ + positioningLink: string; capabilitiesKicker: string; capabilitiesTitle: [string, string]; capabilitiesLink: string; @@ -116,6 +118,7 @@ const zhHans: HomeCopy = { imageNote: '正在连接应用、数据与 Agent', positioningKicker: positioning['zh-Hans'].t1, positioningTitle: ['保留已经有效的系统,', '补上 Agent 可治理运行时。'], + positioningLink: '什么是可执行的业务本体', positioningCopy: '企业 AI 不需要又一次重建,也不需要更多不可审的生成代码。它需要一份 Agent 能写、人能审、运行时能治理的定义,把旧系统、新应用和 AI Agent 接在一起。你的对象与字段、关系、动作、权限、流程,以及 Agent 与工具定义,就是这份定义——你的业务本体:开放、带版本、归你所有,而不是锁在别人平台里的资产。', capabilitiesKicker: '平台能力', capabilitiesTitle: ['从业务结构出发,', '而不是从空白代码开始'], @@ -204,6 +207,7 @@ const en: HomeCopy = { imageNote: 'Connecting applications, data, and agents', positioningKicker: positioning.en.t1, positioningTitle: ['Keep the systems that work.', 'Add a governed runtime for agents.'], + positioningLink: 'What an executable business ontology is', positioningCopy: 'Enterprise AI does not need another rebuild project or another pile of generated code. It needs one definition agents can write, humans can review, and a runtime can govern across legacy systems, new applications, and AI agents. Your objects and fields, relations, actions, permissions, flows, and agent and tool definitions are that definition — your business ontology: open, versioned, and yours, not an asset locked inside someone else’s platform.', capabilitiesKicker: 'Platform capabilities', capabilitiesTitle: ['Start with the business model,', 'not a blank codebase'], @@ -293,6 +297,7 @@ const ja: HomeCopy = { imageNote: 'アプリ、データ、エージェントを接続中', positioningKicker: positioning.ja.t1, positioningTitle: ['今あるシステムを活かし、', 'エージェント用の統制ランタイムを加える。'], + positioningLink: '実行可能なビジネスオントロジーとは', positioningCopy: 'エンタープライズ AI に必要なのは、また一つの再構築プロジェクトでも、レビュー不能な生成コードの山でもありません。エージェントが書き、人がレビューでき、ランタイムが統制する、ひとつの定義です。オブジェクトとフィールド、リレーション、アクション、権限、フロー、そしてエージェントとツールの定義がその定義 — あなたのビジネスオントロジーです。オープンで、バージョン管理され、あなたのもの。誰かのプラットフォームに閉じ込められた資産ではありません。', capabilitiesKicker: 'プラットフォーム機能', capabilitiesTitle: ['白紙のコードではなく、', '業務構造から始める'], @@ -382,6 +387,7 @@ const de: HomeCopy = { imageNote: 'Verbindet Anwendungen, Daten und Agents', positioningKicker: positioning.de.t1, positioningTitle: ['Bewährte Systeme behalten.', 'Eine kontrollierte Runtime für Agents ergänzen.'], + positioningLink: 'Was eine ausführbare Geschäftsontologie ist', positioningCopy: 'Enterprise AI braucht kein weiteres Neuaufbauprojekt und keinen weiteren Stapel generierten Codes. Sie braucht eine Definition, die Agents schreiben, Menschen prüfen und eine Runtime über Legacy-Systeme, neue Anwendungen und AI Agents hinweg kontrolliert. Ihre Objekte und Felder, Beziehungen, Aktionen, Berechtigungen, Flows sowie Agent- und Tool-Definitionen sind diese Definition — Ihre Geschäftsontologie: offen, versioniert und in Ihrem Besitz, kein Asset in der Plattform eines anderen.', capabilitiesKicker: 'Plattformfunktionen', capabilitiesTitle: ['Mit der Geschäftsstruktur beginnen,', 'nicht mit einer leeren Codebasis'], @@ -471,6 +477,7 @@ const es: HomeCopy = { imageNote: 'Conectando aplicaciones, datos y agentes', positioningKicker: positioning.es.t1, positioningTitle: ['Conserva los sistemas que funcionan.', 'Añade un runtime gobernado para agentes.'], + positioningLink: 'Qué es una ontología de negocio ejecutable', positioningCopy: 'La AI empresarial no necesita otro proyecto de reconstrucción ni otra pila de código generado. Necesita una definición que los agentes puedan escribir, las personas revisar y un runtime gobernar entre sistemas heredados, nuevas aplicaciones y agentes de AI. Tus objetos y campos, relaciones, acciones, permisos, flujos y definiciones de agentes y herramientas son esa definición — tu ontología de negocio: abierta, versionada y tuya, no un activo encerrado en la plataforma de otro.', capabilitiesKicker: 'Capacidades de la plataforma', capabilitiesTitle: ['Empieza por la estructura del negocio,', 'no por código en blanco'], @@ -560,6 +567,7 @@ const fr: HomeCopy = { imageNote: 'Connexion des applications, données et agents', positioningKicker: positioning.fr.t1, positioningTitle: ['Conservez les systèmes efficaces.', 'Ajoutez un runtime gouverné pour agents.'], + positioningLink: 'Ce qu’est une ontologie métier exécutable', positioningCopy: 'L’AI en entreprise n’a pas besoin d’un nouveau chantier de reconstruction ni d’une nouvelle pile de code généré. Elle a besoin d’une définition que les agents peuvent écrire, que les humains peuvent relire, et qu’un runtime gouverne à travers systèmes existants, nouvelles applications et agents AI. Vos objets et champs, relations, actions, permissions, flux, et définitions d’agents et d’outils sont cette définition — votre ontologie métier : ouverte, versionnée et à vous, pas un actif enfermé dans la plateforme d’un autre.', capabilitiesKicker: 'Capacités de la plateforme', capabilitiesTitle: ['Partez de la structure métier,', 'pas d’une base de code vide'], @@ -649,6 +657,7 @@ const ko: HomeCopy = { imageNote: '애플리케이션, 데이터와 에이전트 연결 중', positioningKicker: positioning.ko.t1, positioningTitle: ['이미 잘 작동하는 시스템은 유지하고,', '에이전트를 위한 거버넌스 런타임을 더하세요.'], + positioningLink: '실행 가능한 비즈니스 온톨로지란', positioningCopy: '엔터프라이즈 AI에 필요한 것은 또 하나의 재구축 프로젝트도, 검토하기 어려운 생성 코드 더미도 아닙니다. 에이전트가 작성하고 사람이 검토하며 런타임이 기존 시스템, 새 애플리케이션, AI 에이전트 전반에서 거버넌스를 유지하는 하나의 정의입니다. 객체와 필드, 관계, 작업, 권한, 플로, 그리고 에이전트와 도구 정의가 그 정의 — 당신의 비즈니스 온톨로지입니다. 열려 있고, 버전 관리되며, 당신의 것이지, 남의 플랫폼에 갇힌 자산이 아닙니다.', capabilitiesKicker: '플랫폼 기능', capabilitiesTitle: ['빈 코드가 아니라,', '업무 구조에서 시작합니다'], diff --git a/src/lib/i18n.ts b/src/lib/i18n.ts index 14948c5..9ad777e 100644 --- a/src/lib/i18n.ts +++ b/src/lib/i18n.ts @@ -99,6 +99,8 @@ interface Strings { platform: string; aiBuildAsk: string; whyObjectOs: string; + /** The positioning pillar, /[lang]/ontology/ — first entry under Product → Evaluate. */ + ontology: string; dataModeling: string; appInterfaces: string; analytics: string; @@ -171,6 +173,7 @@ const en: Strings = { platform: 'Platform overview', aiBuildAsk: 'AI Build & Ask', whyObjectOs: 'Why ObjectOS', + ontology: 'Ontology', dataModeling: 'Data modeling', appInterfaces: 'App interfaces', analytics: 'Analytics & reporting', @@ -231,6 +234,7 @@ const zhHans: Strings = { platform: '平台总览', aiBuildAsk: 'AI Build & Ask', whyObjectOs: '为什么选 ObjectOS', + ontology: '本体', dataModeling: '数据建模', appInterfaces: '应用界面', analytics: '报表与分析', @@ -291,6 +295,7 @@ const ja: Strings = { platform: 'プラットフォーム概要', aiBuildAsk: 'AI Build & Ask', whyObjectOs: 'ObjectOS を選ぶ理由', + ontology: 'オントロジー', dataModeling: 'データモデリング', appInterfaces: 'アプリ画面', analytics: 'レポートと分析', @@ -351,6 +356,7 @@ const de: Strings = { platform: 'Plattform-Überblick', aiBuildAsk: 'AI Build & Ask', whyObjectOs: 'Warum ObjectOS', + ontology: 'Ontologie', dataModeling: 'Datenmodellierung', appInterfaces: 'App-Oberflächen', analytics: 'Analysen & Berichte', @@ -411,6 +417,7 @@ const es: Strings = { platform: 'Resumen de plataforma', aiBuildAsk: 'AI Build & Ask', whyObjectOs: 'Por qué ObjectOS', + ontology: 'Ontología', dataModeling: 'Modelado de datos', appInterfaces: 'Interfaces de la app', analytics: 'Analítica e informes', @@ -471,6 +478,7 @@ const fr: Strings = { platform: 'Aperçu de la plateforme', aiBuildAsk: 'AI Build & Ask', whyObjectOs: 'Pourquoi ObjectOS', + ontology: 'Ontologie', dataModeling: 'Modélisation des données', appInterfaces: 'Interfaces applicatives', analytics: 'Analytique et rapports', @@ -531,6 +539,7 @@ const ko: Strings = { platform: '플랫폼 개요', aiBuildAsk: 'AI Build & Ask', whyObjectOs: 'ObjectOS를 선택하는 이유', + ontology: '온톨로지', dataModeling: '데이터 모델링', appInterfaces: '앱 화면', analytics: '분석과 리포트', @@ -592,6 +601,7 @@ const toHant = (s: Strings): Strings => ({ platform: s2t(s.siteNav.platform), aiBuildAsk: s2t(s.siteNav.aiBuildAsk), whyObjectOs: s2t(s.siteNav.whyObjectOs), + ontology: s2t(s.siteNav.ontology), dataModeling: s2t(s.siteNav.dataModeling), appInterfaces: s2t(s.siteNav.appInterfaces), analytics: s2t(s.siteNav.analytics),