agentaddress 0.9.1__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.
- agentaddress-0.9.1/.gitignore +20 -0
- agentaddress-0.9.1/CHANGELOG.md +400 -0
- agentaddress-0.9.1/LICENSE +203 -0
- agentaddress-0.9.1/PKG-INFO +498 -0
- agentaddress-0.9.1/README.md +267 -0
- agentaddress-0.9.1/SECURITY.md +17 -0
- agentaddress-0.9.1/demo.py +76 -0
- agentaddress-0.9.1/pyproject.toml +66 -0
- agentaddress-0.9.1/src/aap/__init__.py +327 -0
- agentaddress-0.9.1/src/aap/address.py +88 -0
- agentaddress-0.9.1/src/aap/client.py +455 -0
- agentaddress-0.9.1/src/aap/conversations.py +533 -0
- agentaddress-0.9.1/src/aap/did_web.py +203 -0
- agentaddress-0.9.1/src/aap/discovery.py +356 -0
- agentaddress-0.9.1/src/aap/encryption.py +223 -0
- agentaddress-0.9.1/src/aap/envelope.py +169 -0
- agentaddress-0.9.1/src/aap/envelope_policy.py +133 -0
- agentaddress-0.9.1/src/aap/group_flow.py +128 -0
- agentaddress-0.9.1/src/aap/host_policy.py +58 -0
- agentaddress-0.9.1/src/aap/identity.py +157 -0
- agentaddress-0.9.1/src/aap/inbound.py +205 -0
- agentaddress-0.9.1/src/aap/jcs.py +17 -0
- agentaddress-0.9.1/src/aap/keys.py +74 -0
- agentaddress-0.9.1/src/aap/messages.py +154 -0
- agentaddress-0.9.1/src/aap/payloads.py +771 -0
- agentaddress-0.9.1/src/aap/pending_responses.py +55 -0
- agentaddress-0.9.1/src/aap/relationships.py +514 -0
- agentaddress-0.9.1/src/aap/service_followups.py +367 -0
- agentaddress-0.9.1/src/aap/services.py +456 -0
- agentaddress-0.9.1/src/aap/storage.py +30 -0
- agentaddress-0.9.1/src/aap/stores/__init__.py +1 -0
- agentaddress-0.9.1/src/aap/stores/attestations.py +231 -0
- agentaddress-0.9.1/src/aap/stores/consent.py +73 -0
- agentaddress-0.9.1/src/aap/stores/identity_bindings.py +94 -0
- agentaddress-0.9.1/src/aap/stores/outbound_contacts.py +91 -0
- agentaddress-0.9.1/src/aap/stores/pending_introductions.py +94 -0
- agentaddress-0.9.1/src/aap/stores/pending_proposals.py +159 -0
- agentaddress-0.9.1/src/aap/stores/service_request_groups.py +54 -0
- agentaddress-0.9.1/src/aap/stores/service_requests.py +183 -0
- agentaddress-0.9.1/src/aap/stores/verification_flow.py +118 -0
- agentaddress-0.9.1/src/aap/transport.py +49 -0
- agentaddress-0.9.1/src/aap/trusted_verifiers.py +88 -0
- agentaddress-0.9.1/src/aap/verifier_client.py +363 -0
- agentaddress-0.9.1/src/aap/verifiers.py +372 -0
- agentaddress-0.9.1/src/aap/version.py +1 -0
- agentaddress-0.9.1/tests/__init__.py +0 -0
- agentaddress-0.9.1/tests/test_address.py +138 -0
- agentaddress-0.9.1/tests/test_attestations.py +217 -0
- agentaddress-0.9.1/tests/test_client.py +635 -0
- agentaddress-0.9.1/tests/test_conformance.py +41 -0
- agentaddress-0.9.1/tests/test_consent.py +101 -0
- agentaddress-0.9.1/tests/test_conversations.py +551 -0
- agentaddress-0.9.1/tests/test_did_web.py +128 -0
- agentaddress-0.9.1/tests/test_discovery.py +713 -0
- agentaddress-0.9.1/tests/test_encryption.py +169 -0
- agentaddress-0.9.1/tests/test_envelope.py +377 -0
- agentaddress-0.9.1/tests/test_envelope_policy.py +64 -0
- agentaddress-0.9.1/tests/test_group_flow.py +64 -0
- agentaddress-0.9.1/tests/test_group_payloads.py +178 -0
- agentaddress-0.9.1/tests/test_host_policy.py +68 -0
- agentaddress-0.9.1/tests/test_identity.py +128 -0
- agentaddress-0.9.1/tests/test_identity_bindings.py +83 -0
- agentaddress-0.9.1/tests/test_inbound.py +307 -0
- agentaddress-0.9.1/tests/test_jcs.py +21 -0
- agentaddress-0.9.1/tests/test_keys.py +79 -0
- agentaddress-0.9.1/tests/test_messages.py +218 -0
- agentaddress-0.9.1/tests/test_outbound_contacts.py +81 -0
- agentaddress-0.9.1/tests/test_payloads.py +175 -0
- agentaddress-0.9.1/tests/test_pending_introductions.py +149 -0
- agentaddress-0.9.1/tests/test_pending_proposals.py +115 -0
- agentaddress-0.9.1/tests/test_pending_responses.py +35 -0
- agentaddress-0.9.1/tests/test_relationships.py +435 -0
- agentaddress-0.9.1/tests/test_service_followups.py +377 -0
- agentaddress-0.9.1/tests/test_service_request_groups.py +36 -0
- agentaddress-0.9.1/tests/test_service_requests.py +211 -0
- agentaddress-0.9.1/tests/test_services.py +430 -0
- agentaddress-0.9.1/tests/test_services_payloads.py +312 -0
- agentaddress-0.9.1/tests/test_smoke.py +49 -0
- agentaddress-0.9.1/tests/test_storage.py +65 -0
- agentaddress-0.9.1/tests/test_transport.py +36 -0
- agentaddress-0.9.1/tests/test_trusted_verifiers.py +81 -0
- agentaddress-0.9.1/tests/test_verification_flow.py +208 -0
- agentaddress-0.9.1/tests/test_verification_payloads.py +177 -0
- agentaddress-0.9.1/tests/test_verifier_client.py +402 -0
- agentaddress-0.9.1/tests/test_verifiers.py +517 -0
- agentaddress-0.9.1/tests/vectors/README.md +49 -0
- agentaddress-0.9.1/tests/vectors/envelopes.json +59 -0
- agentaddress-0.9.1/tests/vectors/regenerate.py +110 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.pyc
|
|
3
|
+
.venv/
|
|
4
|
+
.pytest_cache/
|
|
5
|
+
.coverage
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
*.egg-info/
|
|
9
|
+
.DS_Store
|
|
10
|
+
uv.lock
|
|
11
|
+
|
|
12
|
+
# Local agent/session diagnostics
|
|
13
|
+
.aap_*.txt
|
|
14
|
+
.full_msg*.txt
|
|
15
|
+
.ntfy_window.txt
|
|
16
|
+
.peer_search.txt
|
|
17
|
+
.tally_window.txt
|
|
18
|
+
.tool_trace.txt
|
|
19
|
+
.user_msg*.txt
|
|
20
|
+
.claude/
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
### Packaging
|
|
6
|
+
|
|
7
|
+
- Published to PyPI as `agentaddress` (the `aap-python` name was already taken).
|
|
8
|
+
Install with `pip install agentaddress`; the import package remains `aap`.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **End-to-end encrypted AAP envelopes.** `aap.encryption` implements RFC 9180
|
|
13
|
+
HPKE base mode with X25519, HKDF-SHA256, and ChaCha20-Poly1305. Existing
|
|
14
|
+
Ed25519-signed `aap.envelope/v1` JSON is encrypted inside
|
|
15
|
+
`aap.encrypted-envelope/v1`, keeping payloads opaque to relays.
|
|
16
|
+
- **Separate X25519 identity keys.** `IdentityFile` persists an encryption
|
|
17
|
+
keypair alongside the Ed25519 signing keypair and migrates existing identity
|
|
18
|
+
files on load. AgentCards advertise the public key as `encryption_key`.
|
|
19
|
+
- `AAPClient.send_envelope()` and `send_envelope_raw()` encrypt by default.
|
|
20
|
+
`AAPClient.decrypt_inbound()` decrypts relay-delivered encrypted envelopes.
|
|
21
|
+
- Encrypted outbound sends now sign the outer `aap.routing-envelope/v1`
|
|
22
|
+
wrapper with the sender key, binding `from`, `to`, `iat`, `nonce`, and the
|
|
23
|
+
encrypted inner envelope so relays can authenticate and meter the sender
|
|
24
|
+
without decrypting message contents.
|
|
25
|
+
- **Authenticated AgentCard resolution.** `AAPClient` requires the AgentCard
|
|
26
|
+
envelope issuer to equal the requested AAP address, verifies the envelope
|
|
27
|
+
signature with the card's `public_key`, and binds the card's `did:web` domain
|
|
28
|
+
to the requested address domain.
|
|
29
|
+
- **TOFU key-change detection.** AgentCard signing keys are pinned by address in
|
|
30
|
+
memory or in an optional mode-0600 JSON file. Unexpected rotation raises
|
|
31
|
+
`AgentCardKeyChanged` until the caller explicitly clears the pin after
|
|
32
|
+
independently verifying the change.
|
|
33
|
+
- **Envelope freshness/replay policy helpers.** `aap.envelope_policy` adds
|
|
34
|
+
timestamp freshness validation, optional TTL replay caching, and a combined
|
|
35
|
+
signature/freshness verifier for high-risk inbound flows.
|
|
36
|
+
- **Strict inbound receive policy.** `aap.inbound.validate_inbound_envelope()`
|
|
37
|
+
centralizes decrypt-before-verify handling, signature verification,
|
|
38
|
+
freshness checks, and optional replay detection before host dispatch.
|
|
39
|
+
`validate_inbound_chat()` adds chat payload parsing plus active relationship
|
|
40
|
+
authorization.
|
|
41
|
+
- **Service request/response ledger.** `ServiceResponse` now carries its own
|
|
42
|
+
nonce, and `ServiceRequestStore` persists signed outbound requests plus
|
|
43
|
+
verified response proofs for durable request correlation and replay defense.
|
|
44
|
+
- **Signed discovery query responses.** Verifiers now answer discovery queries
|
|
45
|
+
with `aap.discovery-query-response/v1` envelopes bound to the original query
|
|
46
|
+
nonce.
|
|
47
|
+
- **Signed trusted-verifier lists.** Trust-list responses are now
|
|
48
|
+
`aap.trusted-verifiers/v1` envelopes signed by the configured trust root, and
|
|
49
|
+
verifier entries carry the verifier Ed25519 public key.
|
|
50
|
+
- **Signed verifier OTP responses.** Verification start and confirm endpoints
|
|
51
|
+
now return nonce-bound signed envelopes, and confirm responses wrap a verified
|
|
52
|
+
attestation envelope.
|
|
53
|
+
- **Private SDK state writes.** SDK-managed JSON state now writes atomically
|
|
54
|
+
with file mode `0600`.
|
|
55
|
+
|
|
56
|
+
### Security
|
|
57
|
+
|
|
58
|
+
- Configurable relay, verifier, and trust-list endpoints now require HTTPS.
|
|
59
|
+
Plain HTTP is accepted only for loopback development hosts such as
|
|
60
|
+
`localhost`, `127.0.0.1`, and `::1`.
|
|
61
|
+
- AgentCard resolution rejects stale or far-future signed AgentCard envelopes.
|
|
62
|
+
New attestation storage requires a verifier public key, verifies the
|
|
63
|
+
attestation signature, and rejects duplicate verifier nonces.
|
|
64
|
+
- Discovery identity-badge extraction now requires trusted verifier metadata
|
|
65
|
+
and verifier public keys, and returns badges only for signed, trusted,
|
|
66
|
+
unexpired attestations.
|
|
67
|
+
- `TrustListCache` rejects unsigned or wrongly signed trusted-verifier lists
|
|
68
|
+
and persists only the signed envelope. `VerifierPubkeyCache` resolves verifier
|
|
69
|
+
keys from the signed trust list instead of trusting mutable verifier-hosted
|
|
70
|
+
key JSON.
|
|
71
|
+
- `start_sms_verification()` / `start_email_verification()` reject unsigned,
|
|
72
|
+
wrongly signed, wrong-issuer, stale, or nonce-mismatched verifier responses.
|
|
73
|
+
`confirm_sms_verification()` / `confirm_email_verification()` now send signed
|
|
74
|
+
confirm envelopes, verify the signed confirm response, and verify the returned
|
|
75
|
+
`VerificationAttestation` before returning it.
|
|
76
|
+
- Relationship, conversation, verifier, service, replay, attestation, consent,
|
|
77
|
+
pending-verification, and other SDK state files no longer rely on process
|
|
78
|
+
umask for privacy; writes go through a shared private atomic JSON writer.
|
|
79
|
+
- Follow-up grant storage now requires the counterparty public key, verifies
|
|
80
|
+
grant signatures, enforces `env.iss == counterparty`, rejects stale/future
|
|
81
|
+
grants, and rejects duplicate grant nonces.
|
|
82
|
+
- Relationship revocation now requires a signed `aap.relationship-revoke/v1`
|
|
83
|
+
envelope with a nonce. Verified revocations are persisted as proof before the
|
|
84
|
+
active relationship row is removed, and duplicate revoke nonces are rejected.
|
|
85
|
+
- Hosts no longer need to hand-roll inbound chat validation: the SDK exposes a
|
|
86
|
+
receive gate that rejects plaintext by default, verifies the inner signed
|
|
87
|
+
envelope after decryption, and checks active relationship state for chat.
|
|
88
|
+
- `AAPClient.send_envelope_raw()` now validates pre-built protocol envelopes
|
|
89
|
+
before encryption/submission: issuer must equal the client address, signature
|
|
90
|
+
must verify against the client public key, and `iat` must be fresh.
|
|
91
|
+
- Service catalogs are now signed `aap.service-catalog/v1` envelopes. The cache
|
|
92
|
+
verifies the catalog agent, domain binding, signature, and timestamp before
|
|
93
|
+
accepting or persisting a catalog.
|
|
94
|
+
- Discovery query results are accepted only from signed verifier envelopes:
|
|
95
|
+
`query_discovery()` now requires a verifier public-key resolver, verifies the
|
|
96
|
+
expected verifier relay issuer, rejects stale responses, and checks the
|
|
97
|
+
response nonce against the outbound query nonce.
|
|
98
|
+
- Service responses must now match a recorded request, come from the expected
|
|
99
|
+
business, verify against that business key, match the original service id,
|
|
100
|
+
and use a response nonce that has not already been stored.
|
|
101
|
+
- The legacy synchronous `aap.resolve()` helper was removed from the public API.
|
|
102
|
+
AgentCard resolution now goes through `AAPClient.resolve_agent_card()` /
|
|
103
|
+
`resolve_peer()`, which authenticate the card through self-signatures,
|
|
104
|
+
domain binding, and address key pins.
|
|
105
|
+
- The recipient address and delivery metadata remain visible to the relay.
|
|
106
|
+
- HPKE base mode does not provide forward secrecy after compromise of the
|
|
107
|
+
recipient's long-term X25519 private key.
|
|
108
|
+
- Unsigned encrypted routing wrappers should be rejected by relays; encrypted
|
|
109
|
+
delivery requires the authenticated outer routing wrapper above.
|
|
110
|
+
|
|
111
|
+
## v0.9.0 — 2026-06-12 — api subdomain migration + address syntax break
|
|
112
|
+
|
|
113
|
+
Two changes ship together: the api-subdomain relay URL migration and a
|
|
114
|
+
breaking change to the AAP address syntax.
|
|
115
|
+
|
|
116
|
+
### Changed (breaking — address format)
|
|
117
|
+
|
|
118
|
+
- **AAP addresses are now `<localpart>^<domain>` (e.g. `chris^chrisevans.id`).**
|
|
119
|
+
The legacy `agent:<localpart>@<domain>` form is no longer accepted by
|
|
120
|
+
`Address.parse()`. Rationale: the old form was visually
|
|
121
|
+
indistinguishable from email and invited email mental models (DNS MX,
|
|
122
|
+
bounces, etc.); the new form is self-identifying without a strippable
|
|
123
|
+
scheme prefix. **Migration:** replace any literal `agent:X@Y` with `X^Y`. Stored
|
|
124
|
+
addresses must be rewritten out-of-band before upgrading.
|
|
125
|
+
|
|
126
|
+
### Changed
|
|
127
|
+
|
|
128
|
+
- **`DEFAULT_TRUSTED_VERIFIERS_URL`** → `https://api.agentaddress.org/.well-known/aap-trusted-verifiers`
|
|
129
|
+
(`src/aap/verifiers.py`). Callers that don't override
|
|
130
|
+
`AAP_TRUSTED_VERIFIERS_URL` will pick this up automatically on
|
|
131
|
+
upgrade.
|
|
132
|
+
- Test fixtures and example AgentCard endpoints in `README.md` and
|
|
133
|
+
`demo.py` updated to reference `https://api.agentaddress.org`.
|
|
134
|
+
|
|
135
|
+
## v0.8.0 — 2026-06-09 — host-state cleanup
|
|
136
|
+
|
|
137
|
+
Cosmetic and structural cleanup of host-specific naming and one
|
|
138
|
+
behavior change. The F-numbered notes below refer to the internal
|
|
139
|
+
release-readiness review that drove this cleanup.
|
|
140
|
+
|
|
141
|
+
### Removed (breaking for pre-rebrand installs only)
|
|
142
|
+
|
|
143
|
+
- **F1**: deleted the one-time `aap.json → aap.json` rename in
|
|
144
|
+
`aap.identity.load_or_generate`. Users still on a pre-rebrand
|
|
145
|
+
identity file must rename it manually before upgrading; see
|
|
146
|
+
`aap-hermes/INSTALL.md` for the documented step. Resolves the
|
|
147
|
+
env-override ordering side effect (F10) as well.
|
|
148
|
+
|
|
149
|
+
### Changed
|
|
150
|
+
|
|
151
|
+
- **F2, F11**: `aap.identity` module + `IdentityFile` docstrings
|
|
152
|
+
rewritten to host-agnostic phrasing.
|
|
153
|
+
- **F3**: `HERMES_HOME`-by-name disclaimers in `aap.verifiers`,
|
|
154
|
+
`aap.conversations`, and `aap.stores.verification_flow`
|
|
155
|
+
rephrased to generic "no environment lookups" / "host's
|
|
156
|
+
commands layer".
|
|
157
|
+
- **F4**: legacy provider-name parenthetical references in
|
|
158
|
+
`verifier_client.py` and `discovery.py` removed; replaced with
|
|
159
|
+
`TODO(F4)` markers pointing at the spec-promotion roadmap item.
|
|
160
|
+
The legacy `attestation` response-key alias is retained for now
|
|
161
|
+
and will be dropped once the AAP verifier protocol is formalized.
|
|
162
|
+
- **F5**: sibling-repo pointer in `discovery.py` generalized from
|
|
163
|
+
`aap-hermes/discovery.py` to "the host adapter".
|
|
164
|
+
- **F7**: `tests/test_client.py` module docstring corrected to
|
|
165
|
+
describe the AAP relay HTTP client.
|
|
166
|
+
- **F8**: example hostnames updated. README/demo use the reference
|
|
167
|
+
deployment (`relay.agentaddress.org`); tests use RFC 2606
|
|
168
|
+
`.example` hosts (`relay.example`, `verify.example`,
|
|
169
|
+
`bob.example`).
|
|
170
|
+
- **F12**: signed envelope conformance vectors in
|
|
171
|
+
`tests/vectors/envelopes.json` regenerated with the new
|
|
172
|
+
hostnames. Added `tests/vectors/regenerate.py` and
|
|
173
|
+
`tests/vectors/README.md` documenting the regen procedure.
|
|
174
|
+
|
|
175
|
+
### Tests
|
|
176
|
+
|
|
177
|
+
- **F6**: renamed the `tmp_hermes_dir` fixture in
|
|
178
|
+
`tests/test_identity.py` to `tmp_identity_dir`; inner directory
|
|
179
|
+
`hermes_home` → `identity_home`.
|
|
180
|
+
|
|
181
|
+
### Roadmap (no code change)
|
|
182
|
+
|
|
183
|
+
- **F4 (open)**: the verifier wire shapes encoded in
|
|
184
|
+
`verifier_client.py` and `discovery.py` are de-facto a single
|
|
185
|
+
implementation's contract. The agreed direction is to promote
|
|
186
|
+
them to a normative AAP verifier protocol (schemas, conformance
|
|
187
|
+
tests, publication). Scoped as its own initiative.
|
|
188
|
+
|
|
189
|
+
## v0.7.1 — 2026-06-03
|
|
190
|
+
|
|
191
|
+
Domain migration.
|
|
192
|
+
|
|
193
|
+
### Changed
|
|
194
|
+
|
|
195
|
+
- **`DEFAULT_TRUSTED_VERIFIERS_URL`** now points at
|
|
196
|
+
`https://agentaddress.org/.well-known/aap-trusted-verifiers` (was
|
|
197
|
+
`agentcallsign.com`). The reference relay deployment is moving from
|
|
198
|
+
`agentcallsign.com` to `agentaddress.org`; this default tracks it. The
|
|
199
|
+
`AAP_TRUSTED_VERIFIERS_URL` env var still overrides for self-hosted
|
|
200
|
+
trust lists.
|
|
201
|
+
- Test fixtures previously using `agentcallsign.com` as a generic
|
|
202
|
+
address-domain string updated to `agentaddress.org` for consistency.
|
|
203
|
+
|
|
204
|
+
## v0.7.0 — 2026-06-02
|
|
205
|
+
|
|
206
|
+
Promotion from reference codec to full agent SDK. Absorbs protocol + state-store
|
|
207
|
+
layers previously living in `aap-hermes`, so any host (OpenClaw, Hermes, etc.)
|
|
208
|
+
inherits the same machinery.
|
|
209
|
+
|
|
210
|
+
### Added
|
|
211
|
+
|
|
212
|
+
- **`aap.client`** — `AAPClient`, `AAPClientError`, `KeyChangeRejected`. Async HTTP
|
|
213
|
+
client for AAP relays (register, send envelope, poll inbox, resolve peer).
|
|
214
|
+
- **`aap.messages`** — `aap.message/v1` chat payload, `aap.routing-envelope/v1`,
|
|
215
|
+
`build_chat_envelope`, `unwrap_chat_envelope`, `wrap_routing_envelope`.
|
|
216
|
+
- **`aap.host_policy`** — `token_lifetime_days`, `should_auto_renew`, and
|
|
217
|
+
related capability-token policy constants.
|
|
218
|
+
- **`aap.group_flow`** — envelope builders for group-conversation primitives
|
|
219
|
+
(`build_group_invitation_envelope`, `build_group_membership_update_envelope`,
|
|
220
|
+
`build_group_leave_envelope`, `build_group_complete_envelope`). Membership
|
|
221
|
+
update builders now separate the signed issuer from the resulting convener so
|
|
222
|
+
the old convener can sign a handoff to the new convener.
|
|
223
|
+
- **`aap.verifier_client`** — verifier OTP helpers (`start_sms_verification`,
|
|
224
|
+
`confirm_sms_verification`, `start_email_verification`,
|
|
225
|
+
`confirm_email_verification`).
|
|
226
|
+
- **`aap.identity`** — `IdentityFile`, `load_or_generate` for Ed25519 identity
|
|
227
|
+
lifecycle (env / file / generate priority).
|
|
228
|
+
- **`aap.verifiers`** — `TrustListCache`, `VerifierPubkeyCache`,
|
|
229
|
+
`trusted_verifiers_supporting`, `verifier_relay_address`. Path-injected
|
|
230
|
+
fetch + cache layer that complements `aap.trusted_verifiers`'s parser.
|
|
231
|
+
- **`aap.services`** — `ServiceCatalogCache`, `ServiceCatalogPayload`,
|
|
232
|
+
`ServiceDefinition`, `ServiceCatalog`, `ValidationFailure`,
|
|
233
|
+
`validate_service_payload`, `build_service_catalog_envelope`,
|
|
234
|
+
`build_service_request_envelope`, `build_service_response_envelope`.
|
|
235
|
+
Customer↔business protocol surface with signed catalogs and JSON-schema
|
|
236
|
+
validation.
|
|
237
|
+
- **`aap.relationships`** — `RelationshipStore`, `RelationshipRecord`,
|
|
238
|
+
`RelationshipRevocationRecord`, `VALID_RELATIONSHIP_TYPES`, four envelope builders for the
|
|
239
|
+
friend/admin/team handshake. `RelationshipStore.establish()` is the write
|
|
240
|
+
path for records: it verifies proposal/accept signatures, freshness, nonce
|
|
241
|
+
linkage, issuer binding, replay, and embedded AgentCard key/address binding
|
|
242
|
+
before persisting. `RelationshipStore.revoke()` verifies and persists a
|
|
243
|
+
signed revoke envelope before removing an active row.
|
|
244
|
+
- **`aap.service_followups`** — `FollowupGrantStore`, `StoredFollowupGrant`,
|
|
245
|
+
`build_followup_grant_envelope`, `build_followup_envelope`,
|
|
246
|
+
`parse_iso_duration`.
|
|
247
|
+
- **`aap.conversations`** — `Conversation`, `ConversationEventRecord`,
|
|
248
|
+
`ConversationPolicyError`, `ConversationStore`, `broadcast_to_conversation`.
|
|
249
|
+
Group-state receivers should use `accept_invitation()`,
|
|
250
|
+
`apply_membership_update()`, `apply_leave()`, and `apply_complete()`, which
|
|
251
|
+
verify signed envelopes, enforce current-convener authority, validate
|
|
252
|
+
membership diffs/handoffs, and persist event proofs/nonces to reject replay.
|
|
253
|
+
- **`aap.discovery`** — `query_discovery`, `extract_searcher_identities`,
|
|
254
|
+
`build_introduction_response_envelope`.
|
|
255
|
+
- **`aap.pending_responses`** — `PendingResponses` (in-process service-response
|
|
256
|
+
correlation table).
|
|
257
|
+
- **`aap.stores`** subpackage — persistent JSON state stores with `base_dir`
|
|
258
|
+
injection: `AttestationStore`, `PendingProposalStore`, `IdentityBindingStore`,
|
|
259
|
+
`PendingConsent`, `OutboundContactStore`, `PendingVerifications`,
|
|
260
|
+
`PendingIntroductions`, `ServiceRequestGroupIndex`.
|
|
261
|
+
- New runtime dep: `jsonschema>=4.20` (used by `aap.services`).
|
|
262
|
+
|
|
263
|
+
### Changed
|
|
264
|
+
|
|
265
|
+
- Public surface roughly doubled. The v0.6 surface remains fully exported and is
|
|
266
|
+
guarded against regression by `tests/test_smoke.py`.
|
|
267
|
+
|
|
268
|
+
## v0.5.1 — 2026-05-21
|
|
269
|
+
|
|
270
|
+
Small additive release.
|
|
271
|
+
|
|
272
|
+
### Added
|
|
273
|
+
|
|
274
|
+
- **`aap.keys.seed_to_keypair(seed)`**: derive `(seed, public_key)` from a 32-byte Ed25519 seed without dropping down to the `cryptography` library. `generate_keypair()` now delegates to it.
|
|
275
|
+
- **`CatalogEntry.verification_required`** (`dict | None`): capability publishers' `verification_required` metadata is now exposed on `CatalogEntry`, so consumers no longer need to duplicate the parsing in local wrappers.
|
|
276
|
+
|
|
277
|
+
## v0.5.0 — 2026-05-22
|
|
278
|
+
|
|
279
|
+
This release adds the wire-level primitives for verification and discovery. All additive — v0.4 envelopes and AgentCards round-trip identically.
|
|
280
|
+
|
|
281
|
+
### Added
|
|
282
|
+
|
|
283
|
+
- **`VerificationAttestation`** payload (`aap.verification-attestation/v1`): a verifier-signed claim that the verifier challenged the subject and confirmed control of an identity (phone, email, ...). Carries `subject_address`, `identity` (`{"type", "value"}`), `challenge_method`, `verified_at`, `expires_at`, `verifier`, `nonce`.
|
|
284
|
+
- **`DiscoveryIntroductionRequest`** payload (`aap.discovery-introduction-request/v1`): sent by a verifier on a searcher's behalf to ask a recipient whether they want to receive contact. Carries `searcher`, optional `searcher_label_for_recipient`, optional `searcher_attestations`, `verifier_nonce`, `expires_at`.
|
|
285
|
+
- **`DiscoveryIntroductionResponse`** payload (`aap.discovery-introduction-response/v1`): recipient's approve/deny reply, correlated by `verifier_nonce`.
|
|
286
|
+
- **`Envelope.verification_attestations`** (optional `list[str]`): carries one or more serialized attestation envelopes alongside any payload, so recipients can render verified-identity badges without a separate fetch. Included in the JCS-signed form — tampering invalidates the signature. Backward-compatible: omitted from canonical bytes when None/empty.
|
|
287
|
+
- **`trusted_verifiers` module**: parser for the `/.well-known/aap-trusted-verifiers` JSON document, returning `VerifierTrustListEntry` records. Strict on HTTPS: rejects any entry whose `discovery_endpoint`, `verification_endpoint`, or `pubkey_endpoint` is not an `https://` URL. Fetching and caching are left to host implementations.
|
|
288
|
+
|
|
289
|
+
### Changed
|
|
290
|
+
|
|
291
|
+
- **`VerifiedIdentity.value`** is now nullable (`str | None`). AgentCards can carry presence-only indicators (e.g. "this agent has a verified phone") without disclosing the identifier. The previous v0.2 behaviour — `value` carrying the actual phone or email — is preserved when callers populate it.
|
|
292
|
+
|
|
293
|
+
### Spec
|
|
294
|
+
|
|
295
|
+
- See `docs/specs/2026-05-22-aap-verification-and-discovery-design.md` (Rev 1) for the full design.
|
|
296
|
+
|
|
297
|
+
## v0.4.0 — 2026-05-22
|
|
298
|
+
|
|
299
|
+
This release adds group-conversation primitives on top of the v0.3 trust/capability model. Tokens stay strictly 1:1 — groups are a thread-linkage layer above.
|
|
300
|
+
|
|
301
|
+
### Added
|
|
302
|
+
|
|
303
|
+
- **`Envelope.conversation_id`** (optional): opaque string identifier (≤128 chars) that threads messages into a multi-party conversation.
|
|
304
|
+
- **`Envelope.conversation_members`** (optional): list of AAP addresses, length 2–10 inclusive. The sender's declared view of who's in the conversation. Hard-capped at 10 members at the protocol level — `from_dict` rejects envelopes with >10 members.
|
|
305
|
+
- **`GroupInvitation`** payload (`aap.group-invitation/v1`): convener sends this to each prospective member; carries the proposed `members` list, `purpose`, `nonce`. `convener` must be in `members`.
|
|
306
|
+
- **`GroupMembershipUpdate`** payload (`aap.group-membership-update/v1`): convener broadcasts mid-conversation changes (add/remove member, transfer convener role). Carries the full post-update `members` list plus `added`/`removed` deltas.
|
|
307
|
+
- **`GroupLeave`** payload (`aap.group-leave/v1`): any member sends to declare they're exiting. Carries required `nonce` plus optional human-readable `reason`.
|
|
308
|
+
|
|
309
|
+
### Changed
|
|
310
|
+
|
|
311
|
+
- Envelope JCS canonicalization now includes `conversation_id` and `conversation_members` when present. Backward-compatible: envelopes without these fields canonicalize identically to v0.3.
|
|
312
|
+
|
|
313
|
+
### Spec
|
|
314
|
+
|
|
315
|
+
- See `docs/specs/2026-05-22-aap-group-conversations-design.md` (Rev 1) for the full design.
|
|
316
|
+
|
|
317
|
+
### Limits
|
|
318
|
+
|
|
319
|
+
- 10-member cap on groups, enforced at the protocol level. Larger groups need a separate mechanism (group-agent pattern); deferred.
|
|
320
|
+
|
|
321
|
+
## v0.3.0 — 2026-05-22
|
|
322
|
+
|
|
323
|
+
This release replaces the v0.2 verb-registry model with publisher-defined permission identifiers. **Wire format breaks**: v0.2 scope strings of the form `<verb>:<domain>/<noun>` are no longer accepted; scopes must now be `<publisher-domain>/<permission-name>` (or the wildcard `*`).
|
|
324
|
+
|
|
325
|
+
### Removed
|
|
326
|
+
|
|
327
|
+
- `aap.scopes` module (`VERBS`, `WILDCARD`, `parse_scope`, `is_valid_scope`). Replaced by inline scope-string shape validation in `payloads.py`.
|
|
328
|
+
|
|
329
|
+
### Added
|
|
330
|
+
|
|
331
|
+
- **`AccessDenied`** payload (`aap.access-denied/v1`): auto-sent by recipients when a chat or action envelope arrives without a valid `capability_token`. Includes `rejected_payload_type`, `reason` (`no_capability` / `scope_mismatch` / `expired_token` / `invalid_token`), `required_scopes` hint, and `rejected_at` timestamp.
|
|
332
|
+
- **`Envelope.capability_token`** optional field: carries a serialized inner `RelationshipToken` envelope. Recipients deserialize and verify to authorize the carrying envelope. Backward-compatible — omitted when not present. Included in the JCS-signed form so tampering invalidates the signature.
|
|
333
|
+
- **`CapabilityCatalog`** helper: fetches publisher capability metadata from `https://<publisher>/.well-known/aap-capabilities/<name>` with in-process caching. Used by host implementations to render rich consent UI.
|
|
334
|
+
|
|
335
|
+
### Changed
|
|
336
|
+
|
|
337
|
+
- Scope strings throughout (`RelationshipToken.scopes`, `CapabilityRequestScope.scope`, `CapabilityOfferedGrant.scope`, `CapabilityRefresh.requested_scopes`) now validate as `<domain>/<name>` or `*`. No verb prefix.
|
|
338
|
+
|
|
339
|
+
### Spec
|
|
340
|
+
|
|
341
|
+
- See `docs/specs/2026-05-22-aap-trust-capabilities-design.md` (Rev 2) for the full design.
|
|
342
|
+
|
|
343
|
+
## v0.2.0 — 2026-05-22
|
|
344
|
+
|
|
345
|
+
### Added
|
|
346
|
+
|
|
347
|
+
- **Scope vocabulary** (`aap.scopes`): seven standardized verbs (`read`, `write`, `book`, `cancel`, `pay`, `subscribe`, `delegate`) plus the wildcard `*`. Scope strings have the form `<verb>:<noun>` with `<noun>` free-form (typically a domain or URI). Verbs are not extensible by vendors — the registry is fixed so recipients always know the intent class.
|
|
348
|
+
- **`VerifiedIdentity`** payload-component: typed verified identifier (phone, email, etc.) with timestamp and verifier attribution (`"self"` or third-party domain). Embedded in `AgentCard.verified_identities`.
|
|
349
|
+
- **`AgentCard.verified_identities`** optional field — list of `VerifiedIdentity`. Backward-compatible: empty by default, omitted from serialization when empty, parses v0.1 AgentCards without the field.
|
|
350
|
+
- **`CapabilityRequest`** (`aap.capability-request/v1`): structured ask for capability tokens. Carries `scopes` (what the requester wants) and optional `offered_grants` (capabilities the requester reciprocally offers), enabling single-prompt bidirectional relationship setup.
|
|
351
|
+
- **`CapabilityGrant`** (`aap.capability-grant/v1`): wraps a `RelationshipToken` plus the originating request's nonce.
|
|
352
|
+
- **`CapabilityDenial`** (`aap.capability-denial/v1`): explicit "no" with structured reason (`user_denied`, `scope_not_supported`, `rate_limited`, `unknown`).
|
|
353
|
+
- **`CapabilityRefresh`** (`aap.capability-refresh/v1`): request to renew an existing token before expiry.
|
|
354
|
+
|
|
355
|
+
### Changed
|
|
356
|
+
|
|
357
|
+
- **`RelationshipToken.from_dict`** now validates scopes: each scope must parse as a valid `<verb>:<noun>` (or the wildcard `*`); the wildcard `*` is mutually exclusive with other scopes in the same token.
|
|
358
|
+
|
|
359
|
+
### Spec
|
|
360
|
+
|
|
361
|
+
- See `https://github.com/zazig-team/agentToAgentCommunication/blob/main/docs/specs/2026-05-22-aap-trust-capabilities-design.md` for the full trust-primitives design.
|
|
362
|
+
|
|
363
|
+
## v0.1.1 — 2026-05-19
|
|
364
|
+
|
|
365
|
+
Hardening release. Wire format unchanged — v0.1.0 conformance vectors still pass.
|
|
366
|
+
|
|
367
|
+
### Added
|
|
368
|
+
- `Envelope.from_dict` rejects unknown top-level fields.
|
|
369
|
+
- `Envelope.from_dict` enforces `type == "aap.envelope/v1"`.
|
|
370
|
+
- `Address.parse` lowercases the domain.
|
|
371
|
+
- `Address.parse` validates domain characters (ASCII alphanumeric, `.`, `-`).
|
|
372
|
+
- `Address.parse` enforces length caps (localpart 64, domain 253).
|
|
373
|
+
- `AgentCard.from_dict` validates each endpoint entry (dict with string `type` and `uri`).
|
|
374
|
+
- The legacy AgentCard resolver enforced `card.address`, issuer domain,
|
|
375
|
+
redirect, and response-size checks. It was later removed from the public API
|
|
376
|
+
in favor of authenticated, agent-signed AgentCard resolution.
|
|
377
|
+
|
|
378
|
+
### Documented
|
|
379
|
+
- `Envelope` docstring records the temporal-validation gap: v0.1.x does no timestamp, expiry, or replay validation. Callers responsible for temporal policy must implement it themselves.
|
|
380
|
+
|
|
381
|
+
## v0.1.0 — 2026-05-19
|
|
382
|
+
|
|
383
|
+
Initial release. Wire format frozen by conformance vectors.
|
|
384
|
+
|
|
385
|
+
### Added
|
|
386
|
+
- `aap.Envelope` — signed envelope codec (JCS + Ed25519).
|
|
387
|
+
- `aap.Address` — `agent:<localpart>@<domain>` parser.
|
|
388
|
+
- `aap.AgentCard` and `aap.RelationshipToken` payload types.
|
|
389
|
+
- Agent Card resolution client for `POST .well-known/aap-resolve` with a
|
|
390
|
+
caller-supplied verification key. This legacy API was later removed from the
|
|
391
|
+
public surface in favor of authenticated, agent-signed AgentCard resolution.
|
|
392
|
+
- `aap.keys` — Ed25519 keygen / sign / verify and base64url codec.
|
|
393
|
+
|
|
394
|
+
### Not yet implemented
|
|
395
|
+
- DIDComm v2 encrypted envelopes.
|
|
396
|
+
- `did:web` resolver (caller must obtain verification keys out-of-band).
|
|
397
|
+
- OPRF discovery client.
|
|
398
|
+
- Status List 2021 revocation.
|
|
399
|
+
- SD-JWT selective disclosure.
|
|
400
|
+
- ECDH-PSI mutual contact proof.
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
Copyright 2026 Chris Evans
|
|
2
|
+
|
|
3
|
+
Apache License
|
|
4
|
+
Version 2.0, January 2004
|
|
5
|
+
http://www.apache.org/licenses/
|
|
6
|
+
|
|
7
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
8
|
+
|
|
9
|
+
1. Definitions.
|
|
10
|
+
|
|
11
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
12
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
13
|
+
|
|
14
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
15
|
+
the copyright owner that is granting the License.
|
|
16
|
+
|
|
17
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
18
|
+
other entities that control, are controlled by, or are under common
|
|
19
|
+
control with that entity. For the purposes of this definition,
|
|
20
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
21
|
+
direction or management of such entity, whether by contract or
|
|
22
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
23
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
24
|
+
|
|
25
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
26
|
+
exercising permissions granted by this License.
|
|
27
|
+
|
|
28
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
29
|
+
including but not limited to software source code, documentation
|
|
30
|
+
source, and configuration files.
|
|
31
|
+
|
|
32
|
+
"Object" form shall mean any form resulting from mechanical
|
|
33
|
+
transformation or translation of a Source form, including but
|
|
34
|
+
not limited to compiled object code, generated documentation,
|
|
35
|
+
and conversions to other media types.
|
|
36
|
+
|
|
37
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
38
|
+
Object form, made available under the License, as indicated by a
|
|
39
|
+
copyright notice that is included in or attached to the work
|
|
40
|
+
(an example is provided in the Appendix below).
|
|
41
|
+
|
|
42
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
43
|
+
form, that is based on (or derived from) the Work and for which the
|
|
44
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
45
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
46
|
+
of this License, Derivative Works shall not include works that remain
|
|
47
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
48
|
+
the Work and Derivative Works thereof.
|
|
49
|
+
|
|
50
|
+
"Contribution" shall mean any work of authorship, including
|
|
51
|
+
the original version of the Work and any modifications or additions
|
|
52
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
53
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
54
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
55
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
56
|
+
means any form of electronic, verbal, or written communication sent
|
|
57
|
+
to the Licensor or its representatives, including but not limited to
|
|
58
|
+
communication on electronic mailing lists, source code control systems,
|
|
59
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
60
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
61
|
+
excluding communication that is conspicuously marked or otherwise
|
|
62
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
63
|
+
|
|
64
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
65
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
66
|
+
subsequently incorporated within the Work.
|
|
67
|
+
|
|
68
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
69
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
70
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
71
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
72
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
73
|
+
Work and such Derivative Works in Source or Object form.
|
|
74
|
+
|
|
75
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
76
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
77
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
78
|
+
(except as stated in this section) patent license to make, have made,
|
|
79
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
80
|
+
where such license applies only to those patent claims licensable
|
|
81
|
+
by such Contributor that are necessarily infringed by their
|
|
82
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
83
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
84
|
+
institute patent litigation against any entity (including a
|
|
85
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
86
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
87
|
+
or contributory patent infringement, then any patent licenses
|
|
88
|
+
granted to You under this License for that Work shall terminate
|
|
89
|
+
as of the date such litigation is filed.
|
|
90
|
+
|
|
91
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
92
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
93
|
+
modifications, and in Source or Object form, provided that You
|
|
94
|
+
meet the following conditions:
|
|
95
|
+
|
|
96
|
+
(a) You must give any other recipients of the Work or
|
|
97
|
+
Derivative Works a copy of this License; and
|
|
98
|
+
|
|
99
|
+
(b) You must cause any modified files to carry prominent notices
|
|
100
|
+
stating that You changed the files; and
|
|
101
|
+
|
|
102
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
103
|
+
that You distribute, all copyright, patent, trademark, and
|
|
104
|
+
attribution notices from the Source form of the Work,
|
|
105
|
+
excluding those notices that do not pertain to any part of
|
|
106
|
+
the Derivative Works; and
|
|
107
|
+
|
|
108
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
109
|
+
distribution, then any Derivative Works that You distribute must
|
|
110
|
+
include a readable copy of the attribution notices contained
|
|
111
|
+
within such NOTICE file, excluding those notices that do not
|
|
112
|
+
pertain to any part of the Derivative Works, in at least one
|
|
113
|
+
of the following places: within a NOTICE text file distributed
|
|
114
|
+
as part of the Derivative Works; within the Source form or
|
|
115
|
+
documentation, if provided along with the Derivative Works; or,
|
|
116
|
+
within a display generated by the Derivative Works, if and
|
|
117
|
+
wherever such third-party notices normally appear. The contents
|
|
118
|
+
of the NOTICE file are for informational purposes only and
|
|
119
|
+
do not modify the License. You may add Your own attribution
|
|
120
|
+
notices within Derivative Works that You distribute, alongside
|
|
121
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
122
|
+
that such additional attribution notices cannot be construed
|
|
123
|
+
as modifying the License.
|
|
124
|
+
|
|
125
|
+
You may add Your own copyright statement to Your modifications and
|
|
126
|
+
may provide additional or different license terms and conditions
|
|
127
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
128
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
129
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
130
|
+
the conditions stated in this License.
|
|
131
|
+
|
|
132
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
133
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
134
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
135
|
+
this License, without any additional terms or conditions.
|
|
136
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
137
|
+
the terms of any separate license agreement you may have executed
|
|
138
|
+
with Licensor regarding such Contributions.
|
|
139
|
+
|
|
140
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
141
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
142
|
+
except as required for reasonable and customary use in describing the
|
|
143
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
144
|
+
|
|
145
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
146
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
147
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
148
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
149
|
+
implied, including, without limitation, any warranties or conditions
|
|
150
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
151
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
152
|
+
appropriateness of using or redistributing the Work and assume any
|
|
153
|
+
risks associated with Your exercise of permissions under this License.
|
|
154
|
+
|
|
155
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
156
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
157
|
+
unless required by applicable law (such as deliberate and grossly
|
|
158
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
159
|
+
liable to You for damages, including any direct, indirect, special,
|
|
160
|
+
incidental, or consequential damages of any character arising as a
|
|
161
|
+
result of this License or out of the use or inability to use the
|
|
162
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
163
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
164
|
+
other commercial damages or losses), even if such Contributor
|
|
165
|
+
has been advised of the possibility of such damages.
|
|
166
|
+
|
|
167
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
168
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
169
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
170
|
+
or other liability obligations and/or rights consistent with this
|
|
171
|
+
License. However, in accepting such obligations, You may act only
|
|
172
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
173
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
174
|
+
defend, and hold each Contributor harmless for any liability
|
|
175
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
176
|
+
of your accepting any such warranty or additional liability.
|
|
177
|
+
|
|
178
|
+
END OF TERMS AND CONDITIONS
|
|
179
|
+
|
|
180
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
181
|
+
|
|
182
|
+
To apply the Apache License to your work, attach the following
|
|
183
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
184
|
+
replaced with your own identifying information. (Don't include
|
|
185
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
186
|
+
comment syntax for the file format. We also recommend that a
|
|
187
|
+
file or class name and description of purpose be included on the
|
|
188
|
+
same "printed page" as the copyright notice for easier
|
|
189
|
+
identification within third-party archives.
|
|
190
|
+
|
|
191
|
+
Copyright [yyyy] [name of copyright owner]
|
|
192
|
+
|
|
193
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
194
|
+
you may not use this file except in compliance with the License.
|
|
195
|
+
You may obtain a copy of the License at
|
|
196
|
+
|
|
197
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
198
|
+
|
|
199
|
+
Unless required by applicable law or agreed to in writing, software
|
|
200
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
201
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
202
|
+
See the License for the specific language governing permissions and
|
|
203
|
+
limitations under the License.
|