Repository navigation
Commit f6a04e3
fix(runtime): a flow clone the engine refuses no longer installs the source's empty customization package (#29193)
<!-- claude-projects-attribution: {"github_login":"os-steve"} -->
_Requested by **Steve** · [project
thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi9NoBsyXUn3Gyjgj4BbxoetR)_
Fixes #29016
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:流程克隆接口(不带 package 时)现在先让引擎校验副本,校验通过后才创建源包的 `.custom` 配对包。
- 为什么改:原来先建配对包、后校验,名字非法被 400 拒绝后,包列表里仍多出一个空的 `.custom` 包;被拒绝的写入应该什么都不改变。
- 风险与回滚:只调整克隆接口内部顺序,成功路径的结果不变;回滚即还原本 PR 一个文件的改动。
- 先看:`packages/runtime/src/domains/automation.ts` 的
`resolveCloneTarget`(拆成"先判定、后 land")与 `registerAndSaveFlow` 新增的 `land`
段(失败时撤销注册)。
- 两分钟验证:`pnpm --filter @objectstack/runtime exec vitest run
src/domains/automation-flow-clone-custom-package.test.ts`,预期 17 个用例全绿,其中
`[#29016]` 两例。
- 需要你做的:无,席位落地。
## What changes
`POST /api/v1/automation/:name/clone` with `package` omitted used to
ensure the source's paired customization package `BASE.custom` in
`resolveCloneTarget`, before the engine's registration ran its strict
`FlowSchema` parse. A clone refused `400 VALIDATION_FAILED` for an
illegal machine name therefore left a newly installed, empty pair
behind.
- `resolveCloneTarget` now makes every judgement that needs no pair up
front (the `501` for a protocol that cannot ensure, the
omitted-`package` `400` for a source no package ships, the explicit
target's rule) and returns a `land` step instead of a package id. For an
explicit target, `land` returns the already-judged package; for the
default target it ensures the pair and judges it.
- `registerAndSaveFlow` takes that `land` step in place of the bare
`packageId` and calls it **after** the engine has accepted the
definition and **before** the save. A landing that refuses or throws
undoes the registration through the existing `restoreFlowRegistration`,
the same way a refused save does.
- One validation spelling: the engine's registration stays the only
check of the copy's definition; no second `FlowSchema` parse was added
to the door.
### Refusals after the first possible install, measured
| Refusal | Before | After |
|:---|:---|:---|
| Engine registration (strict parse: name pattern, cycles, node config
keys, expressions) | pair stays | nothing installed (pinned) |
| Authoring rule (`refuseUnauthoredFlowWrite`) | pair stays (it ran
after the ensure) | nothing installed (now runs before `land`) |
| Ensured pair judged not writable by the target rule | pair stays |
pair stays (only knowable after the ensure) |
| Store refuses the save (name already held in the pair, two-package
`409`, store failure) | pair stays | pair stays (needs the store; no
rollback machine added) |
| Permission, walled write | judged before the domain is entered |
unchanged |
The last two rows are listed in the acceptance notes, not fixed here.
## Tests
- New describe `[#29016] a clone the engine refuses installs no pair` in
`automation-flow-clone-custom-package.test.ts`. The rig's engine gains
an opt-in `parse` mode (a strict `FlowSchema.parse`, which is what
`registerFlow` runs first), with a control case (legal name lands in the
ensured pair) and the pin: `Bad-Name!` is refused `400
VALIDATION_FAILED` on `name`, the installed-package list is unchanged,
nothing is persisted as a package, and no copy is registered or stored.
- No existing test was edited. The explicit-target refusal cases still
assert `registerFlow` was never called.
- Ablation: the pair ensured eagerly again in `resolveCloneTarget`
(through `scripts/ablation-replace.mjs`, marker landed 1, anchor 1 to
0), the pin goes red, restored to `git diff HEAD` empty:
```
× an illegal machine name is refused 400 and the package list is unchanged
AssertionError: expected [ 'com.acme.crm', …(4) ] to deeply equal [ Array(4) ]
+ "com.acme.crm.custom",
Tests 1 failed | 16 passed (17)
```
## Acceptance notes
- A clone whose save the store refuses after the pair was ensured (the
new name already stored in the pair but not bound in the engine, or a
store failure) still leaves a freshly ensured pair installed. Reach:
needs a pre-existing stored row or a store fault; the pair is the one
Studio's New would ensure and it is empty. Closing it needs either a
store probe before the ensure or a pair rollback, both outside this
card.
- The default pair being judged not writable right after its own ensure
is only reachable if the ensure door answers a pair this door cannot
write into.
## Verification
All on head `3de5e31ba` (after merging `origin/main` once):
- `pnpm --filter '@objectstack/runtime^...' build` then `vitest run
src/domains/automation` under `os-verify-lock`: Test Files 42 passed,
Tests 766 passed, `VERDICT command-exit 0`.
- `pnpm --filter @objectstack/runtime typecheck`: `VERDICT command-exit
0`.
- `eslint --no-inline-config` on the two touched runtime files: exit 0.
- `dispatch-gates --commands`: 61 derived, 60 run with exit 0 (the
teardown-shape self-test after fetching its pinned fixture commit).
`check:dual-build-cjs-loads` is NOT MEASURED locally (exit 3,
PREREQUISITE NOT MET: needs a full workspace build); CI's run is the
reading.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01ADHkmPX8EnvNFVzRVU5NHx)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent eb14f7a commit f6a04e3
3 files changed
Lines changed: 131 additions & 37 deletions
File tree
- .changeset
- packages/runtime/src/domains
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
| 45 | + | |
45 | 46 | | |
46 | 47 | | |
47 | 48 | | |
| |||
97 | 98 | | |
98 | 99 | | |
99 | 100 | | |
100 | | - | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
101 | 108 | | |
102 | 109 | | |
103 | 110 | | |
| |||
126 | 133 | | |
127 | 134 | | |
128 | 135 | | |
129 | | - | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
130 | 141 | | |
131 | 142 | | |
132 | 143 | | |
| |||
310 | 321 | | |
311 | 322 | | |
312 | 323 | | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
313 | 355 | | |
314 | 356 | | |
315 | 357 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2337 | 2337 | | |
2338 | 2338 | | |
2339 | 2339 | | |
2340 | | - | |
| 2340 | + | |
2341 | 2341 | | |
2342 | 2342 | | |
| 2343 | + | |
| 2344 | + | |
| 2345 | + | |
| 2346 | + | |
2343 | 2347 | | |
2344 | | - | |
2345 | | - | |
| 2348 | + | |
| 2349 | + | |
2346 | 2350 | | |
2347 | 2351 | | |
2348 | 2352 | | |
| |||
2355 | 2359 | | |
2356 | 2360 | | |
2357 | 2361 | | |
| 2362 | + | |
| 2363 | + | |
| 2364 | + | |
| 2365 | + | |
| 2366 | + | |
| 2367 | + | |
| 2368 | + | |
| 2369 | + | |
| 2370 | + | |
| 2371 | + | |
| 2372 | + | |
| 2373 | + | |
| 2374 | + | |
| 2375 | + | |
| 2376 | + | |
2358 | 2377 | | |
2359 | 2378 | | |
2360 | 2379 | | |
| |||
2387 | 2406 | | |
2388 | 2407 | | |
2389 | 2408 | | |
2390 | | - | |
| 2409 | + | |
2391 | 2410 | | |
2392 | 2411 | | |
| 2412 | + | |
| 2413 | + | |
| 2414 | + | |
2393 | 2415 | | |
2394 | 2416 | | |
2395 | 2417 | | |
| |||
2423 | 2445 | | |
2424 | 2446 | | |
2425 | 2447 | | |
2426 | | - | |
2427 | | - | |
2428 | | - | |
2429 | | - | |
| 2448 | + | |
| 2449 | + | |
| 2450 | + | |
| 2451 | + | |
| 2452 | + | |
| 2453 | + | |
| 2454 | + | |
| 2455 | + | |
| 2456 | + | |
| 2457 | + | |
| 2458 | + | |
| 2459 | + | |
2430 | 2460 | | |
2431 | 2461 | | |
2432 | 2462 | | |
2433 | 2463 | | |
2434 | 2464 | | |
2435 | 2465 | | |
2436 | | - | |
| 2466 | + | |
2437 | 2467 | | |
2438 | 2468 | | |
2439 | 2469 | | |
| |||
2453 | 2483 | | |
2454 | 2484 | | |
2455 | 2485 | | |
2456 | | - | |
| 2486 | + | |
| 2487 | + | |
| 2488 | + | |
| 2489 | + | |
| 2490 | + | |
| 2491 | + | |
| 2492 | + | |
| 2493 | + | |
| 2494 | + | |
2457 | 2495 | | |
2458 | | - | |
2459 | | - | |
2460 | | - | |
2461 | | - | |
2462 | | - | |
2463 | | - | |
2464 | | - | |
2465 | | - | |
2466 | | - | |
2467 | | - | |
2468 | | - | |
2469 | | - | |
2470 | | - | |
2471 | | - | |
| 2496 | + | |
| 2497 | + | |
| 2498 | + | |
2472 | 2499 | | |
2473 | | - | |
2474 | | - | |
2475 | | - | |
2476 | | - | |
2477 | | - | |
2478 | | - | |
2479 | | - | |
| 2500 | + | |
| 2501 | + | |
| 2502 | + | |
| 2503 | + | |
| 2504 | + | |
| 2505 | + | |
| 2506 | + | |
| 2507 | + | |
| 2508 | + | |
| 2509 | + | |
| 2510 | + | |
| 2511 | + | |
| 2512 | + | |
| 2513 | + | |
| 2514 | + | |
| 2515 | + | |
| 2516 | + | |
| 2517 | + | |
2480 | 2518 | | |
2481 | 2519 | | |
2482 | 2520 | | |
| |||
3761 | 3799 | | |
3762 | 3800 | | |
3763 | 3801 | | |
3764 | | - | |
| 3802 | + | |
3765 | 3803 | | |
3766 | | - | |
| 3804 | + | |
| 3805 | + | |
| 3806 | + | |
| 3807 | + | |
| 3808 | + | |
3767 | 3809 | | |
3768 | 3810 | | |
3769 | 3811 | | |
| |||
3793 | 3835 | | |
3794 | 3836 | | |
3795 | 3837 | | |
3796 | | - | |
| 3838 | + | |
3797 | 3839 | | |
3798 | 3840 | | |
3799 | 3841 | | |
| |||
3812 | 3854 | | |
3813 | 3855 | | |
3814 | 3856 | | |
3815 | | - | |
| 3857 | + | |
3816 | 3858 | | |
3817 | 3859 | | |
3818 | 3860 | | |
| |||
0 commit comments