@aicent/iqa 1.2.8 → 1.3.2

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.
package/README.md CHANGED
@@ -1,258 +1,298 @@
1
- # @aicent/iqa
2
-
3
- **IQA for JavaScript: `iqa://` subject-attestation addressing, `IQA_ROUTE`
4
- derivation, action safety classes -- and the published conformance vectors that
5
- prove an implementation is right.**
6
-
7
- [RFC-009 sec. 10](https://iqa.org/RFC-009/) - sec. 11 - stack v1.2.6 - zero dependencies - no build step
8
-
9
- ---
10
-
11
- ## Verify it in one command -- no trust required
12
-
13
- ```console
14
- $ npx @aicent/iqa
15
- [PASS] all 32 checks passed
16
- ```
17
-
18
- That is the point of this package. A specification is worth exactly what an
19
- independent implementation can reproduce from it, so instead of asking you to
20
- believe a table of numbers, the vectors ship inside the package and replay
21
- locally -- 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.
22
-
23
- The vectors cover the `iqa://` grammar (RFC-009 sec. 10.2), the **closed sets**
24
- (`organ` and `action` -- the deliberate difference from `rttp`, whose verb set
25
- is open), the sec. 11.3 action safety classes, the `IQA_ROUTE` derivation, **and**
26
- the deterministic Ed25519 attestation envelope -- replayed by both
27
- implementations.
28
-
29
- ### The other half -- Python, on PyPI
30
-
31
- ```console
32
- $ pip install iqa-org
33
- $ python -m iqa.selftest
34
- [PASS] all 75 checks passed (3 skipped) # default install
35
-
36
- $ pip install iqa-org[ed25519]
37
- $ python -m iqa.selftest
38
- [PASS] all 78 checks passed # with the optional Ed25519 backend
39
- ```
40
-
41
- Published as **`@aicent/iqa`** -- the bare `iqa` name is unregistered on npm but
42
- blocked by its typosquatting protection, so the JavaScript side lives under
43
- this project's organization, as `@aicent/rttp` already does. PyPI applies the
44
- same class of guard: the Python package is therefore **`iqa-org`** (same name
45
- as the Rust crate; the import stays `import iqa`). It ships a **byte-identical
46
- copy** of this same vector set (three mirrors, one sha256) and replays it
47
- offline, exactly as this one does: two registries, two languages, one
48
- specification.
49
-
50
- ---
51
-
52
- ## Install
53
-
54
- ```console
55
- npm install @aicent/iqa
56
- ```
57
-
58
- Node 18+. No dependencies, no build step, no transitive tree to audit: the
59
- published `src/` is exactly what runs.
60
-
61
- ---
62
-
63
- ## Quickstart
64
-
65
- ```js
66
- import { parse } from '@aicent/iqa';
67
-
68
- const r = parse('iqa://3f9a1b2c.gateway.iqa');
69
-
70
- r.subject // '3f9a1b2c' -- 8-hex routing short form of the AID
71
- r.organ // 'gateway' -- closed set: forge | tss | gateway
72
- r.action // null -- omitted = standing read (sec. 11.1)
73
- r.action_safe // true -- sec. 11.3: omitted and verify are SAFE
74
- r.canonical_uri // 'iqa://3f9a1b2c.gateway.iqa'
75
- r.route_hex // '5c378581' <- pure computation, pinned by the vectors
76
- ```
77
-
78
- The same lines ship as a runnable file:
79
-
80
- ```console
81
- $ node examples/quickstart.mjs
82
- 5c378581
83
- ```
84
-
85
- Its expected output is the route fingerprint the published conformance vectors
86
- pin for that address, so the example can be **checked** rather than believed.
87
-
88
- Addressing is **DNS-free** (RFC-009 sec. 12 #9): the route fingerprint is derived
89
- from the authority by SHA-256, so no registry, resolver or network is
90
- involved. A URI either yields its fields or throws -- there is no fallback, no
91
- `iqas`, and no rewriting to `https`.
92
-
93
- ---
94
-
95
- ## The two closed sets -- the deliberate difference from `rttp`
96
-
97
- `rttp` accepts any well-formed action verb. **`iqa` does not.** RFC-009 sec. 10.1
98
- marks *both* segments "Closed set", and this package enforces exactly that:
99
-
100
- ```js
101
- parse('iqa://3f9a1b2c.gateway.iqa/pulse') // throws -- 'pulse' is an rttp verb
102
- parse('iqa://3f9a1b2c.forgery.iqa') // throws -- organ is forge|tss|gateway
103
- ```
104
-
105
- ### The one rule that surprises people
106
-
107
- **Malformed input is rejected, not normalised.** `iqa://.../AUDIT`,
108
- `iqa://3F9A1B2C....` and `IQA://...` all throw: the canonical form is lowercase
109
- US-ASCII (RFC-009 sec. 10.3), a case variant is not a spelling difference, and
110
- nothing is ever accepted because a check could not be performed.
111
-
112
- ### One honest quirk of the grammar
113
-
114
- The ABNF is an ordered choice (`hash-subject / name-subject`), so a lowercase
115
- hex string of a **non-hash length** (9 digits, say) is a *name subject*, not
116
- an error. The grammar is the grammar; vector #8 pins the behaviour so every
117
- implementation agrees on it.
118
-
119
- ---
120
-
121
- ## Action safety classes (RFC-009 sec. 11.3)
122
-
123
- | `action` | Class | `action_safe` |
124
- |:---|:---|:---|
125
- | *(omitted)* | SAFE -- standing read | `true` |
126
- | `verify` | SAFE -- read-only comparison | `true` |
127
- | `audit` | NOT SAFE -- can trigger Authority Ischemia | `false` |
128
- | `attest` | NOT SAFE -- state transition | `false` |
129
- | `revoke` | NOT SAFE -- state transition | `false` |
130
-
131
- Per sec. 11.2, dereferencing an `iqa` URI MUST NOT transition any subject's
132
- standing. Tooling built on this package MUST gate the three NOT-SAFE verbs
133
- behind an explicit user action -- parsing one is not requesting one.
134
-
135
- ---
136
-
137
- ## API -- main entry
138
-
139
- | Export | What it does |
140
- |:---|:---|
141
- | `parse(uri)` | Validate, canonicalise, classify, derive. Throws `IqaUriError`. |
142
- | `deriveRoute(authority)` | `Uint8Array(4)` = `SHA-256(ASCII(authority))[0:4]`. |
143
- | `deriveRouteHex(authority)` | The same, as 8 lowercase hex characters. |
144
- | `isValidAction(value)` | sec. 10.1 closed-set test. |
145
- | `IqaUriError` | The only error type thrown. |
146
- | `SCHEME`, `ORGANS`, `ACTIONS`, `STANDINGS`, `HASH_LENGTHS` | Constants. |
147
-
148
- ### The attestation envelope -- `@aicent/iqa/conformance`
149
-
150
- The deterministic Ed25519 envelope (SPEC/IQA-URI-ATTEST-v1.2.6 sec. 5: domain
151
- prefix `iqa-attest-v1`, `AID = SHA-256(pub)`, `ts`/`nonce` inside the
152
- signature, 120-second freshness) is part of the shared vector set and is
153
- replayed by this package's conformance run. `buildSigningInput` is exported
154
- from `./conformance` for implementers of other languages.
155
-
156
- ---
157
-
158
- ## The conformance vectors
159
-
160
- ```js
161
- import { loadVectors, runConformance } from '@aicent/iqa/conformance';
162
-
163
- const { checked, failures, passed } = runConformance(loadVectors());
164
- ```
165
-
166
- Or from the command line:
167
-
168
- ```console
169
- npx @aicent/iqa # replay the shipped vectors
170
- npx @aicent/iqa --vectors ./new.json # replay a different vector set
171
- npx @aicent/iqa --json # machine-readable output
172
- ```
173
-
174
- In CI:
175
-
176
- ```yaml
177
- - run: npx @aicent/iqa
178
- ```
179
-
180
- | Group | Count | What it proves |
181
- |:---|---:|:---|
182
- | `positive_uris` | 8 | Accept, classify and derive -- sec. 10.3's own examples, the 256-bit form, the all-zero boundary, the name-subject fall-through |
183
- | `negative_uris` | 18 | Reject -- uppercase anywhere, `iqas://`, userinfo, port, query, fragment, wrong authority shape, closed-set violations on both segments |
184
- | `action_safety` | 5 | sec. 11.3 classes as data |
185
- | `attest_envelope_vector` | 1 | Deterministic Ed25519 envelope, verified through `node:crypto` |
186
-
187
- `vectors.json` is plain JSON and ships inside the package, also reachable as
188
- the subpath export `@aicent/iqa/vectors.json`. Any language can read it; that
189
- is what it is for.
190
-
191
- ### Why the checker lives in this package, and why that is still honest
192
-
193
- `src/conformance.mjs` is written from RFC-009 sec. 10 alone and **must never
194
- import `src/iqa-uri.mjs`**. A conformance suite that reuses the code under
195
- test only proves the code equals itself. The two files share no code -- one is
196
- a streaming charset scanner, the other a single full-match grammar check -- so
197
- the rule is checkable by reading them.
198
-
199
- The vectors are **generated, not written**. `generated_by` in the JSON names
200
- the generator, and the file says so itself: change the cases in the generator,
201
- not the JSON. Hand-editing a conformance vector is how a specification quietly
202
- starts agreeing with its own bugs.
203
-
204
- ---
205
-
206
- ## Scope -- what this package is not
207
-
208
- | | |
209
- |:---|:---|
210
- | OK **Validation / canonicalisation** | Real, and specified (RFC-009 sec. 10.2 / sec. 10.3). |
211
- | OK **Closed-set enforcement** | Real, and specified (sec. 10.1). |
212
- | OK **IQA_ROUTE derivation** | Real (SPEC sec. 3, decision D1). |
213
- | OK **Action safety classes** | Real, and specified (sec. 11.3). |
214
- | OK **Conformance vectors + independent replay** | Published and generated. |
215
- | NO **Dereferencing / resolver service** | Not here. The codec computes; *answering* a standing read is an Organ's job (RFC-009-C sec. 3). |
216
- | NO **Staking, tiers, vitality** | Operator economics and telemetry -- RFC-009 narrative, no cryptographic object in this package. |
217
- | NO **Post-quantum Lattice Guard** | RFC-009 sec. 12 #11 schedules it for v1.4.0; no implementation exists. |
218
- | NO **Revocation transport** | sec. 11.3 defines the verb; executing it is not the codec's job. |
219
- | NO **Confidentiality** | Signing is not encryption. |
220
-
221
- ---
222
-
223
- ## Naming
224
-
225
- | Ecosystem | Name | Status |
226
- |:---|:---|:---|
227
- | crates.io | **`iqa-org`** | **published** -- `1.2.8-alpha`. Every published version of this crate is a pre-release, so Cargo will not select it from a plain `iqa-org` requirement: write `cargo add iqa-org@1.2.8-alpha`. |
228
- | PyPI | **`iqa-org`** | **published** -- the Python reference implementation; `pip install iqa-org` (bare `iqa` blocked by PyPI's typosquatting protection, same class of guard as npm) |
229
- | npm | **`@aicent/iqa`** | the bare `iqa` name is unregistered but **blocked by npm's typosquatting protection** (too similar to existing short names) -- so this package is published under the organization this project controls, as `@aicent/rttp` already is. The package name itself is still just `iqa`. |
230
-
231
- ---
232
-
233
- ## Specification status
234
-
235
- * **`iqa` URI scheme** -- submitted to IANA under RFC 7595, ticket **#1459963**,
236
- Provisional, **under review**. It is **not yet registered** -- as of
237
- 2026-09-20 the IANA "URI Schemes" registry contains no `iqa` entry. Please
238
- describe it that way.
239
- * **Internet-Draft (IETF)** -- under IETF review as the Individual Submission
240
- Internet-Draft `draft-li-iqa-subject-attestation` (revision -00, posted
241
- 2026-09-20, informational):
242
- https://datatracker.ietf.org/doc/draft-li-iqa-subject-attestation/ .
243
- An Internet-Draft is a working document -- it is not an IETF standard and
244
- carries no IETF endorsement.
245
- * **URI grammar** -- RFC-009 sec. 10.2 (frozen; this package adds no syntax).
246
- * **Dereference safety** -- RFC-009 sec. 11 (closed sets and safety classes).
247
- * **Attestation envelope** -- `SPEC/IQA-URI-ATTEST-v1.2.6.md` sec. 5, a **draft**:
248
- the format is implemented and vector-tested, but it is not yet a numbered
249
- RFC-009 section.
250
-
251
- Where this package and the specification disagree, **the specification wins
252
- and this package is wrong.** Please report it.
253
-
254
- ---
255
-
256
- ## License
257
-
258
- Apache-2.0. See `LICENSE`.
1
+ # @aicent/iqa
2
+
3
+ **IQA for JavaScript: `iqa://` subject-attestation addressing, `IQA_ROUTE`
4
+ derivation, action safety classes, the AE-128 fixed attestation envelope -- and
5
+ the published conformance vectors that prove an implementation is right.**
6
+
7
+ [AICENT-009 sec. 10](https://iqa.org/URI/) - sec. 11 - stack v1.2.6 - zero dependencies - no build step
8
+
9
+ ---
10
+
11
+ ## Verify it in one command -- no trust required
12
+
13
+ ```console
14
+ $ npx @aicent/iqa
15
+ [PASS] all 32 checks passed
16
+
17
+ $ node --test
18
+ # 19 test blocks, 0 fail -- including the AE-128 published vector,
19
+ # replayed byte for byte from the draft's documented parameters
20
+ ```
21
+
22
+ That is the point of this package. A specification is worth exactly what an
23
+ independent implementation can reproduce from it, so instead of asking you to
24
+ believe a table of numbers, the vectors ship inside the package and replay
25
+ locally -- 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.
26
+
27
+ The vectors cover the `iqa://` grammar (AICENT-009 sec. 10.2), the **closed sets**
28
+ (`organ` and `action` -- the deliberate difference from `rttp`, whose verb set
29
+ is open), the sec. 11.3 action safety classes, the `IQA_ROUTE` derivation, **and**
30
+ the deterministic Ed25519 attestation envelope -- replayed by both
31
+ implementations. The AE-128 envelope (normative layout: draft-02 sec. 7.2)
32
+ ships with its own
33
+ published vector and full fail-closed matrix under `@aicent/iqa/envelope`.
34
+
35
+ ### The other half -- Python, on PyPI
36
+
37
+ ```console
38
+ $ pip install iqa-org
39
+ $ python -m iqa.selftest
40
+ [PASS] all 108 checks passed (3 skipped) # default install
41
+
42
+ $ pip install iqa-org[ed25519]
43
+ $ python -m iqa.selftest
44
+ [PASS] all 111 checks passed # with the optional Ed25519 backend
45
+ ```
46
+
47
+ Published as **`@aicent/iqa`** -- the bare `iqa` name is unregistered on npm but
48
+ blocked by its typosquatting protection, so the JavaScript side lives under
49
+ this project's organization, as `@aicent/rttp` already does. PyPI applies the
50
+ same class of guard: the Python package is therefore **`iqa-org`** (same name
51
+ as the Rust crate; the import stays `import iqa`). It ships a **byte-identical
52
+ copy** of this same vector set (three mirrors, one sha256) and replays it
53
+ offline, exactly as this one does: two registries, two languages, one
54
+ specification.
55
+
56
+ ---
57
+
58
+ ## Install
59
+
60
+ ```console
61
+ npm install @aicent/iqa
62
+ ```
63
+
64
+ Node 18+. No dependencies, no build step, no transitive tree to audit: the
65
+ published `src/` is exactly what runs.
66
+
67
+ ---
68
+
69
+ ## Quickstart
70
+
71
+ ```js
72
+ import { parse } from '@aicent/iqa';
73
+
74
+ const r = parse('iqa://3f9a1b2c.gateway.iqa');
75
+
76
+ r.subject // '3f9a1b2c' -- 8-hex routing short form of the AID
77
+ r.organ // 'gateway' -- closed set: forge | tss | gateway
78
+ r.action // null -- omitted = standing read (sec. 11.1)
79
+ r.action_safe // true -- sec. 11.3: omitted and verify are SAFE
80
+ r.canonical_uri // 'iqa://3f9a1b2c.gateway.iqa'
81
+ r.route_hex // '5c378581' <- pure computation, pinned by the vectors
82
+ ```
83
+
84
+ The same lines ship as a runnable file:
85
+
86
+ ```console
87
+ $ node examples/quickstart.mjs
88
+ 5c378581
89
+ ```
90
+
91
+ Its expected output is the route fingerprint the published conformance vectors
92
+ pin for that address, so the example can be **checked** rather than believed.
93
+
94
+ Addressing is **DNS-free** (AICENT-009 sec. 12 #9): the route fingerprint is derived
95
+ from the authority by SHA-256, so no registry, resolver or network is
96
+ involved. A URI either yields its fields or throws -- there is no fallback, no
97
+ `iqas`, and no rewriting to `https`.
98
+
99
+ ---
100
+
101
+ ## The two closed sets -- the deliberate difference from `rttp`
102
+
103
+ `rttp` accepts any well-formed action verb. **`iqa` does not.** AICENT-009 sec. 10.1
104
+ marks *both* segments "Closed set", and this package enforces exactly that:
105
+
106
+ ```js
107
+ parse('iqa://3f9a1b2c.gateway.iqa/pulse') // throws -- 'pulse' is an rttp verb
108
+ parse('iqa://3f9a1b2c.forgery.iqa') // throws -- organ is forge|tss|gateway
109
+ ```
110
+
111
+ ### The one rule that surprises people
112
+
113
+ **Malformed input is rejected, not normalised.** `iqa://.../AUDIT`,
114
+ `iqa://3F9A1B2C....` and `IQA://...` all throw: the canonical form is lowercase
115
+ US-ASCII (AICENT-009 sec. 10.3), a case variant is not a spelling difference, and
116
+ nothing is ever accepted because a check could not be performed.
117
+
118
+ ### One honest quirk of the grammar
119
+
120
+ The ABNF is an ordered choice (`hash-subject / name-subject`), so a lowercase
121
+ hex string of a **non-hash length** (9 digits, say) is a *name subject*, not
122
+ an error. The grammar is the grammar; vector #8 pins the behaviour so every
123
+ implementation agrees on it.
124
+
125
+ ---
126
+
127
+ ## Action safety classes (AICENT-009 sec. 11.3)
128
+
129
+ | `action` | Class | `action_safe` |
130
+ |:---|:---|:---|
131
+ | *(omitted)* | SAFE -- standing read | `true` |
132
+ | `verify` | SAFE -- read-only comparison | `true` |
133
+ | `audit` | NOT SAFE -- can trigger Authority Ischemia | `false` |
134
+ | `attest` | NOT SAFE -- state transition | `false` |
135
+ | `revoke` | NOT SAFE -- state transition | `false` |
136
+
137
+ Per sec. 11.2, dereferencing an `iqa` URI MUST NOT transition any subject's
138
+ standing. Tooling built on this package MUST gate the three NOT-SAFE verbs
139
+ behind an explicit user action -- parsing one is not requesting one.
140
+
141
+ ---
142
+
143
+ ## API -- main entry
144
+
145
+ | Export | What it does |
146
+ |:---|:---|
147
+ | `parse(uri)` | Validate, canonicalise, classify, derive. Throws `IqaUriError`. |
148
+ | `deriveRoute(authority)` | `Uint8Array(4)` = `SHA-256(ASCII(authority))[0:4]`. |
149
+ | `deriveRouteHex(authority)` | The same, as 8 lowercase hex characters. |
150
+ | `isValidAction(value)` | sec. 10.1 closed-set test. |
151
+ | `IqaUriError` | The only error type thrown. |
152
+ | `SCHEME`, `ORGANS`, `ACTIONS`, `STANDINGS`, `HASH_LENGTHS` | Constants. |
153
+
154
+ ### AE-128 -- `@aicent/iqa/envelope`
155
+
156
+ ```js
157
+ import { encode, verify, deriveIntentShard, vector1Frame, VECTOR_1_KEY } from '@aicent/iqa/envelope';
158
+
159
+ const frame = encode({
160
+ key: Buffer.from('the organ key material'),
161
+ intent_shard: deriveIntentShard('f3b2a1c4.pillar.example'),
162
+ organ: 'gateway', standing: 'radiant', // or 0x02
163
+ lease_expiry: 1798761600, nonce: 1,
164
+ });
165
+ frame.length // 128 -- one frame, one datagram
166
+
167
+ const { ok, reason, frame: parsed } = verify(frame, key, { now: 1798761600 - 1 });
168
+ // ok=true -- offline: no issuer contact, no key directory, no network call
169
+ parsed.standing_name // 'radiant'
170
+ ```
171
+
172
+ Fixed offsets, HMAC-SHA256 over the whole frame with the attestation field
173
+ zeroed, standing closed set at offset 80, constant-time compare, zero-parser
174
+ verification. The published vector (`vector1Frame()`) reproduces byte for byte
175
+ against the draft's parameters -- and against the Python and Rust
176
+ implementations, field for field.
177
+
178
+ ### The attestation envelope -- `@aicent/iqa/conformance`
179
+
180
+ The deterministic Ed25519 envelope (SPEC/IQA-URI-ATTEST-v1.2.6 sec. 5: domain
181
+ prefix `iqa-attest-v1`, `AID = SHA-256(pub)`, `ts`/`nonce` inside the
182
+ signature, 120-second freshness) is part of the shared vector set and is
183
+ replayed by this package's conformance run. `buildSigningInput` is exported
184
+ from `./conformance` for implementers of other languages.
185
+
186
+ ---
187
+
188
+ ## The conformance vectors
189
+
190
+ ```js
191
+ import { loadVectors, runConformance } from '@aicent/iqa/conformance';
192
+
193
+ const { checked, failures, passed } = runConformance(loadVectors());
194
+ ```
195
+
196
+ Or from the command line:
197
+
198
+ ```console
199
+ npx @aicent/iqa # replay the shipped vectors
200
+ npx @aicent/iqa --vectors ./new.json # replay a different vector set
201
+ npx @aicent/iqa --json # machine-readable output
202
+ ```
203
+
204
+ In CI:
205
+
206
+ ```yaml
207
+ - run: npx @aicent/iqa
208
+ ```
209
+
210
+ | Group | Count | What it proves |
211
+ |:---|---:|:---|
212
+ | `positive_uris` | 8 | Accept, classify and derive -- sec. 10.3's own examples, the 256-bit form, the all-zero boundary, the name-subject fall-through |
213
+ | `negative_uris` | 18 | Reject -- uppercase anywhere, `iqas://`, userinfo, port, query, fragment, wrong authority shape, closed-set violations on both segments |
214
+ | `action_safety` | 5 | sec. 11.3 classes as data |
215
+ | `attest_envelope_vector` | 1 | Deterministic Ed25519 envelope, verified through `node:crypto` |
216
+
217
+ `vectors.json` is plain JSON and ships inside the package, also reachable as
218
+ the subpath export `@aicent/iqa/vectors.json`. Any language can read it; that
219
+ is what it is for.
220
+
221
+ ### Why the checker lives in this package, and why that is still honest
222
+
223
+ `src/conformance.mjs` is written from AICENT-009 sec. 10 alone and **must never
224
+ import `src/iqa-uri.mjs`**. A conformance suite that reuses the code under
225
+ test only proves the code equals itself. The two files share no code -- one is
226
+ a streaming charset scanner, the other a single full-match grammar check -- so
227
+ the rule is checkable by reading them.
228
+
229
+ The vectors are **generated, not written**. `generated_by` in the JSON names
230
+ the generator, and the file says so itself: change the cases in the generator,
231
+ not the JSON. Hand-editing a conformance vector is how a specification quietly
232
+ starts agreeing with its own bugs.
233
+
234
+ ---
235
+
236
+ ## Scope -- what this package is not
237
+
238
+ | | |
239
+ |:---|:---|
240
+ | OK **Validation / canonicalisation** | Real, and specified (AICENT-009 sec. 10.2 / sec. 10.3). |
241
+ | OK **Closed-set enforcement** | Real, and specified (sec. 10.1). |
242
+ | OK **IQA_ROUTE derivation** | Real (SPEC sec. 3, decision D1). |
243
+ | OK **Action safety classes** | Real, and specified (sec. 11.3). |
244
+ | OK **Conformance vectors + independent replay** | Published and generated. |
245
+ | OK **AE-128 fixed envelope** | Real, and specified (draft-02 sec. 7.2, implemented to the byte). |
246
+ | NO **Dereferencing / resolver service** | Not here. The codec computes; *answering* a standing read is an Organ's job (AICENT-009-C sec. 3). |
247
+ | NO **Staking, tiers, vitality** | Operator economics and telemetry -- AICENT-009 narrative, no cryptographic object in this package. |
248
+ | NO **Post-quantum Lattice Guard** | AICENT-009 sec. 12 #11 schedules it for v1.4.0; no implementation exists. |
249
+ | NO **Revocation transport** | sec. 11.3 defines the verb; executing it is not the codec's job. |
250
+ | NO **Confidentiality** | Signing is not encryption. |
251
+
252
+ ---
253
+
254
+ ## Naming
255
+
256
+ | Ecosystem | Name | Status |
257
+ |:---|:---|:---|
258
+ | crates.io | **`iqa-org`** | **published** -- `1.3.2`; the first formal (non-pre-release) publication of the crate was `1.3.1`; Cargo selects it from a plain `iqa-org` requirement. The earlier `1.2.8-alpha` remains published and is not yanked. |
259
+ | PyPI | **`iqa-org`** | **published** -- the Python reference implementation; `pip install iqa-org` (bare `iqa` blocked by PyPI's typosquatting protection, same class of guard as npm) |
260
+ | npm | **`@aicent/iqa`** | the bare `iqa` name is unregistered but **blocked by npm's typosquatting protection** (too similar to existing short names) -- so this package is published under the organization this project controls, as `@aicent/rttp` already is. The package name itself is still just `iqa`. |
261
+
262
+ ---
263
+
264
+ ## Specification status
265
+
266
+ * **`iqa` URI scheme** -- **registered**: IANA "URI Schemes" registry,
267
+ Provisional, **CRI 28** (2026-10-13), submitted under RFC 7595
268
+ (ticket **#1459963**). (The sibling `rttp` scheme is registered:
269
+ Provisional, CRI 27.)
270
+ * **Internet-Draft (IETF)** -- under IETF review as the combined Individual
271
+ Submission Internet-Draft `draft-li-rttp-iqa-addressing` (revision -02,
272
+ 40 pp., 2026-11-01, informational -- both schemes, one document):
273
+ https://datatracker.ietf.org/doc/draft-li-rttp-iqa-addressing/ .
274
+ TXT sha256 `02491c5a59d1e7471be04e8e0d4933dfc22ce19f9b054ead0aa449d6b4485044`.
275
+ An Internet-Draft is a working document -- it is not an IETF standard and
276
+ carries no IETF endorsement.
277
+ * **Conformance records** -- sealed runs and vector families:
278
+ https://iqa.org/conformance/ ; the published vector sets are pinned at
279
+ https://iqa.org/challenge/ .
280
+ * **URI grammar** -- AICENT-009 sec. 10.2 (frozen; this package adds no syntax).
281
+ * **Dereference safety** -- AICENT-009 sec. 11 (closed sets and safety classes);
282
+ the four-state standing vocabulary is normative since v1.2.9, sec. 11.1.1.
283
+ * **Attestation envelope** -- `SPEC/IQA-URI-ATTEST-v1.2.6.md` sec. 5, a **draft**:
284
+ the format is implemented and vector-tested, but it is not yet a numbered
285
+ AICENT-009 section.
286
+ * **AE-128** -- normative layout: draft-li-rttp-iqa-addressing-02 sec. 7.2
287
+ (incorporated into the I-D; re-anchored 2026-11-09). The companion draft
288
+ v0.3 (`ae128-draft-v0.3.md`) remains the historical parameter sheet.
289
+ Implemented here to the byte against the published vector.
290
+
291
+ Where this package and the specification disagree, **the specification wins
292
+ and this package is wrong.** Please report it.
293
+
294
+ ---
295
+
296
+ ## License
297
+
298
+ Apache-2.0. See `LICENSE`.