@nanobpm/nano-workforce 0.194.0 → 0.195.0

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.
@@ -128,11 +128,11 @@ test("convergence-loop golden has arbitrary-graph features the structured builde
128
128
  // (a) the loop head is a serviceTask that MERGES its back-edges directly — after #786/#789 the
129
129
  // round-entry head capture (`capture-head`) is the loop head sitting BEFORE `review-round`, so it
130
130
  // is `capture-head` that absorbs the back-edges (f_start, the review loop, the answer resume, the
131
- // #786 husk auto-retry, and the #796 bounded auto-ack re-entry f_ackRetry); `review-round` then
132
- // takes its single `f_capture` in-edge. A serviceTask merging FIVE back-edges directly is the
133
- // arbitrary-graph shape the structured builder cannot emit — the feature this asserts, now on
134
- // `capture-head`.
135
- assertEquals(between("capture-head", "serviceTask", "incoming"), 5, "capture-head should merge 5 flows on the task itself");
131
+ // #786 husk auto-retry, the #796 bounded auto-ack re-entry f_ackRetry, and the #826 merge-approval
132
+ // change request f_revise); `review-round` then takes its single `f_capture` in-edge. A serviceTask
133
+ // merging SIX back-edges directly is the arbitrary-graph shape the structured builder cannot emit —
134
+ // the feature this asserts, now on `capture-head`.
135
+ assertEquals(between("capture-head", "serviceTask", "incoming"), 6, "capture-head should merge 6 flows on the task itself");
136
136
  assertEquals(between("review-round", "serviceTask", "incoming"), 1, "review-round now takes the single f_capture in-edge");
137
137
  // (b) a single exclusive gateway forks FOUR heterogeneous-condition out-edges.
138
138
  assertEquals(between("gw-status", "exclusiveGateway", "outgoing"), 4, "gw-status should be a 4-way exclusive gateway");
@@ -145,8 +145,8 @@ test("convergence-loop golden has arbitrary-graph features the structured builde
145
145
  // (a): a `loop()` whose body starts with a task derives an exclusive-gateway
146
146
  // loop head that absorbs the back-edge (in>=2), leaving the task itself at
147
147
  // in=1. The golden instead merges its back-edges directly into `capture-head`
148
- // (capture-head in=5: f_start, f_reviewLoop, f_answerLoop, the #786 f_huskRetry, and the #796
149
- // f_ackRetry re-entry) with no loop-head gateway — a shape the builder cannot express.
148
+ // (capture-head in=6: f_start, f_reviewLoop, f_answerLoop, the #786 f_huskRetry, the #796
149
+ // f_ackRetry re-entry, and the #826 f_revise) with no loop-head gateway — a shape the builder cannot express.
150
150
  test("loop() inserts a gateway head, so back-edges cannot merge into a task", () => {
151
151
  const probe = defineFlow("loop-head-probe", (w) => {
152
152
  w.loop((b) => {
@@ -24,7 +24,7 @@
24
24
  // so it clears class (1) — but its topology is NOT expressible with the
25
25
  // structured-only builder (`loop`/`switch`/`branch`), empirically proven
26
26
  // (see `derivation-parity.test.ts`): its loop head `capture-head` is a
27
- // serviceTask that MERGES five back-edges directly (in=5), whereas
27
+ // serviceTask that MERGES six back-edges directly (in=6), whereas
28
28
  // `loop()` always inserts an exclusive-gateway loop head (the task stays
29
29
  // in=1); `gw-status` is a single exclusive gateway with FOUR
30
30
  // heterogeneous-condition out-edges (two `=x = "v"`, one complex boolean,
@@ -207,10 +207,11 @@ export const PORTS: readonly PortEntry[] = [
207
207
  "blocked (arbitrary control-flow graph): single top-level start/end, but " +
208
208
  "its topology is not expressible with the published @nanobpm/workflow's " +
209
209
  "structured-only builder (loop/switch/branch). Proven in the test suite: " +
210
- "the loop head `capture-head` is a serviceTask that merges 5 back-edges " +
211
- "directly (in=5: f_start, f_reviewLoop, f_answerLoop, the #786 husk " +
212
- "auto-retry f_huskRetry, and the #796 bounded auto-ack re-entry " +
213
- "f_ackRetry), but loop() always inserts an exclusive-gateway head " +
210
+ "the loop head `capture-head` is a serviceTask that merges 6 back-edges " +
211
+ "directly (in=6: f_start, f_reviewLoop, f_answerLoop, the #786 husk " +
212
+ "auto-retry f_huskRetry, the #796 bounded auto-ack re-entry " +
213
+ "f_ackRetry, and the #826 merge-approval change request f_revise), but " +
214
+ "loop() always inserts an exclusive-gateway head " +
214
215
  "(task stays in=1); `gw-status` is one gateway with 4 heterogeneous-" +
215
216
  "condition out-edges (no switch/branch emits that); `gw-escalated` is one " +
216
217
  "gateway that is at once a 6-way merge and a 2-way split. Awaits an " +
@@ -22,6 +22,7 @@ const handler: AppJobHandler<In, Record<string, never>> = async (job, app) => {
22
22
  const featureKey = job.variables.featureKey;
23
23
  const prKey = typeof job.variables.prKey === "string" ? job.variables.prKey.trim() : "";
24
24
  const autoMerge = job.variables.autoMerge === true;
25
+ const humanApproval = job.variables.humanApproval === true;
25
26
  const parsed = prKey ? parsePr(prKey) : null;
26
27
  if (!parsed) {
27
28
  // Should not happen — the gateway only routes here when record-feature emitted a parseable
@@ -46,11 +47,12 @@ const handler: AppJobHandler<In, Record<string, never>> = async (job, app) => {
46
47
  pr_key: parsed.prKey,
47
48
  updated_at: new Date().toISOString(),
48
49
  });
49
- await submitPr(app.data, app.engine, parsed, [], MAX_ROUNDS, !autoMerge, featureKey);
50
+ await submitPr(app.data, app.engine, parsed, [], MAX_ROUNDS, !autoMerge, featureKey, humanApproval);
50
51
  app.log.info("converge-feature: enrolled PR into convergence loop", {
51
52
  featureKey,
52
53
  prKey: parsed.prKey,
53
54
  convergeOnly: !autoMerge,
55
+ humanApproval,
54
56
  });
55
57
  return {};
56
58
  };