53 lines
2 KiB
Markdown
53 lines
2 KiB
Markdown
### Action Approval Data Model
|
|
|
|
Actions are JSON files stored in `/opt/homelab/actions/{status}/{action_id}.json`.
|
|
|
|
#### Statuses
|
|
- `pending`: Waiting for operator approval. AI agents create actions in this state.
|
|
- `approved`: Approved by operator, ready for execution.
|
|
- `rejected`: Rejected by operator, will not be executed.
|
|
- `running`: Currently being executed by an agent (e.g. `materializer`).
|
|
- `completed`: Successfully executed.
|
|
- `failed`: Execution failed.
|
|
|
|
#### Human-in-the-Loop (HIL) Protocol
|
|
1. **Request**: Agent identifies a required change and writes a JSON to `actions/pending/`.
|
|
2. **Notification**: System notifies the human operator.
|
|
3. **Audit**: Human reviews `details.reason` and `details.diff`.
|
|
4. **Authorization**: Human moves file to `approved/`.
|
|
5. **Execution**: Agent monitors `approved/` and executes the task.
|
|
|
|
#### Schema
|
|
```json
|
|
{
|
|
"action_id": "string",
|
|
"service": "string",
|
|
"node": "string",
|
|
"type": "deploy_service | restart_service | rollback | scale",
|
|
"risk": "nominal | guarded | critical",
|
|
"status": "pending | approved | rejected | ...",
|
|
"created_at": <unix_seconds>,
|
|
"updated_at": <unix_seconds>,
|
|
"details": {
|
|
"image": "string",
|
|
"reason": "string",
|
|
"diff": "string"
|
|
},
|
|
"transition_history": [
|
|
{
|
|
"from": "string | null",
|
|
"to": "string",
|
|
"timestamp": <unix_seconds>,
|
|
"by": "string (system | operator-tg-12345 | webui)"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
#### Workflow
|
|
1. A system component (e.g. `runtime-materializer` or a future analyzer) creates a file in `actions/pending/`.
|
|
2. `telegram-bot` detects the file, sends a message to allowed users.
|
|
3. Operator clicks "Approve" or "Reject".
|
|
4. `telegram-bot` moves the file to `actions/approved/` or `actions/rejected/` atomically, appending a transition to `transition_history`.
|
|
5. The responsible agent (e.g. `stability-agent` on the target node) picks up the `approved` action, moves it to `running`, executes it, and finally moves it to `completed` or `failed`.
|