forge-openclaw-plugin 0.2.91 → 0.2.92

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.
@@ -2960,6 +2960,7 @@ const AGENT_ONBOARDING_ENTITY_CATALOG = [
2960
2960
  ],
2961
2961
  searchHints: [
2962
2962
  "Clarify whether the user wants a behavioral query, one trip or place, a missing-gap overlay, a manual add or update, or a link before choosing the route.",
2963
+ "For known-place creation or cleanup, ask what label, boundary, and future use should make the place recognizable before calling the dedicated place route.",
2963
2964
  "If the user already named a concrete missing span, confirm only the remaining time or place ambiguity, then use the movement overlay route and read the timeline back.",
2964
2965
  "If the user wants to revise or remove an already-saved correction, identify whether it is a user-defined box, automatic box, recorded stay, recorded trip, or trip point before choosing the repair or delete route."
2965
2966
  ],
@@ -2975,6 +2976,7 @@ const AGENT_ONBOARDING_ENTITY_CATALOG = [
2975
2976
  ],
2976
2977
  searchHints: [
2977
2978
  "Clarify whether the user wants explanation, durable model changes, or a real-time tired or recovered signal before choosing the route.",
2979
+ "For profile or weekday-template edits, ask what future planning behavior should change, such as workload, recovery time, timeboxes, meeting load, or task choice.",
2978
2980
  "Separate durable profile assumptions, weekday-template edits, and right-now fatigue signals before choosing the mutation path.",
2979
2981
  "When the user is trying to understand the practical result of a change, read the overview again after the write instead of stopping at the mutation response."
2980
2982
  ],
@@ -2990,6 +2992,7 @@ const AGENT_ONBOARDING_ENTITY_CATALOG = [
2990
2992
  ],
2991
2993
  searchHints: [
2992
2994
  "Clarify whether the user wants flow discovery, editing, execution, published output, run inspection, or node-level output before choosing the route.",
2995
+ "For one-off execution, ask whether the input contract should stay temporary or become a reusable saved flow before creating anything durable.",
2993
2996
  "Distinguish flow contract, published output, run history, latest-node-output, and chat follow-up questions before reaching for a route.",
2994
2997
  "If the user is still deciding how to run or edit a flow, read flow detail or the box catalog before asking them for structured input details."
2995
2998
  ],
@@ -4776,6 +4779,7 @@ function buildAgentOnboardingPayload(request) {
4776
4779
  ],
4777
4780
  routeSelectionQuestions: [
4778
4781
  "Is the user asking for a day, month, all-time, timeline, place, trip detail, selected-span, or settings answer?",
4782
+ "If this is known-place creation or cleanup, what label, boundary, or future-use distinction is still missing?",
4779
4783
  "Is this a missing-gap overlay, a saved-overlay repair, or an edit to one already-recorded stay, trip, or trip point?",
4780
4784
  "If this is about operating behavior, is the change about passive tracking, publish mode, retention, or companion readiness?",
4781
4785
  "If the target is already known, what one time, place, or saved-object detail is still missing before acting?"
@@ -4837,6 +4841,7 @@ function buildAgentOnboardingPayload(request) {
4837
4841
  "Route-selection questions are internal. User-facing questions should ask for the useful time window, place, selected span, stay, or trip instead of reciting day/month/all-time/timeline/selection route keys.",
4838
4842
  "Use /api/v1/movement/day, /month, /all-time, /timeline, or /selection when the user wants behavioral answers such as how long they stayed at home, when they traveled, which places dominated a period, or what happened across a selected span.",
4839
4843
  "Use GET /api/v1/movement/settings and PATCH /api/v1/movement/settings when the user wants to inspect or change passive capture, publish mode, retention mode, or companion readiness. Do not route settings changes through stays, trips, places, or batch CRUD.",
4844
+ "For known-place creation or cleanup, ask for the place label, boundary, and future use, then use POST /api/v1/movement/places or PATCH /api/v1/movement/places/:id instead of tags or generic entity writes.",
4840
4845
  "Use the movement write routes when the user wants to add a place or manual overlay, update a specific stay or trip, repair one recorded movement span, or attach movement context to another Forge record. If the user is filling a missing-data gap, the usual write path is a user-defined overlay box rather than a raw stay or trip patch.",
4841
4846
  "If the user is revising or removing an existing correction, first identify whether the saved object is a user-defined box, automatic box, recorded stay, recorded trip, or trip point so the repair or delete path stays truthful.",
4842
4847
  "For an explicit statement like 'that missing block was me staying home', do not reopen broad intake. Preflight only if timing overlap is unclear, then create a user-defined `stay` box for that interval and read the updated timeline back."
@@ -4849,6 +4854,7 @@ function buildAgentOnboardingPayload(request) {
4849
4854
  routeKeys: ["overview", "profile", "weekdayTemplate", "fatigueSignal"],
4850
4855
  routeSelectionQuestions: [
4851
4856
  "Is the user trying to understand the overview, change durable profile assumptions, change a weekday curve, or log a right-now fatigue signal?",
4857
+ "What planning decision should the overview or correction change: workload, recovery, timeboxes, meetings, or task choice?",
4852
4858
  "Are they describing a repeatable weekly shape or a one-off current state?",
4853
4859
  "If the lane is already clear, what one weekday, profile field, or signal detail is still missing?"
4854
4860
  ],
@@ -4871,6 +4877,8 @@ function buildAgentOnboardingPayload(request) {
4871
4877
  "Route-selection questions are internal. User-facing questions should ask whether this is a current read, durable assumption, repeated weekday rhythm, or right-now state instead of reciting overview/profile/template/signal route keys.",
4872
4878
  "Use GET /api/v1/life-force for the current overview payload with stats, drains, recommendations, and current-curve state.",
4873
4879
  "Patch the profile only for durable personal settings, update weekday templates only for the curve itself, and post fatigue signals for real-time tired or recovered observations.",
4880
+ "If the user only needs an explanation or planning read, use the overview first and do not turn the conversation into a profile or template mutation.",
4881
+ "For profile or weekday-template edits, ask what future planning behavior should change, such as workload, recovery time, timeboxes, meeting load, or task choice, so the write is not just a nicer description.",
4874
4882
  "If the user says something like 'I always dip on Tuesdays after lunch', treat that as a weekday-template change rather than a one-off fatigue signal.",
4875
4883
  "If the user is asking what changed after a profile, template, or fatigue write, read the overview back so the effect stays visible.",
4876
4884
  "If the user already knows they want a profile change, weekday-template edit, or right-now fatigue signal, skip the broad lane question and ask only for the missing weekday, profile field, or signal detail."
@@ -4883,6 +4891,7 @@ function buildAgentOnboardingPayload(request) {
4883
4891
  routeKeys: ["overview", "profile", "weekdayTemplate", "fatigueSignal"],
4884
4892
  routeSelectionQuestions: [
4885
4893
  "Is the user trying to understand the overview, change durable profile assumptions, change a weekday curve, or log a right-now fatigue signal?",
4894
+ "What planning decision should the overview or correction change: workload, recovery, timeboxes, meetings, or task choice?",
4886
4895
  "Are they describing a repeatable weekly shape or a one-off current state?",
4887
4896
  "If the lane is already clear, what one weekday, profile field, or signal detail is still missing?"
4888
4897
  ],
@@ -4906,6 +4915,8 @@ function buildAgentOnboardingPayload(request) {
4906
4915
  "Route-selection questions are internal. User-facing questions should ask whether this is a current read, durable assumption, repeated weekday rhythm, or right-now state instead of reciting overview/profile/template/signal route keys.",
4907
4916
  "Use GET /api/v1/life-force for the current overview payload with stats, drains, recommendations, and current-curve state.",
4908
4917
  "Patch the profile only for durable personal settings, update weekday templates only for the curve itself, and post fatigue signals for real-time tired or recovered observations.",
4918
+ "If the user only needs an explanation or planning read, use the overview first and do not turn the conversation into a profile or template mutation.",
4919
+ "For profile or weekday-template edits, ask what future planning behavior should change, such as workload, recovery time, timeboxes, meeting load, or task choice, so the write is not just a nicer description.",
4909
4920
  "If the user says something like 'I always dip on Tuesdays after lunch', treat that as a weekday-template change rather than a one-off fatigue signal.",
4910
4921
  "If the user is asking what changed after a profile, template, or fatigue write, read the overview back so the effect stays visible.",
4911
4922
  "If the user already knows they want a profile change, weekday-template edit, or right-now fatigue signal, skip the broad lane question and ask only for the missing weekday, profile field, or signal detail."
@@ -4935,6 +4946,7 @@ function buildAgentOnboardingPayload(request) {
4935
4946
  ],
4936
4947
  routeSelectionQuestions: [
4937
4948
  "Is the job flow discovery, flow creation, flow editing, flow deletion, execution, run history, published output, run detail, node result, latest node output, or flow chat follow-up?",
4949
+ "If this is execution, is it a known saved flow, a one-off input run, or a flow that should become reusable?",
4938
4950
  "Does the user need a stable public contract or one execution artifact?",
4939
4951
  "For flow CRUD, what stable input contract, expected output, or lifecycle effect must stay true?",
4940
4952
  "For flow chat follow-up, which saved flow should receive the message and what should the message accomplish?",
@@ -4984,6 +4996,7 @@ function buildAgentOnboardingPayload(request) {
4984
4996
  "Use the flow routes when the agent needs stable public input contracts, published outputs, node-level results, or reusable execution history.",
4985
4997
  "If the user is still figuring out inputs or editable structure, read flow detail or box catalog before asking them to reconstruct structured inputs from memory.",
4986
4998
  "For flow creation, clarify what the flow should reliably produce, which input contract it should accept, and which first node or box anchors the flow before asking for structured input details.",
4999
+ "For one-off execution, do not create a saved flow unless the user wants reuse. Ask whether the input contract should stay temporary or become durable, then use POST /api/v1/workbench/run for the temporary case.",
4987
5000
  "For flow edits, ask what behavior should change while preserving the public contract unless the user explicitly wants the contract changed.",
4988
5001
  "For flow deletion, confirm the saved flow and whether published outputs or run history need preservation elsewhere before using the delete route.",
4989
5002
  "For saved flow chat follow-ups, use POST /api/v1/workbench/flows/:id/chat only when the user wants to continue a flow-specific conversation. Do not turn that into a new run, note, or generic entity update unless the user asks.",
@@ -2735,6 +2735,97 @@ function mobileSyncSessionProgress(syncSessionId) {
2735
2735
  receivedBytes: chunks.reduce((sum, chunk) => sum + chunk.byte_count, 0)
2736
2736
  };
2737
2737
  }
2738
+ function finiteNumberFromUnknown(value) {
2739
+ if (typeof value === "number" && Number.isFinite(value)) {
2740
+ return value;
2741
+ }
2742
+ if (typeof value === "string" && value.trim().length > 0) {
2743
+ const parsed = Number(value);
2744
+ return Number.isFinite(parsed) ? parsed : null;
2745
+ }
2746
+ return null;
2747
+ }
2748
+ function nestedRecord(value) {
2749
+ return value && typeof value === "object" && !Array.isArray(value)
2750
+ ? value
2751
+ : {};
2752
+ }
2753
+ function expectedWorkoutEvidenceCounts(derived) {
2754
+ const syncCursor = nestedRecord(derived.syncCursor);
2755
+ const captureQuality = nestedRecord(derived.captureQuality);
2756
+ const syncTimeSeriesCount = finiteNumberFromUnknown(syncCursor.timeSeriesSampleCount);
2757
+ const captureHeartRateCount = finiteNumberFromUnknown(captureQuality.heartRateSamples);
2758
+ const syncRoutePointCount = finiteNumberFromUnknown(syncCursor.routePointCount);
2759
+ const captureRoutePointCount = finiteNumberFromUnknown(captureQuality.routePoints);
2760
+ const expectedTimeSeriesSamples = Math.max(0, Math.ceil(Math.max(syncTimeSeriesCount ?? 0, captureHeartRateCount ?? 0)));
2761
+ const expectedRoutePoints = Math.max(0, Math.ceil(Math.max(syncRoutePointCount ?? 0, captureRoutePointCount ?? 0)));
2762
+ return {
2763
+ expectedTimeSeriesSamples,
2764
+ expectedRoutePoints,
2765
+ hasEvidenceMetadata: syncTimeSeriesCount !== null ||
2766
+ captureHeartRateCount !== null ||
2767
+ syncRoutePointCount !== null ||
2768
+ captureRoutePointCount !== null
2769
+ };
2770
+ }
2771
+ function mobileHealthWorkoutImportState(userId) {
2772
+ const rows = getDatabase()
2773
+ .prepare(`WITH time_series_counts AS (
2774
+ SELECT workout_id, COUNT(*) AS time_series_count
2775
+ FROM health_workout_time_series
2776
+ GROUP BY workout_id
2777
+ ),
2778
+ route_counts AS (
2779
+ SELECT workout_id, COUNT(*) AS route_point_count
2780
+ FROM health_workout_routes
2781
+ GROUP BY workout_id
2782
+ )
2783
+ SELECT
2784
+ w.external_uid,
2785
+ w.derived_json,
2786
+ COALESCE(time_series_counts.time_series_count, 0) AS time_series_count,
2787
+ COALESCE(route_counts.route_point_count, 0) AS route_point_count
2788
+ FROM health_workout_sessions w
2789
+ LEFT JOIN time_series_counts ON time_series_counts.workout_id = w.id
2790
+ LEFT JOIN route_counts ON route_counts.workout_id = w.id
2791
+ WHERE w.user_id = ?
2792
+ AND w.source = 'apple_health'
2793
+ AND w.external_uid IS NOT NULL
2794
+ AND w.external_uid <> ''
2795
+ ORDER BY w.started_at DESC`)
2796
+ .all(userId);
2797
+ const alreadyUploadedWorkoutExternalUids = [];
2798
+ let incompleteWorkoutCount = 0;
2799
+ let timeSeriesSampleCount = 0;
2800
+ let routePointCount = 0;
2801
+ for (const row of rows) {
2802
+ const derived = safeJsonParse(row.derived_json, {});
2803
+ const evidenceCounts = expectedWorkoutEvidenceCounts(derived);
2804
+ const actualTimeSeriesCount = Math.max(0, row.time_series_count ?? 0);
2805
+ const actualRoutePointCount = Math.max(0, row.route_point_count ?? 0);
2806
+ const evidenceComplete = evidenceCounts.hasEvidenceMetadata
2807
+ ? actualTimeSeriesCount >= evidenceCounts.expectedTimeSeriesSamples &&
2808
+ actualRoutePointCount >= evidenceCounts.expectedRoutePoints
2809
+ : actualTimeSeriesCount + actualRoutePointCount > 0;
2810
+ if (evidenceComplete) {
2811
+ alreadyUploadedWorkoutExternalUids.push(row.external_uid.toLowerCase());
2812
+ timeSeriesSampleCount += actualTimeSeriesCount;
2813
+ routePointCount += actualRoutePointCount;
2814
+ }
2815
+ else {
2816
+ incompleteWorkoutCount += 1;
2817
+ }
2818
+ }
2819
+ return {
2820
+ alreadyUploadedWorkoutExternalUids,
2821
+ alreadyUploadedWorkoutCount: alreadyUploadedWorkoutExternalUids.length,
2822
+ existingWorkoutCount: rows.length,
2823
+ incompleteWorkoutCount,
2824
+ timeSeriesSampleCount,
2825
+ routePointCount,
2826
+ capturedAt: nowIso()
2827
+ };
2828
+ }
2738
2829
  function mobileSyncSessionUploadPayload(session, receivedChunkIds) {
2739
2830
  return {
2740
2831
  syncSessionId: session.id,
@@ -2747,6 +2838,7 @@ function mobileSyncSessionUploadPayload(session, receivedChunkIds) {
2747
2838
  supportsCompression: true,
2748
2839
  acceptedFamilies: safeJsonParse(session.requested_families_json, []),
2749
2840
  receivedChunkIds,
2841
+ workoutImportState: mobileHealthWorkoutImportState(session.user_id),
2750
2842
  progress: mobileSyncSessionProgress(session.id)
2751
2843
  };
2752
2844
  }
@@ -2,7 +2,7 @@
2
2
  "id": "forge-openclaw-plugin",
3
3
  "name": "Forge",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
- "version": "0.2.91",
5
+ "version": "0.2.92",
6
6
  "activation": {
7
7
  "onStartup": true,
8
8
  "onCapabilities": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-openclaw-plugin",
3
- "version": "0.2.91",
3
+ "version": "0.2.92",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -1537,9 +1537,9 @@ Preferred opening question:
1537
1537
  ## Movement
1538
1538
 
1539
1539
  Aim: clarify whether the user wants to understand time in place, review travel
1540
- behavior, add or update a stay or trip, inspect one place, change movement operating
1541
- settings, or link movement context to another Forge record before choosing the
1542
- dedicated route family.
1540
+ behavior, add or update a stay or trip, create or clean up a known place, change
1541
+ movement operating settings, or link movement context to another Forge record before
1542
+ choosing the dedicated route family.
1543
1543
 
1544
1544
  Arc:
1545
1545
 
@@ -1548,17 +1548,19 @@ Arc:
1548
1548
  2. Ask whether the user is trying to query behavior, add something manually, update
1549
1549
  an existing movement item, or link movement to another Forge entity.
1550
1550
  3. Ask whether the focus is a stay, a trip, a place, a timeline window, or a selected span.
1551
- 4. Ask for the time window, place, or movement item that makes the question concrete.
1552
- 5. Ask what they are trying to notice, preserve, or answer through that movement context.
1553
- 6. If the user is changing movement operating behavior, ask whether the change is
1551
+ 4. If this is place creation or cleanup, ask what label, boundary, and future use
1552
+ should make the place recognizable later.
1553
+ 5. Ask for the time window, place, or movement item that makes the question concrete.
1554
+ 6. Ask what they are trying to notice, preserve, or answer through that movement context.
1555
+ 7. If the user is changing movement operating behavior, ask whether the change is
1554
1556
  about passive tracking, publish mode, retention, or companion readiness.
1555
- 7. Choose the dedicated day, month, all-time, timeline, places, trip-detail,
1557
+ 8. Choose the dedicated day, month, all-time, timeline, places, trip-detail,
1556
1558
  selection, or settings route once the question shape is clear.
1557
- 8. If the truth of one uncertain span is still unclear, read the timeline or saved-box
1559
+ 9. If the truth of one uncertain span is still unclear, read the timeline or saved-box
1558
1560
  detail before you mutate it.
1559
- 9. Skip the meta lane question when the user already named the exact correction or
1561
+ 10. Skip the meta lane question when the user already named the exact correction or
1560
1562
  review target and only one ambiguity remains.
1561
- 10. Use the dedicated movement route once you know whether the user needs timeline
1563
+ 11. Use the dedicated movement route once you know whether the user needs timeline
1562
1564
  review, overlay, place or trip detail, selection summary, settings, or repair.
1563
1565
 
1564
1566
  Direct action rules:
@@ -1591,12 +1593,17 @@ Direct action rules:
1591
1593
  interval or place if that is still ambiguous, then act.
1592
1594
  - When you do act on a concrete missing-gap correction, create the overlay and read
1593
1595
  the relevant timeline back instead of leaving the correction ungrounded.
1596
+ - For known-place creation or cleanup, ask what the place should be called, what
1597
+ counts inside its boundary, and how future movement reads should use it. Use the
1598
+ dedicated place routes, not a tag or batch entity write.
1594
1599
 
1595
1600
  Helpful follow-up lanes:
1596
1601
 
1597
1602
  - whether the user wants time-in-place, travel history, one specific stay or trip, a
1598
1603
  place summary, or a link
1599
1604
  - what time window, place, stay, trip, or selection is in scope
1605
+ - what label, boundary, or future-use distinction makes a known place worth saving or
1606
+ renaming
1600
1607
  - whether the question is behavioral, such as time at home, travel frequency, or place
1601
1608
  distribution, versus an edit
1602
1609
  - whether the edit is a missing-gap overlay versus a true recorded stay/trip patch
@@ -1649,7 +1656,8 @@ Preferred opening question:
1649
1656
  ## Life Force
1650
1657
 
1651
1658
  Aim: clarify whether the user wants to review current energy state, change durable
1652
- profile assumptions, edit weekday curves, or log a real-time fatigue signal.
1659
+ profile assumptions, edit weekday curves, log a real-time fatigue signal, or make a
1660
+ planning decision based on the energy model.
1653
1661
 
1654
1662
  Arc:
1655
1663
 
@@ -1657,22 +1665,25 @@ Arc:
1657
1665
  you reduce it to one life-force lane.
1658
1666
  2. Ask whether the job is overview, profile change, weekday-template change, or fatigue signaling.
1659
1667
  3. Ask what part of the current energy picture feels most important or inaccurate.
1660
- 4. Ask what should stay true if they are changing profile or template assumptions.
1661
- 5. Ask whether the user is describing a stable weekly shape or just how today feels
1668
+ 4. Ask what planning decision should change if the model is corrected: workload,
1669
+ recovery, timeboxing, meeting load, or task choice.
1670
+ 5. Ask what should stay true if they are changing profile or template assumptions.
1671
+ 6. Ask whether the user is describing a stable weekly shape or just how today feels
1662
1672
  when the lane is still blurred.
1663
- 6. If the user describes a repeatable day-shape such as "Mondays crash after lunch",
1673
+ 7. If the user describes a repeatable day-shape such as "Mondays crash after lunch",
1664
1674
  treat that as a weekday-template question before you reach for profile or
1665
1675
  fatigue-signal routes.
1666
- 7. If the user already named the life-force lane clearly, skip the meta lane question
1676
+ 8. If the user already named the life-force lane clearly, skip the meta lane question
1667
1677
  and ask only for the specific weekday, profile field, or signal that still matters.
1668
- 8. If the user wants to see what changed after a write, read the overview back instead
1678
+ 9. If the user wants to see what changed after a write, read the overview back instead
1669
1679
  of leaving the result implicit.
1670
- 9. Route to the dedicated life-force path once the lane is clear.
1680
+ 10. Route to the dedicated life-force path once the lane is clear.
1671
1681
 
1672
1682
  Helpful follow-up lanes:
1673
1683
 
1674
1684
  - whether the user wants explanation, editing, or signaling
1675
1685
  - what part of the energy model feels off or useful
1686
+ - what planning decision the overview or correction should change
1676
1687
  - what durable assumption versus real-time state is being changed
1677
1688
  - whether the user is describing a stable weekly shape or just how today feels
1678
1689
 
@@ -1704,6 +1715,11 @@ Direct action rules:
1704
1715
  instead of treating it as a one-off right-now feeling.
1705
1716
  - If the user is describing how one weekday should usually feel, update that weekday
1706
1717
  template instead of editing the profile.
1718
+ - If the user only needs an explanation or planning read, use the overview first and
1719
+ do not turn the conversation into a profile or template mutation.
1720
+ - For profile or weekday-template edits, ask what future planning behavior should
1721
+ change, such as workload, recovery time, timeboxes, meeting load, or task choice,
1722
+ so the write is not just a more polished description.
1707
1723
  - If the user says something like "I always dip on Tuesdays after lunch", treat that
1708
1724
  as a weekday-template edit, not as a one-off fatigue signal.
1709
1725
  - If the user is describing right-now depletion or recovery, post a fatigue signal and
@@ -1737,18 +1753,20 @@ Arc:
1737
1753
  5. If the user is creating or editing a flow, clarify the flow's job, stable inputs,
1738
1754
  expected public output, and the smallest structural change before asking for node
1739
1755
  details.
1740
- 6. If the user wants to delete or archive a flow, ask which saved flow is affected
1756
+ 6. If the user wants one-off execution, clarify whether this should stay a one-time
1757
+ input run or become a reusable saved flow before creating anything durable.
1758
+ 7. If the user wants to delete or archive a flow, ask which saved flow is affected
1741
1759
  and what future run, published output, or public contract should no longer exist.
1742
- 7. If the user wants to continue a saved flow chat, ask which flow should receive the
1760
+ 8. If the user wants to continue a saved flow chat, ask which flow should receive the
1743
1761
  follow-up and what the message should accomplish.
1744
- 8. If the user already named the flow and action clearly, skip the meta lane
1762
+ 9. If the user already named the flow and action clearly, skip the meta lane
1745
1763
  question and ask only for the missing run, node, or output scope.
1746
- 9. If the user wants a stable public input contract or published output, prefer those
1764
+ 10. If the user wants a stable public input contract or published output, prefer those
1747
1765
  dedicated reads instead of detouring through run history first.
1748
- 10. If the user is debugging one failed run, ask whether the useful artifact is the run
1766
+ 11. If the user is debugging one failed run, ask whether the useful artifact is the run
1749
1767
  summary, one node result, the latest node output, or the published output before
1750
1768
  you start asking for edits.
1751
- 11. Route to the dedicated workbench route family once the execution lane is clear.
1769
+ 12. Route to the dedicated workbench route family once the execution lane is clear.
1752
1770
 
1753
1771
  Helpful follow-up lanes:
1754
1772
 
@@ -1756,6 +1774,7 @@ Helpful follow-up lanes:
1756
1774
  - what exact flow or run is in scope
1757
1775
  - whether they need whole-flow output or node-level detail
1758
1776
  - whether they need a public input contract or a published output instead of a debug trace
1777
+ - whether a requested execution should remain one-off or become a reusable saved flow
1759
1778
 
1760
1779
  Lane-to-route map:
1761
1780
 
@@ -1796,6 +1815,9 @@ Direct action rules:
1796
1815
  - If the user wants one-off input execution without depending on a saved flow id, use
1797
1816
  `POST /api/v1/workbench/run` through the dedicated one-off execution lane and keep
1798
1817
  the user-facing question about the one-off input contract.
1818
+ - For one-off execution, do not create a saved flow unless the user wants reuse. Ask
1819
+ whether the input contract should be temporary or durable, then route to
1820
+ `POST /api/v1/workbench/run` for the temporary case.
1799
1821
  - If the user wants to debug one failed execution, narrow whether they need the run
1800
1822
  detail, one node result, the latest node output, or the published output before you
1801
1823
  ask for flow changes.