|
| 1 | +--- |
| 2 | +"@objectstack/spec": minor |
| 3 | +"@objectstack/service-automation": patch |
| 4 | +"@objectstack/runtime": patch |
| 5 | +--- |
| 6 | + |
| 7 | +fix(spec,runtime,service-automation): `IAutomationService` declares the connector registry it already serves (#4127) |
| 8 | + |
| 9 | +The fourth and last of the dispatcher call sites #4127 found calling a method its |
| 10 | +contract never declared. The first three shipped in #4143; this one was held back |
| 11 | +because the fix is a **type move**, not a type addition — `ConnectorDescriptor` |
| 12 | +was declared in `@objectstack/service-automation`'s engine, which is one |
| 13 | +*implementation* of `IAutomationService`. A contract cannot name a type that |
| 14 | +lives inside its own implementation, so `getConnectorDescriptors` could not be |
| 15 | +declared at all until the type had a home in the spec. |
| 16 | + |
| 17 | +**`IAutomationService` += `getConnectorDescriptors?()`.** It is the sibling of |
| 18 | +`getActionDescriptors`, which the contract has declared since ADR-0018: the two |
| 19 | +fill the flow designer's `connector_action` node together — node vocabulary from |
| 20 | +one, the connector → action → input pickers from the other. Only one of them was |
| 21 | +written down. `GET /api/v1/automation/connectors` has served the other since |
| 22 | +ADR-0022 by probing for the method and then re-typing its own result as `any` to |
| 23 | +filter on `?type=`, which is a filter on a field the type system did not know |
| 24 | +existed — one typo from silently matching nothing and answering an empty |
| 25 | +registry, which is also what this route legitimately returns when the method is |
| 26 | +absent, so the failure had no distinguishable symptom. |
| 27 | + |
| 28 | +Optional for the same reason `getActionDescriptors` is: a connector registry is a |
| 29 | +capability of the flow-engine implementation, not a property of every automation |
| 30 | +slot. A script-runner filling the slot has no connectors to describe, and the |
| 31 | +route answers an empty registry rather than a 404 — the `handlerReady` posture |
| 32 | +does not apply, since the slot is serveable and only this capability is absent. |
| 33 | + |
| 34 | +**`ConnectorDescriptor` / `ConnectorActionDescriptor` / `ConnectorOrigin` / |
| 35 | +`ConnectorState` move to `@objectstack/spec/integration`**, beside the ADR-0097 |
| 36 | +provider contract, for the reason that file already states about itself: they are |
| 37 | +pure types, so a connector plugin — or a designer client, or the dispatcher — |
| 38 | +speaks about registered connectors depending only on the spec, with no runtime |
| 39 | +coupling to the engine. `ConnectorOrigin` is ADR-0097 §4 vocabulary and |
| 40 | +`ConnectorState` is #3017 vocabulary; neither was ever engine-private in meaning, |
| 41 | +only in location. |
| 42 | + |
| 43 | +Nothing is renamed and no shape changes. `@objectstack/service-automation` |
| 44 | +imports the four back and re-exports them from its index — the same names, from |
| 45 | +the same entry point — so every existing importer compiles unchanged. |
| 46 | +`ConnectorState` joins that re-export, which it should have been in all along: it |
| 47 | +is a required field of the descriptor the index has always exported. |
| 48 | + |
| 49 | +**The test fixture had already drifted, which is the concrete cost.** The |
| 50 | +dispatcher's connector mock declared `{ name, label, type, actions }` and omitted |
| 51 | +`origin` and `state` — both **required** on `ConnectorDescriptor`, and both the |
| 52 | +fields a designer reads to tell a live declarative instance from a plugin one |
| 53 | +(ADR-0097 §4), or a dispatchable connector from a degraded one that is listed |
| 54 | +honestly rather than hidden (#3017). Nothing caught it, because an undeclared |
| 55 | +return type cannot be checked against. The fixture is typed now, so it cannot |
| 56 | +drift again, and a new test pins that `origin` / `state` / `degradedReason` |
| 57 | +survive the hop through the route rather than only `name` and `type`. |
| 58 | + |
| 59 | +Verified: `@objectstack/spec` **7089 tests / 272 files** (2 new contract tests), |
| 60 | +`@objectstack/service-automation` **457 / 41**, `@objectstack/runtime` |
| 61 | +**218 http-dispatcher tests** (1 new), `tsc --noEmit`, `pnpm lint`, the liveness |
| 62 | +and empty-state gates, and the three generated-artifact gates — all clean. |
0 commit comments