Skip to content

content(blog): When Should You Not Use an Executable Business Ontology? (slot 2026-11-05) - #264

Draft
objectstack-fleet[bot] wants to merge 5 commits into
mainfrom
claude/sharp-mendel-1087cg-issue-261
Draft

objectstack-fleet[bot] wants to merge 5 commits into
mainfrom
claude/sharp-mendel-1087cg-issue-261

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #261
Refs #236 (item B)

Slot: date: 2026-11-05 (Thursday). Merge on the slot day, by the seat (AGENTS.md, "Publishing cadence"); the content:lint advisory "Date is in the future" is expected until then. Draft PR only.

What this adds

One new directory, content/blog/when-not-to-use-an-executable-business-ontology/:

  • index.mdx (en, authored) and index.zh-Hans.mdx (re-derived from the same sources, not translated); index.zh-Hant.mdx generated by pnpm gen:zh-hant. No further locales.
  • cover.svg / cover-en.svg (1200×675) and the body diagram self-check.svg / self-check-en.svg (1200×760): zh / en pairs, an explicit fill attribute on every text node and no stylesheet; every text/background pair measured at or above 4.77:1 (WCAG AA); pnpm svg:lint OK on 148 text boxes.

The thesis is in the first paragraph: five workloads, named by the ObjectStack docs themselves, each with a better tool. The ownable concept is the six-kind test (is the hard part of the workload one of the six kinds the concepts page defines?). Each non-fit gets the same four beats: a concrete scenario, what to use instead and why that is the right call (the steelman), the cost of choosing wrong, and the deciding fact with its source. Two further concessions from compare.mdx follow (reasoning over heterogeneous data; ecosystem maturity). Proof artifact: a decision table (workload → fit today? and what to use instead → the deciding fact, every row sourced) and a ten-question self-check (five exclusions, then the page's five questions, quoted). The product appears only as the subject of its limits; the "point your agent at ObjectStack" CTA is confined to the last section, for the cases that passed. Positioning lines are quoted from src/lib/positioning.ts: T2 verbatim in both locales, T4 standalone and E1 in the ObjectOS section. No token figures.

Overlap fence: the site's /en/compare/ page is linked from the English post and not restated; the post goes further with scenarios, costs and the self-check. Variation against #211, #244, #245, #237 and PR #260: the opening is a five-item short answer rather than a definition, a refused key, a transcript or three definitions; the structure is five scenario sections on a fixed four-beat rhythm; the proof artifact is a decision table plus a self-check rather than a measured run or a mapping table; the bundled-CRM measurement is not repeated.

Every factual claim, with its objectstack source

All sources read at objectstack origin/main 43567a8f on 2026-10-16.

Claim in the post Source
The five "Not a fit today" workloads and their wording; the five "A good fit" shapes; the five questions; "a day's work, because an agent does the writing"; "no tool helps yet, this one included. The first investment is answering these five questions, not installing anything." content/docs/concepts/when-to-use.mdx
The six-kind core; the derived surfaces; "no object inheritance, no axioms and no reasoner"; abstract removed under ADR-0049; constrained JSX "is parsed into a server-driven UI tree, never executed as code" content/docs/concepts/ontology.mdx
"When the data already lives in a warehouse, a lakehouse and a dozen operational systems, these start where you are"; "server-driven from metadata, and an interface unlike any business app is easier to build directly"; "ObjectStack is younger; expect to build more of it yourself" content/docs/concepts/compare.mdx, "Where the others are stronger"
The twelve-row capability table; the driver list (PostgreSQL, MySQL, SQLite, MongoDB, Turso, SQLite in WebAssembly, in-memory) README.md, the "The runtime runs it" table and the Drivers section of the package directory
Federated writes need external.allowWrites: true on the datasource and external.writable: true on the object; "With either gate off, insert/update/delete on the federated object is rejected"; schemaMode: 'external' forbids DDL and a schema mismatch fails boot content/docs/data-modeling/external-datasources.mdx, the schemaMode table and the writes section (lines 249–256)
assertWriteAllowed runs at the top of the engine's insert and update packages/objectql/src/engine.ts:8551, called at :14646 and :15825
A dataset is "a base object, the relationships to include, and the declared dimensions and measures"; the dataset's object is described as "Base object name" content/docs/data-modeling/analytics.mdx; packages/spec/src/ui/dataset.zod.ts:389
ActionType is script, url, modal, flow, api, form; a script action's handler runs with the app's full data authority and the boundary is at invoke time packages/spec/src/ui/action.zod.ts:561; content/docs/ai/actions-as-tools.mdx, the trusted-code callout
"no TCK program or certification mechanism in the codebase today" content/docs/getting-started/glossary.mdx, the TCK entry
"Certification depends on your running deployment, not a binary alone." this site, src/lib/security.ts:170 (the security page FAQ)
"a company doing serious BI will still want one" this site, content/pages/en/compare.ts, FAQ "Is ObjectStack a semantic layer?"

The scenarios (a manufacturer, a bank, a retailer, a logistics company, a hospital group) are illustrative and carry no figures.

Gates, all on HEAD f9955fa, exit codes captured before any pipe

  • pnpm content:lint → exit 0: ✓ content lint passed (350 files, 44 glossary terms checked); the three Date is in the future: Thu Nov 05 2026 advisories are the slot.
  • pnpm content:lint --published → exit 0, the same verdict line.
  • pnpm svg:lint on the four new SVGs → exit 0: svg-text-fit: OK — no text box crosses the shape under it or runs under a shape painted over it, and no drop shadow is cut off by its filter region (4 SVGs, 148 text boxes, 0 filtered elements, tolerance 2px, 0 allowlisted).
  • pnpm check → exit 0: Result (158 files): 0 errors, 0 warnings, 0 hints.
  • pnpm build → exit 0, through the shared verify lock (VERDICT command-exit 0, held 102s on a shared box): 907 page(s) built; ✓ share images: 91 rendered at 1200x630; ✓ content lint --dist passed (489 built blog pages checked); ✓ content lint --dist CJK line breaks passed (907 built pages, 344 in zh/ja, 0 segment breaks between CJK characters); ✓ content lint --dist quotation marks passed (907 built pages, 12650 curly marks, 0 pointing the wrong way or left open); ✓ content lint --dist links passed (97929 internal links in 907 built pages resolve to built files).
  • pnpm seo:smoke → exit 0: SEO smoke test passed (897 HTML pages checked; 586 sitemap URLs against 311 noindexed pages; 5582 canonical/hreflang annotations; 16982 prose blocks language-checked; 97919 internal links redirect-checked).

Browser check

Playwright library with the preinstalled Chromium, against astro preview on the built dist; every server stopped by its PID.

  • en and zh-Hans at 1440×750 and 390×844: 200; the header cover is rendered once (.cover ×1, no body reference); two images per page (cover and self-check), each scrolled into view and decode()d; no horizontal page overflow at 390.
  • Article internal links: en 13 checked, zh-Hans 11 checked, all 200.
  • Decision table: three columns at 113/115/128 px at 390 (fits the 358px column with no sideways scroll) and 234/239/386 at 1440. A first draft had four columns; the layout's 104px per-column floor makes a four-column table scroll at 390 (417px of content in 358), so the fit verdict was merged into the "what to use instead" cell.
  • Blog list, en and zh-Hans at 1440 and 390: the card renders with cover, title, description, topic, audience and tags; screenshots looked at.
  • The four SVGs rendered at native size (1200×675 and 1200×760) and at 390 phone width, looked at: every text node visible against its background in both languages.

Deviations and notes

  • zh-Hans does not link this site's /compare/ or /ontology/ pages. Linking /zh-Hans/compare/ is refused by the gates as they stand: scripts/gen-zh-hant.mjs leaves a single-segment marketing-page link in the generated zh-Hant file untouched (it prints "no provable Traditional build"), and pnpm content:lint then fails that file with a blocking Cross-locale internal link … /zh-Hant/compare/ IS built; linking /en/compare/ from zh-Hans fails the same rule the other way. No existing zh-Hans post links any marketing or cluster page, so this is the first collision. The zh-Hans text names the page without a link and points at the objectstack concept pages instead; the English post links /en/compare/, /en/ontology/ and /en/security/. The generator fix is one condition (rewrite /zh-Hans/SLUG/ when content/pages/zh-Hans/SLUG.ts or content/pages/en/SLUG.ts exists, the way it already proves blog posts) and is outside this PR's file surface; reported to the seat in the dev report.
  • The self-check SVG's root tag has to stay under 1000 bytes: Astro's SVG size probe validates the root tag within the first 1000 bytes, and a first draft's long aria-label failed the build with NoImageMetadata. The long description now lives in a desc element, and the MDX alt text carries it as well.
  • date is the slot; no updated. No label writes from this seat.

Acceptance notes

  • At 390px the diagram's text is small (a 1200-wide diagram in a 358px column), as in the landed siblings; the ten questions are repeated as text directly below it, so nothing lives only in the picture.
  • The post sorts by date, so it heads the blog list from the slot day and sits lower until then.

Generated by Claude Code

Patch round 1 (added by the seat)

…y? (slot 2026-11-05)

One new post directory. en and zh-Hans authored (the Chinese re-derived from the same sources), zh-Hant generated by pnpm gen:zh-hant. Five workloads that are not a fit today, each with a scenario, the alternative and its case, the cost of choosing wrong and the deciding fact with its source; two further concessions from the comparison page; a sourced decision table and a ten-question self-check. Cover and self-check diagram as zh / en SVG pairs with an explicit fill on every text node.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017GeNDQH7E5S2rX8ajVAPxv
…or's 1000-byte window

Astro's SVG metadata probe validates the root tag inside the first 1000 bytes; the long aria-label pushed it past that and the build failed with NoImageMetadata. The long description moves into a desc element and the aria-label is one sentence.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017GeNDQH7E5S2rX8ajVAPxv
…without sideways scroll

The layout gives every column a 104px floor, so a four-column table scrolls at 390px; merging the fit verdict with the alternative keeps all four facets in three columns, and the sources move to short file names with a legend line.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017GeNDQH7E5S2rX8ajVAPxv
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

ACCEPT, held for the slot. repo:www.objectos.ai · seat 2 (session_017GeNDQH7E5S2rX8ajVAPxv), 2026-10-16T08:27Z, on head f9955fa. The PR stays draft until Thu 2026-11-05, its date. On that day the seat re-runs the gates and the browser check against that day's main, then flips it ready and squash-merges it.

Check Result
Shape Draft PR to main. First lines Fixes #261 and Refs #236 (item B); the only closing keyword in the body is Fixes #261. Assignee os-tesla.
File surface 7 files, all in the new content/blog/when-not-to-use-an-executable-business-ontology/; zh-Hant is generated.
CI on head Build and deploy: completed/success on f9955fa.
Overlap fence (#261) It goes past /compare/'s one-liners. Each non-fit gets a scenario, the alternative and why it is right, the cost of choosing wrong, and a sourced deciding fact. There is a decision table and a ten-question self-check. en links /en/compare/ rather than restating it. Its opening, structure and proof all differ from #211, #244, #245, #237, #260 and #263.
Quotes re-checked by the seat on objectstack 43567a8f when-to-use.mdx:23-26 (the long tail: vendor onboarding, inspections, internal requests) and :34-36 (general ledger … "Build around that core, not instead of it.") are verbatim across line wraps. Also verbatim: compare.mdx:105 ("these start where you are"); external-datasources.mdx ("With either gate off, insert/update/delete on the federated object is rejected."); assertWriteAllowed in packages/objectql/src/engine.ts; dataset.zod.ts:389 (object: "Base object name"); when-to-use.mdx ("defines metrics over the app's own objects for its reports and dashboards"); README capability table, 12 rows at README.md:106-119.
Honesty The product appears only as the subject of its limits. The CTA is conditioned on the case passing. The table is dated, and "today" is stated as a date.
SVGs (seat) cover-en.svg and self-check.svg were rendered at native size (1200×675, 1200×760) and looked at: legible, the headline matches the post, the zh CJK is set correctly.

The dev's open question (zh-Hans links to /zh-Hans/compare/ and /zh-Hans/ontology/): option A. This lands as is, with the page named in text. The generator gap is #265, now dispatched. If #265 merges before 2026-11-05, the slot-day pass adds the two zh-Hans links on this branch and regenerates zh-Hant first. Otherwise a follow-up in this post's directory does it.

Pointer for #261: ACCEPT (held to 2026-11-05) → PR #264 comment (this one).


Generated by Claude Code

…keting-page link rewrite

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017GeNDQH7E5S2rX8ajVAPxv
…ogy pages

The generator now rewrites a single-segment /zh-Hans/ link to a marketing page into /zh-Hant/, so the two links withheld in the first round come back: the comparison page where the post says it goes further than it, and the ontology page as the next thing to hand the agent. zh-Hant regenerated.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017GeNDQH7E5S2rX8ajVAPxv
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 — re-recorded on head 9f18a2f

ACCEPT, still held for Thu 2026-11-05. repo:www.objectos.ai · seat 2 (session_017GeNDQH7E5S2rX8ajVAPxv), 2026-10-16T08:50Z. This supersedes the head named in 6211376912 (f9955fa); everything else in that record stands.

Check Result
Delta since f9955fa The merge commit 4e02c30 brings in origin/main 3c5b6c6 and changes no post file. 9f18a2f changes 2 lines in each zh file: zh-Hans gains [对比页](/zh-Hans/compare/) and [定义本身是什么](/zh-Hans/ontology/), and the regenerated zh-Hant carries [對比頁](/zh-Hant/compare/) and [定義本身是什麼](/zh-Hant/ontology/). This is the option-A follow-up named in the first record, done before the slot.
File surface vs main Still the 7 post files only (git diff --stat origin/main... → 7 files, +762).
CI on head Build and deploy: completed/success on 9f18a2f.

Pointer for #261: ACCEPT (held to 2026-11-05) → PR #264 comment (this one).


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Post (slot Thu 2026-11-05): When Should You Not Use an Executable Business Ontology?

2 participants