Skip to content

Add additional scaffolding - #163

Open
mdeyell-valid-mind wants to merge 7 commits into
mainfrom
mdeyell/sc-17522/scaffolding
Open

Add additional scaffolding #163
mdeyell-valid-mind wants to merge 7 commits into
mainfrom
mdeyell/sc-17522/scaffolding

Conversation

@mdeyell-valid-mind

@mdeyell-valid-mind mdeyell-valid-mind commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add an optional access resolver for embedding-application authorization
  • map verified operator identities to capabilities and assigned agent CUIDs
  • scope review invocations, plans, agent-scoped rules, and agents to the caller's assignments
  • allow assigned users to approve, deny, and summarize their own invocations
  • require runtime agent identities to resolve to a stored Atryum agent when authority mode is enabled
  • record the resolved actor on invocation and plan decisions
  • preserve unrestricted operator access for trusted static API-key credentials
  • bind email-less OAuth runtime tokens to the exact stored agent CUID instead of granting user or unrestricted access
  • store stable agent ownership on invocations, plans, and external sessions
  • scope invocation idempotency keys by stable agent CUID
  • expose summary availability without exposing administrative settings
  • support local invocation summarization without requiring a ValidMind backend client

Access model

Embedders can enable the new behavior with atryum.WithAccessResolver.

For human operator tokens, the resolver maps a verified token email to:

  • an opaque actor ID
  • assigned agent CUIDs
  • read_resources
  • update_agents
  • decide_invocations
  • summarize_invocations
  • decide_plans
  • administrative_operations

Static operator API-key credentials remain unrestricted. Runtime OAuth tokens follow a different path: an email-less client-credentials token must carry an agent identity that resolves to a stored Atryum agent, and the caller is bound only to that agent's CUID. A runtime token with an email must also resolve to a provisioned user assigned to that agent.

Without an access resolver, Atryum continues to use its existing authentication and authorization behavior.

Scoped resources and decisions

Scoped operators can:

  • list and inspect invocations and plans owned by assigned agents
  • approve or deny assigned invocations
  • summarize assigned invocations using the administrator-configured model
  • approve, deny, or request revisions to assigned plans
  • read assigned agents and update permitted agent fields
  • read global rules and agent-scoped rules that overlap their assignments

Administrative operations remain restricted. In particular, scoped users cannot create approval rules while deciding an invocation or override the configured summary model.

Invocation summarization

The PR adds GET /api/v1/invocation-summary/config, an authenticated endpoint that returns only whether invocation summarization is available. This lets the invocation UI enable summarization for assigned users without reading or exposing administrative settings.

Summary availability and execution now treat the configured providers independently. A configured local summarizer works without a ValidMind backend client.

Agent ownership

Invocations, plans, and external sessions now persist agent_cuid alongside the runtime agent_id.

The stable CUID is used to:

  • restrict resources to assigned agents
  • match plans across multiple runtime agent IDs
  • scope idempotency keys per agent
  • retain ownership when runtime aliases change

Migration 030 adds the ownership columns and supporting indexes, and backfills agent_cuid on existing rows from the agents table. Any lookup that keys off the stable CUID (plan-pass matching, idempotency-key scoping) falls back to the agent_id/alias lookup whenever the CUID lookup finds nothing, so a row with no resolved CUID never loses ownership.

Verification

  • go test ./...
  • go vet ./...
  • git diff --check

Compatibility

  • one authenticated route is added: GET /api/v1/invocation-summary/config
  • agent_cuid is an additive field on invocation and plan API representations
  • operator and runtime authorization behavior changes only when an access resolver is configured
  • static operator API-key credentials remain unrestricted
  • runtime client-credentials tokens remain agent-scoped and are not treated as unrestricted users
  • idempotency keys are unique per stable agent CUID; legacy unowned rows retain uniqueness among other unowned rows
  • migration 030 backfills agent_cuid on existing rows and falls back to the agent_id/alias lookup for any row where it's still unset, so in-flight invocations, approved plans, and idempotency retries survive the cutover

@mdeyell-valid-mind
mdeyell-valid-mind marked this pull request as ready for review July 28, 2026 22:08
kam-validmind and others added 3 commits August 11, 2026 10:45
…hing

matchApprovedPlan switched to matching approved plans by the agent's
stable VMCUID, but migration 030 added agent_cuid as a bare nullable
column with no backfill. Any plan approved before this shipped has
agent_cuid = NULL, so the CUID-only lookup found nothing and silently
dropped an otherwise-valid, human-approved pass.

Backfill agent_cuid for existing invocations/plans/external_sessions
in the migration, and fall back to the legacy agent_id/alias lookup
when the CUID lookup comes up empty, mirroring SubmitPlan's existing
revision_of fallback.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
@kam-validmind
kam-validmind requested review from kam-validmind and klall and removed request for even-steven and klall August 14, 2026 11:23
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.

3 participants