Skip to content

Commit 626d444

Browse files
committed
test(objectql): re-pin duplicatePackage's refused-copy case to the flow door's refusal
Claude-Session: https://claude.ai/code/session_019oFY6Hi35J7atvgVFnmoaK Co-authored-by: Claude <noreply@anthropic.com>
1 parent d5d247e commit 626d444

2 files changed

Lines changed: 9 additions & 4 deletions

File tree

‎.changeset/24669-flow-trigger-out-of-closure.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ Clause-②: yes (narrowing)
1212

1313
**BREAKING — what moves for consumers.** This is an accept-set narrowing on the metadata save door, shipped as `minor` under the launch-window convention for accept-set narrowings (`.changeset/pre.json` is in `exit` mode, so the next version pass cuts 18.0.0 and this change ships in it).
1414

15-
- FROM: a publish-mode write of a flow into a package, triggered on or sweeping an object outside the package's closure, answered `200` and was stored, with a `flow-trigger-unknown-object` save advisory. This covers `PUT /api/v1/meta/flow/:name?package=…` (and `saveMetaItem` in publish mode), the promotion of a draft (`POST /api/v1/meta/flow/:name/publish`, `publishMetaItem`) and a package draft publish (`publishPackageDrafts`).
16-
- TO: the same writes answer `422 INVALID_METADATA`, with the `flow-trigger-unknown-object` issue at `error` at the trigger key, and nothing is stored. A package draft publish fails the item, and the batch with it.
15+
- FROM: a publish-mode write of a flow into a package, triggered on or sweeping an object outside the package's closure, answered `200` and was stored, with a `flow-trigger-unknown-object` save advisory. This covers `PUT /api/v1/meta/flow/:name?package=…` (and `saveMetaItem` in publish mode), the promotion of a draft (`POST /api/v1/meta/flow/:name/publish`, `publishMetaItem`), a package draft publish (`publishPackageDrafts`), and a package copy (`duplicatePackage`), which writes its copies through the same door.
16+
- TO: `saveMetaItem` in publish mode, the draft promotion and `publishPackageDrafts` answer `422 INVALID_METADATA`, with the `flow-trigger-unknown-object` issue at `error` at the trigger key, and nothing is stored. A package draft publish fails the item, and the batch with it. In `duplicatePackage`, a copied flow whose trigger object stays outside the copy package's closure is refused with the same rule and listed in its `failed[]`. One way that happens is when that object's own copy was refused.
1717
- Fix: declare a dependency on the package that defines the trigger object in the `dependencies` of the writing package's manifest, or trigger the flow on an object the package may reach (its own, a declared dependency's, or a platform object). Then save again. Saving the flow as a draft (`mode: 'draft'`) is still allowed, because drafts are never gated; publishing that draft is judged.
1818

1919
**The next save of a stored flow whose trigger object is outside its package's closure is refused with the fix; stored flows keep loading and firing until then.** The door judges writes only. A stored row is not re-judged at boot.

‎packages/objectql/src/protocol-duplicate-package-unprefixed-object.test.ts‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,8 @@ describe('ADR-0070 D4 — duplicatePackage of an object whose name lacks the sou
305305
const res = await protocol.duplicatePackage({ sourcePackageId: P, targetPackageId: Q });
306306

307307
expect(res.success).toBe(false);
308-
expect(res.failed).toHaveLength(2);
309-
const [refusal, viewRefusal] = res.failed;
308+
expect(res.failed, JSON.stringify(res.failed)).toHaveLength(3);
309+
const [refusal, viewRefusal, flowRefusal] = res.failed;
310310
expect(refusal).toMatchObject({ type: 'object', name: 'ticket' });
311311
// Located: the object, the name it would take, who holds that name,
312312
// and the source rename that clears it.
@@ -319,6 +319,11 @@ describe('ADR-0070 D4 — duplicatePackage of an object whose name lacks the sou
319319
// closure — and the save door refuses it with the same rule.
320320
expect(viewRefusal).toMatchObject({ type: 'view', name: 'ticket_views' });
321321
expect(viewRefusal.error).toContain('views[0].object [list-view-object-outside-closure]');
322+
// [#24669] And the copy of `dupsrc_on_ticket` keeps the source's
323+
// `ticket` as its trigger object, outside the copy package's closure
324+
// too, so the flow door refuses it — the same verdict, at the third door.
325+
expect(flowRefusal).toMatchObject({ type: 'flow' });
326+
expect(flowRefusal.error).toContain('flows[0].nodes[0].config.objectName [flow-trigger-unknown-object]');
322327

323328
// NEGATIVE CONTROL: the prefixed sibling took the name, with its own
324329
// body, and nothing of `ticket` was written under it.

0 commit comments

Comments
 (0)