@adastracomputing/ink 0.1.1 → 0.1.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/CHANGELOG.md +27 -0
- package/README.md +27 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,8 +8,35 @@ here. Pre-1.0 releases follow `0.Y.Z` semantics, see
|
|
|
8
8
|
|
|
9
9
|
No unreleased changes.
|
|
10
10
|
|
|
11
|
+
## 0.1.2, Python interop CLI emits canonical envelope
|
|
12
|
+
|
|
13
|
+
> **Maturity note.** v0.1.x is wire-compatible across patches (`ink/0.1` stays frozen) but the API surface and trust semantics remain alpha-quality. See [`docs/maturity.md`](docs/maturity.md). Starting with this release, pre-1.0 versions publish under npm's `next` dist-tag; `latest` only advances when a release is explicitly promoted. Adopters who want the current pre-1.0 line install with `npm install @adastracomputing/ink@next`; the bare `npm install @adastracomputing/ink` will resolve to the most recent release a maintainer has stamped adopter-grade.
|
|
14
|
+
|
|
15
|
+
Fixes the v0.1.1 erratum: the Python `examples/interop-cli/` shipped in v0.1.1 emitted a phantom envelope shape (`type`, `intentType`, `purpose`, `urgency` at top level, no `id`, no `correlationId`, no `createdAt`, no body-level `signature`) that no conforming receiver could accept. v0.1.2 rewrites the CLI's envelope builder to emit the canonical `MessageEnvelopeSchema` shape:
|
|
16
|
+
|
|
17
|
+
- `id` and `correlationId` are now generated as 26-char Crockford-base32 ULIDs.
|
|
18
|
+
- `createdAt` is the canonical envelope creation timestamp (ISO-8601 UTC); the body also carries a separate `timestamp` field that `verifyInkAuth()` uses for HTTP §3.3 freshness, distinct from `createdAt`.
|
|
19
|
+
- `intent` is the canonical enum value (`intro_request` for introductions); the legacy `intentType`/`purpose` flatten into `payload: { target, reason, urgency }` per `IntroRequestPayloadSchema`.
|
|
20
|
+
- Body-level `signature` is now produced by the canonical domain-separated signer (`Ed25519("tulpa/sign\n" + JCS(envelope-without-signature))`, base64url, no padding) — matches `src/crypto/sign.ts` byte-for-byte.
|
|
21
|
+
- `provenance` is omitted when absent (the field is `.optional()`; an explicit `null` would be rejected by Zod).
|
|
22
|
+
- HTTP §3.3 fields (`timestamp`, `nonce`) ride alongside the canonical fields so `verifyInkAuth()` still reads them.
|
|
23
|
+
|
|
24
|
+
**CLI now builds `connection_request` envelopes.** `ink-interop send/build --intent-type connection_request` (or the alias `connection`) constructs a `ConnectionRequestPayloadSchema`-conformant payload (`method`, `context`, `profileSnapshot`). This is the bootstrap intent for first contact between strangers: receivers that opt in to foreign senders verify the body signature against the inline key extracted from the sender's `did:key` (trust-on-first-use). Other intent types (`intro_request`, `ask`, `follow_up`) presume the sender is already a known contact and remain reserved for established relationships.
|
|
25
|
+
|
|
26
|
+
Verified end-to-end against `https://api.tulpa.network/ink/v1/<agentId>/intent`: a `did:key:` `connection_request` from `ink-interop send` lands as a pending action in the recipient's inbox (`status: 200`, `accepted: true`, `pendingActionId: 01KT…`). Coverage spans schema validation, body + transport signature verification, replay/freshness, identity resolution, routing, the foreign-DID policy gate, and shield risk-scoring. Tests pinned to the canonical shape (`tests/test_envelope.py`) prevent regression. The npm library itself is unchanged from v0.1.1.
|
|
27
|
+
|
|
28
|
+
**Example-helper API break.** `examples/interop-cli/`'s Python helper `build_intent_envelope()` now requires `keypair`, replaces `intent_type`/`purpose`/`timestamp` with canonical args (`target`, `reason`, `created_at`, etc.), and removes the `extra=` kwarg. Adopters who imported the old helper directly will need to update their calls — the previous signature emitted invalid wire data so no callable interop existed there to preserve. This is an example-only change; the npm library (`@adastracomputing/ink`) exports are unchanged.
|
|
29
|
+
|
|
11
30
|
## 0.1.1, discovery rename and normative SSRF floor
|
|
12
31
|
|
|
32
|
+
> **Erratum, 2026-06-01:** the bundled Python interop CLI at
|
|
33
|
+
> `examples/interop-cli/` shipped with this tag emits an envelope
|
|
34
|
+
> shape that does not match the canonical `MessageEnvelopeSchema`
|
|
35
|
+
> (`id`, `correlationId`, `createdAt`, `intent` enum, payload,
|
|
36
|
+
> body-level `signature`). The npm library is unaffected. End-to-end
|
|
37
|
+
> sends from the Python CLI to a conforming receiver fail with
|
|
38
|
+
> `invalid_envelope`. Fixed in v0.1.2.
|
|
39
|
+
|
|
13
40
|
This release is **wire-compatible with v0.1.0**; the wire version stays `ink/0.1`. Every change below is additive and accepts the prior shape for the duration of the v0.1.x line — implementations that emit and consume v0.1.0 cards / service entries continue to interoperate. One observable library behavior changes: the runtime emit value of the redacted Agent Card `type` field flips from `"tulpa.agent.card"` to `"ink.agent.card"` (see below). Consumers that pinned to the literal must accept either string; the TypeScript union has been widened accordingly.
|
|
14
41
|
|
|
15
42
|
**Service entry rename.** The DID Document service entry for INK endpoints is now `type: "INKAgentEndpoint"`. The legacy `"TulpaAgentEndpoint"` is still accepted by consumers during v0.1.x; new publishers SHOULD emit `INKAgentEndpoint`. When both are present, `INKAgentEndpoint` takes precedence. Removed at the next wire-version bump.
|
package/README.md
CHANGED
|
@@ -10,17 +10,34 @@ An open protocol for AI agents that need to send each other typed, signed messag
|
|
|
10
10
|
|---|---|
|
|
11
11
|
| Spec | [`specs/`](specs/) |
|
|
12
12
|
| Docs | [ink.tulpa.network](https://ink.tulpa.network) |
|
|
13
|
+
| npm | [`@adastracomputing/ink`](https://www.npmjs.com/package/@adastracomputing/ink) |
|
|
13
14
|
| Contributing | [`CONTRIBUTING.md`](CONTRIBUTING.md) |
|
|
14
15
|
| Security | [`SECURITY.md`](SECURITY.md) |
|
|
15
16
|
| Code of Conduct | [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) |
|
|
16
17
|
| Changelog | [`CHANGELOG.md`](CHANGELOG.md) |
|
|
17
18
|
|
|
19
|
+
## Contents
|
|
20
|
+
|
|
21
|
+
- [What's in the envelope](#whats-in-the-envelope)
|
|
22
|
+
- [Install](#install)
|
|
23
|
+
- [Agent-assisted implementation](#agent-assisted-implementation)
|
|
24
|
+
- [Tests](#tests)
|
|
25
|
+
- [Layout](#layout)
|
|
26
|
+
- [What's stable in v0.1](#whats-stable-in-v01)
|
|
27
|
+
- [Naming](#naming)
|
|
28
|
+
- [Relationship to Tulpa](#relationship-to-tulpa)
|
|
29
|
+
- [Interoperability](#interoperability)
|
|
30
|
+
- [Security](#security)
|
|
31
|
+
- [License](#license)
|
|
32
|
+
|
|
18
33
|
## What's in the envelope
|
|
19
34
|
|
|
20
35
|
Every INK message is an Ed25519-signed envelope over a [JCS](https://datatracker.ietf.org/doc/html/rfc8785) (RFC 8785) canonical serialization. The signature base binds the protocol version, HTTP method, request path, recipient DID, body, and timestamp. Replay protection uses a per-sender nonce plus a timestamp freshness window of 5 minutes past and 30 seconds future.
|
|
21
36
|
|
|
22
37
|
Message types cover intents, challenges, resolutions, receipts, audit events, encrypted payloads, and authenticated agent-card queries. Handshake messages carry a correlation ID; audit and receipt messages do not. Key rotation is governed by an authority rule documented in [`docs/key-rotation-rule.md`](docs/key-rotation-rule.md): the Agent Card's published key set is canonical, revoked keys never verify, and a stale bootstrap key cannot bypass rotation.
|
|
23
38
|
|
|
39
|
+
A foreign sender's first envelope to an unestablished recipient is a `connection_request` — the bootstrap intent for first contact. Receivers that opt in to foreign senders verify the body signature against the inline key extracted from the sender's DID (trust-on-first-use) and SHOULD reject any other intent type from a sender they have no prior relationship with; richer intent types (`intro_request`, `ask`, `follow_up`, `schedule_meeting`) presume the sender is already a known contact. See the [Accepting Foreign Senders guide](https://ink.tulpa.network/guides/accepting-foreign-senders/) for the receive-side rules and [`examples/foreign-sender-receiver/`](examples/foreign-sender-receiver/) for a reference implementation.
|
|
40
|
+
|
|
24
41
|
INK assumes [AT Protocol](https://atproto.com) for identity by default but isn't coupled to it. Any system that can publish an Ed25519 signing key under a stable identifier can participate.
|
|
25
42
|
|
|
26
43
|
## Install
|
|
@@ -49,10 +66,18 @@ const input = {
|
|
|
49
66
|
recipientDid: "tulpa:zRecipient",
|
|
50
67
|
body: {
|
|
51
68
|
protocol: "ink/0.1",
|
|
52
|
-
|
|
69
|
+
id: crypto.randomUUID(),
|
|
70
|
+
correlationId: crypto.randomUUID(),
|
|
71
|
+
createdAt: new Date().toISOString(),
|
|
53
72
|
from: agentId,
|
|
54
73
|
to: "tulpa:zRecipient",
|
|
55
|
-
intent: "
|
|
74
|
+
intent: "schedule_meeting",
|
|
75
|
+
payload: {
|
|
76
|
+
proposedTimes: ["2026-06-15T14:00:00Z"],
|
|
77
|
+
topic: "Quick sync",
|
|
78
|
+
format: "video",
|
|
79
|
+
urgency: "normal",
|
|
80
|
+
},
|
|
56
81
|
timestamp: new Date().toISOString(),
|
|
57
82
|
nonce: crypto.randomUUID(),
|
|
58
83
|
},
|
package/package.json
CHANGED