Skip to content

Commit f0bea00

Browse files
committed
feat(spec): extend the example type-check gate from skills/ to content/docs
check:skill-examples compiles the TypeScript in `skills/` against the built spec. It works — it caught the broken `defineTool` example when tool.requiresConfirmation was removed (#3715). But it only ever walked `skills/`: skills/ 9 files with ts blocks, 9 compiled content/docs/ 124 files with ts blocks, 0 compiled So the identical break in a docs page ships. Docs examples are copied verbatim by humans and AI exactly like skill examples; a gate covering a fraction of the surface it appears to cover reads as coverage. Generalises the walker to a SOURCE_ROOTS list and opts in the first batch: 164 docs blocks across 63 pages, taking the gate from 32 to 196 checked examples. content/docs/references/ is excluded — build-docs.ts regenerates it from the schemas, so it cannot drift independently. MARKER IS NOW PER-FORMAT. MDX has no HTML comments: `<!-- os:check -->` in a .mdx fails the fumadocs build outright ("Unexpected character `!`… to create a comment in MDX, use `{/* text */}`"). Verified by building the docs site — the first attempt failed on 60+ pages. skills/*.md keeps `<!-- os:check -->`; content/docs uses `{/* os:check */}`. Both spellings are recognised for ORPHAN detection, so a wrong-format marker fails loudly instead of silently checking nothing. Batch selection was measured, not guessed: marking all 780 docs blocks and compiling showed which are self-contained. Note a subtlety — blocks that "pass" in a 780-file program can be leaning on globals declared by OTHER blocks (a file with no import/export is a global script), so the set was converged by recompiling and dropping newly-failing blocks until green. 164 stand alone. The remaining ~600 are mostly fragments (a `columns: [...]` subtree), which the gate's opt-in design already anticipates; whether any are genuine rot is worth a follow-up pass now that the machinery reaches them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ajwvrmd1hDC9RBofYBhGuR
1 parent 4d00b13 commit f0bea00

64 files changed

Lines changed: 252 additions & 35 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

content/docs/ai/actions-as-tools.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ Add an optional `ai:` block to give the model a precise, LLM-facing description
7070
spec; `list_actions` surfaces `ai.description` to the model, falling back to the
7171
UI `label` when it is absent.
7272

73+
{/* os:check */}
7374
```typescript
7475
export const triageCaseAction = {
7576
name: 'triage_case',

content/docs/ai/agents.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ point at, and reach it through `@objectstack/mcp` (BYO-AI).
167167

168168
## Sales Assistant Agent
169169

170+
{/* os:check */}
170171
```typescript
171172
import { defineAgent } from '@objectstack/spec/ai';
172173

content/docs/api/environment-routing.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ depending on request context.
2424

2525
Enable scoped route registration in `objectstack.config.ts`:
2626

27+
{/* os:check */}
2728
```typescript
2829
import { defineStack } from '@objectstack/spec';
2930

content/docs/api/error-handling-client.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ This guide covers best practices for handling ObjectStack API errors in client a
1717

1818
Every error response from ObjectStack follows this shape:
1919

20+
{/* os:check */}
2021
```typescript
2122
interface ErrorResponse {
2223
success: false; // Always false for error responses
@@ -56,6 +57,7 @@ Error `code` values are lowercase snake_case (`validation_error`, `permission_de
5657

5758
Create a typed error parser to extract structured information from API responses:
5859

60+
{/* os:check */}
5961
```typescript
6062
import type { ErrorResponse } from '@objectstack/spec/api';
6163

content/docs/api/error-handling-server.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ lowercase snake_case members of `StandardErrorCode` (see
2323
`@objectstack/spec/api`), e.g. `validation_error`, `resource_conflict`,
2424
`permission_denied`.
2525

26+
{/* os:check */}
2627
```typescript
2728
import type { ErrorResponse, StandardErrorCode } from '@objectstack/spec/api';
2829

@@ -289,6 +290,7 @@ export const EnrichTaskWithAI: Hook = {
289290

290291
Prevent cascading failures when an external service is down:
291292

293+
{/* os:check */}
292294
```typescript
293295
class CircuitBreaker {
294296
private failures = 0;

content/docs/automation/flows.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ A **Flow** is a visual automation that orchestrates business logic through conne
99

1010
## Basic Structure
1111

12+
{/* os:check */}
1213
```typescript
1314
const approvalFlow = {
1415
name: 'order_approval',
@@ -564,6 +565,7 @@ Edges connect nodes and define the execution path:
564565

565566
Flows use variables to pass data between nodes and to/from callers:
566567

568+
{/* os:check */}
567569
```typescript
568570
variables: [
569571
{ name: 'input_id', type: 'text', isInput: true, isOutput: false },
@@ -738,6 +740,7 @@ is retired; model the same logic as a Flow.
738740

739741
### Record-change flow
740742

743+
{/* os:check */}
741744
```typescript
742745
import type { Flow } from '@objectstack/spec/automation';
743746

content/docs/automation/index.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Automation is ObjectStack's process engine: you attach business logic to the dat
99

1010
The smallest useful automation is a hook (from the CRM example app):
1111

12+
{/* os:check */}
1213
```typescript
1314
import type { Hook, HookContext } from '@objectstack/spec/data';
1415

content/docs/automation/workflows.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ This page keeps the historical route but documents the current split.
2121
Use Flow when something should happen after a record event, schedule, button, or
2222
subflow call:
2323

24+
{/* os:check */}
2425
```typescript
2526
import type { Flow } from '@objectstack/spec/automation';
2627

@@ -63,6 +64,7 @@ registration/runtime.
6364
Use `StateMachineSchema` when the core requirement is "this object can only move
6465
through these states by these events."
6566

67+
{/* os:check */}
6668
```typescript
6769
import type { StateMachineConfig } from '@objectstack/spec/automation';
6870

content/docs/concepts/architecture.mdx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ description — data (objects), automation (flows), access (permissions), and in
8888

8989
### Example: Defining a Customer Object
9090

91+
{/* os:check */}
9192
```typescript
9293
// src/objects/customer.object.ts
9394
import { ObjectSchema, Field } from '@objectstack/spec/data';
@@ -148,6 +149,7 @@ That's the job of the other layers.
148149

149150
### Example: Permission Rules
150151

152+
{/* os:check */}
151153
```typescript
152154
// src/permissions/sales_rep.permission.ts
153155
import { definePermissionSet } from '@objectstack/spec';
@@ -175,6 +177,7 @@ export const SalesRepPermission = definePermissionSet({
175177

176178
### Example: Workflow Automation
177179

180+
{/* os:check */}
178181
```typescript
179182
// src/flows/high_value_customer.flow.ts
180183
import { defineFlow } from '@objectstack/spec';
@@ -221,6 +224,7 @@ Kernel **orchestrates** these rules at runtime, independent of the data structur
221224

222225
### Example: List View
223226

227+
{/* os:check */}
224228
```typescript
225229
// src/views/customer.view.ts
226230
import { defineView } from '@objectstack/spec';
@@ -245,6 +249,7 @@ export const CustomerView = defineView({
245249

246250
### Example: Form View
247251

252+
{/* os:check */}
248253
```typescript
249254
// src/views/customer.view.ts
250255
import { defineView } from '@objectstack/spec';
@@ -300,6 +305,7 @@ User clicks "Save"
300305

301306
### Step 2: UI Layer Sends Request
302307

308+
{/* os:check */}
303309
```typescript
304310
// ObjectUI dispatches an action to Kernel
305311
const request = {
@@ -375,6 +381,7 @@ for (const workflow of workflows) {
375381

376382
### Step 7: ObjectUI Updates Display
377383

384+
{/* os:check */}
378385
```typescript
379386
// Kernel returns success response
380387
// UI optimistically updates the screen
@@ -388,6 +395,7 @@ Here's how all three protocols collaborate for a **Kanban Board** feature:
388395

389396
### 1. ObjectQL: Define the Data
390397

398+
{/* os:check */}
391399
```typescript
392400
import { ObjectSchema, Field } from '@objectstack/spec/data';
393401

@@ -426,6 +434,7 @@ export const Opportunity = ObjectSchema.create({
426434

427435
### 2. Kernel: Define Business Rules
428436

437+
{/* os:check */}
429438
```typescript
430439
import { defineFlow } from '@objectstack/spec';
431440

@@ -450,6 +459,7 @@ export const OpportunityWonFlow = defineFlow({
450459

451460
### 3. ObjectUI: Define the Kanban View
452461

462+
{/* os:check */}
453463
```typescript
454464
import { defineView } from '@objectstack/spec';
455465

content/docs/concepts/index.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ ObjectStack centralizes the "Intent" into a **single Protocol Definition**:
4141

4242
<Tabs items={['Array Format', 'Map Format']}>
4343
<Tab value="Array Format">
44+
{/* os:check */}
4445
```typescript
4546
// ONE definition — everything else derives from it
4647
import { defineStack } from '@objectstack/spec';
@@ -57,6 +58,7 @@ export default defineStack({
5758
```
5859
</Tab>
5960
<Tab value="Map Format">
61+
{/* os:check */}
6062
```typescript
6163
// Map keys become the `name` field automatically
6264
import { defineStack } from '@objectstack/spec';

0 commit comments

Comments
 (0)