Problem Statement
The agent-driven policy loop in #1062 supports agent-authored policy proposals and human approval through CLI/TUI reviewer surfaces. The next step is to support a trusted reviewer agent that can evaluate OpenShell policy chunks and either approve or deny them with guidance.
This should preserve the existing reviewer UX:
- Approve
- Deny
- Deny with guidance
The reviewer agent should not introduce a parallel action such as “approve recommendation.” It should either annotate the existing review surface or, in an explicitly enabled automatic mode, take the same approve/deny actions a human reviewer can take.
Proposed Design
Add an OpenShell-native reviewer-agent path for pending policy chunks.
Suggested flow:
- Main agent hits
policy_denied.
- Main agent submits a policy proposal to
policy.local.
- Gateway stores the proposal as a pending draft chunk.
- Reviewer agent receives structured context:
- sandbox name
- proposed host, port, protocol, method/path, binary
- agent rationale
- validation/prover result
- recent deny/proposal audit events
- prior rejection guidance for related chunks
- Reviewer agent returns one of:
approve
deny
deny_with_guidance
needs_human
- If automatic reviewer mode is enabled, OpenShell records the approve/deny decision with reviewer-agent provenance.
- If advisory reviewer mode is enabled, the TUI/CLI shows the reviewer recommendation, but the human still chooses Approve, Deny, or Deny with guidance.
- Main agent’s
/wait wakes and continues or redrafts.
UX Direction
The TUI should keep the same primary actions:
[a] Approve
[d] Deny
[g] Deny with guidance
Reviewer-agent output appears as context, not as a new button:
Reviewer agent: recommends deny with guidance
Reason: proposed path is broader than the denied request. Scope to /repos/org/repo/contents/demo-runs/<file>.md only.
In automatic mode, the event should read as a real decision:
Denied by reviewer agent
Guidance: scope to the exact GitHub Contents API path only.
Security Requirements
- Reviewer agent must approve based on structured scope, not only natural-language rationale.
- Broad host/path/binary proposals should be denied or escalated to a human.
- Reviewer decisions must be logged with provenance.
- Reviewer agent must not receive raw secrets.
- Denial guidance must round-trip to the main agent through
/wait.
- Reviewer-agent denials should instruct the main agent not to pursue the same access via workaround or policy circumvention.
- Add loop protection/backoff for repeated denials on the same proposal shape.
- Human review remains available.
Relationship To Existing Work
Parent: #1062
Related:
This issue is about the reviewer path for submitted policy chunks. It is not an LLM PolicyAdvisor replacement and should not generate proposals on behalf of the main agent.
Definition of Done
Problem Statement
The agent-driven policy loop in #1062 supports agent-authored policy proposals and human approval through CLI/TUI reviewer surfaces. The next step is to support a trusted reviewer agent that can evaluate OpenShell policy chunks and either approve or deny them with guidance.
This should preserve the existing reviewer UX:
The reviewer agent should not introduce a parallel action such as “approve recommendation.” It should either annotate the existing review surface or, in an explicitly enabled automatic mode, take the same approve/deny actions a human reviewer can take.
Proposed Design
Add an OpenShell-native reviewer-agent path for pending policy chunks.
Suggested flow:
policy_denied.policy.local.approvedenydeny_with_guidanceneeds_human/waitwakes and continues or redrafts.UX Direction
The TUI should keep the same primary actions:
Reviewer-agent output appears as context, not as a new button:
In automatic mode, the event should read as a real decision:
Security Requirements
/wait.Relationship To Existing Work
Parent: #1062
Related:
This issue is about the reviewer path for submitted policy chunks. It is not an LLM PolicyAdvisor replacement and should not generate proposals on behalf of the main agent.
Definition of Done
/wait.