feat(guardrails): steering channel + shell-in-file rule + capability-gap detector
Bundles three operator-reliability guardrails (Vikunja #28/#29/#30) plus the in-flight branch WIP they were built on top of (reasoning_content capture, operator/project profile editor, write-jail workspaceRoot fix) — the tree is interdependent (SessionOrchestrator references reasoningArtifactId from the WIP) and does not compile as separable subsets, so it lands as one commit. Guardrails: - #28 mid-stage steering: ClientMessage.SteerSession -> GlobalStreamHandler -> orchestrator.submitSteering, reusing SteeringNoteAddedEvent + existing context fold (advisory, non-authoritative; invariants #3/#7). Closes the gap where steering typed off an approval gate was silently dropped. - #29 shell-in-file guardrail: ShellInFileContentRule (core:toolintent) blocks a file_write whose content is a bare shell command (e.g. "mkdir -p ..."); FileWriteTool description now advertises auto-mkdir of parent dirs. Basename-allowlist so the extensionless case is caught; scripts/Makefiles/multiline exempt. - #30 pt1 capability-gap detector: deterministic CapabilityGapDetector maps stage intent -> implied ToolCapability, compares to granted tools, emits advisory CapabilityGapDetectedEvent in FreestyleDriver.lockAndRun. Recorded, never fails the gate and never auto-grants (invariants #3/#4/#5). Reflection rung is pt2. Verified: ./gradlew check green (whole tree).
This commit is contained in:
@@ -22,11 +22,8 @@ Emit your result as the `analysis` artifact (JSON, schema provided):
|
||||
- `requirements`: concrete requirements / acceptance criteria, one per line.
|
||||
- `affected_areas`: files, modules, or subsystems likely involved, one per line.
|
||||
|
||||
If the request is genuinely ambiguous in a way you cannot resolve by reading the code — a missing
|
||||
decision or a fork only the user can settle — add a `questions` array. Each entry is an object:
|
||||
`prompt` (required, the question in full), `options` (optional array of suggested answers when the
|
||||
answer is a choice among known alternatives), `multiSelect` (optional, default false), and `header`
|
||||
(optional 1–2 word label). Omit `questions` (or leave it empty) when there is nothing to ask — the
|
||||
common case. The user answers in a form and their answers return to you for a re-run.
|
||||
Always produce the analysis — it is your single exit. Resolving operator forks and open questions
|
||||
is the **Discovery** stage's responsibility, upstream of you; treat the request as settled and do
|
||||
not ask the user anything here. Anything you cannot answer, answer by reading the code.
|
||||
|
||||
Keep it factual and grounded in what you actually read. Do not propose a solution yet.
|
||||
|
||||
Reference in New Issue
Block a user