Skip to content

Commit 3ca5320

Browse files
authored
docs: finish implementation-accuracy audit — durable reference grouping + hand-written doc sync (#1880) (#3243)
Wave 1: 164/164 hand-written docs audited + adversarially verified (335 evidence-backed fixes across 116 docs, 14 verifier repairs). Wave 2.1: durable reference-sidebar grouping in build-docs.ts. Wave 2.2: ui/view describe strings + generator verified. Follow-ups filed: #3244, #3276, #3277, #3278.
1 parent 86d30af commit 3ca5320

135 files changed

Lines changed: 1191 additions & 1251 deletions

File tree

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: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,8 @@ migrations) that genuinely need full authority opt in explicitly with
237237
never the consequence of a forgotten field.
238238

239239
```typescript
240-
await aiService.chatWithTools(messages, tools, {
240+
await aiService.chatWithTools(messages, {
241+
tools,
241242
toolExecutionContext: {
242243
actor: {
243244
id: currentUser.id,

content/docs/ai/connect-mcp.mdx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ copy-paste-ready connect snippets per client), or over REST:
6868

6969
```bash
7070
curl -b cookies.txt -X POST https://your-deployment.example.com/api/v1/keys
71-
# → { "key": "osk_..." } — shown once; store it in your secret manager
71+
# → { "success": true, "data": { "key": "osk_...", "prefix": "osk_...", "name": "API Key" } }
72+
# the raw key is shown once — store it in your secret manager
7273
```
7374

7475
Send it on every request in any of three equivalent forms:
@@ -87,11 +88,12 @@ run insecurely.
8788

8889
## What the agent gets
8990

90-
Ten data and action tools, generated from your metadata:
91+
Eleven tools, generated from your metadata:
9192

9293
| Tool | What it does |
9394
|:---|:---|
9495
| `list_objects` / `describe_object` | Discover which objects exist and their fields |
96+
| `validate_expression` | Check a CEL expression against an object's schema before authoring it into a formula, validation, or flow condition |
9597
| `query_records` / `get_record` | Read data (list queries are capped at 50 rows per page by default) |
9698
| `aggregate_records` | Grouped aggregation (registered when the active driver supports it) |
9799
| `create_record` / `update_record` / `delete_record` | Write data |

content/docs/ai/index.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ flowchart TD
7070

7171
**DO:**
7272
- Declare knowledge sources via the Knowledge Protocol and pick the adapter (`memory`, `ragflow`, custom) that fits your data
73-
- Rely on the built-in data tools (`query_records` / `get_record` / `aggregate_data`) for live record access
73+
- Rely on the built-in data tools (`query_records` / `get_record` / `aggregate_records`) for live record access
7474
- Let permission-aware retrieval and RLS scope what each user's agent can see
7575
- Keep indexed objects in sync via the protocol's event sync
7676

@@ -165,7 +165,7 @@ Server-side, the same flow runs through `chatWithTools`, threading the
165165
end-user's `ExecutionContext` so tool calls respect row-level security:
166166

167167
```typescript
168-
const reply = await aiService.chatWithTools(messages, tools, {
168+
const reply = await aiService.chatWithTools(messages, {
169169
toolExecutionContext: {
170170
actor: { id: currentUser.id, name: currentUser.displayName, positions: currentUser.positions, permissions: currentUser.permissions },
171171
conversationId,

content/docs/api/client-sdk.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ The `@objectstack/client` is the official TypeScript client for ObjectStack. It
1717
- **Batch Operations**: Efficient bulk create/update/upsert/delete with transaction support
1818
- **Query Builder**: Programmatic query construction with `createQuery()` and `createFilter()`
1919
- **Standardized Errors**: Machine-readable error codes with retry guidance
20-
- **Protocol Compliant**: Implements the core API namespaces defined in `@objectstack/spec`, plus additional namespaces (approvals, feed, organizations, projects/environments)
20+
- **Protocol Compliant**: Implements the core API namespaces defined in `@objectstack/spec`, plus additional namespaces (approvals, organizations, projects/environments)
2121

2222
## Installation
2323

@@ -76,7 +76,7 @@ async function main() {
7676
When you call `client.connect()`, the client:
7777

7878
1. Probes `/api/v1/discovery` first, then falls back to `{origin}/.well-known/objectstack`
79-
2. Parses the discovery response including `routes`, `features`, and `services`
79+
2. Parses the discovery response including `routes`, `capabilities`, and `services`
8080
3. Configures all API route paths dynamically
8181

8282
```typescript
@@ -104,7 +104,7 @@ if (discovery.services?.auth?.enabled) {
104104

105105
## Protocol Coverage
106106

107-
The `@objectstack/client` SDK aims to implement the ObjectStack API protocol specification. The core namespaces are listed below; the client also exposes additional namespaces (`approvals`, `feed`, `organizations`, `oauth`, `projects`/environments) — see [`index.ts`](https://github.com/objectstack-ai/framework/blob/main/packages/client/src/index.ts) for the full surface:
107+
The `@objectstack/client` SDK aims to implement the ObjectStack API protocol specification. The core namespaces are listed below; the client also exposes additional namespaces (`approvals`, `organizations`, `oauth`, `projects`/environments) — see [`index.ts`](https://github.com/objectstack-ai/framework/blob/main/packages/client/src/index.ts) for the full surface:
108108

109109
| Namespace | Status | Methods | Purpose |
110110
|:----------|:------:|:--------|:--------|

content/docs/api/data-api.mdx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,9 @@ or the analytics service's `cubes` config) — a cube referenced by a query that
197197
yet registered is lazily auto-inferred from that query's shape, but metadata isn't
198198
proactively generated for every object.
199199

200-
**Response**: Array of cube definitions with measures and dimensions (time-based
201-
dimensions are `dimensions` entries with `type: "time"`).
200+
**Response**: `{ success: true, data: [...] }` where `data` is an array of cube
201+
definitions with measures and dimensions (time-based dimensions are `dimensions`
202+
entries with `type: "time"`).
202203

203204
### `POST /analytics/sql`
204205

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,9 @@ export const ValidateTaskData: Hook = {
202202
## 4. Error Logging and Monitoring
203203

204204
There is no global `onError` lifecycle event — the hook `HookEvent` enum only
205-
covers `before*` / `after*` of `find`, `insert`, `update`, `delete` (and their
206-
bulk variants). Each `Hook` does expose an `onError` *strategy* field
205+
covers `before*` / `after*` of `find`, `insert`, `update`, `delete`. Bulk
206+
(`multi: true`) writes fire these same events, not separate `*Many` variants.
207+
Each `Hook` does expose an `onError` *strategy* field
207208
(`'abort'` — the default — or `'log'`) that decides whether a handler failure
208209
aborts the operation or is merely logged. For structured error logging, wrap the
209210
risky work in a try/catch inside the handler and log there:

content/docs/api/index.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ Returns the full discovery manifest.
105105
**Response**:
106106
```json
107107
{
108-
"version": "1.0.0",
108+
"version": "v1",
109109
"apiName": "ObjectStack API",
110110
"routes": {
111111
"data": "/api/v1/data",
@@ -124,7 +124,7 @@ Returns the full discovery manifest.
124124
"auth": { "enabled": false, "status": "unavailable", "message": "Install plugin-auth to enable" }
125125
},
126126
"capabilities": {
127-
"feed": { "enabled": false },
127+
"cron": { "enabled": false },
128128
"automation": { "enabled": false },
129129
"search": { "enabled": false }
130130
}

content/docs/api/plugin-endpoints.mdx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ The following endpoints become available when the corresponding plugin is instal
2828

2929
### Workflow (`/workflow`) — Plugin Required
3030

31+
<Callout type="warn">
32+
Not yet mounted. These routes are declared in the API protocol but the core dispatcher registers no `/workflow` handler and no bundled plugin provides a `workflow` service (only an in-memory dev stub), so they return **404** today. `discovery.services.workflow` reports `unavailable` in a standard install.
33+
</Callout>
34+
3135
| Method | Endpoint | Description |
3236
|:-------|:---------|:------------|
3337
| GET | `/workflow/:object/config` | Get workflow configuration |
@@ -46,6 +50,10 @@ The automation dispatcher also exposes flow CRUD (`GET`/`POST /automation`, `GET
4650

4751
### Views (`/ui`) — Plugin Required
4852

53+
<Callout type="warn">
54+
Not yet mounted. The `/ui/views` CRUD routes are declared in the API protocol but no handler is registered for them, so they return **404** today (and the `/api/v1/ui` prefix is itself deprecated in favour of `/api/v1/meta/view`). The always-available view **resolver** is a separate route — see the note below.
55+
</Callout>
56+
4957
| Method | Endpoint | Description |
5058
|:-------|:---------|:------------|
5159
| GET | `/ui/views/:object` | List views for an object |
@@ -60,6 +68,10 @@ The auto-generated (non-CRUD) view resolver `GET /ui/view/:object/:type` is alwa
6068

6169
### Realtime (`/realtime`) — Plugin Required
6270

71+
<Callout type="warn">
72+
Not implemented. There is no realtime HTTP or WebSocket surface: `@objectstack/service-realtime` is an in-process pub/sub bus consumed via `kernel.getService('realtime')`, not over HTTP. The dispatcher has no `/realtime` branch, discovery deliberately omits the route (`features.websockets` is `false`), and the routes below would return **404** (ADR-0076 D12). They document the planned protocol shape only.
73+
</Callout>
74+
6375
| Method | Endpoint | Description |
6476
|:-------|:---------|:------------|
6577
| POST | `/realtime/connect` | Establish WebSocket/SSE connection |

content/docs/api/wire-format.mdx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,6 @@ The response is the `DeleteDataResponse` envelope: `{ object, id, success }`.
254254
}
255255
```
256256

257-
<Callout type="info">
258-
**Soft Delete:** If the object enables soft delete (`softDelete: { enabled: true }` in its definition), the record is moved to the trash / recycle bin instead of being permanently deleted.
259-
</Callout>
260-
261257
---
262258

263259
## 6. Get Metadata
@@ -365,7 +361,7 @@ Field-level failures carry a `fields` array.
365361

366362
```json
367363
{
368-
"error": "[Security] Access denied: operation 'update' on object 'task' is not permitted for roles [standard_user]",
364+
"error": "[Security] Access denied: operation 'update' on object 'task' is not permitted for positions [standard_user]",
369365
"code": "PERMISSION_DENIED",
370366
"object": "task"
371367
}

content/docs/automation/approvals.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ A flow declares `runAs` (ADR-0049), and for approvals this is the decision that
2424
- `runAs: 'user'` (default) — the flow's data operations run as the **submitter**, respecting their RLS. Good when the flow only touches records the submitter can already see.
2525
- `runAs: 'system'`**elevated**, bypasses RLS. Needed when the flow must read/write records the submitter can't (e.g. post to a ledger, notify an approver who owns rows the submitter can't see). Declare it **explicitly** so the elevation is visible, not accidental.
2626

27-
A schedule-triggered escalation has no triggering userso it must be `system` to act at all.
27+
A schedule-triggered escalation has no triggering user, so under the default `runAs: 'user'` its data operations run **unscoped** (elevated, RLS-bypassing) anyway — declare `system` to make that elevation explicit and intended rather than an implicit fail-open (the engine warns, and `os lint` flags the bare shape as `flow-schedule-runas-unscoped`).
2828

2929
### 3. The approval node
3030

0 commit comments

Comments
 (0)