Repository navigation
Commit ab75996
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} -->
_Requested by **Elon** · [project
thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9DU7tsm5bu7hCcGfaFJtkLYA)_
Fixes #27977
domain:server#3 · os-elon-musk · session_016WV4cx4GVsYbtK2oE4scBf
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:只加一个测试文件 `connector-definition-cluster.test.ts`,用两个内核(各自
ObjectQLPlugin 元数据协议 + 自动化插件)共享一个 SQLite 文件和一条总线,测量「在 A 上发布改过的连接器定义,B
会不会跟着重建」。不改任何运行时代码。
- 为什么改:#27428 的裁决 6513279565 要求单独测量这一点。结论:B 不跟。lane 2 把变更送到了 B
的协议监听器,但自动化插件的监听只认 `flow`,`metadata:reloaded` 又只在本内核触发,所以 B
一直用旧定义,直到重载或重启。缺口以 `it.fails` 钉住,修复卡是 #28002。
- 风险与回滚:零运行时风险,测试不进发布包(`files` 只发 `dist`)。回滚即删掉这个文件。
-
先看:`packages/services/service-automation/src/connector-definition-cluster.test.ts`,`it.fails`
那一例和其后的对照例。
- 两分钟验证:`pnpm --filter @objectstack/service-automation exec vitest run
src/connector-definition-cluster.test.ts`,预期 `2 passed | 1 expected fail
(3)`。
- 需要你做的:无,席位落地。
## What changes
One new test file,
`packages/services/service-automation/src/connector-definition-cluster.test.ts`,
built like `connector-credential-cluster.test.ts` (#27941): two
`ObjectKernel` replicas, each running `ObjectQLPlugin`'s metadata
protocol and `AutomationServicePlugin`, over ONE better-sqlite3 file
both open, joined by a bus that delivers every publish to every
subscriber (publisher included). Each replica is attached the way
`MetadataClusterBridgePlugin` attaches it at `kernel:ready`: lane 2
(`attachMetadataMutationPubSub`) and lane 4
(`attachConnectorCredentialPubSub`). Lane 1 (`metadata.changed`) is not
attached: it replays into a `MetadataManager`'s caches, and the
connector reconcile reads the ObjectQL registry and the protocol's
execution view, never that manager.
A definition change is published on A through the per-item door (a draft
`saveMetaItem`, then `publishMetaItem`), changing
`providerConfig.endpoint` from V1 to V2.
## Measurement
| | result |
|:--|:--|
| A, the publishing replica | re-materializes with V2 (ObjectQLPlugin
announces A's own `metadata:reloaded` after the per-item publish) |
| lane 2 to B | delivered: B's protocol replays `connector/NAME` into
B's mutation listeners |
| B's live instance, no reload on B | **does not converge**: B's
provider is never called (`expected undefined to be
'https://v2.billing.example.test'`) |
| control: `metadata:reloaded` on B | B materializes V2 from its own
read of the shared store |
Cause, read from the code: `subscribeFlowMutations` in `plugin.ts`
returns early for any mutation whose type is not `flow`, and
`metadata:reloaded` is a kernel-local hook a peer never receives. So the
gap is the trigger, not the store or the read. The lane choice for the
fix belongs to #28002.
## Tests
- `connector-definition-cluster.test.ts`: `Tests 2 passed | 1 expected
fail (3)`.
- Harness health, a plain `it`: A converges and lane 2 reaches B. This
keeps the `it.fails` from passing on a broken harness.
- The gap, `it.fails` naming #27977 and #28002: B converges with no
reload on B. Its failure was read with the case temporarily run as a
plain `it`: the one assertion that fails is B's last endpoint,
`undefined` instead of V2.
- Control, a plain `it`: B holds no instance before the reload, and
holds V2 after it.
- `pnpm --filter @objectstack/service-automation test`: `Test Files 222
passed (222) · Tests 2832 passed | 1 expected fail (2833)`, lock VERDICT
command-exit 0.
- `pnpm --filter @objectstack/service-automation typecheck`: lock
VERDICT command-exit 0.
## Acceptance notes
- Side finding, same root, measured with a throwaway probe that is not
committed: a direct active save (`saveMetaItem` with no mode, what `PUT
/api/v1/meta/connector/:name` calls) does not re-materialize even on the
writing replica. A stayed on V1 after saving V2, and its listeners heard
the mutation. The seat recorded it on #28002.
- No changeset (`skip-changeset`): the package publishes only `dist`.
After `pnpm --filter @objectstack/service-automation build`, `grep` for
the test's names in `dist` gave 0 hits, and the positive control
`AutomationServicePlugin` gave 4 files.
## Verification
Head `022ad12c`, base `46943657`.
<details><summary>Derived gate families and lint</summary>
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 50 families over the 1 changed path.
49 exited 0. `pnpm check:dual-build-cjs-loads` exited 3 (PREREQUISITE
NOT MET: it needs every package's `dist` in this worktree), so it is NOT
MEASURED locally and CI runs it. `check-plugin-teardown-shape
--self-test` exited 3 on the shallow clone and 0 after `git fetch
--unshallow`. `--ran` reconciliation: `50 derived, 49 run, 1
NOT-MEASURED, 0 UNRUN`. `pnpm lint` exited 0.
</details>
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(Not touched.)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes.
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset: nothing published,
`skip-changeset`.
- [x] 6. `packages/spec` touched: not touched.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English.
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
---
_Generated by [Claude
Code](https://claude.ai/code/session_016WV4cx4GVsYbtK2oE4scBf)_
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_016WV4cx4GVsYbtK2oE4scBf
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 0aac0bf commit ab75996
1 file changed
Lines changed: 219 additions & 0 deletions
| 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 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
0 commit comments