Skip to content

Commit 8856050

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/l2-hook-body-lint-warning-4e1787
2 parents d664aa9 + d4f4f36 commit 8856050

56 files changed

Lines changed: 1461 additions & 127 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.

.changeset/adapter-hono-auth-wildcard-yields.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
"@objectstack/adapter-hono": patch
2+
"@objectstack/hono": patch
33
---
44

55
fix(adapters/hono): the auth wildcard yields paths the auth service does not own (#4117)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
---
3+
4+
docs(adr-0104): amend the upgrade-path advertisement clause to record how it landed (#4253/#4284) — `os migrate meta` names the migrations without gate status, because gate status is per deployment (2026-07-27 addendum) while `meta` acts on source, which deploys to zero-or-N of them; status is reported where a datastore is actually open. Releases nothing.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
'@objectstack/spec': patch
3+
'@objectstack/runtime': patch
4+
---
5+
6+
Discovery stops telling Cloud/Enterprise deployments that nothing implements `ai` (#4093 follow-up).
7+
8+
`CORE_SERVICE_PROVIDER` recorded `null` for `ai` because no **workspace** package provides it, and `serviceUnavailableMessage('ai')` therefore produced *"No implementation ships for the 'ai' slot"*. That is false: `@objectstack/service-ai` registers the slot in `objectstack-ai/cloud`. The table conflated "not in this repository" with "does not exist" — the same class of wrong answer the table was introduced to end, one step further out.
9+
10+
Verified against the cloud repository rather than inferred: `packages/service-ai/src/plugin.ts` calls `ctx.registerService('ai', …)`, and the package is `private: true`, so there is genuinely nothing to install — which is why `null` stays right and an `Install X` sentence would still be wrong. `search`, `workflow` and `graphql` were checked the same way and nothing registers them in either repository, so their `null` and their "nothing ships" sentence are accurate.
11+
12+
`ai` now carries a `REMEDY_DETAIL` sentence — *"Provided by @objectstack/service-ai in ObjectStack Cloud/Enterprise — no implementation ships in the open framework"* — the mechanism `ui` already used. Both discovery (`services.ai.message`) and the `/ai` 501 body report it.
13+
14+
This **removes** code: `/ai`'s domain had a local message override, added because the shared sentence was wrong there. Correcting the table fixed the domain *and* discovery, which the override could never reach, so the override and `capabilityUnavailable`'s `message?` parameter are both gone. A slot whose sentence is wrong needs the table corrected, not a local exception.
15+
16+
Also corrected: three places still describing `/ai`'s absent-service answer as a 404 (`docs/api/client-sdk.mdx`, `docs/releases/v17.mdx`, and a comment in `packages/client`'s URL-conformance test) — stale since that answer became 501.
17+
18+
FROM → TO: `services.ai.message` and the `/ai/*` 501 body change text. Nothing branches on either — `status` and `enabled` are the contract, the message is prose for humans and agents.

.changeset/console-pin-pr-gate.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
---
3+
4+
ci: build the pinned objectui SHA on the PR that moves it (#4290)
5+
6+
`.objectui-sha` is the single source of truth for the vendored Console SPA —
7+
release.yml reads it, clones objectui at that commit, builds
8+
`@object-ui/console` and copies the dist into `packages/console/`. Editing that
9+
one line replaces the entire frontend the platform ships, and nothing on the PR
10+
side ever built it.
11+
12+
The pin appeared in exactly two workflows, neither a gate: release.yml
13+
(post-merge, on the main push) and showcase-smoke.yml (manual + nightly, whose
14+
own header says "it never gates PRs"). It is also a root dotfile, so it matched
15+
neither of ci.yml's `core` and `docs` filters — #4288 moved the pin 76 commits
16+
with six of fourteen checks skipped, including Build Core, Test Core, Build Docs
17+
and the Dogfood gate. A SHA that cannot build — a typo, a commit that was
18+
force-pushed away, a broken objectui, a dead bundle canary — reached `main`
19+
green and would have surfaced at publish time. The only thing between the two
20+
was the author remembering to run `scripts/build-console.sh` locally.
21+
22+
Adds ci.yml's `Console Pin Gate`: a `console` paths filter over `.objectui-sha`,
23+
`scripts/build-console.sh` and the two files that gate them, and a job that
24+
builds `@object-ui/console` at the pin against this tree's `@objectstack/client`
25+
and then runs `pnpm check:console-sha`.
26+
27+
Two details that keep it honest rather than merely green:
28+
29+
- It restores `packages/console/dist` under **release.yml's existing cache key**
30+
(`hashFiles('.objectui-sha', 'scripts/build-console.sh')`), so only a pin the
31+
repo has never built misses — and a miss is exactly when the gate has work to
32+
do. Watching the workflow and the drift guard therefore costs about a minute,
33+
not a full vite build.
34+
- The restore/save pair is **split**, where release.yml uses the combined
35+
action, because the combined post-step saves even when the job failed.
36+
`build-console.sh` writes the SHA stamp before it asserts the bundle canary,
37+
so a canary failure leaves a stamped-but-broken dist that would be cached,
38+
restored, and then waved through the stamp check. Saving only once every
39+
assertion is green is what lets a restored dist carry the same guarantees as a
40+
freshly built one. A separate step asserts a real dist is on disk first, since
41+
`check:console-sha` deliberately exits 0 when there is no dist at all.
42+
43+
Scope, stated plainly: this proves the pinned SHA builds. It does not cover a
44+
`packages/client` change breaking the injected-client bundle — that input lives
45+
under `packages/**`, and watching it here would rebuild the console on a large
46+
fraction of every PR. release.yml remains the only check for that direction.
47+
48+
CI and docs only; this releases nothing.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
---
3+
4+
test-only: the D12 honesty gate iterates the known-fake inventory — every
5+
`CORE_FALLBACK_FACTORIES` product registered slot-by-slot must come out of
6+
both discovery builders as `degraded`, never `available` (#3898 suggestion 4;
7+
`cache`/`queue`/`job` had no per-slot pin before). Releases nothing.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
"@objectstack/plugin-dev": patch
3+
"@objectstack/types": minor
4+
---
5+
6+
fix(plugin-dev,types): the production escape hatch stops being silent (#3900)
7+
8+
`DevPlugin.init()` refuses to run under `NODE_ENV=production` (ADR-0115 D6), and
9+
`OS_ALLOW_DEV_PLUGIN` overrides that refusal. As shipped, the override returned
10+
early with **no output at all**: the process ran the development assembly while
11+
every log line and the ready banner read like an ordinary production start.
12+
13+
That reproduces, one level up, the defect the guard exists to close. The guard's
14+
own precedent says so — `OS_ALLOW_DEGRADED_TENANCY` boots degraded *and brands
15+
it everywhere an operator looks*, and `OS_ALLOW_DRIVER_CONNECT_FAILURE`'s
16+
contract is "logged loudly at startup". An escape hatch that says nothing leaves
17+
the operator's only evidence of a degraded state in an env var they may not have
18+
set themselves.
19+
20+
**The override now brands itself, twice.** A warning at `init()` — emitted
21+
before any assembly work, so it survives an assembly step that later throws —
22+
and a repeat on the ready banner, which is the surface an operator actually
23+
reads:
24+
25+
```
26+
⚠ DEV ASSEMBLY UNDER NODE_ENV=production (OS_ALLOW_DEV_PLUGIN is set) — the boot
27+
guard was explicitly overridden. This process is running the DEVELOPMENT
28+
assembly, which is not hardened for production traffic (ADR-0115 D6).
29+
• Auth secret is the default published inside @objectstack/plugin-dev. It is
30+
public, so anyone can mint a session this stack accepts. Pass `authSecret`
31+
explicitly.
32+
• Data goes to the in-memory driver with persistence disabled — every record
33+
is lost when this process exits.
34+
```
35+
36+
Only hazards that are live for *that* configuration are named: the secret line
37+
is suppressed when the operator passed their own `authSecret`, and the driver
38+
line when the `driver` toggle is off. The dev-admin seed is deliberately absent
39+
`plugin-auth`'s `maybeSeedDevAdmin` is hard-gated to
40+
`NODE_ENV === 'development'` and cannot fire on this path, so warning about it
41+
would spend the attention the real hazards need.
42+
43+
**New export — `resolveAllowDevPlugin()` (`@objectstack/types`).** The flag moves
44+
off a bare `process.env['OS_ALLOW_DEV_PLUGIN'] === '1'` and joins the
45+
`OS_ALLOW_*` family's shared truthy vocabulary, next to
46+
`resolveAllowDegradedTenancy` / `resolveAllowDriverConnectFailure`.
47+
48+
FROM → TO for operators: `OS_ALLOW_DEV_PLUGIN=1` keeps working unchanged.
49+
`OS_ALLOW_DEV_PLUGIN=true` (and `on` / `yes`, case-insensitive, surrounding
50+
whitespace ignored) **now takes effect** where the strict comparison previously
51+
ignored it and failed the boot. That is a widening, in the direction an operator
52+
setting the flag already intended; falsy and unrecognised values still refuse to
53+
boot, and unset still means "fail fast". If you were relying on
54+
`OS_ALLOW_DEV_PLUGIN=true` being inert as a way to keep the guard armed, unset
55+
the variable instead.
56+
57+
No change to the refusal path, which this issue re-verified end to end:
58+
`kernel.use()` only registers, `initPluginWithTimeout` does not catch,
59+
`bootstrap()` rethrows, and `os serve`'s outer handler prints the message and
60+
exits `1`. The `throw` is genuinely fatal here, so it needs none of the
61+
`process.exit(1)` the tenancy guard required for sitting inside a broad `catch`.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
---
3+
4+
docs: fix the plugin-spec CHANGELOG example that still taught the retired
5+
`onUpgrade` hook as running automatically (#4212 family). Releases nothing.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
---
3+
4+
fix(dx): remove the per-package `lint` scripts (`eslint src`) from `@objectstack/verify`, `@objectstack/cli` and `@objectstack/lint` (#4276). A standalone run resolves the root flat config but honors the inline directives the root gate's `--no-inline-config` exists to ignore, so it fails on rules the config never registers — verify was red on a clean HEAD. Lint only from the root; the scoped recipe is documented in `eslint.config.mjs`. Dev scripts only; releases nothing.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
---
3+
4+
Repo-plumbing only: the pending changeset `adapter-hono-auth-wildcard-yields` referenced the Hono adapter by its old `@objectstack/adapter-hono` name, which `changeset version` rejects because the workspace package is named `@objectstack/hono`. Renamed the entry; a full sweep of every other pending changeset (and `pre.json`) against the workspace found nothing else stale. Releases nothing by itself.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
---
3+
4+
chore(spec): register the `adr0104-field-file-collection` dogfood proof tag in the ADR-0054 registry, honestly unbound — the collection contract it guards is `lifecycle` on the system `sys_file` object, already bound to `data-lifecycle`. Gate-only (`packages/spec/scripts/`, not published), so this releases nothing.

0 commit comments

Comments
 (0)