Skip to content

content(blog): What Do AI Models Lack in the Enterprise? A World, Hands and a Fence (slot 2026-11-03) - #260

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

objectstack-fleet[bot] wants to merge 3 commits into
mainfrom
claude/sharp-mendel-1087cg-issue-236-a

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Refs #236 (item A)

Slot: date: 2026-11-03 (Tuesday) — seat 2's first slot after the positioning wave; merge on the slot day, by the seat (AGENTS.md, "Publishing cadence"). The "Date is in the future" advisory from content:lint is expected until then. Items B, C and D stay open on #236.

What this adds

One new post directory, content/blog/what-do-ai-models-lack-in-the-enterprise/:

  • index.mdx (en, authored) and index.zh-Hans.mdx (re-derived, not translated); index.zh-Hant.mdx generated by pnpm gen:zh-hant. No further locales this round.
  • cover.svg / cover-en.svg and the body diagram three-supplies.svg / three-supplies-en.svg — zh / en pairs, every text node carries a class whose rule sets fill, all 24 text/background pairs ≥ 4.77:1 (WCAG AA), rendered at native size and looked at.

The concept is the front page's "What the model lacks is not intelligence: a world, hands, and a fence." The post opens with the three definitions, states the checkable claim (an executable business ontology supplies all three from one artifact), gives the proof artifact — a table mapping each supply to the runtime mechanism with file:line — then one number measured on the bundled CRM (1,844 lines / 30 files; 78 lines of fence; 0 lines of plumbing), the RAG + function-calling + policy-layer stack steelmanned with a five-row comparison, five limits, the positioning paragraph quoted from positioning.ts, and the "point your agent at it" CTA. Frontmatter: topic: ai-agents, audience: it, description 223 / 90 chars.

Writing rule 9 against the siblings: no story opening (#244, #245), no two-user run (#237), no definition/removal test (#211); the proof artifacts here are the mechanism map and a line-count split, neither used by the other four. Post 1's removal test and #237's run are linked, not repeated. Internal links go only to posts on main today (objectos-action-tools, objectos-agent-permission-boundaries, the definition post, the point-your-agent how-to), so every one of them is a built page for content-lint --dist.

Every factual claim, with its objectstack source

All sources are objectstack-ai/objectstack at origin/main = 1ecb08a1 (read 2026-10-16), unless a sibling commit is named. Line numbers are of that commit.

# Claim in the post Source
1 The three "00 · The idea" sentences, quoted verbatim apps/docs/app/[lang]/page.tsx:127-131 (identical text at 712361b7, the commit the card cites)
2 T1/T2/T3 and the README's one-line definition; T4 (standalone form) and E1 quoted, never paraphrased README.md:7-16, README.md:28-32; www.objectos.ai src/lib/positioning.ts — a script compared en T2/T4/E1 and zh-Hans t2/t4/e1 against the module: all six byte-exact
3 The six-kind core (objects and fields, relations, actions, permissions, flows, agent and tool definitions) content/docs/concepts/ontology.mdx:16-25; README.md:81-82
4 Pipeline objectstack.config.ts -> objectstack.json -> runtime -> database · REST/realtime API · UI · MCP server; the runtime "derives" and "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." content/docs/concepts/ontology.mdx:64-73
5 "The ontology is the definition of your business that the runtime executes: authored as typed metadata in objectstack.config.ts, compiled into the objectstack.json artifact." content/docs/concepts/ontology.mdx:14-15
6 Projections (views, dashboards, apps, translations) are not part of the ontology; the core bounds what an agent must hold content/docs/concepts/ontology.mdx:34-40 (the removal test itself is post 1, linked, not repeated)
7 MCP server at /api/v1/mcp, on by default; "Objects are tools, actions are tools, permissions decide what an agent may call, and audit records what it did"; objects exposed automatically, actions opt in with ai: { exposed: true }; same permissions and RLS as a human README.md:161-177 (quote at 163-164); content/docs/ai/connect-mcp.mdx:7-11, :240-248
8 "Twelve tools, generated from your metadata" and their names content/docs/ai/connect-mcp.mdx:223-233
9 ai.exposed is a schema field defaulting to false; description ≥ 40 chars required when exposed; the "deliberate governance gate … must never be silently armed" comment packages/spec/src/ui/action.zod.ts:764, :771, :1966-1972 (refinement); comment at :707-719
10 A real opt-in: CompleteTaskAction with ai: { exposed: true, description: … } (UI-only keys trimmed in the post) examples/app-todo/src/actions/task.actions.ts:6-20
11 The bundled CRM's one action, Convert Lead, is type: 'flow' with no ai block, so list_actions answers empty for it examples/app-crm/src/actions/convert-lead.action.ts:9-32; examples/app-crm/src/actions/index.ts exports only it; grep -rn exposed examples/app-crm/src → no match
12 Security is middleware registered on the ObjectQL engine (ql.registerMiddleware(...)); the security service is registered by the same plugin packages/plugins/plugin-security/src/security-plugin.ts:2293-2294; :2278
13 MCP tools never touch the data engine directly; "all reads/writes go through an injected McpDataBridge that the host wires to the SAME permission/RLS-enforcing path the REST API uses. This module owns the tool shape; the bridge owns execution + security." packages/mcp/src/mcp-http-tools.ts:4-11
14 An action body "executes as TRUSTED app code once invoked", so the bridge "gates at invoke time: ai.exposed (the author's explicit AI opt-in, ADR-0011) + the ADR-0066 D4 capability gate"; runAction enforces requiredPermissions as the caller and loads the subject record under RLS packages/mcp/src/mcp-http-tools.ts:1128-1133; :240-245
15 run_action's own description: the action body "runs as trusted application code with the app's full data authority"; requiresConfirmation refuses without confirm: true packages/mcp/src/mcp-http-tools.ts:1182-1188
16 Audit rows are written by engine hooks on afterInsert / afterUpdate / afterDelete packages/plugins/plugin-audit/src/audit-writers.ts:2180-2185 (and :1757)
17 Read audit is a per-object opt-in for record-detail views; list and search results are not audited packages/plugins/plugin-audit/src/audit-plugin.ts:38-49
18 "Access-narrowing answers fail CLOSED … a resolution failure returns a DENY filter (zero rows), never undefined" packages/spec/src/contracts/security-service.ts:28-31
19 "REST /actions is NOT ai.exposed-gated and sits OUTSIDE this gate, so a human in front of that route is still yours to arrange" packages/spec/src/ai/tool.zod.ts:95-98
20 Fourth gate: "The runtime enforces permissions and audit on every call, so even a wrong app stays inside the fence"; os validate rejects "missing security posture" README.md:184-189; :187
21 Federating an external datasource is read-only by default and early README.md:85-87; content/docs/concepts/ontology.mdx:49-53
22 The scaffolder writes AGENTS.md and installs the skills bundle; npm create objectstack@latest my-app; npx os dev --ui README.md:41-47, :60-64; content/docs/concepts/ontology.mdx:85-91
23 OAuth as yourself or an API key; the stdio key is re-checked on every call content/docs/ai/connect-mcp.mdx:22-24, :202-209
24 Measurement: find examples/app-crm/src -name '*.ts' -not -name '*.test.ts' | xargs cat | wc -l → 1844, over 30 files; per directory: objects/ 486 lines / 7 files (six objects), actions/ 35 + flows/ 205 = 240, security/ 88 lines / 2 files of which sales-positions.ts is 78 (two permission sets crm_sales_user and guest_portal, three positions sales_rep, sales_manager, finance_approver); the remainder is views 292, dashboards 140, apps 40, pages 46, translations 241, datasets 38, datasources 52, data 157, hooks 24 the README's own command (README.md:202-204) run on git archive 1ecb08a1 examples/app-crm/src; examples/app-crm/src/security/sales-positions.ts
25 Zero lines of tool registration, authorization middleware or audit code in the CRM: grep -rn -i 'registerTool|middleware|authoriz|checkPermission|audit' examples/app-crm/src → 2 hits, both inside comment blocks examples/app-crm/src/security/sales-positions.ts:10 (" * authorization resolver reads."), examples/app-crm/src/views/lead.view.ts:103 (" * authorizes the write.")
26 Each CRM object declares sharingModel (five public_read_write, the line item controlled_by_parent), from which the runtime computes the row filter examples/app-crm/src/objects/*.object.ts (account:11, activity:12, contact:12, lead:12, opportunity:12, opportunity-line-item:21)

PM mechanism assumption — measured

The card's mapping holds, with one bound worth stating in the post (and stated): world = objects, fields, relations (claims 3–5); hands = objects as tools automatically and actions as tools on the author's ai.exposed opt-in (claims 7–11); fence = permissions / RLS / FLS / sharing enforced as engine middleware every path shares, plus audit hooks (claims 12–18). The bound: the ai.exposed opt-in guards the MCP run_action door; REST /actions is outside that gate (claim 19), and read audit is narrower than write audit (claim 17). Both are in the post's "What this does not solve".

Gates (local, at 2bb6ff4; exit codes captured before any pipe)

Heavy gates ran under the shared verify lock (OS_VERIFY_LOCK_SLOT=www-236a), the build and check joined with &&; the lock's VERDICT batch-last-exit 0, held 1m56s on a shared box in the first run.

Gate Exit Verdict line
pnpm content:lint 0 ✓ content lint passed (350 files, 44 glossary terms checked) — advisories only: title 68 cols, description 223 cols, "Date is in the future" (expected)
pnpm content:lint --published (inside pnpm build) 0 ✓ content lint passed (350 files, 44 glossary terms checked)
svg-text-fit (inside pnpm build; also run alone on the four new SVGs) 0 svg-text-fit: OK — … (122 SVGs, 2587 text boxes, 183 filtered elements, tolerance 2px, 1 allowlisted); alone: (4 SVGs, 114 text boxes, 0 filtered elements, …, 0 allowlisted)
pnpm build (astro build + og-images + content-lint --dist) 0 [build] Complete! · ✓ share images: 91 rendered at 1200x630 … no uncovered glyph · ✓ content lint --dist passed (489 built blog pages checked) · ✓ content lint --dist CJK line breaks passed (891 built pages, …, 0 segment breaks …) · ✓ content lint --dist quotation marks passed (891 built pages, 12441 curly marks, 0 pointing the wrong way or left open …) · ✓ content lint --dist links passed (94461 internal links in 891 built pages resolve to built files)
pnpm check 0 Result (154 files): 0 errors, 0 warnings, 0 hints
pnpm seo:smoke 0 SEO smoke test passed (881 HTML pages checked; 580 sitemap URLs against 301 noindexed pages; 5508 canonical/hreflang annotations; 16524 prose blocks language-checked; 94451 internal links redirect-checked)
Browser check (Chromium at /opt/pw-browsers/chromium, Playwright library from /opt/node-tools, against astro preview of dist/) 0 BROWSER CHECK PASS: 67 checks, 0 failing — en, zh-Hans, zh-Hant at 1440×750 and 390×844: HTTP 200; img.cover = 1 and 0 cover references in the body; every image scrolled into view and decode()d; 56 / 55 / 55 internal links all 200; no horizontal page overflow; all three tables overflow-x: auto scroll containers (the mapping table fits at 390 after the 3-column revision); blog list en and zh-Hans at both widths shows the post first with its cover decoded

CI runs the same build on the pull; the check-runs on this PR are the record for it.

File surface

Exactly one new directory under content/blog/ (7 files); nothing else in the tree changed. git diff --stat 6ada491..2bb6ff4 = 7 files, all under content/blog/what-do-ai-models-lack-in-the-enterprise/.

Acceptance notes

  • The lock's first run sequenced build and check with ; and a final [ $B -eq 0 ] && [ $C -eq 0 ], so its verdict covered both anyway; the second run (this head) joined them with &&.
  • A sibling's astro preview on port 4338 was left untouched; mine ran on 4399 → 4401 → 4402 and each was stopped by its own PID.
  • Not filed (observation, no defect): content-lint's snippet-width advisory fires for every title over 60 columns, including post 1's 87; the title here is a query (rule 2) at 68.

Generated by Claude Code

…nds and a Fence" (slot 2026-11-03)

Post A of the second ontology wave: the front page's "a world, hands, and a
fence" line, mapped to the runtime mechanism that supplies each, with
file:line sources at objectstack 1ecb08a1, one measurement on the bundled
CRM (1,844 lines / 30 files; 78 lines of fence; 0 lines of plumbing), the
RAG + function calling + policy-layer alternative steelmanned, and the
limits. en and zh-Hans authored, zh-Hant generated; cover and diagram as
zh / -en SVG pairs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017GeNDQH7E5S2rX8ajVAPxv
…a directory legend, for phone-width reading

Co-Authored-By: Claude Fable 5.1 <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-16T07:28Z, on head 2bb6ff4. The PR stays draft until Tue 2026-11-03, 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 (cadence: merge time is publish time).

Check Result
Shape Draft PR to main. The first line is Refs #236 (item A), and the body has no closing keyword, as it should not: items B–D stay open. Assignee os-tesla.
File surface 7 files, all in the new content/blog/what-do-ai-models-lack-in-the-enterprise/. zh-Hant is generated. Nothing outside the claimed surface.
CI on head Build and deploy: completed/success on 2bb6ff4.
Writing rules The thesis lands in the first 100 words. The query title is 68 columns, so the width advisory fires; it is an advisory, not a gate. One minted concept (world / hands / fence) and one measured number (78 lines of fence). The alternative stack is steelmanned with a five-row table, five limits are stated, and the CTA is "point your agent at it". The proof is a sourced mapping table plus a directory measurement, so it does not repeat #229's os validate run or #237's two-user MCP run.
Facts re-checked by the seat on objectstack 1ecb08a1 Measurement: the README's own command (README.md:203) gives 30 files and 1,844 lines; src/security/sales-positions.ts is 78 lines. Quotes, verbatim: packages/spec/src/ai/tool.zod.ts:95-98 (REST /actions outside the ai.exposed gate), packages/spec/src/contracts/security-service.ts:28-31 (fail CLOSED), packages/mcp/src/mcp-http-tools.ts:1128-1133 (action body is TRUSTED code; invoke-time gate) and :1185 ("full data authority"), packages/plugins/plugin-audit/src/audit-plugin.ts:38-49 (read audit covers record-detail views only), content/docs/ai/connect-mcp.mdx:223 ("Twelve tools"), security-plugin.ts:2294 (ql.registerMiddleware). CRM actions carry no ai block. Quickstart commands appear in README.md:46,55,63.
Positioning T2, T4 and E1 are byte-exact from src/lib/positioning.ts. The dev checked this by script; the seat read the "Hosted" section.
SVGs (seat) cover-en.svg and three-supplies.svg were rendered at native size (1200×675, 1200×584) and looked at: legible, no clipping, no dark-on-dark. The zh diagram's CJK is set correctly.

Note for the slot-day check: objectstack's own docs still quote the CRM at 31 files / 1,929 lines (content/docs/concepts/metadata-driven.mdx:230-232; the essay's "31 files", content/blog/the-ontology-is-the-software.mdx:119). The CRM has since lost a file (9e9e6f97), so this post's 30 / 1,844 measured at 1ecb08a1 is the correct figure; the upstream docs are the stale side. On slot day the seat re-runs the README command, and if the number has moved again it updates the figure or dates it.

Pointer for #236: ACCEPT (item A, held to 2026-11-03) → PR #260 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.

2 participants