Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,21 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). The Har

## [Unreleased] — v2 (in progress)

Work on the **v2 milestone** has begun. v2 is **additive**: it introduces two new protocol layers on top of the stable Schema layer and does **not** change `harness.yaml` — the `version` field stays `"1"` and the `harness.schema.json` `$id` (`/schema/v1/...`) is frozen. A fragment authored against v1 is Exchange-compatible without modification. New v2 schema artifacts are grouped under the `/schema/v2/` `$id` namespace.
Work on the **v2 milestone** continues. v2 is **additive**: it introduces two new protocol layers on top of the stable Schema layer and does **not** change `harness.yaml` — the `version` field stays `"1"` and the `harness.schema.json` `$id` (`/schema/v1/...`) is frozen. A fragment authored against v1 is Exchange-compatible without modification. New v2 schema artifacts are grouped under the `/schema/v2/` `$id` namespace.

### Added (draft)

- **Exchange layer:** the signed **offer envelope** (`exchange.schema.json`) and the consent-first `Offer → Preview → Accept / Edit / Reject → Apply` flow for peer-to-peer (1:1) fragment sharing — "AirDrop for harnesses." ed25519 sender identity; optional X25519 payload encryption. Normative draft in [protocol/exchange.md](protocol/exchange.md), specified by [HEP-7](heps/hep-0007-exchange-layer.md). *Status: Review.*
- **Registry layer:** hosted discovery at harnessprotocol.io — indexing of public `owner/repo` profiles/fragments/plugins, search, SHA-256 integrity hashing, and an append-only transparency log (`registry.schema.json`). GitHub stays authoritative; the registry is a discovery convenience, not a trust anchor. Normative draft in [protocol/registry.md](protocol/registry.md), specified by [HEP-8](heps/hep-0008-registry-layer.md). *Status: Review.* Verified authors, curation, and minisign registry signing are deferred to v3.
- **Registry layer:** hosted discovery at harnessprotocol.io — indexing of public `owner/repo` profiles/fragments/plugins, search, SHA-256 integrity hashing, and an append-only transparency log (`registry.schema.json`). GitHub stays authoritative; the registry is a discovery convenience, not a trust anchor. Normative draft in [protocol/registry.md](protocol/registry.md), specified by [HEP-8](heps/hep-0008-registry-layer.md). *Status: Review.* Verified authors, curation, and minisign registry signing are deferred to v3. The service prototype (hosted index, registration/discovery APIs, transparency-log server) required for Accepted has not started.

These layers are in **Review** status under the HEP process and are not yet released. Schema mirrors under `website/public/schema/v2/` are published at release, not during draft.
This layer is in **Review** status under the HEP process and is not yet released. Its schema mirror under `website/public/schema/v2/` is published at release, not during draft.

## [v1.1.0] — 2026-07-27

**Exchange layer accepted** — the first of the two v2-milestone layers to ship; Registry remains in Review (see Unreleased above). [HEP-7](heps/hep-0007-exchange-layer.md) moves from Review to **Accepted**: both the format prototype (schema, examples, eval tests) and the runtime prototype (ed25519/X25519 signing and verification, canonicalization, and the `harness exchange keygen/offer/accept` flow, shipped in [harness-kit](https://github.com/harnessprotocol/harness-kit)) are satisfied. Backward-compatible: Exchange adds no `harness.yaml` fields, the `version` field stays `"1"`, and the v1 schema `$id` is unchanged.

### Added

- **Exchange layer:** the signed **offer envelope** (`exchange.schema.json`) and the consent-first `Offer → Preview → Accept / Edit / Reject → Apply` flow for peer-to-peer (1:1) fragment sharing — "AirDrop for harnesses." ed25519 sender identity; optional X25519 payload encryption. Normative in [protocol/exchange.md](protocol/exchange.md), specified by [HEP-7](heps/hep-0007-exchange-layer.md). The `schema/draft/` schema is snapshotted to `schema/2026-07-27/` and published to `website/public/schema/v2/exchange.schema.json`.

## [v1.0.0] — 2026-06-05

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The specification is organized into three layers, each building on the previous.
| Layer | Description | Status |
|-------|-------------|--------|
| **Schema** | The `harness.yaml` format, JSON Schema validation, security model, plugin manifest | v1 — current |
| **Exchange** | Harness-to-harness sharing: publish, fetch, and compose harnesses across tools and teams | v2 — draft ([HEP-7](heps/hep-0007-exchange-layer.md)) |
| **Exchange** | Harness-to-harness sharing: publish, fetch, and compose harnesses across tools and teams | v2 — accepted ([HEP-7](heps/hep-0007-exchange-layer.md)) |
| **Registry** | Hosted discovery at harnessprotocol.io: search, publish, version resolution, integrity verification | v2/v3 — draft ([HEP-8](heps/hep-0008-registry-layer.md)) |

Layers are intentionally decoupled. A tool can implement Schema-layer validation today without any dependency on exchange or registry infrastructure.
Expand Down Expand Up @@ -104,7 +104,7 @@ Full documentation is available at [harnessprotocol.io/spec](https://harnessprot
| [protocol/inheritance.md](protocol/inheritance.md) | `extends` resolution order and per-section merge rules |
| [protocol/application.md](protocol/application.md) | Application pipeline, effective configuration, error handling |
| [protocol/source-resolution.md](protocol/source-resolution.md) | Source resolution algorithm for `owner/repo` and local path references |
| [protocol/exchange.md](protocol/exchange.md) | *(v2 draft)* Exchange layer — the signed offer envelope and consent-first sharing flow |
| [protocol/exchange.md](protocol/exchange.md) | *(v2)* Exchange layer — the signed offer envelope and consent-first sharing flow |
| [protocol/registry.md](protocol/registry.md) | *(v2 draft)* Registry layer — hosted discovery, integrity hashing, and the transparency log |
| [security/threat-model.md](security/threat-model.md) | Threat model and security design |
| [security/trust-boundaries.md](security/trust-boundaries.md) | Trust boundaries between spec, implementations, profiles, and remote content |
Expand All @@ -113,7 +113,7 @@ Full documentation is available at [harnessprotocol.io/spec](https://harnessprot
| [security/integrity.md](security/integrity.md) | Content integrity verification |
| [security/instruction-injection.md](security/instruction-injection.md) | Instruction injection threat and mitigations |
| [security/skill-injection.md](security/skill-injection.md) | Skill behavioral injection threat and mitigations |
| [security/exchange.md](security/exchange.md) | *(v2 draft)* Exchange threat model — authenticity, consent, confidentiality in transit |
| [security/exchange.md](security/exchange.md) | *(v2)* Exchange threat model — authenticity, consent, confidentiality in transit |
| [security/registry.md](security/registry.md) | *(v2 draft)* Registry threat model — the registry is an index, not a trust anchor |
| [security/crypto-map.md](security/crypto-map.md) | How SHA-256 integrity, ed25519 (Exchange), and minisign signing compose |

Expand Down
4 changes: 3 additions & 1 deletion heps/hep-0007-exchange-layer.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Exchange layer — peer-to-peer harness fragment sharing
hep: 7
type: Standards Track
status: Review
status: Accepted
authors: [siracusa5 <siracusa5>]
sponsor: siracusa5 <siracusa5>
created: 2026-06-05
Expand Down Expand Up @@ -109,3 +109,5 @@ Per the Standards Track prototype requirement, this HEP's **format prototype is
- Eval coverage: `eval/src/tests/schema/exchange.test.ts` — valid/invalid envelopes, the `oneOf` exclusivity, and the two-step "envelope valid but wrapped fragment invalid" check.

The **runtime prototype** — the `harness exchange offer/accept` subcommands, ed25519 signing/verification, X25519 encryption, the relay API, and the consent-first preview UI — is a behavior of the reference implementation and is required in [harness-kit](https://github.com/harnessprotocol/harness-kit) before this HEP moves to **Accepted**. As with HEP-6, the in-repo artifacts verify the *declaration surface*; the prose specifies the apply-time semantics a conformant implementation MUST enforce.

**Runtime prototype: satisfied.** `harness-kit` ships `keygen`, `offer`, and `accept` CLI subcommands (`apps/cli/src/commands/exchange.ts`) backed by `@harness-kit/exchange` (`packages/exchange`): ed25519 keypair generation and fingerprinting, canonical-JSON signing/verification, X25519 payload encryption, and the consent-first Preview → Accept/Edit/Reject → Apply flow, with test coverage for the envelope and keypair logic. The one named piece not yet built is the **relay API**; per this HEP that is non-blocking, since clipboard/file transport already covers the zero-infrastructure MVP. On that basis this HEP moves to **Accepted**.
2 changes: 1 addition & 1 deletion protocol/exchange.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This document specifies the **Exchange layer** of the Harness Protocol: a push-based, consent-required flow for sharing a single `kind: fragment` document from one person to another. Exchange is introduced in the v2 milestone and is specified normatively by [HEP-7](../heps/hep-0007-exchange-layer.md). The offer envelope is validated by [`schema/draft/exchange.schema.json`](../schema/draft/exchange.schema.json).

> **Status:** Draft (v2). The format is specified here; runtime behavior is implemented in the reference implementation. Normative language ("MUST", "SHOULD", etc.) follows [BCP 14](https://www.rfc-editor.org/info/bcp14), as in the rest of the specification.
> **Status:** Accepted (v2). The format is specified here; runtime behavior is implemented in the reference implementation. Normative language ("MUST", "SHOULD", etc.) follows [BCP 14](https://www.rfc-editor.org/info/bcp14), as in the rest of the specification.

---

Expand Down
8 changes: 4 additions & 4 deletions protocol/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S

## Protocol Layers

The Harness Protocol is organized into three layers, each building on the previous. Version 1 delivers the Schema layer. The Exchange and Registry layers are in draft for v2 — see [HEP-7](../heps/hep-0007-exchange-layer.md) and [HEP-8](../heps/hep-0008-registry-layer.md), and the normative drafts in [Exchange](./exchange.md) and [Registry](./registry.md).
The Harness Protocol is organized into three layers, each building on the previous. Version 1 delivers the Schema layer. The Exchange layer is accepted for v2 ([HEP-7](../heps/hep-0007-exchange-layer.md), normative spec in [Exchange](./exchange.md)); the Registry layer remains in draft for v2 ([HEP-8](../heps/hep-0008-registry-layer.md), normative draft in [Registry](./registry.md)).

| Layer | Description | Status |
|-------|-------------|--------|
| **Schema** | The `harness.yaml` format: structure, validation rules, security model, inheritance semantics | v1 (current) |
| **Exchange** | Harness-to-harness sharing — a protocol for publishing, fetching, and composing harnesses between tools and teams ("AirDrop for harnesses") | v2 (draft — HEP-7) |
| **Exchange** | Harness-to-harness sharing — a protocol for publishing, fetching, and composing harnesses between tools and teams ("AirDrop for harnesses") | v2 (accepted — HEP-7) |
| **Registry** | Hosted discovery at harnessprotocol.io — search, publish, version resolution, integrity verification for the broader ecosystem | v2/v3 (draft — HEP-8) |

The layers are intentionally decoupled. A tool can implement Schema-layer validation today without any dependency on exchange or registry infrastructure. When Exchange ships, tools opt in incrementally.
The layers are intentionally decoupled. A tool can implement Schema-layer validation today without any dependency on exchange or registry infrastructure. Exchange has shipped; tools opt in incrementally. Registry will follow the same pattern once accepted.

## What v1 Delivers

Expand Down Expand Up @@ -90,7 +90,7 @@ MCP, AGENTS.md, and Agent Skills are stewarded under the **Agentic AI Foundation
| [Environment](./environment.md) | Environment variable declarations, sensitive handling |
| [Fragments](./fragments.md) | `kind: fragment` — partial harness documents for composition |
| [Source Resolution](./source-resolution.md) | Source resolution algorithm for `owner/repo` and local path references |
| [Exchange](./exchange.md) | *(v2 draft)* The signed offer envelope and consent-first peer-to-peer sharing flow |
| [Exchange](./exchange.md) | *(v2)* The signed offer envelope and consent-first peer-to-peer sharing flow |
| [Registry](./registry.md) | *(v2 draft)* Hosted discovery, integrity hashing, namespace design, transparency log |
| [Application](./application.md) | Application pipeline, effective configuration, error handling |
| [Inheritance](./inheritance.md) | `extends` resolution order and per-section merge rules |
Expand Down
120 changes: 120 additions & 0 deletions schema/2026-07-27/exchange.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://harnessprotocol.io/schema/v2/exchange.schema.json",
"title": "Harness Protocol v2 — Exchange Offer Envelope",
"description": "Schema for Exchange-layer offer envelopes: a signed wrapper that carries a harness fragment from a sender to a receiver through the consent-first exchange flow. The wrapped fragment is opaque to this schema; it MUST independently validate against the harness schema (https://harnessprotocol.io/schema/v1/harness.schema.json) with kind: fragment semantics.",
"type": "object",
"required": ["version", "type", "sender", "expires", "signature"],
"properties": {
"$schema": {
"type": "string",
"description": "JSON Schema URI for editor tooling. Recommended value: 'https://harnessprotocol.io/schema/v2/exchange.schema.json'."
},
"version": {
"type": "string",
"const": "1",
"description": "Offer-envelope format version. Must be the string '1'. This is the Exchange layer's own format version — independent of the harness.yaml 'version' field and of the v2 milestone label. Receivers MUST reject envelopes with an unrecognized version and surface a clear error."
},
"type": {
"type": "string",
"enum": ["offer"],
"description": "Envelope type. Only 'offer' is defined in this version. Receivers MUST reject unknown types. The value 'receipt' is reserved for a future version (signed acknowledgement of receipt)."
},
"sender": {
"type": "object",
"required": ["key"],
"description": "The sender's self-sovereign identity. The only authenticated identity is the key; 'display' is advisory.",
"properties": {
"key": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "The sender's ed25519 public key, lowercase hex-encoded (32 bytes / 64 hex chars). This key is the sender's identity. Receivers SHOULD show a fingerprint derived from it (see the Exchange specification) rather than the raw key."
},
"display": {
"type": "string",
"maxLength": 64,
"description": "Optional, UNVERIFIED display name. A hint only — receivers MUST NOT treat it as authenticated identity."
}
},
"additionalProperties": false
},
"recipient": {
"type": "object",
"required": ["key"],
"description": "The intended recipient. REQUIRED for encrypted envelopes (the payload is encrypted to this key) and absent for unaddressed plaintext offers.",
"properties": {
"key": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "The recipient's ed25519 public key, lowercase hex-encoded. Converted to its X25519 equivalent to derive the shared secret for payload encryption."
}
},
"additionalProperties": false
},
"message": {
"type": "string",
"maxLength": 1024,
"description": "Optional human-readable message from the sender, displayed to the receiver at preview time. Not covered by the signature (it is not security-critical content)."
},
"fragment": {
"type": "object",
"description": "The plaintext fragment being offered: a harness document with kind: fragment, serialized as a JSON object (YAML-equivalent fields, JSON types). Opaque to this schema; it MUST independently validate against the harness schema with fragment semantics before the envelope is considered well-formed. Present only in unencrypted envelopes; mutually exclusive with 'encrypted-fragment'."
},
"encrypted-fragment": {
"type": "object",
"required": ["algorithm", "nonce", "ciphertext"],
"description": "The fragment encrypted to the recipient's key. Present only in encrypted envelopes; mutually exclusive with 'fragment'. The receiver decrypts and then validates the decrypted content against the harness schema.",
"properties": {
"algorithm": {
"type": "string",
"const": "x25519-xsalsa20-poly1305",
"description": "Authenticated encryption scheme: X25519 key agreement with XSalsa20-Poly1305 (the NaCl 'box' construction)."
},
"nonce": {
"type": "string",
"contentEncoding": "base64",
"description": "Base64-encoded encryption nonce."
},
"ciphertext": {
"type": "string",
"contentEncoding": "base64",
"description": "Base64-encoded ciphertext of the canonical-JSON fragment bytes."
}
},
"additionalProperties": false
},
"suggested-import-mode": {
"type": "string",
"enum": ["merge", "replace", "skip"],
"description": "A non-binding hint about how the fragment should be applied. The receiver sets the actual import-mode and MAY override this at the Accept step."
},
"expires": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 timestamp after which the offer is stale. Receivers MUST NOT apply an expired offer. This bounds replay: an offer intercepted in transit cannot be applied indefinitely."
},
"signature": {
"type": "string",
"pattern": "^[a-f0-9]{128}$",
"description": "Detached ed25519 signature, lowercase hex-encoded (64 bytes / 128 hex chars), produced by the sender's private key. For plaintext envelopes it covers the canonical-JSON bytes of 'fragment'; for encrypted envelopes it covers the raw 'encrypted-fragment.ciphertext' bytes. Receivers MUST verify the signature before preview; verification failure is a hard rejection with no 'proceed anyway' path."
}
},
"oneOf": [
{
"title": "Plaintext offer",
"required": ["fragment"],
"not": { "anyOf": [{ "required": ["encrypted-fragment"] }, { "required": ["recipient"] }] }
},
{
"title": "Encrypted offer",
"required": ["encrypted-fragment", "recipient"],
"not": { "required": ["fragment"] }
}
],
"patternProperties": {
"^x-": {
"description": "Implementation-specific extension field. The x- prefix signals a non-standard field. Implementations MUST ignore unrecognized x- fields to ensure forward compatibility."
}
},
"additionalProperties": false
}
Loading
Loading