rttp 1.2.6__tar.gz → 1.2.7__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.
@@ -1,4 +1,4 @@
1
- # Changelog — `rttp` (Python)
1
+ # Changelog -- `rttp` (Python)
2
2
 
3
3
  All notable changes to the `rttp` package. Format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/); versioning is
@@ -6,11 +6,40 @@ All notable changes to the `rttp` package. Format follows
6
6
 
7
7
  ---
8
8
 
9
- ## [1.2.6] — 2026-09-19
9
+ ## [1.2.7] -- 2026-09-21
10
10
 
11
- **Version alignment — no code change.** Every module, byte layout and
11
+ **Conformance surface grown; wire format untouched.** The shipped
12
+ `rttp/vectors/rttp-conformance-v1.2.6.json` is now 13,460 bytes
13
+ (`sha256 4b743e63...`) and the self-test replays every added case: **83 checks**
14
+ in full, and **80 passed with 3 skipped** on a zero-dependency install -- a check
15
+ that cannot be performed is reported as skipped, never as passed.
16
+
17
+ ### Added
18
+
19
+ * **Nine fail-closed frame cases, one positive frame.** Each of the nine frames
20
+ must be rejected; the positive frame must be accepted with an empty action.
21
+ * **The published Ed25519 envelope vector**, replayed three ways: the canonical
22
+ signing input byte for byte, `AID == SHA-256(public key)`, and the signature
23
+ itself (the third one skips without the optional primitive).
24
+
25
+ ### Changed
26
+
27
+ * **Skipped checks are now counted and printed**, so a default install can no
28
+ longer look like a full pass.
29
+ * Per-section counts are reported: 38 conformance, 16 envelope rules, 22 envelope
30
+ flow, 2 RFC 8032, 5 zero-dependency.
31
+
32
+ ### Note
33
+
34
+ * PyPI and npm carry `1.2.7`; crates.io carries the same code as the pre-release
35
+ `1.2.8-alpha`. The registry version strings differ by publishing policy, not by
36
+ code -- the vectors and their `sha256` are identical everywhere.
37
+
38
+ ## [1.2.6] -- 2026-09-19
39
+
40
+ **Version alignment -- no code change.** Every module, byte layout and
12
41
  conformance vector is identical to 0.1.2, and the self-test still reports the
13
- same 53 checks. Only the version string and the maturity classifier change.
42
+ the same 53 checks (full set, i.e. with the optional Ed25519 backend). Only the version string and the maturity classifier change.
14
43
 
15
44
  ### Changed
16
45
 
@@ -20,23 +49,23 @@ same 53 checks. Only the version string and the maturity classifier change.
20
49
  The old `0.1.x` line was a package-maturity number that corresponded to
21
50
  nothing in the specification, and it made the same package look like two
22
51
  different releases on two registries.
23
- * **`Development Status` classifier: `3 - Alpha` → `4 - Beta`.** A
52
+ * **`Development Status` classifier: `3 - Alpha` -> `4 - Beta`.** A
24
53
  non-pre-release version must not ship with an "Alpha" classifier; leaving
25
54
  the two in conflict invites the question "which one is true?".
26
55
  * Install command note: on crates.io every published version of this crate is
27
56
  a pre-release, so Cargo will not select it from a plain `rttp` requirement.
28
57
  Write `cargo add rttp@1.2.6-alpha` (or pin `rttp = "1.2.6-alpha"`).
29
58
 
30
- ## [0.1.2] — 2026-09-18
59
+ ## [0.1.2] -- 2026-09-18
31
60
 
32
- **Metadata correction — no code change.** Every module, byte layout and
61
+ **Metadata correction -- no code change.** Every module, byte layout and
33
62
  conformance vector is identical to 0.1.1, and the self-test still reports the
34
- same 53 checks.
63
+ the same 53 checks (full set, i.e. with the optional Ed25519 backend).
35
64
 
36
65
  ### Fixed
37
66
 
38
67
  * **The distribution identity now matches the IANA registration.** The package
39
- was authored as `RTTP Working Group` — a name that appears in no filing. The
68
+ was authored as `RTTP Working Group` -- a name that appears in no filing. The
40
69
  `rttp` URI-scheme registration on file with IANA (ticket `[IANA #1459939]`)
41
70
  names **`RTTP.COM Organization`** as the `Author/Change controller`, and every
42
71
  other public surface uses that same name. Both package manifests now say it
@@ -44,19 +73,19 @@ same 53 checks.
44
73
 
45
74
  | Field | Before | After |
46
75
  |:---|:---|:---|
47
- | `pyproject.toml` → `authors` (PyPI) | `RTTP Working Group` | **`RTTP.COM Organization`** |
48
- | `package.json` → `author` (npm) | `RTTP Working Group` | **`RTTP.COM Organization`** |
76
+ | `pyproject.toml` -> `authors` (PyPI) | `RTTP Working Group` | **`RTTP.COM Organization`** |
77
+ | `package.json` -> `author` (npm) | `RTTP Working Group` | **`RTTP.COM Organization`** |
49
78
 
50
79
  Package metadata cannot be edited after publication, so 0.1.0 and 0.1.1 keep
51
80
  the old string inside their own metadata; this is the version that carries the
52
81
  correction. Project pages display the latest version, so the visible author
53
82
  name becomes correct once this release is out.
54
83
 
55
- ## [0.1.1] — 2026-09-18
84
+ ## [0.1.1] -- 2026-09-18
56
85
 
57
- **Documentation only — no code change.** Every module, byte layout and
86
+ **Documentation only -- no code change.** Every module, byte layout and
58
87
  conformance vector is identical to 0.1.0, and the self-test still reports the
59
- same 53 checks.
88
+ the same 53 checks (full set, i.e. with the optional Ed25519 backend).
60
89
 
61
90
  ### Fixed
62
91
 
@@ -64,7 +93,7 @@ same 53 checks.
64
93
  below said the JavaScript side "will publish under the `@rttp` scope". That
65
94
  scope **cannot be created at all**: npm already has a personal account named
66
95
  `rttp`, and an organization name may not collide with a user name. The
67
- JavaScript side is published as **`@aicent/rttp`** — this project's own
96
+ JavaScript side is published as **`@aicent/rttp`** -- this project's own
68
97
  organization, with the package name itself still just `rttp`.
69
98
  * **README distribution table** now names the npm package exactly
70
99
  (`@aicent/rttp`), and gives `pip install rttp` for this package, matching the
@@ -74,74 +103,74 @@ same 53 checks.
74
103
 
75
104
  | Registry | Name | State |
76
105
  |:---|:---|:---|
77
- | PyPI | `rttp` | this package — `pip install rttp` |
78
- | npm | `@aicent/rttp` | **published 0.1.1** — 2026-09-18 |
106
+ | PyPI | `rttp` | this package -- `pip install rttp` |
107
+ | npm | `@aicent/rttp` | **published 0.1.1** -- 2026-09-18 |
79
108
  | crates.io | `rttp` | held by this project |
80
109
 
81
- ## [0.1.0] — 2026-09-17
110
+ ## [0.1.0] -- 2026-09-17
82
111
 
83
112
  First release. Scope is deliberately narrow: **framing, addressing and sealing**,
84
113
  with zero dependencies and no transport.
85
114
 
86
115
  ### Added
87
116
 
88
- * **`rttp.pulse_header`** — `PulseHeader128` codec for the 128-byte
89
- hardware-aligned frame header (RFC-002 §4.1), including the v1.2.6 extension
117
+ * **`rttp.pulse_header`** -- `PulseHeader128` codec for the 128-byte
118
+ hardware-aligned frame header (RFC-002 sec. 4.1), including the v1.2.6 extension
90
119
  block:
91
- * `SPEC_REV` `0x66` · `FLAGS` `0x67` · `ACTION_LEN` `0x68` · `ACTION` `0x69`(16B)
92
- · `RESERVED` `0x79`(7B)
93
- * bytes `0x00`–`0x65` are **not touched**, `VERSION_ID` stays 130 — readers
120
+ * `SPEC_REV` `0x66` - `FLAGS` `0x67` - `ACTION_LEN` `0x68` - `ACTION` `0x69`(16B)
121
+ - `RESERVED` `0x79`(7B)
122
+ * bytes `0x00`-`0x65` are **not touched**, `VERSION_ID` stays 130 -- readers
94
123
  that only understand the original layout remain conformant
95
- * `build()` · `build_for_uri()` · `parse()` · `verify()` · `to_hex()` /
124
+ * `build()` - `build_for_uri()` - `parse()` - `verify()` - `to_hex()` /
96
125
  `from_hex()`
97
- * strict verification (R1–R7): unknown `SPEC_REV` rejected, `SPEC_REV=0` with a
126
+ * strict verification (R1-R7): unknown `SPEC_REV` rejected, `SPEC_REV=0` with a
98
127
  non-zero block rejected, non-zero `RESERVED` rejected, unknown `FLAGS` bits
99
128
  rejected, `ACTION` padding must be zero, `ACTION_LEN` must agree with the
100
129
  payload
101
- * **`rttp.rttp_uri`** — validation, canonicalisation and `ROUTE_SHARD`
102
- derivation for `rttp://` URIs (RFC-002 §10.2 / §10.3):
103
- * `ROUTE_SHARD = SHA-256(ASCII(canonical_authority))[0:16]` — deterministic,
104
- pure computation, **no DNS** (§10.5)
130
+ * **`rttp.rttp_uri`** -- validation, canonicalisation and `ROUTE_SHARD`
131
+ derivation for `rttp://` URIs (RFC-002 sec. 10.2 / sec. 10.3):
132
+ * `ROUTE_SHARD = SHA-256(ASCII(canonical_authority))[0:16]` -- deterministic,
133
+ pure computation, **no DNS** (sec. 10.5)
105
134
  * hash-intent (`8lowhex`) and name-intent forms; open-set `action` vocabulary
106
135
  * fail-closed rejection of uppercase, `userinfo`, `port`, `query`,
107
136
  `fragment`, multi-segment paths, wrong segment counts, leading/trailing `-`,
108
137
  whitespace, and non-`rttp` schemes
109
- * accepts both `rttp://` and `web+rttp://` — the second as a **tolerance** for
138
+ * accepts both `rttp://` and `web+rttp://` -- the second as a **tolerance** for
110
139
  the browser protocol-handler form, which RFC-002 no longer defines
111
140
  (2026-09-17). Not a conformance claim; see "Known gaps" below.
112
- * **`rttp.seal`** — managed profile: HMAC-SHA256 over a pre-shared key table,
113
- bidirectional switch↔agent signing, `ts|nonce` with a 120-second skew window.
114
- * **`rttp.seal_asym`** — **sovereign profile**: Ed25519 seals with
141
+ * **`rttp.seal`** -- managed profile: HMAC-SHA256 over a pre-shared key table,
142
+ bidirectional switch<->agent signing, `ts|nonce` with a 120-second skew window.
143
+ * **`rttp.seal_asym`** -- **sovereign profile**: Ed25519 seals with
115
144
  `AID = SHA-256(public_key)`.
116
145
  * self-certifying: the envelope carries the public key, so a verifier
117
- recomputes the identity instead of trusting a claim — **no issuance, no
146
+ recomputes the identity instead of trusting a claim -- **no issuance, no
118
147
  registry, no directory**
119
148
  * `ts` and `nonce` are **inside** the signed input, so they cannot be rewritten
120
149
  without breaking the signature
121
150
  * freshness enforced by default (`|now - ts| <= 120 s`); archival verification
122
151
  available explicitly via `check_freshness=False`
123
- * lowercase-hex only — a case variant is rejected, not normalised
124
- * `generate_keypair()` · `seal()` · `unseal()` · `verify_envelope()` ·
125
- `verify_claims()` · `public_bundle()` · `signing_input()`
152
+ * lowercase-hex only -- a case variant is rejected, not normalised
153
+ * `generate_keypair()` - `seal()` - `unseal()` - `verify_envelope()` -
154
+ `verify_claims()` - `public_bundle()` - `signing_input()`
126
155
  * requires the `ed25519` extra; without it every call raises `SealError` with
127
156
  the install instruction rather than degrading to an unsigned path
128
- * **`rttp.aid`** — Autonomous Identity derivation (RFC-001), shared by both
157
+ * **`rttp.aid`** -- Autonomous Identity derivation (RFC-001), shared by both
129
158
  profiles so an AID means one thing across the stack.
130
- * **`rttp.selftest`** — `python -m rttp.selftest`, **53 checks**:
131
- * 25 conformance vectors (6 positive URIs · 15 rejections · 3 deterministic
132
- frames · 1 `SPEC_REV=0` compatibility vector)
133
- * RFC 8032 §7.1 TEST 1 / TEST 2, proving the signature backend is standard
134
- Ed25519 — so a failure identifies *which* half broke
159
+ * **`rttp.selftest`** -- `python -m rttp.selftest`, **53 checks with the optional Ed25519 backend (29 by default)**:
160
+ * 25 conformance vectors (6 positive URIs - 15 rejections - 3 deterministic
161
+ frames - 1 `SPEC_REV=0` compatibility vector)
162
+ * RFC 8032 sec. 7.1 TEST 1 / TEST 2, proving the signature backend is standard
163
+ Ed25519 -- so a failure identifies *which* half broke
135
164
  * 22 envelope checks, including a 14-case tamper matrix in which every single
136
165
  alteration must be rejected, and an explicit replay-window test
137
166
  * 4 static-scan checks proving the core modules import nothing outside the
138
167
  standard library
139
168
  * `--vectors` prints the deterministic envelope vector for the specification;
140
169
  `--quiet` prints the summary line only
141
- * **`rttp/vectors/rttp-conformance-v1.2.6.json`** — the published vectors, shipped
170
+ * **`rttp/vectors/rttp-conformance-v1.2.6.json`** -- the published vectors, shipped
142
171
  as package data so the self-test runs from an installed wheel, offline.
143
172
  * Console entry point `rttp-selftest`.
144
- * **`MANIFEST.in`** — the source distribution carries `README.md`,
173
+ * **`MANIFEST.in`** -- the source distribution carries `README.md`,
145
174
  `CHANGELOG.md`, `LICENSE`, `pyproject.toml` and the published vectors, and
146
175
  excludes virtual environments and build noise. Both the wheel and the sdist
147
176
  pass `twine check`.
@@ -149,51 +178,51 @@ with zero dependencies and no transport.
149
178
  ### Notes
150
179
 
151
180
  * **Zero dependencies** in the core, and that is a machine-checked claim rather
152
- than a promise — see the static-scan section of the self-test.
181
+ than a promise -- see the static-scan section of the self-test.
153
182
  * The reference implementation evaluates the
154
183
  **`iqa`** namespace nowhere: this package is the `rttp` protocol only.
155
184
  * ~~Distribution: PyPI `rttp`. The npm name `rttp` is held by an unrelated,
156
185
  unmaintained project, so the JavaScript side will publish under the `@rttp`
157
- scope.~~ — **corrected 2026-09-18.** PyPI `rttp` is now **published** (0.1.0,
186
+ scope.~~ -- **corrected 2026-09-18.** PyPI `rttp` is now **published** (0.1.0,
158
187
  2026-09-17). The npm name `rttp` is indeed held by an unrelated, unmaintained
159
- project — but the **`@rttp` scope cannot be created at all**, because a
188
+ project -- but the **`@rttp` scope cannot be created at all**, because a
160
189
  personal account already holds that name. The JavaScript side is therefore
161
190
  published as **`@aicent/rttp`**: this project's own organization, with the
162
191
  package name still just `rttp`.
163
192
 
164
193
  ### Known gaps
165
194
 
166
- Tracked in `SPEC/RTTP-SEAL-ENVELOPE-v1.2.6.md` §8 and §10. Deliberately listed
195
+ Tracked in `SPEC/RTTP-SEAL-ENVELOPE-v1.2.6.md` sec. 8 and sec. 10. Deliberately listed
167
196
  here so nobody has to discover them:
168
197
 
169
198
  * No transport and no client. The core encodes, addresses and seals; sending is a
170
199
  separate package's job.
171
200
  * No revocation, and no key rotation story. Both belong to RFC-003.
172
- * No replay **cache**: freshness (§3.4) bounds the window, but within it a replayed
201
+ * No replay **cache**: freshness (sec. 3.4) bounds the window, but within it a replayed
173
202
  envelope still verifies unless the verifier keeps a short-lived nonce store.
174
203
  * No transport-origin binding: the seal proves who signed, not which connection
175
204
  delivered it.
176
205
  * Rust parity: the published `rttp` crate has no transport layer and no envelope.
177
206
  Python and Node are the conforming implementations so far.
178
- * ~~the browser-registration prefix is accepted because RFC-002 §10.6 requires
179
- it…~~ — **superseded 2026-09-17.** That form was removed from both
207
+ * ~~the browser-registration prefix is accepted because RFC-002 sec. 10.6 requires
208
+ it...~~ -- **superseded 2026-09-17.** That form was removed from both
180
209
  specifications and will never be submitted to IANA. `rttp_uri` still accepts it
181
- as a **tolerance** — a browser hands the handler that string, and refusing it
182
- would break the protocol-handler path — but the specification defines no such
210
+ as a **tolerance** -- a browser hands the handler that string, and refusing it
211
+ would break the protocol-handler path -- but the specification defines no such
183
212
  form, so the acceptance is **outside the specification** and a conforming
184
213
  third-party implementation is not required to reproduce it.
185
214
  * ~~**Open, and ours to fix:** the published vectors asserted things the
186
- specification no longer said.~~ — **resolved 2026-09-18.** The generator now
215
+ specification no longer said.~~ -- **resolved 2026-09-18.** The generator now
187
216
  classifies every forward case explicitly:
188
- * `positive_uris` — each entry carries `tolerance` (boolean) and `note`. The
217
+ * `positive_uris` -- each entry carries `tolerance` (boolean) and `note`. The
189
218
  case whose `uri` carries the browser-registration prefix is `tolerance: true`,
190
219
  with its reason recorded: it is accepted only because that is the scheme name
191
- under which a handler is registered (RFC-002 §10.6) — never because the
220
+ under which a handler is registered (RFC-002 sec. 10.6) -- never because the
192
221
  specification defines it. It is **not** a conformance claim, and the 25-check
193
222
  total is unchanged.
194
- * `negative_uris` — the two case-clause citations were corrected from
195
- `(RFC-002 §10.2)` to **`§10.3`**, the clause that actually carries the
196
- lowercase rule. §10.2 now appears nowhere in the vector set.
223
+ * `negative_uris` -- the two case-clause citations were corrected from
224
+ `(RFC-002 sec. 10.2)` to **`sec. 10.3`**, the clause that actually carries the
225
+ lowercase rule. sec. 10.2 now appears nowhere in the vector set.
197
226
  Regenerated (`SPEC/tools/conformance.py --generate`), replayed (`--check`,
198
227
  25/25), and mirrored byte-identically into both packages. After the change:
199
228
  Python self-test 53/53, Node runner 25/25.
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rttp
3
- Version: 1.2.6
4
- Summary: RTTP reference implementation: PulseHeader128 framing, rttp:// addressing, and self-certifying Ed25519 seals (RFC-002 §4.1 / §10 / §11).
3
+ Version: 1.2.7
4
+ Summary: RTTP reference implementation: PulseHeader128 framing, rttp:// addressing, and self-certifying Ed25519 seals (RFC-002 sec. 4.1 / sec. 10 / sec. 11).
5
5
  Author: RTTP.COM Organization
6
6
  License-Expression: Apache-2.0
7
7
  Project-URL: Homepage, https://rttp.com/
@@ -31,35 +31,45 @@ Dynamic: license-file
31
31
  128-byte `PulseHeader128` frame, `rttp://` intent addressing, and self-certifying
32
32
  Ed25519 seals.**
33
33
 
34
- [RFC-002 §4.1](https://rttp.com/RFC-002/) · [§10](https://rttp.com/RFC-002/) · §11 · v1.2.6
34
+ [RFC-002 sec. 4.1](https://rttp.com/RFC-002/) - [sec. 10](https://rttp.com/RFC-002/) - sec. 11 - v1.2.6
35
35
 
36
36
  ---
37
37
 
38
- ## Verify it in one command — no trust required
38
+ ## Verify it in one command -- no trust required
39
39
 
40
40
  ```console
41
41
  $ pip install rttp
42
42
  $ python -m rttp.selftest
43
- rttp 1.2.6 self-test
43
+ rttp 1.2.7 self-test
44
44
  python 3.14.2 on win32
45
45
  ...
46
- [PASS] all 53 checks passed
46
+ [PASS] all 80 checks passed (3 skipped) # default install: the Ed25519 checks are skipped
47
+
48
+ $ pip install rttp[ed25519]
49
+ $ python -m rttp.selftest
50
+ rttp 1.2.7 self-test
51
+ python 3.14.2 on win32
52
+ ...
53
+ [PASS] all 83 checks passed # with the optional Ed25519 backend
47
54
  ```
48
55
 
49
56
  That is the point of this package. A specification is worth exactly what an
50
- independent implementation can reproduce from it — so instead of asking you to
51
- believe a table of numbers, this ships the vectors and replays them locally:
52
-
53
- * **25 conformance checks** — `rttp://` parsing, fail-closed rejections, and the
54
- URI → `ROUTE_SHARD` → 128-byte frame chain, bit for bit.
55
- * **2 RFC 8032 checks** — the Ed25519 backend is shown to be *standard* Ed25519,
57
+ independent implementation can reproduce from it -- so instead of asking you to
58
+ believe a table of numbers, this ships the vectors and replays them locally.
59
+ The 83 checks below are the full set, i.e. with the optional Ed25519 backend
60
+ installed; a default install runs 80 checks and skips 3.
61
+
62
+ * **38 conformance checks** -- `rttp://` parsing, fail-closed rejections, and the
63
+ URI -> `ROUTE_SHARD` -> 128-byte frame chain, bit for bit.
64
+ * **2 RFC 8032 checks** -- the Ed25519 backend is shown to be *standard* Ed25519,
56
65
  not a lookalike, so a failure tells you which half broke.
57
- * **22 envelope checks** — round-trip, self-certification, freshness, and a
58
- 14-case tamper matrix where every alteration must be rejected.
59
- * **4 zero-dependency checks** — a static scan proving the core imports nothing
66
+ * **38 envelope checks** -- 16 rule-layer checks that need no primitive, plus
67
+ round-trip, self-certification, freshness and a 14-case tamper matrix where
68
+ every alteration must be rejected.
69
+ * **5 zero-dependency checks** -- a static scan proving the core imports nothing
60
70
  outside the standard library.
61
71
 
62
- Offline. No account. No network. `[PASS]` or it is not.
72
+ Offline. No account. No network. `[PASS]` or it is not. Every vector file shipped here is listed in `vectors.manifest.json` with its byte count and SHA-256, produced by a generator rather than typed by hand - recompute the hash yourself if you prefer.
63
73
 
64
74
  ---
65
75
 
@@ -73,7 +83,7 @@ pip install rttp[ed25519] # + sovereign-profile seals (Ed25519)
73
83
  Python 3.9+. No compiled extensions in the core.
74
84
 
75
85
  The core deliberately has **no dependencies**. A protocol reference that cannot be
76
- read without resolving a dependency tree is not much of a reference — and an
86
+ read without resolving a dependency tree is not much of a reference -- and an
77
87
  air-gapped reviewer should be able to check the frames.
78
88
 
79
89
  ---
@@ -82,13 +92,13 @@ air-gapped reviewer should be able to check the frames.
82
92
 
83
93
  | Module | What it does | Authority |
84
94
  |:---|:---|:---|
85
- | `rttp.pulse_header` | `PulseHeader128` codec — build / parse / verify the 128-byte hardware-aligned header, including the v1.2.6 extension block at `0x66`–`0x7F` | RFC-002 §4.1 + `SPEC/RTTP-FRAME-EXT-v1.2.6.md` |
86
- | `rttp.rttp_uri` | Validate, canonicalise and derive `ROUTE_SHARD` from an `rttp` URI | RFC-002 §10.2 / §10.3 ABNF |
87
- | `rttp.seal` | **Managed profile** — symmetric HMAC-SHA256 over a pre-shared key table | — |
88
- | `rttp.seal_asym` | **Sovereign profile** — Ed25519, self-certifying, no issuance and no registry | `SPEC/RTTP-SEAL-ENVELOPE-v1.2.6.md` (draft) |
95
+ | `rttp.pulse_header` | `PulseHeader128` codec -- build / parse / verify the 128-byte hardware-aligned header, including the v1.2.6 extension block at `0x66`-`0x7F` | RFC-002 sec. 4.1 + `SPEC/RTTP-FRAME-EXT-v1.2.6.md` |
96
+ | `rttp.rttp_uri` | Validate, canonicalise and derive `ROUTE_SHARD` from an `rttp` URI | RFC-002 sec. 10.2 / sec. 10.3 ABNF |
97
+ | `rttp.seal` | **Managed profile** -- symmetric HMAC-SHA256 over a pre-shared key table | -- |
98
+ | `rttp.seal_asym` | **Sovereign profile** -- Ed25519, self-certifying, no issuance and no registry | `SPEC/RTTP-SEAL-ENVELOPE-v1.2.6.md` (draft) |
89
99
  | `rttp.aid` | Autonomous Identity derivation | RFC-001 |
90
100
 
91
- Plus `rttp.vectors` — the published conformance vectors, shipped inside the wheel
101
+ Plus `rttp.vectors` -- the published conformance vectors, shipped inside the wheel
92
102
  so the self-test works from an installed package with no repository checkout.
93
103
 
94
104
  ---
@@ -106,9 +116,9 @@ parsed["action"] # 'verify'
106
116
  parsed["route_shard"].hex() # 16-byte routing hash, pure computation
107
117
  ```
108
118
 
109
- Addressing is **DNS-free** (RFC-002 §10.5): the routing hash is derived from the
119
+ Addressing is **DNS-free** (RFC-002 sec. 10.5): the routing hash is derived from the
110
120
  authority by SHA-256, so no registry, resolver or network is involved. Malformed
111
- input is rejected rather than normalised — a case variant is not a spelling
121
+ input is rejected rather than normalised -- a case variant is not a spelling
112
122
  difference, it is a different string.
113
123
 
114
124
  ### Build a frame from a URI
@@ -126,9 +136,9 @@ len(raw) # 128
126
136
  pulse_header.verify(raw)["action"] # 'verify'
127
137
  ```
128
138
 
129
- `build_for_uri` performs the mapping RFC-002 §10.4 promises: the URI's authority
139
+ `build_for_uri` performs the mapping RFC-002 sec. 10.4 promises: the URI's authority
130
140
  becomes `ROUTE_SHARD`, its path becomes `ACTION`. Readers that only understand
131
- `0x00`–`0x65` keep working — the extension block occupies bytes that were already
141
+ `0x00`-`0x65` keep working -- the extension block occupies bytes that were already
132
142
  zero, and `VERSION_ID` stays 130.
133
143
 
134
144
  ### Seal with your own identity
@@ -152,7 +162,7 @@ credentials to obtain, and no operator who could refuse to issue them.
152
162
 
153
163
  ## Two profiles, and when each applies
154
164
 
155
- | | **Managed** — `seal` | **Sovereign** — `seal_asym` |
165
+ | | **Managed** -- `seal` | **Sovereign** -- `seal_asym` |
156
166
  |:---|:---|:---|
157
167
  | Primitive | HMAC-SHA256 | Ed25519 |
158
168
  | Key material | pre-shared table | self-generated |
@@ -161,7 +171,7 @@ credentials to obtain, and no operator who could refuse to issue them.
161
171
  | A stranger can participate | no | **yes** |
162
172
  | One leaked key | can forge any peer | forges one identity |
163
173
 
164
- Inside a set of symmetric secrets there is no such thing as a stranger — whoever
174
+ Inside a set of symmetric secrets there is no such thing as a stranger -- whoever
165
175
  holds the shared key can mint anybody's seal. The managed profile is therefore for
166
176
  a closed organism, where a fixed set of roles genuinely do trust each other.
167
177
 
@@ -170,19 +180,19 @@ preference; it is the difference between a private system and a public one.
170
180
 
171
181
  ---
172
182
 
173
- ## Scope — what this package is not
183
+ ## Scope -- what this package is not
174
184
 
175
185
  | | |
176
186
  |:---|:---|
177
- | ✅ **Framing** | Real, and specified. |
178
- | ✅ **Addressing** | Real, and specified. |
179
- | ✅ **Sealing** | Real, and specified (draft). |
180
- | ❌ **Transport** | **Not here.** This package encodes, addresses and seals. It does not open sockets, and there is no `send()` — a client and its transport belong to a separate package, so that the codec stays dependency-free and auditable. |
181
- | ❌ **Routing service** | Not here. `ROUTE_SHARD` is computed locally; delivering a frame to that hash is an operator's job, not the codec's. |
182
- | ❌ **Confidentiality** | Signing is not encryption. |
187
+ | OK **Framing** | Real, and specified. |
188
+ | OK **Addressing** | Real, and specified. |
189
+ | OK **Sealing** | Real, and specified (draft). |
190
+ | NO **Transport** | **Not here.** This package encodes, addresses and seals. It does not open sockets, and there is no `send()` -- a client and its transport belong to a separate package, so that the codec stays dependency-free and auditable. |
191
+ | NO **Routing service** | Not here. `ROUTE_SHARD` is computed locally; delivering a frame to that hash is an operator's job, not the codec's. |
192
+ | NO **Confidentiality** | Signing is not encryption. |
183
193
 
184
194
  **The seal is an envelope around the frame, not bytes inside it.** A reader that
185
- parses only the 128-byte header sees no seal at all — which is why the two
195
+ parses only the 128-byte header sees no seal at all -- which is why the two
186
196
  concerns are specified separately.
187
197
 
188
198
  Unknown revisions, algorithms and malformed input **fail closed** everywhere.
@@ -193,7 +203,7 @@ Nothing in this package is ever accepted because a check could not be performed.
193
203
  ## Conformance vectors
194
204
 
195
205
  `rttp/vectors/rttp-conformance-v1.2.6.json` is generated, not hand-edited. Each
196
- vector is deterministic: fixed sequence numbers, fixed timestamp, fixed AID — so
206
+ vector is deterministic: fixed sequence numbers, fixed timestamp, fixed AID -- so
197
207
  two implementations either agree byte for byte or they do not.
198
208
 
199
209
  The vector set is the intended deliverable for third-party certification: pass it
@@ -207,21 +217,21 @@ needing to trust the authors.
207
217
  | Ecosystem | Name | Status |
208
218
  |:---|:---|:---|
209
219
  | crates.io | `rttp` | held by this project |
210
- | PyPI | `rttp` | **this package** — `pip install rttp` |
211
- | npm | **`@aicent/rttp`** | the unscoped `rttp` name on npm is held by an unrelated, unmaintained 2017 REST helper, and the `rttp` scope cannot be created at all — a personal account already holds that name — so the JavaScript side is published under this project's own organization. The package name itself is still just `rttp` |
220
+ | PyPI | `rttp` | **this package** -- `pip install rttp` |
221
+ | npm | **`@aicent/rttp`** | the unscoped `rttp` name on npm is held by an unrelated, unmaintained 2017 REST helper, and the `rttp` scope cannot be created at all -- a personal account already holds that name -- so the JavaScript side is published under this project's own organization. The package name itself is still just `rttp` |
212
222
 
213
223
  ---
214
224
 
215
225
  ## Specification status
216
226
 
217
- * **`rttp` URI scheme** — submitted to IANA under RFC 7595, ticket **#1459939**,
227
+ * **`rttp` URI scheme** -- submitted to IANA under RFC 7595, ticket **#1459939**,
218
228
  Provisional (First Come, First Served), **under review**. It is **not yet
219
- registered** — as of 2026-09-15 the IANA URI Schemes registry contains no
229
+ registered** -- as of 2026-09-15 the IANA URI Schemes registry contains no
220
230
  `rttp` entry. Please describe it that way.
221
- * **Frame layout** — RFC-002 §4.1, extended by `SPEC/RTTP-FRAME-EXT-v1.2.6.md`.
222
- * **Seal envelope** — `SPEC/RTTP-SEAL-ENVELOPE-v1.2.6.md`, a **draft**: the format
231
+ * **Frame layout** -- RFC-002 sec. 4.1, extended by `SPEC/RTTP-FRAME-EXT-v1.2.6.md`.
232
+ * **Seal envelope** -- `SPEC/RTTP-SEAL-ENVELOPE-v1.2.6.md`, a **draft**: the format
223
233
  is implemented and vector-tested, but it is not yet a numbered RFC-002 section.
224
- * **Managed profile** — implementation only; it predates the sovereign profile and
234
+ * **Managed profile** -- implementation only; it predates the sovereign profile and
225
235
  has no standalone specification.
226
236
 
227
237
  Where this package and a specification disagree, **the specification wins and the