131 lines
3.6 KiB
Markdown
131 lines
3.6 KiB
Markdown
# Inbox Shared Test Conventions
|
|
|
|
## Purpose
|
|
|
|
This document captures shared assumptions used by multiple `inbox` test-plan documents so command and workflow files can stay focused on behavior rather than repeating setup boilerplate.
|
|
|
|
## Recommended Fixture Shape
|
|
|
|
Use an isolated temp workspace per case:
|
|
|
|
- database path: `TMPDIR/coord.db`
|
|
- optional body file: `TMPDIR/body.md`
|
|
- optional artifact file: `TMPDIR/artifact.txt`
|
|
|
|
Recommended bootstrap command:
|
|
|
|
```bash
|
|
inbox --db TMPDIR/coord.db --json init
|
|
```
|
|
|
|
## Global Flags
|
|
|
|
Root-level flags apply to every subcommand:
|
|
|
|
- `--db`: SQLite database path, default `.agents/coord.db`
|
|
- `--json`: emit machine-readable JSON
|
|
- `--agent`: acting agent identity shortcut used by commands that accept agent context
|
|
|
|
When a command-specific `--agent` or `--from` flag is omitted, the root `--agent` value may be used instead. Cases that verify fallback behavior should state that explicitly.
|
|
|
|
## Success JSON Contract
|
|
|
|
Successful JSON output uses this shape:
|
|
|
|
```json
|
|
{
|
|
"ok": true,
|
|
"command": "send",
|
|
"data": {}
|
|
}
|
|
```
|
|
|
|
Shared assertion points:
|
|
|
|
- `ok` is `true`
|
|
- `command` matches the invoked subcommand
|
|
- `data` contains the command-specific payload
|
|
|
|
## Error JSON Contract
|
|
|
|
Failure JSON output uses this shape:
|
|
|
|
```json
|
|
{
|
|
"ok": false,
|
|
"error": {
|
|
"code": "invalid_input",
|
|
"message": "..."
|
|
}
|
|
}
|
|
```
|
|
|
|
Shared assertion points:
|
|
|
|
- `ok` is `false`
|
|
- `error.code` matches the stable contract
|
|
- `error.message` is present and human-readable
|
|
|
|
## Exit Code Contract
|
|
|
|
The current CLI contract uses these exit codes:
|
|
|
|
| Exit Code | Meaning | Typical Error Code |
|
|
| --- | --- | --- |
|
|
| `0` | success | none |
|
|
| `10` | no matching work / timeout without match | `no_matching_work` |
|
|
| `20` | lease conflict | `lease_conflict` |
|
|
| `30` | invalid input, invalid state, usage-style error | `invalid_input` or `invalid_state` |
|
|
| `40` | referenced thread or message missing | `not_found` |
|
|
| `50` | unexpected internal failure | `internal_error` |
|
|
|
|
When a case expects no result, assert both the exit code and the JSON error code.
|
|
|
|
## Body Input Rules
|
|
|
|
Commands that support `--body` and `--body-file` follow these rules:
|
|
|
|
- `--body` and `--body-file` are mutually exclusive
|
|
- `--body-file` content is read verbatim into the message body
|
|
- unreadable `--body-file` should be treated as `invalid_input`
|
|
|
|
Relevant commands:
|
|
|
|
- `send`
|
|
- `update`
|
|
- `reply`
|
|
- `done`
|
|
- `fail`
|
|
|
|
## Artifact Rules
|
|
|
|
Commands with artifact support use these shared rules:
|
|
|
|
- `--artifact` may be repeated
|
|
- `--artifact-kind` may be specified once for all artifacts, or once per artifact
|
|
- `--artifact-metadata-json` may be specified once for all artifacts, or once per artifact
|
|
- `--artifact-kind` and `--artifact-metadata-json` are invalid without at least one `--artifact`
|
|
- an empty artifact path is invalid input
|
|
|
|
When artifact behavior is under test, assert at least:
|
|
|
|
- artifact count
|
|
- artifact `path`
|
|
- artifact `kind`
|
|
- metadata presence when supplied
|
|
|
|
## Read And Unread Assertions
|
|
|
|
Unread-related cases should verify behavior from the agent's point of view, not only raw message existence.
|
|
|
|
Recommended checks:
|
|
|
|
- `fetch --unread` returns a thread before read acknowledgement
|
|
- `show --mark-read` clears unread state for that agent
|
|
- a new message to the same thread makes the thread unread again
|
|
- `wait-reply` may clear blocked unread state for the waiting agent when the reply is consumed
|
|
|
|
## Workflow Authoring Rule
|
|
|
|
If a case spans multiple commands, place the end-to-end narrative in `workflows/README.md` first, then add narrower command-level cases only when they introduce behavior that is easier to reason about in isolation.
|