Commit db16b94
* feat(client)!: converge analytics.query/meta/explain and automation.trigger on unwrapResponse
The four dispatcher-served methods ended `return res.json()` and handed their
callers the `{ success, data }` envelope whole, while every other
dispatcher-served method of ObjectStackClient strips it through
`unwrapResponse`. All four now end `return this.unwrapResponse(res)` and
declare the payload: `AnalyticsResult`, `AnalyticsMetadataResponse['data']`,
`AnalyticsSqlResponse['data']`, `AutomationResult` (the value
`automation.execute` already answered for the same handler).
`analytics.queryDataset` is protected: served bare by @objectstack/rest, it
keeps `res.json()`; its body is byte-identical (only its docblock says why).
Tests: `envelope-convergence.test.ts` (new, mocked transport: the payload on
all four, the unchanged rejection path, the no-`data` pass-through, and the
protected method); `analytics-automation-json-erasure.test.ts` re-driven
against the real producers to the payload; `return-type-precision.test.ts`
pins reversed (payload compiles, `.data` is the type error); the caller
census regenerated to the post-convergence ledger with the cloud census
command kept and reworded. One breaking changeset with the migration table.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza
* test(client): let the census method slicer close on a namespace's last property
`queryDataset` is the last member of `analytics = {…}` and closes with a bare
`}`; the slicer required `},` and could not find it inside the block.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza
* test(client): slice census methods on masked source, anchored to the next sibling
The previous anchor (a method's own closing brace) stopped at queryDataset's
parameter type literal, and a `\s+` indentation capture absorbed newlines.
Comments are masked first so docblock prose cannot satisfy a code assertion.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza
* test(client): assert queryDataset's route by its code spelling, not the docblock's
`analytics/dataset/query` only ever appeared in prose; the method spells it
`getRoute('analytics')` + `${route}/dataset/query`, which is what a
comment-masked slice can see.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza
* docs(changeset): scope the #13079 failure-path claims to the envelope level
Contract review corrections, prose only. `client.automation.trigger` is
excepted from the universal compile-error claim: `r.success` and `r.error`
compile before and after (both declared on `AutomationResult`), and their
meaning moves from the envelope's to the run's own — a refusal the door does
not classify as 400/409/422 is answered 200 through `deps.success(result)`
(`respondToFlowTrigger`, classification in `flow-dispatch-status.ts`), as
`execute` already does. The "not a value you will receive" sentence is
scoped to the envelope level, and the `meta` sentence no longer implies the
four doors ever populated it.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza
* feat(spec): register the client envelope convergence in the ADR-0087 ledger (#13079)
The changeset for this branch carried
`adr-0087: not-required (runtime-interface-only …)` and the gate refused it:
`runtime-interface-only` inherits the migration-prescription refusal, and this
body ships a `## Migration` table. The truthful disposition is `registered`.
The ledger already carries two entries of exactly this class on this package,
landed four days before this branch — `client-delete-result-success` and
`client-meta-reset-result-reset`, both `@objectstack/client` return-shape
moves, both "same call, same wire body", both pure `unwrapResponse`
passthroughs with no `packages/spec` schema movement. This one is the stronger
case of the three: those corrected declarations that were UNINHABITED, so they
revealed a defect rather than breaking working code, whereas this moves reads
that work today.
- `entries/semantic/18.client-envelope-convergence-analytics-automation.ts` —
one `SemanticMigration` for major 18, the open window. surface: the resolved
value of `client.analytics.query` / `.meta` / `.explain` and
`client.automation.trigger`, from the dispatcher's `{ success, data }`
envelope to `data`. replacement: the payload, `r.data.X` -> `r.X`, the four
rows of this branch's own `## Migration` table. reason: one SDK calling
convention, and the wire is byte-identical — this branch's diff touches no
`packages/spec` path at all (`git diff --name-only <merge-base> HEAD --
packages/spec` is empty). `tsc` names every site on the three analytics
methods (TS2339), but NOT on `automation.trigger`: `AutomationResult` itself
declares `success: boolean` and `error?: string`
(`packages/spec/src/contracts/automation-service.ts`, byte-identical at the
merge base and here), so `r.success` / `r.error` compile on both sides while
their subject moves from the envelope to the run. An untyped JS caller has no
channel at all, which is why the ledger entry is the only notification that
reaches it. acceptanceCriteria: no code reads `.data` off the four, and every
branch on `r.success` / `r.error` off `trigger` is re-read by hand.
- `migrations/registry.ts` — regenerated by `gen:migration-registry`
(144 semantic, 75 retired-key, 88 retired-def); never hand-edited.
- The changeset's ADR-0087 marker moves to
`registered client-envelope-convergence-analytics-automation`; the rest of
the file is byte-identical (one line changed).
`gen:spec-changes` and `gen:upgrade-guide` were re-run and write no diff:
`PROTOCOL_VERSION` is 17.0.0, so both artifacts project majors up to 17 and
neither carries any step-18 entry yet — the 2026-08-29 precedent
`client-meta-reset-result-reset` appears zero times in either file too.
Issue anchors live in a source comment at the top of the entry rather than in
its strings: the strings are projected into `spec-changes.json` and
`docs/protocol-upgrade-guide.md` when 18 becomes current, and this repo's issue
numbers do not resolve for the consumers who read those.
Registration requested on #14996; the landing PR is #14526, which stays the
`domain:cli` seat's to land.
Claude-Session: https://claude.ai/code/session_0174WZTU6XcFcS7g2kykC53i
Co-authored-by: Claude <noreply@anthropic.com>
* fix(spec): respell the four methods in the ADR-0087 entry so the #13079 census does not count its prose (#13079)
`packages/client/src/envelope-caller-census.test.ts` (§3, this branch's own
ratchet) walks the whole workspace for `analytics.query|meta|explain (` and
`automation.trigger (` — over comment-masked source, so a docblock is exempt
but a STRING LITERAL is not — and requires every hit to be classified in its
hand ledger. The entry added in 24f2507 wrote the four methods in their
call-site spelling inside its `surface` / `replacement` / `acceptanceCriteria`
prose, so the census counted 9 sites in the entry file and the same 9 in the
generated `registry.ts`: `sdkSites.length` 46 instead of 28, 18 unclassified,
`Test Core (1/6)` red on 24f2507 while the same shard was green on d543e09.
Fixed inside this registration's own surface only. Every mention of the four is
respelled so no `(` follows the method name, whitespace included:
- surface — `client.automation.trigger (the resolved value …)` becomes an em
dash and a colon, no parenthesis and no closing one
- replacement — `client.analytics.query(q)` / `.meta(cube?)` / `.explain(q)` /
`client.automation.trigger(name, payload)` now name their arguments in words
("called with a query", "with or without a cube name", "given a trigger name
and a payload"), and the four rewrite rows keep their `r.data.X` → `r.X`
spelling exactly, which the census does not match
- acceptanceCriteria — the four `client.…()` forms lose their empty parens
⛔ The census test itself is untouched: it is the `domain:cli` seat's file, and
the fix belongs on the side that introduced the text.
Verified with the census's own matcher (its regex, over the tree's own
`maskComments`): the entry file and `registry.ts` now yield 0 hits each, down
from 9 and 9. `pnpm --filter @objectstack/client exec vitest run
src/envelope-caller-census.test.ts` — 14 passed, including
`sdkSites.length === 28`, the mechanical-enumeration-vs-hand-ledger equality and
the zero-unclassified assertion. `registry.ts` regenerated by
`gen:migration-registry`; no other file touched, and the entry's meaning is
unchanged.
Claude-Session: https://claude.ai/code/session_0174WZTU6XcFcS7g2kykC53i
Co-authored-by: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 5c58423 commit db16b94
9 files changed
Lines changed: 900 additions & 227 deletions
File tree
- .changeset
- packages
- client/src
- spec/src/migrations
- entries/semantic
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
Lines changed: 66 additions & 55 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | | - | |
6 | | - | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
39 | | - | |
| 38 | + | |
| 39 | + | |
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
43 | | - | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
44 | 47 | | |
45 | | - | |
46 | | - | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
47 | 51 | | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
52 | 58 | | |
53 | 59 | | |
54 | 60 | | |
| |||
72 | 78 | | |
73 | 79 | | |
74 | 80 | | |
75 | | - | |
76 | | - | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
77 | 85 | | |
78 | 86 | | |
79 | 87 | | |
| |||
299 | 307 | | |
300 | 308 | | |
301 | 309 | | |
302 | | - | |
303 | | - | |
| 310 | + | |
| 311 | + | |
304 | 312 | | |
305 | 313 | | |
306 | | - | |
| 314 | + | |
307 | 315 | | |
308 | 316 | | |
309 | 317 | | |
310 | 318 | | |
311 | 319 | | |
312 | | - | |
313 | | - | |
314 | | - | |
315 | | - | |
316 | | - | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
317 | 326 | | |
318 | 327 | | |
319 | | - | |
| 328 | + | |
320 | 329 | | |
321 | 330 | | |
322 | 331 | | |
323 | 332 | | |
324 | | - | |
| 333 | + | |
325 | 334 | | |
326 | 335 | | |
327 | | - | |
| 336 | + | |
328 | 337 | | |
329 | 338 | | |
330 | | - | |
| 339 | + | |
331 | 340 | | |
332 | | - | |
333 | | - | |
334 | | - | |
335 | | - | |
336 | | - | |
337 | | - | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
338 | 347 | | |
339 | 348 | | |
340 | | - | |
| 349 | + | |
341 | 350 | | |
342 | 351 | | |
343 | | - | |
| 352 | + | |
344 | 353 | | |
345 | 354 | | |
346 | 355 | | |
347 | 356 | | |
348 | 357 | | |
349 | | - | |
350 | | - | |
351 | | - | |
352 | | - | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
353 | 361 | | |
354 | 362 | | |
355 | | - | |
| 363 | + | |
356 | 364 | | |
357 | 365 | | |
358 | | - | |
| 366 | + | |
359 | 367 | | |
360 | | - | |
361 | 368 | | |
362 | | - | |
363 | | - | |
364 | | - | |
365 | | - | |
366 | | - | |
367 | | - | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
368 | 377 | | |
369 | 378 | | |
370 | 379 | | |
| |||
406 | 415 | | |
407 | 416 | | |
408 | 417 | | |
409 | | - | |
410 | | - | |
411 | | - | |
412 | | - | |
413 | | - | |
414 | | - | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
415 | 425 | | |
416 | 426 | | |
417 | 427 | | |
| |||
420 | 430 | | |
421 | 431 | | |
422 | 432 | | |
423 | | - | |
424 | | - | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
425 | 436 | | |
426 | 437 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1546 | 1546 | | |
1547 | 1547 | | |
1548 | 1548 | | |
1549 | | - | |
1550 | | - | |
1551 | | - | |
| 1549 | + | |
| 1550 | + | |
| 1551 | + | |
| 1552 | + | |
1552 | 1553 | | |
1553 | 1554 | | |
1554 | 1555 | | |
| |||
0 commit comments