Skip to content

Explore provider-neutral guard decision protocol #192

Description

@judell

Background

Bram already has provider-neutral protocol surfaces for worklist mode, lifecycle intents, structured action payloads, and direct-edit authorization. Guard denials are still mostly conveyed as provider-specific hook output plus prose, so Codex and Claude can diverge after a blocked tracked-file edit.

The recent no-op edit attempts showed the gap: a guard denial can correctly block a mutation, but the agent still has to infer the next legal transition from conventions text and an English error message.

Sketch from dropped worklist item

Explore a provider-neutral guard-decision protocol for denied or constrained tool actions.

Potential direction: persist a short-lived advisory file at resources/.guard-decision.json whenever a Bram guard denies an action. It must not replace resources/.worklist-authorization.json, resources/.worklist-intent.json, resources/.worklist-result.json, or /__worklist/mutate.

Possible shape:

{
  "kind": "guard-decision",
  "version": 1,
  "decision": "deny",
  "reason": "freestyle-tracked-file-preview",
  "operation": {
    "provider": "codex",
    "hook": "PreToolUse",
    "tool": "apply_patch"
  },
  "paths": ["app/example.py"],
  "allowedNext": ["ask-user-confirm-inline-edit", "switch-to-worklist-proposal"],
  "issuedAtMs": 1781323000000,
  "ttlMs": 300000
}

The proposal was dropped because it is still too vague to implement safely. Before turning this into code, clarify:

  • Which denial classes should be in v1.
  • Whether resources/.guard-decision.json is the right surface or whether this belongs in existing trace/status surfaces.
  • The exact allowedNext vocabulary and which actor consumes it.
  • How Claude and Codex should stay semantically aligned despite different hook contracts.
  • How stale decisions are detected and ignored.
  • What tests prove the protocol without hardening a premature design.

Candidate denial classes from the draft

  • freestyle-tracked-file-preview
  • worklist-missing-coverage
  • worklist-inline-prose
  • mechanical-worklist-change
  • mcp-path-unrecognized
  • gh-body-at-antipattern

Files likely involved later

  • app/__shell/conventions.md
  • app/__shell/worklist-guard.py
  • app/shell/worklist-guard-codex.py
  • docs/apis.md

Source: dropped worklist item provider-neutral-guard-decision.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions