Write down the mechanics that are easy to get wrong - #102
Merged
Merged
Conversation
Four things lived only in one maintainer's head: docs/api.md is generated and a test fails when it is stale, the public surface is an allowlist in tools/api_contract.py, check_share_safety.py gates identifiers in CI, and a local virtualenv matches neither the Python matrix nor the dependency floor. Judgement calls stay in docs/use-of-ai.md and docs/firmware-families.md, which this links rather than restates. The three reference stacks are named by their public upstream and pin so a reader can fetch their own; none is checked in here, and none substitutes for hardware.
Reads and writes against a real appliance, outside the bridge, have a handful of preconditions that are invisible until one is missed: the bridge holds the appliance's one DTLS session, Docker bridge NAT drops replies from the ephemeral port these devices answer on, and a session with no reader thread times out every exchange after a clean handshake. Each of those has cost a debugging session, and each reads as a dead device rather than a harness fault. Writing them down beside the session lifecycle turns a stall into something checkable.
The table named upstream iotivity 1.2.1 as the pin used here, two lines under a rule that a mechanism claim has to cite the stack the appliance actually runs. These appliances run Samsung's fork of it, vendored in TizenRT, and ca_adapter_net_ssl.c differs between the two by 1295 lines — enough that an upstream line number lands somewhere unrelated in the fork. As written the table sent a reader to the tree that produced the published 5684 error. The fork is now the first row with its pin and sparse-checkout command, upstream is kept and labelled contrast only, and mbedTLS is added: the build links TizenRT's own 2.7.8 rather than the 2.4.0 the iotivity extlib's prep.sh pins, and the DTLS behaviour these appliances show is only legible across both trees.
QuiteYellow
added a commit
that referenced
this pull request
Sep 19, 2026
The peerId citation pointed at the pin table in AGENTS.md, which arrives with #102 and is not on main yet. test_links_between_markdown_files_ resolve maps a blob/main URL back to a local path, so the link failed the suite on this branch and would have coupled two independent changes in the merge order. The line names the fork and gives both trees' line numbers itself, which is what a reader needs at that point anyway.
The lifecycle bullet pointed at local-tools/probe_paths.py, which is gitignored, so it named a file no contributor can open. The bullet already states the lifecycle it was illustrating. The safety section said an appliance wedges "once its session table fills". That is the RFC 6347 section 4.2.8 eviction mechanism, and the audit of the stack these appliances run found no peer cap, no idle timeout and no LRU anywhere in it. The silence is measured; that cause is not. It now says what was seen, which is minutes of silence after repeated handshakes in quick succession. The line count between fork and upstream does not reproduce at the pin the table gives. At e590f30ab against 1.2.1 it is 1371 changed lines, or 1205 ignoring whitespace; the 1295 in the text matches neither, and most likely came from the master checkout the tree held before it was re-pinned. The point survives without a figure.
The reference table led its first row with "IoTivity classic, Samsung's fork". Read quickly, that is a family name, and the family name sends a reader to upstream. Upstream is the wrong tree for these appliances. It sets VERIFY_REQUIRED and carries no ECDHE-ECDSA-AES128-GCM-SHA256, yet the appliances complete a session on an empty client certificate using exactly that suite. So the row is now TizenRT's iotivity_1.2-rel fork, its path runs down to that directory, and the sentence below states what a reader loses by following the family label: a tree that answers this question differently.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four things lived only in my head, and each one has cost time to rediscover:
docs/api.mdis generated.tests/test_public_api_contract.pyfails when it is stale, so the symptom is a test failure with no obvious connection to the docstring that caused it.tools/api_contract.py, so a new exported name needs a deliberate edit there. I hit this addingPeerInitiatedHandshakeError.tools/check_share_safety.pygates identifiers in CI as the "Share safety" job, and a value that is already public belongs in itsSAFE_UUIDSset with the reason.--no-deps, and the file gives theuv runincantation for pinning an interpreter when output depends on one.The judgement calls stay where they already are.
docs/use-of-ai.mdcarries the rules about evidence and appliance safety,docs/firmware-families.mdcarries how to tell which stack a claim may cite, and this file links both, since a duplicated rule is a second place to update.The three reference stacks get a table with their public upstream and the pin used here, so a reader can fetch their own copy. None is checked into this repository, and none is a substitute for hardware.
AGENTS.mdoverCLAUDE.mdfor the filename: it is the cross-tool convention, and.gitignoreexcludes.claude/anyway.One section deliberately duplicates: appliance safety. An assistant reading only the root file should not have to follow a link before it learns it can brick hardware.
Two commits added after the first review pass.
Driving the library by hand. Reads and writes against a real appliance, outside the bridge, have preconditions that are invisible until one is missed: the bridge holds the appliance's one DTLS session, Docker bridge NAT drops the replies these devices send from an ephemeral port, and a session with no reader thread times out every exchange after a clean handshake. Each of those reads as a dead device rather than a harness fault, and each has cost a session to rediscover.
The reference table pointed at the wrong tree. It named upstream iotivity
1.2.1as the pin used here, two lines under the rule that a mechanism claim has to cite the stack an appliance actually runs. These appliances run Samsung's fork of it, vendored in TizenRT, andca_adapter_net_ssl.cdiffers between the two by 1295 lines — enough that an upstream line number lands somewhere unrelated in the fork. As written the table sent a reader to the tree that produced the published 5684 error. The fork is now the first row with its pin and a sparse-checkout command, upstream is kept and labelled contrast only, and mbedTLS is added: the build links TizenRT's own 2.7.8, not the 2.4.0 the iotivity extlib'sprep.shpins, and the DTLS behaviour these appliances show is only legible across both trees.#103 and #104 depend on this one: both cite the pin this table now carries.