Skip to content

Commit 28713f5

Browse files
committed
docs: add VERIFY.md control surface and features/ map for agent-driven verification
1 parent 18a96af commit 28713f5

5 files changed

Lines changed: 236 additions & 0 deletions

File tree

‎VERIFY.md‎

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# VERIFY — fpRust
2+
3+
How an agent launches, checks, drives, and cleans up verification of this
4+
library. Read this plus the relevant `features/*.md` file before touching the
5+
code.
6+
7+
`source_commit: 18a96af` · `last_verified_at: 2026-09-23` · `verification_status: passed`
8+
9+
## Launch
10+
11+
```bash
12+
cd <repo root>
13+
cargo test
14+
```
15+
16+
Runs 120 unit tests (in-module `#[test]` blocks under `src/`) plus 24 doc
17+
tests — ~10s total. `test.sh` and `paralleltest.sh` are legacy wrappers;
18+
`cargo test` is the canonical surface. `clippy.sh` runs the linter.
19+
20+
## Doctor
21+
22+
```bash
23+
cargo test maybe::test_maybe -- --exact # smoke: ~1s (name a real test)
24+
cargo build
25+
```
26+
27+
A healthy tree: smoke test PASS, `cargo build` clean, full suite
28+
`120 passed; 0 failed` + `24 passed` doc tests.
29+
30+
## Drive
31+
32+
- Per feature: run `cargo test <module>::` (e.g. `cargo test fp::`) from the
33+
feature file's Drive section.
34+
- For behavior not covered by a test, write a scratch driver **outside** the
35+
repo: `cargo new /tmp/fprust-driver`, add to its `Cargo.toml`:
36+
37+
```toml
38+
[dependencies]
39+
fp_rust = { path = "<repo root>" }
40+
futures = "0.3"
41+
```
42+
43+
then `cargo run` — never add driver files inside the repo.
44+
45+
## Evidence
46+
47+
- Save `cargo test <module> -- --nocapture` output to files under a scratch
48+
dir (e.g. `/tmp/fprust-evidence/`).
49+
- For scratch drivers, record the driver source plus its stdout.
50+
51+
## When a check fails
52+
53+
Classify before fixing — four different failures need four different repairs:
54+
55+
| Class | Meaning | Repair |
56+
| --- | --- | --- |
57+
| Product regression | Library behavior changed for the worse | Report; do not edit the map or tests to match |
58+
| Doc drift | The map/VERIFY.md no longer matches the library | Update the doc; the product is fine |
59+
| Spec/oracle error | The acceptance spec or test expectation is wrong | Oracles are read-only; propose the change for review |
60+
| Harness failure | Toolchain, cargo, target/, or environment broke | Fix the harness; the product is fine |
61+
62+
Never "fix" a failing check by editing the map or a test to describe the new
63+
behavior — that hides product regressions. If the new behavior is intentional,
64+
the map/test update is a separate reviewed change.
65+
66+
## Cleanup
67+
68+
- Remove scratch driver dirs and evidence dirs you created.
69+
- `git status` must show no modifications inside the repo.

‎features/README.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Feature Map — fpRust
2+
3+
One file per feature area. Each answers: what exists, how to drive it, what
4+
usually lies. Sweep order for a broad regression pass:
5+
`core.md` → `reactive.md` → `concurrency.md`.
6+
7+
- [core.md](core.md) — Maybe/Optional, fp functions, common helpers
8+
- [reactive.md](reactive.md) — MonadIO, Publisher
9+
- [concurrency.md](concurrency.md) — Actor, Coroutine, Handler, sync primitives
10+
11+
## Maintenance
12+
13+
Each feature file carries `source_commit` + `last_verified_at` +
14+
`verification_status`. After any change to the covered source files, re-run
15+
the affected feature's Drive section and update the metadata. Do not rewrite
16+
the map on a schedule — re-verify on relevant code change only (event-driven,
17+
not calendar-driven).
18+
19+
A `verification_status` of `failed` means the product changed; classify the
20+
failure per VERIFY.md §When a check fails before editing the map.

‎features/concurrency.md‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Feature: concurrency
2+
3+
`source_commit: 18a96af` · `last_verified_at: 2026-09-23` · `verification_status: passed`
4+
5+
User goal: Actor model, coroutines (`cor_do_m`), Handler job posting, and
6+
sync primitives (BlockingQueue, CountdownLatch, WillAsync/WillSync).
7+
8+
## Preconditions
9+
10+
- Repo root; `cargo test` works.
11+
12+
## Entry points
13+
14+
| Area | Files | Tests |
15+
| --- | --- | --- |
16+
| Actor | `src/actor.rs` | `actor::test_*` (9) |
17+
| Coroutine | `src/cor.rs` | `cor::test_*` (10) |
18+
| Handler | `src/handler.rs` | `handler::test_*` (8) |
19+
| sync primitives | `src/sync.rs` | `sync::test_*` (17) |
20+
21+
## Drive
22+
23+
```bash
24+
cargo test actor::
25+
cargo test cor::
26+
cargo test handler::
27+
cargo test sync::
28+
```
29+
30+
## Observable outcomes
31+
32+
- Actor: receives in order; spawn child + forward; context accumulates
33+
state; double-start safe; send after stop rejected; ask returns reply.
34+
- Coroutine: `cor_do_m` sequences yields; start idempotent; lifecycle states
35+
correct; `yield_from` on a dead target returns None.
36+
- Handler: jobs run FIFO; post before start preserved; post after stop
37+
rejected; double-start keeps running.
38+
- sync: BlockingQueue FIFO offer/poll + put/take, poll-empty → None,
39+
take-timeout → None, is_alive/stop; CountdownLatch releases all waiters,
40+
zero doesn't block, below-zero safe; WillAsync lifecycle + remove callback.
41+
42+
## Failure paths
43+
44+
- Actor messages out of order or send-after-stop accepted → lifecycle broken.
45+
- `cor_do_m` skipping yields or dead-target yield_from hanging → coroutine
46+
broken.
47+
- Handler FIFO violated or post-after-stop accepted → ordering/guard broken.
48+
- BlockingQueue poll on empty blocking instead of None → non-blocking
49+
contract broken; CountdownLatch not releasing all waiters → latch broken.
50+
51+
## Evidence
52+
53+
- `cargo test <module> -- --nocapture` output; cross-thread tests
54+
(`cross_thread_producer`, `countdownlatch_cross_thread`) are the oracle
55+
for concurrency claims — a single-threaded pass proves nothing there.

‎features/core.md‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Feature: core
2+
3+
`source_commit: 18a96af` · `last_verified_at: 2026-09-23` · `verification_status: passed`
4+
5+
User goal: Optional/Maybe semantics, fp function helpers (map/reduce/filter/
6+
fold/compose/pipe/partial/spread), common helpers (LinkedListAsync,
7+
SubscriptionFunc, RawFunc/RawReceiver, get_mut, generate_id).
8+
9+
## Preconditions
10+
11+
- Repo root; `cargo test` works (VERIFY.md → Launch, Doctor).
12+
13+
## Entry points
14+
15+
| Area | Files | Tests |
16+
| --- | --- | --- |
17+
| Maybe | `src/maybe.rs` | `maybe::test_*` (17) + doc tests |
18+
| fp functions | `src/fp.rs` | `fp::test_*` (23) + doc tests |
19+
| common helpers | `src/common.rs` | `common::test_*` (14) |
20+
21+
## Drive
22+
23+
```bash
24+
cargo test maybe::
25+
cargo test fp::
26+
cargo test common::
27+
```
28+
29+
## Observable outcomes
30+
31+
- `Maybe::just(1)` present; `Maybe::val()` unwraps; `map`/`ap`/`just` doc
32+
tests pin the API shape.
33+
- fp: `compose`/`pipe` are mirrors (`test_fp_compose_pipe_are_mirror`);
34+
`partial_left_last_one`; `spread_and_call`; `fp!` macro curried forms.
35+
- common: `LinkedListAsync` FIFO + clone-shares-state; `SubscriptionFunc`
36+
clone-equal-same-id / distinct-ids; `RawFunc`/`RawReceiver` invoke/pass.
37+
38+
## Failure paths
39+
40+
- `just` of a value reporting absent → presence contract broken.
41+
- `compose`/`pipe` no longer mirroring → ordering contract broken.
42+
- `LinkedListAsync` clone not sharing state or draining out of order →
43+
shared-state FIFO broken.
44+
- `SubscriptionFunc` clones comparing unequal → identity contract broken.
45+
46+
## Evidence
47+
48+
- `cargo test <module> -- --nocapture` output; doc tests are part of the
49+
oracle — a doc-test failure is a product failure, not a doc nit.

‎features/reactive.md‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Feature: reactive
2+
3+
`source_commit: 18a96af` · `last_verified_at: 2026-09-23` · `verification_status: passed`
4+
5+
User goal: Rx-like MonadIO streams and Publisher pub/sub.
6+
7+
## Preconditions
8+
9+
- Repo root; `cargo test` works.
10+
11+
## Entry points
12+
13+
| Area | Files | Tests |
14+
| --- | --- | --- |
15+
| MonadIO | `src/monadio.rs` | `monadio::test_*` (13) |
16+
| Publisher | `src/publisher.rs` | `publisher::test_*` (14) |
17+
18+
## Drive
19+
20+
```bash
21+
cargo test monadio::
22+
cargo test publisher::
23+
```
24+
25+
## Observable outcomes
26+
27+
- MonadIO `of` returns value; `subscribe`/`subscribe_fn` deliver via on_next.
28+
- Publisher: `publish` notifies all subscribers; `map` runs on publish;
29+
`unsubscribe` stops delivery to the correct observer only; subscribe
30+
returns the same handle for the same observer; blocking-queue subscription
31+
mode works.
32+
33+
## Failure paths
34+
35+
- `unsubscribe` removing the wrong observer or not stopping delivery →
36+
observer-registry broken.
37+
- `map` not running on publish → transform chain broken.
38+
- Multiple subscribers not all notified → fanout broken.
39+
- Blocking-queue mode losing values → queue bridge broken.
40+
41+
## Evidence
42+
43+
- `cargo test <module> -- --nocapture` output.

0 commit comments

Comments
 (0)