Stage 4 of 4. Typescript. Plan about 2 hours.
Join ranking and dependency planning while preserving four distinct outcomes: ready, no-match, ambiguous and blocked. A score gap below the margin is ambiguous even if the tie-breaker produces a first result. A ranked winner can still be blocked by permissions. Return the ranked explanations in every outcome so a caller can display the decision.
The boundary for this stage is route. Keep earlier stage behavior intact: the final grader runs every stage against the same workspace.
pj skill router 4
Worked Orchard case
Before coding, review TypeScript object types and Tool schema design. Complete stage 3 first.
Abstain when two skills score too closely or the chosen plan needs unavailable permissions. An explanation of why routing stopped is more useful than an arbitrary winning skill.
publish request -> release-publish score 2
allowed=[read]; publish requires network
status=blocked, no execution planBuild and inspect
Apply the score margin before dependency planning. Treat ranking as evidence for selection, not authority to execute a tool.
Implement the stage in your learner workspace. The CLI helpers are provided adapters and import your functions; they do not substitute the reference solution.
python3 scripts/project_test.py skill-router --stage 4 --path learning-artifacts/skill-routerAfter the cumulative stages pass, run your artifact on the original sample input from the repository root:
node learning-artifacts/skill-router/cli.ts projects/skill-router/examples/skills projects/skill-router/examples/request.jsonSKILL.md provides standard name and description; routing.json is this project's documented local extension. The router emits plans and explanations, and never executes a selected skill. Keyword tokenization is an ASCII lexical baseline; a multilingual routing model is an extension.
Investigate next
How would you tune one ambiguous keyword without overfitting to the example request?