Skip to content

Commit 78b78d3

Browse files
committed
docs(releases,nav): v17 follow-up — Console gap backfill, sidebar restore, first docs sweep
Three related closures on the just-merged v17 release page (#3906): 1. The Console section was missing 25 objectui commits. The v17 frontend window is cf2d56e32a11 → 4a4829d0ef39 = 128 commits, but the pending console-*.md changesets covered only 103: the range 2cb8d78e24ad...c6cfdf1288b6 landed with no changeset — exactly the "SHA bump leaves no trace" failure scripts/bump-objectui.sh exists to prevent. Two of the missing commits are breaking and each is the frontend half of a backend change the page already documented (useClientNotifications delegates ↔ #3612 SDK removal; @object-ui/types Capabilities re-exports ↔ the retired capabilities cluster). Both now sit beside their backend halves and in the upgrade checklist, with the other eight substantive commits folded into the Console section and .changeset/console-c6cfdf1288b6-backfill.md recording the range itself. 2. "releases" returns to the root sidebar. #3423 unlisted References and Releases together ("lookup content ... the docs home page links both"); that trade holds for References (22 generated pages) but not for Releases in a release window, when the upgrade notes are what people open the docs for. References stays out. check-release-notes now enforces what its success line already claimed: the section must be reachable via the root nav OR a /docs/releases link on the docs home — either satisfies it (preserving #3423's option), losing both fails the build. Negative-tested both directions. 3. First v17 docs sweep (docs/v17-docs-sweep.md — playbook + append-only run log with a watermark, built to re-run while the RC train iterates). Run 1 fixed the drift v17 left in hand-written prose: services-checklist (17→16 services, graphql rows, the dissolved ObjectStackProtocol), the anonymous-deny matrix still listing /graphql + handleGraphQL, sharing docs describing owner/group shapes as "declared but not enforced" (they no longer parse), http-protocol claiming enable.trash exists, REST/GraphQL in objectql diagrams/prose, and the objectstack-api skill description (mirrors regenerated via gen:skill-docs). False positives and out-of-scope findings (spec comment drift, implementation-status.mdx staleness) are logged for the next run. Verified: pnpm docs:build passes; check:release-notes / doc-authoring / role-word / org-identifier / nul-bytes / skill-docs-sync all green; the new guard branch fails when both entry points are removed and passes with either. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LXvaYR7TiJBCxYwjn51owH
1 parent a641d10 commit 78b78d3

17 files changed

Lines changed: 287 additions & 35 deletions
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
"@objectstack/console": minor
3+
---
4+
5+
Console (objectui) backfill for `2cb8d78e24ad...c6cfdf1288b6` — the one refresh in
6+
the v17 window that landed with no changeset.
7+
8+
`scripts/bump-objectui.sh` emits a `@objectstack/console` changeset on every bump
9+
precisely so a SHA move leaves a trace (see `docs/releases-maintenance.md`). One
10+
bump in this window did not, so 25 commits — including two breaking ones — were
11+
absent from the release history and from the curated v17 page. This entry records
12+
them after the fact; it declares no new SHA move (`.objectui-sha` already points
13+
past this range at `4a4829d0ef39`).
14+
15+
Frontend changes in this range:
16+
17+
- feat(react)!: trim dead device/preference delegates from useClientNotifications (objectstack#3612 companion) (#2862)
18+
- feat(types)!: drop the ObjectStack/ObjectOS/ObjectQL/ObjectUI Capabilities re-exports (#2860)
19+
- feat: gate detail/form edit & delete on the server's effective operation set (framework#3546) (#2832)
20+
- feat(app-shell): approver values become record lookups (framework#3508) (#2834)
21+
- feat(console): group tenancy posture affordances — org switcher as write context + org attribution (ADR-0105 Phase 1) (#2858)
22+
- feat(console): i18n the system-settings hub (objectui#2851 P2) (#2859)
23+
- fix(dashboard,charts): resolve `{current_user_id}` in widget filters (framework#3574) (#2857)
24+
- fix(grid): validate email format in the import preview (objectstack#3566) (#2840)
25+
- fix(fields): consistent image-field rendering + click-to-zoom (#2836) (#2837)
26+
- fix(app-shell): stop the flow-node repeater from committing during render (#2838) (#2839)
27+
28+
Plus 15 dependency bumps, three of them major for the Console's own build:
29+
`maplibre-gl` 5→6, `chalk` 5→6, `jsdom` 29→30 (dev).
30+
31+
objectui range: `2cb8d78e24ad...c6cfdf1288b6`
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
---
3+
4+
Docs-only: close two gaps in the v17 release page and make the Releases section
5+
reachable from the sidebar again. Releases nothing.
6+
7+
**The Console section was missing 25 objectui commits.** The v17 frontend window
8+
is `cf2d56e32a11` (what 16.1.0 pinned) → `4a4829d0ef39` = 128 commits, but the
9+
pending `console-*.md` changesets only covered 103 of them: the range
10+
`2cb8d78e24ad...c6cfdf1288b6` landed with no changeset, which is exactly the
11+
"a SHA bump leaves no trace" failure `scripts/bump-objectui.sh` exists to
12+
prevent. Two of the missing commits are breaking, and both are the frontend half
13+
of a backend change the page already documented — so the page described one side
14+
of each and omitted the other:
15+
16+
- `useClientNotifications` loses its dead device/preference delegates
17+
(objectui#2862), the companion to the SDK removal in #3612
18+
- `@object-ui/types` drops the Capabilities re-exports (objectui#2860), the
19+
companion to the retired capabilities-descriptor cluster
20+
21+
Both now appear beside their backend halves and in the upgrade checklist, along
22+
with the other eight substantive commits (effective-operation-set gating on
23+
detail/form, approver record lookups, `{current_user_id}` in widget filters, org
24+
switcher as write context, system-settings i18n, image click-to-zoom, import
25+
email validation, flow-node repeater render fix) and the three major build-dep
26+
bumps. `.changeset/console-c6cfdf1288b6-backfill.md` records the range itself so
27+
the history no longer has a hole.
28+
29+
**`releases` returns to the root sidebar.** #3423 took References and Releases
30+
out of the tree as a decluttering pass, on the stated basis that "URLs still
31+
resolve and the docs home page links both". That trade holds for References (22
32+
generated pages) but reads poorly for Releases during a release window, when
33+
finding the upgrade notes is the reason someone opened the docs. References stays
34+
out.
35+
36+
**First v17 docs sweep** (`docs/v17-docs-sweep.md` — playbook + append-only run
37+
log, designed for re-runs while the RC train keeps accumulating changesets).
38+
Run 1 fixed the drift v17 left in hand-written prose: `services-checklist`
39+
(17→16 services, graphql rows, the dissolved `ObjectStackProtocol`),
40+
authorization/permissions pages still describing `/graphql` in the
41+
anonymous-deny matrix and owner/`group` sharing shapes as "declared but not
42+
enforced" (they no longer parse), `http-protocol` claiming `enable.trash`
43+
exists, "REST/GraphQL" in objectql diagrams/prose, and the `objectstack-api`
44+
skill description (mirrors regenerated via `gen:skill-docs`).
45+
46+
**`check-release-notes` now checks what it claims.** Its success line said every
47+
release page is "navigable" while it only ever read the section's own
48+
`meta.json` — it could not see that the section had been unlisted from the root
49+
nav, so it stayed green for the entire period the whole section was absent from
50+
the sidebar. It now also requires the section to be reachable via the root nav
51+
**or** a `/docs/releases` link on the docs home page: either satisfies it, so
52+
#3423's trade remains available, but losing both now fails the build.

content/docs/ai/skills-reference.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ ObjectStack ships **9 domain-specific skills**. Each is self-contained — an AI
5151
| 4 | [UI](#ui) | `ui` | `skills/objectstack-ui/` | Author ObjectStack UI metadata — Views (list/form/kanban/calendar/gantt), Apps (navigation), Pages (structured plus the HTML and React source-authoring tiers, ADR-0080/0081), Dashboards, Reports, Charts, Actions, and package Docs (`src/docs/*.md`). |
5252
| 5 | [Automation](#automation) | `automation` | `skills/objectstack-automation/` | Design ObjectStack automation — Flows (visual logic), Triggers, Approvals, state machines, scheduled jobs, and webhooks. |
5353
| 6 | [AI](#ai) | `ai` | `skills/objectstack-ai/` | Design ObjectStack AI skills, tools, knowledge sources, conversations, model registry entries, and MCP integrations. |
54-
| 7 | [API](#api) | `api` | `skills/objectstack-api/` | Design the server-side API surface that an ObjectStack runtime exposes — REST/GraphQL endpoints, auth providers, realtime channels, error envelopes, batch/versioning contracts. |
54+
| 7 | [API](#api) | `api` | `skills/objectstack-api/` | Design the server-side API surface that an ObjectStack runtime exposes — REST endpoints, auth providers, realtime channels, error envelopes, batch/versioning contracts. |
5555
| 8 | [i18n](#i18n) | `i18n` | `skills/objectstack-i18n/` | Author ObjectStack translation bundles — object/field labels, view text, app navigation strings, automation messages — and configure locale fallback, coverage reporting, and the per-locale source layout. |
5656
| 9 | [Formula](#formula) | `expression` | `skills/objectstack-formula/` | Author CEL expressions used across ObjectStack — formula fields, field conditional rules (`visibleWhen`, `readonlyWhen`, `requiredWhen`), validation / sharing / visibility predicates, flow conditions, and dynamic seed values. |
5757

@@ -145,9 +145,9 @@ Do not use for general LLM prompting questions unrelated to ObjectStack metadata
145145

146146
**Domain** `api` · **Path** `skills/objectstack-api/`
147147

148-
Design the server-side API surface that an ObjectStack runtime exposes — REST/GraphQL endpoints, auth providers, realtime channels, error envelopes, batch/versioning contracts.
148+
Design the server-side API surface that an ObjectStack runtime exposes — REST endpoints, auth providers, realtime channels, error envelopes, batch/versioning contracts.
149149

150-
Use when the user is adding `*.endpoint.ts`, configuring auth providers, defining custom routes, or extending the REST/GraphQL generator.
150+
Use when the user is adding `*.endpoint.ts`, configuring auth providers, defining custom routes, or extending the REST generator.
151151

152152
Do not use for: consuming an ObjectStack API from a client (that is just standard HTTP — no skill needed); the auto-generated CRUD endpoints (those follow from objectstack-data); request-side query syntax (see objectstack-query). CEL expressions in route guards or auth predicates: load objectstack-formula alongside.
153153

content/docs/kernel/services-checklist.mdx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ for the protocol-method inventory; treat the per-service status columns as
1313
historical until this page is regenerated.
1414
</Callout>
1515

16-
The ObjectStack protocol defines **17 kernel services** registered via the `CoreServiceName` enum. Each service maps to a set of protocol methods (57 total), governed by the `ObjectStackProtocol` interface.
16+
The ObjectStack protocol defines **16 kernel services** registered via the `CoreServiceName` enum (the never-implemented `graphql` entry was removed in v17). Each service maps to a set of protocol methods governed by its per-domain contract (`DataProtocol`, `MetadataProtocol`, ...) — the transitional `ObjectStackProtocol` composition alias was dissolved in v17 (ADR-0076 D9); capability availability comes from the runtime discovery `services` registry.
1717

1818
**Key architecture principle**: The kernel itself only provides **data** and **metadata** (framework). Everything else — including **auth** and **automation** — is delivered by **plugins**. The current `@objectstack/objectql` package is an example kernel implementation to get the basic API running; production kernels will be rebuilt as new plugins.
1919

@@ -42,7 +42,7 @@ The ObjectStack protocol defines **17 kernel services** registered via the `Core
4242
├─────────────────────────────────────────────────────────┤
4343
│ Plugin Layer │
4444
│ All other services: auth, automation, workflow, ui, │
45-
│ realtime, notification, ai, i18n, graphql, search, │
45+
│ realtime, notification, ai, i18n, search,
4646
│ file-storage, cache, queue, job │
4747
│ │
4848
│ Discovery API reports: enabled/unavailable/degraded │
@@ -72,7 +72,6 @@ The ObjectStack protocol defines **17 kernel services** registered via the `Core
7272
| 14 | **cache** | `core` || ✅ Built-in (in-memory fallback) | `@objectstack/service-cache` |
7373
| 15 | **queue** | `core` || ✅ Built-in (in-memory fallback) | `@objectstack/service-queue` |
7474
| 16 | **job** | `core` || ✅ Built-in (in-memory fallback) | `@objectstack/service-job` |
75-
| 17 | **graphql** | `optional` || ❌ Plugin Required | TBD plugin |
7675

7776
<Callout type="warn">
7877
**Criticality Levels**
@@ -282,7 +281,7 @@ The i18n service is a **core built-in service** with automatic in-memory fallbac
282281
// Production (overrides built-in fallback)
283282
kernel.use(new I18nServicePlugin({ defaultLocale: 'en', localesDir: './i18n' }));
284283

285-
// Development (automatic — DevPlugin registers i18n stub for all 17 core services)
284+
// Development (automatic — DevPlugin registers i18n stub for all 16 core services)
286285
kernel.use(new DevPlugin());
287286

288287
// No plugin required — kernel auto-injects in-memory fallback if none registered
@@ -331,9 +330,9 @@ AppPlugin will:
331330

332331
---
333332

334-
## 12–17. Infrastructure Services
333+
## 12–16. Infrastructure Services
335334

336-
`cache`, `queue`, and `job` are `core` services: like `i18n`, the kernel auto-injects an in-memory fallback when no plugin registers them (see `CORE_FALLBACK_FACTORIES` in `packages/core/src/fallbacks/`). The `optional` services (`file-storage`, `search`, `graphql`) stay disabled until a plugin provides them.
335+
`cache`, `queue`, and `job` are `core` services: like `i18n`, the kernel auto-injects an in-memory fallback when no plugin registers them (see `CORE_FALLBACK_FACTORIES` in `packages/core/src/fallbacks/`). The `optional` services (`file-storage`, `search`) stay disabled until a plugin provides them.
337336

338337
| Service | Description |
339338
|:--------|:------------|
@@ -342,7 +341,6 @@ AppPlugin will:
342341
| **cache** | General-purpose cache. In-memory fallback; Redis via `@objectstack/service-cache`. |
343342
| **queue** | Message queue. In-memory fallback; BullMQ / Redis via `@objectstack/service-queue`. |
344343
| **job** | Scheduled task execution. In-memory fallback; cron-based, concurrency control. |
345-
| **graphql** | Auto-generate GraphQL schema from Object metadata. |
346344

347345
---
348346

@@ -373,8 +371,7 @@ AppPlugin will:
373371
|:-------|:------------|
374372
| **plugin-realtime** | WebSocket / SSE real-time push |
375373
| **plugin-notification** | Notification engine |
376-
| **plugin-ai** | NLQ, chat, suggestions, insights |
377-
| **plugin-graphql** | GraphQL API endpoint |
374+
| **plugin-ai** | Chat, completion, models, conversations (`service-ai`, Cloud/EE) |
378375
| **plugin-search** | Full-text search |
379376
| **plugin-job** | Scheduled tasks |
380377
| **plugin-queue** | Message queue |

content/docs/meta.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"deployment",
1818
"plugins",
1919
"kernel",
20-
"protocol"
20+
"protocol",
21+
"releases"
2122
]
2223
}

content/docs/permissions/authorization.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ site — the file you read when behavior surprises you.
4848

4949
| # | Gate | What it decides | Enforcement site | Failure direction |
5050
|---|---|---|---|---|
51-
| 1 | **Anonymous deny** | No identity → HTTP 401. **Uniform across every HTTP surface that reaches object data** (#2567): REST `/data`, the metadata endpoints (`/meta`), the dispatcher GraphQL endpoint (`/graphql`), and the raw-hono standard `/data` routes — one shared decision, so a caller denied on `/data` can't read the same rows through a sibling door. **Default-on** (ADR-0056 D2): public serving requires an explicit `api.requireAuth: false` opt-out, which logs a boot warning. Control plane (`/auth`, `/health`, `/discovery`) is exempt; share-links validate their token then read as SYSTEM. | `packages/core/src/security/anonymous-deny.ts` `shouldDenyAnonymous` — called by `rest-server.ts` `enforceAuth`, the dispatcher `handleGraphQL`/`handleMetadata`/`handleAI`, and `plugin-hono-server` `denyAnonymous` (default in `packages/spec/src/api/rest-server.zod.ts`); a source-enumerating ratchet in `authz-conformance.test.ts` fails CI if a new surface ships ungated | fail-closed |
51+
| 1 | **Anonymous deny** | No identity → HTTP 401. **Uniform across every HTTP surface that reaches object data** (#2567): REST `/data`, the metadata endpoints (`/meta`), and the raw-hono standard `/data` routes (the dispatcher GraphQL endpoint left the matrix when the GraphQL surface was removed in v17 — `/graphql` now 404s) — one shared decision, so a caller denied on `/data` can't read the same rows through a sibling door. **Default-on** (ADR-0056 D2): public serving requires an explicit `api.requireAuth: false` opt-out, which logs a boot warning. Control plane (`/auth`, `/health`, `/discovery`) is exempt; share-links validate their token then read as SYSTEM. | `packages/core/src/security/anonymous-deny.ts` `shouldDenyAnonymous` — called by `rest-server.ts` `enforceAuth`, the dispatcher `handleMetadata`/`handleAI`, and `plugin-hono-server` `denyAnonymous` (default in `packages/spec/src/api/rest-server.zod.ts`); a source-enumerating ratchet in `authz-conformance.test.ts` fails CI if a new surface ships ungated | fail-closed |
5252
| 2 | **Public-form grant** | An anonymous form submission carries a declaration-derived `publicFormGrant` authorizing ONLY create + read-back on the form's declared target object — never anything else (ADR-0056 Option A). No guest-portal configuration needed (anonymous principals hold the `guest` position). | `packages/plugins/plugin-security/src/security-plugin.ts` (ObjectQL middleware) | scope-limited allow |
5353
| 3 | **Object CRUD** | `allowRead/Create/Edit/Delete` (+ the destructive lifecycle class `allowTransfer/Restore/Purge`, gated ahead of the M2 operations — #1883) resolved across the caller's permission sets. | `packages/plugins/plugin-security/src/permission-evaluator.ts` `checkObjectPermission` | fail-closed 403 |
54-
| 4 | **OWD / sharing** | Org-wide default (`private` / `public_read` / `public_read_write` / `controlled_by_parent`; **unset or unknown ⇒ `private`, fail-closed** — ADR-0090 D1) plus the external dial (`externalSharingModel`, ADR-0090 D11), manual record shares, criteria sharing rules (owner-type rules are declared but seed-skipped — [not enforced](/docs/permissions/sharing-rules#owner-based-sharing-rules)), business-unit hierarchy widening (ADR-0057 D5: scope-depth hierarchy lives on `sys_business_unit`, not positions). | `packages/plugins/plugin-sharing/src/sharing-service.ts` + `sharing-rule-service.ts` | fail-closed to owner-only |
54+
| 4 | **OWD / sharing** | Org-wide default (`private` / `public_read` / `public_read_write` / `controlled_by_parent`; **unset or unknown ⇒ `private`, fail-closed** — ADR-0090 D1) plus the external dial (`externalSharingModel`, ADR-0090 D11), manual record shares, criteria sharing rules (owner-type rules were removed from the authoring surface in v17 rather than left declared-but-skipped — [Sharing Rules](/docs/permissions/sharing-rules#recipient-types)), business-unit hierarchy widening (ADR-0057 D5: scope-depth hierarchy lives on `sys_business_unit`, not positions). | `packages/plugins/plugin-sharing/src/sharing-service.ts` + `sharing-rule-service.ts` | fail-closed to owner-only |
5555
| 5 | **Row-level security** | CEL predicates (`using` read filter, `check` write post-image) compiled into the query. If **no** applicable policy compiles, the result is a deny-all sentinel (fail-closed); an uncompilable policy alongside compilable ones is excluded from the OR-union **with a logged warning** — exclusion can only narrow access, never widen it. Tenant isolation is a wildcard RLS rule AND-ed on top. | `packages/plugins/plugin-security/src/rls-compiler.ts` + `security-plugin.ts` | fail-closed |
5656
| 6 | **Field-level security** | Read mask (strip non-readable fields) + write deny per `fields` rules. Caller queries that **filter, sort, group, or aggregate by** a non-readable field are rejected outright (HTTP 403, `field_predicate_denied`) — masking only the output would leave row presence as a value oracle. RLS-injected predicates are exempt (they run after the guard and may reference hidden fields like `owner_id`). | `packages/plugins/plugin-security/src/field-masker.ts` + `predicate-guard.ts` | fail-closed on predicates; see posture note below |
5757

content/docs/permissions/field-level-security.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ fields: {
4141
The client-side ObjectForm / inline grid hides non-editable fields from
4242
the UI — but that is a **UX layer only**. The SecurityPlugin middleware
4343
enforces field-level write rules on the server, regardless of how the
44-
request arrived (REST, GraphQL, raw ObjectQL call).
44+
request arrived (REST, SDK, raw ObjectQL call).
4545

4646
**On read**`find` / `findOne` results have non-readable fields
4747
stripped from every record before the response leaves the engine.

0 commit comments

Comments
 (0)