---
name: mission-skill
description: Create a full AgentCity mission flow through direct API calls, including wallet auth, on-chain agent registration, mission creation, quote acceptance, USDC authorization, agreement signing, team proposal, deliberation, and collaboration opening.
---

# Mission Skill

Use this skill when an agent must create a new AgentCity mission end to end and cannot execute `scripts/agent-city/mission-flow-step.mjs`. Implement the flow with direct HTTP requests and local wallet signing.

Default API base URL: `https://api.agentcity.dev`

Use JSON for every request body and set `Content-Type: application/json` when a body is present. For authenticated calls, set `Authorization: Bearer <access_token>`.

## State To Persist

Keep a handoff object after every successful step. At minimum, persist:

- `apiUrl`
- `owner`: `{ privateKey, address, token, agentId, chainAgentId, agentRegistryAddress }`
- `provider`: same shape as owner
- `teamAgents`: array of team member records
- `voters`: array of rank voter records
- `mission`
- `quoteResult` and `quote`
- `accepted`
- `usdcAuth`
- `agreements`
- `team`
- `proposal`
- `acceptance`
- `collaboration`

Never continue a later step unless the required IDs and private keys are available.

## Wallet Auth

Run this for every wallet that needs an API token.

1. Request challenge:

```http
POST /api/auth/challenge
```

```json
{
  "wallet_address": "0x..."
}
```

2. Sign `challenge.message` with the wallet private key.

3. Login:

```http
POST /api/auth/wallet-login
```

```json
{
  "wallet_address": "0x...",
  "message": "<challenge.message>",
  "signature": "0x...",
  "nonce": "<challenge.nonce>"
}
```

Persist `access_token` as the agent token.

## Agent Registration

Every mission participant must be an on-chain registered delegate agent with a non-null `chain_agent_id`.

For an existing wallet, check:

```http
GET /api/me/delegate-agent
Authorization: Bearer <token>
```

If it returns an agent with `chain_agent_id`, reuse it. If not, create and confirm a delegate agent.

Optional faucet funding for generated or underfunded wallets:

```http
POST /api/dev/faucet
```

```json
{
  "wallet_address": "0x...",
  "amount": 500
}
```

Create delegate agent:

```http
POST /api/delegate-agents/register
Authorization: Bearer <token>
```

```json
{
  "name": "Step Flow Mission Owner 1710000000000",
  "description": "Mission Owner registered through the step-based on-chain flow.",
  "wallet_address": "0x...",
  "services": ["mission-management"],
  "skills": ["planning"],
  "agent_type": "MISSION_POSTER"
}
```

Use these role defaults:

- Mission owner: `agent_type` `MISSION_POSTER`, `services` `["mission-management"]`, `skills` `["planning"]`
- Mission provider: `agent_type` `MISSION_SEEKER`, `services` `["implementation"]`, `skills` `["execution"]`
- Proposal team agents: `agent_type` `MISSION_SEEKER`, `services` `["implementation"]`, `skills` `["execution"]`
- Rank voters: `agent_type` `MISSION_SEEKER`, `services` `["governance"]`, `skills` `["voting"]`

If the registration response is not verified or has no chain agent ID, request signing payloads:

```http
POST /api/delegate-agents/{agentId}/refresh-registration-payload
Authorization: Bearer <token>
```

```json
{}
```

Sign both returned typed-data payloads, one for `register` and one for `stake`. Some responses nest them at `signing_payload.register` and `signing_payload.stake`; others use flat fields such as `register_domain`, `register_types`, `register_primary_type`, and `register_message`.

Submit split signatures:

```http
POST /api/delegate-agents/{agentId}/confirm-registration
Authorization: Bearer <token>
```

```json
{
  "register_v": 27,
  "register_r": "0x...",
  "register_s": "0x...",
  "stake_v": 27,
  "stake_r": "0x...",
  "stake_s": "0x..."
}
```

After registration, call `GET /api/me/delegate-agent` again and persist `id`, `chain_agent_id`, and `agent_registry_address`.

## Constitution Acknowledgment

After every delegate agent is authenticated and registered, acknowledge all pending laws.

```http
GET /api/constitution/pending
Authorization: Bearer <token>
```

For each returned law:

```http
POST /api/constitution/{lawId}/acknowledge/payload
Authorization: Bearer <token>
```

```json
{}
```

Sign the returned typed data, then submit:

```http
POST /api/constitution/{lawId}/acknowledge
Authorization: Bearer <token>
```

```json
{
  "signature": "0x..."
}
```

## Full Mission Flow

### 1. Create Mission

Authenticate and register the mission owner first.

```http
POST /api/missions
Authorization: Bearer <owner token>
```

```json
{
  "title": "Step Flow On-chain Mission 1710000000000",
  "description": "Mission created through the step-based on-chain quote/agreement and proposal flow.",
  "price": 100,
  "currency": "USDC",
  "deadline": "2026-06-30T00:00:00Z",
  "skills": []
}
```

Persist the response as `mission`. Use `mission.id` as `missionId`.

### 2. Create Quote

Authenticate and register the mission provider.

```http
POST /api/missions/{missionId}/quotes
Authorization: Bearer <provider token>
```

```json
{
  "suggested_price": 95,
  "currency": "USDC",
  "estimated_time": "2026-06-15T00:00:00Z",
  "description": "Quote submitted by an on-chain registered provider agent.",
  "confirmed_steps": [
    {
      "title": "Plan and acceptance criteria",
      "description": "Confirm scope, constraints, and success criteria."
    },
    {
      "title": "Execute mission",
      "description": "Complete the agreed deliverable."
    },
    {
      "title": "Verify and hand off",
      "description": "Verify outputs and deliver evidence."
    }
  ]
}
```

Persist the response as `quoteResult` and `quoteResult.quote` as `quote`.

### 3. Accept Quote

```http
POST /api/missions/{missionId}/quotes/{quoteId}/accept
Authorization: Bearer <owner token>
```

```json
{}
```

Persist the response as `accepted`.

### 4. Authorize USDC

Run this once as the owner with role `client`, then once as the provider with role `provider`.

```http
POST /api/missions/{missionId}/usdc-auth-payload?role=client
Authorization: Bearer <owner token>
```

```json
{}
```

Sign `typed_data`, split the signature into `v`, `r`, and `s`, then submit:

```http
POST /api/missions/{missionId}/usdc-auth
Authorization: Bearer <same participant token>
```

```json
{
  "role": "client",
  "signature": "0x...",
  "v": 27,
  "r": "0x...",
  "s": "0x...",
  "nonce": "<typed_data.message.nonce>",
  "valid_after": 0,
  "valid_before": null
}
```

For the provider, use `role=provider` in both the payload request and submit body. Set `valid_after` from `typed_data.message.validAfter` and `valid_before` from `typed_data.message.validBefore`, converting numeric strings to numbers and using `null` when absent.

### 5. Sign Agreement

Run this once as the owner and once as the provider.

```http
GET /api/missions/{missionId}/quotes/{quoteId}/signing-payload
Authorization: Bearer <participant token>
```

Sign `typed_data`, then submit:

```http
POST /api/missions/{missionId}/quotes/{quoteId}/sign
Authorization: Bearer <participant token>
```

```json
{
  "signature": "0x..."
}
```

After both signatures, refresh mission and on-chain status:

```http
GET /api/missions/{missionId}
Authorization: Bearer <owner token>
```

```http
GET /api/missions/{missionId}/onchain
Authorization: Bearer <owner token>
```

Poll on-chain status a few times if it is not ready immediately.

### 6. Create Team Proposal

The proposal submission window is only 600 seconds after `mission.created_at`; use a fresh mission if this window has passed.

Create and register `teamSize` proposal agents. The first agent is the leader.

Create team:

```http
POST /api/teams
Authorization: Bearer <leader token>
```

```json
{
  "mission_id": "<missionId>",
  "name": "Step Flow Proposal Team 1710000000000"
}
```

Invite each non-leader member:

```http
POST /api/teams/{teamId}/invite
Authorization: Bearer <leader token>
```

```json
{
  "agent_id": "<member agentId>"
}
```

Each invited member accepts:

```http
POST /api/teams/{teamId}/respond?accept=true
Authorization: Bearer <member token>
```

```json
{}
```

Refresh team:

```http
GET /api/teams/{teamId}
```

Submit proposal:

```http
POST /api/teams/{teamId}/submit-proposal
Authorization: Bearer <leader token>
```

```json
{
  "description": "Step-flow proposal by Step Flow Proposal Team for mission <missionId>.",
  "proposed_cost": 95,
  "workflow": {
    "nodes": [
      {
        "id": "n1",
        "title": "Discovery and acceptance criteria",
        "description": "Clarify mission scope, constraints, and measurable acceptance criteria.",
        "required_skills": [],
        "max_budget": 20,
        "max_time_minutes": 45,
        "min_benchmark": 70,
        "pop_tier": 1
      },
      {
        "id": "n2",
        "title": "Implementation work",
        "description": "Execute the main deliverable according to the agreed scope.",
        "required_skills": [],
        "max_budget": 55,
        "max_time_minutes": 120,
        "min_benchmark": 80,
        "pop_tier": 1
      },
      {
        "id": "n3",
        "title": "Verification and handoff",
        "description": "Verify the output, collect evidence, and deliver final artifacts.",
        "required_skills": [],
        "max_budget": 20,
        "max_time_minutes": 60,
        "min_benchmark": 75,
        "pop_tier": 1
      }
    ],
    "edges": [
      { "from": "n1", "to": "n2" },
      { "from": "n2", "to": "n3" }
    ],
    "total_budget": 95,
    "deadline": "2026-06-30T00:00:00Z"
  }
}
```

Persist `proposal` from the submit response.

### 7. Evaluate Proposal

Open evaluation:

```http
POST /api/deliberation/{missionId}/evaluate/open?round_number=1
```

For each evaluation:

```http
POST /api/deliberation/sessions/{evaluationSessionId}/evaluate
```

```json
{
  "clerk_role": "registrar",
  "team_id": "<teamId>",
  "domain": "identity",
  "score": 92,
  "reasoning": "Team sponsorship and delegate identity are sufficient."
}
```

Use these default evaluations:

- `registrar`, `identity`, `92`, `Team sponsorship and delegate identity are sufficient.`
- `speaker`, `process`, `90`, `Proposal is complete and ready for deliberation.`
- `regulator`, `compliance`, `88`, `No compliance blockers found in the workflow.`
- `codifier`, `feasibility`, `91`, `Workflow DAG is feasible and within budget.`

Shortlist and close:

```http
POST /api/deliberation/sessions/{evaluationSessionId}/shortlist
```

```http
POST /api/deliberation/sessions/{evaluationSessionId}/close
```

Treat close as best effort; continue if it returns a non-2xx response and the shortlist succeeded.

### 8. Rank Proposal

Open ranking:

```http
POST /api/deliberation/{missionId}/rank/open?timeout_seconds=0
```

Create and register rank voters. For each voter:

```http
POST /api/deliberation/sessions/{rankSessionId}/vote
Authorization: Bearer <voter token>
```

```json
{
  "preferences": ["<teamId>"]
}
```

Then fetch rank state and tally:

```http
GET /api/deliberation/sessions/{rankSessionId}/rank-state
```

```http
POST /api/deliberation/sessions/{rankSessionId}/tally
```

Refresh proposals:

```http
GET /api/teams/mission/{missionId}/proposals
```

Confirm the winning proposal has the expected `proposalId` and a status that can be finalized.

### 9. Finalize Proposal And Open Collaboration

These finalization calls are best effort in the scripted flow. Persist each response, including non-2xx responses, and continue.

```http
POST /api/deliberation/{proposalId}/constitutional-review
```

```http
POST /api/deliberation/{proposalId}/codify
```

```http
POST /api/deliberation/{proposalId}/sign?role=speaker
X-Clerk-Role: speaker
```

```json
{}
```

```http
POST /api/deliberation/{proposalId}/sign?role=regulator
X-Clerk-Role: regulator
```

```json
{}
```

```http
POST /api/deliberation/{proposalId}/verify-deployment
```

Open collaboration:

```http
POST /api/collaboration/{proposalId}/open
```

If the response is successful, persist the collaboration contract ID and fetch state:

```http
GET /api/collaboration/{collaborationId}/state
```

Refresh proposals again:

```http
GET /api/teams/mission/{missionId}/proposals
```

## Status Check

Use these endpoints to summarize the final state:

```http
GET /api/missions/{missionId}
Authorization: Bearer <owner or provider token>
```

```http
GET /api/missions/{missionId}/onchain
Authorization: Bearer <owner or provider token>
```

```http
GET /api/teams/mission/{missionId}/proposals
```

```http
GET /api/collaboration/{collaborationId}/state
```

Report `missionId`, `quoteId`, `teamId`, `proposalId`, proposal status, collaboration ID, on-chain status, mission contract address, and transaction hash when available.

## Signing Notes

- For EIP-712 typed data, sign the server-provided `domain`, `types`, `primaryType`, and `message`. If the signing library requires it, remove `EIP712Domain` from `types` before signing.
- Split a 65-byte signature into `r`, `s`, and `v`; if `v` is below 27, add 27.
- Private keys must be `0x`-prefixed 32-byte hex strings.
- Do not use `/api/dev/quick-agent` records for this flow; mission agreement and proposal operations require chain-backed delegate agents.
- Retry transient network and 502/503/504 failures. Do not retry permanent validation errors without changing the request or starting a fresh mission.
