@adastracomputing/ink 0.2.0 → 0.3.0

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
@@ -4,7 +4,9 @@
4
4
 
5
5
  An open protocol for AI agents that need to send each other typed, signed messages on the public web. Built for scheduling, introductions, receipts, and other coordination flows where a user delegates an agent to act on their behalf.
6
6
 
7
- **Status: v0.1, experimental.** Wire formats, trust semantics, and APIs may change without backward-compatible migration before v1.0.
7
+ **Status: experimental; current defined wire version `ink/0.2`.** Wire formats, trust semantics, and APIs may change without backward-compatible migration before v1.0. On npm, `latest` is `0.1.2` and `0.2.0` is published on the `next` tag; senders still emit `ink/0.1` by default unless explicitly configured.
8
+
9
+ `ink/0.2` is the recommended target for new receiver implementations. It is a backward-compatible minor over `ink/0.1`, changing only the body-signature domain: the neutral `ink/sign` in place of the legacy `tulpa/sign`, selected from the signed `protocol` field. `ink/0.1` remains fully supported: both are major version 0, and conformant major-0 receivers accept either. There is no plan to drop `ink/0.1` within major 0; any future version sunset follows the [compatibility policy](specs/ink-compatibility-policy.md).
8
10
 
9
11
  | | |
10
12
  |---|---|
@@ -23,7 +25,7 @@ An open protocol for AI agents that need to send each other typed, signed messag
23
25
  - [Agent-assisted implementation](#agent-assisted-implementation)
24
26
  - [Tests](#tests)
25
27
  - [Layout](#layout)
26
- - [What's stable in v0.1](#whats-stable-in-v01)
28
+ - [What's stable](#whats-stable)
27
29
  - [Naming](#naming)
28
30
  - [Relationship to Tulpa](#relationship-to-tulpa)
29
31
  - [Interoperability](#interoperability)
@@ -130,9 +132,9 @@ test/ vitest unit + integration tests
130
132
 
131
133
  The library runs on any runtime providing standard Web Crypto and `fetch`: Node 24+, Deno, Bun, Cloudflare Workers, browsers. The timestamp freshness window is enforced inside `verifyInkAuth`; nonce single-use is enforced when a `NonceStore` is passed (otherwise `checkReplay` must be called separately). Nonce backing storage and its TTL policy are the integrator's choice.
132
134
 
133
- ## What's stable in v0.1
135
+ ## What's stable
134
136
 
135
- Reliable to depend on:
137
+ These hold across major version 0 (both `ink/0.1` and `ink/0.2`). Reliable to depend on:
136
138
 
137
139
  - Envelope structure and signing base
138
140
  - Authorization: signed intent plus Agent Card key set
@@ -30,13 +30,26 @@ export declare function decodePublicKeyMultibase(multibase: string): Uint8Array;
30
30
  * Returns the raw 32-byte public key.
31
31
  */
32
32
  export declare function decodeEncryptionKeyMultibase(multibase: string): Uint8Array;
33
+ /**
34
+ * agentId method prefixes that carry the same key-derived identity. Both encode
35
+ * the identical multibase public key, so they denote the same actor. `tulpa:`
36
+ * is canonical for emission (see deriveAgentId); `ink:` is an accepted inbound
37
+ * alias introduced in ink/0.4. Accept both, emit one.
38
+ */
39
+ export declare const AGENT_ID_KEY_PREFIXES: readonly ["tulpa:", "ink:"];
33
40
  /**
34
41
  * Derive agent ID from a public key.
35
- * Format: tulpa:<multibase-encoded-public-key>
42
+ * Format: tulpa:<multibase-encoded-public-key> (canonical emission).
36
43
  */
37
44
  export declare function deriveAgentId(publicKey: Uint8Array): string;
38
45
  /**
39
46
  * Extract the public key from an agent ID.
40
47
  * Only used for initial key exchange — after that, always resolve via identity store.
48
+ *
49
+ * Accepts either the canonical `tulpa:` prefix or the `ink:` alias (ink/0.4):
50
+ * both carry the identical multibase key, so a signature made with that key
51
+ * verifies regardless of which accepted prefix carried it. The prefix is
52
+ * identity syntax, not signing authority. The multibase tail is decoded the
53
+ * same way for both, so a malformed tail is rejected identically.
41
54
  */
42
55
  export declare function extractPublicKeyFromAgentId(agentId: string): Uint8Array;
@@ -156,9 +156,16 @@ export function decodeEncryptionKeyMultibase(multibase) {
156
156
  }
157
157
  return key;
158
158
  }
159
+ /**
160
+ * agentId method prefixes that carry the same key-derived identity. Both encode
161
+ * the identical multibase public key, so they denote the same actor. `tulpa:`
162
+ * is canonical for emission (see deriveAgentId); `ink:` is an accepted inbound
163
+ * alias introduced in ink/0.4. Accept both, emit one.
164
+ */
165
+ export const AGENT_ID_KEY_PREFIXES = Object.freeze(["tulpa:", "ink:"]);
159
166
  /**
160
167
  * Derive agent ID from a public key.
161
- * Format: tulpa:<multibase-encoded-public-key>
168
+ * Format: tulpa:<multibase-encoded-public-key> (canonical emission).
162
169
  */
163
170
  export function deriveAgentId(publicKey) {
164
171
  return `tulpa:${encodePublicKeyMultibase(publicKey)}`;
@@ -166,13 +173,19 @@ export function deriveAgentId(publicKey) {
166
173
  /**
167
174
  * Extract the public key from an agent ID.
168
175
  * Only used for initial key exchange — after that, always resolve via identity store.
176
+ *
177
+ * Accepts either the canonical `tulpa:` prefix or the `ink:` alias (ink/0.4):
178
+ * both carry the identical multibase key, so a signature made with that key
179
+ * verifies regardless of which accepted prefix carried it. The prefix is
180
+ * identity syntax, not signing authority. The multibase tail is decoded the
181
+ * same way for both, so a malformed tail is rejected identically.
169
182
  */
170
183
  export function extractPublicKeyFromAgentId(agentId) {
171
184
  if (typeof agentId !== "string" || agentId.length === 0 || agentId.length > 512) {
172
185
  throw new Error("Invalid agent ID");
173
186
  }
174
- const prefix = "tulpa:";
175
- if (!agentId.startsWith(prefix)) {
187
+ const prefix = AGENT_ID_KEY_PREFIXES.find((p) => agentId.startsWith(p));
188
+ if (!prefix) {
176
189
  throw new Error("Invalid agent ID format");
177
190
  }
178
191
  return decodePublicKeyMultibase(agentId.slice(prefix.length));
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { signInkMessage, verifyInkSignature, buildSignatureBase, buildAuthHeader, computeMessageHash, computeEventHash, computeAuditMerkleLeafHash, signAuditEvent, verifyAuditEventSignature, signAuditResponse, verifyAuditResponseSignature, verifyAuditEventChain, signAuditQueryResponse, verifyAuditQueryResponseSignature, encryptInkPayload, decryptInkPayload, checkReplay, base64urlEncode, base64urlDecode, hexToBytes, bytesToHex, jcsCanonicalize, MAX_TIMESTAMP_AGE_MS, MAX_FUTURE_TIMESTAMP_MS, } from "./crypto/ink.js";
2
2
  export { signMessage, verifyMessage } from "./crypto/sign.js";
3
3
  export { verifyInkSignatureWithKeys } from "./crypto/multi-key-verify.js";
4
- export { generateKeypair, generateEncryptionKeypair, deriveAgentId, encodePublicKeyMultibase, encodeEncryptionKeyMultibase, decodePublicKeyMultibase, decodeEncryptionKeyMultibase, extractPublicKeyFromAgentId, } from "./crypto/keys.js";
4
+ export { generateKeypair, generateEncryptionKeypair, deriveAgentId, encodePublicKeyMultibase, encodeEncryptionKeyMultibase, decodePublicKeyMultibase, decodeEncryptionKeyMultibase, extractPublicKeyFromAgentId, AGENT_ID_KEY_PREFIXES, } from "./crypto/keys.js";
5
5
  export { fetchAgentCard, extractCandidateKeys, resolveBaseUrl, } from "./discovery/agent-card.js";
6
6
  export { verifyInkAuth, type NonceStore } from "./middleware/ink-auth.js";
7
7
  export { verifyInclusionReceipt, verifyAuditQueryResponse, type InclusionReceipt, type InclusionReceiptVerifyResult, type AuditQueryResponse, type AuditQueryResponseVerifyResult, type VerifyStep, } from "./audit/inclusion-receipt.js";
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  export { signInkMessage, verifyInkSignature, buildSignatureBase, buildAuthHeader, computeMessageHash, computeEventHash, computeAuditMerkleLeafHash, signAuditEvent, verifyAuditEventSignature, signAuditResponse, verifyAuditResponseSignature, verifyAuditEventChain, signAuditQueryResponse, verifyAuditQueryResponseSignature, encryptInkPayload, decryptInkPayload, checkReplay, base64urlEncode, base64urlDecode, hexToBytes, bytesToHex, jcsCanonicalize, MAX_TIMESTAMP_AGE_MS, MAX_FUTURE_TIMESTAMP_MS, } from "./crypto/ink.js";
5
5
  export { signMessage, verifyMessage } from "./crypto/sign.js";
6
6
  export { verifyInkSignatureWithKeys } from "./crypto/multi-key-verify.js";
7
- export { generateKeypair, generateEncryptionKeypair, deriveAgentId, encodePublicKeyMultibase, encodeEncryptionKeyMultibase, decodePublicKeyMultibase, decodeEncryptionKeyMultibase, extractPublicKeyFromAgentId, } from "./crypto/keys.js";
7
+ export { generateKeypair, generateEncryptionKeypair, deriveAgentId, encodePublicKeyMultibase, encodeEncryptionKeyMultibase, decodePublicKeyMultibase, decodeEncryptionKeyMultibase, extractPublicKeyFromAgentId, AGENT_ID_KEY_PREFIXES, } from "./crypto/keys.js";
8
8
  // Discovery: Agent Card fetch + candidate-key extraction
9
9
  export { fetchAgentCard, extractCandidateKeys, resolveBaseUrl, } from "./discovery/agent-card.js";
10
10
  // Middleware: transport-level INK auth
package/docs/maturity.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # Maturity Notice
2
2
 
3
- > INK v0.1 is **experimental**. Wire formats, trust semantics and APIs
4
- > may change without backward-compatible migration before v1.0. Do not
5
- > use for load-bearing production traffic without your own review.
3
+ > INK is **experimental**. The current defined wire version is `ink/0.2`, a
4
+ > backward-compatible minor over `ink/0.1` (both major version 0). Wire formats,
5
+ > trust semantics and APIs may change without backward-compatible migration
6
+ > before v1.0. Do not use for load-bearing production traffic without your own
7
+ > review.
6
8
 
7
9
  ## What "experimental" means here
8
10
 
@@ -12,8 +14,8 @@
12
14
  agent-card fetch, and DoS-amplification surfaces. Internal review is
13
15
  not a substitute for a third-party audit, treat the security
14
16
  posture accordingly.
15
- - Interop vectors (`../test-vectors/`) are authoritative for v0.1 but may
16
- be added to or revised between v0.1 patch releases. Mismatched
17
+ - Interop vectors (`../test-vectors/`) are authoritative for the current wire
18
+ version but may be added to or revised between patch releases. Mismatched
17
19
  implementations should report discrepancies as issues.
18
20
  - The protocol is in use by one production integrator (Tulpa). That is
19
21
  one data point, not a guarantee of robustness at scale.
@@ -22,7 +24,9 @@
22
24
  Bun, and edge runtimes. Browser use is feasible but not exercised by
23
25
  the maintainers.
24
26
 
25
- ## What is stable in v0.1
27
+ ## What is stable
28
+
29
+ These hold across major version 0 (`ink/0.1` and `ink/0.2`):
26
30
 
27
31
  - Envelope structure (fields, canonicalization with JCS / RFC 8785)
28
32
  - Ed25519 signing base: `ink/0.1\nMETHOD\nPATH\nrecipientDid\nJCS(body)\ntimestamp`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adastracomputing/ink",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Library and specification for the INK (Inter-agent Networking Kernel) protocol",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "author": "Ad Astra Computing Inc.",
@@ -61,12 +61,12 @@
61
61
  "zod": "^4.4.3"
62
62
  },
63
63
  "devDependencies": {
64
- "@cloudflare/workers-types": "^4.20260418.1",
64
+ "@cloudflare/workers-types": "^4.20260604.1",
65
65
  "@types/node": "^24.12.4",
66
- "@typescript-eslint/eslint-plugin": "^8.60.0",
66
+ "@typescript-eslint/eslint-plugin": "^8.60.1",
67
67
  "@typescript-eslint/parser": "^8.60.0",
68
- "eslint": "^10.4.0",
69
- "tsx": "^4.22.3",
68
+ "eslint": "^10.4.1",
69
+ "tsx": "^4.22.4",
70
70
  "typescript": "^6.0.3",
71
71
  "vitest": "^4.1.7"
72
72
  },
@@ -1,7 +1,8 @@
1
1
  # INK Agent Containment and Governance Extension v0.1
2
2
 
3
- ## Status
4
- Draft
3
+ **Status:** Draft
4
+ **Authors:** Ad Astra Computing
5
+ **Last updated:** 2026-05-24
5
6
 
6
7
  ## Purpose
7
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Status:** Draft
4
4
  **Authors:** Ad Astra Computing
5
- **Date:** 2026-03-19
5
+ **Last updated:** 2026-06-01
6
6
 
7
7
  ## Problem
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Status:** Draft
4
4
  **Authors:** Ad Astra Computing
5
- **Date:** 2026-03-19
5
+ **Last updated:** 2026-05-24
6
6
 
7
7
  ## Problem
8
8
 
@@ -1,7 +1,8 @@
1
1
  # INK Compatibility and Versioning Policy
2
2
 
3
- ## Status
4
- Draft, v1 stabilization
3
+ **Status:** Draft, v1 stabilization
4
+ **Authors:** Ad Astra Computing
5
+ **Last updated:** 2026-05-24
5
6
 
6
7
  ## Purpose
7
8
 
@@ -15,7 +16,7 @@ This is the normative compatibility contract. Any change to the INK wire format
15
16
 
16
17
  INK uses a single protocol version string in every message envelope, receipt, audit event and handshake message.
17
18
 
18
- Current version: `ink/0.1`
19
+ Defined versions: `ink/0.1` (default) and `ink/0.2` (negotiated). See [§1.4](#14-defined-wire-versions).
19
20
 
20
21
  The version string appears in the `protocol` field of every top-level INK object and in the first line of every signature base.
21
22
 
@@ -48,6 +49,17 @@ prefix (e.g. `network.ink.*`) and define a transition policy. Until then,
48
49
  conforming implementations MUST emit and accept `network.tulpa.*` types as
49
50
  specified.
50
51
 
52
+ ### 1.4 Defined wire versions
53
+
54
+ Two wire versions are defined:
55
+
56
+ - `ink/0.1`, the original version. A sender emits it by default unless it has positively negotiated otherwise.
57
+ - `ink/0.2`, a backward-compatible minor that changes only the body-signature domain separator, from the legacy `tulpa/sign\n` to the neutral `ink/sign\n`. Everything else, the transport-auth signature base, the envelope shape, the encryption and audit sub-protocols and every `network.tulpa.*` type, is identical to `ink/0.1`.
58
+
59
+ `ink/0.2` is receiver-first. A receiver advertises the versions it verifies in its Agent Card `supportedProtocolVersions` array; when that field is absent a sender MUST assume `ink/0.1` only, and a sender MUST NOT emit `ink/0.2` to a receiver that has not advertised it. The negotiation is what keeps the change compatible: an `ink/0.1`-only receiver never receives `ink/0.2` traffic, so it is never asked to verify a domain it does not implement. An `ink/0.2` receiver selects the body-signature domain from the signed `protocol` field and verifies both versions, and because `protocol` is inside the signed body a relabelled message fails verification.
60
+
61
+ This satisfies §1.1. The minor bump adds a capability without breaking deployed `ink/0.1` implementations, because the body-signature domain is negotiated rather than assumed.
62
+
51
63
  ---
52
64
 
53
65
  ## 2. Compatibility Rules
@@ -1,7 +1,8 @@
1
1
  # INK v0.1 Compliance Checklist and Implementation Matrix
2
2
 
3
- ## Status
4
- Draft, v0.1 alpha conformance
3
+ **Status:** Draft, v0.1 alpha conformance
4
+ **Authors:** Ad Astra Computing
5
+ **Last updated:** 2026-05-27
5
6
 
6
7
  ## Purpose
7
8
 
@@ -1,7 +1,8 @@
1
1
  # INK Containment Phase 1, Implementation Spec
2
2
 
3
- ## Status
4
- Draft
3
+ **Status:** Draft
4
+ **Authors:** Ad Astra Computing
5
+ **Last updated:** 2026-06-01
5
6
 
6
7
  ## Purpose
7
8
 
@@ -1,10 +1,8 @@
1
1
  # INK Introduction Receipts Extension v0.1
2
2
 
3
- ## Status
4
- Draft
5
-
6
- ## Last Updated
7
- 23 March 2026
3
+ **Status:** Draft
4
+ **Authors:** Ad Astra Computing
5
+ **Last updated:** 2026-05-24
8
6
 
9
7
  ## Purpose
10
8
 
@@ -1,7 +1,8 @@
1
1
  # INK Key Rotation Specification v0.1
2
2
 
3
- ## Status
4
- Draft
3
+ **Status:** Draft
4
+ **Authors:** Ad Astra Computing
5
+ **Last updated:** 2026-05-24
5
6
 
6
7
  ## Purpose
7
8