@smthrs/flow 1.0.0-rc.13 → 1.0.0-rc.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Resume compatibility is weaker than result reuse: unchanged callback source
3
+ * may rebuild a recorded plan, but an opaque closure still cannot earn a cache
4
+ * hit. Only the interpreter's PlanRecorded guard uses this projection. Approval
5
+ * digests and dispatch keys keep the original entropy-bearing material.
6
+ *
7
+ * @since 1.0.0
8
+ * @internal
9
+ */
10
+ import { isRecord } from "@smthrs/canonical/Record";
11
+ import * as Graph from "../Graph.js";
12
+ /** Missing source metadata retains the old identity and fails closed. */
13
+ const callback = (value) => isRecord(value) && value._tag === "FunctionIdentity" && value.algorithm === "sha256-source-ephemeral/v4" &&
14
+ typeof value.sourceDigest === "string"
15
+ ? { _tag: value._tag, algorithm: value.algorithm, digest: value.sourceDigest }
16
+ : value;
17
+ /** Project only callback slots, never identity-shaped application data. */
18
+ const body = (value) => {
19
+ if (!isRecord(value))
20
+ return value;
21
+ switch (value._tag) {
22
+ case "FlowCall":
23
+ return isRecord(value.declaration)
24
+ ? { ...value, declaration: { ...value.declaration, body: callback(value.declaration.body) } }
25
+ : value;
26
+ case "Map":
27
+ return { ...value, mapper: callback(value.mapper) };
28
+ case "AndThen":
29
+ return { ...value, continuation: callback(value.continuation) };
30
+ case "Branch":
31
+ return { ...value, predicate: callback(value.predicate) };
32
+ case "Catch":
33
+ return { ...value, filterIdentity: callback(value.filterIdentity) };
34
+ default:
35
+ return value;
36
+ }
37
+ };
38
+ /**
39
+ * The same drafts, with only callback identities made restart-comparable.
40
+ *
41
+ * @since 1.0.0
42
+ * @private
43
+ */
44
+ export const recordedPlanDrafts = (graph) => Graph.drafts(graph).map((draft) => ({ ...draft, material: { ...draft.material, body: body(draft.material.body) } }));
45
+ //# sourceMappingURL=RecordedPlan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecordedPlan.js","sourceRoot":"","sources":["../../../src/internal/RecordedPlan.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAEnD,OAAO,KAAK,KAAK,MAAM,aAAa,CAAA;AAEpC,yEAAyE;AACzE,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAW,EAAE,CAC3C,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,IAAI,KAAK,CAAC,SAAS,KAAK,4BAA4B;IACtG,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ;IACtC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,YAAY,EAAE;IAC9E,CAAC,CAAC,KAAK,CAAA;AAEX,2EAA2E;AAC3E,MAAM,IAAI,GAAG,CAAC,KAAc,EAAW,EAAE;IACvC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAClC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,UAAU;YACb,OAAO,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC;gBAChC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,WAAW,EAAE,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE;gBAC7F,CAAC,CAAC,KAAK,CAAA;QACX,KAAK,KAAK;YACR,OAAO,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAA;QACrD,KAAK,SAAS;YACZ,OAAO,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAA;QACjE,KAAK,QAAQ;YACX,OAAO,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAA;QAC3D,KAAK,OAAO;YACV,OAAO,EAAE,GAAG,KAAK,EAAE,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAA;QACrE;YACE,OAAO,KAAK,CAAA;IAChB,CAAC;AACH,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAkB,EAAiC,EAAE,CACtF,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA","sourcesContent":["/**\n * Resume compatibility is weaker than result reuse: unchanged callback source\n * may rebuild a recorded plan, but an opaque closure still cannot earn a cache\n * hit. Only the interpreter's PlanRecorded guard uses this projection. Approval\n * digests and dispatch keys keep the original entropy-bearing material.\n *\n * @since 1.0.0\n * @internal\n */\n\nimport { isRecord } from \"@smthrs/canonical/Record\"\nimport type * as Plan from \"@smthrs/plan/Plan\"\nimport * as Graph from \"../Graph.ts\"\n\n/** Missing source metadata retains the old identity and fails closed. */\nconst callback = (value: unknown): unknown =>\n isRecord(value) && value._tag === \"FunctionIdentity\" && value.algorithm === \"sha256-source-ephemeral/v4\" &&\n typeof value.sourceDigest === \"string\"\n ? { _tag: value._tag, algorithm: value.algorithm, digest: value.sourceDigest }\n : value\n\n/** Project only callback slots, never identity-shaped application data. */\nconst body = (value: unknown): unknown => {\n if (!isRecord(value)) return value\n switch (value._tag) {\n case \"FlowCall\":\n return isRecord(value.declaration)\n ? { ...value, declaration: { ...value.declaration, body: callback(value.declaration.body) } }\n : value\n case \"Map\":\n return { ...value, mapper: callback(value.mapper) }\n case \"AndThen\":\n return { ...value, continuation: callback(value.continuation) }\n case \"Branch\":\n return { ...value, predicate: callback(value.predicate) }\n case \"Catch\":\n return { ...value, filterIdentity: callback(value.filterIdentity) }\n default:\n return value\n }\n}\n\n/**\n * The same drafts, with only callback identities made restart-comparable.\n *\n * @since 1.0.0\n * @private\n */\nexport const recordedPlanDrafts = (graph: Graph.Graph): ReadonlyArray<Plan.NodeDraft> =>\n Graph.drafts(graph).map((draft) => ({ ...draft, material: { ...draft.material, body: body(draft.material.body) } }))\n"]}
@@ -19,7 +19,7 @@ engine, database, or jj: planning reads declarations only. They import
19
19
  add both at the version of `@smthrs/flows` you have:
20
20
 
21
21
  ```bash
22
- npm install @smthrs/flow@1.0.0-rc.13 @smthrs/plan@1.0.0-rc.13
22
+ npm install @smthrs/flow@1.0.0-rc.14 @smthrs/plan@1.0.0-rc.14
23
23
  ```
24
24
 
25
25
  `@smthrs/flows` re-exports the same modules, so `import { Graph } from "@smthrs/flows"`
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@smthrs/flow",
3
3
  "type": "module",
4
- "version": "1.0.0-rc.13",
4
+ "version": "1.0.0-rc.14",
5
5
  "license": "MIT",
6
6
  "smthrs": {
7
7
  "group": "engine"
@@ -289,11 +289,11 @@
289
289
  "tag": "next"
290
290
  },
291
291
  "dependencies": {
292
- "@smthrs/crypto": "1.0.0-rc.13",
293
- "@smthrs/keys": "1.0.0-rc.13",
294
- "@smthrs/plan": "1.0.0-rc.13",
295
- "@smthrs/canonical": "1.0.0-rc.13",
296
- "@smthrs/capability": "1.0.0-rc.13"
292
+ "@smthrs/crypto": "1.0.0-rc.14",
293
+ "@smthrs/keys": "1.0.0-rc.14",
294
+ "@smthrs/plan": "1.0.0-rc.14",
295
+ "@smthrs/canonical": "1.0.0-rc.14",
296
+ "@smthrs/capability": "1.0.0-rc.14"
297
297
  },
298
298
  "devDependencies": {
299
299
  "@effect/language-service": "0.87.2",
@@ -80,6 +80,7 @@ import * as HumanTask from "./HumanTask.ts"
80
80
  import * as BoundedJson from "./internal/BoundedJson.ts"
81
81
  import { ExecutionMiddleware } from "./internal/ExecutionMiddleware.ts"
82
82
  import { OutcomeValueTypeId } from "./internal/OutcomeMarker.ts"
83
+ import { recordedPlanDrafts } from "./internal/RecordedPlan.ts"
83
84
  import * as Sleep from "./Sleep.ts"
84
85
  import * as WaitFor from "./WaitFor.ts"
85
86
 
@@ -272,7 +273,7 @@ const planPages = (
272
273
  > =>
273
274
  Effect.gen(function*() {
274
275
  const identity = yield* StepKey.content({
275
- body: { flow, nodes: Graph.drafts(graph), edges: Graph.edges(graph) },
276
+ body: { flow, nodes: recordedPlanDrafts(graph), edges: Graph.edges(graph) },
276
277
  inputs: {},
277
278
  layers: [],
278
279
  capabilities: {}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Resume compatibility is weaker than result reuse: unchanged callback source
3
+ * may rebuild a recorded plan, but an opaque closure still cannot earn a cache
4
+ * hit. Only the interpreter's PlanRecorded guard uses this projection. Approval
5
+ * digests and dispatch keys keep the original entropy-bearing material.
6
+ *
7
+ * @since 1.0.0
8
+ * @internal
9
+ */
10
+
11
+ import { isRecord } from "@smthrs/canonical/Record"
12
+ import type * as Plan from "@smthrs/plan/Plan"
13
+ import * as Graph from "../Graph.ts"
14
+
15
+ /** Missing source metadata retains the old identity and fails closed. */
16
+ const callback = (value: unknown): unknown =>
17
+ isRecord(value) && value._tag === "FunctionIdentity" && value.algorithm === "sha256-source-ephemeral/v4" &&
18
+ typeof value.sourceDigest === "string"
19
+ ? { _tag: value._tag, algorithm: value.algorithm, digest: value.sourceDigest }
20
+ : value
21
+
22
+ /** Project only callback slots, never identity-shaped application data. */
23
+ const body = (value: unknown): unknown => {
24
+ if (!isRecord(value)) return value
25
+ switch (value._tag) {
26
+ case "FlowCall":
27
+ return isRecord(value.declaration)
28
+ ? { ...value, declaration: { ...value.declaration, body: callback(value.declaration.body) } }
29
+ : value
30
+ case "Map":
31
+ return { ...value, mapper: callback(value.mapper) }
32
+ case "AndThen":
33
+ return { ...value, continuation: callback(value.continuation) }
34
+ case "Branch":
35
+ return { ...value, predicate: callback(value.predicate) }
36
+ case "Catch":
37
+ return { ...value, filterIdentity: callback(value.filterIdentity) }
38
+ default:
39
+ return value
40
+ }
41
+ }
42
+
43
+ /**
44
+ * The same drafts, with only callback identities made restart-comparable.
45
+ *
46
+ * @since 1.0.0
47
+ * @private
48
+ */
49
+ export const recordedPlanDrafts = (graph: Graph.Graph): ReadonlyArray<Plan.NodeDraft> =>
50
+ Graph.drafts(graph).map((draft) => ({ ...draft, material: { ...draft.material, body: body(draft.material.body) } }))