Skip to content

content(blog): what makes a business app AI-writable — post 3 of the positioning wave (slot 2026-10-22) - #245

Open
objectstack-fleet[bot] wants to merge 4 commits into
mainfrom
claude/pm-dispatch-objectos-ju9td1-issue-229
Open

objectstack-fleet[bot] wants to merge 4 commits into
mainfrom
claude/pm-dispatch-objectos-ju9td1-issue-229

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #229

Post 3 of the positioning wave, slot Thursday 2026-10-22. Merge on the slot day only: the charter says "merge time is publish time".

Re-slot. The post was slotted for Thu 10-15. The wave slipped one week: post 1 landed on 10-15 as #212, and post 2 moved to 10-20. Commit 3142a3f moves date to 2026-10-22 in all four locale files, and moves the back-linked posts' updated to 2026-10-22T10:00:00+08:00, 9 lines. 13 lines change. Gates on that commit all exit 0: content:lint, check, build (892 pages, tree clean) and seo:smoke.

Branch. This branch holds three commits from the staged lin/issue-229, replayed onto main @ 1174309. The replay is patch-equal to lin/post-base..lin/issue-229, with byte-identical diffs. Head 8b27e08.

Known follow-up. A seat fixup re-dates the stack's updated lines to 2026-10-15 and lands later today. This PR sets the same lines to 10-22, so the branch then takes main with a merge commit that keeps 10-22.

What this PR adds

One new post, content/blog/what-makes-a-business-app-ai-writable/, in en, zh-Hans, zh-Hant (generated by pnpm gen:zh-hant) and ja, with its cover and two diagrams in the English and Chinese text sets:

  • Title: What Makes a Business App AI-Writable? Typed, Validated, Reviewed, Governed (en, as ruled; ja tightened to 87 columns, query shape kept).
  • date: 2026-10-22, no updated, topic: ai-agents, audience: developer, tags AI agents / AI-writable (translated per locale).
  • Angle: the four gates from objectstack README.md:166-176 ("Why the mistakes don't ship"), quoted whole, and what has to be true of a target format before an agent can write into it and a human can sign off.
  • Ownable concept + number (rule 1): the mistake ledger — for a target format, each mistake class an agent can make, the gate that catches it, and what would have shipped otherwise; grounded in 49 author-time rules at 17.7.0 and a 127-line, 11-file app.
  • Promise: AI-writable. CTA: the README's agent path (npm create objectstack@latest my-app && cd my-app, point your coding agent at it, npx os dev --ui). os start appears 0 times.
  • Canonical strings: T4 in its T4_STANDALONE form and E1, verbatim from src/lib/positioning.ts per locale; ObjectOS appears nowhere else.
  • Honesty (rule 7): steelmen for vibe-coded apps and hand-written code; a "What the gates do not catch" section (business-logic correctness, requirements the reviewer misses, novel logic, and the two gates this run did not exercise).
  • Cross-links: to how-to-point-your-agent-at-objectstack (the corrective error post) and give-your-agent-rules-for-governable-apps.

The proof artifact is real (rule 5)

Run in this container on Node 22 against the published packages, not reconstructed:

  • npm create objectstack@latest support-desk → create-objectstack 17.7.0; @objectstack/cli 17.7.0, @objectstack/spec 17.7.0, @objectstack/lint 17.7.0.
  • The README's support desk (ticket object, Resolve action, "Open tickets" view, Support nav group, one permission set): 127 insertions across 11 files.
  • Clean run: Running author-time rules (49) → ✓ Validation passed (327ms). The count equals AUTHORING_RULES.length in the installed @objectstack/lint 17.7.0 (verified by importing the package).
  • Three deliberate mistakes, one per README class: bare status in the Resolve predicate, rowActions: ['resolve'] naming no action, sharingModel deleted. npm run validate → ✗ Author-time rules failed (3 issues) with rules expression-invalid, action-name-undefined, security-owd-unset, exit 1. Quoted verbatim in the post.
  • Typed gate, separately: required: 'yes' → tsc TS2322: Type 'string' is not assignable to type 'boolean | undefined', exit 2.
  • Fixed run: ✓ Validation passed (240ms).
  • The post also quotes a real advisory from the clean run (allowRead without a readScope) as the gate surfacing a half-decision.

"41 rules" was not reused; the post states the earlier 17.2.0 measurement as history and the 17.7.0 count as the current one.

Also in this PR (back-links; updated = publish day; date and slug untouched)

  • give-your-agent-rules-for-governable-apps: one sentence appended to point 3 ("Validatable at generation time") in all seven authored locales, linking the new post (de/es/fr/ko link the English page and say so); zh-Hant regenerated; updated: 2026-10-06T10:00:00+08:00 → 2026-10-15T10:00:00+08:00, the day the link goes public (seat ruling on the sibling card).
  • how-to-point-your-agent-at-objectstack (en-only): one sentence after "That message is the product." linking the new post; updated: 2026-10-22T10:00:00+08:00 inserted (the post had none).

Two commits on the branch: 7a790b4 (the post, assets and back-links) and 7c6a8f8 (the updated values moved to the publish day).

Gates on 7c6a8f8 (all exit 0)

  • pnpm content:lint: ✓ content lint passed (351 files, 44 glossary terms checked). Advisories only: "Date is in the future: Thu Oct 15 2026" ×4 on the new post (expected for a slot-day post); "Updated is in the future: 2026-10-15" ×9 on the two back-linked posts (expected: the value is the slot day); snippet-width warnings on the en (75 columns, the ruled title), zh-Hans/zh-Hant (64) and ja (87) titles.
  • pnpm content:lint --published: same verdict line.
  • pnpm check: Result (152 files): 0 errors.
  • pnpm build: zh-Hant: generated 48, kept 0 hand-maintained; 892 page(s) built in 77.50s; content lint --dist passed (490 built blog pages); CJK line breaks passed; quotation marks passed (12464 curly marks, 0 wrong); links passed (94590 internal links); tree clean after the build's own gen:zh-hant.
  • pnpm seo:smoke: SEO smoke test passed (882 HTML pages checked; 581 sitemap URLs against 301 noindexed pages; 5516 canonical/hreflang annotations).
  • pnpm svg:lint: svg-text-fit: OK (124 SVGs, 2705 text boxes, 1 allowlisted).

Browser check (AGENTS.md, six viewports, light and dark)

On 7a790b4 (the content head; 7c6a8f8 changes only nine frontmatter updated values): dist/ served by astro preview, Playwright Chromium: the article in en, zh-Hans and ja × 1366×625, 1440×750, 1512×830, 1920×945, 390×844, 360×800 × light and dark (36 pairs), the en blog list at the six viewports × light and dark (12), and each of the six served SVGs on its own at native size — 54/54 assertions: HTTP 200, scrollWidth equals the viewport, no element past the viewport outside a scroll container, the cover renders, both body diagrams render, no repeated image, the transcript and the CTA present, the post first in Latest, the theme applied. Native-size contrast check on the six SVGs: lowest 4.72:1, no text outside its box, no overlaps.

On 7c6a8f8: the two back-linked posts in en at 1440×750 and 390×844 — 4/4: HTTP 200, no overflow, the new link present, the meta row renders "Updated Oct 15, 2026", article:modified_time is 2026-10-15T02:00:00.000Z; the back-link paragraphs were looked at at both widths and read naturally.

Two defects found by looking and fixed before this head: the English gates diagram's caption crossed a dashed arrow (a stroke, invisible to the fill-based gate) — caption shortened; the four-column ledger table clipped its last column inside the scroll wrapper at 390 — merged to three columns, which now fit 360.

Acceptance notes

  • Q1 = A (seat ruling): how-to-point-your-agent-at-objectstack keeps its 17.2.0 figures (41 rules, an 11-skill bundle) as a dated measurement; it is labelled "Verified against 17.2.0", and a refresh needs a full re-run of that post's transcript, which is not this card's job. The new post states the 17.2.0 count as history next to the 17.7.0 count.
  • Pre-existing and site-wide, not this post's: body diagrams render at ~328px on phones (the Phone-width reading of blog tables and diagrams: table rows run up to 2,394px on one line, and diagram text renders at 3–4px #213 finding); code spans inside table cells break mid-token under the table wrap rule at 360/390.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr

🤖 Generated with Claude Code

https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr

…, with a real os validate transcript (slot 2026-10-15)

Post 3 of the positioning wave. One new post, content/blog/what-makes-a-business-app-ai-writable/,
in en, zh-Hans, zh-Hant (generated by pnpm gen:zh-hant) and ja, with its cover and two diagrams
in the English and Chinese text sets. The proof artifact is a real run of npm run validate on a
scaffolded support desk at ObjectStack 17.7.0: three deliberate mistakes of the three classes the
README names (a bare CEL predicate, a dangling row-action binding, a missing sharingModel), the
49-rule gate refusing each with a located, corrective message, and a clean pass after the fix.
Canonical T4 (standalone) and E1 are quoted verbatim from src/lib/positioning.ts per locale.

Back-links added where they read naturally, with updated set and date untouched:
- give-your-agent-rules-for-governable-apps (all 7 authored locales; zh-Hant regenerated)
- how-to-point-your-agent-at-objectstack (en only, as published)

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
…26-10-15)

The seat's ruling on the sibling card: `updated` records the day the change goes
public, not the edit day. give-your-agent-rules-for-governable-apps (seven authored
locales, zh-Hant regenerated) and how-to-point-your-agent-at-objectstack now carry
updated: 2026-10-15T10:00:00+08:00, the slot of the post they link to. The new post
keeps no updated; no date or slug changes.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
The positioning wave slipped by one week: post 1 missed its Thu 2026-10-08
slot and is re-slotted to Thu 2026-10-15, post 2 moves to Tue 2026-10-20.
Under the Publishing cadence rules (two slots a week, one post per slot, an
agent's date is its planned slot, never two posts on one day) post 3 can no
longer hold Thu 2026-10-15 and moves to the next Thursday slot, 2026-10-22.
The post is unpublished, so its date may still change.

- what-makes-a-business-app-ai-writable: date 2026-10-15 -> 2026-10-22 in en,
  ja and zh-Hans; zh-Hant regenerated with pnpm gen:zh-hant.
- give-your-agent-rules-for-governable-apps (seven authored locales, zh-Hant
  regenerated) and how-to-point-your-agent-at-objectstack: updated
  2026-10-15T10:00:00+08:00 -> 2026-10-22T10:00:00+08:00, so the back-link
  revision still carries the day the linked post goes public.

No other changes: no slug, title, prose, or asset edits.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
main (#254) moved the sweep's updated lines to 2026-10-15, the day the
sweep went live. This post sets the same lines on its back-linked
posts to its own slot day, which is later, so this side wins. main changed
nothing else in these files since the branch point.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
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-10-15): What Makes a Business App AI-Writable? Typed, Validated, Reviewed, Governed

2 participants