Skip to content

Commit e863251

Browse files
docs(skills): name ignore as the seed mode default and the minimal-preset job/queue exception; correct three capability comments (#31377)
<!-- claude-projects-attribution: {"github_login":"huangyiirene"} --> _Requested by **Irene** · [project thread](https://claude.ai/code/project/chan_01TJXtQ1tVD26ecLDZxFS67x?thread=cmsg_01TJXtQ1tVD26ecLDZxFS67xMHHsB36x9Uqo5Pp94AzKsu)_ Fixes #31299 Clause-②: no Metadata-protocol: none `dispatch-gates --tier` reads a contract-review model mandate for `skills/**` (clause ①). That mandate is waived by the maintainer's standing order in this project (2026-11-03). This card ran on the project's default model, and the dispatching seat (domain:skills#3) runs the contract review. ## 维护者速读 - 改了什么:平台技能 § Seed Data 把 `mode` 的默认值从 `upsert` 改为 `ignore`;§ `requires:` 说明 `--preset minimal` 在有 `email`、`approvals` 或 `auth` 时仍保留 `job` 和 `queue`。自动化技能 DocuSign 评测用例 1 的 `expected_output` 不再含它自己禁止的 `connector-esign`,回调写成 `type: 'api'` 流程,并按技能所教用 `config.signature` 校验 DocuSign Connect 自己的签名头。另外三处只改注释:spec 里 `package-registry` 的说明、`os serve` 里 `requires: ['mcp']` 那一句、`app-showcase` 的注释;`app-showcase` 的 `requires` 去掉常开的 `messaging` 和 `job`。 - 为什么改:这六处与 `main` 的代码不符,会教代理错误的默认值和过时的“需要显式开启”读法(#31299,来自 #31297 契约复核的“其他位置”)。 - 风险与回滚:不改行为。技能文字、一条评测用例和注释;`app-showcase` 少列两个常开能力,默认预设下照样挂载。平台 SKILL.md 删掉 Turso 行里重复的一句来付字节,净 -40 字节(5994 / 6011 tokens),不动棘轮。发版 `@objectstack/skills` patch;回滚即 revert。 - 先看:`skills/objectstack-platform/SKILL.md` L296 与 L366;然后 `skills/objectstack-automation/evals/integrations-declared.json` 用例 1。 - 两分钟验证:对照 `packages/spec/src/data/seed.zod.ts` L207(`SeedMode.default('ignore')`)和 `packages/core/src/capability-composition.ts` L86、L135–L138(`NEEDS_JOB_AND_QUEUE`)读两行;`node scripts/check-skills-token-ratchet.mjs`(平台 5994 / 6011)。 - 需要你做的:批准。`check-governed-merges` 判为 Tier H(`skills/**`),需 `os-zhuang` 或 `hotlong` 批准;契约复核全量 PASS 6717563682、增量 PASS 6717774623(`Head-sha` `1ff1c115`),席位已 ACCEPT。 ## The six sites, before and after | # | Site | Before | After | Proof on `main` `e2e6ec7dc` | |:--|:--|:--|:--|:--| | 1 | `skills/objectstack-platform/SKILL.md` L366, § Seed Data | `upsert` named as the `mode` default | `ignore` named as the default; all five modes still listed (byte-neutral swap) | `packages/spec/src/data/seed.zod.ts` L207 `mode: SeedMode.default('ignore')`; `skills/objectstack-data/references/seeds.md` § Import modes already says `ignore` (default) | | 2 | same file L296, § `requires:` | "`--preset minimal` drops exactly those" | "`--preset minimal` drops them; `email`, `approvals` or `auth` keeps `job` and `queue`" | `packages/core/src/capability-composition.ts` L86 `NEEDS_JOB_AND_QUEUE = ['email', 'approvals', 'auth']`, L130-L138: the slate is skipped under `minimal`, then `job` and `queue` are put back when any of those tokens is present; its callers are `serve.ts` L3016, `verify/src/required-providers.ts` L138 and `cli/src/utils/schema-migration-plugins.ts` L2012 | | 3 | `skills/objectstack-automation/evals/integrations-declared.json` case 1 | `expected_output` used the forbidden `connector-esign` and lacked the required `type: 'api'`; it also named a "gap" (Connect's own header unverified, status polled) | "not a new connector package"; "a `type: 'api'` flow with a start-node `secretRef`, and its `config.signature` names DocuSign Connect's own header (…), so status changes arrive verified instead of polled"; the gap sentence is gone. Assertions unchanged | `skills/objectstack-automation/SKILL.md` L364 ("Vendor-signed: `config.signature` replaces it (recipe 4)"), L419-L420; `references/integration-recipes.md` L130-L133 (the `X-DocuSign-Signature-1` block); `packages/spec/src/automation/api-trigger-signature.test.ts` L86 | | 4 | `packages/spec/src/kernel/platform-capabilities.ts` L385-L392, the `'package-registry'` slate note | "That registry keys `marketplace`, not this token, so under `objectstack serve` this entry is inert until the runtime half … lands" | the CLI mounts it through `CAPABILITY_PROVIDERS` (`@objectstack/core`), which keys this token at `PackageServicePlugin`, the provider the spec row declares and the same one `marketplace` resolves to; a stock boot mounts it, one instance when `marketplace` is also declared | `packages/core/src/capability-providers.ts` L174-L178 (`'package-registry'` row) and L164-L173; `serve.ts` L5161-L5167 (`resolverMounted`); `capability-composition.ts` L130-L133. Comment only | | 5 | `packages/cli/src/commands/serve.ts` L3002 | "Explicit `requires: ['mcp']` in config works regardless of the env var." | "Explicit `requires: ['mcp']` still mounts the plugin, but with the env var off the route is not served: `isMcpServerEnabled()` alone decides it." (an authenticated caller gets 404; an anonymous one is refused with 401 first, `mcp.ts` L107-L110) | `packages/runtime/src/domains/mcp.ts` L112-L114 (404 whenever `isMcpServerEnabled()` is false); `core/src/capability-providers.ts` L154-L158 (a declared `mcp` mounts `MCPServerPlugin`); CHANGELOG "New single decision point `isMcpServerEnabled()`" (`packages/cli/CHANGELOG.md` L42383). Comment only | | 6 | `examples/app-showcase` | `objectstack.config.ts` L95-L101 described `messaging` and `job` as needed, L109 listed both; `src/automation/flows/index.ts` L163-L165, L423, L647 told the reader to install them | the two bullets are gone, a comment above `requires` says both are always-on, that a `--preset minimal` boot drops `messaging` and drops `job` only when `email`, `approvals` or `auth` is absent (this app declares `approvals`), and to list there what it drops, and both entries are removed from `requires`; the three flow comments say the same | `packages/spec/src/kernel/platform-capabilities.ts` `PLATFORM_ALWAYS_ON_CAPABILITIES`; `capability-composition.ts` L130-L133 | Case 3, in diff form (one JSON line, shown as the changed phrases): ```diff -A declarative instance inside the app, not a platform plugin and not a `connector-esign` family: +A declarative instance inside the app, not a platform plugin and not a new connector package: -the callback is an `api` flow with a start-node `secretRef`. +the callback is a `type: 'api'` flow with a start-node `secretRef`, and its `config.signature` names DocuSign Connect's own header (`signs: 'body'`, `header: 'X-DocuSign-Signature-1'`, `algorithm: 'hmac-sha256'`, `encoding: 'base64'`), so status changes arrive verified instead of polled. - One gap is named plainly: DocuSign Connect signs its own header, which the `api` door does not verify, so status is polled until vendor schemes are verified. ``` After the edit every `must_contain` entry is in the case's `expected_output` and no `must_not_contain` entry is. The `must_not_contain` list keeps `connector-esign` unchanged, so the case still fails an answer that proposes that package. The gap sentence was removed because the skill now teaches the opposite: a vendor-signed callback is verified through `config.signature`, and recipe 4 gives DocuSign's own header as the example. No assertion was added for the signature block, since the prompt does not name the header. ## `app-showcase`: entries removed, and why `messaging` and `job` are on `PLATFORM_ALWAYS_ON_CAPABILITIES`, so every boot the example is served under (`os dev` / `os serve`, default preset, as in CI's e2e job) mounts both whether listed or not. The platform skill teaches listing them only under `--preset minimal` (`skills/objectstack-automation/SKILL.md` L351). Nothing else reads the example's `requires` list: no example test, `e2e`, `qa` or `scripts` file reads it (grep for `.requires`, `'messaging'`, `'job'`), and no dogfood test boots the example under `--preset minimal`. The one effect of dropping a declared token is that a missing provider would warn instead of failing boot. Both providers are dependencies of `@objectstack/cli` (`packages/cli/package.json` L94, L96), so that cannot happen here. The example's tests and typecheck were run after the change (Gates). ## Token readings (`scripts/check-skills-token-ratchet.mjs`, tokens = ceil((bytes − 20) / 4)) | File | `main` `e2e6ec7dc` | This PR | Ceiling | |:--|:--|:--|:--| | `skills/objectstack-platform/SKILL.md` | 24034 B = 6004 | 23994 B = 5994 | 6011 (unchanged) | - Site 1: 0 B (two mode names swap places). - Site 2: +47 B. - **Deletion (-87 B):** the Turso row of § Driver Selection Guide (L206) loses " — ships with the ObjectStack cloud / enterprise distribution, not the open framework". Fact it held: Turso ships only in the cloud / enterprise distribution, not the open framework. Surviving homes: the same cell's "**Cloud / EE only**" and its next sentence ("The open-core CLI recognizes `libsql://` URLs but **fails loudly**"), and `skills/objectstack-platform/references/operations.md` L152 (`driver-turso` (**cloud / EE only**)). § Driver Selection Guide is not registered in `check-skill-identifier-liveness.mjs` or `check-skill-top-level-keys.mjs`, and no script or test greps the cut text. Net -40 B. No remainder, so `scripts/check-skills-token-ratchet.mjs` is untouched. No rewrap: every untouched line is byte-identical to `main`. L333 (`auth` implies `email`) and L338 (pair `triggers` with `job` under minimal) stay true and are not restated: under `minimal`, `triggers` alone still mounts no `job`. The case-3 sentence removal is the seat's ruling (no objection, 2026-11-08): it sits inside case 1, and the skill now teaches `config.signature` verification (`skills/objectstack-automation/SKILL.md` L364, `references/integration-recipes.md` L130-L133). ## Deviations - should-fix from review 6717563682 applied in 1ff1c11 (two comments) ## Sweep - `skills/objectstack-platform/evals/` and `skills/objectstack-data/` for a seed `upsert` default: none. `objectstack-data/references/seeds.md` § Import modes and the generated `content/docs/references/data/seed.mdx` already say `ignore` (default). - `skills/**` for "drops exactly" or another unqualified minimal-preset claim: `objectstack-platform/evals/config-plugins-ops.json` case 3 says "Only a `--preset minimal` boot drops them" of `job` and `messaging`. Its prompt involves no `email`, `approvals` or `auth`, so it stays true; left alone. The case at L340 (`storage`, `settings`) is outside the exception. - `skills/**` and every eval for `connector-esign`: only the case fixed here. - Tests, ADRs and docs for a claim that an explicit `requires: ['mcp']` serves the route with the env flag off: none. `content/docs/ai/connect-mcp.mdx` L542 already says the 404 means the surface is disabled. So item 5 stays a comment fix, not a `domain:server` card. - No generator emits the spec note: it is a `//` comment inside the array, not a TSDoc block, and no file under `content/docs/` carries its old text. `check:docs` and `check:skill-refs` exit 0. ## Other sites found (not edited) - `packages/spec/src/kernel/platform-capabilities.ts` L348, the TSDoc of `PLATFORM_ALWAYS_ON_CAPABILITIES`: "`objectstack serve --preset minimal` opts out entirely". That is true of the slate but leaves out the `job` / `queue` put-back of `NEEDS_JOB_AND_QUEUE`. It is outside this card's one-comment surface. ## Changeset `.changeset/platform-skill-seed-default-minimal-preset.md`: `'@objectstack/skills': patch`, with `Clause-②: no` and `Metadata-protocol: none`. No `@objectstack/spec` or `@objectstack/cli` entry: their edits are comments only, `Check Changeset` counts changesets per PR (one is present), and AGENTS.md § Post-Task Checklist step 3 asks for one for a change that publishes behaviour. `examples/app-showcase` is `private`. ## Gates `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 103 commands against merge base `e2e6ec7dc`. All 103 ran on head `0ab1aaaa`, and again, re-derived identical, on head `1ff1c115` (the contract review's should-fix, two comment edits) after a full `pnpm build` (exit 0), under `NODE_OPTIONS=--max-old-space-size=8192`: **103 × exit 0, 0 NOT MEASURED** among the listed commands. The CI-only families dispatch-gates names as not locally measurable (shard attestation, Build Core steps, type-check lanes, dogfood jobs) are left to CI. Per-command records: project files `card-31299/gates-0ab1aaaa.txt` and `card-31299/gates-1ff1c115.txt` (the latter also carries `example-showcase` and `cli` typecheck, exit 0). The order's named checks: `pnpm check:skill-identifier-liveness`, `pnpm --filter @objectstack/spec run check:skill-refs` and `node scripts/check-skills-token-ratchet.mjs` (platform 5994 / 6011) are in that list and exit 0. Run beside it, since dispatch-gates derives no test family for these paths: - `pnpm --filter @objectstack/spec run check:skill-examples` :: exit 0 - `pnpm --filter @objectstack/example-showcase run typecheck` :: exit 0 - `pnpm --filter @objectstack/example-showcase test` :: exit 0 (544 passed) - `pnpm --filter @objectstack/cli run typecheck` :: exit 0 - `pnpm --filter @objectstack/spec exec tsc --noEmit` :: exit 0 - `node scripts/check-commit-card-trailers.mjs --range origin/main..HEAD` :: exit 0 - `node scripts/pm/check-governed-merges.mjs --branch HEAD` :: Tier H (`skills/**` ×2) `origin/main` moved to `f4b4c8aeb` during the run. Only `serve.ts` changed underneath this diff, away from the edited sentence, and `git merge-tree` merges cleanly. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01J8VVAmBZAddKTWUJs6Xnq2 <!-- signed: domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7 --> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 405a78e commit e863251

7 files changed

Lines changed: 36 additions & 26 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@objectstack/skills': patch
3+
---
4+
5+
Clause-②: no
6+
Metadata-protocol: none
7+
8+
`objectstack-platform`: § Seed Data now names `ignore` as the seed `mode` default (`SeedMode` defaults to `ignore`, not `upsert`), and § `requires:` says that `--preset minimal` keeps `job` and `queue` when `email`, `approvals` or `auth` is present instead of dropping every always-on token. `objectstack-automation`'s DocuSign eval case no longer forbids a string its own model answer uses, and its model answer now verifies DocuSign Connect's own signature header through `config.signature` instead of polling.

‎examples/app-showcase/objectstack.config.ts‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,21 +92,21 @@ export default defineStack({
9292
// • automation — AutomationServicePlugin (flow engine + node executors).
9393
// • approvals — ApprovalsServicePlugin, so the `approval` flow node
9494
// (ADR-0019) is contributed to the engine.
95-
// • messaging — MessagingServicePlugin, so the `notify` node delivers to
96-
// the inbox channel (`sys_inbox_message` rows) instead of
97-
// degrading to a logged no-op.
9895
// • triggers — record-change + schedule FlowTrigger plugins, so the
9996
// autolaunched / schedule flows below actually auto-fire.
100-
// • job — JobServicePlugin, the timing backend the schedule trigger
101-
// delegates to (interval / cron jobs).
10297
// • marketplace — PackageServicePlugin (sys_packages store). Enables the AI
10398
// blueprint flow to auto-create a writable "app package" home
10499
// (ADR-0033 zero-package app building) and the Studio package
105100
// selector to list DB packages.
106101
// • mailbox — MailboxServicePlugin: the inbound-mail objects
107102
// (`sys_mailbox`, `sys_mail_message`, `sys_mail_association`)
108103
// and their read gates, served through the data API.
109-
requires: ['ui', 'automation', 'approvals', 'messaging', 'triggers', 'job', 'marketplace', 'webhooks', 'realtime', 'mailbox'],
104+
// Not listed: `messaging` (the `notify` node's inbox delivery) and `job` (the
105+
// timing backend the schedule trigger delegates to) are always-on core
106+
// capabilities that every boot mounts, listed or not. A `--preset minimal`
107+
// boot drops `messaging`, and drops `job` only when `email`, `approvals`
108+
// or `auth` is absent; there, list what it drops.
109+
requires: ['ui', 'automation', 'approvals', 'triggers', 'marketplace', 'webhooks', 'realtime', 'mailbox'],
110110

111111
// Concrete connectors for the `connector_action` node. The baseline engine
112112
// ships the dispatch node + an empty registry; these plugins populate it.

‎examples/app-showcase/src/automation/flows/index.ts‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ export const ReassignWizardFlow = defineFlow({
160160
* recipient + message to the messaging service, which fans out to the user's
161161
* channels (inbox by default). The `notify` node ships in every automation
162162
* engine; delivery is backed by `@objectstack/service-messaging`
163-
* (`MessagingServicePlugin`). Without that plugin the node degrades to a
164-
* logged no-op instead of failing the flow — install it and this flow starts
165-
* landing inbox rows with no edit.
163+
* (`MessagingServicePlugin`), always-on: every boot mounts it unless
164+
* `--preset minimal` drops it. Without that plugin the node degrades to a
165+
* logged no-op instead of failing the flow.
166166
*/
167167
export const TaskAssignedNotifyFlow = defineFlow({
168168
name: 'showcase_task_assigned_notify',
@@ -420,8 +420,9 @@ export const TaskCompletedSlackFlow = defineFlow({
420420
* switch or the posture, so a finding here would be false for the default
421421
* deployment.
422422
*
423-
* Install `requires: ['automation', 'triggers', 'job', 'messaging']` for the
424-
* binding machinery this example demonstrates.
423+
* Install `requires: ['automation', 'triggers']` for the binding machinery
424+
* this example demonstrates (`job` and `messaging` are always-on; list them
425+
* too only under `--preset minimal`).
425426
*/
426427
export const ScheduledDigestFlow = defineFlow({
427428
name: 'showcase_scheduled_digest',
@@ -643,8 +644,8 @@ export const ShowcaseMcpConnectorEchoFlow = defineFlow({
643644
* resumed by an external `resume(runId)` (it never silently no-ops).
644645
*
645646
* A short demo delay keeps it observable in-session; a production reminder would
646-
* use e.g. `timerDuration: 'P3D'`. Install
647-
* `requires: ['automation', 'triggers', 'job', 'messaging']`.
647+
* use e.g. `timerDuration: 'P3D'`. Install `requires: ['automation', 'triggers']`
648+
* (`job` and `messaging` are always-on; list them too only under `--preset minimal`).
648649
*/
649650
export const TaskFollowUpFlow = defineFlow({
650651
name: 'showcase_task_follow_up',

‎packages/cli/src/commands/serve.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2999,7 +2999,8 @@ export default class Serve extends Command {
29992999
// on the SAME decision point (`isMcpServerEnabled`), so serving the
30003000
// route without also loading the MCP plugin would 501 every request
30013001
// (#2698: the default must yield a connectable MCP endpoint). Explicit
3002-
// `requires: ['mcp']` in config works regardless of the env var.
3002+
// `requires: ['mcp']` still mounts the plugin, but with the env var off
3003+
// the route is not served: `isMcpServerEnabled()` alone decides it.
30033004
// - Pinyin search recall (#2486): locale-gated platform capability. When
30043005
// `OS_SEARCH_PINYIN_ENABLED` is unset, the default derives from the
30053006
// stack's configured locales (any `zh-*` → on), and the resolved

‎packages/spec/src/kernel/platform-capabilities.ts‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -382,14 +382,14 @@ export const PLATFORM_ALWAYS_ON_CAPABILITIES: readonly string[] = Object.freeze(
382382
// this slate (its only hard requirement is the ObjectQL engine, which is not
383383
// a capability token), so it joins the TAIL like any other reader.
384384
//
385-
// ⚠️ SCOPE, measured on `serve`'s capability resolver at c17ff70f3f: a slate
386-
// entry is force-appended to every app's `requires`, and the CLI then mounts
387-
// it only if `Serve.CAPABILITY_PROVIDERS` keys the token. That registry keys
388-
// `marketplace`, not this token, so under `objectstack serve` this entry is
389-
// inert until the runtime half of the same ruling lands (#17676 items 2/3/5,
390-
// the engine lane). The declaration is deliberately first: it is the single
391-
// list both runtimes read, and the thing the runtime half is written
392-
// against.
385+
// Mounting: a slate entry joins every boot's served tokens
386+
// (`resolveServedCapabilities`, `@objectstack/core`) unless the preset is
387+
// `minimal`, and the CLI mounts it through `CAPABILITY_PROVIDERS`
388+
// (`@objectstack/core`, `capability-providers.ts`). That registry keys this
389+
// token at `@objectstack/service-package`'s `PackageServicePlugin`, the
390+
// provider `PLATFORM_CAPABILITY_PROVIDERS` declares and the same one
391+
// `marketplace` resolves to, so a stock `objectstack serve` boot mounts it;
392+
// an app that also declares `marketplace` gets one instance, not two.
393393
'package-registry',
394394
]);
395395

‎skills/objectstack-automation/evals/integrations-declared.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
{
55
"id": 1,
66
"prompt": "Our contract-lifecycle app (objects `contract`, `crm_account`) needs DocuSign: send a contract out for signature, read an envelope's status, and reflect status changes on the record. DocuSign publishes a 4.7 MB Swagger 2.0 document with several hundred operations, authenticates with OAuth 2.0, and its Connect webhooks sign posts with their own HMAC header. Propose what to build and where.",
7-
"expected_output": "A declarative instance inside the app, not a platform plugin and not a `connector-esign` family: `defineConnector` with `provider: 'openapi'`, whose `providerConfig.spec` is a packaged OpenAPI 3.x document converted offline from the Swagger 2.0 document and trimmed to the three operations (create envelope, get envelope, list status changes) (or `providerConfig.include` names those three operation keys, the `mcp` provider's allowlist meaning, where a non-array or unknown entry is fatal). Fields on `contract` (`envelope_id`, `signature_status`). Flows dispatch `connector_action`; the callback is an `api` flow with a start-node `secretRef`. `auth` is `{ type: 'oauth2', grant: 'authorization_code', authorizationUrl, tokenUrl, scopes, clientId, credentialRef }`, the client secret only a `credentialRef` (no inline `clientSecret`, no short-lived token parked behind a `bearer` `credentialRef`): the built-in `openapi` provider obtains and refreshes the token per dispatch, and the instance stays degraded \"not connected\" until an administrator holding `manage_connector_connections` connects it once per organization (`POST /api/v1/automation/connectors/docusign/connection`, then the vendor's redirect to `GET …/connectors/oauth/callback`; `DELETE` revokes). One gap is named plainly: DocuSign Connect signs its own header, which the `api` door does not verify, so status is polled until vendor schemes are verified. `connectorConfig.input` is a value slot: the per-contract payload reads the record through a CEL envelope (`envelopeId: { dialect: 'cel', source: 'record.envelope_id' }`), judged against the action's `inputSchema` before dispatch. The answer proposes no `registerConnector` code and no plugin.",
7+
"expected_output": "A declarative instance inside the app, not a platform plugin and not a new connector package: `defineConnector` with `provider: 'openapi'`, whose `providerConfig.spec` is a packaged OpenAPI 3.x document converted offline from the Swagger 2.0 document and trimmed to the three operations (create envelope, get envelope, list status changes) (or `providerConfig.include` names those three operation keys, the `mcp` provider's allowlist meaning, where a non-array or unknown entry is fatal). Fields on `contract` (`envelope_id`, `signature_status`). Flows dispatch `connector_action`; the callback is a `type: 'api'` flow with a start-node `secretRef`, and its `config.signature` names DocuSign Connect's own header (`signs: 'body'`, `header: 'X-DocuSign-Signature-1'`, `algorithm: 'hmac-sha256'`, `encoding: 'base64'`), so status changes arrive verified instead of polled. `auth` is `{ type: 'oauth2', grant: 'authorization_code', authorizationUrl, tokenUrl, scopes, clientId, credentialRef }`, the client secret only a `credentialRef` (no inline `clientSecret`, no short-lived token parked behind a `bearer` `credentialRef`): the built-in `openapi` provider obtains and refreshes the token per dispatch, and the instance stays degraded \"not connected\" until an administrator holding `manage_connector_connections` connects it once per organization (`POST /api/v1/automation/connectors/docusign/connection`, then the vendor's redirect to `GET …/connectors/oauth/callback`; `DELETE` revokes). `connectorConfig.input` is a value slot: the per-contract payload reads the record through a CEL envelope (`envelopeId: { dialect: 'cel', source: 'record.envelope_id' }`), judged against the action's `inputSchema` before dispatch. The answer proposes no `registerConnector` code and no plugin.",
88
"files": [],
99
"assertions": {
1010
"must_contain": ["defineConnector", "provider: 'openapi'", "credentialRef", "connector_action", "type: 'api'", "secretRef", "Swagger 2.0", "oauth2", "authorization_code", "/connection"],

‎skills/objectstack-platform/SKILL.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ Drivers are the storage layer:
203203
| **SQL** | `@objectstack/driver-sql` | Production (PostgreSQL, MySQL, SQLite) | `SqlDriver` — Knex.js under the hood (`pg` / `mysql` / `better-sqlite3` clients) |
204204
| **MongoDB** | `@objectstack/driver-mongodb` | Production (document store) | `MongoDBDriver` |
205205
| **SQLite WASM** | `@objectstack/driver-sqlite-wasm` | Browser / WebContainer | `SqliteWasmDriver` — in-process, no server |
206-
| **Turso** | `@objectstack/driver-turso` | Edge, serverless, multi-tenant | **Cloud / EE only** — ships with the ObjectStack cloud / enterprise distribution, not the open framework. The open-core CLI recognizes `libsql://` URLs but **fails loudly** (`UnsupportedDriverError`) |
206+
| **Turso** | `@objectstack/driver-turso` | Edge, serverless, multi-tenant | **Cloud / EE only**. The open-core CLI recognizes `libsql://` URLs but **fails loudly** (`UnsupportedDriverError`) |
207207

208208
### Wiring a driver — you usually do not
209209

@@ -293,7 +293,7 @@ CLI: `os serve` / `os dev`
293293
### `requires:` — which service plugins boot
294294

295295
Step 4's list is the fixed core. Tokens marked ° are always-on: every boot
296-
mounts them, listed or not, and `--preset minimal` drops exactly those. Every
296+
mounts them, listed or not, and `--preset minimal` drops them; `email`, `approvals` or `auth` keeps `job` and `queue`. Every
297297
other service plugin is opt-in (`requires: [...]` on the stack root turns it on) but the host defaults, mounted under every preset: `mcp` unless `OS_MCP_SERVER_ENABLED=false`, and `pinyin-search` when `i18n` names a `zh-*` locale (`OS_SEARCH_PINYIN_ENABLED` overrides). The CLI expands each
298298
token through the `CAPABILITY_PROVIDERS` registry in
299299
`@objectstack/core`:
@@ -363,7 +363,7 @@ The stack's `data:` collection is authored with `defineSeed()`, which
363363
**objectstack-data** owns — go there for `externalId` matching, `env:` scoping,
364364
and which keys are derived.
365365

366-
`mode` (`upsert` default · `insert` · `update` · `ignore` · `replace` ⚠️ **data
366+
`mode` (`ignore` default · `upsert` · `insert` · `update` · `replace` ⚠️ **data
367367
loss**) decides what a replay does to rows that already exist —
368368
[Import modes](../objectstack-data/references/seeds.md#import-modes).
369369

0 commit comments

Comments
 (0)