Skip to content
This repository was archived by the owner on Oct 1, 2026. It is now read-only.
This repository was archived by the owner on Oct 1, 2026. It is now read-only.

Role agents get the permissions, network and tools their role needs #138

Description

@lukemaj

Outcome

Every agent Prism or a planner starts in a role can do that role's job unattended: it has the permissions, network and tools the job needs, is never started in a mode that waits for human approval, and is never asked to do something its role cannot do.

Evidence (2026-09-27 to 2026-09-28, Router 0.37.0, policy 2.10.0, Chromeria T3 planner; job prism-muk1zqbl-09879193, lukemaj/transcribe-queue#3)

Agent Started by, role, route Mode and permissions What happened
#142 implementer planner, spawn_thread no role, Claude Opus 5.5 full-access Worked end to end.
Prism dispatcher Prism, dispatcher, Codex gpt-6-luna max inherited Asked the planner twice: versioning authority (legitimate) and "direct an eligible independent-review route so I can continue without choosing or starting another agent myself" (caused by the next row).
Prism workers impl_2/3/5 Prism, worker, OpenCode Muse Spark free OpenCode * allow Could not obtain independent review: worker kit threadTools: none and "worker rules forbid starting agents", so it self-reviewed. Also reported list_thread_pull_requests "not available in this environment" though its brief required it. When told to run Luna itself through a nested opencode run, it did, got a request_changes verdict with 7 majors at 19:57, then went silent while parsing it; the job blocked (see #132) and that verdict never reached anyone.
Runner proof Prism runner n/a Proof ran in the canonical checkout (head_commit 57e96b6, main), not the worker's worktree at 6c1c881, so the dispatcher correctly reported exact-head proof missing.
Reviewer planner, spawn_thread(role: reviewer, runtimeMode: "auto"), Codex gpt-6-luna Codex auto = sandbox: workspace-write, no network (CodexSessionRuntime.ts:535-539) gh issue view failed: "error connecting to api.github.com". Returned a blocker it could not resolve.
Worker planner, spawn_thread(role: worker, runtimeMode: "auto"), OpenCode Muse free OpenCode auto falls back to asking: bash: ask, edit: ask First command waited for an approval nobody saw, was aborted; no progress for about 20 hours. Parent saw running.
Worker (retry), Reviewer (retry) planner, same roles, runtimeMode: "full-access" full Both succeeded; the reviewer approved 01d5550 without re-finding the lost Luna majors (two reviews on nearby SHAs disagreed and nothing reconciled them).

Settings at the time: prismRoles in Chromeria sets models only; no role kit sets runtimeMode, instructions or skills, so every role inherits the spawning thread's mode (packages/contracts/src/prism.ts, "absent means the spawning thread's runtime mode"). Default thread-tool scopes: dispatcher children, reviewer project-read, worker none.

Causes

  1. A role's capabilities come from whoever spawns it, not from the role. The same role works or silently stalls depending on a mode string the caller passes; the meaning of each mode differs by provider (Codex auto has no network, OpenCode auto asks for every command).
  2. Independent review is assigned to an agent that cannot start one. The worker is told to obtain it but has no thread tools and is forbidden to start agents; the dispatcher then asks the planner for a route instead of starting a reviewer itself.
  3. Briefs require tools the role does not have (list_thread_pull_requests, link_pull_request for OpenCode workers).
  4. Proof is measured in the wrong checkout when the worker uses a worktree.

Elon record

  • Wanted result: unattended role agents never block on permissions or missing network, and every required step (review, proof) is done by a role able to do it.
  • Cuts: surfacing child approval prompts to the parent (Parent threads cannot see a child blocked on an approval chromeria#58, closed as superseded): unnecessary once roles never run in approval modes. Runtime capability probes at launch: add only if the static mapping drifts. Capability-based model routing (#118): unrelated.
  • Smallest surviving solution:
    1. Each role kit carries the capability it needs (worker: edit, shell, network, git push; reviewer: read, shell for tests, network, no writes enforced by instructions; dispatcher: thread tools and network). Prism maps that to each provider's non-interactive mode and uses it for the role, ignoring a weaker caller runtimeMode with a reported note.
    2. The dispatcher starts the independent reviewer (reviewer role, different family) itself after every candidate; workers are never asked to.
    3. Briefs list only tools the target role has; the dispatcher does tool-gated steps (PR linking) itself.
    4. Runner proof runs at the candidate's worktree HEAD.

Acceptance criteria

  • Starting a worker or reviewer with runtimeMode: "auto" on OpenCode or Codex yields a session that runs shell commands without approval and reaches GitHub, or is refused with a named reason; never a silent wait.
  • A Prism job whose worker produces a candidate gets an independent review from a reviewer-role thread started by the dispatcher, bound to the candidate SHA, with no planner question.
  • No worker brief requires a tool its kit lacks (test on the rendered brief for each provider).
  • The runner's proof report's head_commit equals the candidate SHA when the worker used a worktree.
  • Rerun of the Issue Build the Mac-only Agent Observer #3 scenario: no planner question about review routes, no approval wait, proof on the candidate SHA.

Non-goals

Contribution to the Objective

Makes Prism jobs run to a reviewed PR without the planner rescuing them.

Blockers

Part of the kit schema and spawn behavior lives in toolboxmd/t3code (packages/contracts/src/prism.ts, apps/server/src/mcp/toolkits/threads/); the implementing planner decides the split.

Proof

Deterministic tests for the role-to-mode mapping per provider and for brief tool requirements; one live Prism job on a small Issue showing the criteria above.

Activity

  1. lukemaj commented on Oct 1, 2026

    @lukemaj
    ContributorAuthor

    Resolved in Chromeria: every Prism role has every thread tool (toolboxmd/chromeria#93, #101), children start in full access (toolboxmd/chromeria#89), and the runner's wrong-checkout proof is deleted with the runner (toolboxmd/chromeria#92).

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions