Skip to content

feat(agent-creation): full-stack agent CRUD with authority scopes and proxy tokens#202

Open
marcus-sa wants to merge 22 commits intomainfrom
marcus-sa/agent-crud-discover
Open

feat(agent-creation): full-stack agent CRUD with authority scopes and proxy tokens#202
marcus-sa wants to merge 22 commits intomainfrom
marcus-sa/agent-crud-discover

Conversation

@marcus-sa
Copy link
Copy Markdown
Owner

@marcus-sa marcus-sa commented Mar 28, 2026

Summary

  • Discovery → Deliver pipeline: Problem validation (6 interviews, 2 personas), user stories, architecture design (ADR-081/082/083), acceptance criteria, and TDD roadmap — all tracked in docs/feature/agent-creation/
  • Backend: Agent CRUD route handlers (agent-route.ts), SurrealDB queries with atomic 5-step creation / 6-step deletion (agent-queries.ts), domain types, schema migrations for agent table fields (runtime, name, sandbox_config) and workspace.sandbox_provider
  • Frontend: Agents registry page, detail page with authority scopes display, creation form with runtime selection, proxy token dialog, agent card component, React hooks (use-agents, use-agent-actions), sidebar nav link, and router integration
  • Tests: 4 acceptance test suites (external CRUD, operational dashboard, sandbox creation, walking skeleton) with 23 passing scenarios; 4 client component test files with 33 passing tests covering agent card, authority scope form, proxy token dialog, and all 3 pages
  • Authority model: 11 configurable actions (create/confirm decisions, create/complete tasks, create/acknowledge/resolve observations, create questions/suggestions/intents, submit intents) with auto/propose/blocked permission levels per agent

Test plan

  • bun test tests/acceptance/agents/ — 23 acceptance tests pass (17 R2/R3 skipped as expected)
  • bun --config=bunfig.client.toml test app/src/client/ — 33 client component tests pass
  • bun run typecheck — no type errors

🤖 Generated with Claude Code

marcus-sa and others added 16 commits March 28, 2026 21:39
…assumptions

Validates the agent CRUD feature through evidence-based discovery:
- Drop agent_type enum, replace with runtime field (brain/sandbox/external)
- Authority scopes assigned per-agent at creation via authorized_to relation
- Sandbox provider config at workspace level, agent config on agent record
- Agents page serves as both registry and operational dashboard

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 077e40d836b2
Complete product discovery through acceptance test design for agent
management feature — replacing hardcoded agent_type enum with runtime-based
architecture (brain/sandbox/external).

DISCUSS: 13 user stories across 3 releases, walking skeleton prioritizing
external agent CRUD. Comprehensive journey design with emotional arcs,
shared artifact registry, and outcome KPIs.

DESIGN: Zero new dependencies. Schema migrations (runtime field,
sandbox_config, workspace sandbox provider). 5-step atomic creation
transaction with proxy token inside transaction. Authority model using
authorized_to edges with 11 configurable actions defaulting to "propose".
Three ADRs (081-083) covering migration strategy, transaction atomicity,
and custom agent authority.

DISTILL: 40 acceptance test scenarios (R1 enabled, R2/R3 skipped).
Walking skeleton validates full architecture. 43% error coverage ratio.
Port-to-port tests through HTTP endpoints only.

Review fixes applied: proxy token prefix aligned to brp_ (matching
proxy-token-core.ts), proxy token moved inside transaction for atomicity,
authority actions enumerated, R1 session list limitation documented,
sandbox config validation error shapes specified, name uniqueness
pre-check endpoint added.

Also adds deferred work policy to AGENTS.md requiring GitHub issues for
all out-of-scope items.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 4cd0327eee06
Migration 0081 extends the agent table with three new fields for the
agent creation feature: runtime (brain|sandbox|external), name, and
sandbox_config (optional object for sandbox agent configuration).

Backfills runtime from existing agent_type values and name from the
linked identity record. Updates identity-bootstrap.ts to write
runtime:'brain' and name for system agents on workspace creation.

Step-ID: 01-01

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: b12fcd376ff6
Migration 0082 adds settings.sandbox_provider field to workspace table.
Allowed values: local, e2b, daytona, docker (or NONE when unset).
Controls which sandbox environment is available for sandbox agents.

Step-ID: 01-02

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 48c247bb6e8f
Define the agent domain model (types.ts) with AgentRuntime,
AuthorityAction (11 actions), AuthorityPermission, CreateAgentInput,
AgentListItem, AgentDetail, and related types.

Implement query functions (agent-queries.ts):
- listAgents: graph traversal workspace <- member_of <- identity <- identity_agent -> agent
- checkAgentName: name uniqueness validation within workspace
- createAgentTransaction: atomic 7-step creation (agent, identity, edges, authority scopes, proxy token)
- getAgentDetail: batched query for agent + identity + scopes + sessions
- deleteAgentTransaction: atomic cascade deletion with safety validations

Step-ID: 01-03
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: b7ab04783990
Create agent-route.ts with handler factory pattern following the
established policy-route.ts conventions. Five handlers delegate to
agent-queries.ts: list, create, detail, check-name, and delete.

All handlers resolve identity from Better Auth session, validate
workspace existence, and set span attributes for observability.
The create handler validates runtime, sandbox provider config,
and name requirements before delegating to the transaction.

Routes registered in start-server.ts with check-name before :agentId
to prevent parameter capture.

Step-ID: 01-04

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 9069c9c3fb35
…ts passing

Backend implementation of agent CRUD (R1 walking skeleton):
- Schema migrations 0081 (runtime/name/sandbox_config) and 0082 (sandbox_provider)
- Domain types, SurrealDB query functions, route handlers
- Atomic creation transaction (agent+identity+edges+scopes+proxy_token)
- Atomic deletion with edge cleanup and brain agent protection
- 4 walking skeleton + 19 focused acceptance tests all passing

Frontend phases (04-06) deferred to separate deliver run per AGENTS.md.

Step-ID: 01-01, 01-02, 01-03, 01-04, 02-01, 02-02, 02-03, 03-01, 03-02
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: ded004690bca
Add the agents list page with runtime grouping (brain/sandbox/external),
agent card component with runtime-appropriate actions (View for brain,
Edit+Delete for others), data hooks, route registration at /agents, and
sidebar navigation link. Includes 5 client component tests.

Step-ID: 04-01

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 6043552b1ca5
Add AgentDetailPage component at /agents/$agentId that shows agent
configuration, authority scopes as action-permission pairs, and recent
workspace sessions. Brain agents display a read-only system agent note;
external/sandbox agents show a delete button with confirmation dialog.
Back navigation link returns to the agent registry.

6 client tests covering: name/description rendering, authority scopes
table, read-only note for brain agents, delete button for non-brain
agents, back navigation, and session display.

Step-ID: 04-02

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: dd52c78ca7e6
…and authority scope config

Multi-step creation flow: runtime selection (external/sandbox), then form with
name validation (uniqueness via check-name API), description, model, and 11-action
authority scope table defaulting to propose. Registers /agents/new route before
/agents/$agentId to prevent param matching conflict.

Step-ID: 05-01

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 65bb4073b311
After successful external agent creation, the proxy token dialog now
displays the one-time brp_ token with copy button and X-Brain-Auth
usage instructions. Sandbox agents (no proxy_token in response)
navigate directly to /agents. Adds 4 unit tests for ProxyTokenDialog
and 2 integration tests for the create page flow branching.

Step-ID: 05-02

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 06765285b51f
…ns, and name link

Covers: runtime badge labels (Brain/External/Sandbox), View-only for brain agents,
Edit+Delete for non-brain agents, agent name as link to detail page,
description presence/absence, and onDelete callback invocation.

Step-ID: 06-01

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: f42e5fadd91a
Verify the AuthorityScopeForm renders all 11 authority actions as rows,
defaults each to "propose" permission, provides auto/propose/blocked
options, triggers onChange on permission change, and disables all inputs
when disabled prop is set.

Step-ID: 06-02

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: bbedc056ccd8
…current safety

Bun's mock.module replaces the entire module globally. When agent test files
run concurrently, whichever mock loads last wins. Mocks missing useParams,
useMatchRoute, or useSearch caused SyntaxError in concurrent test files.

Step-ID: 06-02

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 2cda602cd499
The frontend had wrong action names (edit_task, edit_decision,
create_session, create_commit) instead of the 11 actions from
architecture-design.md (confirm_decision, complete_task,
acknowledge_observation, resolve_observation).

Also: test imports AUTHORITY_ACTIONS from component instead of
redefining locally, and detail page test fixture uses real actions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 2525b6b5c6e3
Move seedBrainAgent, getIdentityForAgent, getAuthorityEdgesForIdentity,
hasMemberOfEdge, and getProxyTokensForIdentity from agents-test-kit to
shared-fixtures for reuse across test suites. Add proxy-token-dialog
component.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 550f09346680
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

Typecheck: remove unused imports (Link, beforeEach, within, useWorkspaceState),
prefix unused param with underscore, fix mock.calls type cast.

Acceptance tests: add required `name` and `runtime` fields to agent creation
in identity-schema, walking-skeleton, audit-trail, and reactive-test-kit
to match migration 0081 schema requirements.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 9b4a987fa965
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

…ction

Migration 0081 failed silently because DEFINE FIELD name ON agent applied
to existing records with NONE for name. The migrate.ts runner was not
detecting transaction failures from SurrealDB streaming frames.

- Fix migrate.ts to use frame.isError() for proper failure detection
- Remove agent_type from authority_scope (one record per action now)
- Simplify checkAuthority to: authorized_to edge → global default → blocked
- Bootstrap brain-managed agents with authorized_to edges and member_of
- Update all tests to remove agent_type from agent record creation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 9109f9be5e82
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

marcus-sa and others added 2 commits March 29, 2026 01:06
agent_type was a closed enum that no longer exists in the DB schema.
Remove it from JWT token issuance (was hardcoded "code_agent" for all
person tokens), MCP auth validation (no longer validates against a
closed set), and proxy telemetry (renamed to agent_name). AgentType
is now a free-form string alias, not a constrained union.

- Remove "urn:brain:agent_type" JWT claim from OAuth token issuance
- Remove VALID_AGENT_TYPES closed-set validation from MCP auth
- Remove "urn:brain:agent_type" from BrainTokenClaims type
- Rename proxy span attribute from proxy.agent_type to proxy.agent_name
- Fix seed.ts to use name+runtime instead of agent_type

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 0e8ec61f0a06
AgentType was a closed enum that no longer reflects the data model.
Delete the type alias completely and remove it from all imports.
Remove agentType parameter from checkAuthority (was unused in queries).
Remove agentType from McpAuthResult (no longer needed for auth).
Remove DEFAULT_AGENT_TYPE from MCP route handlers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 01725a9cea5a
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

marcus-sa and others added 2 commits March 29, 2026 14:49
Evolution document captures feature summary, key decisions from all waves,
steps completed, architecture, and lessons learned. Architecture design,
component boundaries, technology stack, test scenarios, walking skeleton,
and UX journey artifacts migrated to permanent directories.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: d5e7a5484983
Remove docs/feature/agent-creation/ (process scaffolding superseded by
evolution doc and permanent artifact locations), RCA analysis doc, and
nWave session state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Marcus Schack Abildskov <work@marcus-sa.dev>
Entire-Checkpoint: 6a48a065ac91
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant