From d17b206d92039ee2a2d5cfad3d92a16c25eff107 Mon Sep 17 00:00:00 2001 From: dp-web4 Date: Sun, 17 May 2026 18:05:54 -0700 Subject: [PATCH 1/2] docs(spec): resolve C5-G1 casing-authority contradictions (P1/P3/P6) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit presence-protocol.md's normative casing statements were self-contradictory and contradicted the JSON Schemas + conformance vectors §7 binds: - P1 (HIGH): §3 falsely stated tool INPUT is camelCase; schemas require snake_case inputs. Rewrote §3 as a surface-split rule (input snake / output+§5-type camel / §4 resource snake), anchored to the bound schemas. - P3 (MED): §7 had no precedence rule and bound only the vectors JSON. Added a Precedence clause making the Schemas DIRECTORY + vectors normative over prose on any wire-shape/casing disagreement. - P6 (MED): narrowed §5's overbroad "all wire shapes camelCase"; corrected §8 drift row 5 whose "rename to camelCase in v1" aspiration contradicted the §7-bound snake_case conformance vectors (sovereign_lct, chain_length). Zero wire-shape change — artifacts were already correct; only prose was wrong. Remediates the merged C5 audit (PR #204). 1 file, +27/-8. Co-Authored-By: Claude Opus 4.7 (1M context) --- web4-standard/core-spec/presence-protocol.md | 35 +++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/web4-standard/core-spec/presence-protocol.md b/web4-standard/core-spec/presence-protocol.md index 333a846..46ca864 100644 --- a/web4-standard/core-spec/presence-protocol.md +++ b/web4-standard/core-spec/presence-protocol.md @@ -97,10 +97,19 @@ via content negotiation, but this is not required for v0. ## 3. Tool surface -All tool calls follow standard MCP JSON-RPC semantics. The wire -format for tool input arguments is **camelCase** JSON; tool output -is also camelCase. Timestamps are ISO-8601 UTC strings. UUIDs are -RFC 4122 v4 hex with dashes. Session IDs are UUIDs. +All tool calls follow standard MCP JSON-RPC semantics. Wire casing +is split by surface and is fixed by the JSON Schemas in +`web4-standard/schemas/presence-protocol/` (normative — see §7): + +- **Tool input arguments are `snake_case`** (`plugin_id`, + `host_agent`, `action_id`, …), as the input schemas require. +- **Tool output and all §5 type-catalog shapes are `camelCase`** + (`sessionId`, `softLct`, `protocolVersion`, …). +- **§4 resource bodies are `snake_case`** (`sovereign_lct`, + `chain_length`, …), matching the bound conformance vectors. + +Timestamps are ISO-8601 UTC strings. UUIDs are RFC 4122 v4 hex +with dashes. Session IDs are UUIDs. The eight tools below MUST be implemented by a conforming presence layer. @@ -426,9 +435,12 @@ All resource bodies are JSON, mime type `application/json`. ## 5. Type catalog -All wire shapes use **camelCase keys** regardless of the source -language's native convention. Languages map to their native casing -via serializer hints. +The type-catalog shapes below — and all tool **output** shapes — +use **camelCase keys** regardless of the source language's native +convention. Languages map to their native casing via serializer +hints. This camelCase rule does **not** extend to tool *input* +arguments or §4 resource bodies, both of which are `snake_case` +per §3 and the bound schemas/vectors. ### 5.1 Session @@ -610,6 +622,13 @@ A conforming SDK implementation MUST: present in tool results. 4. Pass the conformance test scenarios against a reference daemon. +**Precedence.** Where this document's prose and the JSON Schemas +at `web4-standard/schemas/presence-protocol/` (or the conformance +vectors bound in item 5) disagree about a wire shape — including +key casing — the Schemas and vectors are normative and the prose +is in error. The Schemas directory is normatively bound by this +clause, not only the vectors JSON. + Conformance does not require implementing the v0 policy engine stub literally; an implementation MAY return real policy decisions earlier than the spec mandates, provided the shape @@ -628,7 +647,7 @@ honesty about where it isn't yet held. | `TrustState` is missing `entityId`, `successCount`, `successRate` in all SDKs | All 3 SDKs | Add fields — covered by `1a-4`. | | Error codes `policy_denied`, `vault_denied`, `invalid_role` referenced by SDKs but never emitted by daemon | Daemon | Emit them when the policy engine lands in v1. | | `WitnessEntry.timestamp` is a string in SDK types but parsed as `chrono::DateTime` in Rust | Rust SDK | Internal — wire format is the string. No spec change. | -| Daemon's `hestia://society/state` resource returns `trust_states_known` (snake_case) | Daemon | Rename to `trustStatesKnown` for camelCase consistency in v1. | +| Daemon's `hestia://society/state` resource returns `trust_states_known` (snake_case) | None — not drift | §3/§4.1 fix `snake_case` as the normative casing for resource bodies, consistent with the §7-bound conformance vectors (`sovereign_lct`, `chain_length`, …). No rename: the earlier camelCase aspiration contradicted the bound vectors. | --- From 94cb0043e2c8b4663fb4195bd5e173f2ec6eb707 Mon Sep 17 00:00:00 2001 From: dp-web4 Date: Sun, 17 May 2026 18:12:56 -0700 Subject: [PATCH 2/2] docs(spec): resolve C5-G3 localized staleness (P4/P5/P7/P9) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four independent one-spot fixes from the C5 presence-protocol internal-consistency audit (PR #204): - P4 (MED): §3.1 output example pinned stale `protocolVersion: 0`; updated to `1` to match §2's v1 declaration and the conformance vectors. - P5 (MED): §5.4 PolicyResult type-catalog entry lagged the §3.4 tool surface — added `status`, `nextPollMs`, and documented `enforced`. Cross-references §3.4.1 wait protocol. - P7 (LOW): §2 link text "tool/connect" → `hestia_connect` with correct in-doc anchor. - P9 (LOW): §3.1 error list for `hestia.invalid_role` omitted the §6.1 reservation caveat (v1+; v0 daemons may emit `hestia.internal_error` instead). Zero wire-shape change — only prose/examples brought in line with existing schemas and normative sections. Complements the G1 casing- authority commit (same branch). Co-Authored-By: Claude Opus 4.6 --- web4-standard/core-spec/presence-protocol.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/web4-standard/core-spec/presence-protocol.md b/web4-standard/core-spec/presence-protocol.md index 46ca864..6d4292c 100644 --- a/web4-standard/core-spec/presence-protocol.md +++ b/web4-standard/core-spec/presence-protocol.md @@ -84,7 +84,7 @@ This protocol is versioned with a single integer `protocolVersion`. change to error code semantics, requires a version bump.** The daemon advertises its `protocolVersion` in the -[`tool/connect`](#31-tool-connect) response. SDKs MUST expose a +[`hestia_connect`](#31-hestia_connect) response. SDKs MUST expose a `PROTOCOL_VERSION` constant matching the version they implement. SDKs SHOULD emit a warning on connect if their version differs from the daemon's; they SHOULD NOT refuse the session — forward @@ -148,12 +148,12 @@ same plugin_id as synthetic for the lifetime of that record. "sessionId": "97a3-...", "softLct": "lct:web4:session:abc123", "assignedRole": "citizen", - "protocolVersion": 0 + "protocolVersion": 1 } ``` **Errors:** -- `hestia.invalid_role` — the requested role is not available to plugins +- `hestia.invalid_role` (v1+) — the requested role is not available to plugins; v0 daemons MAY emit `hestia.internal_error` instead (see §6.1) - `hestia.internal_error` — connection setup failed ### 3.2 `hestia_begin_action` @@ -493,12 +493,18 @@ per §3 and the bound schemas/vectors. "policy:policy:", "decision:deny", "rule:deny-destructive-commands" - ] + ], + "status": "decided", + "nextPollMs": null } ``` `decision` is one of `"allow"`, `"deny"`, `"warn"`. `ruleId` and `ruleName` are `null` on default-policy decisions. `policyId` is -the v0 alias of `ruleId` retained for back-compat. +the v0 alias of `ruleId` retained for back-compat. `enforced` is +`true` when the policy engine actively blocked or allowed the +action (vs. a default pass-through). `status` and `nextPollMs` +support the wait protocol (§3.4.1): synchronous engines always +return `"decided"` / `null`. ### 5.5 TrustState