Skip to content

FEAT-3: policy push from owner to agent - #35

Merged
joy-software merged 1 commit into
mainfrom
feature/policy-push
Jun 7, 2026
Merged

FEAT-3: policy push from owner to agent#35
joy-software merged 1 commit into
mainfrom
feature/policy-push

Conversation

@joy-software

Copy link
Copy Markdown
Contributor

What

Lets an owner push a new supervision policy to a dial-home agent over the existing order channel, so a policy update reaches an agent that can never be contacted inbound.

Owner (src/spero/owner.py)

  • AgentRegistry.queue_policy(agent_id, policy_yaml) appends a {"type": "policy", "policy": ...} order to the agent's queue.
  • POST /agents/{agent_id}/policy (async, token-guarded) accepts {"policy": "<yaml>"}, validates it with load_policy_str, returns 422 on invalid YAML or policy, and on success queues the order and returns {"queued": "policy"}.

Agent (src/spero/agent.py)

  • latest_policy_order(orders) returns the YAML of the last policy order, so an agent that pulls several at once converges on the newest.
  • swap_supervisor(sup, policy_yaml, approver) validates the YAML, stops the old Supervisor, and starts a new one on the same RemoteApprover so approvals keep flowing. An invalid push is logged and skipped, leaving the current supervisor running, so a bad push can never take the agent down.
  • The report loop applies approve orders as before, then hot-swaps on a policy order.

Tests

  • Owner: policy push queues and delivers the order, then clears it; invalid policy and unparseable YAML both return 422 and queue nothing.
  • Agent: latest_policy_order picks the last push; swap_supervisor swaps to the new policy while preserving the approver state; an invalid push leaves the old supervisor running.

Gates

ruff check, ruff format --check, mypy, pytest all green. 234 passed.

Add a policy-push path that rides the existing dial-home order queue, so an
owner can update an agent's supervision policy without reaching inbound.

Owner:
- AgentRegistry.queue_policy(agent_id, policy_yaml) appends a
  {"type": "policy", "policy": ...} order.
- POST /agents/{agent_id}/policy validates the YAML with load_policy_str and
  returns 422 on invalid input, queues the order on success.

Agent:
- latest_policy_order picks the newest policy order when several arrive at once.
- swap_supervisor validates, stops the old Supervisor, and starts a new one on
  the same RemoteApprover so approvals keep flowing. An invalid push is logged
  and skipped, leaving the current supervisor running so the loop never crashes.
- The report loop applies approve orders as before, then hot-swaps on a policy
  order.
@joy-software
joy-software merged commit a450bd5 into main Jun 7, 2026
8 checks passed
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