Skip to content

feat: graph workspace and static analysis - #483

Merged
stefan-gorules merged 4 commits into
masterfrom
feat/graph-workspace-and-static-analysis
Jul 16, 2026
Merged

feat: graph workspace and static analysis#483
stefan-gorules merged 4 commits into
masterfrom
feat/graph-workspace-and-static-analysis

Conversation

@stefan-gorules

Copy link
Copy Markdown
Contributor

Graphs join the workspace

The workspace now stores decision graphs alongside policies and statically analyzes them. Types flow through the graph the way the runtime merges data: pass-through, loops, input and output field mappings, switch arms with branch narrowing, and nested decision nodes resolved against the callee's signature, whether that callee is a policy or another graph. Every expression is checked with the same strict checker policies use, with diagnostics anchored to the exact node, cell or expression. Nodes that cannot be typed (custom nodes, schema-less inputs) become opaque instead of guesses, and are listed so the editor can badge them.

TypeScript function nodes

Function nodes accept TypeScript, including enums. Sources are stripped to plain JS once at compile time instead of on every evaluation. Output types come from the host through a resolver callback or a request/push API, so a resolved function node types its downstream instead of ending the analysis.

Dictionaries in graphs

Graphs can import policies and use their dictionaries: decision-table output columns can be dictionary typed, and input schemas may declare $dictionary fields that resolve to string enums for both typing and validation. Membership is enforced at runtime as well as in diagnostics, dictionary labels appear in the natural-language projection, and resolution follows imports transitively, matching exactly what the runtime can load.

Editor intelligence for graphs

Completions, hover, inspect and the natural-language projection work inside graph nodes through the same cursor API policies use. Properties and nodes can be renamed with references tracked across documents: renaming a policy output updates the graphs that call it, and graph property renames follow input/output mappings through nested decisions.

Explainable graph runs

Trace enhancement enriches a simulator run with per-expression reads and values, decision-table row evaluations with a per-cell input pass bitmask, and recursion into sub-decisions. A dependencies query returns the property dependency tree behind any output of a graph document.

Workspace API

paths() and removePath() replace the separate policy and document variants and behave consistently for both kinds of documents. The nodejs binding exposes the full workspace surface, including the function-type resolver hook and ts-support helpers for typechecking function sources.

Fixes

Traced and untraced decision-table evaluation now agree on first-hit selection, and a missing rule cell is treated as an empty cell in both, matching the analyzer. Dictionary diagnostics accept exactly what the runtime can resolve, no more and no less. Rename and reference spans are character offsets on every path, and renaming a field that exists only in a data model produces the correct edit again.

Business Value

Graph editing gets the same guardrails policies already have: type errors, unknown fields and uncovered tables surface while editing, anchored where they occur, instead of failing at runtime or silently producing nulls. Function nodes stop being walls in the analysis, so typed graphs stay typed end to end. Simulation explains itself, showing which rows matched and what each expression read. And what the editor reports is what the engine executes; the fixes close the remaining gaps where the two disagreed.

stefan-gorules and others added 4 commits July 16, 2026 14:01
Generalize PolicyWorkspace into Workspace: one store for policy and
graph documents (DecisionContent union) with cross-document analysis.

- Static type-flow analysis for decision graphs: topological walk with
  strict expression checking, switch branch narrowing, decision-node
  signature compatibility, output schema checks, coverage/nullability
  for decision tables, unreachable-node and parentheses lints
- TypeScript function nodes: type stripping at compile time, types via
  consumer-provided resolver (sync callback or request/push), resolved
  types flow downstream instead of opaque walls
- Dictionaries in graphs: imported through policy imports
  (forward-transitive), typed output columns, $dictionary input schema
  fields resolved to enums at eval, membership validation at runtime
- Editor support for graphs: inspect/completions/NL via shared cursor,
  property and node rename with cross-document reference tracking,
  ReplaceNode edits
- Trace enhancement for graph runs (per-node reads, DT row evaluations
  and inputPass bitmask, sub-decision recursion)
- Workspace facade: generic paths()/remove_path() replace the
  policy/document-specific variants; nodejs binding exposes the full
  workspace API incl. ts-support helpers

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@stefan-gorules
stefan-gorules merged commit 8d1910c into master Jul 16, 2026
63 of 64 checks passed
@stefan-gorules
stefan-gorules deleted the feat/graph-workspace-and-static-analysis branch July 16, 2026 21:42
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.

2 participants