You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: implementation-accuracy audit of the #4212-family affected docs (#4312)
* docs: checkpoint the docs-accuracy audit pass over 18 hand-written docs
WIP checkpoint — the adversarial verification pass is still running and will
add repairs on top of this commit. Recorded now so the work survives.
An audit agent read each doc, located the backing implementation under
packages/, and applied evidence-backed fixes in place (158 across 18 docs).
Every fix carries file:line evidence in the run's fix log. The heaviest:
- kernel/cluster.mdx (22): documented an `eventBus.emit(...)` API that exists
nowhere in the codebase, a `ctx.cluster` PluginContext property that does
not exist, `defineStack({ cluster })` that stack.zod.ts silently strips,
fabricated `postgres`/`nats` drivers, the wrong env var (real one is
OS_CLUSTER_DRIVER), and an at-least-once delivery promise neither shipped
driver provides.
- protocol/kernel/plugin-spec.mdx (20): `plugin.manifest.ts` as the manifest
filename — grep-empty across the implementation, the real one is
objectstack.plugin.json; `context.plugins.isInstalled()` which does not
exist; compound semver ranges ('>=1.0.0 <2.0.0') that make the resolver's
anchored parse throw; init described as registration order when bootstrap()
runs the dependency-topological order.
- data-modeling/external-datasources.mdx (3): credentialsRef samples used a
`secret:` prefix the shipped SecretBinder cannot dereference (`sys_secret:`),
so copying the sample fails closed at connect.
- deployment/migration-from-objectql.mdx (2): a `^3.1.0` pin that can never
resolve to the current 16.1.0 line.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HrRNgrWaRtggzmrHpbomyh
* docs: implementation-accuracy audit of the #4212-family affected docs
Ran the repo's docs-accuracy-audit workflow scoped to the drift-check advisory
from #4242 (14 docs) plus 4 the retired-surface grep implicated. 158
evidence-backed fixes across 18 docs, each cited to file:line. The largest
classes:
- kernel/cluster.mdx (22): a documented `eventBus.emit(...)` that exists
nowhere in packages/, a `ctx.cluster` PluginContext property that does not
exist, `defineStack({ cluster })` that stack.zod.ts silently strips,
`postgres`/`nats` listed as shipped drivers when neither package exists,
`REDIS_URL` for the real `OS_CLUSTER_DRIVER`, and an at-least-once delivery
promise no shipped driver provides.
- protocol/kernel/plugin-spec.mdx (20): `plugin.manifest.ts` as the manifest
filename — grep-empty across packages/, apps/ and examples/; the real one is
`objectstack.plugin.json`. Plus `context.plugins.isInstalled()` (no such
member), compound semver ranges (`'>=1.0.0 <2.0.0'`) that make the resolver
throw, and init ordering described as registration order when bootstrap()
runs a dependency topological sort.
- data-modeling/external-datasources.mdx: `credentialsRef: 'secret:…'` — the
shipped binder only resolves `sys_secret:<id>`, so the sample as written
fails closed at connect.
- deployment/migration-from-objectql.mdx: a `^3.1.0` pin that can never
resolve to the current 16.1.0 line.
VERIFICATION STATUS — 7 of 18 docs carry an adversarial-verifier pass; the
other 11 do not (the run hit the session limit mid-phase). The verifier earned
its keep on the 7 it reached: 8 repairs, including a fabricated
`enforceNetworkAccess` (real: `enforceNetworkRequest`,
plugin-permission-enforcer.ts:212) and an over-broad retirement claim that
would have contradicted the live app-bundle `onEnable`. The remaining 11 are
committed unverified and MUST NOT ship until their verifier pass runs — the PR
stays draft until then.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HrRNgrWaRtggzmrHpbomyh
* chore(lint): ratchet the role-word baseline down after the docs audit
The audit pass removed a "role" occurrence from kernel/events.mdx (now clean)
and one from kernel/services-checklist.mdx (4 → 3). check-role-word is a
ratchet, so an improvement fails the gate until the baseline records it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HrRNgrWaRtggzmrHpbomyh
* docs: apply adversarial-verifier repairs (metadata-lifecycle, protocol/kernel/index)
Verifier pass for two more of the 18 audited docs completed: 27 of the audit's
fixes confirmed against code, 5 repaired. Checkpoint commit — the remaining
verifier passes are still running and will land separately.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HrRNgrWaRtggzmrHpbomyh
* docs: apply the remaining adversarial-verifier repairs
Completes the verifier phase for all 18 audited docs (36/36 agents, 0 errors).
Across the run: 158 audit fixes, 29 verifier repairs, 91 residual items
recorded rather than guessed at.
The repairs are why this phase exists — the audit agents were confident and
sometimes wrong. Representative catches:
- `enforceNetworkAccess` invented for the real `enforceNetworkRequest`
(plugin-permission-enforcer.ts:212).
- A retirement callout widened to "None of it existed" over a list containing
`onEnable`, which would have contradicted the live app-bundle contract
AppPlugin.start() dispatches (app-plugin.ts:574).
- `cluster.lock.withLock(key, fn)` attributed to service-job's cron scheduler,
which actually does `lock.acquire(...)` + manual release
(cron-job-adapter.ts:139-147).
- A "(planned)" marker dropped from the webhook dispatcher, which filed an
already-shipping partitioned dispatcher under "Not started".
Gates: check-doc-authoring 215 files clean; check-role-word OK (44 baselined);
docs build compiles all pages.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HrRNgrWaRtggzmrHpbomyh
---------
Co-authored-by: Claude <noreply@anthropic.com>
@@ -66,11 +66,11 @@ to relearn the syntax across surfaces.
66
66
most common mistake (and the root cause of issue #1491) is a condition like
67
67
`{record.rating} >= 4`: in CEL, `{…}` is a **map literal**, so it is a parse
68
68
error. Write bare CEL: `record.rating >= 4`. Braces belong only in `{{ … }}`
69
-
text templates. As of 7.6 a malformed expression no longer silently does
70
-
nothing — it fails `objectstack build` and throws at runtime.
69
+
text templates. A malformed expression does not silently do nothing — it fails
70
+
`os build` and throws at runtime.
71
71
</Callout>
72
72
73
-
**Template formatting (7.6).** A `template` hole is a field path with an optional
73
+
**Template formatting.** A `template` hole is a field path with an optional
74
74
whitelisted formatter — `{{ path | formatter[:arg] }}` — with defined value→string
75
75
semantics (no arbitrary logic; put logic in a CEL field):
76
76
@@ -121,9 +121,14 @@ evaluates (`objectql` computes a formula virtual field from its `expression`
121
121
only). Do **not** pass `type: 'currency' | 'number' | …` to `Field.formula` — it
122
122
is rejected by the typed `FieldInput` and, untyped, would override `type:'formula'`
123
123
so the field silently never computes. To declare what the formula returns, set
124
-
**`returnType`** (`'number' | 'text' | 'boolean' | 'date'`); it is inferred and
125
-
stamped automatically by the AI build path, and consumers (dashboard measures,
126
-
formatting) read it instead of re-parsing the expression. The CEL source is the
124
+
**`returnType`** (`'number' | 'text' | 'boolean' | 'date'`). You declare it
125
+
yourself — nothing back-fills it — but the agent-callable `validate_expression`
126
+
tool reports the type it infers from the expression (`inferredType`) so an AI
127
+
author can stamp the matching value. Consumers read the declared `returnType`
128
+
instead of re-parsing the expression (record-title eligibility, for one: a
129
+
formula is title-eligible only when its `returnType` is `'text'`, which is what
130
+
lets it be *derived* as the record title — an explicit `nameField` pointer is
131
+
honored either way). The CEL source is the
127
132
**`expression`** key — it is the only key the schema and runtime read for a
128
133
formula's source; there is no separate `formula` source key.
129
134
</Callout>
@@ -161,7 +166,7 @@ Cheat-sheet of what you'll write daily:
161
166
162
167
Registered automatically into every `Environment` by `@objectstack/formula`.
163
168
All functions are pure given a pinned `now`, which is what makes
164
-
`objectstack build` artifacts byte-stable across runs.
169
+
`os build` artifacts byte-stable across runs.
165
170
166
171
| Function | Returns | Description |
167
172
|:---|:---|:---|
@@ -197,20 +202,21 @@ Keep them pure, dependency-free, and AI-readable.
197
202
|`record`| the row being evaluated | formulas, validation, sharing, visibility |
198
203
|`previous`| row before update | hooks, validation on update |
199
204
|`input`| hook payload | hooks |
200
-
|`os.user`| install / request user | seed, predicates with identity |
205
+
|`current_user`| the authenticated subject — the canonical binding (ADR-0068). `user`, `ctx.user` and `os.user` are aliases of the **same** object | predicates with identity |
206
+
|`os.user`| alias of `current_user`| seed, predicates with identity |
201
207
|`os.org`| active organization | seed, predicates |
Copy file name to clipboardExpand all lines: content/docs/deployment/migration-from-objectql.mdx
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,7 +5,7 @@ description: Step-by-step guide for migrating from @objectql/core to @objectstac
5
5
6
6
# Migrating from `@objectql/core` to `@objectstack/objectql`
7
7
8
-
Starting with `@objectstack/objectql` v3.1, all core functionality previously provided by `@objectql/core` is now available upstream. This guide walks you through migrating your project so that `@objectql/core` can be removed.
8
+
The core functionality previously provided by `@objectql/core` — the introspection types, the utility functions, and the kernel factory — was upstreamed into `@objectstack/objectql` in **v3.0.4** and has shipped in every release since (the current release line is **v16.x**). This guide walks you through migrating your project so that `@objectql/core` can be removed.
9
9
10
10
## Why Migrate?
11
11
@@ -26,7 +26,7 @@ Starting with `@objectstack/objectql` v3.1, all core functionality previously pr
Copy file name to clipboardExpand all lines: content/docs/deployment/vercel.mdx
+8-5Lines changed: 8 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,7 +5,7 @@ description: Deploy ObjectStack applications to Vercel with the Hono server adap
5
5
6
6
# Deploy to Vercel
7
7
8
-
ObjectStack 11 deploys to Vercel in **server mode** — serverless functions running the **Hono** adapter (`@objectstack/hono`). The published ObjectStack Studio/console ships as a static Vite SPA that points at a separate ObjectStack server (via `VITE_SERVER_URL`).
8
+
ObjectStack deploys to Vercel in **server mode** — serverless functions running the **Hono** adapter (`@objectstack/hono`). The Console SPA can also be deployed on its own as a static Vite build that points at a separate ObjectStack server (via `VITE_SERVER_URL`) — but that build comes from the Console source repo ([objectui](https://github.com/objectstack-ai/objectui)), not from the prebuilt `@objectstack/console` package.
9
9
10
10
<Callouttype="warn">
11
11
**Removed in 11.** The in-browser MSW mode (`@objectstack/plugin-msw`) and the Next.js adapter (`@objectstack/nextjs`) are no longer published — use the Hono server path below.
@@ -43,7 +43,7 @@ In Server mode, ObjectStack runs inside Vercel Serverless Functions. API request
43
43
This is a valid self-contained pattern when you want to ship a Vite SPA *and* its API from a single Vercel project: the SPA is served as static assets, and a Hono-based serverless function handles `/api/*` requests.
44
44
45
45
<Callouttype="info">
46
-
The published ObjectStack Studio/console (`@objectstack/console`) does **not** use this topology. It deploys as a pure static SPA with no `api/` function — it is meant to be embedded in, or pointed at, a separate ObjectStack server via `VITE_SERVER_URL`. For that separate server, prefer the CLI (`objectstack serve`) over a hand-rolled Hono function.
46
+
The framework-vendored Console (`@objectstack/console`) does **not** use this topology. It is a **prebuilt, dist-only** package — no source and no build step, just static assets — that an ObjectStack server mounts at `/_console` (`os serve --ui`, on by default). Its bundle is baked same-origin, and `VITE_SERVER_URL` is a build-time Vite flag, so aiming a Console at a *different* origin means building it yourself from the Console source repo ([objectui](https://github.com/objectstack-ai/objectui)). For the server itself, prefer the CLI (`os serve`) over a hand-rolled Hono function.
47
47
</Callout>
48
48
49
49
**1. Create the kernel singleton** (`api/_kernel.ts` — prefixed with `_` to prevent Vercel from creating a route):
@@ -82,7 +82,10 @@ export async function ensureApp(): Promise<Hono> {
82
82
`InMemoryDriver` keeps this snippet self-contained, but on serverless **all data
83
83
is lost on every cold start** — fine for a demo, wrong for anything real. Before
84
84
going past a proof of concept, swap the driver for a real database (see
85
-
[Database Drivers](/docs/data-modeling/drivers)) and point `OS_DATABASE_URL` at it.
85
+
[Database Drivers](/docs/data-modeling/drivers)). A hand-built kernel does **not**
86
+
resolve `OS_DATABASE_URL` on its own — that precedence lives in the CLI and in
87
+
`createStandaloneStack()` — so read the connection string yourself, e.g.
**2. Create the API entrypoint** (`api/index.ts`):
@@ -134,7 +137,7 @@ Setting `VITE_SERVER_URL` to empty string tells the client SDK to use same-origi
134
137
135
138
Configure these in Vercel Project Settings → Environment Variables:
136
139
137
-
### Studio / SPA build
140
+
### Console / SPA build
138
141
139
142
| Variable | Description |
140
143
| :--- | :--- |
@@ -179,7 +182,7 @@ storage for artifacts.
179
182
-[ ]`api/_kernel.ts` boots the kernel with the correct driver
180
183
-[ ]`vercel.json` sets `VITE_USE_MOCK_SERVER=false` and `VITE_SERVER_URL=` (empty)
181
184
-[ ] Rewrite rule routes `/api/*` to `/api` and excludes `/api/` from SPA rewrite
182
-
-[ ]`OS_DATABASE_URL`is configured in Vercel environment variables (for production drivers)
185
+
-[ ]The production connection string is set in Vercel environment variables **and** read explicitly by the driver you construct in `api/_kernel.ts` (`OS_DATABASE_URL` is resolved by the CLI / `createStandaloneStack()`, not by a hand-built kernel)
183
186
-[ ] CORS is configured if frontend and API are on different origins
0 commit comments