Skip to content

flows: AgentOptions has no permissions field on the TypeScript authoring surface #445

Description

@kjgbot

Re-filed from #442, which can no longer launch a run — see AgentWorkforce/cloud#3768. Scope here is deliberately narrower than #442: the TypeScript authoring-surface parity gap only. Enforcement stays in #442.

Spec citation

docs/RFC-0001-everything-is-a-relayflow.md:237: "An agent step declares its mutable surfaces up front: workspace... Anything undeclared is outside the contract and outside the step's permissions (gate 8 makes this enforceable, not advisory)."

Current state

The declarative kernel spec already has a real, per-step permissions field — AgentStepSpec.permissions?: PermissionsSpec (packages/sdk/src/spec.ts:250):

interface PermissionsSpec {
  fileGlobs?: string[];
  networkAllowlist?: string[];
  accessPreset?: "readonly" | "readwrite";
}

It compiles to KernelAgentStep.permissions / KernelPermissionsSpec (file_globs / network_allowlist / access_preset, packages/sdk/src/spec.ts:443) and is schema-validated by both the SDK (packages/sdk/src/validate.ts:490, packages/sdk/src/compile.ts:471-472,533-537,637-641) and the kernel (kernel/relayflowd-core/src/spec.rs).

The gap: it is not on the TypeScript authoring surface. AgentOptions in packages/surface/src/context.ts exposes task, workspace, cli, model, cwd, transport — no permissions. So f.agent(name, options) in a .flow.ts file has no way to set it; only the declarative YAML/JSON dialect (or a hand-built StepSpec / compileSpec() call) can.

This is the same class of gap that #310 fixed for cli / model, and that prior fix is the shape to follow.

Scope

  1. Ctx.agent options. Add optional permissions?: PermissionsSpec to AgentOptions in packages/surface/src/context.ts, mirroring AgentStepSpec.permissions exactly (camelCase fileGlobs / networkAllowlist / accessPreset).
  2. Lowering. authored-worker-step.ts's agent() passes options.permissions through onto the compiled step spec when present, exactly the way options.cli / options.model / options.cwd are passed through today.
  3. Docs and tests. Surface + SDK coverage mirroring the existing AgentStepSpec.permissions validation cases.

A message that needs updating with this change

authored-worker-step.ts's agent() currently refuses a per-step AgentOptions.workspace string carrying a ": readonly" / ": readwrite" suffix, telling the author to "use the declarative spec's permissions field, which is real." That is accurate about the field existing and being validated, but it overstates the effect — "real" there means "a real, validated field," not "actually restricts what the agent does." Once permissions is settable from TypeScript, that message should point at the new option and should not imply enforcement that does not exist yet.

Motivating example

const draft = await f.agent("writer", {
  task: "...",
  permissions: { fileGlobs: ["drafts/**"], accessPreset: "readwrite" },
});

const review = await f.agent("reviewer", {
  task: "Review drafts/post.md and flag issues; do not edit it.",
  permissions: { fileGlobs: ["drafts/**"], accessPreset: "readonly" },
});

Today this cannot be expressed in TypeScript at all.

Explicitly out of scope

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    garden-readyScoped and ready for an agent to pick up

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions