18. Known Limitations at v1.0 (normative in the sense that they MUST NOT be denied)#
These are real, found during implementation, and stated so nobody rediscovers them as surprises. Each is either accepted for v1.0 or has a named future path.
- Handoff-guard coverage is lookahead-bounded (H11, §9.6). The hub's end-velocity bound needs the next segment already scheduled. A client's scheduling lookahead therefore sets the coverage: the bound can act only while the current segment is shorter than that lookahead. It correlates usefully with the pathology it targets — an oversized spline tangent implies a steep chord, and a steep chord over bounded displacement implies a short segment — but that is a correlation, not a guarantee. Long segments are not bounded. Raising a client's lookahead is the direct widener; the hub's own legality checks are the backstop.
- (Struck by RFC-065: device-authored EVENT kinds are labeled by the entry-level
event_kindstable and a channel's purpose by the entry-levelrole, §8.1 and §9.4. The number is kept so later items keep their citations.) - No safety-EVENT kind exists for the override and
home_requiredmodes (§11.1). This is by decision, not omission: they are latched modes, not stop edges, and an edge kind would imply an operator action that hub-side reconciliation did not have. If a mode edge is genuinely wanted it is an additive kind. - Reboot-commit is specified but unproven.
reboot_in_msand theREBOOTINGGOODBYE code are allocated and normatively described (§9.3), but no reference implementation emits them yet. Treat as a specified extension point, not as field-tested behavior. - The reference shedding implementation exercises only the STATE rows. The §10.4 table is normative in full, but the reference hub currently applies it to STATE pushes only; the STREAM decimation rows and the segment-class rows are specified and unit-tested rather than field-exercised. Implementers writing a STREAM-shedding hub are the first users of those rows.
- Event replay is catalog-gated but single-ring in the reference hub. A device declaring
replay_depthon an EVENT channel other than the log channel gets no replay from the reference implementation unless it wires its own ring. The rule (§9.4) is general; the reference coverage is not. - The frozen conformance mini-catalog carries no §8.8 annotations and no safety INTENT channel. Consequently the golden vectors do not cover per-op
access,option_access, the role exemption, or any settings-metamodel annotation. Those are covered by behavioral tests and device catalogs only. Extending fixture coverage is a v1.1 candidate and would, by construction, move the frozen pins — which is why it was not done at the tag. - Blob namespace validity is now specified (RFC-049e), still not shipped. §8.4 specifies NACK
INVALID_NAMESPACEfor ablob.nsvalue outside every registered/device-defined namespace, distinct fromCHUNK_UNAVAILABLEfor a valid namespace's missing store/slot. Phase D landed (RFC-042 staleness, RFC-045 hub behavior,source.background_run) without this item: the reference hub still answers an unregisterednswithCHUNK_UNAVAILABLE— observably safe, but not the specified code. Implementation: open, no phase currently owns it. - The grammar-level MALFORMED rule is now stated precisely (RFC-049e), and the reference hub was already compliant. The earlier "a full BLOB_REQ carrying
chunksis malformed" framing named a state with no independent wire representation — "full" is derived from the absence ofchunks, so that exact combination could never be encoded, and no decoder could reject it. §8.4 now states the two rules that ARE representable and MUST be enforced: an emptychunksarray is MALFORMED, and a catalog-namespace (ns = 0) request carryingstore_idorslotis MALFORMED.decodeBlobReq(blob_req.hpp) already rejected both shapes asDecodeError::Malformedbefore RFC-049 restated the rule precisely — its own header comment cites the older RFC-022.6, not RFC-049. Nothing to implement here; recorded so the tightened wording is not mistaken for unshipped work. - Packed layouts have no 64-bit integer type. An 8-byte identifier in a packed slot is two
u32fields (§12.7). Documentation that says "u64" in a packed context means exactly that. - Crypto is a seam, not a battery. A conforming library MAY ship with stub sign/verify. Hub signing (§12.5) and therefore evil-twin detection exist only where the application injects a real implementation; a client MUST treat an absent signature per H9 and MUST NOT assume the capability is present because the protocol defines it.
- The trust ledger has no wall clock (H7, §7.2).
first_seen/last_seenare frequently zero, and a device that never reports a version can never trip the tripwire. - Cleartext transport bounds everything (H4). Every trust mechanism here is designed to be useful without confidentiality — which is why the hub signature works without secrecy and why proof presentation exists — but the ceiling is "honest LAN" until a secure transport lands in v2.
- One relay hop only (§14.3).
- Preset/store device backends are optional and largely unimplemented. The blob verb, the STORE class and the trust-ledger store are specified and implemented; general device preset stores are a specified mechanism with no reference device backend yet.
- WELCOME
identity(37) is live forproduct/fw_version/hub_name; theinfosub-map is not. RFC-016(a) landed: the reference codec encodes the identity sub-map and the reference hub populatesproductandfw_version, so "what firmware is this machine running" now HAS an in-band answer at its one wire home (§4.2-4, §6.3). The device-definedinfosub-map (sub-key 4) remains unimplemented — decoders skip it per §4.3. A client MUST still tolerate a hub with no identity at all; §6.3's tolerance rule is unchanged. - The
session-rosterchannel is allocated and described but not built. No reference catalog builder declares it, so the roster snapshot of §12.7 — and with it the "a late joiner learns existing sessions' names" property that offsets §9.4's no-replay rule — is specification, not shipped behavior. The session-events channel and the administration ops around it are implemented; the roster STATE they complement is not. - Action-intent resets have vocabulary but no reference verb.
action.<name>andmeta.reset_genare registered and specified (§9.3); no reference hub exposes a reset as an INTENT yet, so the observable-reset rule is untested in the field. - Registry
ref:fields lag this document's numbering. Inserting §6.4 (readiness) and splitting §12.2 into §12.3–§12.5 shifted several pointers: entries citing §6.4/§6.5/§6.6/§6.8 mean §6.5/§6.6/§6.7/§6.9, and entries citing §12.2 for pairing, token presentation or signing mean §12.3, §12.4 and §12.5 respectively. Values are unaffected (§5.7). Correcting theref:strings requires regenerating the constants header, so it is a follow-up commit rather than part of this document. curve_familystep(3) is declarable but has no reference renderer. The registry now says so machine-checkably:status: reserved(RFC-049a) — the number is allocated and never renumbered, but the reference engine has no step renderer yet, so astepdeclaration currently renders as quintic, and the reference delegate's grant echo therefore reportsc2_quinticfor astepwish even under a follow-client policy: the echo is what the machine will do (§9.6's effective-family rule applied all the way down), never a claim about a renderer that does not exist.requested_curve_family(48, RFC-049b) makes that gap directly visible once a hub emits it: a client seesrequested=step, effective=c2_quinticas two present keys, not an inference. When a step renderer lands, only the delegate's mapping changes,statusflips toactive, and declaring clients see the echo flip tostep.- The
source.background_runper-source setting (RFC-045, formally registered by RFC-048) is now shipped. The reference firmware exposes it as an ordinarypattern-state(0x1200) settings-metamodel field, defaultingfalse(the pattern generator stops when its owning session's source ownership is released, unless a later session re-activates it) — persisted to NVS like the device's other settings. A client MUST still not assume every hub has adopted it; the setting's presence, per the settings metamodel, is how a client tells whether a given hub has. - BLE GATT, UDP discovery, and BLE→WS cross-transport migration are shipped and live-verified. RFC-043/046 pin the BLE identity, advertising payload,
ws_port/ipv4WELCOME keys, and the UDP probe/reply. Both landed in Phase E (src/comms/ValenceBleTransport.*,src/comms/ValenceUdpDiscovery.*) and are live on the deployed reference hub: a live UDP probe/reply exchange confirmed unicast, broadcast, and the 1-reply-per-source-per-second rate limit against the real device, and a live BLE scan confirmed the advertised name, service UUID, and primary/scan-response payload split, exactly as designed. The live-GATT-session and migration residuals BOTH cleared 2026-07-28: a Tauri 2 Android client held a live GATT session with full control against the reference hub, then performed the §6.3 BLE→WS mid-session upgrade handoff — oneinstance_id, session preserved across bindings [operator-verified 2026-07-28]. One residual remains real: generic control-frame fragmentation over a small (unnegotiated) BLE ATT MTU is unimplemented — a control frame that still does not fit after MTU negotiation simply fails to send rather than being split. The WS→BLE direction of migration remains unexercised (no known client wants it; the rule is direction-agnostic by construction). - RENDERING.md's vocabulary is wired onto the reference catalog, and the reference client renders from it. RFC-048 landed the spec/registry text; the reference catalog, Nucleus
flagship_p4/src/hub/ValenceCatalog.h, carries entry-levelrank(key 16), field-levelrank/aspect/scope/provenance/unit_id(keys 19-23) andcategory(key 10, theui_categoriesvocabulary). Measured there at the RFC-082 landing (2026-10-01, Nucleus e661ab4): 117desc, 47role, 23category, 73rank, 33unit_id, 5aspect, 5scopeand 4provenanceannotations. The client half is Phosphor, the reference renderer (RENDERING.md §13): it builds category tabs and rank-gated cards from the catalog and derives each field's archetype by the RENDERING.md §8.2 table, per renderer class. Neither half is evidence that any other hub or client does; the Completeness Doctrine's fallback rule (RENDERING.md §14d) is what keeps a client that has not adopted the vocabulary conformant. - Blob backpressure is shipped as of fw 2.1.81 (RFC-050); completion signaling is not. §8.4's backpressure table and
blob_chunks_in_flightreplace the earlier advisory "a hub MAY pace... MUST respect backpressure" wording the spec fresh-eyes panel found gave no binding-independent signal to code against; BLOB_DONE (0x20) replaces "the sender just stops and hopes" with a positive, idempotent completion signal. The hold-not-drop half landed in the HEAP RELIEF pass:ValenceAsyncWsTransport::write()gatesBLOB_CHUNKonlimits::blob_chunks_in_flight(4) via the same queue-depth check the STATE/STREAM shed-early path already used, holding rather than arming the control-stall timer — live-verified on-device, the catalog BLOB transfer (129/129 chunks) completes cleanly under load that used to close the session. Still not shipped: the hub does not abort a sustained-congestion transfer with NACKBUSY, and no reference client or hub emits BLOB_DONE — do not infer either from the backpressure fix above.