Skip to content

fix(core): harden declarative workflow runtime - #84

Open
LukasParke wants to merge 6 commits into
mattapperson:mainfrom
LukasParke:lukeparke/openrouter-workflow-hardening
Open

fix(core): harden declarative workflow runtime#84
LukasParke wants to merge 6 commits into
mattapperson:mainfrom
LukasParke:lukeparke/openrouter-workflow-hardening

Conversation

@LukasParke

Copy link
Copy Markdown
Collaborator

What

  • route declarative invokeTool nodes through shared validation, steering, UI, decoration, and item-schema paths
  • reject duplicate node ids per workflow-document scope
  • support exact conditional matching and cap run-code bodies
  • cache dynamic parallel hydration per index
  • feed hydration errors back into workflow planner revisions
  • accept runtime registries for layers, sub-harnesses, UI libraries, and named workflows
  • extract a Sentrux-safe core tooling seam instead of importing builders upward into adapters

Why

Declarative workflows bypassed tool gates, could silently mis-hydrate duplicate ids, rebuilt dynamic branches repeatedly, and failed generation without giving the planner actionable hydration feedback. The historical port also introduced a forbidden layer-direction edge, so this version first moves shared tool machinery to a foundational tooling layer.

This semantically ports item 14 from fork/port/openrouter-fixes commit 4cb90e35 onto current post-#68 names/architecture.

Test plan

  • core 1,458 tests pass
  • types 46, context 9, eval 264, inspector 56, platform-node 62 tests pass
  • core/types/web/inspector typechecks and examples typecheck
  • root lint
  • sentrux check . and sentrux gate .
  • both workflow JSON schema artifacts regenerated
  • clean-context review; fixed root exports, plan duplicate-id gate, and invokeTool result decoration/schema equivalence

Schema

Adds conditional matchMode and the run-code body size constraint. Both published schema copies were regenerated in the implementation commit.

LukasParke and others added 6 commits August 12, 2026 21:09
Signed-off-by: Luke Parke <5702154+LukasParke@users.noreply.github.com>
Signed-off-by: Luke Parke <5702154+LukasParke@users.noreply.github.com>
Signed-off-by: Luke Parke <5702154+LukasParke@users.noreply.github.com>
Signed-off-by: Luke Parke <5702154+LukasParke@users.noreply.github.com>
…d uniqueness, route matchMode, hydration cache

- invokeTool nodes dispatch through the shared tool-execution path
  (executeToolCall) instead of bare tool.execute — JSON-workflow tools now
  get the same argument validation, steering, and tool-UI as model-driven
  calls, and the transcript records the matching function_call_output item
- executeToolCall is extracted from adapters/openrouter into a new
  core-tooling layer (packages/core/src/tooling/) so builders can reach it
  without a builders→adapters Sentrux violation; its broadcaster and
  tool-context/tool-UI helpers move to util/ and tooling/ accordingly
  (event-broadcaster and broadcaster-utils now live in util/)
- document-scope node-id uniqueness (DUPLICATE_NODE_ID via
  NoeticConfigError), scoped per document so an id shared between the outer
  doc and an inline subflow document — safe at runtime because the hydrator
  suffixes subflow ids — is not a false positive; dynamicWorkflow routes
  uniqueness failures through the planner revision loop instead of throwing
- per-index hydration cache for dynamic inParallel (an each-template
  re-hydrated every path on every invocation)
- ConditionalRoute.matchMode 'substring' (default) | 'exact', lowercased
  once at hydration; documents the 'cat'-matches-'concatenate' footgun
- DynamicWorkflowOpts accepts the full hydration registries (layers,
  subHarnesses, uiLibraries, workflows) and hydration config errors feed
  the revision loop with a register-your-refs hint
- runCode execute capped at 256 KiB-equivalent length; subprocess request
  metadata no longer duplicates code+input
- JSON schema artifacts regenerated via gen:schema; one test fixture
  corrected — it passed only because invokeTool nodes previously skipped
  validation

Ported from OpenRouter's fork (commit 4cb90e3 there), adapted to current
names (invokeTool/conditional/inParallel/runCode/callModel, builders/) and
current Sentrux layering.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Luke Parke <5702154+LukasParke@users.noreply.github.com>
Apply review fixes for shared invokeTool result decoration/validation, reusable duplicate-id discovery, plan authoring validation, and preserved core workflow exports.

Signed-off-by: Luke Parke <5702154+LukasParke@users.noreply.github.com>
@vercel

vercel Bot commented Aug 13, 2026

Copy link
Copy Markdown

@LukasParke is attempting to deploy a commit to the Matt Apperson's projects Team on Vercel.

A member of the Team first needs to authorize it.

@LukasParke

Copy link
Copy Markdown
Collaborator Author

Agent: Code CI/structural/DCO are green where configured; remaining external red checks are compat with an empty upstream OPENROUTER_API_KEY and Vercel authorization. Where core CI is red, the only failure is the unrelated timing-sensitive executeRunCode retry-backoff test; affected local/full suites passed. I cannot rerun upstream Actions without admin rights.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant