Skip to content

Commit d96a4f7

Browse files
authored
feat(router): milestone 2 slice 1 session-aware policy (#15)
* feat(router): add session-aware policy inputs and continuity switching * feat(router): propagate policy metadata and add milestone 2 checkpoint * fix(router): align continuity metadata and refusal explanations * docs/router: clarify emitted fields and add fixture hard-constraint case * fix(router): clarify current-target blocker semantics --------- Co-authored-by: Hanna Rosengren <4538260+hannasoderstromdev@users.noreply.github.com>
1 parent a0ffc3b commit d96a4f7

7 files changed

Lines changed: 668 additions & 32 deletions

File tree

docs/contracts/router-contracts.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,32 @@ Notes:
154154
"selectedTargetId": "string|null",
155155
"shouldSwitch": "boolean|null",
156156
"continuityCost": "low|medium|high|null",
157+
"continuityDecision": "stay_on_current_target|select_target_without_current_context|avoid_switch_due_to_continuity_cost|switch_target|no_selected_target|null",
158+
"continuityReason": "string|null",
157159
"routingOverride": {
158160
"requested": "auto|stronger|cheaper|stay",
159161
"applied": "boolean",
160162
"reason": "string|null"
161163
},
164+
"modeResolution": {
165+
"previousMode": "plan|implement|debug|review|summarize|agent_workflow|out_of_domain|null",
166+
"proposedMode": "plan|implement|debug|review|summarize|agent_workflow|out_of_domain",
167+
"resolvedMode": "plan|implement|debug|review|summarize|agent_workflow|out_of_domain",
168+
"transitionReason": "string"
169+
}|null,
170+
"policyInputs": {
171+
"hardConstraints": {
172+
"privacy": "enforced|advisory|off",
173+
"availability": "enforced|advisory|off",
174+
"clientCompatibility": "enforced|advisory|off",
175+
"requiredPrivacyTier": "external|local|standard|restricted|unknown|null",
176+
"clientSurface": "string|null"
177+
},
178+
"softConstraints": {
179+
"userPreference": "auto|stronger|cheaper|stay",
180+
"projectOverride": "string|object|null"
181+
}
182+
}|null,
162183
"explanation": "string",
163184
"refusalReason": "string|null"
164185
}
@@ -170,6 +191,7 @@ Notes:
170191
* `shouldSwitch` and `continuityCost` may be `null` when status is refused.
171192
* `softConstraintInputs` records preference inputs for explainability even when policy depth is staged.
172193
* `routingOverride` matches current implementation output naming.
194+
* `continuityDecision`, `continuityReason`, `modeResolution`, and `policyInputs` are currently emitted by the implementation and treated as additive experimental fields in `0.1.0-experimental`.
173195

174196
### 5) ContextPackage
175197

docs/decision-log.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,43 @@ Consequences:
123123
Follow-up:
124124
- Next review milestone: Milestone 2 plan-to-implementation checkpoint.
125125
- Linked artifacts (logs, fixtures, docs, PRs): docs/ROUTER-PHASE-PLAN.md, docs/contracts/router-contracts.md
126+
127+
## Milestone 2 Checkpoint (Slice 1)
128+
129+
Decision ID: DEC-2026-05-10-milestone-2-slice-1-session-policy
130+
Related deferred item: Milestone 2 staged policy depth
131+
Status: committed
132+
Date: 2026-05-10
133+
Owners: team
134+
135+
Context:
136+
- Milestone 2 requires session-aware routing with explicit policy inputs, while keeping current behavior stable and deferring high-risk commitments until verification gates are met.
137+
138+
Options considered:
139+
- Option A: implement full policy depth and enforcement in one large change.
140+
- Option B: ship a scoped first slice with session-mode resolution, named hard/soft inputs, and continuity-aware switching plus focused tests.
141+
142+
Tradeoffs:
143+
- Option A: faster feature completion on paper, higher regression and review risk.
144+
- Option B: lower risk and clearer validation trail, requires additional follow-up slices.
145+
146+
Verification signal:
147+
- Expected signal from phase plan: policy inputs represented explicitly and decision outputs explainable with session and continuity context.
148+
- Evidence observed:
149+
- Router now exposes `modeResolution`, `policyInputs`, `taskType`, and continuity fields in route decisions.
150+
- Switchboard evidence summaries now carry these fields through workflow logs.
151+
- Tests cover staged hard constraints (availability, privacy, client compatibility) and continuity decisions.
152+
153+
Decision:
154+
- Chosen option: Option B.
155+
- Scope of commitment: complete Milestone 2 slice 1 with deterministic session-policy behavior and evidence propagation.
156+
- What remains intentionally deferred: numeric continuity scoring, final taxonomy freeze, strict universal enforcement defaults, and cross-surface validation beyond current scope.
157+
158+
Consequences:
159+
- Near-term implementation impact: improves explainability and policy shape with minimal API disruption.
160+
- Test and replay impact: adds coverage for staged hard constraints and continuity cost behavior.
161+
- Migration impact: low; fields are additive and aligned with experimental contracts.
162+
163+
Follow-up:
164+
- Next review milestone: Milestone 2 slice 2 planning.
165+
- Linked artifacts (logs, fixtures, docs, PRs): src/router/router.js, src/switchboard/workflow.js, test/router.test.js, test/switchboard-workflow.test.js

src/router/data/fixtures.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,26 @@
122122
"classificationReason": "implementation_signal"
123123
}
124124
},
125+
{
126+
"name": "availability_constraint_refusal",
127+
"input": "Implement the plan.",
128+
"session": {
129+
"mode": "plan",
130+
"policyInputs": {
131+
"hardConstraints": {
132+
"availability": "enforced"
133+
}
134+
}
135+
},
136+
"targetOverride": "coder_unavailable",
137+
"expected": {
138+
"status": "refused",
139+
"mode": "implement",
140+
"requiredCapabilities": ["repo_context", "file_read", "file_edit"],
141+
"explanationIncludes": ["hard constraints"],
142+
"classificationReason": "implementation_signal"
143+
}
144+
},
125145
{
126146
"name": "ambiguous_implementation_approval",
127147
"input": "Sounds good, go ahead.",

0 commit comments

Comments
 (0)