Commit 78f44f2
authored
feat(actor): v0.6.20 — per-user Actor threading + scoped config resolution (#286)
* feat(actor): thread per-user Actor through kernel + re-key compiled-config cache
Repin all v0.1.24 animus-protocol git deps to v0.1.25 and add the new
zero-dep `animus-actor` crate. v0.1.25 additively adds `actor: Option<Actor>`
to config/control/runner/session request types. control-protocol (v0.1.13 ->
v0.1.25), workflow-runner-protocol (v0.5.3 -> v0.1.25) and subject-protocol-wire
move with it (wire must share control's subject-protocol rev); queue +
subject-protocol-v05 stay on the matched v0.5.10 pair.
WU-C: thread `actor: Option<&Actor>` through resolve_plugin_base ->
load_via_resident -> config_load_call (serialized into config/load params) and
load_workflow_config[_with_metadata]. Re-key the compiled-config cache by
(project_root, ActorCacheKey) and fold the actor key into compile_token so one
user's compiled config can never be served to another; invalidate_compiled
clears every actor partition for a root. ActorCacheKey uses unambiguous JSON
(no delimiter-collision between distinct identities).
WU-D: relay actor through the control surface (struct passthrough) and populate
the runner WorkflowExecuteRequest.actor in execute.rs. The daemon control path
spawns a detached runner child that rebuilds its request from the persisted
record, so the authenticated actor is relayed to that child via a trusted
daemon->child env handoff (WORKFLOW_ACTOR_ENV) carried in the runner overrides.
TRUST BOUNDARY: the actor is set ONLY from the authenticated control request;
never synthesized from local CLI context, workflow YAML, agent output, or
subject content.
Tests: per-actor cache isolation (no cross-leak), actor=None == global,
invalidate clears all partitions, claim-order independence, delimiter-collision
resistance, and the detached-runner actor env round-trip.
* feat(actor): scope workflow bootstrap + lifecycle to the actor; relay actor to the MCP sidecar
TASK 1 (resolve the deferred bootstrap P2): thread the transport-asserted
Actor through the workflow run/bootstrap + the phase-plan / config / retry
resolution it calls, so a user's PRIVATE workflow (visible only in that actor's
config_source partition) resolves at run-time, not from the global view.
- `WorkflowServiceApi::run(input, actor: Option<&Actor>)`: actor-scoped
default-workflow-ref / phase-plan / skip-guard / retry resolution. actor=None
== today's global behavior. Both FileServiceHub + InMemory impls + all callers
updated (system/local/test callers pass None; the control-routed detached
start passes the run's actor via DetachedRunnerOverrides).
- Added actor-aware variants (old fns delegate to None): `resolve_phase_plan_
for_workflow_ref_for_actor`, `load_workflow_config_or_default_for_actor`,
`load_agent_runtime_config_*_for_actor`.
- Persist the actor on the run so EVERY later lifecycle transition (resume /
pause / cancel / complete / fail / mark_* / resolve_merge_conflict) re-resolves
from the same partition — otherwise a private workflow starts then fails at the
next transition. Stored in a kernel-owned `workflows.actor` SQLite column (NOT
the protocol record); `save()` switched from INSERT OR REPLACE to an ON CONFLICT
upsert so the column survives every later save. Test seam gains per-(root,actor)
base injection.
TASK 2 (WU-G): relay the actor to the per-agent `animus mcp serve` sidecar so an
agent's MCP tool calls can scope to the user (per-user integrations / subject /
queue). The built-in MCP server is spawned PER AGENT SESSION (runtime_contract
mcp.stdio.command), so the actor reaches it per-agent-spawn:
- `inject_default_stdio_mcp_for_agent(.., actor)` appends `--actor-json` to the
default serve args (in-tree ad-hoc callers pass None; the out-of-tree runner
passes WorkflowPhaseRunRequest.actor).
- `animus mcp serve --actor-json` parses the Actor and pins it on AoMcpServer
(`pinned_actor`), exposed via `pinned_actor()`; `run_tool` (the single tool
choke point) emits per-user audit. Full per-tool ENFORCEMENT (scoping the
underlying subject/queue/integration RPCs) is the consumer-side change tracked
separately.
TRUST BOUNDARY: the actor is sourced ONLY from the authenticated run/control
request, never from workflow YAML, agent output, or subject content.
Tests: actor-private workflow resolves for its actor and NOT for None/another
actor; run() persists the actor and it survives a lifecycle save; --actor-json
clap parse; inject appends/omits --actor-json; actor round-trips through the
serve arg.
* chore(release): v0.6.20 — per-user actor threading + scoped config resolution1 parent 1d2c225 commit 78f44f2
50 files changed
Lines changed: 1132 additions & 302 deletions
File tree
- crates
- animus-mcp-oauth/src
- animus-plugin-runtime/src
- orchestrator-cli
- src
- cli_types
- services
- cost
- operations
- ops_mcp
- ops_workflow
- runtime
- runtime_agent
- runtime_chat
- runtime_daemon
- tests
- orchestrator-config
- src
- workflow_config
- orchestrator-core
- src
- services
- workflow
- orchestrator-daemon-runtime
- orchestrator-plugin-host
- src/session
- tests
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
30 | | - | |
| 30 | + | |
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
40 | 41 | | |
41 | 42 | | |
42 | 43 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
107 | 107 | | |
108 | 108 | | |
109 | 109 | | |
110 | | - | |
| 110 | + | |
111 | 111 | | |
112 | 112 | | |
113 | 113 | | |
| |||
0 commit comments