Files
tines/AGENTS.md
T
kyleandClaude Opus 5.5 203550bfc4
CI / ci (push) Canceled after 0s
docs: expand README with diagrams; bring AGENTS.md up to date
README: protocol, fragmentation, poll and addressed-delivery diagrams;
observation fields and identity; transport, belief and trim guidance;
simulator example; constants table.

AGENTS.md: drop the completed plan's task-by-task workflow and Task 14
notes, point at both specs, use scripts/ci.sh as the gate, and update
the identity-hash constraint to include `to`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 05:14:56 -07:00

106 lines
4.7 KiB
Markdown

# AGENTS.md — tines
Instructions for AI agents working on **tines**: opportunistic shared memory
for mostly-offline robots. Read this before touching code.
## What tines is
Small robots collect facts about the world while mostly offline. When two of
them happen to meet in range, they swap what they know so each one's picture of
the world improves. No robot depends on receiving anything, but there is no
reason not to share.
`tines` is the library that does this: a store of timestamped-by-age
observations, a belief layer derived from them, and a delay-tolerant exchange
protocol over any datagram link. Read the full intent, goals, anti-goals, and
architecture in the **spec first**:
- **Core design (authoritative):** `docs/superpowers/specs/2026-10-16-tines-design.md`
- **Addressed delivery (authoritative):** `docs/superpowers/specs/2026-10-18-tines-addressed-delivery.md`
- **Implementation plans:** `docs/superpowers/plans/`
The plans argue from the specs. Where a plan is silent, the **spec rules**.
Do not edit the specs or the plans — they are design history, not source.
`README.md` is the user-facing overview and should track the code.
## Architecture (three layers)
```
memory — "my priors": beliefs per topic, derived from storage under a policy
storage — append-only log of raw observations; local trimming policy
comms — contact-driven exchange of observations; transport trait + adapters
```
Only observations cross the wire. Memory is a pure function of storage plus a
policy and is never transmitted. See the spec's "Architecture" section for the
`Observation`, `Store`, `BeliefPolicy`, `Transport`, and exchange protocol
details.
## Workflow
Changes are TDD: write the failing test → see it fail → implement → see it
pass → commit.
1. Keep the public API small. New public names in `tines-core` (types, trait
methods, functions) need a reason; call them out when you add them.
2. Before committing, run the full gate, which is what CI runs:
`sh scripts/ci.sh` (fmt, clippy and rustdoc with warnings as errors, tests
with and without `alloc`, and the `thumbv7em-none-eabihf` build).
3. Use conventional commit messages (`fix(core): …`, `ci: …`, `docs: …`).
The `Node` facade is core, not application glue: an application on any target
should only need to construct a `Node` with its `NodeId`, store, and transport,
call `poll()` in its loop, and `observe()` when it sees something.
## Hard constraints (non-negotiable in `tines-core`)
- `tines-core` is `#![no_std]`; `alloc` is a cargo feature (default on). With
`--no-default-features` it must build for `thumbv7em-none-eabihf`. Only
`MemStore` may require `alloc`.
- No async, no threads, no I/O, and no panic on untrusted input in core. Every
frame from the wire is untrusted: malformed bytes are dropped, never
unwrapped.
- Core never maps a transport `Addr` to a `NodeId`; every frame carries the
sender's `NodeId`.
- Identity hash covers `(observer, seq, topic, payload, to)` **only**.
`age_ms`, `observed_at` and `lifetime_ms` are excluded.
- Addressed observations (`to = Some`) never appear in a summary Bloom
filter, and an addressed observation past its `lifetime_ms` is never
stored or forwarded.
- `Node::next_seq()` must be persisted by the application across reboots
(`boot_count << 32 | counter`); a repeated seq after reboot collides in the
ID hash and must dedupe silently (`insert` returns `Ok(false)`).
- `NodeId = [u8; 16]`, `ObservationId = [u8; 16]`, `Tick = u64` (local
monotonic ms, supplied on every call).
### Review Focus (each covered by a test; keep it that way)
1. Reused `seq` after reboot → store dedupes, `insert` returns `Ok(false)`.
2. Oversized `topic`/`payload` at `observe()` → `Err(TooLarge)`, never truncate/panic.
3. Garbage frames → dropped, no panic, no store change.
4. Frame from an address with no prior `Contact` → treated as implicit contact.
5. Tick going backwards → age saturates at stored value, never underflow.
6. Every emitted frame fits the transport's `mtu()`, including summaries.
### Compile-time constants (`tines-core/src/consts.rs`)
`MAX_TOPIC=64`, `MAX_PAYLOAD=1024`, `MAX_PEERS=8`, `SUMMARY_BYTES=512`,
`BLOOM_K=3`, `SUMMARY_INTERVAL_MS=2000`, `REASSEMBLY_TIMEOUT_MS=5000`,
`SEND_QUEUE_CAP=256`, `MAX_FRAME=1500`. Match the exact values above.
## Crate layout
```
tines/
tines-core/ no_std core: Observation, Store/Transport/BeliefPolicy traits,
exchange state machine, Node facade, in-memory store, reference
policies
tines-sim/ std: simulator, contact traces, convergence and relay
property tests
```
## Not started
`tines-udp`, `tines-sqlite`, `tines-cli`, and `tines-serial` (from the core
spec's crate layout) belong to a future plan. Don't start them unless asked.