Skip to content

Commit 460cf35

Browse files
author
Matthias Zimmermann
committed
feat: add AGENTS.md
1 parent db4b9a2 commit 460cf35

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed

AGENTS.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Agent Instructions
2+
3+
Instructions for AI coding agents working on this repository.
4+
5+
## Project Overview
6+
7+
**Arkiv SDK** is the official Python library for interacting with Arkiv networks—a permissioned storage system for decentralized apps supporting flexible entities with binary data, attributes, and metadata.
8+
9+
The SDK is built on top of [Web3.py](https://github.com/ethereum/web3.py) and should feel like "web3.py + entities".
10+
11+
## Architecture
12+
13+
### Clients
14+
15+
| Client | Base Class | Provider | HTTP Stack |
16+
|--------|------------|----------|------------|
17+
| `Arkiv` (sync) | `Web3` | `HTTPProvider` | `requests` |
18+
| `AsyncArkiv` (async) | `AsyncWeb3` | `AsyncHTTPProvider` | `aiohttp` |
19+
20+
- Entity operations live under `client.arkiv.*`, following Web3's module pattern (`eth`, `net`, etc.)
21+
- Always use `async with AsyncArkiv(...)` for proper session cleanup
22+
- `AsyncArkiv` must call `_disconnect_provider()` on `__aenter__` failure to avoid aiohttp session leaks
23+
24+
### Key Modules
25+
26+
| Module | Purpose |
27+
|--------|---------|
28+
| `arkiv.client` | `Arkiv` and `AsyncArkiv` clients |
29+
| `arkiv.provider` | `ProviderBuilder` for HTTP/WS providers |
30+
| `arkiv.account` | `NamedAccount` for wallet/key management |
31+
| `arkiv.node` | `ArkivNode` for local containerized nodes |
32+
| `arkiv.module` / `arkiv.module_async` | Entity CRUD, queries, event watching |
33+
34+
### ProviderBuilder
35+
36+
Fluent API for constructing providers:
37+
38+
```python
39+
ProviderBuilder().kaolin().build() # Kaolin testnet HTTP
40+
ProviderBuilder().localhost(8545).ws().build() # Local WebSocket
41+
ProviderBuilder().custom(url).timeout(5).async_mode().build() # Custom async with timeout
42+
```
43+
44+
## Coding Conventions
45+
46+
### Test Naming
47+
48+
- Sync tests: `test_provider_*`, `test_create_entity_*`, etc.
49+
- Async tests: `test_async_provider_*`, `test_async_create_entity_*`, etc.
50+
51+
### Test Patterns
52+
53+
- Use `delayed_rpc_server` fixture for deterministic timeout tests
54+
- Use invalid hostnames like `https://nonexistent.rpc-node.local` for DNS failure tests
55+
- Sync timeout: expect `requests.exceptions.ReadTimeout`
56+
- Async timeout: expect `asyncio.TimeoutError` or `aiohttp.ClientError`
57+
- Sync DNS failure: expect `requests.exceptions.ConnectionError`
58+
- Async DNS failure: expect `aiohttp.ClientConnectorDNSError`
59+
60+
### Style
61+
62+
- MyPy strict mode enabled
63+
- Ruff for linting and formatting (88 char lines, double quotes, trailing commas)
64+
- Use `logging` module for debug/info output in tests and library code
65+
66+
## Quality Gates
67+
68+
Before any commit:
69+
70+
```bash
71+
./scripts/check-all.sh
72+
```
73+
74+
This runs:
75+
1. `pre-commit run --all-files` – linting, formatting, trailing whitespace
76+
2. `mypy --strict src/` – type checking
77+
3. `pytest -n auto` – all tests in parallel
78+
79+
## Workflow for Changes
80+
81+
Follow this workflow for any code changes:
82+
83+
1. **Understand first** – Ensure you understand the problem and we have a shared understanding of what needs to be done or fixed.
84+
85+
2. **Confirm before changing** – Before making changes, ensure there is a clear instruction to actually change anything. If unsure, ask.
86+
87+
3. **Follow existing patterns** – When proposing changes, make sure you understand the coding patterns and align your changes according to the existing patterns.
88+
89+
4. **Minimal changes only** – Before making a change, ensure that the change is minimal and only changes the item that was discussed.
90+
91+
5. **Run relevant tests** – Before suggesting that you have completed the change, run the relevant tests to ensure that the desired new behaviour is observed.
92+
93+
6. **Propose missing tests** – Should tests for the new feature/behaviour be missing, make a proposal for which tests you'd add.
94+
95+
7. **Full quality check** – Once local tests confirm the changes work as intended, run `./scripts/check-all.sh` to verify the new code base does not break old tests and conforms to the coding standards.
96+
97+
## Known Issues
98+
99+
- `AsyncArkiv` must disconnect provider on `__aenter__` failure to avoid unclosed `aiohttp.ClientSession` warnings
100+
- WebSocket providers are always async; sync `Arkiv` client rejects them with a clear error message
101+
102+
## Dependencies
103+
104+
- **uv** – Package and version management
105+
- **pytest** + **pytest-asyncio** – Testing framework
106+
- **testcontainers** – Local Arkiv node containers for integration tests
107+
- **Web3.py 7.x** – Underlying Ethereum client library

0 commit comments

Comments
 (0)