tcxp://tcxp.org/rule/0 A tcxp address is tcxp: followed by a ground and a pointer. The ground is / (virtual), // (network) or /// (local). An @ at the start of the pointer's second segment makes the address a call. Categories: Unverified, Unpublished, Ground, Document, Protocol Every combination of space and call: Address Space Ground Call Pointer -------------------------------------- ------- ------ ---- ------------------------------ tcxp:/example.com/fn/check-forecast virtual / no example.com/fn/check-forecast tcxp:/example.com/@fn/check-forecast virtual / yes example.com/@fn/check-forecast tcxp:/foo/bar virtual / no foo/bar tcxp:/foo/@bar virtual / yes foo/@bar tcxp://example.com/fn/check-forecast network // no example.com/fn/check-forecast tcxp://example.com/@fn/check-forecast network // yes example.com/@fn/check-forecast tcxp://foo/bar network // no foo/bar tcxp://foo/@bar network // yes foo/@bar tcxp:///example.com/fn/check-forecast local /// no example.com/fn/check-forecast tcxp:///example.com/@fn/check-forecast local /// yes example.com/@fn/check-forecast tcxp:///foo/bar local /// no foo/bar tcxp:///foo/@bar local /// yes foo/@bar ======================================================================== tcxp://tcxp.org/rule/1 The Typed Context Protocol (tcxp) is a set of guarantees, enforced by logical rules, to observe, measure, and engineer interactions with Typed Context Objects over time. Categories: Unverified, Unpublished, Ground, Document, Protocol As a protocol, tcxp allows any design choice except breaking these rules. Breaking a rule breaks the protocol. ======================================================================== tcxp://tcxp.org/rule/2 Every tcxp address starts with tcxp:, in lowercase, with nothing before it. Categories: Unverified, Unpublished, Ground, Document, Protocol The scheme name tells any software that the rest of the string is a tcxp address. tcxp is provisionally registered with IANA (https://www.iana.org/assignments/uri-schemes/prov/tcxp) (2026-10-09). Software reading an address should also accept an uppercase scheme, since URI schemes are case-insensitive, but addresses are always written in lowercase. ======================================================================== tcxp://tcxp.org/rule/3 Two slashes after tcxp: followed by a domain mean a real address. The domain owns it, and the address resolves through that domain. tcxp:///? resolves at https:///?, with the path and query copied character for character. Categories: Unverified, Unpublished This works the same way as https://: whoever controls the domain controls every name under it, with no registration needed. The domain is written in lowercase, with no user name or port, for example tcxp://example.com/…. With QUERY, the state pair is removed from the URL and its decoded value is sent as the body; with GET, it stays in the URL (tcxp://tcxp.org/rule/12). ======================================================================== tcxp://tcxp.org/rule/4 One slash after tcxp: means a virtual address. It has no host and is never fetched. Categories: Unverified, Unpublished A virtual address names something that exists only within the document or space where it was declared, such as a draft, a test, or private state, for example tcxp:/notes/idea-1. ======================================================================== tcxp://tcxp.org/rule/5 Names that every implementation shares are real addresses on tcxp.org, maintained by the W3C Typed Context Protocol Community Group. Categories: Unverified, Unpublished The shared vocabulary covers what all tcxp software must agree on, written as tcxp://tcxp.org/. A name is added to it only through the Community Group, and once published it is never removed or changed in meaning. Where a good URI already exists elsewhere, use that instead of adding a new shared name. The first path segment web is reserved for tcxp.org's own web pages, such as https://tcxp.org/web/signup, and is never a registry name. ======================================================================== tcxp://tcxp.org/rule/6 A path is a series of segments separated by /. Each segment is percent-encoded as tcxp://tcxp.org/rule/29 describes, and segments are case-sensitive. Categories: Unverified, Unpublished A path names a thing, and anything with its own identity gets its own path, for example tcxp://example.com/forecasts/q3/v2. Every segment has at least one character, so a path never contains // and never ends with /. Real addresses always have a path after the domain. Forecast and forecast are different segments. Because percent-encoding gives every character exactly one spelling, so does every name: a space is %20, so My Notes.txt is written My%20Notes.txt. ======================================================================== tcxp://tcxp.org/rule/7 A query starts with ? after the path, and & separates its key=value pairs. Parameters come first, then $variables. Categories: Unverified, Unpublished The path names the function, and the query supplies its inputs. The shape is: tcxp:///?=&=&$=&~state= Written out in full, with an empty context: tcxp://example.com/fn/check-forecast?currency=usd&quarter=q3&$region=us&~state=%7B%22context%22%3A%7B%22decide%22%3A%5B%5D%2C%22intent%22%3A%5B%5D%2C%22observe%22%3A%5B%5D%2C%22reason%22%3A%5B%5D%2C%22trace%22%3A%5B%5D%7D%7D What the state pair holds is tcxp://tcxp.org/rule/24, and where it goes is tcxp://tcxp.org/rule/11. ======================================================================== tcxp://tcxp.org/rule/8 Two tcxp addresses name the same thing only when they are identical, character for character. Categories: Unverified, Unpublished Comparing addresses is a plain string check, which is what lets an address serve as a facet value: equal strings are a MATCH, anything else is NO MATCH. The one exception is the scheme, which is lowercased before comparing (tcxp://tcxp.org/rule/2). tcxp://example.com/forecasts/q3 and tcxp://example.com/forecasts/quarter/3 are both valid, but they are different addresses, so each owner settles on one form for each thing. ======================================================================== tcxp://tcxp.org/rule/9 An address's identity is the address with the state pair removed. Categories: Unverified, Unpublished The state pair (tcxp://tcxp.org/rule/24) carries state, and state changes from call to call. If it counted toward identity, the same function called with different state would never match itself. Two addresses that differ only in their state pair name the same thing. ======================================================================== tcxp://tcxp.org/rule/10 The context is one JSON object with exactly five lists: intent, observe, reason, decide and trace. It is held by the context key of the state pair (tcxp://tcxp.org/rule/24), either inline or in a stored copy. Categories: Unverified, Unpublished All five lists are always present, even when empty, so a reader never has to guess whether a missing list means "none" or "not sent." Each entry in a list is a row (tcxp://tcxp.org/rule/25). The address in a row is a reference, and reading the context never fetches it. For example, here is the state pair for a context with one intent, decoded so it can be read: ~state={"context":{"decide":[],"intent":[{"ref":"tcxp://example.com/intents/forecast-in-usd","timestamp":"2026-10-11T13:06:00.000Z"}],"observe":[],"reason":[],"trace":[]}} Written in the address, percent-encoded: ~state=%7B%22context%22%3A%7B%22decide%22%3A%5B%5D%2C%22intent%22%3A%5B%7B%22ref%22%3A%22tcxp%3A%2F%2Fexample.com%2Fintents%2Fforecast-in-usd%22%2C%22timestamp%22%3A%222026-10-11T13%3A06%3A00.000Z%22%7D%5D%2C%22observe%22%3A%5B%5D%2C%22reason%22%3A%5B%5D%2C%22trace%22%3A%5B%5D%7D%7D ======================================================================== tcxp://tcxp.org/rule/11 The state pair is always the last pair in the query, and an address has at most one. Categories: Unverified, Unpublished The shape, with other pairs and with the state pair as the only pair: tcxp:///?=&=&~state= tcxp:///?~state= Fixing its place means the state can be found and removed without reading the rest of the query, which is how an address's identity is found (tcxp://tcxp.org/rule/9). Everything before the state pair and the & or ? in front of it is the identity; the pair itself is the state. ======================================================================== tcxp://tcxp.org/rule/12 Over HTTP, a tcxp address is resolved with the QUERY method. The address's identity is the request target, and the value of its state pair is the request body, sent as JSON. A server also answers GET on the same address, and a GET with the state pair in the URL is treated exactly like a QUERY with that state in the body (tcxp://tcxp.org/rule/14). Categories: Unverified, Unpublished QUERY (RFC 10008 (https://www.rfc-editor.org/rfc/rfc10008)) is safe and idempotent like GET, but carries a body, so the state has no length limit. The body is plain JSON, not percent-encoded; values in the request target are still encoded, because the target is a URI. The body is the decoded value of the state pair, the wrapped object {"context": …} (tcxp://tcxp.org/rule/24), with media type application/json. Sending the state in the body or inline in the state pair is the same call, because both have the same identity (tcxp://tcxp.org/rule/9). The body is the wrapped object, not the ~state key or the bare context. A browser calling a server on another origin asks it first, so that server must list QUERY in Access-Control-Allow-Methods. ======================================================================== tcxp://tcxp.org/rule/13 A written-out tcxp address may carry the context inline in its state pair only while the whole address is at most 8,000 characters. Longer state is not inlined. Categories: Unverified, Unpublished An address written out, such as in a link, a document or a facet value, has to survive every piece of software that handles it. 8,000 octets is the length that HTTP asks all senders and recipients to support (RFC 9110, section 4.1 (https://www.rfc-editor.org/rfc/rfc9110#section-4.1)); longer addresses are cut off or refused by some servers, proxies and tools. Beyond that length, the state is stored and the address carries a reference to it instead (tcxp://tcxp.org/rule/15). ======================================================================== tcxp://tcxp.org/rule/14 The same call can be written as an address or sent as a request. A written address carries the state in its state pair, percent-encoded: inline, or as a stored copy's address (tcxp://tcxp.org/rule/15). A QUERY request carries the state as plain JSON in its body. Categories: Unverified, Unpublished A written address is what people click, share and store. It is always a URI, so its state must be percent-encoded, and a browser can only send it with GET, so the address bar never carries a request body. A request is what software sends (tcxp://tcxp.org/rule/12), and its body never appears in the address bar, browser history or server URL logs. Both forms have the same identity (tcxp://tcxp.org/rule/9), so they are the same call. ======================================================================== tcxp://tcxp.org/rule/15 When inline state would make a written address longer than 8,000 characters, the state is stored separately, and the context key of the state pair holds the stored copy's tcxp address instead. Categories: Unverified, Unpublished Decoded so it can be read, the written address then looks like this: tcxp://example.com/fn/check-forecast?quarter=q3&~state={"context":"tcxp://example.com/contexts/sha256-350250820add930b504ea1b632831165b010accaaeae010ea432648c37b09a90"} Written out in the address, the value is percent-encoded like any other value: tcxp://example.com/fn/check-forecast?quarter=q3&~state=%7B%22context%22%3A%22tcxp%3A%2F%2Fexample.com%2Fcontexts%2Fsha256-350250820add930b504ea1b632831165b010accaaeae010ea432648c37b09a90%22%7D The stored copy lives at a real address (tcxp://tcxp.org/rule/3) so the receiver can fetch it; a virtual address has no meaning outside the document or space where it was declared. The stored copy is always the wrapped object with the five lists (tcxp://tcxp.org/rule/24). Whoever stores the state controls who may read it. How the stored copy is named is tcxp://tcxp.org/rule/16. ======================================================================== tcxp://tcxp.org/rule/16 A stored copy is named by the SHA-256 hash of its canonical JSON: the last path segment is sha256- followed by 64 lowercase hex digits. A receiver checks the hash before using the state. Categories: Unverified, Unpublished Canonical JSON (RFC 8785 (https://www.rfc-editor.org/rfc/rfc8785)) gives every object exactly one serialization, with keys sorted, so the same state always has the same hash. A stored copy is the wrapped object (tcxp://tcxp.org/rule/24). For the context from tcxp://tcxp.org/rule/10, the stored copy in canonical form is: { "context": { "decide": [], "intent": [ { "ref": "tcxp://example.com/intents/forecast-in-usd", "timestamp": "2026-10-11T13:06:00.000Z" } ], "observe": [], "reason": [], "trace": [] } } and its name is sha256-350250820add930b504ea1b632831165b010accaaeae010ea432648c37b09a90. Because the name is the hash, it never points to different state, and altered state is caught rather than trusted. Hex digits are lowercase so the name has one spelling (tcxp://tcxp.org/rule/8). ======================================================================== tcxp://tcxp.org/rule/17 A spike is an object created by an observation, instructed by an intent. The intent and the observation are the refs of rows in the intent and observe lists of the spike's context (tcxp://tcxp.org/rule/10). Categories: Unverified, Unpublished The intent says what to look for, the observation is the act of looking, and the spike is the object that comes out. Because both are addresses in rows of the context, every spike can be traced back to what asked for it and what made it. For example, decoded so it can be read: state={ "context": { "decide": [], "intent": [ { "ref": "tcxp://example.com/intents/find-yesterday", "timestamp": "2026-10-11T13:06:00.000Z" } ], "observe": [ { "ref": "tcxp://example.com/observations/note-1", "timestamp": "2026-10-11T13:06:04.217Z" } ], "reason": [], "trace": [] } } ======================================================================== tcxp://tcxp.org/rule/18 A spike has exactly four facets, as the keys data, meaning, structure and ground. Categories: Observe, Unverified All four keys are always present, in lowercase with exactly these names, so any reader is guaranteed to find them. A spike with a missing key, an extra key, or a key spelled differently, such as Meaning or world, is rejected. ======================================================================== tcxp://tcxp.org/rule/19 data is the anchor facet: it is what gets matched against the sensor object. meaning, structure and ground are the context facets, built around the anchor. Categories: Observe, Unverified If the sensor object has the rule "MATCH the word yesterday," the anchor is the observed word yesterday. The context facets are then constructed around it: what it means, what shape it has, and what grounds it in the real world. ground holds the real-world conditions a reader must account for before acting on the anchor: a sea captain reads the data to make a decision, and ground says that the freezing temperature of this ocean differs. Only the anchor is matched against the sensor object; the context facets describe the anchor, and are never matched in its place. ======================================================================== tcxp://tcxp.org/rule/20 A sensor object is a JSON object with exactly one key, sensor: an array whose entries each have exactly three keys, trigger, emit and else. trigger is a tcxp address; emit and else are each a tcxp address, or null when there is nothing to do. Categories: Intent, Unverified When the trigger is true, emit is evaluated; when it is false, else is evaluated. All three keys are always present, so a reader never has to guess whether a missing else means "nothing" or "not sent." ======================================================================== tcxp://tcxp.org/rule/21 Logic primitives live at tcxp://tcxp.org/logic//, where is one of string, number, boolean, array or object. A trigger calls one, with its inputs in the query, for example tcxp://tcxp.org/logic/string/contains?word=yesterday. Categories: Unverified, Unpublished ======================================================================== tcxp://tcxp.org/rule/22 The function of a tcxp address is everything before its first ?. Two addresses call the same function when their functions are identical, even if their queries differ. Categories: Unverified, Unpublished This answers a different question from tcxp://tcxp.org/rule/8. Identical addresses name the same thing; identical functions mean the same function, possibly called with different inputs. For example, tcxp://tcxp.org/rule/7?position=7 and tcxp://tcxp.org/rule/7 are different addresses that call the same function, tcxp://tcxp.org/rule/7. ======================================================================== tcxp://tcxp.org/rule/23 Every timestamp is written in ISO 8601 in UTC, with milliseconds and a trailing Z, and is exactly 24 characters long, for example 2026-10-10T16:35:12.345Z. Categories: Unverified, Unpublished The shape is YYYY-MM-DDTHH:MM:SS.sssZ. Milliseconds are always three digits, even when they are zero (.000), and UTC is always written as Z, never as +00:00. Because there is one format with a fixed length, each moment has exactly one spelling, and sorting timestamps as text puts them in time order. ======================================================================== tcxp://tcxp.org/rule/24 The state pair is the ~state key and its value: a JSON object with exactly one key, context, which holds either the context or the tcxp address of a stored copy of it. The value is percent-encoded in the address. Categories: Unverified, Unpublished The value is always wrapped in {"context": …}, with no exceptions; a bare context object or a bare address is never valid, and so is a wrapper with any other key. Decoded so it can be read, the state pair for an empty context is: ~state={"context":{"decide":[],"intent":[],"observe":[],"reason":[],"trace":[]}} and for a stored copy (tcxp://tcxp.org/rule/15): ~state={"context":"tcxp://example.com/contexts/sha256-…"} A stored copy is always the wrapped object with the five lists, never another address, so a reference is followed at most once. Written in the address, the first example is percent-encoded as: ~state=%7B%22context%22%3A%7B%22decide%22%3A%5B%5D%2C%22intent%22%3A%5B%5D%2C%22observe%22%3A%5B%5D%2C%22reason%22%3A%5B%5D%2C%22trace%22%3A%5B%5D%7D%7D ======================================================================== tcxp://tcxp.org/rule/25 Every entry in the five lists of a context is a row: a JSON object with exactly two keys, timestamp and ref. ref is a tcxp address, and timestamp is when the row was written (tcxp://tcxp.org/rule/23). Categories: Unverified, Unpublished What a row refers to always lives behind its address. Nothing else is written inline, so checking a row means checking two fixed keys, one fixed-length timestamp and one tcxp address. A row's position in its list is its index, so rows have no index key. For example, decoded so it can be read: ~state={"context":{"decide":[],"intent":[{"ref":"tcxp://example.com/intents/forecast-in-usd","timestamp":"2026-10-11T13:06:00.000Z"}],"observe":[],"reason":[],"trace":[]}} ======================================================================== tcxp://tcxp.org/rule/26 An Observatron is a bound element, for example an HTML element with a sensor bound to it through data-tcxp. Categories: Unverified, Unpublished Any HTML element whose value can be observed with event listeners, such as a textarea and its value, can be bound to tcxp with the data-tcxp attribute. This rule sets only the principle; what the attribute holds is not defined yet. ======================================================================== tcxp://tcxp.org/rule/27 A query key uses only letters, digits, dots and hyphens, with at least one character, and is case-sensitive. A variable's key is $ followed by such a name. The only other key is ~state. Categories: Unverified, Unpublished Keys are fixed names defined by the spec or by whoever defines a function, never user content. They never need encoding, they sort the same way everywhere, and they can't be mistaken for a variable or the state pair. ======================================================================== tcxp://tcxp.org/rule/28 Within each group of the query, parameters and then $variables, pairs are written in character-code order of their keys, and a key appears at most once. The state pair stays last (tcxp://tcxp.org/rule/11). Categories: Unverified, Unpublished ======================================================================== tcxp://tcxp.org/rule/29 A path segment or a value in an address is percent-encoded so it has exactly one spelling: the characters A–Z a–z 0–9 - . _ ~ stay as they are, and every other byte of its UTF-8 encoding is written as % followed by two uppercase hex digits. A space is %20, never +, and a character from that set is never encoded. Categories: Unverified, Unpublished User content is carried in values exactly as written; decoding returns it unchanged. JavaScript's encodeURIComponent leaves ! ' ( ) * unencoded, so implementations encode those too. ======================================================================== tcxp://tcxp.org/rule/30 Any JSON written in an address is first put in canonical form (RFC 8785 (https://www.rfc-editor.org/rfc/rfc8785)), then percent-encoded. Categories: Unverified, Unpublished Canonical JSON sorts keys and removes whitespace, so every JSON value has exactly one spelling, the same form tcxp://tcxp.org/rule/16 uses for hashing. ======================================================================== tcxp://tcxp.org/rule/31 Every tcxp object and its address correspond one to one: an object has exactly one address, and an address decodes to exactly one object. Converting either way and back gives the original, character for character. Categories: Unverified, Unpublished The one form is fixed by four rules: keys (tcxp://tcxp.org/rule/27), the order of pairs (tcxp://tcxp.org/rule/28), percent-encoding (tcxp://tcxp.org/rule/29) and JSON in values (tcxp://tcxp.org/rule/30). A list's order is part of the object, so two lists with the same entries in a different order are different objects. A reader rejects an address that is not in this one form, rather than correcting it. The object is the JSON exactly as written: addresses inside it are strings, and are never followed when converting between an object and its address. ======================================================================== tcxp://tcxp.org/rule/32 Before a real (//) or local (///) address is published, it can be edited or removed freely. Once published, the address is permanent: it can never be removed or reassigned. What it returns is up to its provider. Virtual (/) addresses are exempt. Categories: Unverified, Unpublished This applies to every real and local address, including entries in the tcxp.org registry. Those are editable until published, like anything else. Virtual addresses are exempt because they exist only within the document or space where they were declared, where they can be overwritten freely. What is permanent is the address itself, not its response. An address may return a different value each time it is fetched, such as a random number or an exchange rate. That is allowed. ======================================================================== tcxp://tcxp.org/rule/33 Three slashes after tcxp: mean a local address: an absolute path to a file on the local machine, for example tcxp:///projects/docs/rules.tcxp. Categories: Unverified, Unpublished This is the same form as file:/// (RFC 8089 (https://www.rfc-editor.org/rfc/rfc8089)): an empty host followed by an absolute path. Relative paths such as ../rules.tcxp are never used. The path follows tcxp://tcxp.org/rule/6, so My Notes.txt is written My%20Notes.txt. Like a real address, a local address is permanent once published (tcxp://tcxp.org/rule/32). ======================================================================== tcxp://tcxp.org/rule/34 A tcxp document is a UTF-8 text file with the extension .tcxp and the media type text/vnd.tcxp. Reading, parsing or displaying it never executes it and never fetches any address it contains. Categories: Unverified, Unpublished A tcxp document is data: it may describe an algorithm or be documentation only. Its syntax is not defined yet. Registration of the media type text/vnd.tcxp with IANA is in progress. ======================================================================== tcxp://tcxp.org/rule/35 When a document or an address is passed to a function, the function decides whether each address in its arguments is a reference or is evaluated. The document never decides this. Categories: Unverified, Unpublished A reference is passed as it is, and nothing is fetched or run. Evaluating an address can run an algorithm locally, or resolve it at the domain it names with QUERY (tcxp://tcxp.org/rule/12), which sends the state, including its context, to that domain. ======================================================================== tcxp://tcxp.org/rule/36 Every value in a query is a JSON value, in every address: real, local and virtual. A string keeps its double quotes. Categories: Unverified, Unpublished Like any JSON in an address, a value is put in canonical form and then percent-encoded (tcxp://tcxp.org/rule/30). For example, Bob, who likes Alice and is 25, decoded so it can be read: tcxp://example.com/people/add?details={"age":25}&likes="Alice"&name="Bob" Written in the address: tcxp://example.com/people/add?details=%7B%22age%22%3A25%7D&likes=%22Alice%22&name=%22Bob%22 "Alice" and "Bob" are strings, 25 is a number, and {"age":25} is an object. The keys are in character-code order (tcxp://tcxp.org/rule/28). ======================================================================== tcxp://tcxp.org/rule/37 A governor is software that evaluates tcxp addresses: given an address and its state, it decides whether to act, ask a question, or halt. Each governor holds one root object, tcxp, which starts empty and lasts as long as the governor runs. Categories: Protocol, Unverified, Unpublished Writing, reading or parsing an address never evaluates it (tcxp://tcxp.org/rule/34). A function decides which addresses in its arguments are evaluated (tcxp://tcxp.org/rule/35), and a governor carries that out. Evaluating a real address resolves it at its domain (tcxp://tcxp.org/rule/3), and evaluating a local address reads its file (tcxp://tcxp.org/rule/33). Evaluating a virtual address that starts with @ reads or calls a member of the governor's tcxp (tcxp://tcxp.org/rule/38). A virtual address without @ is never evaluated. Governors never share a tcxp; for example, two browser tabs each have their own. ======================================================================== tcxp://tcxp.org/rule/38 A virtual address (tcxp://tcxp.org/rule/4) whose path starts with @ names a member of the governor's root object, tcxp (tcxp://tcxp.org/rule/37). Categories: Protocol, Unverified, Unpublished tcxp:/@memo is tcxp.memo, and each further segment names a member of the one before it, so tcxp:/@memo/message is tcxp.memo.message. In an address, @ is percent-encoded (tcxp://tcxp.org/rule/29), so tcxp:/@memo is written tcxp:/%40memo. ======================================================================== tcxp://tcxp.org/rule/39 The slashes after tcxp: follow standard URI syntax (RFC 3986, section 3 (https://www.rfc-editor.org/rfc/rfc3986#section-3)): // is followed by a host, /// is an empty host followed by an absolute path, and / is an absolute path with no host. Categories: Unverified, Unpublished These are the same forms file: uses (RFC 8089 (https://www.rfc-editor.org/rfc/rfc8089)): file:///etc/hosts has an empty host, and file:/etc/hosts has no host. Both name the same file. In tcxp, the three forms mean different things: a real address (tcxp://tcxp.org/rule/3), a local address (tcxp://tcxp.org/rule/33) and a virtual address (tcxp://tcxp.org/rule/4). ======================================================================== tcxp://tcxp.org/rule/40 The rule set is itself a spike: data holds the rules, meaning says what they are, structure holds their JSON Schema, and ground tells the reader how to work with them in the real world. Categories: Observe, Unverified, Unpublished The recursion happens at the level being operated on: tcxp://tcxp.org/rule/18 is inside data, so a reader checks the spike against the very rules it carries, with no separate description of tcxp. This is how the rules are handed to any reader, including an LLM: pass the spike as it is. ground names the one approved place to get the official tools, the registry address tcxp://tcxp.org/install (tcxp://tcxp.org/rule/5). Decoded so it can be read: { "data": { "rules": […] }, "ground": { "instructions": "You are reading the tcxp rules. Before building anything, install the official tcxp SDK listed at the registry address, and use it to validate this spike.", "registry": "tcxp://tcxp.org/install" }, "meaning": "The complete rule set of the Typed Context Protocol (tcxp).", "structure": {…} } ======================================================================== tcxp://tcxp.org/rule/41 Whoever reads the rules is part of the protocol: the observer is part of the model, and ground is where they enter it. Every decision loop includes its observer, and the real-world effect of a decision returns to the observer as a new observation. Categories: Observe, Unverified, Unpublished An observer, such as a person using an LLM in their own situation, knows things from experience that the data cannot show; that is written in ground (tcxp://tcxp.org/rule/19). The decision's output acts on the real world, the observer experiences the result, and it is recorded as a new row in observe (tcxp://tcxp.org/rule/10). The loop closes through the observer, not around them. This applies to these rules too: whoever reads them is an observer in this loop (tcxp://tcxp.org/rule/40). ======================================================================== tcxp://tcxp.org/rule/42 A published address is never removed, but it can be deprecated. A deprecated address keeps its meaning and still resolves, and it names the address that replaces it, if there is one. Categories: Unverified, Unpublished Deprecation tells readers to stop using an address without breaking anything that already uses it (tcxp://tcxp.org/rule/32). A deprecated rule card keeps its id and its text, adds Deprecated to categories, and names its replacement in details and references. For example, if rule 0 replaces rule 4, rule 4's details ends with Deprecated: replaced by tcxp://tcxp.org/rule/0. and its references include 0. ======================================================================== tcxp://tcxp.org/rule/43 Every tcxp address has the form tcxp:/?, where is a JSON object with exactly two keys, params and state, both always present. The only @ before the ? is the optional one right after the boundary, and it makes the address a call. Categories: Unverified, Unpublished, Ground The ground is / (virtual), // (network) or /// (local) (tcxp://tcxp.org/rule/0). The boundary is the first segment after the ground, such as example.com or foo, and the pointer is the rest of the path. params holds the key-value pairs, and state holds what ~state held. An address without @ may still have a ?: it is then a reference, or a call written down but not made. Values inside the JSON may contain @. The JSON is put in canonical form, then percent-encoded (tcxp://tcxp.org/rule/30). For example, decoded so it can be read: tcxp:/foo/@bar?{"params":{"x":1},"state":{"context":{"decide":[],"intent":[],"observe":[],"reason":[],"trace":[]}}} is the call tcxp.foo.bar({ params: { x: 1 }, state: { context: { … } } }) , and the same address without the @ is that call written down but not made.