feat: plane-2 rules read declared param roles instead of guessing args

Add ParamRole and a defaulted Tool.paramRoles to the tool contract; built-in
tools declare which params carry effects: file_read/write/edit -> path=PATH,
shell -> argv=EXEC_COMMAND. PathContainmentRule / ExecInterpreterRule /
NetworkHostRule now inspect only the declared params when roles are present, and
fall back to the looksLikePath / leading-token / extractHost heuristic only for
un-enriched (e.g. custom) tools - so a custom FILE_WRITE tool is still
containment-checked. Shared extractParamStrings flattens String and List<*>
(argv) values. SessionOrchestrator.runPlane2Assessment resolves the tool once
and passes tool.paramRoles into the assessment input.

This retires the arg-guessing from the first-party path: a slashy edit 'content'
arg is no longer mis-flagged as a path.
This commit is contained in:
2026-05-31 16:15:22 +04:00
parent 97d03eb7bd
commit ff166ed311
14 changed files with 125 additions and 14 deletions
@@ -599,13 +599,14 @@ abstract class SessionOrchestrator(
): RiskSummary? {
val assessor = toolCallAssessor ?: return null
val policy = workspacePolicy ?: return null
val capabilities = toolRegistry?.resolve(toolName)?.requiredCapabilities ?: emptySet()
val tool = toolRegistry?.resolve(toolName)
val assessment = assessor.assess(
ToolCallAssessmentInput(
request = request,
capabilities = capabilities,
capabilities = tool?.requiredCapabilities ?: emptySet(),
workspace = policy,
probe = worldProbe,
paramRoles = tool?.paramRoles ?: emptyMap(),
),
)
emit(