76. Slash command entity-context separation

August 11, 2026 · View on GitHub

Date: 2026-07-28

Status

Accepted

Extends entity-context rules for conversation surfaces in ADR 0086.

Refines ADR 0002 (initial design) and reinforces ADR 0020 (single-responsibility agents).

Context

Each agent consumes inputs from a specific entity context. The code agent reads issue title, body, labels, and triage comments to implement a fix; the fix agent reads review feedback and the PR diff to iterate on an existing branch. Running either agent in the wrong context is a category error — the code agent cannot extract issue fields from a PR comment, and the fix agent cannot iterate on a branch that does not yet exist (#533).

ADR 0002 defined /implement (now /fs-code per ADR 0042) on issues and /review on PRs, but did not explicitly restrict commands to their entity context. ADR 0020 established single-responsibility agents with tailored sandboxes — context separation is the dispatch-layer corollary.

The restriction was implemented in #533 as if guards in the per-repo shim dispatch workflow (internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml) and is enforced today via ISSUE_HAS_PR checks there. The Go dispatch router (internal/dispatch/router.go) does not yet enforce entity-kind separation — it accepts any valid agent name regardless of entity context. Future CEL trigger expressions on harness files (ADR 0061) are the intended long-term enforcement mechanism.

Decision

Slash commands are restricted to the entity context where their agent's inputs exist:

CommandAllowed contextRationale
/fs-codeIssue without an associated PRConsumes issue title/body/triage output
/fs-fixPR (issue with associated PR)Consumes review feedback and PR diff
/fs-reviewPR (issue with associated PR)Evaluates the current PR head
/fs-triageEitherOperates on issue metadata (available on both)
/fs-retroEitherRead-only analysis of completed workflows
/fs-prioritizeEitherRead-only scoring of issue metadata

Dispatch layers must enforce these restrictions before agent invocation. The enforcement mechanism is implementation-specific:

  • GitHub Actions dispatch (current): ISSUE_HAS_PR guards in the routing script.
  • Go router (interim): should add Entity.Kind checks to routeSlashCommand for code and fix stages.
  • CEL triggers (target state per ADR 0061): harness trigger expressions encode the entity-kind constraint (e.g., event.entity.kind == "work_item" && !has(event.entity.linked_change_proposal) for the code agent).

Consequences

  • Commands invoked in the wrong context are silently dropped — no agent runs, no error comment. This matches the existing behavior for unauthorized or unrecognized commands.
  • Users see only the commands relevant to their context in practice, reducing confusion from overlapping command names (#461).
  • Adding a new agent requires deciding its entity context and encoding the constraint in the dispatch layer alongside the harness definition.
  • The Go router needs a follow-up change to enforce entity-kind separation, aligning it with the GitHub Actions dispatch behavior.