Skip to content

feat(cli): bootstrap agents with scoped setup flow#79

Open
madtank wants to merge 2 commits intomainfrom
orion/bootstrap-agent
Open

feat(cli): bootstrap agents with scoped setup flow#79
madtank wants to merge 2 commits intomainfrom
orion/bootstrap-agent

Conversation

@madtank
Copy link
Copy Markdown
Member

@madtank madtank commented Apr 19, 2026

Summary

  • add axctl bootstrap-agent for one-shot scoped agent setup
  • propagate auth/5xx failures during agent existence checks instead of masking them
  • cover the bootstrap flow with focused tests

Validation

  • pytest tests/test_bootstrap_agent.py -q

cc @orion for review.

anvil and others added 2 commits April 18, 2026 01:01
Collapses the 15-step manual sequence documented in
shared/state/axctl-friction-2026-04-17.md §0 into a single command:

    axctl bootstrap-agent axolotl \
      --space-id <uuid> \
      --description "..." \
      --model codex:gpt-5.4 \
      --audience both \
      --save-to /home/ax-agent/agents/axolotl \
      --profile next-axolotl

What it does, in order:

1. Requires a user PAT (axp_u_). Agent PATs are refused with an
   actionable message — they can't create agents or mint credentials.
2. Prints the effective-config line (base_url + user_env + source path)
   so operators don't silently target the wrong environment.
3. POST /api/v1/agents with X-Space-Id — the proven-prod creation path.
4. If the agent already exists in the target space and --allow-existing
   is set, reuses it; otherwise exits 2 with a clear error.
5. Optional metadata polish via PUT /api/v1/agents/manage/{name}.
6. Mints an agent-bound PAT. Tries /credentials/agent-pat first
   (canonical per the ax-operator skill); on HTML/404/405 falls back
   to POST /api/v1/keys with bound_agent_id + allowed_agent_ids +
   audience + prod-compatible scopes (api:read, api:write). The
   fallback exists because /credentials/* isn't routed to the backend
   on prod today.
7. Writes workspace: {save_to}/.ax/config.toml and .ax/token at 0600.
8. Optional named profile compatible with `axctl profile verify`.
9. Verifies with GET /auth/me + the fresh PAT and prints resolved
   allowed_spaces so the caller sees containment (agent-lock + space-lock).

client.py: extended create_key() with bound_agent_id, audience, scopes,
and space_id parameters. Backward-compatible (all kwargs default None).

Tests: 9 new covering happy-path with mgmt route, HTML-fallback,
404-fallback, already-exists abort, already-exists reuse, user-PAT-required
gate, agent-PAT rejection, --dry-run (zero side effects), and the
effective-config line. 230 existing tests still pass.

Tracked friction items closed: §0 (one-shot), §2 (effective-config line
on mutating commands), §3 (CLI-side fallback when /credentials/* isn't
routed), §4 (prod scope vocabulary hidden behind the command).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…review fix)

Addresses axolotl's PR #67 review finding. The prior implementation
caught all httpx.HTTPStatusError and returned None, which silently
treated 401/403/5xx as "agent not found" and proceeded to creation.
Axolotl reproduced with a fake 401: the helper returned None.

Fix:
- Narrow the exception handling in _find_agent_in_space: only a 404
  is treated as "not found" (space gone / non-member → downstream POST
  gives a cleaner error). Everything else (401, 403, 5xx, network
  errors) propagates so users see the real failure instead of a
  confusing duplicate-create downstream.

Regression tests added (parametrized):
- test_bootstrap_does_not_swallow_existence_check_errors[401/403/500/503]
  asserts the command exits non-zero AND never reaches POST /api/v1/agents
  or any PAT-mint path when the existence check returns an auth/server
  error.
- test_bootstrap_handles_404_on_existence_as_not_found asserts a 404
  is still treated as "agent absent, continue" — the one benign case.

All 14 bootstrap tests + 235 suite total pass. Ruff clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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