File size: 17,717 Bytes
70650b7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
# M32 β€” Protocol Standardisation & Conformance

**Spec version:** v3.0 β€” *experimental*
**Depends on:** [M03 Capability Bus](../../modules/M03-capability-bus.md), [X02 Event Log](../../cross-cutting/X02-events.md), [M14 Federation](../../phase-2/modules/M14-federation.md), [X09 Conformance Suite](../cross-cutting/X09-conformance-suite.md)
**Depended on by:** anyone building an alternate implementation of HearthNet

---

## 1. Responsibility

Turn the HearthNet specs from "Christof's working code with documentation" into something a **second team** could implement compatibly. This module is the bookkeeping for that: a versioned protocol document set, a conformance reporting capability, governance for how the spec changes, and a registry of known implementations and their conformance levels.

The premise is that long-term, a single implementation is fragile. If HearthNet only works as long as one person maintains it, it doesn't survive. Standardising the protocol (the wire formats, the capability contracts, the federation semantics) so other implementations can interoperate is the path to durability β€” and it sets up the social and legal scaffolding (versioning policy, change process, conformance claims) that other projects will need to take HearthNet seriously.

This is not "rewrite HearthNet as an RFC". It's "package what already exists in a form that can be cited, versioned, and conformance-tested". The reference implementation is HearthNet itself; the protocol document is the contract; the conformance suite (X09) is the proof.

---

## 2. Non-goals

- **Submitting to IETF / W3C in v3.0.** That's a multi-year governance process and is out of scope. We make ourselves *ready* for it by structuring the documents and adopting RFC-style versioning conventions, but we don't file anything.
- **Patent licensing.** There are no patented techniques in HearthNet's core (capability bus, event log, federation, etc. β€” all build on well-known primitives). We document this assumption but do not run a patent review.
- **Trademark of "HearthNet".** Out of scope. If the protocol survives, someone (probably ki-fusion-labs.de) eventually claims the name; v3.0 doesn't deal with that.
- **Conformance certification with a fee structure.** Conformance reports are self-published and free. No "HearthNet Insideβ„’ certification programme".
- **Backward compatibility forever.** Protocol versions can have breaking changes between major versions, with documented migration. Within a minor version, compatibility is required.

---

## 3. File layout

The module is unusual in that most of its content lives *outside* the `hearthnet/` Python package β€” in a top-level `protocol/` directory at the repository root.

```
protocol/                                # repo-root sibling of hearthnet/
β”œβ”€β”€ README.md
β”œβ”€β”€ VERSION                              # current protocol version (e.g. 3.0.0)
β”œβ”€β”€ CHANGELOG.md
β”œβ”€β”€ governance.md                        # change process, decision rights
β”œβ”€β”€ versioning.md                        # semver-with-twists rules
β”œβ”€β”€ reference-implementations.md         # registry
β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ 01-identity-and-addressing.md
β”‚   β”œβ”€β”€ 02-transport.md
β”‚   β”œβ”€β”€ 03-capability-bus.md
β”‚   β”œβ”€β”€ 04-event-log.md
β”‚   β”œβ”€β”€ 05-tokens.md
β”‚   β”œβ”€β”€ 06-federation.md
β”‚   └── ...
└── experimental/
    β”œβ”€β”€ 30-evidence.md
    └── 31-civil-defense.md

hearthnet/protocol/
β”œβ”€β”€ __init__.py
β”œβ”€β”€ service.py                           # ProtocolService β€” registry and report capability
β”œβ”€β”€ registry.py                          # In-memory + persisted registry of known impls
└── report.py                            # Conformance report dataclass + serialiser
```

The `protocol/` directory is the **specification artefact** β€” versioned alongside code but conceptually independent. The Python `hearthnet/protocol/` module is the thin runtime surface that lets a HearthNet node expose its conformance information on the bus.

---

## 4. Public API

### 4.1 Dataclasses

```python
@dataclass(frozen=True)
class ProtocolVersion:
    major:  int
    minor:  int
    patch:  int
    suffix: str = ""        # "", "rc1", "experimental"

    def __str__(self) -> str: ...        # "3.0.0" or "3.0.0-rc1"
    def is_compatible_with(self, other: ProtocolVersion) -> bool: ...   # same major

@dataclass(frozen=True)
class ImplementationDescriptor:
    name:           str                  # e.g. "hearthnet-reference"
    vendor:         str                  # e.g. "ki-fusion-labs.de"
    version:        str                  # implementation version, e.g. "0.4.2"
    protocol_versions: tuple[ProtocolVersion, ...]   # which protocol versions supported
    homepage_url:   str | None
    contact:        str | None

@dataclass(frozen=True)
class ConformanceReport:
    implementation:  ImplementationDescriptor
    protocol_version: ProtocolVersion
    suite_version:   str                   # X09 conformance suite version
    ran_at:          datetime
    sections: dict[str, SectionResult]     # section name β†’ result
    overall: Literal["pass","fail","partial","skipped"]
    signature: bytes                       # implementation signs its own report

@dataclass(frozen=True)
class SectionResult:
    name:          str
    total:         int
    passed:        int
    failed:        int
    skipped:       int
    failures:      tuple[FailureDetail, ...]
```

### 4.2 Capabilities

```python
async def protocol_version_list() -> list[ProtocolVersion]
async def protocol_self_describe() -> ImplementationDescriptor
async def protocol_conformance_report(suite_version: str | None = None) -> ConformanceReport
async def protocol_registry_list() -> list[ImplementationDescriptor]
async def protocol_registry_announce(descriptor: ImplementationDescriptor) -> AnnounceReceipt
```

These are stable (non-experimental) capabilities β€” the protocol must include its own self-description and conformance-reporting capability, otherwise interop is impossible.

### 4.3 Service class

```python
class ProtocolService:
    def __init__(self,
                 bus: CapabilityBus,
                 event_log: EventLog,
                 federation: FederationService,
                 registry: ImplementationRegistry,
                 conformance_runner: ConformanceRunner | None,
                 config: ProtocolConfig): ...

    def supported_versions(self) -> list[ProtocolVersion]: ...
    def self_descriptor(self) -> ImplementationDescriptor: ...
    async def run_conformance(self, suite_version: str | None = None) -> ConformanceReport: ...
    async def announce(self, descriptor: ImplementationDescriptor) -> None: ...   # to local registry + federation
    async def registry_list(self) -> list[ImplementationDescriptor]: ...
```

### 4.4 Implementation registry

```python
class ImplementationRegistry:
    """Local registry of known implementations.

    Populated by:
      - self (this node, on startup)
      - federation peers' announcements
      - operator-curated additions
    """
    async def upsert(self, descriptor: ImplementationDescriptor, source: NodeID) -> None: ...
    async def list(self) -> list[ImplementationDescriptor]: ...
    async def known_by_name(self, name: str) -> list[ImplementationDescriptor]: ...
```

---

## 5. Behaviour

### 5.1 Versioning policy

Protocol versions follow **semver with explicit stability tiers**:

- **Major** (`X.0.0`): breaking changes to wire formats or capability contracts. New major version requires explicit migration documentation. Old majors remain readable for migration purposes for at least 2 years.
- **Minor** (`X.Y.0`): additive β€” new capabilities, new event types, new optional fields. Backward compatibility within the major is required: a `3.0` impl talking to a `3.2` impl must work, with the `3.0` side ignoring new fields/events.
- **Patch** (`X.Y.Z`): clarification, typo fixes, no functional change.
- **Suffix** `-experimental`: capabilities in the `experimental.*` namespace; can change without bumping major.

Each protocol document carries a frontmatter `protocol-version: 3.X.Y` that names the smallest version that contains it. The `protocol/VERSION` file is the current latest. The `CHANGELOG.md` lists every diff between versions.

### 5.2 Stability tiers

Capabilities are tagged with one of:

- `stable` β€” frozen at the major version; any change is a breaking change.
- `provisional` β€” expected to become stable; minor-version breaking changes allowed with deprecation period.
- `experimental` β€” `experimental.*` namespace; may change or vanish.

The `protocol_self_describe` capability reports which capabilities the implementation supports and at which tier. A capability marked `stable` in the protocol but implemented at `experimental` tier in the node is a configuration error and is logged at startup.

### 5.3 Conformance reporting

A `ConformanceReport` is the artefact produced by running the X09 conformance suite against a running node. The report is:

- **Self-signed** by the implementation β€” there is no central authority that "certifies" reports.
- **Reproducible** β€” the suite version is in the report; running the same suite against the same impl should produce equivalent results modulo timestamps.
- **Public** β€” implementations are encouraged to publish their reports openly (in their repo, on their website, federated via the registry).
- **Honest about partial conformance** β€” `partial` is a valid outcome and is more useful than a misleading `pass`.

Reports do not expire, but a report from suite version `1.0.0` is not equivalent to a report from `2.0.0`. The X09 suite versions independently of the protocol.

### 5.4 Implementation registry & federation

Each HearthNet node announces its `ImplementationDescriptor` to its federation peers on connect. Peers add it to their local registry. Operators can query their local registry for "who else is out there" via `protocol_registry_list`.

The registry is *advisory*. There is no trust beyond "this peer claimed this descriptor at this time". A peer claiming to be an implementation it isn't is a security incident, but the registry doesn't authenticate vendor names β€” only that the node signed its descriptor.

### 5.5 Governance (documented, not enforced)

The `protocol/governance.md` document describes how protocol changes happen:

1. **Proposal**: any contributor writes a "change note" as a PR to `protocol/`. Includes motivation, exact spec diff, migration story, and conformance impact.
2. **Discussion**: open period (default 4 weeks) for review.
3. **Decision**: maintainers (initially just Christof, ideally expanding to a small group) accept, reject, or request revision. Rejections are logged with rationale.
4. **Merge**: accepted change merges to `protocol/main` with version bump per Β§5.1 rules.
5. **Release**: tagged release of the protocol document set independent of code releases.

This is a process document; the module does not *enforce* governance technically. Enforcement is social.

### 5.6 Reference implementations registry

`protocol/reference-implementations.md` is a living document listing known implementations. v3.0 entries:

- **hearthnet-reference** (Python, this codebase). Status: complete, all stable + provisional + experimental capabilities.
- (placeholder for a second impl when one exists).

Adding an implementation to this document requires a PR demonstrating at minimum a passing conformance report for `core` sections of the X09 suite at the current major version.

### 5.7 Migration documentation

Each major version transition ships a `protocol/migration/X-to-Y.md` document. v3.0 includes:

- `protocol/migration/2-to-3.md` β€” placeholder for now; v3.0 introduces only experimental capabilities, so a strict v2β†’v3 migration is effectively a no-op for stable code paths.

### 5.8 Failure modes

- **Mismatched protocol versions in federation**: handled by M14 federation manifest version negotiation. M32 itself doesn't intervene at runtime; it just reports.
- **Conformance suite not present**: `protocol.conformance.report` returns `skipped` overall with reason `suite_not_installed`.
- **Conflicting registry entries** (same `name` claimed by two distinct vendors): both stored; the registry list returns both; operators decide.

---

## 6. Errors

| Code                          | When                                                              |
|-------------------------------|-------------------------------------------------------------------|
| `protocol_version_unknown`    | Operation references a protocol version not in our table         |
| `protocol_suite_not_installed`| Conformance report requested but X09 not available               |
| `protocol_descriptor_invalid` | Announcement with malformed descriptor                            |
| `protocol_unsupported_capability` | Federation negotiation finds no compatible major version       |

---

## 7. Configuration

```python
@dataclass(frozen=True)
class ProtocolConfig:
    enabled:                  bool = True       # this one is enabled by default
    supported_versions:       tuple[str, ...] = ("3.0.0",)
    default_announce_version: str = "3.0.0"
    descriptor:               ImplementationDescriptor = field(default_factory=lambda: ImplementationDescriptor(
        name="hearthnet-reference",
        vendor="ki-fusion-labs.de",
        version="0.4.2",
        protocol_versions=(ProtocolVersion(3, 0, 0),),
        homepage_url="https://ki-fusion-labs.de/hearthnet",
        contact=None,
    ))
    announce_to_federation:   bool = True
    conformance_auto_run_on_startup: bool = False
    registry_max_entries:     int = 4096
```

---

## 8. Tests

### 8.1 Unit

- `test_protocol_version_compat` β€” same major compatible; different major not.
- `test_descriptor_signature_roundtrip`.
- `test_registry_upsert_idempotent`.
- `test_conformance_report_signed` β€” self-signed report's signature verifies against the implementation's identity.
- `test_protocol_version_parse` β€” `"3.0.0"`, `"3.0.0-rc1"`, `"3.0.0-experimental"` parse correctly.

### 8.2 Integration

- Two nodes (same impl, same version): announce β†’ registry shows both.
- Two nodes (same impl, different versions): registry shows both; federation negotiates highest compatible.
- Run conformance suite against the reference impl: must pass `core/*` sections by definition (the suite is built to match the spec).

### 8.3 Spec-document tests

- `test_protocol_documents_present` β€” every protocol document referenced in `protocol/README.md` exists.
- `test_protocol_version_consistent` β€” `protocol/VERSION` matches the `default_announce_version` in code.
- `test_changelog_format` β€” `protocol/CHANGELOG.md` parses as a sequence of versioned entries with semver-valid ordering.

### 8.4 Negative

- Malformed descriptor β†’ `protocol_descriptor_invalid`.
- Federation peer announces protocol `99.0.0` β†’ registry stores it, federation negotiation declines.

---

## 9. Cross-references

- **All Phase 1, 2, 3 modules** β€” they collectively *are* the protocol. M32's job is the meta-layer.
- **Phase 2 M14 Federation** β€” federation manifest carries protocol version; negotiation uses M32's compat rules.
- **Phase 3 X09 Conformance Suite** β€” produces the data that M32's report capability surfaces.

---

## 10. Open research questions

1. **Independent implementation.** The protocol is real only when a second implementation exists. v3.0 ships only the reference. A small "minimal HearthNet" written in Go or Rust as a contrast implementation would prove the spec is implementable from the documents alone. Concrete next step, but not in v3.0.

2. **Formal verification of wire formats.** TLS-style formal proofs of the federation handshake and capability-bus dispatch would be valuable. Out of v3.0 scope; documented as a research direction.

3. **Governance bootstrapping.** "Christof decides" is fine for now and honest about the project's state. Transitioning to a multi-maintainer model needs a path β€” a Tech Steering Committee, a foundation, or simply a documented succession plan. Currently undefined.

4. **Standards-body engagement.** If the protocol matures, IETF (for federation/transport) and W3C (for capability-bus semantics if they look RPC-like) are plausible homes. v3.0 deliberately avoids premature standards engagement; the bar is "second implementation exists and is interoperable".

5. **Legal entity.** ki-fusion-labs.de is currently the operating entity. Whether a separate legal entity (e.V., foundation) is needed for a multi-vendor protocol is a real question. Out of code scope.

6. **Trademark and naming.** "HearthNet" as a trademark is undefined; the protocol could be renamed to something more obviously generic at standardisation time. The reference impl can keep the name.

7. **Optionality flags vs separate profiles.** A node might support `core` only, or `core + federation`, or everything. Whether to model this as per-capability optionality (current approach) or named profiles (`HearthNet-Core`, `HearthNet-Federated`, `HearthNet-Civdef`) is a design question that needs feedback from a second impl team.

8. **Conformance suite drift.** The X09 suite is the source of truth for "what does conformance mean"; the protocol documents describe the *intent*. When the two disagree, currently the suite wins (because it's executable). This is pragmatic but not principled. A future version may flip this and use the suite to *test* the documents, with the documents as primary.

---

*Last updated: spec v3.0.*