Describe the feature
Support hierarchical projection composition so later projection nodes can consume earlier projection scores, calibrated confidences, or named projection outputs instead of forcing every routing overlay into one shallow scores -> mappings step.
Primary layer
global level
Why this layer?
This changes the generic projection contract and runtime evaluation order across router config, DSL, CLI schema, and insights surfaces. It is broader than one detector family or one UI page.
Why do you need this feature?
Today projection composition is shallow:
- scores read base signals
- mappings read one score
- decisions read named mapping outputs
That works for simple coordination, but it gets awkward for layered routing constructs such as:
- difficulty -> verification pressure -> premium reasoning overlay
- ambiguity -> escalation pressure -> fallback policy band
- cost pressure + quality pressure -> final policy label
Without projection-to-projection composition, those interactions either get flattened into one oversized score or pushed back into decision logic.
Additional context
Affected repo surfaces
src/semantic-router/pkg/classification/classifier_projections.go for dependency-aware runtime evaluation
src/semantic-router/pkg/config/{projection_config.go,validator_projection.go} for graph-aware validation
src/semantic-router/pkg/dsl/{ast.go,parser.go,compiler.go,decompiler.go,validator_conflicts.go} for authoring and compile/decompile parity
src/vllm-sr/cli/{models.py,validator.py} for CLI parity
dashboard/frontend/src/pages/ConfigPageProjectionsSection.tsx if dashboard editing exposes dependent projection nodes
Suggested starting points
- Start by defining one constrained dependency model, such as score inputs that may reference earlier projection scores or outputs.
- Add validator rules for undefined references, cycles, and evaluation ordering before broadening the syntax.
- Keep the runtime auditable by making ordering explicit rather than implicit.
Current contract limits
The current runtime computes projections in a single shallow pass:
- partitions normalize competing base-signal matches
- scores compute weighted sums
- mappings emit decision-visible labels
That means scores do not currently form a richer typed dependency graph.
Validation commands
make agent-report ENV=cpu CHANGED_FILES="src/semantic-router/pkg/classification/classifier_projections.go,src/semantic-router/pkg/config/projection_config.go,src/semantic-router/pkg/config/validator_projection.go,src/semantic-router/pkg/dsl/ast.go,src/semantic-router/pkg/dsl/parser.go,src/semantic-router/pkg/dsl/compiler.go,src/semantic-router/pkg/dsl/decompiler.go,src/semantic-router/pkg/dsl/validator_conflicts.go,src/vllm-sr/cli/models.py,src/vllm-sr/cli/validator.py,dashboard/frontend/src/pages/ConfigPageProjectionsSection.tsx,dashboard/frontend/src/pages/configPageSupport.ts"
make vllm-sr-test
make test-semantic-router
make dashboard-check
Acceptance criteria
Non-goals
- arbitrary scripting or free-form expression languages in projections
- recursive or cyclic projection graphs
- bypassing decision readability by pushing full routing policy into projections
Related
Describe the feature
Support hierarchical projection composition so later projection nodes can consume earlier projection scores, calibrated confidences, or named projection outputs instead of forcing every routing overlay into one shallow
scores -> mappingsstep.Primary layer
global level
Why this layer?
This changes the generic projection contract and runtime evaluation order across router config, DSL, CLI schema, and insights surfaces. It is broader than one detector family or one UI page.
Why do you need this feature?
Today projection composition is shallow:
That works for simple coordination, but it gets awkward for layered routing constructs such as:
Without projection-to-projection composition, those interactions either get flattened into one oversized score or pushed back into decision logic.
Additional context
Affected repo surfaces
src/semantic-router/pkg/classification/classifier_projections.gofor dependency-aware runtime evaluationsrc/semantic-router/pkg/config/{projection_config.go,validator_projection.go}for graph-aware validationsrc/semantic-router/pkg/dsl/{ast.go,parser.go,compiler.go,decompiler.go,validator_conflicts.go}for authoring and compile/decompile paritysrc/vllm-sr/cli/{models.py,validator.py}for CLI paritydashboard/frontend/src/pages/ConfigPageProjectionsSection.tsxif dashboard editing exposes dependent projection nodesSuggested starting points
Current contract limits
The current runtime computes projections in a single shallow pass:
That means scores do not currently form a richer typed dependency graph.
Validation commands
make agent-report ENV=cpu CHANGED_FILES="src/semantic-router/pkg/classification/classifier_projections.go,src/semantic-router/pkg/config/projection_config.go,src/semantic-router/pkg/config/validator_projection.go,src/semantic-router/pkg/dsl/ast.go,src/semantic-router/pkg/dsl/parser.go,src/semantic-router/pkg/dsl/compiler.go,src/semantic-router/pkg/dsl/decompiler.go,src/semantic-router/pkg/dsl/validator_conflicts.go,src/vllm-sr/cli/models.py,src/vllm-sr/cli/validator.py,dashboard/frontend/src/pages/ConfigPageProjectionsSection.tsx,dashboard/frontend/src/pages/configPageSupport.ts" make vllm-sr-test make test-semantic-router make dashboard-checkAcceptance criteria
Non-goals
Related