fix(groomer): resolve LLM-emitted lane ids through laneAliases map before validation#475
fix(groomer): resolve LLM-emitted lane ids through laneAliases map before validation#475itsmiso-ai wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
AI Automated Review
Full PR review.
Analysis engine: MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic) — routed smart (risk match: db_or_migration_changes)
Recommendation: Approve
This is a clean, well-scoped bug fix that correctly resolves the reported issue where Nvidia model outputs legacy lane IDs (normal, escalated) that fail validation against the configured lane IDs (local, cloud, frontier, backlog).
Change Summary
src/lib/groomer/schema.ts
- Imports
resolveLaneIdfrom the existinglane-configlibrary (consistent with repository patterns established in PR 454) - Refactors lane validation to: (1) check if laneId is a string, (2) resolve through
resolveLaneId(), (3) validate the resolved ID, (4) mutatelaneObj.idto the resolved value so downstream consumers see the configured lane ID
src/lib/groomer/schema.test.ts
- Adds 5 focused tests covering: direct lane ID pass-through,
normal→localalias,escalated→frontieralias, bogus lane rejection, and input object mutation verification
Required Checks
✅ review migration for data loss risk
Not applicable — no migration present.
This PR contains zero database changes. The diff touches only TypeScript validation logic in src/lib/groomer/schema.ts and its test file. There is no Prisma schema change, no migration file, and no SQL. Therefore, there is no data loss risk to assess.
✅ test migration on a copy of production schema
Not applicable — no migration present.
Same rationale as above: this PR introduces no database migrations. The lane alias resolution operates purely at the application validation layer, not the database layer. Repository history confirms the lane aliases feature was introduced in PR 454 (feat: 3-tier lane model (local/cloud/frontier) with backward-compat aliases) and migration-safe deployments in PR 434 (feat: support migration-safe custom lane deployments); this PR extends that alias resolution to the groomer schema validation path.
Standards Compliance
| Convention | Status |
|---|---|
Error handling (error instanceof Error pattern) |
N/A — validation errors are structured array messages, consistent with existing validateGroomerOutput() design |
| No commit of secrets | ✅ No secrets involved |
Import from @/lib/lane-config |
✅ Reuses existing resolveLaneId and isValidLane helpers |
| TypeScript types | ✅ No type regressions |
| Input validation | ✅ Bogus lane IDs are still rejected |
Evidence Provider Findings
No evidence providers configured for this PR.
Tool Harness Findings
No tool harness findings — reviewing corpus directly.
CI Check Results
All checks passed successfully:
- Docker Build: ✅ completed
- Build: ✅ completed
- Tests: ✅ completed (39 tests, including 5 new)
- Typecheck: ✅ completed
- Lint: ✅ completed
Unknowns / Needs Verification
None. The PR is self-contained with clear bug evidence ("4/4 dry-runs failed post PR PR 473"), a correct fix pattern matching established alias resolution elsewhere in the codebase, and comprehensive test coverage.
Bug
Nvidia model returns legacy lane IDs (
normal,escalated) despite system prompt enumerating configured IDs (local,cloud,frontier,backlog). Live evidence: 4/4 dry-runs failed post PR #473 withinvalid lane id: normal.Fix
Route lane id through
resolveLaneId()before validation invalidateGroomerOutput(). This reuses the existinglaneAliasesmap (e.g.{ normal: "local", escalated: "frontier" }) so legacy LLM output is resolved to configured lane IDs.Also mutates the input lane object with the resolved id so downstream consumers (the plan, the apply path, the audit log, the GroomingRun record) all see the configured lane id rather than the raw alias.
Changes
src/lib/groomer/schema.ts— importresolveLaneId, resolve + validate lane id, mutatelaneObj.idon successsrc/lib/groomer/schema.test.ts— 5 new tests: direct lane id pass-through, normal→local alias, escalated→frontier alias, bogus rejection, input mutationVerification