tickvault-ob 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tickvault_ob-0.1.0/.github/workflows/ci.yml +68 -0
- tickvault_ob-0.1.0/.github/workflows/release.yml +100 -0
- tickvault_ob-0.1.0/.gitignore +10 -0
- tickvault_ob-0.1.0/CONTRIBUTING.md +102 -0
- tickvault_ob-0.1.0/Cargo.lock +2940 -0
- tickvault_ob-0.1.0/Cargo.toml +63 -0
- tickvault_ob-0.1.0/LICENSE-APACHE +202 -0
- tickvault_ob-0.1.0/LICENSE-MIT +21 -0
- tickvault_ob-0.1.0/PKG-INFO +148 -0
- tickvault_ob-0.1.0/README.md +526 -0
- tickvault_ob-0.1.0/bindings/Cargo.toml +21 -0
- tickvault_ob-0.1.0/bindings/LICENSE-APACHE +202 -0
- tickvault_ob-0.1.0/bindings/LICENSE-MIT +21 -0
- tickvault_ob-0.1.0/bindings/README.md +121 -0
- tickvault_ob-0.1.0/bindings/src/lib.rs +845 -0
- tickvault_ob-0.1.0/bindings/tests/conftest.py +82 -0
- tickvault_ob-0.1.0/bindings/tests/test_archive.py +66 -0
- tickvault_ob-0.1.0/bindings/tests/test_arrow.py +70 -0
- tickvault_ob-0.1.0/bindings/tests/test_gate_ten_lines.py +68 -0
- tickvault_ob-0.1.0/bindings/tests/test_iteration.py +121 -0
- tickvault_ob-0.1.0/bindings/tests/test_plot.py +86 -0
- tickvault_ob-0.1.0/bindings/tests/test_semantics.py +106 -0
- tickvault_ob-0.1.0/bindings/tests/test_typing.py +80 -0
- tickvault_ob-0.1.0/docs/.nojekyll +0 -0
- tickvault_ob-0.1.0/docs/app.js +366 -0
- tickvault_ob-0.1.0/docs/data/binance-us/_manifest.jsonl +1 -0
- tickvault_ob-0.1.0/docs/data/binance-us/venue=binance-us/symbol=BTC-USDT/date=2026-08-25/part-1787637355193065875-0000.parquet +0 -0
- tickvault_ob-0.1.0/docs/data/bitstamp/_manifest.jsonl +1 -0
- tickvault_ob-0.1.0/docs/data/bitstamp/venue=bitstamp/symbol=BTC-USD/date=2026-08-25/part-1787637358288785208-0000.parquet +0 -0
- tickvault_ob-0.1.0/docs/data/bybit/_manifest.jsonl +1 -0
- tickvault_ob-0.1.0/docs/data/bybit/venue=bybit/symbol=BTC-USDT/date=2026-08-25/part-1787637354762284125-0000.parquet +0 -0
- tickvault_ob-0.1.0/docs/data/coinbase/_manifest.jsonl +1 -0
- tickvault_ob-0.1.0/docs/data/coinbase/venue=coinbase/symbol=BTC-USD/date=2026-08-25/part-1787637356715735750-0000.parquet +0 -0
- tickvault_ob-0.1.0/docs/data/coverage.json +277 -0
- tickvault_ob-0.1.0/docs/data/index.json +94 -0
- tickvault_ob-0.1.0/docs/data/kraken/_manifest.jsonl +1 -0
- tickvault_ob-0.1.0/docs/data/kraken/venue=kraken/symbol=BTC-USD/date=2026-08-25/part-1787637356351189292-0000.parquet +0 -0
- tickvault_ob-0.1.0/docs/data/okx/_manifest.jsonl +1 -0
- tickvault_ob-0.1.0/docs/data/okx/venue=okx/symbol=BTC-USDT/date=2026-08-25/part-1787637354945811709-0000.parquet +0 -0
- tickvault_ob-0.1.0/docs/index.html +206 -0
- tickvault_ob-0.1.0/docs/pkg/tickvault_viewer.d.ts +108 -0
- tickvault_ob-0.1.0/docs/pkg/tickvault_viewer.js +429 -0
- tickvault_ob-0.1.0/docs/pkg/tickvault_viewer_bg.wasm +0 -0
- tickvault_ob-0.1.0/docs/pkg/tickvault_viewer_bg.wasm.d.ts +21 -0
- tickvault_ob-0.1.0/docs/python.md +110 -0
- tickvault_ob-0.1.0/docs/querying.md +97 -0
- tickvault_ob-0.1.0/docs/reconstruction.md +102 -0
- tickvault_ob-0.1.0/docs/schema.md +175 -0
- tickvault_ob-0.1.0/docs/style.css +153 -0
- tickvault_ob-0.1.0/docs/venues.md +380 -0
- tickvault_ob-0.1.0/examples/capture.rs +34 -0
- tickvault_ob-0.1.0/pyproject.toml +42 -0
- tickvault_ob-0.1.0/python/tickvault/__init__.py +286 -0
- tickvault_ob-0.1.0/python/tickvault/__init__.pyi +124 -0
- tickvault_ob-0.1.0/python/tickvault/py.typed +0 -0
- tickvault_ob-0.1.0/scripts/build-viewer.sh +32 -0
- tickvault_ob-0.1.0/scripts/make-demo-data.py +127 -0
- tickvault_ob-0.1.0/scripts/refresh-demo-data.sh +52 -0
- tickvault_ob-0.1.0/src/bin/tickvault.rs +1580 -0
- tickvault_ob-0.1.0/src/book/checksum.rs +278 -0
- tickvault_ob-0.1.0/src/book/l3.rs +1014 -0
- tickvault_ob-0.1.0/src/book/mod.rs +594 -0
- tickvault_ob-0.1.0/src/book/replay.rs +244 -0
- tickvault_ob-0.1.0/src/clock.rs +445 -0
- tickvault_ob-0.1.0/src/config.rs +372 -0
- tickvault_ob-0.1.0/src/error.rs +118 -0
- tickvault_ob-0.1.0/src/fixed.rs +532 -0
- tickvault_ob-0.1.0/src/gap.rs +1109 -0
- tickvault_ob-0.1.0/src/latency.rs +381 -0
- tickvault_ob-0.1.0/src/lib.rs +60 -0
- tickvault_ob-0.1.0/src/limits.rs +402 -0
- tickvault_ob-0.1.0/src/pipeline.rs +822 -0
- tickvault_ob-0.1.0/src/query/aggregate.rs +554 -0
- tickvault_ob-0.1.0/src/query/mod.rs +300 -0
- tickvault_ob-0.1.0/src/query/replay.rs +187 -0
- tickvault_ob-0.1.0/src/reconstruct/checkpoint.rs +501 -0
- tickvault_ob-0.1.0/src/reconstruct/mod.rs +725 -0
- tickvault_ob-0.1.0/src/recorder.rs +303 -0
- tickvault_ob-0.1.0/src/sequence.rs +1000 -0
- tickvault_ob-0.1.0/src/session.rs +1580 -0
- tickvault_ob-0.1.0/src/status.rs +240 -0
- tickvault_ob-0.1.0/src/store/compact.rs +475 -0
- tickvault_ob-0.1.0/src/store/manifest.rs +480 -0
- tickvault_ob-0.1.0/src/store/mod.rs +18 -0
- tickvault_ob-0.1.0/src/store/reader.rs +386 -0
- tickvault_ob-0.1.0/src/store/recovery.rs +581 -0
- tickvault_ob-0.1.0/src/store/retention.rs +390 -0
- tickvault_ob-0.1.0/src/store/rows.rs +464 -0
- tickvault_ob-0.1.0/src/store/schema.rs +700 -0
- tickvault_ob-0.1.0/src/store/writer.rs +583 -0
- tickvault_ob-0.1.0/src/supervise.rs +446 -0
- tickvault_ob-0.1.0/src/symbols.rs +467 -0
- tickvault_ob-0.1.0/src/transport/http.rs +81 -0
- tickvault_ob-0.1.0/src/transport/mod.rs +14 -0
- tickvault_ob-0.1.0/src/transport/replay.rs +121 -0
- tickvault_ob-0.1.0/src/transport/ws.rs +71 -0
- tickvault_ob-0.1.0/src/types.rs +186 -0
- tickvault_ob-0.1.0/src/venue/binance_us.rs +326 -0
- tickvault_ob-0.1.0/src/venue/bitstamp.rs +674 -0
- tickvault_ob-0.1.0/src/venue/bybit.rs +373 -0
- tickvault_ob-0.1.0/src/venue/coinbase.rs +442 -0
- tickvault_ob-0.1.0/src/venue/kraken.rs +539 -0
- tickvault_ob-0.1.0/src/venue/mod.rs +552 -0
- tickvault_ob-0.1.0/src/venue/okx.rs +390 -0
- tickvault_ob-0.1.0/src/venue/registry.rs +239 -0
- tickvault_ob-0.1.0/tests/common/mod.rs +848 -0
- tickvault_ob-0.1.0/tests/conformance.rs +487 -0
- tickvault_ob-0.1.0/tests/fixtures/README.md +50 -0
- tickvault_ob-0.1.0/tests/fixtures/binance_us_depth.jsonl +25 -0
- tickvault_ob-0.1.0/tests/fixtures/binance_us_snapshot.json +1 -0
- tickvault_ob-0.1.0/tests/fixtures/bitstamp_diff.jsonl +12 -0
- tickvault_ob-0.1.0/tests/fixtures/bitstamp_live_orders.jsonl +501 -0
- tickvault_ob-0.1.0/tests/fixtures/bitstamp_snapshot.json +1 -0
- tickvault_ob-0.1.0/tests/fixtures/bitstamp_snapshot_l3.json +1 -0
- tickvault_ob-0.1.0/tests/fixtures/bybit_orderbook.jsonl +10 -0
- tickvault_ob-0.1.0/tests/fixtures/coinbase_l2.jsonl +12 -0
- tickvault_ob-0.1.0/tests/fixtures/kraken_book.jsonl +8 -0
- tickvault_ob-0.1.0/tests/fixtures/okx_books.jsonl +8 -0
- tickvault_ob-0.1.0/tests/gate_crash_recovery.rs +319 -0
- tickvault_ob-0.1.0/tests/gate_gap_detection.rs +587 -0
- tickvault_ob-0.1.0/tests/gate_idle_feed.rs +160 -0
- tickvault_ob-0.1.0/tests/gate_l3.rs +588 -0
- tickvault_ob-0.1.0/tests/gate_query.rs +318 -0
- tickvault_ob-0.1.0/tests/gate_reconstruct.rs +269 -0
- tickvault_ob-0.1.0/tickvault.example.toml +69 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
env:
|
|
6
|
+
CARGO_TERM_COLOR: always
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
# Formatting, lints and the whole suite. Clippy is -D warnings because a
|
|
10
|
+
# warning nobody fails on is a warning nobody reads.
|
|
11
|
+
test:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- run: rustup component add rustfmt clippy
|
|
16
|
+
- run: cargo fmt --check
|
|
17
|
+
- run: cargo clippy --all-targets -- -D warnings
|
|
18
|
+
- run: cargo test --release
|
|
19
|
+
|
|
20
|
+
# The phase 3 acceptance gate, and the reason the archive can claim anything
|
|
21
|
+
# about crashes: SIGKILL the writer at randomised offsets during sustained
|
|
22
|
+
# write, restart, and assert every file reads back and the truncation point is
|
|
23
|
+
# recorded. It spawns and kills real processes, so it lives behind --ignored
|
|
24
|
+
# and runs here rather than on every developer's `cargo test`.
|
|
25
|
+
crash-gate:
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
timeout-minutes: 20
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v4
|
|
30
|
+
- run: cargo test --release --test gate_crash_recovery -- --ignored --nocapture
|
|
31
|
+
|
|
32
|
+
# Two claims. The read half of the crate compiles without the capture half,
|
|
33
|
+
# which is what makes the viewer possible; and the viewer rebuilds the same
|
|
34
|
+
# book the library does, which is what makes the viewer honest.
|
|
35
|
+
wasm:
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v4
|
|
39
|
+
- run: rustup target add wasm32-unknown-unknown
|
|
40
|
+
# The feature split: no tokio, no TLS stack, no C compression codec.
|
|
41
|
+
- run: cargo check --lib --no-default-features --target wasm32-unknown-unknown
|
|
42
|
+
- name: viewer compiles to wasm
|
|
43
|
+
working-directory: viewer
|
|
44
|
+
run: cargo build --release --target wasm32-unknown-unknown
|
|
45
|
+
- name: viewer agrees with the library
|
|
46
|
+
working-directory: viewer
|
|
47
|
+
run: cargo test --release
|
|
48
|
+
|
|
49
|
+
# The bindings, against a wheel rather than a source tree, so the tests
|
|
50
|
+
# exercise what someone actually installs.
|
|
51
|
+
python:
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
- uses: actions/setup-python@v5
|
|
56
|
+
with:
|
|
57
|
+
python-version: '3.12'
|
|
58
|
+
# The Python tests replay committed tapes through this binary to build a
|
|
59
|
+
# fixture archive, so they need it built but never need a live venue.
|
|
60
|
+
- run: cargo build --release --bin tickvault
|
|
61
|
+
- run: pip install maturin pytest pyarrow polars pandas matplotlib
|
|
62
|
+
- name: build and install the wheel
|
|
63
|
+
working-directory: bindings
|
|
64
|
+
run: |
|
|
65
|
+
maturin build --release --out dist
|
|
66
|
+
pip install --no-index --find-links dist tickvault-ob
|
|
67
|
+
- working-directory: bindings
|
|
68
|
+
run: pytest tests -q
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
# Tag driven. `git tag v0.1.0 && git push --tags` builds wheels for every
|
|
4
|
+
# platform and publishes them, so the README's `pip install tickvault` stops
|
|
5
|
+
# being a claim about something that does not exist.
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
tags: ['v*']
|
|
9
|
+
# Buildable on demand too, so the wheels can be checked without claiming a
|
|
10
|
+
# version on PyPI.
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
wheels:
|
|
15
|
+
name: wheel (${{ matrix.target }})
|
|
16
|
+
runs-on: ${{ matrix.os }}
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
include:
|
|
21
|
+
- os: ubuntu-latest
|
|
22
|
+
target: x86_64-unknown-linux-gnu
|
|
23
|
+
- os: macos-latest
|
|
24
|
+
target: aarch64-apple-darwin
|
|
25
|
+
# macos-latest runners are Apple silicon, so an Intel Mac would
|
|
26
|
+
# otherwise fall back to the sdist and compile Rust at install time.
|
|
27
|
+
- os: macos-latest
|
|
28
|
+
target: x86_64-apple-darwin
|
|
29
|
+
- os: windows-latest
|
|
30
|
+
target: x86_64-pc-windows-msvc
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
- uses: actions/setup-python@v5
|
|
34
|
+
with:
|
|
35
|
+
python-version: '3.12'
|
|
36
|
+
# One wheel per platform covers every Python from 3.9 up, because the
|
|
37
|
+
# extension is built against the stable ABI. Without that it would be a
|
|
38
|
+
# wheel per platform per interpreter version.
|
|
39
|
+
- name: build
|
|
40
|
+
uses: PyO3/maturin-action@v1
|
|
41
|
+
with:
|
|
42
|
+
command: build
|
|
43
|
+
target: ${{ matrix.target }}
|
|
44
|
+
args: --release --out dist --manifest-path bindings/Cargo.toml
|
|
45
|
+
manylinux: auto
|
|
46
|
+
- uses: actions/upload-artifact@v4
|
|
47
|
+
with:
|
|
48
|
+
name: wheels-${{ matrix.target }}
|
|
49
|
+
path: dist
|
|
50
|
+
|
|
51
|
+
sdist:
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
- uses: PyO3/maturin-action@v1
|
|
56
|
+
with:
|
|
57
|
+
command: sdist
|
|
58
|
+
args: --out dist --manifest-path bindings/Cargo.toml
|
|
59
|
+
- uses: actions/upload-artifact@v4
|
|
60
|
+
with:
|
|
61
|
+
name: sdist
|
|
62
|
+
path: dist
|
|
63
|
+
|
|
64
|
+
# Checks the wheel actually installs and works before anything is published.
|
|
65
|
+
# A release that ships a broken wheel is worse than no release.
|
|
66
|
+
verify:
|
|
67
|
+
needs: [wheels]
|
|
68
|
+
runs-on: ubuntu-latest
|
|
69
|
+
steps:
|
|
70
|
+
- uses: actions/checkout@v4
|
|
71
|
+
- uses: actions/setup-python@v5
|
|
72
|
+
with:
|
|
73
|
+
python-version: '3.12'
|
|
74
|
+
- uses: actions/download-artifact@v4
|
|
75
|
+
with:
|
|
76
|
+
name: wheels-x86_64-unknown-linux-gnu
|
|
77
|
+
path: dist
|
|
78
|
+
# The Python tests replay committed tapes through this binary, so they
|
|
79
|
+
# need it built and never need a live venue.
|
|
80
|
+
- run: cargo build --release --bin tickvault
|
|
81
|
+
- run: pip install pytest pyarrow polars pandas matplotlib
|
|
82
|
+
- run: pip install --no-index --find-links dist tickvault-ob
|
|
83
|
+
- working-directory: bindings
|
|
84
|
+
run: pytest tests -q
|
|
85
|
+
|
|
86
|
+
publish:
|
|
87
|
+
needs: [wheels, sdist, verify]
|
|
88
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
89
|
+
runs-on: ubuntu-latest
|
|
90
|
+
environment: pypi
|
|
91
|
+
# Trusted publishing: PyPI verifies this workflow rather than a long-lived
|
|
92
|
+
# token living in the repo's secrets.
|
|
93
|
+
permissions:
|
|
94
|
+
id-token: write
|
|
95
|
+
steps:
|
|
96
|
+
- uses: actions/download-artifact@v4
|
|
97
|
+
with:
|
|
98
|
+
path: dist
|
|
99
|
+
merge-multiple: true
|
|
100
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Contributing to tickvault
|
|
2
|
+
|
|
3
|
+
Thanks for looking. tickvault records order books, and its whole claim is that
|
|
4
|
+
the resulting dataset is honest about its own holes. So the bar for anything
|
|
5
|
+
touching what the archive says about itself is deliberately high, and the bar
|
|
6
|
+
for everything else is normal.
|
|
7
|
+
|
|
8
|
+
## The contract you must not break
|
|
9
|
+
|
|
10
|
+
**Nothing may claim to be clean unless it was checked.** That is the sentence
|
|
11
|
+
the repo exists to defend, and most of the review of a change goes into whether
|
|
12
|
+
it quietly weakens one of these:
|
|
13
|
+
|
|
14
|
+
- **A detected gap stops the book.** Never stitch deltas across a hole. A
|
|
15
|
+
stitched book looks continuous and is wrong, which is the exact failure that
|
|
16
|
+
makes free order book data untrustworthy.
|
|
17
|
+
- **Unverifiable is not clean.** A message that could not be checked is counted
|
|
18
|
+
apart from one that was checked and passed. Bitstamp's aggregated feed reports
|
|
19
|
+
0% verified, and it is never rounded up to look like the others.
|
|
20
|
+
- **Null is not zero.** Where the data cannot answer, it returns nothing. A
|
|
21
|
+
one-sided book has no mid. An aggregated feed does not know what traded.
|
|
22
|
+
Writing a zero there is a claim, and a false one.
|
|
23
|
+
- **Our faults are labelled as ours.** Rows lost because the writer fell behind
|
|
24
|
+
are counted separately from messages the venue never sent. Same for retention:
|
|
25
|
+
data we chose to stop keeping is a different manifest entry from data we lost.
|
|
26
|
+
- **Never blame the venue for our own defect.** If our decimal rendering lost
|
|
27
|
+
digits, or the book was shallower than the checksum covers, that message is
|
|
28
|
+
unverifiable, not a gap.
|
|
29
|
+
|
|
30
|
+
If a change of yours makes a gate fail, the change is wrong, not the gate. Three
|
|
31
|
+
of the gates were written after a passing test turned out to be passing for the
|
|
32
|
+
wrong reason, which is why they assert properties rather than outputs.
|
|
33
|
+
|
|
34
|
+
## Getting oriented
|
|
35
|
+
|
|
36
|
+
| Path | What lives there |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `src/venue/` | The `Venue` trait, six implementations, and the capability matrix that keeps the ingest loop free of special cases. |
|
|
39
|
+
| `src/session.rs` | The ingest loop. Exactly two branches on venue capabilities; everything else is data. |
|
|
40
|
+
| `src/gap.rs` | Suspect windows and the report they feed. The product. |
|
|
41
|
+
| `src/store/` | Parquet schema, writer, manifest, recovery, retention. |
|
|
42
|
+
| `src/reconstruct/`, `src/query/` | Rebuilding a book at an instant, and reading the archive. |
|
|
43
|
+
| `src/supervise.rs`, `src/status.rs` | Running as a service, and answering for it. |
|
|
44
|
+
| `docs/venues.md` | Per-venue findings, measured rather than read off a doc page. |
|
|
45
|
+
| `docs/schema.md` | Every column, and what null means in it. |
|
|
46
|
+
| `tests/gate_*.rs` | The gates. Each states a property. |
|
|
47
|
+
| `viewer/` | The reconstruction engine compiled to wasm, behind the demo page. |
|
|
48
|
+
| `bindings/` | The Python package. |
|
|
49
|
+
|
|
50
|
+
## Building and testing
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cargo test # the suite
|
|
54
|
+
cargo test -- --ignored # real SIGKILLs, plus one live venue reconciliation
|
|
55
|
+
cargo clippy --all-targets -- -D warnings
|
|
56
|
+
cargo fmt --check
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
CI runs all of that except the live reconciliation, which measures Bitstamp's two
|
|
60
|
+
feeds against each other and would make the build depend on a venue's afternoon.
|
|
61
|
+
|
|
62
|
+
The Python and wasm halves have their own commands:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
cd bindings && maturin develop --release && pytest tests
|
|
66
|
+
scripts/build-viewer.sh && cd viewer && cargo test
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Adding a venue
|
|
70
|
+
|
|
71
|
+
This is meant to be mechanical rather than archaeological, and the conformance
|
|
72
|
+
suite in `tests/conformance.rs` is what makes it so. Implement `Venue`, declare
|
|
73
|
+
its capabilities honestly, add a captured fixture, and the suite will tell you
|
|
74
|
+
what is inconsistent.
|
|
75
|
+
|
|
76
|
+
Two things worth knowing before you start:
|
|
77
|
+
|
|
78
|
+
- **Measure the feed, do not read the docs.** Nearly every interesting line in
|
|
79
|
+
`docs/venues.md` contradicts what the venue's documentation implies. Capture a
|
|
80
|
+
tape with `tickvault record --out tape.jsonl` and look at it.
|
|
81
|
+
- **Declare what the venue cannot prove.** A venue with no sequencing gets a
|
|
82
|
+
`MonotonicTimestamp` scheme and a blind spot entry, not a hopeful guess. The
|
|
83
|
+
capability matrix is what keeps the honesty rules enforceable in one place.
|
|
84
|
+
|
|
85
|
+
## Style
|
|
86
|
+
|
|
87
|
+
Commits are one logical change each, buildable on their own, with a subject in
|
|
88
|
+
the imperative and a body explaining why rather than what. Several of the
|
|
89
|
+
existing messages record a measurement that overturned an assumption; that is
|
|
90
|
+
the useful kind.
|
|
91
|
+
|
|
92
|
+
No em dashes anywhere, in code, comments, docs or commit messages.
|
|
93
|
+
|
|
94
|
+
Comments explain why, not what. If a comment restates the line below it, delete
|
|
95
|
+
one of them.
|
|
96
|
+
|
|
97
|
+
## Publishing a number
|
|
98
|
+
|
|
99
|
+
Any figure in the README has to be reproducible by a command in the README.
|
|
100
|
+
`tickvault bench` backs the throughput claim, `tests/gate_*.rs` back the
|
|
101
|
+
correctness ones, and `docs/venues.md` says which machine and which capture each
|
|
102
|
+
measurement came from. A number without a way to check it does not belong here.
|