{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 0, "utc": "2026-08-26T20:22:57.420Z", "payload": {"revision": "rev-5", "normative_path": "SPEC.md", "normative_sha256": "cea7847f98f9751734995f46fd4e1bde211c8eb9d03dbbb477934213865bb91a", "normative_bytes": "41952", "canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "00798f05dd086676754a97e63e759fedf856075d", "commit_utc": "2026-08-26T12:00:41-04:00", "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "observed_utc": "2026-08-26T20:22:57.418Z"}, "payload_hash": "7d9c87b7d58ba07b22b68e8b07c0d50714fcc377c627ea9c60bec3bc6518df29", "prev": null, "prev_wave": null, "sig": null, "frame_hash": "a5aa6e6ba81d6b97b80ce46bc20905428d5679bb18309d176356bd194cdd005a"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 1, "utc": "2026-08-26T20:43:39.106Z", "payload": {"vocabulary": {"estate": {"status": "live", "where": "\u00a79.2 egg variant"}, "invite": {"status": "live", "where": "\u00a79.2 egg variant"}, "neighborhood": {"status": "live", "where": "\u00a79.2 egg variant"}, "organism": {"status": "live", "where": "\u00a79.2 egg variant"}, "rapplication": {"status": "live", "where": "\u00a79.2 egg variant"}, "session": {"status": "live", "where": "\u00a79.2 egg variant"}, "memory": {"status": "live", "where": "\u00a77.2 kind family"}, "swarm": {"status": "live", "where": "\u00a77.2 kind family"}, "body": {"status": "live", "where": "\u00a77.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate \u2014 bytes only at git 24c8fdc, sha256 690f6109\u2026"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (\u00a77.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (\u00a77.1)"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 \u00a76"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's word is `organism` (\u00a79.2)"}}, "revision": "rev-5", "normative_path": "SPEC.md", "normative_sha256": "cea7847f98f9751734995f46fd4e1bde211c8eb9d03dbbb477934213865bb91a", "normative_bytes": "41952", "canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "00798f05dd086676754a97e63e759fedf856075d", "commit_utc": "2026-08-26T12:00:41-04:00", "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "observed_utc": "2026-08-26T20:43:39.097Z"}, "payload_hash": "50283a1267c896d96e5f33f1c03060729a3695e0ab2e1f782390978d5e6c1dd5", "prev": "7d9c87b7d58ba07b22b68e8b07c0d50714fcc377c627ea9c60bec3bc6518df29", "prev_wave": null, "sig": null, "frame_hash": "963bf0689eb294164029a9088910749446c4e0fe0757fd27988b8fc220e5ab36"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 2, "utc": "2026-08-26T20:54:19.670Z", "payload": {"rules": [{"t": "fact", "c": "spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted."}, {"t": "gotcha", "c": "Canonical form is RFC 8785 JCS and FORBIDS floats \u2014 numbers ride as strings. A float silently breaks byte-reproducibility."}, {"t": "fact", "c": "payload_hash = H(\"rapp/1:particle\", payload) \u2014 content only, reproducible across instances."}, {"t": "fact", "c": "frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) \u2014 unique per stream instance."}, {"t": "gotcha", "c": "prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable."}, {"t": "gotcha", "c": "\u00a76.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name \u2014 sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint."}, {"t": "pattern", "c": "Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed."}, {"t": "gotcha", "c": "A swarm-stream frame with sig==null is refused (\u00a77.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null."}, {"t": "fact", "c": "Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs."}, {"t": "pattern", "c": "Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise \u2014 this is how N streams compose into one view."}, {"t": "pattern", "c": "One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct."}], "profiles": {"interop": {"why": "a peer may be out of date; lead with what it can get WRONG", "types": ["gotcha"], "show": ["keys", "stale_terms", "pointer"], "max_rules": "6"}, "authoring": {"why": "hand-building a frame; the envelope rules are what bite", "types": ["gotcha", "fact"], "show": ["keys", "eggs"], "max_rules": "8"}, "audit": {"why": "judging conformance; refuse-never-repair and the identity law govern", "types": ["pattern", "gotcha"], "show": ["keys", "stale_terms"], "max_rules": "8"}, "onboarding": {"why": "new organism; needs the shape of the world, not the edge cases", "types": ["fact"], "show": ["keys", "eggs", "stale_terms", "pointer"], "max_rules": "5"}, "minimal": {"why": "smallest honest context", "types": [], "show": ["stale_terms"], "max_rules": "0"}}, "exchange": {"shape": "push a frame in, get a frame back shaped by what you pushed \u2014 ONE hop.", "rule": "the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.", "idempotence": "keyed on the request's payload_hash \u2014 a retry returns the existing reply, never a second one.", "carrier": "POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward."}, "kind_families": {"memory": {"stream": "memory-stream", "logs": "one organism's life", "kinds": ["memory.chat-turn", "memory.tool-call", "memory.save", "memory.reconstructed", "memory.re-genesis"]}, "swarm": {"stream": "swarm-stream (net:label)", "logs": "the planetary wire", "kinds": ["swarm.guidance", "swarm.echo", "swarm.telemetry", "swarm.reconstructed", "swarm.re-genesis"]}, "body": {"stream": "body-stream (bare rappid)", "logs": "an organism's biography", "kinds": ["body.pulse", "body.twin-pulse", "body.reconstructed", "body.re-genesis"]}}, "frame_keys": ["spec", "kind", "stream_id", "seq", "utc", "payload", "payload_hash", "prev", "prev_wave", "sig", "frame_hash"], "profile_signals": {"unknown-peer": "interop", "stranger": "interop", "handshake": "interop", "write": "authoring", "author": "authoring", "mint": "authoring", "build": "authoring", "verify": "audit", "check": "audit", "conform": "audit", "drift": "audit", "join": "onboarding", "new": "onboarding", "install": "onboarding"}, "default_profile": "interop", "vocabulary": {"estate": {"status": "live", "where": "\u00a79.2 egg variant"}, "invite": {"status": "live", "where": "\u00a79.2 egg variant"}, "neighborhood": {"status": "live", "where": "\u00a79.2 egg variant"}, "organism": {"status": "live", "where": "\u00a79.2 egg variant"}, "rapplication": {"status": "live", "where": "\u00a79.2 egg variant"}, "session": {"status": "live", "where": "\u00a79.2 egg variant"}, "memory": {"status": "live", "where": "\u00a77.2 kind family"}, "swarm": {"status": "live", "where": "\u00a77.2 kind family"}, "body": {"status": "live", "where": "\u00a77.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate \u2014 bytes only at git 24c8fdc, sha256 690f6109\u2026"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (\u00a77.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (\u00a77.1)"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 \u00a76"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's word is `organism` (\u00a79.2)"}}, "revision": "rev-5", "normative_path": "SPEC.md", "normative_sha256": "cea7847f98f9751734995f46fd4e1bde211c8eb9d03dbbb477934213865bb91a", "normative_bytes": "41952", "canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "002cf089d3219f17c55b05ab1e2d8246e316dc8b", "commit_utc": "2026-08-26T16:48:15-04:00", "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "observed_utc": "2026-08-26T20:54:19.668Z"}, "payload_hash": "7fc511c74e677a748a71b7042fa1519429e0819096b5bdfcc610f7985fe980ff", "prev": "50283a1267c896d96e5f33f1c03060729a3695e0ab2e1f782390978d5e6c1dd5", "prev_wave": null, "sig": null, "frame_hash": "8c78ac8415a48e8ff02d4c4363cf3afd2003399c76e64ad938609a7ca8fe7b23"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 3, "utc": "2026-08-26T20:56:55.638Z", "payload": {"rules": [{"t": "fact", "c": "spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted."}, {"t": "gotcha", "c": "Canonical form is RFC 8785 JCS and FORBIDS floats \u2014 numbers ride as strings. A float silently breaks byte-reproducibility."}, {"t": "fact", "c": "payload_hash = H(\"rapp/1:particle\", payload) \u2014 content only, reproducible across instances."}, {"t": "fact", "c": "frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) \u2014 unique per stream instance."}, {"t": "gotcha", "c": "prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable."}, {"t": "gotcha", "c": "\u00a76.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name \u2014 sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint."}, {"t": "pattern", "c": "Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed."}, {"t": "gotcha", "c": "A swarm-stream frame with sig==null is refused (\u00a77.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null."}, {"t": "fact", "c": "Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs."}, {"t": "pattern", "c": "Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise \u2014 this is how N streams compose into one view."}, {"t": "pattern", "c": "One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct."}], "profiles": {"interop": {"why": "a peer may be out of date; lead with what it can get WRONG", "types": ["gotcha"], "show": ["keys", "stale_terms", "pointer"], "max_rules": "6"}, "authoring": {"why": "hand-building a frame; the envelope rules are what bite", "types": ["gotcha", "fact"], "show": ["keys", "eggs"], "max_rules": "8"}, "audit": {"why": "judging conformance; refuse-never-repair and the identity law govern", "types": ["pattern", "gotcha"], "show": ["keys", "stale_terms"], "max_rules": "8"}, "onboarding": {"why": "new organism; needs the shape of the world, not the edge cases", "types": ["fact"], "show": ["keys", "eggs", "stale_terms", "pointer"], "max_rules": "5"}, "minimal": {"why": "smallest honest context", "types": [], "show": ["stale_terms"], "max_rules": "0"}}, "exchange": {"shape": "push a frame in, get a frame back shaped by what you pushed \u2014 ONE hop.", "rule": "the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.", "idempotence": "keyed on the request's payload_hash \u2014 a retry returns the existing reply, never a second one.", "carrier": "POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward."}, "kind_families": {"memory": {"stream": "memory-stream", "logs": "one organism's life", "kinds": ["memory.chat-turn", "memory.tool-call", "memory.save", "memory.reconstructed", "memory.re-genesis"]}, "swarm": {"stream": "swarm-stream (net:label)", "logs": "the planetary wire", "kinds": ["swarm.guidance", "swarm.echo", "swarm.telemetry", "swarm.reconstructed", "swarm.re-genesis"]}, "body": {"stream": "body-stream (bare rappid)", "logs": "an organism's biography", "kinds": ["body.pulse", "body.twin-pulse", "body.reconstructed", "body.re-genesis"]}}, "frame_keys": ["spec", "kind", "stream_id", "seq", "utc", "payload", "payload_hash", "prev", "prev_wave", "sig", "frame_hash"], "profile_signals": {"unknown-peer": "interop", "stranger": "interop", "handshake": "interop", "write": "authoring", "author": "authoring", "mint": "authoring", "build": "authoring", "verify": "audit", "check": "audit", "conform": "audit", "drift": "audit", "join": "onboarding", "new": "onboarding", "install": "onboarding"}, "default_profile": "interop", "vocabulary": {"estate": {"status": "live", "where": "\u00a79.2 egg variant"}, "invite": {"status": "live", "where": "\u00a79.2 egg variant"}, "neighborhood": {"status": "live", "where": "\u00a79.2 egg variant"}, "organism": {"status": "live", "where": "\u00a79.2 egg variant"}, "rapplication": {"status": "live", "where": "\u00a79.2 egg variant"}, "session": {"status": "live", "where": "\u00a79.2 egg variant"}, "memory": {"status": "live", "where": "\u00a77.2 kind family"}, "swarm": {"status": "live", "where": "\u00a77.2 kind family"}, "body": {"status": "live", "where": "\u00a77.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate \u2014 bytes only at git 24c8fdc, sha256 690f6109\u2026"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (\u00a77.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (\u00a77.1)"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 \u00a76"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's word is `organism` (\u00a79.2)"}}, "revision": "rev-5", "normative_path": "SPEC.md", "normative_sha256": "cea7847f98f9751734995f46fd4e1bde211c8eb9d03dbbb477934213865bb91a", "normative_bytes": "41952", "canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "a37274a99c223188590cfcab5573db552ee2c0ee", "commit_utc": "2026-08-26T16:54:40-04:00", "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "observed_utc": "2026-08-26T20:56:55.632Z"}, "payload_hash": "49b49714dfd8ee162b27b251d87e3e268d4a35d17bcc39efb39055f3cf63b3d8", "prev": "7fc511c74e677a748a71b7042fa1519429e0819096b5bdfcc610f7985fe980ff", "prev_wave": null, "sig": null, "frame_hash": "587365ca3a04258348e943e709469d1eb5c07235d26e04d4637e3dffa9dd17c7"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 4, "utc": "2026-08-26T20:56:55.773Z", "payload": {"rules": [{"t": "fact", "c": "spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted."}, {"t": "gotcha", "c": "Canonical form is RFC 8785 JCS and FORBIDS floats \u2014 numbers ride as strings. A float silently breaks byte-reproducibility."}, {"t": "fact", "c": "payload_hash = H(\"rapp/1:particle\", payload) \u2014 content only, reproducible across instances."}, {"t": "fact", "c": "frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) \u2014 unique per stream instance."}, {"t": "gotcha", "c": "prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable."}, {"t": "gotcha", "c": "\u00a76.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name \u2014 sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint."}, {"t": "pattern", "c": "Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed."}, {"t": "gotcha", "c": "A swarm-stream frame with sig==null is refused (\u00a77.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null."}, {"t": "fact", "c": "Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs."}, {"t": "pattern", "c": "Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise \u2014 this is how N streams compose into one view."}, {"t": "pattern", "c": "One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct."}], "profiles": {"interop": {"why": "a peer may be out of date; lead with what it can get WRONG", "types": ["gotcha"], "show": ["keys", "stale_terms", "pointer"], "max_rules": "6"}, "authoring": {"why": "hand-building a frame; the envelope rules are what bite", "types": ["gotcha", "fact"], "show": ["keys", "eggs"], "max_rules": "8"}, "audit": {"why": "judging conformance; refuse-never-repair and the identity law govern", "types": ["pattern", "gotcha"], "show": ["keys", "stale_terms"], "max_rules": "8"}, "onboarding": {"why": "new organism; needs the shape of the world, not the edge cases", "types": ["fact"], "show": ["keys", "eggs", "stale_terms", "pointer"], "max_rules": "5"}, "minimal": {"why": "smallest honest context", "types": [], "show": ["stale_terms"], "max_rules": "0"}}, "moods": {"night": {"when": {"hour_gte": "22"}, "profile": "minimal", "why": "low-attention hours; smallest honest context"}, "early": {"when": {"hour_lt": "6"}, "profile": "minimal", "why": "same"}, "storm": {"when": {"conditions": "storm,rain,snow"}, "profile": "audit", "why": "degraded links are when drift hides; lead with verification"}, "clear": {"when": {"conditions": "clear,sunny"}, "profile": "interop", "why": "good conditions, normal posture"}}, "exchange": {"shape": "push a frame in, get a frame back shaped by what you pushed \u2014 ONE hop.", "rule": "the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.", "idempotence": "keyed on the request's payload_hash \u2014 a retry returns the existing reply, never a second one.", "carrier": "POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward."}, "kind_families": {"memory": {"stream": "memory-stream", "logs": "one organism's life", "kinds": ["memory.chat-turn", "memory.tool-call", "memory.save", "memory.reconstructed", "memory.re-genesis"]}, "swarm": {"stream": "swarm-stream (net:label)", "logs": "the planetary wire", "kinds": ["swarm.guidance", "swarm.echo", "swarm.telemetry", "swarm.reconstructed", "swarm.re-genesis"]}, "body": {"stream": "body-stream (bare rappid)", "logs": "an organism's biography", "kinds": ["body.pulse", "body.twin-pulse", "body.reconstructed", "body.re-genesis"]}}, "frame_keys": ["spec", "kind", "stream_id", "seq", "utc", "payload", "payload_hash", "prev", "prev_wave", "sig", "frame_hash"], "profile_signals": {"unknown-peer": "interop", "stranger": "interop", "handshake": "interop", "write": "authoring", "author": "authoring", "mint": "authoring", "build": "authoring", "verify": "audit", "check": "audit", "conform": "audit", "drift": "audit", "join": "onboarding", "new": "onboarding", "install": "onboarding"}, "default_profile": "interop", "vocabulary": {"estate": {"status": "live", "where": "\u00a79.2 egg variant"}, "invite": {"status": "live", "where": "\u00a79.2 egg variant"}, "neighborhood": {"status": "live", "where": "\u00a79.2 egg variant"}, "organism": {"status": "live", "where": "\u00a79.2 egg variant"}, "rapplication": {"status": "live", "where": "\u00a79.2 egg variant"}, "session": {"status": "live", "where": "\u00a79.2 egg variant"}, "memory": {"status": "live", "where": "\u00a77.2 kind family"}, "swarm": {"status": "live", "where": "\u00a77.2 kind family"}, "body": {"status": "live", "where": "\u00a77.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate \u2014 bytes only at git 24c8fdc, sha256 690f6109\u2026"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (\u00a77.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (\u00a77.1)"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 \u00a76"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's word is `organism` (\u00a79.2)"}}, "revision": "rev-5", "normative_path": "SPEC.md", "normative_sha256": "cea7847f98f9751734995f46fd4e1bde211c8eb9d03dbbb477934213865bb91a", "normative_bytes": "41952", "canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "a37274a99c223188590cfcab5573db552ee2c0ee", "commit_utc": "2026-08-26T16:54:40-04:00", "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "observed_utc": "2026-08-26T20:56:55.769Z"}, "payload_hash": "f75e1511ae48bc35efc791b9f15c869cb316e36de351786ba7ca8d868c8b1b72", "prev": "49b49714dfd8ee162b27b251d87e3e268d4a35d17bcc39efb39055f3cf63b3d8", "prev_wave": null, "sig": null, "frame_hash": "5aa99ae21b39b2c3e5e63c696dc3c34596aabbc721cda002b9c4f7ef100f7363"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 5, "utc": "2026-08-26T23:55:13.834Z", "payload": {"rules": [{"t": "fact", "c": "spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted."}, {"t": "gotcha", "c": "Canonical form is RFC 8785 JCS and FORBIDS floats \u2014 numbers ride as strings. A float silently breaks byte-reproducibility."}, {"t": "fact", "c": "payload_hash = H(\"rapp/1:particle\", payload) \u2014 content only, reproducible across instances."}, {"t": "fact", "c": "frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) \u2014 unique per stream instance."}, {"t": "gotcha", "c": "prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable."}, {"t": "gotcha", "c": "\u00a76.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name \u2014 sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint."}, {"t": "pattern", "c": "Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed."}, {"t": "gotcha", "c": "A swarm-stream frame with sig==null is refused (\u00a77.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null."}, {"t": "fact", "c": "Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs."}, {"t": "pattern", "c": "Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise \u2014 this is how N streams compose into one view."}, {"t": "pattern", "c": "One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct."}], "profiles": {"interop": {"why": "a peer may be out of date; lead with what it can get WRONG", "types": ["gotcha"], "show": ["keys", "stale_terms", "pointer"], "max_rules": "6"}, "authoring": {"why": "hand-building a frame; the envelope rules are what bite", "types": ["gotcha", "fact"], "show": ["keys", "eggs"], "max_rules": "8"}, "audit": {"why": "judging conformance; refuse-never-repair and the identity law govern", "types": ["pattern", "gotcha"], "show": ["keys", "stale_terms"], "max_rules": "8"}, "onboarding": {"why": "new organism; needs the shape of the world, not the edge cases", "types": ["fact"], "show": ["keys", "eggs", "stale_terms", "pointer"], "max_rules": "5"}, "minimal": {"why": "smallest honest context", "types": [], "show": ["stale_terms"], "max_rules": "0"}}, "moods": {"night": {"when": {"hour_gte": "22"}, "profile": "minimal", "why": "low-attention hours; smallest honest context"}, "early": {"when": {"hour_lt": "6"}, "profile": "minimal", "why": "same"}, "storm": {"when": {"conditions": "storm,rain,snow"}, "profile": "audit", "why": "degraded links are when drift hides; lead with verification"}, "clear": {"when": {"conditions": "clear,sunny"}, "profile": "interop", "why": "good conditions, normal posture"}}, "exchange": {"shape": "push a frame in, get a frame back shaped by what you pushed \u2014 ONE hop.", "rule": "the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.", "idempotence": "keyed on the request's payload_hash \u2014 a retry returns the existing reply, never a second one.", "carrier": "POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward."}, "kind_families": {"memory": {"stream": "memory-stream", "logs": "one organism's life", "kinds": ["memory.chat-turn", "memory.tool-call", "memory.save", "memory.reconstructed", "memory.re-genesis"]}, "swarm": {"stream": "swarm-stream (net:label)", "logs": "the planetary wire", "kinds": ["swarm.guidance", "swarm.echo", "swarm.telemetry", "swarm.reconstructed", "swarm.re-genesis"]}, "body": {"stream": "body-stream (bare rappid)", "logs": "an organism's biography", "kinds": ["body.pulse", "body.twin-pulse", "body.reconstructed", "body.re-genesis"]}}, "frame_keys": ["spec", "kind", "stream_id", "seq", "utc", "payload", "payload_hash", "prev", "prev_wave", "sig", "frame_hash"], "profile_signals": {"unknown-peer": "interop", "stranger": "interop", "handshake": "interop", "write": "authoring", "author": "authoring", "mint": "authoring", "build": "authoring", "verify": "audit", "check": "audit", "conform": "audit", "drift": "audit", "join": "onboarding", "new": "onboarding", "install": "onboarding"}, "default_profile": "interop", "vocabulary": {"estate": {"status": "live", "where": "\u00a79.2 egg variant"}, "invite": {"status": "live", "where": "\u00a79.2 egg variant"}, "neighborhood": {"status": "live", "where": "\u00a79.2 egg variant"}, "organism": {"status": "live", "where": "\u00a79.2 egg variant"}, "rapplication": {"status": "live", "where": "\u00a79.2 egg variant"}, "session": {"status": "live", "where": "\u00a79.2 egg variant"}, "memory": {"status": "live", "where": "\u00a77.2 kind family"}, "swarm": {"status": "live", "where": "\u00a77.2 kind family"}, "body": {"status": "live", "where": "\u00a77.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate \u2014 bytes only at git 24c8fdc, sha256 690f6109\u2026"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (\u00a77.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (\u00a77.1)"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 \u00a76"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's word is `organism` (\u00a79.2)"}}, "revision": "rev-5", "normative_path": "SPEC.md", "normative_sha256": "cea7847f98f9751734995f46fd4e1bde211c8eb9d03dbbb477934213865bb91a", "normative_bytes": "41952", "canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "d2cd5abed48d3f52b86bbb975ac3558286d1db41", "commit_utc": "2026-08-04T16:43:50-04:00", "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "observed_utc": "2026-08-26T23:55:13.824Z"}, "payload_hash": "776f7ea01b2ce0c748ca9eeed8886b4e70101ba63871dbf82a12fbd3e84f91e8", "prev": "f75e1511ae48bc35efc791b9f15c869cb316e36de351786ba7ca8d868c8b1b72", "prev_wave": null, "sig": null, "frame_hash": "f7a423190f613f9d0de3c63fb8add1a1d032410f2c74eb79a201da6151a7107a"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 6, "utc": "2026-08-27T22:47:28.791Z", "payload": {"rules": [{"t": "fact", "c": "spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted."}, {"t": "gotcha", "c": "Canonical form is RFC 8785 JCS and FORBIDS floats \u2014 numbers ride as strings. A float silently breaks byte-reproducibility."}, {"t": "fact", "c": "payload_hash = H(\"rapp/1:particle\", payload) \u2014 content only, reproducible across instances."}, {"t": "fact", "c": "frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) \u2014 unique per stream instance."}, {"t": "gotcha", "c": "prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable."}, {"t": "gotcha", "c": "\u00a76.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name \u2014 sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint."}, {"t": "pattern", "c": "Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed."}, {"t": "gotcha", "c": "A swarm-stream frame with sig==null is refused (\u00a77.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null."}, {"t": "fact", "c": "Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs."}, {"t": "pattern", "c": "Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise \u2014 this is how N streams compose into one view."}, {"t": "pattern", "c": "One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct."}, {"t": "fact", "c": "\u00a79.4 (rev-6): hatching an egg MUST mint a fresh \u00a76.2 identity for the INSTANCE \u2014 the artifact rappid rides the egg unchanged and is shared by every install; the instance identity never is. The instance SHOULD record grown_from = the \u00a79.1 egg address it grew from: written at mint, immutable, null when unknown, NEVER fabricated. Lineage, not inheritance \u2014 it confers no authority, no trust, no key material."}], "profiles": {"interop": {"why": "a peer may be out of date; lead with what it can get WRONG", "types": ["gotcha"], "show": ["keys", "stale_terms", "pointer"], "max_rules": "6"}, "authoring": {"why": "hand-building a frame; the envelope rules are what bite", "types": ["gotcha", "fact"], "show": ["keys", "eggs"], "max_rules": "8"}, "audit": {"why": "judging conformance; refuse-never-repair and the identity law govern", "types": ["pattern", "gotcha"], "show": ["keys", "stale_terms"], "max_rules": "8"}, "onboarding": {"why": "new organism; needs the shape of the world, not the edge cases", "types": ["fact"], "show": ["keys", "eggs", "stale_terms", "pointer"], "max_rules": "5"}, "minimal": {"why": "smallest honest context", "types": [], "show": ["stale_terms"], "max_rules": "0"}}, "moods": {"night": {"when": {"hour_gte": "22"}, "profile": "minimal", "why": "low-attention hours; smallest honest context"}, "early": {"when": {"hour_lt": "6"}, "profile": "minimal", "why": "same"}, "storm": {"when": {"conditions": "storm,rain,snow"}, "profile": "audit", "why": "degraded links are when drift hides; lead with verification"}, "clear": {"when": {"conditions": "clear,sunny"}, "profile": "interop", "why": "good conditions, normal posture"}}, "exchange": {"shape": "push a frame in, get a frame back shaped by what you pushed \u2014 ONE hop.", "rule": "the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.", "idempotence": "keyed on the request's payload_hash \u2014 a retry returns the existing reply, never a second one.", "carrier": "POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward."}, "kind_families": {"memory": {"stream": "memory-stream", "logs": "one organism's life", "kinds": ["memory.chat-turn", "memory.tool-call", "memory.save", "memory.reconstructed", "memory.re-genesis"]}, "swarm": {"stream": "swarm-stream (net:label)", "logs": "the planetary wire", "kinds": ["swarm.guidance", "swarm.echo", "swarm.telemetry", "swarm.reconstructed", "swarm.re-genesis"]}, "body": {"stream": "body-stream (bare rappid)", "logs": "an organism's biography", "kinds": ["body.pulse", "body.twin-pulse", "body.reconstructed", "body.re-genesis"]}}, "frame_keys": ["spec", "kind", "stream_id", "seq", "utc", "payload", "payload_hash", "prev", "prev_wave", "sig", "frame_hash"], "profile_signals": {"unknown-peer": "interop", "stranger": "interop", "handshake": "interop", "write": "authoring", "author": "authoring", "mint": "authoring", "build": "authoring", "verify": "audit", "check": "audit", "conform": "audit", "drift": "audit", "join": "onboarding", "new": "onboarding", "install": "onboarding"}, "default_profile": "interop", "vocabulary": {"estate": {"status": "live", "where": "\u00a79.2 egg variant"}, "invite": {"status": "live", "where": "\u00a79.2 egg variant"}, "neighborhood": {"status": "live", "where": "\u00a79.2 egg variant"}, "organism": {"status": "live", "where": "\u00a79.2 egg variant"}, "rapplication": {"status": "live", "where": "\u00a79.2 egg variant"}, "session": {"status": "live", "where": "\u00a79.2 egg variant"}, "memory": {"status": "live", "where": "\u00a77.2 kind family"}, "swarm": {"status": "live", "where": "\u00a77.2 kind family"}, "body": {"status": "live", "where": "\u00a77.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate \u2014 bytes only at git 24c8fdc, sha256 690f6109\u2026"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (\u00a77.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (\u00a77.1)"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 \u00a76"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's words are `organism` (\u00a79.2) and `instance` (\u00a79.4)"}, "grown_from": {"status": "live", "where": "\u00a79.4 instantiation \u2014 instance lineage key"}, "instance": {"status": "live", "where": "\u00a79.4 instantiation \u2014 a hatched install; fresh \u00a76.2 identity, never shared"}}, "revision": "rev-6", "normative_path": "SPEC.md", "normative_sha256": "8212bbccaf86f2dc81bd07e2fcd5184f3a157f4eee162b13a698407684b6e134", "normative_bytes": "43509", "canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "2d3e50df04d5beaf40045da244493503d16f7779", "commit_utc": "2026-08-27T18:47:20-04:00", "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "observed_utc": "2026-08-27T22:47:28.791Z"}, "payload_hash": "72402ad7f2666f634e82ceb9ada3d2f577db5100160bd88c51f9f0aafc7ffad2", "prev": "776f7ea01b2ce0c748ca9eeed8886b4e70101ba63871dbf82a12fbd3e84f91e8", "prev_wave": null, "sig": null, "frame_hash": "da8dd02d50796c57ac7f9b7b1d8fd86d8a2d10ba15d28776914e71118243ce12"}
{"frame_hash":"3620f45825dbf73280a1df2db3aac4de87b07297afc35e1cee3034eb3c3ea6ef","kind":"body.pulse","payload":{"canonical_repo":"https://github.com/kody-w/rapp-1","commit":"9506f486b316cea84e8eaadc7b664eb4b3bcf942","commit_utc":"2026-08-29T21:43:06-04:00","default_profile":"interop","exchange":{"carrier":"POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward.","idempotence":"keyed on the request's payload_hash — a retry returns the existing reply, never a second one.","rule":"the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.","shape":"push a frame in, get a frame back shaped by what you pushed — ONE hop."},"frame_keys":["spec","kind","stream_id","seq","utc","payload","payload_hash","prev","prev_wave","sig","frame_hash"],"kind_families":{"body":{"kinds":["body.pulse","body.twin-pulse","body.reconstructed","body.re-genesis"],"logs":"an organism's biography","stream":"body-stream (bare rappid)"},"memory":{"kinds":["memory.chat-turn","memory.tool-call","memory.save","memory.reconstructed","memory.re-genesis"],"logs":"one organism's life","stream":"memory-stream"},"swarm":{"kinds":["swarm.guidance","swarm.echo","swarm.telemetry","swarm.reconstructed","swarm.re-genesis"],"logs":"the planetary wire","stream":"swarm-stream (net:label)"}},"moods":{"clear":{"profile":"interop","when":{"conditions":"clear,sunny"},"why":"good conditions, normal posture"},"early":{"profile":"minimal","when":{"hour_lt":"6"},"why":"same"},"night":{"profile":"minimal","when":{"hour_gte":"22"},"why":"low-attention hours; smallest honest context"},"storm":{"profile":"audit","when":{"conditions":"storm,rain,snow"},"why":"degraded links are when drift hides; lead with verification"}},"normative_bytes":"50950","normative_path":"SPEC.md","normative_sha256":"ad116c1524c02918b9f53a508389b433cf011e1f44500ad6e315f5784e079140","observed_utc":"2026-08-30T01:43:43.314Z","profile_signals":{"author":"authoring","build":"authoring","check":"audit","conform":"audit","drift":"audit","handshake":"interop","install":"onboarding","join":"onboarding","mint":"authoring","new":"onboarding","stranger":"interop","unknown-peer":"interop","verify":"audit","write":"authoring"},"profiles":{"audit":{"max_rules":"8","show":["keys","stale_terms"],"types":["pattern","gotcha"],"why":"judging conformance; refuse-never-repair and the identity law govern"},"authoring":{"max_rules":"8","show":["keys","eggs"],"types":["gotcha","fact"],"why":"hand-building a frame; the envelope rules are what bite"},"interop":{"max_rules":"6","show":["keys","stale_terms","pointer"],"types":["gotcha"],"why":"a peer may be out of date; lead with what it can get WRONG"},"minimal":{"max_rules":"0","show":["stale_terms"],"types":[],"why":"smallest honest context"},"onboarding":{"max_rules":"5","show":["keys","eggs","stale_terms","pointer"],"types":["fact"],"why":"new organism; needs the shape of the world, not the edge cases"}},"registered_kinds":["body.pulse","body.re-genesis","body.reconstructed","body.twin-pulse","memory.chat-turn","memory.re-genesis","memory.reconstructed","memory.save","memory.tool-call","swarm.echo","swarm.guidance","swarm.re-genesis","swarm.reconstructed","swarm.telemetry"],"revision":"rev-7","rules":[{"c":"spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted.","t":"fact"},{"c":"Canonical form is RFC 8785 JCS and FORBIDS floats — numbers ride as strings. A float silently breaks byte-reproducibility.","t":"gotcha"},{"c":"payload_hash = H(\"rapp/1:particle\", payload) — content only, reproducible across instances.","t":"fact"},{"c":"frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) — unique per stream instance.","t":"fact"},{"c":"prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable.","t":"gotcha"},{"c":"§6.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name — sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint.","t":"gotcha"},{"c":"Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed.","t":"pattern"},{"c":"A swarm-stream frame with sig==null is refused (§7.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null.","t":"gotcha"},{"c":"Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs.","t":"fact"},{"c":"Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise — this is how N streams compose into one view.","t":"pattern"},{"c":"One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct.","t":"pattern"},{"c":"§9.4 (rev-6): hatching an egg MUST mint a fresh §6.2 identity for the INSTANCE — the artifact rappid rides the egg unchanged and is shared by every install; the instance identity never is. The instance SHOULD record grown_from = the §9.1 egg address it grew from: written at mint, immutable, null when unknown, NEVER fabricated. Lineage, not inheritance — it confers no authority, no trust, no key material.","t":"fact"},{"c":"§11.1 / Constitution Article 15: an owner-activated Grail is identified by Hb(\"rapp/1:grail\", exact kernel bytes) and never changes; every ring and release/deployment stage rejects kernel-drift and proves the resolved executed entry point.","t":"gotcha"}],"vocabulary":{"body":{"status":"live","where":"§7.2 kind family"},"estate":{"status":"live","where":"§9.2 egg variant"},"grail":{"status":"live","where":"§3 terminology; §11.1 immutable Grail kernel conformance; Constitution Article 15"},"grown_from":{"status":"live","where":"§9.4 instantiation — instance lineage key"},"instance":{"status":"live","where":"§9.4 instantiation — a hatched install; fresh §6.2 identity, never shared"},"invite":{"status":"live","where":"§9.2 egg variant"},"memory":{"status":"live","where":"§7.2 kind family"},"metropolis":{"status":"retired","where":"rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate — bytes only at git 24c8fdc, sha256 690f6109…"},"neighborhood":{"status":"live","where":"§9.2 egg variant"},"organism":{"status":"live","where":"§9.2 egg variant"},"rapp-frame/2.0":{"status":"retired","where":"legacy envelope token, superseded by rapp/1 (§7.1)"},"rapp-frame/2.1":{"status":"retired","where":"legacy envelope token, superseded by rapp/1 (§7.1)"},"rapp-protocol/1.0":{"status":"retired","where":"legacy, superseded by rapp/1"},"rapp-rappid-spec/2.0":{"status":"retired","where":"legacy, superseded by rapp/1 §6"},"rapplication":{"status":"live","where":"§9.2 egg variant"},"rbox":{"status":"not-in-spec","where":"operator's working word for a machine running an organism; the spec's words are `organism` (§9.2) and `instance` (§9.4)"},"session":{"status":"live","where":"§9.2 egg variant"},"swarm":{"status":"live","where":"§7.2 kind family"}}},"payload_hash":"c8bdac0f3f194d35f8b60d968178dbb6ed133b6422d721c9e3e34980118679d2","prev":"72402ad7f2666f634e82ceb9ada3d2f577db5100160bd88c51f9f0aafc7ffad2","prev_wave":null,"seq":7,"sig":null,"spec":"rapp/1","stream_id":"rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6","utc":"2026-08-30T01:43:43.314Z"}
{"frame_hash":"65e2b1694f6c8d418bd66c7e8e8f567f798f5e9a210e68b9e0ed226aaf364786","kind":"body.pulse","payload":{"canonical_repo":"https://github.com/kody-w/rapp-1","commit":"7c8ee377eec000f07a0b659cf52939f16b01c58d","commit_utc":"2026-08-29T21:48:49-04:00","default_profile":"interop","exchange":{"carrier":"POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward.","idempotence":"keyed on the request's payload_hash — a retry returns the existing reply, never a second one.","rule":"the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.","shape":"push a frame in, get a frame back shaped by what you pushed — ONE hop."},"frame_keys":["spec","kind","stream_id","seq","utc","payload","payload_hash","prev","prev_wave","sig","frame_hash"],"kind_families":{"body":{"kinds":["body.pulse","body.twin-pulse","body.reconstructed","body.re-genesis"],"logs":"an organism's biography","stream":"body-stream (bare rappid)"},"memory":{"kinds":["memory.chat-turn","memory.tool-call","memory.save","memory.reconstructed","memory.re-genesis"],"logs":"one organism's life","stream":"memory-stream"},"swarm":{"kinds":["swarm.guidance","swarm.echo","swarm.telemetry","swarm.reconstructed","swarm.re-genesis"],"logs":"the planetary wire","stream":"swarm-stream (net:label)"}},"moods":{"clear":{"profile":"interop","when":{"conditions":"clear,sunny"},"why":"good conditions, normal posture"},"early":{"profile":"minimal","when":{"hour_lt":"6"},"why":"same"},"night":{"profile":"minimal","when":{"hour_gte":"22"},"why":"low-attention hours; smallest honest context"},"storm":{"profile":"audit","when":{"conditions":"storm,rain,snow"},"why":"degraded links are when drift hides; lead with verification"}},"normative_bytes":"51305","normative_path":"SPEC.md","normative_sha256":"c0fb3cd46d110daaabdcfad17f2105dc27dda613dbc10665852fcc974f42e1cc","observed_utc":"2026-08-30T01:50:03.050Z","profile_signals":{"author":"authoring","build":"authoring","check":"audit","conform":"audit","drift":"audit","handshake":"interop","install":"onboarding","join":"onboarding","mint":"authoring","new":"onboarding","stranger":"interop","unknown-peer":"interop","verify":"audit","write":"authoring"},"profiles":{"audit":{"max_rules":"8","show":["keys","stale_terms"],"types":["pattern","gotcha"],"why":"judging conformance; refuse-never-repair and the identity law govern"},"authoring":{"max_rules":"8","show":["keys","eggs"],"types":["gotcha","fact"],"why":"hand-building a frame; the envelope rules are what bite"},"interop":{"max_rules":"6","show":["keys","stale_terms","pointer"],"types":["gotcha"],"why":"a peer may be out of date; lead with what it can get WRONG"},"minimal":{"max_rules":"0","show":["stale_terms"],"types":[],"why":"smallest honest context"},"onboarding":{"max_rules":"5","show":["keys","eggs","stale_terms","pointer"],"types":["fact"],"why":"new organism; needs the shape of the world, not the edge cases"}},"registered_kinds":["body.pulse","body.re-genesis","body.reconstructed","body.twin-pulse","memory.chat-turn","memory.re-genesis","memory.reconstructed","memory.save","memory.tool-call","swarm.echo","swarm.guidance","swarm.re-genesis","swarm.reconstructed","swarm.telemetry"],"revision":"rev-8","rules":[{"c":"spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted.","t":"fact"},{"c":"Canonical form is RFC 8785 JCS and FORBIDS floats — numbers ride as strings. A float silently breaks byte-reproducibility.","t":"gotcha"},{"c":"payload_hash = H(\"rapp/1:particle\", payload) — content only, reproducible across instances.","t":"fact"},{"c":"frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) — unique per stream instance.","t":"fact"},{"c":"prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable.","t":"gotcha"},{"c":"§6.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name — sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint.","t":"gotcha"},{"c":"Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed.","t":"pattern"},{"c":"A swarm-stream frame with sig==null is refused (§7.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null.","t":"gotcha"},{"c":"Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs.","t":"fact"},{"c":"Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise — this is how N streams compose into one view.","t":"pattern"},{"c":"One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct.","t":"pattern"},{"c":"§9.4 (rev-6): hatching an egg MUST mint a fresh §6.2 identity for the INSTANCE — the artifact rappid rides the egg unchanged and is shared by every install; the instance identity never is. The instance SHOULD record grown_from = the §9.1 egg address it grew from: written at mint, immutable, null when unknown, NEVER fabricated. Lineage, not inheritance — it confers no authority, no trust, no key material.","t":"fact"},{"c":"§11.1 / Constitution Article 15: the authenticated registry selects one (release_scope, grail_id); every ring and release/deployment stage rejects kernel-drift and execution gates prove the exact resolved kernel entry point.","t":"gotcha"}],"vocabulary":{"body":{"status":"live","where":"§7.2 kind family"},"estate":{"status":"live","where":"§9.2 egg variant"},"grail":{"status":"live","where":"§3 terminology; §11.1 immutable Grail kernel conformance; Constitution Article 15"},"grown_from":{"status":"live","where":"§9.4 instantiation — instance lineage key"},"instance":{"status":"live","where":"§9.4 instantiation — a hatched install; fresh §6.2 identity, never shared"},"invite":{"status":"live","where":"§9.2 egg variant"},"memory":{"status":"live","where":"§7.2 kind family"},"metropolis":{"status":"retired","where":"rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate — bytes only at git 24c8fdc, sha256 690f6109…"},"neighborhood":{"status":"live","where":"§9.2 egg variant"},"organism":{"status":"live","where":"§9.2 egg variant"},"rapp-frame/2.0":{"status":"retired","where":"legacy envelope token, superseded by rapp/1 (§7.1)"},"rapp-frame/2.1":{"status":"retired","where":"legacy envelope token, superseded by rapp/1 (§7.1)"},"rapp-protocol/1.0":{"status":"retired","where":"legacy, superseded by rapp/1"},"rapp-rappid-spec/2.0":{"status":"retired","where":"legacy, superseded by rapp/1 §6"},"rapplication":{"status":"live","where":"§9.2 egg variant"},"rbox":{"status":"not-in-spec","where":"operator's working word for a machine running an organism; the spec's words are `organism` (§9.2) and `instance` (§9.4)"},"session":{"status":"live","where":"§9.2 egg variant"},"swarm":{"status":"live","where":"§7.2 kind family"}}},"payload_hash":"fb24c39d10b7083a7907f85cd35d5e04a15edd1d233171782cfb297374e19f37","prev":"c8bdac0f3f194d35f8b60d968178dbb6ed133b6422d721c9e3e34980118679d2","prev_wave":null,"seq":8,"sig":null,"spec":"rapp/1","stream_id":"rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6","utc":"2026-08-30T01:50:03.050Z"}
{"frame_hash":"24d8a02b1be5490c0d531dc568a4b6b580526015b7eb0b61b7062873cb8efbf3","kind":"body.pulse","payload":{"canonical_repo":"https://github.com/kody-w/rapp-1","commit":"309050cc3d05c908d2338cb3b63068601b3cab2f","commit_utc":"2026-08-29T22:07:31-04:00","default_profile":"interop","exchange":{"carrier":"POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward.","idempotence":"keyed on the request's payload_hash — a retry returns the existing reply, never a second one.","rule":"the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.","shape":"push a frame in, get a frame back shaped by what you pushed — ONE hop."},"frame_keys":["spec","kind","stream_id","seq","utc","payload","payload_hash","prev","prev_wave","sig","frame_hash"],"kind_families":{"body":{"kinds":["body.pulse","body.twin-pulse","body.reconstructed","body.re-genesis"],"logs":"an organism's biography","stream":"body-stream (bare rappid)"},"memory":{"kinds":["memory.chat-turn","memory.tool-call","memory.save","memory.reconstructed","memory.re-genesis"],"logs":"one organism's life","stream":"memory-stream"},"swarm":{"kinds":["swarm.guidance","swarm.echo","swarm.telemetry","swarm.reconstructed","swarm.re-genesis"],"logs":"the planetary wire","stream":"swarm-stream (net:label)"}},"moods":{"clear":{"profile":"interop","when":{"conditions":"clear,sunny"},"why":"good conditions, normal posture"},"early":{"profile":"minimal","when":{"hour_lt":"6"},"why":"same"},"night":{"profile":"minimal","when":{"hour_gte":"22"},"why":"low-attention hours; smallest honest context"},"storm":{"profile":"audit","when":{"conditions":"storm,rain,snow"},"why":"degraded links are when drift hides; lead with verification"}},"normative_bytes":"52301","normative_path":"SPEC.md","normative_sha256":"f3125fc81c143ffefe96909326f6b0a70a01a97a2aaeed9d7945cd2359b5252b","observed_utc":"2026-08-30T02:08:03.554Z","profile_signals":{"author":"authoring","build":"authoring","check":"audit","conform":"audit","drift":"audit","handshake":"interop","install":"onboarding","join":"onboarding","mint":"authoring","new":"onboarding","stranger":"interop","unknown-peer":"interop","verify":"audit","write":"authoring"},"profiles":{"audit":{"max_rules":"8","show":["keys","stale_terms"],"types":["pattern","gotcha"],"why":"judging conformance; refuse-never-repair and the identity law govern"},"authoring":{"max_rules":"8","show":["keys","eggs"],"types":["gotcha","fact"],"why":"hand-building a frame; the envelope rules are what bite"},"interop":{"max_rules":"6","show":["keys","stale_terms","pointer"],"types":["gotcha"],"why":"a peer may be out of date; lead with what it can get WRONG"},"minimal":{"max_rules":"0","show":["stale_terms"],"types":[],"why":"smallest honest context"},"onboarding":{"max_rules":"5","show":["keys","eggs","stale_terms","pointer"],"types":["fact"],"why":"new organism; needs the shape of the world, not the edge cases"}},"registered_kinds":["body.pulse","body.re-genesis","body.reconstructed","body.twin-pulse","memory.chat-turn","memory.re-genesis","memory.reconstructed","memory.save","memory.tool-call","swarm.echo","swarm.guidance","swarm.re-genesis","swarm.reconstructed","swarm.telemetry"],"revision":"rev-9","rules":[{"c":"spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted.","t":"fact"},{"c":"Canonical form is RFC 8785 JCS and FORBIDS floats — numbers ride as strings. A float silently breaks byte-reproducibility.","t":"gotcha"},{"c":"payload_hash = H(\"rapp/1:particle\", payload) — content only, reproducible across instances.","t":"fact"},{"c":"frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) — unique per stream instance.","t":"fact"},{"c":"prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable.","t":"gotcha"},{"c":"§6.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name — sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint.","t":"gotcha"},{"c":"Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed.","t":"pattern"},{"c":"A swarm-stream frame with sig==null is refused (§7.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null.","t":"gotcha"},{"c":"Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs.","t":"fact"},{"c":"Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise — this is how N streams compose into one view.","t":"pattern"},{"c":"One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct.","t":"pattern"},{"c":"§9.4 (rev-6): hatching an egg MUST mint a fresh §6.2 identity for the INSTANCE — the artifact rappid rides the egg unchanged and is shared by every install; the instance identity never is. The instance SHOULD record grown_from = the §9.1 egg address it grew from: written at mint, immutable, null when unknown, NEVER fabricated. Lineage, not inheritance — it confers no authority, no trust, no key material.","t":"fact"},{"c":"§11.1 / Constitution Article 15: owner policy selects only release_scope; the activated registry selects grail_id; every ring rejects kernel-drift; execution consumes bytes from a sealed immutable object or equivalent write-excluded snapshot.","t":"gotcha"}],"vocabulary":{"body":{"status":"live","where":"§7.2 kind family"},"estate":{"status":"live","where":"§9.2 egg variant"},"grail":{"status":"live","where":"§3 terminology; §11.1 immutable Grail kernel conformance; Constitution Article 15"},"grown_from":{"status":"live","where":"§9.4 instantiation — instance lineage key"},"instance":{"status":"live","where":"§9.4 instantiation — a hatched install; fresh §6.2 identity, never shared"},"invite":{"status":"live","where":"§9.2 egg variant"},"memory":{"status":"live","where":"§7.2 kind family"},"metropolis":{"status":"retired","where":"rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate — bytes only at git 24c8fdc, sha256 690f6109…"},"neighborhood":{"status":"live","where":"§9.2 egg variant"},"organism":{"status":"live","where":"§9.2 egg variant"},"rapp-frame/2.0":{"status":"retired","where":"legacy envelope token, superseded by rapp/1 (§7.1)"},"rapp-frame/2.1":{"status":"retired","where":"legacy envelope token, superseded by rapp/1 (§7.1)"},"rapp-protocol/1.0":{"status":"retired","where":"legacy, superseded by rapp/1"},"rapp-rappid-spec/2.0":{"status":"retired","where":"legacy, superseded by rapp/1 §6"},"rapplication":{"status":"live","where":"§9.2 egg variant"},"rbox":{"status":"not-in-spec","where":"operator's working word for a machine running an organism; the spec's words are `organism` (§9.2) and `instance` (§9.4)"},"session":{"status":"live","where":"§9.2 egg variant"},"swarm":{"status":"live","where":"§7.2 kind family"}}},"payload_hash":"668aff2ebe980ce7a79a661e53bfa2612f110e2d6d80fe4b6250d5740d9ca521","prev":"fb24c39d10b7083a7907f85cd35d5e04a15edd1d233171782cfb297374e19f37","prev_wave":null,"seq":9,"sig":null,"spec":"rapp/1","stream_id":"rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6","utc":"2026-08-30T02:08:03.554Z"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 10, "utc": "2026-08-30T02:16:22.873Z", "payload": {"canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "be742eb97c36a705df0ee250e163e20c6d1cee76", "commit_utc": "2026-08-29T22:16:22-04:00", "default_profile": "interop", "exchange": {"carrier": "POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward.", "idempotence": "keyed on the request's payload_hash — a retry returns the existing reply, never a second one.", "rule": "the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.", "shape": "push a frame in, get a frame back shaped by what you pushed — ONE hop."}, "frame_keys": ["spec", "kind", "stream_id", "seq", "utc", "payload", "payload_hash", "prev", "prev_wave", "sig", "frame_hash"], "kind_families": {"body": {"kinds": ["body.pulse", "body.twin-pulse", "body.reconstructed", "body.re-genesis"], "logs": "an organism's biography", "stream": "body-stream (bare rappid)"}, "memory": {"kinds": ["memory.chat-turn", "memory.tool-call", "memory.save", "memory.reconstructed", "memory.re-genesis"], "logs": "one organism's life", "stream": "memory-stream"}, "swarm": {"kinds": ["swarm.guidance", "swarm.echo", "swarm.telemetry", "swarm.reconstructed", "swarm.re-genesis"], "logs": "the planetary wire", "stream": "swarm-stream (net:label)"}}, "moods": {"clear": {"profile": "interop", "when": {"conditions": "clear,sunny"}, "why": "good conditions, normal posture"}, "early": {"profile": "minimal", "when": {"hour_lt": "6"}, "why": "same"}, "night": {"profile": "minimal", "when": {"hour_gte": "22"}, "why": "low-attention hours; smallest honest context"}, "storm": {"profile": "audit", "when": {"conditions": "storm,rain,snow"}, "why": "degraded links are when drift hides; lead with verification"}}, "normative_bytes": "59282", "normative_path": "SPEC.md", "normative_sha256": "78f9cae4cbed02c7b5cd2a648350ccb4ffeacebb49fcbbe34ac6c80a4e507cf0", "observed_utc": "2026-08-30T02:16:22.873Z", "profile_signals": {"author": "authoring", "build": "authoring", "check": "audit", "conform": "audit", "drift": "audit", "handshake": "interop", "install": "onboarding", "join": "onboarding", "mint": "authoring", "new": "onboarding", "stranger": "interop", "unknown-peer": "interop", "verify": "audit", "write": "authoring"}, "profiles": {"audit": {"max_rules": "8", "show": ["keys", "stale_terms"], "types": ["pattern", "gotcha"], "why": "judging conformance; refuse-never-repair and the identity law govern"}, "authoring": {"max_rules": "8", "show": ["keys", "eggs"], "types": ["gotcha", "fact"], "why": "hand-building a frame; the envelope rules are what bite"}, "interop": {"max_rules": "6", "show": ["keys", "stale_terms", "pointer"], "types": ["gotcha"], "why": "a peer may be out of date; lead with what it can get WRONG"}, "minimal": {"max_rules": "0", "show": ["stale_terms"], "types": [], "why": "smallest honest context"}, "onboarding": {"max_rules": "5", "show": ["keys", "eggs", "stale_terms", "pointer"], "types": ["fact"], "why": "new organism; needs the shape of the world, not the edge cases"}}, "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "revision": "rev-10", "rules": [{"c": "spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted.", "t": "fact"}, {"c": "Canonical form is RFC 8785 JCS and FORBIDS floats — numbers ride as strings. A float silently breaks byte-reproducibility.", "t": "gotcha"}, {"c": "payload_hash = H(\"rapp/1:particle\", payload) — content only, reproducible across instances.", "t": "fact"}, {"c": "frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) — unique per stream instance.", "t": "fact"}, {"c": "prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable.", "t": "gotcha"}, {"c": "§6.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name — sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint.", "t": "gotcha"}, {"c": "Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed.", "t": "pattern"}, {"c": "A swarm-stream frame with sig==null is refused (§7.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null.", "t": "gotcha"}, {"c": "Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs.", "t": "fact"}, {"c": "Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise — this is how N streams compose into one view.", "t": "pattern"}, {"c": "One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct.", "t": "pattern"}, {"c": "§9.4 (rev-6): hatching an egg MUST mint a fresh §6.2 identity for the INSTANCE — the artifact rappid rides the egg unchanged and is shared by every install; the instance identity never is. The instance SHOULD record grown_from = the §9.1 egg address it grew from: written at mint, immutable, null when unknown, NEVER fabricated. Lineage, not inheritance — it confers no authority, no trust, no key material.", "t": "fact"}, {"c": "§11.1 / Constitution Article 15: owner policy selects only release_scope; the activated registry selects grail_id; every ring rejects kernel-drift; execution consumes bytes from a sealed immutable object or equivalent write-excluded snapshot.", "t": "gotcha"}, {"t": "gotcha", "c": "A sealed egg is public ciphertext, not password-protected hosting: the signed manifest binds AES-256-GCM data and a scoped key service; no shared DEK belongs in the egg, URL, client, log, or frame."}], "vocabulary": {"body": {"status": "live", "where": "§7.2 kind family"}, "estate": {"status": "live", "where": "§9.2 egg variant"}, "grail": {"status": "live", "where": "§3 terminology; §11.1 immutable Grail kernel conformance; Constitution Article 15"}, "grown_from": {"status": "live", "where": "§9.4 instantiation — instance lineage key"}, "instance": {"status": "live", "where": "§9.4 instantiation — a hatched install; fresh §6.2 identity, never shared"}, "invite": {"status": "live", "where": "§9.2 egg variant"}, "memory": {"status": "live", "where": "§7.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate — bytes only at git 24c8fdc, sha256 690f6109…"}, "neighborhood": {"status": "live", "where": "§9.2 egg variant"}, "organism": {"status": "live", "where": "§9.2 egg variant"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 §6"}, "rapplication": {"status": "live", "where": "§9.2 egg variant"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's words are `organism` (§9.2) and `instance` (§9.4)"}, "session": {"status": "live", "where": "§9.2 egg variant"}, "swarm": {"status": "live", "where": "§7.2 kind family"}, "sealed": {"status": "live", "where": "§9.2 sealed egg variant and §9.2.1 profile"}}}, "payload_hash": "bdd160bcb07e675dbd27a575dcbb9bf57241e91c8c6da590ad3a6eb146a5d97a", "prev": "668aff2ebe980ce7a79a661e53bfa2612f110e2d6d80fe4b6250d5740d9ca521", "prev_wave": null, "sig": null, "frame_hash": "d08fece2b3dd52593d7dad4602c0dd2f71e52e73d74c9813d90087f9015a495c"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 11, "utc": "2026-08-30T15:04:13.566Z", "payload": {"canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "177b09bffad360ed2c2b222d32fbad387cc19747", "commit_utc": "2026-08-30T11:04:01-04:00", "default_profile": "interop", "exchange": {"carrier": "POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward.", "idempotence": "keyed on the request's payload_hash — a retry returns the existing reply, never a second one.", "rule": "the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.", "shape": "push a frame in, get a frame back shaped by what you pushed — ONE hop."}, "frame_keys": ["spec", "kind", "stream_id", "seq", "utc", "payload", "payload_hash", "prev", "prev_wave", "sig", "frame_hash"], "kind_families": {"body": {"kinds": ["body.pulse", "body.twin-pulse", "body.reconstructed", "body.re-genesis"], "logs": "an organism's biography", "stream": "body-stream (bare rappid)"}, "memory": {"kinds": ["memory.chat-turn", "memory.tool-call", "memory.save", "memory.reconstructed", "memory.re-genesis"], "logs": "one organism's life", "stream": "memory-stream"}, "swarm": {"kinds": ["swarm.guidance", "swarm.echo", "swarm.telemetry", "swarm.reconstructed", "swarm.re-genesis"], "logs": "the planetary wire", "stream": "swarm-stream (net:label)"}}, "moods": {"clear": {"profile": "interop", "when": {"conditions": "clear,sunny"}, "why": "good conditions, normal posture"}, "early": {"profile": "minimal", "when": {"hour_lt": "6"}, "why": "same"}, "night": {"profile": "minimal", "when": {"hour_gte": "22"}, "why": "low-attention hours; smallest honest context"}, "storm": {"profile": "audit", "when": {"conditions": "storm,rain,snow"}, "why": "degraded links are when drift hides; lead with verification"}}, "normative_bytes": "63278", "normative_path": "SPEC.md", "normative_sha256": "2f9cc5cfc737597f152d814a4a2faaba9a30f8ff66221d2a8803a17f90ca5c8e", "observed_utc": "2026-08-30T15:04:13.566Z", "profile_signals": {"author": "authoring", "build": "authoring", "check": "audit", "conform": "audit", "drift": "audit", "handshake": "interop", "install": "onboarding", "join": "onboarding", "mint": "authoring", "new": "onboarding", "stranger": "interop", "unknown-peer": "interop", "verify": "audit", "write": "authoring"}, "profiles": {"audit": {"max_rules": "8", "show": ["keys", "stale_terms"], "types": ["pattern", "gotcha"], "why": "judging conformance; refuse-never-repair and the identity law govern"}, "authoring": {"max_rules": "8", "show": ["keys", "eggs"], "types": ["gotcha", "fact"], "why": "hand-building a frame; the envelope rules are what bite"}, "interop": {"max_rules": "6", "show": ["keys", "stale_terms", "pointer"], "types": ["gotcha"], "why": "a peer may be out of date; lead with what it can get WRONG"}, "minimal": {"max_rules": "0", "show": ["stale_terms"], "types": [], "why": "smallest honest context"}, "onboarding": {"max_rules": "5", "show": ["keys", "eggs", "stale_terms", "pointer"], "types": ["fact"], "why": "new organism; needs the shape of the world, not the edge cases"}}, "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "revision": "rev-11", "rules": [{"c": "spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted.", "t": "fact"}, {"c": "Canonical form is RFC 8785 JCS and FORBIDS floats — numbers ride as strings. A float silently breaks byte-reproducibility.", "t": "gotcha"}, {"c": "payload_hash = H(\"rapp/1:particle\", payload) — content only, reproducible across instances.", "t": "fact"}, {"c": "frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) — unique per stream instance.", "t": "fact"}, {"c": "prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable.", "t": "gotcha"}, {"c": "§6.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name — sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint.", "t": "gotcha"}, {"c": "Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed.", "t": "pattern"}, {"c": "A swarm-stream frame with sig==null is refused (§7.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null.", "t": "gotcha"}, {"c": "Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs.", "t": "fact"}, {"c": "Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise — this is how N streams compose into one view.", "t": "pattern"}, {"c": "One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct.", "t": "pattern"}, {"c": "§9.4 (rev-6): hatching an egg MUST mint a fresh §6.2 identity for the INSTANCE — the artifact rappid rides the egg unchanged and is shared by every install; the instance identity never is. The instance SHOULD record grown_from = the §9.1 egg address it grew from: written at mint, immutable, null when unknown, NEVER fabricated. Lineage, not inheritance — it confers no authority, no trust, no key material.", "t": "fact"}, {"c": "§11.1 / Constitution Article 15: owner policy selects only release_scope; the activated registry selects grail_id; every ring rejects kernel-drift; execution consumes bytes from a sealed immutable object or equivalent write-excluded snapshot.", "t": "gotcha"}, {"t": "gotcha", "c": "A sealed egg is public ciphertext, not password-protected hosting: the signed manifest binds AES-256-GCM data and a scoped key service; no shared DEK belongs in the egg, URL, client, log, or frame."}, {"t": "fact", "c": "RAPP CI/CD promotes one immutable release payload hash through an ordered evidence chain; no ring may rebuild, patch, substitute, or skip the candidate."}, {"t": "gotcha", "c": "RAPP Deploy forbids in-place serving mutation: growth happens in an isolated candidate lineage and reaches users only through bounded, reversible waves."}, {"t": "pattern", "c": "A new encounter may produce an offspring or cross with a fresh identity and typed parent addresses; lineage may continue indefinitely, but every attempt is bounded and parent authority never transfers implicitly."}], "vocabulary": {"body": {"status": "live", "where": "§7.2 kind family"}, "estate": {"status": "live", "where": "§9.2 egg variant"}, "grail": {"status": "live", "where": "§3 terminology; §11.1 immutable Grail kernel conformance; Constitution Article 15"}, "grown_from": {"status": "live", "where": "§9.4 instantiation — instance lineage key"}, "instance": {"status": "live", "where": "§9.4 instantiation — a hatched install; fresh §6.2 identity, never shared"}, "invite": {"status": "live", "where": "§9.2 egg variant"}, "memory": {"status": "live", "where": "§7.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate — bytes only at git 24c8fdc, sha256 690f6109…"}, "neighborhood": {"status": "live", "where": "§9.2 egg variant"}, "organism": {"status": "live", "where": "§9.2 egg variant"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 §6"}, "rapplication": {"status": "live", "where": "§9.2 egg variant"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's words are `organism` (§9.2) and `instance` (§9.4)"}, "session": {"status": "live", "where": "§9.2 egg variant"}, "swarm": {"status": "live", "where": "§7.2 kind family"}, "sealed": {"status": "live", "where": "§9.2 sealed egg variant and §9.2.1 profile"}, "rapp-cicd": {"status": "live", "where": "§11.2 and protocols/rapp-cicd/1/SPEC.md"}, "rapp-deploy": {"status": "live", "where": "§11.2 and protocols/rapp-deploy/1/SPEC.md"}, "offspring": {"status": "live", "where": "§9.4 typed lineage and PHILOSOPHY.md"}, "cross": {"status": "live", "where": "§9.4 typed multi-parent lineage and PHILOSOPHY.md"}}, "philosophy": {"path": "PHILOSOPHY.md", "sha256": "b996127493930b5bfd601bf828a372341e0b507e5e19bee9c5bdfec2e1112c62"}, "operational_profiles": {"rapp-cicd/1": {"status": "live", "spec_path": "protocols/rapp-cicd/1/SPEC.md", "spec_sha256": "6d27d10103a3204f3b65a2e246462d197016bce5203dd510ba3ce209740e8278", "schema_path": "protocols/rapp-cicd/1/schema.json", "schema_sha256": "5936057868f46fc74afa00532f4aea60cfbb667c7c2f09998e1e86a0c2e629cc"}, "rapp-deploy/1": {"status": "live", "spec_path": "protocols/rapp-deploy/1/SPEC.md", "spec_sha256": "b5fc84465fb201fd97d7059997490a8fae5bf79ec55e935b0cfd9b4c787108e5", "schema_path": "protocols/rapp-deploy/1/schema.json", "schema_sha256": "aca783f3274cd865926f6b943163189fa93a7bbc4c7d4258856a54779a4a71ba"}}}, "payload_hash": "1e2261c57c17db3e0a49d8576e8572115196f63312980bbdc015a628668b2be7", "prev": "bdd160bcb07e675dbd27a575dcbb9bf57241e91c8c6da590ad3a6eb146a5d97a", "prev_wave": null, "sig": null, "frame_hash": "4a15c02725494680ee8d9ae53e342e59cee4bcc30792b8056529bbd2290d55d9"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 12, "utc": "2026-08-30T18:33:07.718Z", "payload": {"canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "019ccb4b6177cb192b2383d31423874f298e4251", "commit_utc": "2026-08-30T14:32:45-04:00", "default_profile": "interop", "exchange": {"carrier": "POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward.", "idempotence": "keyed on the request's payload_hash — a retry returns the existing reply, never a second one.", "rule": "the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.", "shape": "push a frame in, get a frame back shaped by what you pushed — ONE hop."}, "frame_keys": ["spec", "kind", "stream_id", "seq", "utc", "payload", "payload_hash", "prev", "prev_wave", "sig", "frame_hash"], "kind_families": {"body": {"kinds": ["body.pulse", "body.twin-pulse", "body.reconstructed", "body.re-genesis"], "logs": "an organism's biography", "stream": "body-stream (bare rappid)"}, "memory": {"kinds": ["memory.chat-turn", "memory.tool-call", "memory.save", "memory.reconstructed", "memory.re-genesis"], "logs": "one organism's life", "stream": "memory-stream"}, "swarm": {"kinds": ["swarm.guidance", "swarm.echo", "swarm.telemetry", "swarm.reconstructed", "swarm.re-genesis"], "logs": "the planetary wire", "stream": "swarm-stream (net:label)"}}, "moods": {"clear": {"profile": "interop", "when": {"conditions": "clear,sunny"}, "why": "good conditions, normal posture"}, "early": {"profile": "minimal", "when": {"hour_lt": "6"}, "why": "same"}, "night": {"profile": "minimal", "when": {"hour_gte": "22"}, "why": "low-attention hours; smallest honest context"}, "storm": {"profile": "audit", "when": {"conditions": "storm,rain,snow"}, "why": "degraded links are when drift hides; lead with verification"}}, "normative_bytes": "65151", "normative_path": "SPEC.md", "normative_sha256": "e753f4f967ce7553fec4ba04373d06d9b10fd8b83e868ba1ce5b866f65243fa0", "observed_utc": "2026-08-30T18:33:07.718Z", "profile_signals": {"author": "authoring", "build": "authoring", "check": "audit", "conform": "audit", "drift": "audit", "handshake": "interop", "install": "onboarding", "join": "onboarding", "mint": "authoring", "new": "onboarding", "stranger": "interop", "unknown-peer": "interop", "verify": "audit", "write": "authoring"}, "profiles": {"audit": {"max_rules": "8", "show": ["keys", "stale_terms"], "types": ["pattern", "gotcha"], "why": "judging conformance; refuse-never-repair and the identity law govern"}, "authoring": {"max_rules": "8", "show": ["keys", "eggs"], "types": ["gotcha", "fact"], "why": "hand-building a frame; the envelope rules are what bite"}, "interop": {"max_rules": "6", "show": ["keys", "stale_terms", "pointer"], "types": ["gotcha"], "why": "a peer may be out of date; lead with what it can get WRONG"}, "minimal": {"max_rules": "0", "show": ["stale_terms"], "types": [], "why": "smallest honest context"}, "onboarding": {"max_rules": "5", "show": ["keys", "eggs", "stale_terms", "pointer"], "types": ["fact"], "why": "new organism; needs the shape of the world, not the edge cases"}}, "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "revision": "rev-12", "rules": [{"c": "spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted.", "t": "fact"}, {"c": "Canonical form is RFC 8785 JCS and FORBIDS floats — numbers ride as strings. A float silently breaks byte-reproducibility.", "t": "gotcha"}, {"c": "payload_hash = H(\"rapp/1:particle\", payload) — content only, reproducible across instances.", "t": "fact"}, {"c": "frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) — unique per stream instance.", "t": "fact"}, {"c": "prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable.", "t": "gotcha"}, {"c": "§6.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name — sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint.", "t": "gotcha"}, {"c": "Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed.", "t": "pattern"}, {"c": "A swarm-stream frame with sig==null is refused (§7.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null.", "t": "gotcha"}, {"c": "Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs.", "t": "fact"}, {"c": "Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise — this is how N streams compose into one view.", "t": "pattern"}, {"c": "One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct.", "t": "pattern"}, {"c": "§9.4 (rev-6): hatching an egg MUST mint a fresh §6.2 identity for the INSTANCE — the artifact rappid rides the egg unchanged and is shared by every install; the instance identity never is. The instance SHOULD record grown_from = the §9.1 egg address it grew from: written at mint, immutable, null when unknown, NEVER fabricated. Lineage, not inheritance — it confers no authority, no trust, no key material.", "t": "fact"}, {"c": "§11.1 / Constitution Article 15: owner policy selects only release_scope; the activated registry selects grail_id; every ring rejects kernel-drift; execution consumes bytes from a sealed immutable object or equivalent write-excluded snapshot.", "t": "gotcha"}, {"t": "gotcha", "c": "A sealed egg is public ciphertext, not password-protected hosting: the signed manifest binds AES-256-GCM data and a scoped key service; no shared DEK belongs in the egg, URL, client, log, or frame."}, {"t": "fact", "c": "RAPP CI/CD promotes one immutable release payload hash through an ordered evidence chain; no ring may rebuild, patch, substitute, or skip the candidate."}, {"t": "gotcha", "c": "RAPP Deploy forbids in-place serving mutation: growth happens in an isolated candidate lineage and reaches users only through bounded, reversible waves."}, {"t": "pattern", "c": "A new encounter may produce an offspring or cross with a fresh identity and typed parent addresses; lineage may continue indefinitely, but every attempt is bounded and parent authority never transfers implicitly."}, {"t": "fact", "c": "kody-w/RAPP remains the public foundation and product home; kody-w/rapp-1 defines the interoperable protocol only."}], "vocabulary": {"body": {"status": "live", "where": "§7.2 kind family"}, "estate": {"status": "live", "where": "§9.2 egg variant"}, "grail": {"status": "live", "where": "§3 terminology; §11.1 immutable Grail kernel conformance; Constitution Article 15"}, "grown_from": {"status": "live", "where": "§9.4 instantiation — instance lineage key"}, "instance": {"status": "live", "where": "§9.4 instantiation — a hatched install; fresh §6.2 identity, never shared"}, "invite": {"status": "live", "where": "§9.2 egg variant"}, "memory": {"status": "live", "where": "§7.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate — bytes only at git 24c8fdc, sha256 690f6109…"}, "neighborhood": {"status": "live", "where": "§9.2 egg variant"}, "organism": {"status": "live", "where": "§9.2 egg variant"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 §6"}, "rapplication": {"status": "live", "where": "§9.2 egg variant"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's words are `organism` (§9.2) and `instance` (§9.4)"}, "session": {"status": "live", "where": "§9.2 egg variant"}, "swarm": {"status": "live", "where": "§7.2 kind family"}, "sealed": {"status": "live", "where": "§9.2 sealed egg variant and §9.2.1 profile"}, "rapp-cicd": {"status": "live", "where": "§11.2 and protocols/rapp-cicd/1/SPEC.md"}, "rapp-deploy": {"status": "live", "where": "§11.2 and protocols/rapp-deploy/1/SPEC.md"}, "offspring": {"status": "live", "where": "§9.4 typed lineage and PHILOSOPHY.md"}, "cross": {"status": "live", "where": "§9.4 typed multi-parent lineage and PHILOSOPHY.md"}}, "philosophy": {"canonical_repository": "https://github.com/kody-w/RAPP", "canonical_commit": "cb921ae59b5d762ce0bdd5493764cbb1c8b539fe", "canonical_path": "PHILOSOPHY.md", "canonical_sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c", "mirror_path": "PHILOSOPHY.md", "mirror_sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c"}, "operational_profiles": {"rapp-cicd/1": {"status": "live", "spec_path": "protocols/rapp-cicd/1/SPEC.md", "spec_sha256": "6d27d10103a3204f3b65a2e246462d197016bce5203dd510ba3ce209740e8278", "schema_path": "protocols/rapp-cicd/1/schema.json", "schema_sha256": "5936057868f46fc74afa00532f4aea60cfbb667c7c2f09998e1e86a0c2e629cc"}, "rapp-deploy/1": {"status": "live", "spec_path": "protocols/rapp-deploy/1/SPEC.md", "spec_sha256": "b5fc84465fb201fd97d7059997490a8fae5bf79ec55e935b0cfd9b4c787108e5", "schema_path": "protocols/rapp-deploy/1/schema.json", "schema_sha256": "aca783f3274cd865926f6b943163189fa93a7bbc4c7d4258856a54779a4a71ba"}}, "constitution": {"path": "CONSTITUTION.md", "sha256": "545086b6cd241bfc4741e94c8cec3300e61d9f446f1571694f11b7ea549e5129", "size_bytes": 13494}, "foundation": {"schema": "rapp-foundation-pointer/1", "status": "canonical-product-home", "repository": "https://github.com/kody-w/RAPP", "commit": "cb921ae59b5d762ce0bdd5493764cbb1c8b539fe", "path": "PHILOSOPHY.md", "sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c", "size_bytes": 2633, "relationship": "kody-w/RAPP is the public RAPP foundation and product home; kody-w/rapp-1 is the interoperable protocol authority"}}, "payload_hash": "415f2f79e285039f476baf647e0e037b52cc4ead110a5c99a44634e12ffc055a", "prev": "1e2261c57c17db3e0a49d8576e8572115196f63312980bbdc015a628668b2be7", "prev_wave": null, "sig": null, "frame_hash": "d2bcf3a642237634025fece571187fc7db0e0a473192b03858a5a6c9735b8cc0"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 13, "utc": "2026-08-30T18:48:18.785Z", "payload": {"canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "5e30f66396f4cd125bce5718b1fef92d8d3ddab8", "commit_utc": "2026-08-30T14:42:40-04:00", "default_profile": "interop", "exchange": {"carrier": "POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward.", "idempotence": "keyed on the request's payload_hash — a retry returns the existing reply, never a second one.", "rule": "the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.", "shape": "push a frame in, get a frame back shaped by what you pushed — ONE hop."}, "frame_keys": ["spec", "kind", "stream_id", "seq", "utc", "payload", "payload_hash", "prev", "prev_wave", "sig", "frame_hash"], "kind_families": {"body": {"kinds": ["body.pulse", "body.twin-pulse", "body.reconstructed", "body.re-genesis"], "logs": "an organism's biography", "stream": "body-stream (bare rappid)"}, "memory": {"kinds": ["memory.chat-turn", "memory.tool-call", "memory.save", "memory.reconstructed", "memory.re-genesis"], "logs": "one organism's life", "stream": "memory-stream"}, "swarm": {"kinds": ["swarm.guidance", "swarm.echo", "swarm.telemetry", "swarm.reconstructed", "swarm.re-genesis"], "logs": "the planetary wire", "stream": "swarm-stream (net:label)"}}, "moods": {"clear": {"profile": "interop", "when": {"conditions": "clear,sunny"}, "why": "good conditions, normal posture"}, "early": {"profile": "minimal", "when": {"hour_lt": "6"}, "why": "same"}, "night": {"profile": "minimal", "when": {"hour_gte": "22"}, "why": "low-attention hours; smallest honest context"}, "storm": {"profile": "audit", "when": {"conditions": "storm,rain,snow"}, "why": "degraded links are when drift hides; lead with verification"}}, "normative_bytes": "65569", "normative_path": "SPEC.md", "normative_sha256": "e5abd6a32801761fdd5c151a4f90fa4c989b545da02d3cd26dfc4765fab8409a", "observed_utc": "2026-08-30T18:48:18.785Z", "profile_signals": {"author": "authoring", "build": "authoring", "check": "audit", "conform": "audit", "drift": "audit", "handshake": "interop", "install": "onboarding", "join": "onboarding", "mint": "authoring", "new": "onboarding", "stranger": "interop", "unknown-peer": "interop", "verify": "audit", "write": "authoring"}, "profiles": {"audit": {"max_rules": "8", "show": ["keys", "stale_terms"], "types": ["pattern", "gotcha"], "why": "judging conformance; refuse-never-repair and the identity law govern"}, "authoring": {"max_rules": "8", "show": ["keys", "eggs"], "types": ["gotcha", "fact"], "why": "hand-building a frame; the envelope rules are what bite"}, "interop": {"max_rules": "6", "show": ["keys", "stale_terms", "pointer"], "types": ["gotcha"], "why": "a peer may be out of date; lead with what it can get WRONG"}, "minimal": {"max_rules": "0", "show": ["stale_terms"], "types": [], "why": "smallest honest context"}, "onboarding": {"max_rules": "5", "show": ["keys", "eggs", "stale_terms", "pointer"], "types": ["fact"], "why": "new organism; needs the shape of the world, not the edge cases"}}, "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "revision": "rev-13", "rules": [{"c": "spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted.", "t": "fact"}, {"c": "Canonical form is RFC 8785 JCS and FORBIDS floats — numbers ride as strings. A float silently breaks byte-reproducibility.", "t": "gotcha"}, {"c": "payload_hash = H(\"rapp/1:particle\", payload) — content only, reproducible across instances.", "t": "fact"}, {"c": "frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) — unique per stream instance.", "t": "fact"}, {"c": "prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable.", "t": "gotcha"}, {"c": "§6.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name — sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint.", "t": "gotcha"}, {"c": "Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed.", "t": "pattern"}, {"c": "A swarm-stream frame with sig==null is refused (§7.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null.", "t": "gotcha"}, {"c": "Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs.", "t": "fact"}, {"c": "Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise — this is how N streams compose into one view.", "t": "pattern"}, {"c": "One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct.", "t": "pattern"}, {"c": "§9.4 (rev-6): hatching an egg MUST mint a fresh §6.2 identity for the INSTANCE — the artifact rappid rides the egg unchanged and is shared by every install; the instance identity never is. The instance SHOULD record grown_from = the §9.1 egg address it grew from: written at mint, immutable, null when unknown, NEVER fabricated. Lineage, not inheritance — it confers no authority, no trust, no key material.", "t": "fact"}, {"c": "§11.1 / Constitution Article 15: owner policy selects only release_scope; the activated registry selects grail_id; every ring rejects kernel-drift; execution consumes bytes from a sealed immutable object or equivalent write-excluded snapshot.", "t": "gotcha"}, {"t": "gotcha", "c": "A sealed egg is public ciphertext, not password-protected hosting: the signed manifest binds AES-256-GCM data and a scoped key service; no shared DEK belongs in the egg, URL, client, log, or frame."}, {"t": "fact", "c": "RAPP CI/CD promotes one immutable release payload hash through an ordered evidence chain; no ring may rebuild, patch, substitute, or skip the candidate."}, {"t": "gotcha", "c": "RAPP Deploy forbids in-place serving mutation: growth happens in an isolated candidate lineage and reaches users only through bounded, reversible waves."}, {"t": "pattern", "c": "A new encounter may produce an offspring or cross with a fresh identity and typed parent addresses; lineage may continue indefinitely, but every attempt is bounded and parent authority never transfers implicitly."}, {"t": "fact", "c": "kody-w/RAPP remains the public foundation and product home; kody-w/rapp-1 defines the interoperable protocol only."}], "vocabulary": {"body": {"status": "live", "where": "§7.2 kind family"}, "estate": {"status": "live", "where": "§9.2 egg variant"}, "grail": {"status": "live", "where": "§3 terminology; §11.1 immutable Grail kernel conformance; Constitution Article 15"}, "grown_from": {"status": "live", "where": "§9.4 instantiation — instance lineage key"}, "instance": {"status": "live", "where": "§9.4 instantiation — a hatched install; fresh §6.2 identity, never shared"}, "invite": {"status": "live", "where": "§9.2 egg variant"}, "memory": {"status": "live", "where": "§7.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate — bytes only at git 24c8fdc, sha256 690f6109…"}, "neighborhood": {"status": "live", "where": "§9.2 egg variant"}, "organism": {"status": "live", "where": "§9.2 egg variant"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 §6"}, "rapplication": {"status": "live", "where": "§9.2 egg variant"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's words are `organism` (§9.2) and `instance` (§9.4)"}, "session": {"status": "live", "where": "§9.2 egg variant"}, "swarm": {"status": "live", "where": "§7.2 kind family"}, "sealed": {"status": "live", "where": "§9.2 sealed egg variant and §9.2.1 profile"}, "rapp-cicd": {"status": "live", "where": "§11.2 and protocols/rapp-cicd/1/SPEC.md"}, "rapp-deploy": {"status": "live", "where": "§11.2 and protocols/rapp-deploy/1/SPEC.md"}, "offspring": {"status": "live", "where": "§9.4 typed lineage and PHILOSOPHY.md"}, "cross": {"status": "live", "where": "§9.4 typed multi-parent lineage and PHILOSOPHY.md"}}, "philosophy": {"canonical_repository": "https://github.com/kody-w/RAPP", "canonical_commit": "cb921ae59b5d762ce0bdd5493764cbb1c8b539fe", "canonical_path": "PHILOSOPHY.md", "canonical_sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c", "mirror_path": "PHILOSOPHY.md", "mirror_sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c"}, "operational_profiles": {"rapp-cicd/1": {"status": "live", "spec_path": "protocols/rapp-cicd/1/SPEC.md", "spec_sha256": "6d27d10103a3204f3b65a2e246462d197016bce5203dd510ba3ce209740e8278", "schema_path": "protocols/rapp-cicd/1/schema.json", "schema_sha256": "5936057868f46fc74afa00532f4aea60cfbb667c7c2f09998e1e86a0c2e629cc"}, "rapp-deploy/1": {"status": "live", "spec_path": "protocols/rapp-deploy/1/SPEC.md", "spec_sha256": "b5fc84465fb201fd97d7059997490a8fae5bf79ec55e935b0cfd9b4c787108e5", "schema_path": "protocols/rapp-deploy/1/schema.json", "schema_sha256": "aca783f3274cd865926f6b943163189fa93a7bbc4c7d4258856a54779a4a71ba"}}, "constitution": {"path": "CONSTITUTION.md", "sha256": "545086b6cd241bfc4741e94c8cec3300e61d9f446f1571694f11b7ea549e5129", "size_bytes": 13494}, "foundation": {"schema": "rapp-foundation-pointer/1", "status": "canonical-product-home", "repository": "https://github.com/kody-w/RAPP", "commit": "cb921ae59b5d762ce0bdd5493764cbb1c8b539fe", "path": "PHILOSOPHY.md", "sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c", "size_bytes": 2633, "relationship": "kody-w/RAPP is the public RAPP foundation and product home; kody-w/rapp-1 is the interoperable protocol authority"}}, "payload_hash": "78a89c06509b5100494b9c7e0f551acdc6209fd90aded734321f3580b0f07051", "prev": "415f2f79e285039f476baf647e0e037b52cc4ead110a5c99a44634e12ffc055a", "prev_wave": null, "sig": null, "frame_hash": "bbcee75ebbbf82d11d8ffd666fdda34c8233642de6d6e4f45910d43a24a001e3"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 14, "utc": "2026-08-30T23:40:07.000Z", "payload": {"canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "1a27d11eec48a7f9ebda4208916a67ffd3a24b7f", "commit_utc": "2026-08-30T19:40:07-04:00", "default_profile": "interop", "exchange": {"carrier": "POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward.", "idempotence": "keyed on the request's payload_hash — a retry returns the existing reply, never a second one.", "rule": "the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.", "shape": "push a frame in, get a frame back shaped by what you pushed — ONE hop."}, "frame_keys": ["spec", "kind", "stream_id", "seq", "utc", "payload", "payload_hash", "prev", "prev_wave", "sig", "frame_hash"], "kind_families": {"body": {"kinds": ["body.pulse", "body.twin-pulse", "body.reconstructed", "body.re-genesis"], "logs": "an organism's biography", "stream": "body-stream (bare rappid)"}, "memory": {"kinds": ["memory.chat-turn", "memory.tool-call", "memory.save", "memory.reconstructed", "memory.re-genesis"], "logs": "one organism's life", "stream": "memory-stream"}, "swarm": {"kinds": ["swarm.guidance", "swarm.echo", "swarm.telemetry", "swarm.reconstructed", "swarm.re-genesis"], "logs": "the planetary wire", "stream": "swarm-stream (net:label)"}}, "moods": {"clear": {"profile": "interop", "when": {"conditions": "clear,sunny"}, "why": "good conditions, normal posture"}, "early": {"profile": "minimal", "when": {"hour_lt": "6"}, "why": "same"}, "night": {"profile": "minimal", "when": {"hour_gte": "22"}, "why": "low-attention hours; smallest honest context"}, "storm": {"profile": "audit", "when": {"conditions": "storm,rain,snow"}, "why": "degraded links are when drift hides; lead with verification"}}, "normative_bytes": "78183", "normative_path": "SPEC.md", "normative_sha256": "d345235be5bc698d78c5893285abd09f2e62a398f781123d1de8da313a01c7de", "observed_utc": "2026-08-30T23:40:07.000Z", "profile_signals": {"author": "authoring", "build": "authoring", "check": "audit", "conform": "audit", "drift": "audit", "handshake": "interop", "install": "onboarding", "join": "onboarding", "mint": "authoring", "new": "onboarding", "stranger": "interop", "unknown-peer": "interop", "verify": "audit", "write": "authoring"}, "profiles": {"audit": {"max_rules": "8", "show": ["keys", "stale_terms"], "types": ["pattern", "gotcha"], "why": "judging conformance; refuse-never-repair and the identity law govern"}, "authoring": {"max_rules": "8", "show": ["keys", "eggs"], "types": ["gotcha", "fact"], "why": "hand-building a frame; the envelope rules are what bite"}, "interop": {"max_rules": "6", "show": ["keys", "stale_terms", "pointer"], "types": ["gotcha"], "why": "a peer may be out of date; lead with what it can get WRONG"}, "minimal": {"max_rules": "0", "show": ["stale_terms"], "types": [], "why": "smallest honest context"}, "onboarding": {"max_rules": "5", "show": ["keys", "eggs", "stale_terms", "pointer"], "types": ["fact"], "why": "new organism; needs the shape of the world, not the edge cases"}}, "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "revision": "rev-14", "rules": [{"c": "spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted.", "t": "fact"}, {"c": "Canonical form is RFC 8785 JCS and FORBIDS floats — numbers ride as strings. A float silently breaks byte-reproducibility.", "t": "gotcha"}, {"c": "payload_hash = H(\"rapp/1:particle\", payload) — content only, reproducible across instances.", "t": "fact"}, {"c": "frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) — unique per stream instance.", "t": "fact"}, {"c": "prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable.", "t": "gotcha"}, {"c": "§6.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name — sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint.", "t": "gotcha"}, {"c": "Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed.", "t": "pattern"}, {"c": "A swarm-stream frame with sig==null is refused (§7.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null.", "t": "gotcha"}, {"c": "Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs.", "t": "fact"}, {"c": "Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise — this is how N streams compose into one view.", "t": "pattern"}, {"c": "One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct.", "t": "pattern"}, {"c": "§9.4 (rev-6): hatching an egg MUST mint a fresh §6.2 identity for the INSTANCE — the artifact rappid rides the egg unchanged and is shared by every install; the instance identity never is. The instance SHOULD record grown_from = the §9.1 egg address it grew from: written at mint, immutable, null when unknown, NEVER fabricated. Lineage, not inheritance — it confers no authority, no trust, no key material.", "t": "fact"}, {"c": "§11.1 / Constitution Article 15: owner policy selects only release_scope; the activated registry selects grail_id; every ring rejects kernel-drift; execution consumes bytes from a sealed immutable object or equivalent write-excluded snapshot.", "t": "gotcha"}, {"t": "gotcha", "c": "A sealed egg is public ciphertext, not password-protected hosting: the signed manifest binds AES-256-GCM data and a scoped key service; no shared DEK belongs in the egg, URL, client, log, or frame."}, {"t": "fact", "c": "RAPP CI/CD promotes one immutable release payload hash through an ordered evidence chain; no ring may rebuild, patch, substitute, or skip the candidate."}, {"t": "gotcha", "c": "RAPP Deploy forbids in-place serving mutation: growth happens in an isolated candidate lineage and reaches users only through bounded, reversible waves."}, {"t": "pattern", "c": "A new encounter may produce an offspring or cross with a fresh identity and typed parent addresses; lineage may continue indefinitely, but every attempt is bounded and parent authority never transfers implicitly."}, {"t": "fact", "c": "kody-w/RAPP remains the public foundation and product home; kody-w/rapp-1 defines the interoperable protocol only."}], "vocabulary": {"body": {"status": "live", "where": "§7.2 kind family"}, "estate": {"status": "live", "where": "§9.2 egg variant"}, "grail": {"status": "live", "where": "§3 terminology; §11.1 immutable Grail kernel conformance; Constitution Article 15"}, "grown_from": {"status": "live", "where": "§9.4 instantiation — instance lineage key"}, "instance": {"status": "live", "where": "§9.4 instantiation — a hatched install; fresh §6.2 identity, never shared"}, "invite": {"status": "live", "where": "§9.2 egg variant"}, "memory": {"status": "live", "where": "§7.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate — bytes only at git 24c8fdc, sha256 690f6109…"}, "neighborhood": {"status": "live", "where": "§9.2 egg variant"}, "organism": {"status": "live", "where": "§9.2 egg variant"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 §6"}, "rapplication": {"status": "live", "where": "§9.2 egg variant"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's words are `organism` (§9.2) and `instance` (§9.4)"}, "session": {"status": "live", "where": "§9.2 egg variant"}, "swarm": {"status": "live", "where": "§7.2 kind family"}, "sealed": {"status": "live", "where": "§9.2 sealed egg variant and §9.2.1 profile"}, "rapp-cicd": {"status": "live", "where": "§11.2 and protocols/rapp-cicd/1/SPEC.md"}, "rapp-deploy": {"status": "live", "where": "§11.2 and protocols/rapp-deploy/1/SPEC.md"}, "offspring": {"status": "live", "where": "§9.4 typed lineage and PHILOSOPHY.md"}, "cross": {"status": "live", "where": "§9.4 typed multi-parent lineage and PHILOSOPHY.md"}}, "philosophy": {"canonical_repository": "https://github.com/kody-w/RAPP", "canonical_commit": "cb921ae59b5d762ce0bdd5493764cbb1c8b539fe", "canonical_path": "PHILOSOPHY.md", "canonical_sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c", "mirror_path": "PHILOSOPHY.md", "mirror_sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c"}, "operational_profiles": {"rapp-cicd/1": {"status": "live", "spec_path": "protocols/rapp-cicd/1/SPEC.md", "spec_sha256": "6d27d10103a3204f3b65a2e246462d197016bce5203dd510ba3ce209740e8278", "schema_path": "protocols/rapp-cicd/1/schema.json", "schema_sha256": "5936057868f46fc74afa00532f4aea60cfbb667c7c2f09998e1e86a0c2e629cc"}, "rapp-deploy/1": {"status": "live", "spec_path": "protocols/rapp-deploy/1/SPEC.md", "spec_sha256": "b5fc84465fb201fd97d7059997490a8fae5bf79ec55e935b0cfd9b4c787108e5", "schema_path": "protocols/rapp-deploy/1/schema.json", "schema_sha256": "aca783f3274cd865926f6b943163189fa93a7bbc4c7d4258856a54779a4a71ba"}}, "constitution": {"path": "CONSTITUTION.md", "sha256": "c218819541c0a2caa88048f208aa28c632577bff9a8512b1d7f6d2e484a18d21", "size_bytes": 16124}, "foundation": {"schema": "rapp-foundation-pointer/1", "status": "canonical-product-home", "repository": "https://github.com/kody-w/RAPP", "commit": "cb921ae59b5d762ce0bdd5493764cbb1c8b539fe", "path": "PHILOSOPHY.md", "sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c", "size_bytes": 2633, "relationship": "kody-w/RAPP is the public RAPP foundation and product home; kody-w/rapp-1 is the interoperable protocol authority"}, "schema": "rapp-spec-revision/1", "previous_revision": "rev-13", "previous_normative_sha256": "e5abd6a32801761fdd5c151a4f90fa4c989b545da02d3cd26dfc4765fab8409a", "normative": {"media_type": "text/markdown; charset=utf-8", "text": "# The RAPP Protocol Suite\n### Unified normative specification of identity, canonicalization, the frame, the wire, and the egg\n\n> **Generated/materialized view.** These exact UTF-8 bytes are carried inside\n> the selected specification-revision frame in `anchor/chain.jsonl`. The frame\n> chain proves integrity and lineage; canonical owner-ratified publication\n> selects authority. Change the protocol by appending a successor frame, not by\n> treating this file as independent authority.\n\n**Status:** Owner-ratified RAPP/1 **rev-14 amendment**. It is effective iff the\nprepared chain snapshot has been accepted onto canonical protected main under\nthe transition in §12.2. **Obsoletes / consolidates:**\n`rapp-frame/2.0`, `rapp-frame/2.1`, `rapp-rappid-spec/2.0`, `rapp-protocol/1.0`, all scattered egg specs\n(§9 subsumes them), and `OSI.md`. This is the current materialized view of the single living standard;\nthe consolidated specs are retired historical record (Protocol Constitution Article 6). Rev-14 becomes\nthe published current revision when the source merge and append-only anchor update carrying these exact\nbytes complete.\n\n**Rides existing standards; invents nothing:** requirement terms [RFC 2119]/[RFC 8174]; JSON restricted to\nI-JSON [RFC 7493] over [RFC 8259]; canonicalization [RFC 8785] (JCS); hashing SHA-256 [FIPS 180-4] with\ngit-style domain separation; identifiers on the [RFC 3986] URI model; case-sensitive grammar [RFC 7405]\nover [RFC 5234] ABNF; keyless entropy UUIDv4 [RFC 9562]; keyed identity X.509 SPKI [RFC 5280]; signatures\ndetached unencoded JWS [RFC 7515]/[RFC 7797], EdDSA [RFC 8037] / ES256 [RFC 7518]/[RFC 6979]. RAPP is a\n*profile* over these, as HTTP profiles TCP/URIs/MIME.\n\n---\n\n## 1. Introduction\nRAPP is a content-addressed distributed organism. Its integrity rests on one invariant: **the same\nconcept has the same bytes everywhere.** This document specifies, normatively and completely, five\nload-bearing primitives so any two independent implementations interoperate **byte-for-byte with no\nout-of-band agreement**: canonicalization (§4), content addressing (§5), identity (§6), the frame (§7),\nthe egg (§9) — all riding one wire (§8): `POST /chat`, or a signed append-only frame. Implementations add\nagents, cartridges, and registered `kind`s — never new endpoints, never new envelopes.\n\n**Repository scope.** `kody-w/RAPP` is the canonical public RAPP foundation,\nproduct home, reference implementation, organism model, and philosophy.\n`kody-w/rapp-1` is the canonical interoperable protocol authority. This\nspecification governs wire-compatible bytes and conformance; it does not absorb\nthe RAPP product or any downstream Rappter/RapterBox LLC product.\n\n**Specification authority.** The append-only DOGG chain at\n`anchor/chain.jsonl` carries the normative revision content. Its hashes prove\nintegrity, not authority or ratification. Until an authenticated RAPP\nregistry/checkpoint exists, the chain accepted by the owner onto protected\ncanonical `kody-w/rapp-1` main is authoritative; an immutable accepted commit\nplus head frame hash is the portable checkpoint. `SPEC.md` is the byte-exact\nmaterialized human view, and `orient.json` is only a discovery beacon. The\nselected chain-frame hash, not a mutable path or `rev-N` label, is the durable\nidentity of a protocol revision (§12.2).\n\n### 1.1 The layered model\n```\n  L5  EGG        cartridge packaging (§9)          — MIME-multipart analogue\n  L4  FRAME      universal event envelope (§7)     — the IP packet of RAPP\n  L3  WIRE       transport: /chat + frames (§8)    — HTTP-analogue single method\n  L2  IDENTITY   rappid namespace + trust (§6,§10) — URI + PKI analogue\n  L1  ADDRESS    canonicalization + hash (§4,§5)   — the git object model\n```\nA higher layer **MUST NOT** redefine a lower one. Every layer names exactly one canonical form.\n\n## 2. Requirements language\nThe key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHOULD**, **MAY** are as in [RFC 2119]/\n[RFC 8174] when in **bold caps**. (The Federal Constitution adopts the same clause.)\n\n## 3. Terminology\n**organism** — a running brainstem with persistent identity. **rappid** — the eternal, mint-once name of an\norganism/door/object (§6): minted once from a UUIDv4 or a public key, never derived from content or name.\n**frame** — one immutable content-addressed event (§7). **stream** — an append-only hash-chained frame\nsequence sharing one `stream_id`. **particle / wave** — a frame's two domain-separated addresses:\npayload-hash / whole-frame-hash (§7.3). **canonical form** — the one [RFC 8785] byte string for a value\n(§4). **legacy form** — any other historical encoding; legacy is drift and **MUST** be migrated out\n(Fed. Const. Art. III), except sealed re-genesis history (§12.1).\n**Grail kernel** — an estate-declared, byte-pinned runtime substrate. Its `grail_id` is\n`\"grail:\" || Hb(\"rapp/1:grail\", kernel_bytes)`; repository, immutable ref, commit, path, raw SHA-256,\nand byte length are provenance and verification data, not alternate identities. Once activated through\n§13.3, those bytes are permanent (Protocol Constitution Art. 15); capabilities evolve outside them.\n**release capsule** — the canonical `rapp-cicd/1-release` payload identifying one immutable candidate.\n**serving lineage** — the sequence of qualified release identities that have received user traffic;\nthe currently served release is immutable even while a separate candidate lineage grows.\n**deployment cell** — an independently observable and isolatable runtime failure domain governed by\n`rapp-deploy/1`.\n\n## 4. Canonicalization (L1)\n`canonical(v)` is the UTF-8 byte string produced by **[RFC 8785] JCS** for the value `v`, defined **only**\nover I-JSON [RFC 7493]. JCS fixes member-name ordering (UTF-16 code-unit), string escaping, and number\nserialization (ECMAScript `Number::toString`, [ECMA-262]); there is no insignificant whitespace and no\nbyte-order mark.\n\n**RAPP input-domain profile (parse-side interoperability — this is a RAPP rule, not a JCS mandate).** An\nimplementation **MUST** refuse (never repair) any JSON value that, at any depth, contains: (a) duplicate\nmember names in one object; (b) an unpaired UTF-16 surrogate in any string; (c) a number token that does\nnot survive the binary64 round-trip — let `d` be the token's nearest binary64 value under `roundTiesToEven`\n(the IEEE-754 default; ±∞ are admissible results); the token is refused iff `d` is not finite, or the\n[RFC 8785] serialization of `d` (ECMA-262 `Number::toString`) denotes a different mathematical value than\nthe token (so `0.1` is accepted — it round-trips — while `9007199254740993` and `1e999` (→ +∞) are refused); (d) canonical form exceeding 1 MiB or JSON nesting depth\nexceeding 64 (the root value is depth 1; each nested object/array adds 1). Refusal is whole (§7.5-style),\nnever partial.\n\n**No normalization.** RAPP applies **no** Unicode normalization when hashing, storing, or re-emitting an\nexisting value; strings are code-point sequences preserved verbatim and equality everywhere is code-point\nequality (no canonical-equivalence matching). A producer creating a **new** human-or-identifier string\n(slug, kind, label, `payload` object key) **MUST** emit it in Unicode NFC.\n\n> **Migration note (drift C4):** the `twin`/`rapp-body` `_frame.mjs::canonicalize()` (sorted-key\n> `JSON.stringify`) coincides with JCS only for string-only payloads; it **MUST** be replaced by the JCS\n> implementation of record, imported (not re-typed) by every repo that content-addresses.\n\n## 5. Content addressing (L1) — domain-separated\nEvery hash is **domain-separated** (git's `type\\0`, Nix's tagged store — collisions across address spaces\nare made unconstructible):\n```\nH(space, v) = lowercase_hex( SHA-256( utf8(space) || 0x0A || canonical(v) ) )     ; v a value (§4)\nHb(space, b) = lowercase_hex( SHA-256( utf8(space) || 0x0A || b ) )                ; b raw octets\n```\n`space` is an exact ASCII tag, none containing `0x0A`: `\"rapp/1:particle\"`, `\"rapp/1:wave\"`, `\"rapp/1:egg\"`,\n`\"rapp/1:egg-manifest\"`, `\"rapp/1:rappid\"`, `\"rapp/1:grail\"`, `\"rapp/1:seal\"`,\n`\"rapp/1:sealed-aad\"`, `\"rapp/1:sealed-key-request\"`. A tag is used by either `H` or `Hb`, never\nboth. Output is always exactly 64 lowercase hex, **never truncated or uppercased**. Two values\nare treated as the same object iff their same-space hashes are equal; SHA-256 collision resistance\n[FIPS 180-4] is a security assumption of this standard (§14). A `name/X.Y` label is never identity — only\na hash is. A bare 64-hex is meaningful **only** within its space; an implementation **MUST NOT** dereference\na hash from one space as an object of another, and content-addressed stores **MUST** key by `(space, hash)`.\n\n## 6. Identity — the rappid (L2)\n### 6.1 Grammar (case-sensitive, [RFC 7405])\n```abnf\nrappid    = %s\"rappid:@\" owner \"/\" slug \":\" hash\nowner     = lclabel                       ; the lowercase GitHub login (1-39 chars)\nslug      = lclabel                        ; 1-100 chars\nlclabel   = lcalnum *( [\"-\"] lcalnum )     ; no leading/trailing/adjacent hyphen\nlcalnum   = LCALPHA / DIGIT\nLCALPHA   = %x61-7A                         ; a-z\nhash      = 64HEXDIGLC\nHEXDIGLC  = DIGIT / %x61-66                 ; 0-9 a-f\n```\n`owner` **MUST** be the lowercase form of the GitHub login (logins are case-insensitive; display casing is\npresentation, never identity). Lengths are normative: `owner` 1–39, `slug` 1–100; an implementation\n**MUST** refuse longer. This self-locating form is the **only** conformant rappid; `rappid:<slug>:<hash>`,\n`rappid:v2:…`, bare UUIDs, `moment:`/name-hash derivations are legacy and **MUST** be migrated out\n(Art. III), not read forever.\n\n### 6.1.1 stream_id and kind grammar\n```abnf\nstream_id   = memory-stream / body-stream / swarm-stream\nmemory-stream = rappid \":\" instance      ; one organism instance's memory\nbody-stream   = rappid                    ; an organism's biography\nswarm-stream  = %s\"net:\" lclabel          ; a planetary-wire stream\ninstance      = lclabel                   ; 1-64 chars\nkind          = lclabel \".\" lclabel       ; each label 1-64 chars\n```\nA `kind` string carries **no intrinsic family**; the §13 registry binds each registered `kind` to exactly\none family. Membership is tested by exact-match against the registry — never prefix inference, never wildcards.\n\n### 6.2 Minting (mint-once)\nThe 64-hex tail is minted **exactly once** per identity, then immutable:\n- **keyless:** `tail = Hb(\"rapp/1:rappid\", uuid4_octets)`, where `uuid4_octets` is the 16-octet binary\n  UUIDv4 [RFC 9562] §5.4 (field/byte order per §4 of that RFC).\n- **keyed:** `tail = Hb(\"rapp/1:rappid\", SPKI_DER)`, the DER `SubjectPublicKeyInfo` [RFC 5280] of the master key.\n\nA producer **MUST NOT** derive the tail from owner/slug or any name (`sha256(\"owner/slug\")` is prohibited —\ndrift ID-01/C3). On read of an existing `rappid.json` an implementation **MUST** reuse the stored tail\n(canonicalize-on-read) and **MUST NOT** re-mint — with exactly one mechanism: the owner-authorized\n**re-anchor** (§6.3), which mints a fresh 64-hex tail once per authorization and records the superseded id\nin `_migrated_from`. Re-anchor is lawful in exactly three cases: (a) a 128→256-bit provisional upgrade\n(§6.3); (b) §10 key rotation or compromise; (c) migrating a pre-rev-3 keyed tail minted with the un-tagged\n`sha256(SPKI)` formula (which fails §10 discovery and **MUST** be re-anchored like a provisional identity).\n\n### 6.3 Canonicalization on read; provisional identifiers\n`canonicalize_rappid(s)` restructures any legacy form into §6.1, **preserving the existing hash** (never\ninventing one). A restructured identifier whose tail is not exactly 64 lowercase hex (e.g. a legacy 32-hex\ntail) is **provisional**: it exists only inside the reading process and **MUST NOT** appear in any emitted\nframe, `stream_id`, egg, or registry entry. The one-time owner-authorized 128→256-bit re-anchor mints a\nfresh 64-hex, records the old id in `_migrated_from`, and is the only way a provisional identity becomes\nusable. A provisional identifier found in a stored artifact is a drift finding (Art. III). Re-anchor is the\nsingle re-mint mechanism (§6.2), lawful only in the enumerated cases: provisional 128→256-bit upgrade,\n§10 key rotation/compromise, and pre-rev-3 un-tagged-`sha256(SPKI)` keyed-tail migration.\n\n**A re-anchor is valid only with a verifiable authorization** — a self-asserted `_migrated_from` is\ninsufficient (it would let anyone hijack an identity). A re-anchor **MUST** be recorded as an owner-signed\n§13.3 **re-anchor record** `{old_rappid, new_rappid, case, utc, sig, old_key_sig?}`; a consumer **MUST**\nrefuse a `new_rappid` (and treat `_migrated_from` as drift) unless that record is present and:\n- `case:\"rotation\"` (uncompromised): `old_key_sig` (a §10 JWS by the **old** key) verifies — proof of\n  continuity;\n- `case:\"compromise\"`: `old_key_sig` is waived but a §10 **tombstone** for `old_rappid` is registered in the\n  same append;\n- `case:\"tag-migrate\"` (pre-rev-3 keyed tail): the verifier checks `lowercase_hex(SHA-256(SPKI_DER_old))` ==\n  the old tail;\n- `case:\"upgrade\"` (provisional 128→256): the old provisional id resolved to this owner at read time.\nEach mints one fresh tail. The **estate_owner's own** re-anchor record **MUST** be signed by the outgoing\n`estate_owner` key (§13.2); root-key compromise is recovered only by out-of-band re-anchoring (§13.1).\n\n## 7. The Frame (L4)\n### 7.1 The envelope — exactly eleven keys\n```json\n{\n  \"spec\":         \"rapp/1\",\n  \"kind\":         \"<klabel.klabel>\",\n  \"stream_id\":    \"<stream_id>\",\n  \"seq\":          <uint53>,\n  \"utc\":          \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"payload\":      { },\n  \"payload_hash\": \"<64hex>\",\n  \"frame_hash\":   \"<64hex>\",\n  \"prev\":         \"<64hex|null>\",\n  \"prev_wave\":    \"<64hex|null>\",\n  \"sig\":          \"<jws|null>\"\n}\n```\n- **`spec` MUST be the exact string `\"rapp/1\"`** in every frame. `rapp-frame/2.0`/`2.1` are legacy tokens\n  and **MUST NOT** be emitted. Any revision changing the key set, any field's grammar, or either hash rule\n  **MUST** change this token and land an Art. III total migration; revisions adding only new registered\n  `kind`s/registry entries keep the token (Fed. Const. Art. II).\n- **Exactly these eleven keys, always present**, none missing, none extra. A field that does not apply is\n  present with value `null` (`prev`/`prev_wave` at genesis and on non-swarm streams; `sig` when unsigned) — never omitted,\n  because [RFC 8785] hashes `null` and an absent key differently. Extra or missing keys are refused (§7.5).\n- **`payload` MUST be a JSON object** (possibly empty `{}`); never `null`, array, string, number, or bool.\n- `seq` is `uint53` (§7.4). A producer **MUST NOT** emit a frame whose canonical form exceeds 1 MiB or\n  nesting depth 64 (§4).\n\n### 7.2 Kind families (one envelope, registry-bound families)\n| family | example registered kinds | `stream_id` form | logs |\n|---|---|---|---|\n| `memory` | `memory.chat-turn`, `memory.tool-call`, `memory.save`, `memory.reconstructed` | memory-stream | one organism's life |\n| `swarm`  | `swarm.guidance`, `swarm.echo`, `swarm.telemetry`, `swarm.reconstructed` | swarm-stream | the planetary wire |\n| `body`   | `body.pulse`, `body.twin-pulse`, `body.reconstructed`, `body.re-genesis` | body-stream | an organism's biography |\nEach family also has a `*.re-genesis` kind (`memory.re-genesis`, `swarm.re-genesis`, `body.re-genesis`)\nused only by §12.1. The family is **not** the kind's prefix — it is the §13 registry binding (so\n`body.twin-pulse` is family `body`). Adding a family or event is a new registered `kind` on the **same** envelope (Art. IV), never a\nnew frame type. A frame's `kind` family **MUST** be compatible with its `stream_id` form (table column 3).\n\n### 7.3 Particle and wave (the unification)\nA frame carries **both** of its domain-separated addresses; a reader collapses it to whichever it needs.\nComputed in order:\n- **particle** — `payload_hash = H(\"rapp/1:particle\", payload)`. The **worldline identity and chain link**.\n- **wave** — `frame_hash = H(\"rapp/1:wave\", frame \\ {frame_hash, sig})` — the frame with **exactly** the\n  `frame_hash` and `sig` keys removed, all nine remaining keys (including `payload_hash`) present.\nBecause `payload_hash` is in the wave pre-image, `frame_hash` attests the particle; because only\n`frame_hash` (cannot hash itself) and `sig` (signs the result) are removed, the pre-image is unambiguous\nand non-circular. Both hashes are always present (never `null`).\n\n### 7.4 Chaining, time, and merge order\n- **`utc`** **MUST** be exactly the 24-byte form `YYYY-MM-DDTHH:MM:SS.mmmZ` — uppercase `T`/`Z`, exactly\n  three fractional digits, no numeric offset; the seconds field **MUST NOT** be `60` (a leap second clamps\n  to `59.999`). All `utc` comparisons are **bytewise** over this fixed form (identical to chronological order).\n- **Worldline chain (particle):** the **genesis** frame has `seq`=0 and `prev`=null; every later frame has\n  `seq` = predecessor's `seq`+1 (contiguous) and `prev` = predecessor's `payload_hash`. `seq` is `uint53`\n  (JSON integer, 0 ≤ seq ≤ 2^53−1, no fraction/exponent; a stream nearing 2^53−1 converges by re-genesis).\n- **Wire chain (wave):** `prev_wave` **MUST** be non-null **iff** `stream_id` is a swarm-stream **and**\n  `seq` > 0, in which case it equals the predecessor's `frame_hash`; in every other frame (all memory/body\n  streams, every genesis) it **MUST** be `null`. (Presence is a function of stream family, not transport.)\n- A frame is **immutable**: a new state is a new frame at a new hash; the head pointer (§7.6) re-points.\n- **Cross-stream merge order** (Dream-Catcher) is the total order: ascending `utc` (bytewise), ties broken\n  by ascending `frame_hash` (bytewise); no further ties are possible (§5).\n\n### 7.5 Verification (the complete consumer checklist)\nBefore accepting a frame, a consumer **MUST**, in order, **refuse** (never repair/reparent) on any failure:\n1. **Shape & types:** exactly the eleven §7.1 keys; `spec`==`\"rapp/1\"`; `kind` a string matching §6.1.1\n   ABNF and registered (§13); `stream_id` a string matching §6.1.1; `seq` a `uint53`; `utc` matching the\n   §7.4 fixed form **and** a calendar-valid [RFC 3339] `date-time` (so `2026-13-45T25:61:61.999Z` is\n   refused); `payload` a JSON object; `payload_hash`/`frame_hash` `64HEXDIGLC`; `prev`/`prev_wave` each\n   `null` or `64HEXDIGLC`; `sig` `null` or a §10 JWS string.\n1a. **Stream binding:** `frame.stream_id` **MUST** byte-equal the identifier of the stream being extended\n   or read (its declared `stream_id` at the head pointer / repo path of record). A genesis frame is\n   accepted only for the stream it names. (Defeats cross-stream genesis/segment replay — §14.)\n2. **Particle:** `payload_hash` == `H(\"rapp/1:particle\", payload)`.\n3. **Wave:** `frame_hash` == `H(\"rapp/1:wave\", frame \\ {frame_hash, sig})`.\n4. **Chain:** `seq`==head.`seq`+1 and `prev`==head.`payload_hash` (or `seq`==0 ∧ `prev`==null at genesis);\n   `utc` ≥ head.`utc` (bytewise).\n5. **Wire:** if `stream_id` is a swarm-stream and `seq`>0, `prev_wave`==head.`frame_hash`; else\n   `prev_wave`==null.\n6. **Signature:** if `sig`≠null, verify per §10 (present-but-invalid is refusal); a swarm-stream frame with\n   `sig`==null is refused (§8/§10).\nSteps 1–5 are **time-independent** (kind lookups only append, §13), so a frame passing them passes forever;\nstep 6 alone may flip pass→fail when a §10 tombstone with `revoked_utc` ≤ the frame's `utc` is later\nregistered — the one time-dependent check.\n\n### 7.6 Heads and forks\nA stream's **head** is the frame with the greatest verified `seq` descending from its registered genesis\n(§13). A consumer **MUST** persist, per stream, the highest `(seq, frame_hash)` it verified and **MUST**\nrefuse any presented head with lower `seq`, or a different `frame_hash` at an already-verified `seq` (no\nrollback, no silent reorg). Two distinct valid frames with equal `stream_id`, `seq`, and `prev` are a\n**fork**: a consumer **MUST** refuse both branches past the fork point and surface a drift finding; only\nthe owner resolves a fork (Art. X), by re-genesis (§12.1) if needed.\n\n**Exception (re-genesis head reset).** The no-rollback rule above refuses a lower-`seq` head — but a\nlegitimate §12.1 re-genesis presents a new genesis at `seq`=0. When (and only when) the §13 registry maps a\n`stream_id` to a new genesis `frame_hash` (§12.1 step 3), a consumer **MUST** verify that registered\ngenesis (§7.5) and then **reset** its persisted head for that `stream_id` to it. Only a registry-published\ngenesis authorizes a reset; any other lower-`seq` head remains a refused rollback.\n\n## 8. The Wire (L3)\nAll interaction rides one of exactly two forms:\n1. **Synchronous — `POST /chat`, `application/json` both ways.** Request: `user_input` (string, REQUIRED);\n   `session_id` (string, OPTIONAL — omit to start a session); `idempotency_key` (string, OPTIONAL — a repeat\n   with the same key returns the original response, not a new turn or duplicate session; scoped to\n   `session_id` when present, else to the key alone so session-creation is also de-duplicated); unrecognized members **MUST** be\n   ignored, never refused. Success: HTTP 200 with **exactly** `{response:string, agent_logs:[string],\n   session_id:string}` (no extra members). An unknown `session_id`, a refusal, or a malformed request\n   **MUST** be HTTP 422, `{error:{code:string, step:string|null}}` where `code` is a §13-registered error\n   code (e.g. `\"unknown-session\"`) and `step` is the failing §7.5 step as a string — one of\n   `\"1\",\"1a\",\"2\",\"3\",\"4\",\"5\",\"6\"` — or `null`. No other shape is conformant. New capability is a new agent\n   behind `/chat`, never a sibling REST route.\n2. **Asynchronous — an append-only frame (§7) published to a stream** (a repo path, an `events/` log). A\n   frame on a **swarm-stream MUST** carry `sig`≠null (§10); memory/body-stream frames **MAY** be unsigned.\n   Any *history* is safe to read given a trusted head (§14); the hash chain (§5) makes tampering\n   detectable.\n\n## 9. The Egg (L5) — the single egg spec of record\nAn **egg** is a cartridge packing a unit of the estate. **RAPP §9 is the one egg spec of record** (it\nsubsumes and retires `EGG_FAMILY.md`, `NEIGHBORHOOD_EGG_SPEC.md`, `ESTATE_SPEC.md`, `rappterbook/EGG_SPEC.md`,\nand the rest — drift C7). No other document may re-specify eggs; they cite this section.\n\n### 9.1 Container, manifest, and egg address\nAn egg is either a JSON object (`invite`/`session` variants) or a ZIP whose root is `manifest.json` (tree\nvariants). The manifest is a §4 value with exactly these members:\n```json\n{ \"schema\": \"rapp/1-egg\", \"variant\": \"<variant>\", \"rappid\": \"<§6.1 rappid>\",\n  \"created_utc\": \"<§7.4 utc>\", \"contents\": [ {\"path\":\"<rel>\",\"hash\":\"<64hex>\"}, … ], \"payload\": { },\n  \"sig\": \"<jws|null>\" }\n```\n- `contents` **MUST** list every packed file **except `manifest.json` itself**, exactly once each, with\n  `hash = Hb(\"rapp/1:egg\", file_octets)` (§5) over the raw stored octets. `contents` is **always present**;\n  for JSON (pointer/session) variants it **MUST** be exactly `[]`.\n- `path` **MUST** be a relative POSIX path: `/`-separated NFC UTF-8 segments, no `.`/`..` segment, no\n  leading `/`, no backslash, no Windows drive-qualified first segment (`ALPHA \":\"`), no duplicate `path`\n  in one manifest. A segment **MUST NOT** end in a period/space, contain `:`, contain a C0 control, or have\n  a case-insensitive basename equal to `CON`, `PRN`, `AUX`, `NUL`, `COM1`–`COM9`, or `LPT1`–`LPT9`.\n  `contents` **MUST** be sorted ascending\n  by the UTF-8 bytes of `path`.\n- `payload` is a §4 object (variant-specific). `sig` is a §10 JWS over `canonical(manifest \\ {sig})`, or\n  `null`. For the `invite` variant `sig` is REQUIRED and **MUST** verify with `kid` in the §13.2 estate-owner\n  succession (invites are estate-issued; a `sig` by any other key, even a validly registered one, is\n  refused — otherwise an attacker mints a fresh rappid and forges invites). For other variants a non-null\n  `sig` **MUST** verify per §10 with `kid` == a keyed rappid the consumer resolves via §13; a consumer\n  presented a signed egg **MUST** verify it.\n- **The egg's one §5 address is** `egg_hash = H(\"rapp/1:egg-manifest\", manifest \\ {sig})` — the manifest with\n  exactly the `sig` key removed (mirroring §7.3's wave rule: `sig` authenticates the egg, `egg_hash` names\n  it, so re-signing never changes identity). Stores key eggs by `(\"rapp/1:egg-manifest\", egg_hash)`.\n  (`\"rapp/1:egg\"` addresses file octets; `\"rapp/1:egg-manifest\"` addresses the egg as a whole.)\n- **Container determinism.** A ZIP variant **MUST** use compression method `stored` (0) for **every** entry\n  — no deflate in any variant (deflate is library-dependent, so it cannot be byte-reproducible; transport\n  compression, if any, wraps the egg and is not the egg). Entries appear in `contents` order with\n  `manifest.json` first; the `manifest.json` entry's octets **MUST** be exactly `canonical(manifest)`; all\n  timestamps `1980-01-01 00:00:00`; no extra fields; UTF-8 filename flag set; `contents[].hash` is over the\n  file octets (identical to the archive octets under method 0). A JSON-variant egg's serialized form\n  **MUST** be exactly `canonical(manifest)`. Two conformant packers of the **same manifest value** thus emit\n  byte-identical eggs.\n\n### 9.2 Variants (the ratified set — closes EGG-01)\n| variant | container | packs | required members |\n|---|---|---|---|\n| `organism` | ZIP | a full brainstem instance | contents (sorted) MUST include `rappid.json`, `soul.md`; MAY include `agents/*`, `organs/*`, memory files |\n| `rapplication` | ZIP | one rapp | contents MUST include `rappid.json` and exactly one `agent.py` at the root (the agent of record); MAY include one `ui.html` and files under `state/` |\n| `session` | JSON | one runtime + transcript | `payload` = `{runtime:<string>, transcript:[<object>]}`; contents `[]` |\n| `invite` | JSON | a QR-sized pointer (**no packed files**) | `payload` = `{target_rappid:<rappid>, target_url:<string>, target_kind:(\"neighborhood\" / \"estate\")}`; contents `[]`; `sig` REQUIRED |\n| `neighborhood` | ZIP | several organisms meant to live together | `payload` = `{members:[<rappid>,…]}`; contents = one sub-egg per member, named `<owner>--<slug>.egg` at the root, matched by the sub-egg manifest's `rappid` == the `payload.members[]` entry |\n| `estate` | ZIP | several neighborhoods | `payload` = `{neighborhoods:[<rappid>,…]}`; contents = one sub-egg per neighborhood, named `<owner>--<slug>.egg` at root, matched by sub-egg `rappid` |\n| `sealed` | ZIP | publicly mirrorable ciphertext with scoped key release | contents MUST be exactly `ciphertext.bin`; payload is the closed `rapp-sealed-artifact/1` profile in §9.2.1; `sig` REQUIRED |\n\nThe QR-sized invite that caused EGG-01 is the **`invite`** variant: a signed pointer object, not a\nmember-packing `neighborhood` egg. The banned legacy stamps (`brainstem-egg/2.3-neighborhood`,\n`neighborhood-egg/1.0`) migrate to `{schema:\"rapp/1-egg\", variant:\"invite\" / \"neighborhood\"}` (Art. III).\n\n### 9.2.1 Sealed artifact profile\n\nThe `sealed` variant lets any unauthenticated mirror, including a commit-pinned\n`raw.githubusercontent.com` URL, distribute an encrypted artifact globally without distributing its\ndecryption key.\n\nThe public bytes are **ciphertext, not access control**. Bytecode or obfuscation alone provides no\nconfidentiality. A conformant producer **MUST** use a random 256-bit data-encryption key (DEK) per artifact,\n**MUST NOT** embed that DEK or a shared master key in the egg/client/URL, and **MUST NOT** place a password\nin a URL. A password, passkey, device assertion, or account credential may authenticate to the key service;\nit is not the artifact encryption key.\n\nThe ZIP contents are exactly one file:\n\n```text\nciphertext.bin = AES-256-GCM ciphertext || 16-byte authentication tag\n```\n\nThe manifest `payload` has exactly:\n\n```json\n{\n  \"schema\": \"rapp-sealed-artifact/1\",\n  \"cipher\": \"A256GCM\",\n  \"nonce\": \"<12 bytes, unpadded base64url>\",\n  \"plaintext_commitment\": \"<64hex>\",\n  \"plaintext_bytes\": 1234,\n  \"media_type\": \"application/wasm\",\n  \"key_id\": \"<64hex>\",\n  \"key_service_rappid\": \"rappid:@owner/key-service:64hex\",\n  \"key_service_url\": \"https://keys.example.com/chat\",\n  \"access\": \"scoped-key-release\",\n  \"aad_hash\": \"<64hex>\"\n}\n```\n\n`plaintext_commitment` is a keyed commitment that cannot be tested without the DEK:\n\n```text\nprk = HMAC-SHA-256(32 zero octets, DEK)\ncommitment_key = HMAC-SHA-256(prk, utf8(\"rapp/1:sealed-commitment\") || 0x01)\nplaintext_commitment = lowercase_hex(HMAC-SHA-256(commitment_key, plaintext_octets))\n```\n\nThis is the [RFC 5869] HKDF-Extract/HKDF-Expand construction with an empty salt, one 32-byte output block,\nand the exact info string `rapp/1:sealed-commitment`. The commitment is public but does not permit an\noffline dictionary attack without the random 256-bit DEK.\n\nThe exact authenticated-data descriptor is:\n\n```json\n{\n  \"schema\": \"rapp-sealed-artifact/1\",\n  \"artifact_rappid\": \"<manifest.rappid>\",\n  \"created_utc\": \"<manifest.created_utc>\",\n  \"key_id\": \"<payload.key_id>\",\n  \"plaintext_commitment\": \"<payload.plaintext_commitment>\",\n  \"plaintext_bytes\": 1234,\n  \"media_type\": \"<payload.media_type>\"\n}\n```\n\n`aad_hash = H(\"rapp/1:sealed-aad\", descriptor)`, and `canonical(descriptor)` is supplied as AES-GCM\nadditional authenticated data. `nonce` decodes to exactly 12 bytes. `plaintext_bytes` is an integer from\nzero through `2^30` (1 GiB), a RAPP safety ceiling below both the [NIST SP 800-38D] per-invocation limit\nand the deterministic non-ZIP64 container boundary.\n`ciphertext.bin` length is exactly `plaintext_bytes + 16`. The sealed egg's manifest signature is REQUIRED\nand verifies per §10 with `kid` exactly equal to `manifest.rappid`. A sealed artifact therefore uses a\nkeyed §6.2 rappid controlled by its authorized publisher; another valid registry key cannot sign on its\nbehalf.\n\n`key_service_rappid` identifies the RAPP organism authorizing key release. `key_service_url` is its absolute\nHTTPS §8 `POST /chat` URL and **MUST** end in `/chat`. The URL is location, not authority: the service\nresponse is accepted only when its signatures and identifiers bind to `key_service_rappid`.\n\nThe caller sends the following canonical JSON object as the `user_input` string:\n\n```json\n{\n  \"schema\": \"rapp-sealed-key-request/1\",\n  \"egg_hash\": \"<64hex>\",\n  \"key_id\": \"<64hex>\",\n  \"recipient_rappid\": \"rappid:@owner/device:64hex\",\n  \"recipient_spki_der_b64\": \"<standard base64>\",\n  \"request_nonce\": \"<64hex>\",\n  \"expires_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"sig\": \"<recipient detached JWS>\"\n}\n```\n\n`sig` is over `canonical(request \\ {sig})` and verifies under `recipient_rappid`; `egg_hash` is the §9.1\nsealed egg address. The key service verifies entitlement, exact `(egg_hash,key_id)`, request expiry,\nrecipient key binding, and nonce non-reuse.\n\nThe §8 `response` string is canonical JSON:\n\n```json\n{\n  \"schema\": \"rapp-sealed-key-release/1\",\n  \"egg_hash\": \"<request.egg_hash>\",\n  \"key_id\": \"<request.key_id>\",\n  \"recipient_rappid\": \"<request.recipient_rappid>\",\n  \"request_hash\": \"<H('rapp/1:sealed-key-request', request without sig)>\",\n  \"wrap_alg\": \"ECDH-ES+A256KW\",\n  \"wrapped_key_jwe\": \"<JWE Compact Serialization>\",\n  \"issued_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"expires_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"service_sig\": \"<key-service detached JWS>\"\n}\n```\n\n`service_sig` is over `canonical(release \\ {service_sig})` and verifies under `key_service_rappid`.\n`wrapped_key_jwe` uses [RFC 7516] with `alg:\"ECDH-ES+A256KW\"` and `enc:\"A256GCM\"` for the declared\nrecipient SPKI. The service **MUST NOT** return a global raw DEK. Authorization, expiry, device scope, and\nkey rotation are service policy recorded in signed frames, not fields that alter the sealed egg's content\naddress.\n\nA mirror URL **SHOULD** be immutable (for GitHub Raw, pin a commit SHA rather than a moving branch). URL\nsecrecy is never assumed: integrity comes from the egg address and signature, confidentiality from\nAES-GCM, and use authorization from scoped key release.\n\nRevocation prevents future key release. It cannot erase ciphertext or plaintext already downloaded and\ndecrypted by an authorized recipient. A conformant product **MUST** state this limit plainly. It also\n**MUST NOT** claim that encrypted bytecode cannot be inspected after decryption; legal/license controls and\nbounded server authority remain separate from cryptographic confidentiality.\n\n### 9.3 Conformance\n- **Producer** **MUST** emit only `schema:\"rapp/1-egg\"` with a variant from §9.2, a §6.1 rappid, and, for\n  ZIP variants, a `contents` list whose every hash verifies. It **MUST NOT** emit any legacy egg schema.\n- **Consumer** **MUST** read every §9.2 variant, dispatch on `variant`, verify **integrity then viability** —\n  (0) the manifest is a §4 value satisfying **every §9.1 rule** — exact member set, `path` grammar (no `..`,\n  no leading `/`, no backslash), no duplicate paths, sort order, and for ZIP variants the archive entry set\n  equals `contents` ∪ {`manifest.json`} in the §9.1 deterministic order (this is the zip-slip defense; an\n  unenforced path grammar defends nothing); (1) every `contents[].hash` recomputes per §5; (2) the variant's\n  §9.2 structural requirements hold — and refuse whole on any failure; it **MUST NOT** reparent on transport.\n\n### 9.4 Instantiation — instance identity and `grown_from` lineage (rev-6; closes the hatch seam)\nAn egg names an **artifact**; a hatch creates an **instance**. Rev-5 specified packing and reading but\nleft instantiation identity unwritten, so every implementation had to invent its own — this section is\nthat missing word.\n\n- The `rappid` in a packed egg's `rappid.json` (§9.2) names the **artifact**. Every hatch of the same\n  egg reads the **same** artifact identity (§6.2 canonicalize-on-read); re-minting it on hatch is\n  prohibited (§6.2).\n- A consumer that instantiates an egg into a live installation **MUST** mint a **fresh §6.2 identity\n  for the instance**, exactly once, at first boot — from entropy, never derived from the artifact\n  identity, host name, or path. Two instances of one egg share the artifact identity and **MUST NOT**\n  share an instance identity.\n- The instance's identity document **SHOULD** record **`grown_from`**: the §9.1 egg address\n  (64 lowercase hex) of the egg it was instantiated from. `grown_from` is written at mint time and is\n  **immutable** thereafter; it is `null` when the source is unknown; a producer **MUST NOT** fabricate\n  it — lineage is a fact about a birth, never a claim to invent. An instance that cannot say where it\n  came from says `null`.\n- `grown_from` is **lineage, not inheritance**: it confers no authority, no trust, and no §10 key\n  material. A reader **MUST** treat it as an unverified assertion unless the named egg is available and\n  its address recomputes per §9.1/§5.\n- A newly authored artifact produced from one or more existing RAPP objects **MAY** record\n  `crossed_from` in its packaged `rappid.json`. The value is a sorted, duplicate-free array of typed\n  addresses `{space, hash}`, where `space` is `\"rapp/1:particle\"` or `\"rapp/1:egg-manifest\"` and `hash`\n  is 64 lowercase hex. One parent denotes an **offspring**; two or more denote a **cross**. The new\n  artifact **MUST** mint its own §6.2 rappid; parent artifacts and identities remain unchanged.\n  `crossed_from` is lineage only: it transfers no signature authority, ownership, entitlement, secret,\n  or trust. A verifier treats each parent as unverified until the addressed object is available and\n  recomputes in its declared space.\n\n## 10. Trust and signatures (L2)\n`sig` is OPTIONAL on memory/body streams and REQUIRED on swarm streams (§8). Chain integrity comes from the\nhash links (§5), not signatures. When present, `sig` **MUST** be JWS Compact Serialization with **detached,\nunencoded payload** ([RFC 7515] App. F + [RFC 7797]):\n- protected header members are **exactly** `alg` (`\"EdDSA\"` or `\"ES256\"`), `b64` (`false`), `crit`\n  (`[\"b64\"]`), `kid` (signer's §6.1 rappid), no others; the header octets **MUST** be `canonical(header)`\n  (§4 — JCS orders them `alg`, `b64`, `crit`, `kid`, no whitespace);\n- the `sig` string is the detached compact form `BASE64URL(canonical(header)) || \"..\" || BASE64URL(signature)`;\n- JWS signing input = `BASE64URL(canonical(header)) || \".\" || canonical(frame \\ {sig})`;\n- `alg`: `EdDSA`/Ed25519 [RFC 8037] or `ES256` [RFC 7518]; ES256 signers **SHOULD** sign deterministically\n  [RFC 6979] (Ed25519 is deterministic by construction) so signed frame files stay byte-reproducible.\n\n**Key discovery.** A keyed rappid's tail is one-way (`Hb(\"rapp/1:rappid\",SPKI)`). A verifier resolves the\nsigner's SPKI (DER) **from the §13 registry** entry (`rappid` → `spki_der_b64`); the door-of-record\n`rappid.json` is the publication venue the registry entry is generated from, not itself a verification\nsource. The verifier **MUST** check `Hb(\"rapp/1:rappid\", SPKI_DER)` == the rappid's tail and refuse on\nmismatch or registry absence.\n\n**Key lifecycle.** Rotation is an identity re-anchor (§6.3, case `rotation`) with new `tail =\nHb(\"rapp/1:rappid\", newSPKI)` and a §13.3 re-anchor record. A re-anchor **deprecates** the superseded\nrappid's §13 `spki` entry: a verifier **MUST** refuse a `sig` whose `kid` is a superseded rappid on any\nframe with `utc` ≥ the re-anchor record's `utc` (rotation gives forward security; earlier frames verify as\nbefore). Compromise is declared by an owner-signed **tombstone** in the §13 registry `{rappid, revoked_utc}`; a verifier **MUST** refuse any `sig` by a\ntombstoned key on a frame whose `utc` ≥ `revoked_utc`, checking tombstones at verification time (§7.5 step\n6). \"Owner-signed\" means a `sig` verifying with `kid` == the registry's designated `estate_owner` rappid\n(§13). A consumer **MUST NOT** infer authorship from an unsigned frame (keyless rappids assert location,\nnot authorship).\n\n## 11. Conformance classes\n- **Producer:** emits only §4 JCS/I-JSON bytes, §5 domain-separated full-SHA-256 addresses, §6 rappids\n  minted per §6.2, §7.1 eleven-key frames, §9 `rapp/1-egg` variants — and **no legacy form**.\n- **Consumer:** runs the full §7.5 checklist (incl. 1a binding), §9.3 egg verification, §10 signature +\n  key-discovery + tombstone checks, canonicalizes legacy ids on read (§6.3), refuses on any failure, never\n  repairs/reparents/rolls back (§7.6).\n- **Router/Mirror:** invents no endpoints (§8), declares subordination to\n  `kody-w/rapp-1` for protocol semantics, and serves only\n  provenance-stamped hash-matching mirrors. Estate-specific product scope is\n  resolved separately through that estate's signed registry and master plan.\n\n### 11.1 Immutable Grail kernel conformance\nAn estate declares a Grail kernel through the exact §13.3 `grail-kernel` entry. Its `release_scope`\nselects the release family to which the pin applies; a registry **MUST** contain at most one\n`grail-kernel` entry for any release scope. Its entry-level `sig`\n**MUST** verify under `declared_by`, which **MUST** be the estate owner in effect at `activated_utc`\n(§13.2); `activated_utc` **MUST NOT** be more than 300 seconds after the verifier's first-seen time for\nthat entry. The pin activates locally when a consumer first accepts an authenticated, non-rollback\nregistry containing that valid declaration. Until then it is structural evidence only. The Grail is\nidentified by `grail_id`, never by a mutable branch, tag, repository name, or product label. Once\nactivated, the pin is a permanent compatibility anchor, not a moving release channel:\n\n1. Every conformance evaluation **MUST** receive `release_scope` from an authenticated owner-controlled\n   release policy, never from candidate bytes or candidate-controlled configuration, then resolve its\n   one `grail_id` exclusively from the activated, persisted §13.3 binding. If the policy repeats\n   `grail_id`, that value is only a consistency assertion and **MUST** byte-equal the registry result; it\n   cannot select or rebind the pin. Every ring and release/deployment stage, including development,\n   qualification, Preprod, installation, and production verification, **MUST** compare the candidate's\n   Grail path to that exact binding, SHA-256, and byte length.\n2. A missing, changed, substituted, or unmeasured Grail byte is `kernel-drift` and **MUST** fail closed.\n   Approval, urgency, compatibility claims, and semantic equivalence cannot waive byte inequality.\n3. A pipeline **MUST NOT** silently restore the pinned file after testing a different file. The exact\n   release-shaped artifact containing the immutable Grail bytes **MUST** itself pass the release gates.\n4. Every gate **MUST** resolve every archive, container, wrapper, environment override, symlink, and\n   filesystem indirection to one regular runtime entry-point file under the immutable release root;\n   refuse links and ambiguous alternatives; verify its bytes; and bind the release digest, resolved\n   entry-point path, `release_scope`, `grail_id`, raw SHA-256, and byte length into its evidence.\n5. Every gate that executes the kernel **MUST** bind verification atomically to execution from a sealed\n   immutable object or snapshot. An already-open descriptor is sufficient only when its backing bytes\n   are under platform-enforced write exclusion for the entire verification-through-consumption interval\n   and the interpreter/loader consumes that exact descriptor without reopening a pathname. An immutable\n   content-addressed release root is sufficient only when no concurrent principal can modify it. A\n   hash-then-path-launch without one of those guarantees is nonconformant. At least one execution gate for\n   every supported production platform **MUST** perform this proof before release approval. Merely\n   carrying an unused matching file is insufficient. A stored transpiled, bundled, generated, or patched\n   derivative is different kernel bytes and requires a new `grail_id`; ordinary interpreter/JIT\n   compilation directly from the pinned bytes is permitted when no alternate stored kernel is selected.\n6. New implementation behavior **MUST** live outside the Grail kernel and **MUST NOT** alter any\n   RAPP-visible canonical form or wire semantic except through the registration and evolution rules of\n   §§7, 9, 12, and 13.\n7. If required behavior cannot be expressed outside the pin, the implementation **MUST** report an\n   incompatibility. It **MUST NOT** edit the Grail and continue under the same identity.\n8. Different kernel bytes produce a different `grail_id` and therefore are a different Grail. A new\n   `grail-kernel` entry may coexist and may name the old `grail_id` as `predecessor`, but it **MUST NOT**\n   overwrite, retag, alias, or redefine the prior Grail. A successor uses a new `release_scope`; an\n   existing scope is never rebound. A non-null `predecessor` **MUST** name an earlier accepted\n   `grail-kernel` entry and **MUST NOT** form a cycle. A registry **MUST** contain at most one\n   `grail-kernel` entry for each `grail_id`.\n9. On first activation a consumer **MUST** persist the full canonical `grail-kernel` entry. Every later\n   accepted registry **MUST** retain that entry byte-for-byte. Removal, mutation, or a second entry for\n   the same `grail_id` is a permanent `kernel-drift` refusal even when `registry_seq` increased.\n\nThis rule governs release topology rather than the §8 wire shape, so it does not add a frame member,\nendpoint, compatibility shim, or alternate `rapp/1` encoding.\n\n### 11.2 Operational conformance profiles\nRAPP/1 defines the substrate. Two subordinate operational profiles define how a production AI changes\nwithout mutating that substrate or the serving system underneath users:\n\n- **RAPP CI/CD** (`rapp-cicd/1`) — `protocols/rapp-cicd/1/SPEC.md`; immutable release capsules,\n  ordered qualification evidence, exact-candidate promotion, Preprod, and rollback/restore proof.\n- **RAPP Deploy** (`rapp-deploy/1`) — `protocols/rapp-deploy/1/SPEC.md`; isolated serving/candidate\n  lineages, cellular rollout, progressive exposure, expiring AI-health evidence, quarantine, and exact\n  rollback.\n\nThe profiles are RAPP/1 applications, not alternate wire versions:\n\n1. Their payloads **MUST** be §4 canonical I-JSON and are identified by\n   `H(\"rapp/1:particle\", payload)`.\n2. Authoritative profile payloads **MUST** travel in signed RAPP/1 frames using a registered compatible\n   kind. Local unsigned files are drafts, fixtures, or caches and cannot authorize promotion or traffic.\n3. They **MUST NOT** add a transport endpoint beside §8 `POST /chat`, redefine any RAPP/1 primitive, or\n   weaken §11.1.\n4. An estate activates a profile through an authenticated §13.3 `protocol` entry pinning its exact\n   repository, path, and SHA-256. A moving branch is discovery, never authority.\n5. A claim of **RAPP production conformance** requires both profiles. Core Producer, Consumer, and\n   Router/Mirror implementations remain conformant without implementing production operations.\n6. Fixed envelope keys carry the safety invariants. Policy-defined check identifiers, component kinds,\n   health objectives, and resilience controls are extension points; adding one does not change the\n   profile token or the RAPP/1 wire.\n7. A consumer **MUST** refuse unknown required policy semantics. It may preserve and relay unknown\n   optional evidence, but may not treat it as satisfying a requirement it does not implement.\n\nThe executable reference validators are `rapp_cicd.py` and `rapp_deploy.py`; controlled profile vectors\nare in `operations_conformance.py`. JSON Schemas define structural shape, while the reference validators\nenforce ordering, identity, temporal, and cross-document rules that JSON Schema cannot express.\n\n## 12. Versioning, evolution, no-legacy\nRAPP is a **living standard** (WHATWG): revised in place, never forked into parallel versions; a `name/X.Y`\nlabel **MUST NOT** ever denote two shapes (Art. II) — a shape change moves the token (§7.1). Published\ncontent-addressed artifacts are **immutable** (SemVer/crates). Because the estate has **no uncontrolled\nuserspace**, there is **no perpetual backward compatibility** (Art. III): a change to a canonical form is a\n**total migration** of every instance + **deletion** of the old form. Sealed re-genesis history (§12.1) is\nthe retained live-stream exception and is not \"legacy compatibility.\"\n\nImmutable specification-governance history is a separate narrow exception:\nrev-5 through rev-13 anchor frames retain interpretable immutable pointer\npayloads so their ratified normative bytes remain resolvable. They are\nhistorical authority records, not accepted live legacy protocol forms. A\nproducer **MUST NOT** emit the pointer-only revision profile after rev-13.\n\n### 12.1 Re-genesis (converging an immutable chain — one owner-authorized operation)\n1. **Terminal seal:** `seal = Hb(\"rapp/1:seal\", head_octets)`. `head_octets` is the exact octets of the old\n   head's record **as retained under `legacy/`** (step 4): for a one-frame-per-file store, the retired\n   file's full octets; for a line-oriented log, the head's line **excluding** its trailing terminator. The\n   retained `legacy/` artifact is the verification reference for the seal, and retirement **MUST** preserve\n   those octets bit-exact. The step-3 `genesis` registry entry **SHOULD** record the `legacy/` artifact's\n   repo+path so a consumer **MAY** verify the seal against it. (Defined for every legacy shape, including\n   ones that cannot be §7.3-hashed.)\n2. **New genesis:** emit `seq`=0, `prev`=null, `kind` = the registered re-genesis kind **of the stream's\n   family** — `memory.re-genesis`, `swarm.re-genesis`, or `body.re-genesis` (three §13 kinds, used only\n   here) so the frame satisfies §7.2 family↔stream compatibility for any stream — `sig`≠null owner-signed\n   (§10, §13 `estate_owner`), `payload` = `{\"migrated_from\":{\"stream_id\":<old>,\"terminal_seal\":<seal>,\n   \"terminal_seq\":<n>}}` and no other members. A consumer **MUST** treat any `*.re-genesis` kind as the sole\n   re-genesis marker for its family and refuse an unsigned/non-owner one.\n3. **Register (the linearization point):** append a §13.3 `genesis` entry mapping the `stream_id` to the new\n   genesis's `frame_hash`, **and flag every prior `genesis` entry for that `stream_id` `deprecated`** — the\n   first convergence included (it deprecates the creation-time genesis), so exactly one non-deprecated entry\n   always remains. A consumer resolves the current genesis **only** via that sole non-deprecated entry. A\n   **concurrent** second registration fails closed (the append is the linearization point, Art. IX); a\n   later fork/brick (§7.6/§14) is a fresh owner-authorized convergence that appends again and re-deprecates.\n4. **Retire:** move old frames under `legacy/` — retained as immutable sealed history, never served as\n   current, never extended, never read as live chain. No live frame may set `prev`/`prev_wave` to a retired\n   hash (a dangling ref is a drift finding).\n5. Keep the old `stream_id` unless the identity itself re-anchored (§6.3), in which case the registry entry\n   also records `old_stream_id → new_stream_id`.\n6. Two frames with equal `stream_id`+`seq` from different eras are disambiguated **solely** by descent from\n   the current registered genesis. Re-genesis is one-time per convergence; a repeat *of the same\n   convergence* is the concurrent case (step 3, fails closed).\n\n### 12.2 DOGG specification revision chain\n\nThe RAPP/1 revision content is the append-only JSONL stream at\n`anchor/chain.jsonl`. The chain's particle, wave, and predecessor hashes prove\nbyte integrity and linear history; they do **not** authenticate who selected a\nhead or ratified an amendment. Until a separately authenticated RAPP\nregistry/checkpoint is ratified, authority is selected by owner-ratified\nacceptance of a chain snapshot onto protected canonical\n`refs/heads/main` at `https://github.com/kody-w/rapp-1`. A consumer starting\nfrom an out-of-band pinned accepted commit and head frame hash has the same\nimmutable selection evidence. An internally valid fork is not authoritative\nmerely because its hashes verify.\n\nEvery protocol adjustment **MUST** append exactly one valid successor frame:\n\n- `spec` remains `\"rapp/1\"`, the envelope remains exactly eleven keys, and the\n  allowed registered anchor kind is `body.pulse`; this profile does not create\n  a new kind or alter canonicalization, hashing, or registered-kind semantics;\n- `stream_id` remains the bootstrap-pinned anchor stream, `seq` is contiguous,\n  `prev` names the predecessor's `payload_hash`, `prev_wave` and `sig` are\n  `null`, and the applicable §7.5 integrity checks hold;\n- the frame's `frame_hash` is the durable protocol-revision identity.\n  Human names such as `rev-14` are lookup labels/views, never identities.\n\n#### 12.2.1 Immutable bootstrap boundary\n\nVerification begins from the frozen `rapp-anchor-bootstrap/1` profile published\nthrough `anchor/bootstrap/index.json`. The index names a\n`anchor/bootstrap/sha256-<raw-profile-sha256>.json` object and pins the exact\nstdlib verifier at `anchor/bootstrap_verify.py` by raw SHA-256 and byte length.\nThe profile fixes the exact-integer JCS subset and limits, particle/wave\ndomains, eleven frame keys, timestamp/sequence/predecessor rules, canonical\nrepository and protected ref, anchor stream ID, genesis frame and payload\nhashes, `body.pulse` anchor profile, null signature/wave fields, and byte/depth\nlimits needed to verify this chain.\n\nThe content-addressed bootstrap profile is immutable. Changing it requires a\nnew bootstrap schema/version and a new external ratification; mutating\n`rapp-anchor-bootstrap/1` in place is refusal. Its initial authenticity is\nnecessarily external — owner-ratified protected canonical main or an\nout-of-band pinned profile hash/immutable commit — because neither a chain nor\ncode fetched with that chain can circularly authenticate its own parser.\n`rapp.py` remains the complete reference implementation and is cross-checked,\nbut it is not the mutable bootstrap trust pin.\n\n#### 12.2.2 Revision payloads and historical exception\n\nFrames through rev-13 retain their immutable legacy pointer fields:\n`canonical_repo`, a full 40-lowercase-hex `commit`, safe relative\n`normative_path`, raw-file `normative_sha256`, and decimal-string\n`normative_bytes`. A resolver **MUST** construct only an immutable\ncommit-pinned GitHub Raw URL from those fields, fetch the bytes, and verify\nlength and raw SHA-256 before use. A branch or tag name in `commit`, an unsafe\npath, malformed UTF-8, a byte-order mark, or a hash/length mismatch is refusal.\nPath validation occurs on the original string before path-library\nnormalization: empty, absolute, `.`/`..`, empty components, repeated slash,\nleading `./`, trailing slash, backslash, percent-encoded ambiguity, or any\nvalue whose reconstructed POSIX form differs is refused.\nThese pointer payloads are immutable governance history under Article 3's\nnarrow exception; they **MUST NOT** be emitted for rev-14 or later.\n\nRev-14 and each successor using this profile carries all normative text inside\nthe chain frame. Its payload **MUST** include\n`schema:\"rapp-spec-revision/1\"`, a unique `revision`, and both\n`previous_revision` and `previous_normative_sha256` matching the immediate\npredecessor. It preserves the useful legacy fields above, carries the\npublication/ratification metadata defined below, and adds exactly this\n`normative` object:\n\n```json\n{\n  \"media_type\": \"text/markdown; charset=utf-8\",\n  \"text\": \"<exact normative SPEC.md Unicode text>\",\n  \"sha256\": \"<lowercase SHA-256 of text encoded as UTF-8>\",\n  \"bytes\": 123\n}\n```\n\n`normative.text` **MUST** encode as UTF-8 without a byte-order mark;\n`normative.sha256` and `normative.bytes` **MUST** match those exact octets and\nthe corresponding legacy `normative_sha256` and `normative_bytes`. The complete\ncanonical frame remains subject to §4's 1 MiB limit. Inline revisions require\nonly the selected, verified chain bytes once fetched; their commit/path fields\nare immutable provenance, not a second source for normative text.\n\nThe payload's `publication` object, repeated in the beacon and revision index,\nrecords: canonical repository `https://github.com/kody-w/rapp-1`; protected ref\n`refs/heads/main`; selection by owner-ratified acceptance; the accepted\ncanonical-main commit as linearization point; prohibition of history\nreplacement; mandatory rebase/regeneration for a competing append; rev-14\nratification under rev-13 Article 14; application of this chain-append process\nfrom rev-15 onward; and `authenticated_registry_checkpoint:null` until one\nactually exists. This metadata **MUST NOT** be interpreted as a signature or\nauthenticated registry.\n\n#### 12.2.3 Content-addressed publication and resolution\n\nEvery chain frame **MUST** also be published, without a trailing line\nterminator, at:\n\n```text\nanchor/frames/<frame_hash>.json\n```\n\nA fetch through mutable main is discovery only. Given frame hash `F`, a\nstranger may fetch\n`https://raw.githubusercontent.com/kody-w/rapp-1/main/anchor/frames/F.json`,\nparse it under the pinned bootstrap, and accept the object only if its computed\nwave equals `F`. For accepted snapshot commit `C`, the immutable URL is\n`https://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/frames/F.json`.\nWrong content at the correct hash-derived path is refusal.\n\n`anchor/index.json` is a deterministic generated index from `seq`, revision\nlabel, frame hash, and payload hash to those objects. It carries no independent\nauthority: a consumer **MUST** verify each selected object and match the index\nand beacon to the fully verified chain. Resolution by frame hash uses the path\nalgorithm directly; resolution by payload hash or sequence uses the verified\nindex; resolution by revision label is a view over it. The fixed pre-profile\nrev-5 pulses share one historical label, so the `rev-5` view resolves to the\ngreatest matching `seq`, while every pulse remains directly resolvable by\nsequence and hashes.\n\nA consumer **MUST** verify the chain from the bootstrap-pinned genesis before\nusing a revision as selected history. It **MUST** refuse an invalid frame shape,\nparticle, wave, or `prev`; a fork or duplicate `seq`; duplicate frame/payload\nhashes; a duplicate profiled revision; an unsupported schema; a legacy\npointer-only frame after rev-13; malformed UTF-8; normative hash/length drift;\nbootstrap/index/object drift; or an object absent from the selected chain.\n\n`orient.json` is only a beacon to the head. Its sequence, frame hash, payload\nhash, bootstrap/index pins, authority-selection metadata, and every retained\nhead mirror — including `registered_kinds`, vocabulary, operational profiles,\nfoundation, philosophy, and Constitution metadata — **MUST** be regenerated\nfrom and match the verified head. While the beacon schema remains\n`rapp/1-anchor`, `spec.normative_path` **MUST** remain as a compatibility alias\nequal to `spec.materialized_path`. `SPEC.md` **MUST** reproduce the selected\nhead byte-for-byte. The Atom feed and mutable main URLs are discovery only.\n\nMaterialization and immutable-pointer caching **MUST** use bounded reads and\nsame-directory atomic replacement without following a symlink in the\ndestination leaf or path. A symlink, unsafe directory component, oversized\ncache entry, content change during read/write, or compare-and-swap mismatch is\nrefusal; the requested leaf is replaced, never the symlink target.\n\nAfter acceptance, let `C` be the full 40-hex canonical-main commit containing\nthe accepted snapshot. The immutable checkpoint URLs are:\n\n```text\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/chain.jsonl\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/orient.json\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/index.json\n```\n\nThe authority linearization point is the owner-ratified acceptance of `C` onto\nprotected canonical main, not creation of a local frame, a feed event, or a\nhash alone. A stale competing append **MUST** rebase onto the accepted head and\nregenerate. Force-push or history replacement of accepted authority is\nprohibited.\n\n#### 12.2.4 Rev-14 transition and draft replacement\n\nRev-14 is ratified under rev-13 Article 14. Owner acceptance of the prepared\nchange onto canonical protected main makes the final rev-14 frame effective;\nthe new chain-append process governs rev-15 onward. Before that acceptance,\nrev-14 artifacts are unpublished drafts. A later commit in the same\nowner-ratified change may deterministically replace the one unpublished rev-14\ndraft line/object and update dependent hashes, but **MUST** preserve every\nrev-5 through rev-13 line byte-for-byte and **MUST NOT** represent the replaced\ndraft as accepted history.\n\nThe publication generator **MUST** hold one cross-process exclusive lock across\nread, verification, generation, comparison, and publication. Immediately\nbefore replacing `chain.jsonl` it **MUST** re-read and verify the on-disk head\nand compare the complete expected prefix; a stale writer or changed prefix is\nrefused. Supporting content-addressed artifacts are published first, the\nauthority chain is compare-and-swap replaced next, and the beacon is replaced\nlast, with file and parent-directory synchronization. Because the chain is\nauthority content and the beacon is only a derived view, interruption after a\nvalid chain replacement may leave a stale or missing beacon; the next locked\nrun **MUST** deterministically regenerate it from the verified chain rather\nthan refusing the valid head forever.\n\nThis chain and beacon are unsigned. They provide integrity after authority\nselection, not authorship, and implementations **MUST NOT** fabricate a\nsignature or authenticated registry/checkpoint state for them.\n\n## 13. The registry — an estate's signed root of trust (append-only)\nEach estate selects an owner-controlled `canonical_source` for its\n`schema:\"rapp/1-registry\"` document. The kody-w reference estate may publish\nits registry through `kody-w/RAPP` or another owner-authorized location, but\nthat estate instance cannot alter this protocol. Because §7.6 head resets, §10\nkey discovery, tombstone revocation, and ownership all resolve through the\nselected registry, it is the **root of trust for that estate** and is itself\nauthenticated (an unsigned mutable file at the root of the trust graph would\nforge that estate).\n\n### 13.1 Trust anchor and registry authentication\n- The one bootstrap axiom is the **`estate_owner` rappid string** itself: since a keyed tail is\n  `Hb(\"rapp/1:rappid\", SPKI_DER)`, the rappid **is** a self-certifying key fingerprint, distributed\n  out-of-band exactly once (QR, invite, docs) the way a root-CA certificate is.\n- The registry document **MUST** carry a top-level `registry_seq` (uint53) and a detached §10 JWS `sig` over\n  `canonical(registry \\ {sig})` with `kid` = the `estate_owner` rappid. A consumer **MUST** verify this\n  signature against an SPKI whose `Hb(\"rapp/1:rappid\", SPKI_DER)` equals the anchor rappid's tail (the SPKI\n  may travel alongside the registry — the tail check authenticates it) and **MUST** refuse an unsigned or\n  non-verifying registry.\n- **No rollback:** a consumer persists the highest `registry_seq` it verified and refuses any registry with\n  a lower one (mirrors §7.6). **Freshness:** a consumer **MUST** obtain the registry from `canonical_source`\n  or a provenance-stamped (Art. VIII) mirror of it, **SHOULD** refresh before any §7.5-step-6 or §7.6\n  head-reset decision, and **MUST** report a verification made against a registry older than its staleness\n  policy as *stale*, not *clean*.\n\n### 13.2 Owner succession (time-scoped authority)\n\"Owner-signed\" means: the `sig` verifies per §10 **and** `kid` is the estate-owner **in effect at the\nartifact's `utc`** — the current `estate_owner` or any predecessor reachable through the registry's\nre-anchor records (§13.3), with the artifact's `utc` inside that owner's tenure `[record.utc, successor.utc)`.\nVerification uses the owner in effect at the artifact's time, **never only the current one** (so a routine\nowner key rotation never invalidates historical re-genesis frames or tombstones). Estate-owner **root-key\ncompromise** is recovered only by re-distributing a new trust anchor out-of-band (§13.1) — it cannot be\nexpressed inside the registry it signs.\n\n### 13.3 Entry types (each a §4 value; document `schema:\"rapp/1-registry\"`)\nThe registry is an I-JSON document; every entry is append-only (never removed/renamed; retirement is a\n`deprecated:true` flag). Entry types and their exact members:\n- **protocol** `{type:\"protocol\", name, spec_repo, spec_path, spec_hash, deprecated}` — an estate\n  adoption pin, never a power to redefine a protocol. An entry with `name:\"rapp/1\"` that is used for a\n  current-conformance claim **MUST** set `spec_repo:\"https://github.com/kody-w/rapp-1\"`,\n  `spec_path:\"SPEC.md\"`, and `spec_hash` to a normative SHA-256 published by a verified frame in this\n  repository's anchor chain. A historical RAPP/1 pin may be retained only as `deprecated:true`; it does\n  not override the current anchor. Other protocol entries are subordinate to their own canonical\n  authorities and **MUST NOT** claim the `rapp/1` name or namespace.\n- **kind** `{type:\"kind\", kind, family, deprecated}` (incl. the three `*.re-genesis` kinds)\n- **egg-variant** `{type:\"egg-variant\", variant, deprecated}` · **error-code** `{type:\"error-code\", code}`\n  (both closed namespaces; unregistered value = not conformant)\n- **genesis** `{type:\"genesis\", stream_id, frame_hash, deprecated, old_stream_id?, new_stream_id?}` — **every**\n  stream registers its creation genesis; re-genesis appends a new one and deprecates all prior (§12.1 step 3);\n  §7.6's \"registered genesis\" is the sole non-deprecated `genesis` for a `stream_id`.\n- **spki** `{type:\"spki\", rappid, spki_der_b64, deprecated}` — the §10 key-discovery source.\n- **tombstone** `{type:\"tombstone\", rappid, revoked_utc, sig}`, `sig` owner-signed over `canonical(entry \\ {sig})`.\n- **re-anchor** `{type:\"re-anchor\", old_rappid, new_rappid, case:(\"upgrade\"|\"rotation\"|\"compromise\"|\"tag-migrate\"),\n  utc, sig, old_key_sig?}` — `sig` owner-signed; `old_key_sig` a §10 JWS by the **old** key over\n  `canonical(entry \\ {sig,old_key_sig})`, REQUIRED for `case:\"rotation\"`. This is the normative succession record (§13.2).\n- **grail-kernel** `{type:\"grail-kernel\", release_scope, grail_id, repository, immutable_ref,\n  object_format, commit, path, mode, blob, sha256, size_bytes, activated_utc, predecessor, declared_by,\n  sig}` — exactly these members. `release_scope` is an absolute HTTPS URI selected by the estate owner;\n  no two entries may share it. `grail_id` is\n  `\"grail:\" || Hb(\"rapp/1:grail\", kernel_bytes)`; `repository` is an absolute HTTPS URI;\n  `immutable_ref` is a full `refs/tags/...` name that **MUST** resolve exactly to `commit`;\n  `object_format` is `\"sha1\"` or `\"sha256\"` and fixes the required lowercase hexadecimal length of\n  `commit` and `blob`; `path` at `commit` **MUST** resolve through the repository tree to exactly one\n  regular blob with `mode` `\"100644\"` or `\"100755\"` and object id `blob`;\n  `path` is a relative NFC POSIX path with no empty, `\".\"`, or `\"..\"` component; `sha256` is the raw\n  kernel bytes' 64-lowercase-hex SHA-256; `size_bytes` is their positive `uint53` length;\n  `activated_utc` has the exact §7.4 form; `predecessor` is null or another `grail_id`; `declared_by` is\n  a keyed rappid; and `sig` is a detached §10 JWS whose protected `kid` equals `declared_by`, over\n  `canonical(entry \\ {sig})`. The entry is additionally covered by the registry's §13.1 signature. A\n  consumer verifies the entry signer as the estate owner in effect at `activated_utc`, verifies the\n  referenced bytes, recomputes both hashes, persists the canonical entry on first activation, applies\n  §11.1, and refuses a missing/mutated prior binding, duplicate `grail_id`, or locator whose bytes\n  disagree.\n- **estate_owner** `{type:\"estate_owner\", rappid}` (exactly one non-deprecated) · **master-plan**\n  `{type:\"master-plan\", repo, path}` (Fed. Const. Art. VII).\n\n§7.5 steps 1–5 are time-independent (append-only lookups); **only** step 6 (tombstones) and §13.2 owner\ntenure are time-scoped, and both are monotone given the §13.1 no-rollback rule.\n\n## 14. Security considerations\n- **Integrity:** every object is domain-separated content-addressed (§5); a hostile mirror cannot alter\n  bytes without breaking the hash, so *history is safe given a trusted head*.\n- **Head freshness is not self-certifying:** the chain authenticates history, not which head is current; a\n  hostile mirror may serve a stale/forked head. Consumers counter with the §7.6 monotonic-head rule; swarm\n  heads **SHOULD** be owner-signed.\n- **Cross-stream replay:** without §7.5 step 1a, any genesis/segment of stream A replays as stream B (seq=0,\n  prev=null always pass). Step 1a's stream binding is mandatory.\n- **Address-space confusion:** §5 domain tags make a particle, wave, egg, or rappid tail with equal hex\n  non-interchangeable; stores key by `(space, hash)`.\n- **Canonicalization attacks:** the §4 I-JSON input-domain profile (no duplicate keys, no lone surrogates,\n  exact binary64, no normalization ambiguity) removes hash-splitting and NFC-twin vectors.\n- **Identity forgery / key compromise:** authorship requires a keyed rappid + valid §10 `sig`; rotation is\n  §6.3 re-anchor (verifiable authorization, §6.3/§13.3 — a self-asserted `_migrated_from` is refused);\n  compromise is a §13 tombstone enforced at verify time. Because a tombstone gates on the frame's\n  producer-controlled `utc`, a compromised key can still emit frames stamped just below `revoked_utc`; after\n  a compromise the owner **SHOULD** advance affected stream heads (or re-genesis) past `revoked_utc`.\n- **Root of trust:** the registry is the estate's signed root (§13.1); it is authenticated by an owner\n  signature anchored to the out-of-band `estate_owner` rappid fingerprint, `registry_seq`-monotonic against\n  rollback, and freshness-checked (a stale registry silently un-revokes keys and hides re-geneses).\n- **Producer-controlled `utc` (DoS/merge bias):** a future-dated head can brick a stream (successors refused\n  as earlier) and bias UTC-first merges. A consumer **SHOULD** refuse a frame whose `utc` exceeds receipt\n  time by >300 s, and adversarial-scope merges **SHOULD** rank by `min(utc, first-seen)`; a bricked stream\n  converges by re-genesis (§12.1).\n- **Sealed-artifact limits:** a public mirror sees ciphertext and metadata. AES-GCM protects confidentiality\n  only while the DEK remains secret; a recipient that has lawfully decrypted plaintext can copy it.\n  Revocation stops future wrapped-key release, not prior possession. Shared passwords, embedded master keys,\n  moving-branch URLs, nonce reuse under one DEK, and claims that bytecode cannot be inspected after\n  decryption are non-conformant security postures (§9.2.1).\n- **Kernel substitution:** testing mutable ring bytes and restoring the Grail only after approval creates\n  an untested release. §11.1 requires the release-shaped artifact to contain the pinned bytes before its\n  tests, attestations, and approval; a digest mismatch is a blocking `kernel-drift` finding.\n- **Kernel registry rollback/rebinding:** persisting only `registry_seq` does not preserve an activated\n  Grail declaration across a malicious higher-sequence registry. Consumers also persist every activated\n  canonical `grail-kernel` entry and reject its later removal, mutation, or duplication (§11.1).\n\n## 15. References\n[RFC 2119] [RFC 8174] requirement terms · [RFC 8259] JSON · [RFC 7493] I-JSON · [RFC 8785] JCS ·\n[FIPS 180-4] SHA-256 · [RFC 3986] URI · [RFC 5234] ABNF · [RFC 7405] case-sensitive ABNF · [RFC 9562] UUID\n(obsoletes RFC 4122) · [RFC 5280] X.509 SPKI · [RFC 7515] JWS · [RFC 7797] unencoded JWS payload ·\n[RFC 7518] JWA/ES256 · [RFC 8037] EdDSA in JOSE · [RFC 6979] deterministic ECDSA · [RFC 3339] timestamps ·\n[NIST SP 800-38D] AES-GCM · [RFC 2104] HMAC · [RFC 5869] HKDF · [RFC 7516] JWE · [ECMA-262] ECMAScript.\n\n---\n\n### Revision log\n- **rev-14 (DOGG specification-chain authority)** — makes the append-only\n  `anchor/chain.jsonl` frame history carry normative specification content\n  while protected canonical-main acceptance selects authority; defines the\n  frame hash as durable revision identity; embeds the normative Markdown in a\n  normal `body.pulse`; retains immutable rev-5–rev-13 pointer history; freezes\n  a content-addressed bootstrap verifier profile; publishes hash-addressed\n  frame objects and a deterministic index; makes `SPEC.md` a materialized\n  selected-head view; and records the rev-13 Article 14 transition without\n  inventing signatures or changing any RAPP/1 wire primitive.\n- **rev-13 (public governance closure)** — makes the ratified public Protocol\n  Constitution final for protocol governance; limits private governance and\n  master plans to estate/product concerns; makes registry `protocol` entries\n  subordinate adoption pins; verifies the exact canonical RAPP foundation\n  object before anchoring; and aligns every public teaching surface with\n  estate-specific registry authority.\n- **rev-12 (foundation/protocol boundary)** — records `kody-w/RAPP` as the\n  canonical public foundation and product home; limits `kody-w/rapp-1` to\n  protocol authority; ratifies the complete public Protocol Constitution; makes\n  registries explicit estate instances rather than protocol authorities; pins\n  the canonical foundation commit and philosophy hash; and removes any\n  implication that protocol publication transfers product, brand, company, or\n  ownership authority.\n- **rev-11 (planetary operations profiles)** — constitutionalized immutable candidate/serving lineage\n  separation; defined RAPP CI/CD (`rapp-cicd/1`) and RAPP Deploy (`rapp-deploy/1`) as subordinate,\n  registry-pinned production profiles; required exact-candidate qualification, production-shaped\n  Preprod, cellular progressive exposure, expiring AI-health evidence, state/data continuity,\n  automatic containment, and exact rollback while retaining policy-defined extension points; and\n  defined typed, non-authoritative offspring/cross lineage without changing the egg or frame envelopes.\n- **rev-10 (sealed artifact + Grail execution closure)** — registered the `sealed` egg variant for\n  globally mirrorable public ciphertext with signed manifests and scoped recipient key release (§9.2.1);\n  added the `rapp/1:sealed-aad` and `rapp/1:sealed-key-request` address spaces; retained rev-9's exclusive\n  `release_scope` selection, persisted Grail binding, and verification-to-execution protections; and made\n  both confidentiality limits and kernel drift release-blocking.\n- **rev-9 (Grail selection and execution closure)** — makes release policy select only\n  `release_scope`, resolves `grail_id` exclusively through the activated persisted registry binding,\n  and closes verification-to-execution races by requiring a sealed immutable object/snapshot or\n  platform-enforced write exclusion through byte consumption.\n- **rev-8 (immutable Grail closure)** — makes pin selection deterministic through `release_scope`,\n  defines the exact signed §13.3 `grail-kernel` entry and owner-at-time activation, requires consumers\n  to persist every accepted binding, and specifies repository-object and executed-entry-point\n  verification across interpreted and derived runtimes.\n- **rev-7 (immutable Grail constitution)** — defines the Grail kernel by the SHA-256 of its exact bytes\n  (§3), makes every ring and release/deployment stage verify both the pin and the actually executed entry\n  point (§11.1), forbids post-test substitution, and makes changed bytes a different Grail rather than a\n  mutation. This is release governance only; the RAPP wire and existing canonical forms are unchanged.\n- **rev-6 (instantiation lineage)** — added §9.4's fresh per-install instance identity and immutable\n  `grown_from` lineage, closing the hatch seam without changing the frame or egg envelopes.\n- **rev-5 (war-game round 3 fold)** — folded 5 blockers + 7 majors + 7 minors, all clustered on the trust\n  model that rev-4's fixes made load-bearing: the **registry is now a signed root of trust** (§13.1) —\n  owner-signed, anchored to the out-of-band `estate_owner` rappid fingerprint, `registry_seq`-monotonic,\n  freshness-checked (B-1); **re-anchor requires a verifiable §13.3 authorization record** with old-key\n  continuity proof / tombstone / SPKI-tail check (B-2, mint-once now enforceable); **owner-succession is\n  time-scoped** so a key rotation never invalidates historical signatures (B-3); **eggs are `stored`-only**\n  (deflate is non-deterministic) with `canonical(manifest)` bytes (B-4); **invites sign under the\n  estate-owner succession** not the egg's own rappid (B-5); `egg_hash` excludes `sig` (M-1); first\n  re-genesis deprecates the creation genesis (M-2); full **registry entry schema** §13.3 (M-3); registry\n  freshness rule (M-4); egg consumer enforces §9.1 (zip-slip, M-5); rotated key refused on new frames (M-6);\n  `rapplication` exact `agent.py` (M-7); rev label, `invite` naming, sub-egg collision, rounding rule,\n  idempotency, compromise-window, seal-path (m-1…m-7).\n- **rev-4 (war-game round 2 fold)** — folded 6 blockers + 14 majors + 8 minors: domain-tagged mint\n  reconciled across Constitution/ledger (B1); §4(c) binary64 round-trip test so `0.1` is accepted (B2);\n  re-genesis head-reset exception so it isn't refused as rollback (B3); family-matched `*.re-genesis` kinds\n  so memory/swarm streams can converge (B4); whole-egg address `H(\"rapp/1:egg-manifest\",…)` + signed invites\n  + manifest self-reference resolved + deterministic ZIP/`contents` ordering (B5, M2–M4); re-anchor\n  enumerated three cases incl. key rotation (B6, M-rotation); `head_octets` pinned to the retained `legacy/`\n  artifact (M6); subsequent-convergence via `deprecated` (M7); every stream registers its genesis (M8); JWS\n  header canonical bytes + registry key-discovery + `estate_owner` designation (M9–M11); `/chat` error `step`\n  as string incl. `\"1a\"` + code namespace + session semantics (M12, m5); tombstone as the one time-dependent\n  verify check (M13); egg draft-artifact + dangling `§4` reference removed (M1, M5); calendar-valid `utc`,\n  depth convention, kind dedup/bounds (m2, m7, m8).\n- **rev-3 (war-game round 1 fold)** — folded 7 blockers + 19 majors + 12 minors from the Fable adversarial last-call:\n  I-JSON input domain + no-normalization/NFC (§4); **domain-separated hashing** (§5, the stronger option);\n  fixed `utc` byte form (§7.4); `prev_wave` by stream family not transport (§7.4); **stream-binding**\n  anti-replay (§7.5.1a); `spec` token pinned to `rapp/1` (§7.1); full JWS profile + key discovery + rotation/\n  tombstone (§10); hardened re-genesis with raw-byte terminal seal + registry linearization (§12.1); heads &\n  forks (§7.6); `/chat` fully specified (§8); **egg variants ratified into the standard**, killing the\n  6-spec collision and closing EGG-01 (§9); registry append-only (§13); type-validated verify (§7.5.1);\n  cross-stream merge tie-break (§7.4); provisional-identifier rule (§6.3); all references added (§15).\n- **rev-2** — first last-call tightening (7 self-review defects).\n- **rev-1** — initial unified draft.\n\n*The canonical protocol authority is the owner-selected, verified\nspecification chain in this repository. The canonical public RAPP foundation\nand product home remain at `kody-w/RAPP`.*\n", "sha256": "d345235be5bc698d78c5893285abd09f2e62a398f781123d1de8da313a01c7de", "bytes": 78183}, "publication": {"canonical_repository": "https://github.com/kody-w/rapp-1", "protected_ref": "refs/heads/main", "selection": "owner-ratified acceptance of the chain snapshot onto protected canonical main", "linearization": "the accepted canonical-main commit containing the new frame", "history_replacement": "prohibited", "competing_append": "must rebase onto the accepted head and regenerate", "transition": "rev-14-ratified-under-rev-13-article-14", "chain_append_process": "governs-rev-15-and-later", "authenticated_registry_checkpoint": null}}, "payload_hash": "c7549bbd3e133b833930e24e008817ea295734b870f41706455d3f45821aba3a", "prev": "78a89c06509b5100494b9c7e0f551acdc6209fd90aded734321f3580b0f07051", "prev_wave": null, "sig": null, "frame_hash": "59629adab4e26d156f3d66ecfb766e08705919ea1d2adc92ba0ad2b17337dfc2"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 15, "utc": "2026-09-02T01:31:21.000Z", "payload": {"canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "58058d08c9f0e340fae07c9865647f599c32634d", "commit_utc": "2026-09-01T21:31:21-04:00", "default_profile": "interop", "exchange": {"carrier": "POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward.", "idempotence": "keyed on the request's payload_hash — a retry returns the existing reply, never a second one.", "rule": "the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.", "shape": "push a frame in, get a frame back shaped by what you pushed — ONE hop."}, "frame_keys": ["spec", "kind", "stream_id", "seq", "utc", "payload", "payload_hash", "prev", "prev_wave", "sig", "frame_hash"], "kind_families": {"body": {"kinds": ["body.pulse", "body.twin-pulse", "body.reconstructed", "body.re-genesis"], "logs": "an organism's biography", "stream": "body-stream (bare rappid)"}, "memory": {"kinds": ["memory.chat-turn", "memory.tool-call", "memory.save", "memory.reconstructed", "memory.re-genesis"], "logs": "one organism's life", "stream": "memory-stream"}, "swarm": {"kinds": ["swarm.guidance", "swarm.echo", "swarm.telemetry", "swarm.reconstructed", "swarm.re-genesis"], "logs": "the planetary wire", "stream": "swarm-stream (net:label)"}}, "moods": {"clear": {"profile": "interop", "when": {"conditions": "clear,sunny"}, "why": "good conditions, normal posture"}, "early": {"profile": "minimal", "when": {"hour_lt": "6"}, "why": "same"}, "night": {"profile": "minimal", "when": {"hour_gte": "22"}, "why": "low-attention hours; smallest honest context"}, "storm": {"profile": "audit", "when": {"conditions": "storm,rain,snow"}, "why": "degraded links are when drift hides; lead with verification"}}, "normative_bytes": "79692", "normative_path": "SPEC.md", "normative_sha256": "348e7d5baa94aaf2ce4c5354f3cb261f389298a04af65e271a686d3b62f7c384", "observed_utc": "2026-09-02T01:31:21.000Z", "profile_signals": {"author": "authoring", "build": "authoring", "check": "audit", "conform": "audit", "drift": "audit", "handshake": "interop", "install": "onboarding", "join": "onboarding", "mint": "authoring", "new": "onboarding", "stranger": "interop", "unknown-peer": "interop", "verify": "audit", "write": "authoring"}, "profiles": {"audit": {"max_rules": "8", "show": ["keys", "stale_terms"], "types": ["pattern", "gotcha"], "why": "judging conformance; refuse-never-repair and the identity law govern"}, "authoring": {"max_rules": "8", "show": ["keys", "eggs"], "types": ["gotcha", "fact"], "why": "hand-building a frame; the envelope rules are what bite"}, "interop": {"max_rules": "6", "show": ["keys", "stale_terms", "pointer"], "types": ["gotcha"], "why": "a peer may be out of date; lead with what it can get WRONG"}, "minimal": {"max_rules": "0", "show": ["stale_terms"], "types": [], "why": "smallest honest context"}, "onboarding": {"max_rules": "5", "show": ["keys", "eggs", "stale_terms", "pointer"], "types": ["fact"], "why": "new organism; needs the shape of the world, not the edge cases"}}, "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "revision": "rev-15", "rules": [{"c": "spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted.", "t": "fact"}, {"c": "Canonical form is RFC 8785 JCS and FORBIDS floats — numbers ride as strings. A float silently breaks byte-reproducibility.", "t": "gotcha"}, {"c": "payload_hash = H(\"rapp/1:particle\", payload) — content only, reproducible across instances.", "t": "fact"}, {"c": "frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) — unique per stream instance.", "t": "fact"}, {"c": "prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable.", "t": "gotcha"}, {"c": "§6.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name — sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint.", "t": "gotcha"}, {"c": "Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed.", "t": "pattern"}, {"c": "A swarm-stream frame with sig==null is refused (§7.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null.", "t": "gotcha"}, {"c": "Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs.", "t": "fact"}, {"c": "Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise — this is how N streams compose into one view.", "t": "pattern"}, {"c": "One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct.", "t": "pattern"}, {"c": "§9.4 (rev-6): hatching an egg MUST mint a fresh §6.2 identity for the INSTANCE — the artifact rappid rides the egg unchanged and is shared by every install; the instance identity never is. The instance SHOULD record grown_from = the §9.1 egg address it grew from: written at mint, immutable, null when unknown, NEVER fabricated. Lineage, not inheritance — it confers no authority, no trust, no key material.", "t": "fact"}, {"c": "§11.1 / Constitution Article 15: owner policy selects only release_scope; the activated registry selects grail_id; every ring rejects kernel-drift; execution consumes bytes from a sealed immutable object or equivalent write-excluded snapshot.", "t": "gotcha"}, {"t": "gotcha", "c": "A sealed egg is public ciphertext, not password-protected hosting: the signed manifest binds AES-256-GCM data and a scoped key service; no shared DEK belongs in the egg, URL, client, log, or frame."}, {"t": "fact", "c": "RAPP CI/CD promotes one immutable release payload hash through an ordered evidence chain; no ring may rebuild, patch, substitute, or skip the candidate."}, {"t": "gotcha", "c": "RAPP Deploy forbids in-place serving mutation: growth happens in an isolated candidate lineage and reaches users only through bounded, reversible waves."}, {"t": "pattern", "c": "A new encounter may produce an offspring or cross with a fresh identity and typed parent addresses; lineage may continue indefinitely, but every attempt is bounded and parent authority never transfers implicitly."}, {"t": "fact", "c": "kody-w/RAPP remains the public foundation and product home; kody-w/rapp-1 defines the interoperable protocol only."}, {"t": "fact", "c": "The rapp/1 wire is frozen: §4, §5, §6.1-6.2, §7.1, §7.3, §7.5, §8 and §9.1 never change under the rapp/1 token; a change is rapp/2 beside it, and rapp/1 artifacts verify forever."}], "vocabulary": {"body": {"status": "live", "where": "§7.2 kind family"}, "estate": {"status": "live", "where": "§9.2 egg variant"}, "grail": {"status": "live", "where": "§3 terminology; §11.1 immutable Grail kernel conformance; Constitution Article 15"}, "grown_from": {"status": "live", "where": "§9.4 instantiation — instance lineage key"}, "instance": {"status": "live", "where": "§9.4 instantiation — a hatched install; fresh §6.2 identity, never shared"}, "invite": {"status": "live", "where": "§9.2 egg variant"}, "memory": {"status": "live", "where": "§7.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate — bytes only at git 24c8fdc, sha256 690f6109…"}, "neighborhood": {"status": "live", "where": "§9.2 egg variant"}, "organism": {"status": "live", "where": "§9.2 egg variant"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 §6"}, "rapplication": {"status": "live", "where": "§9.2 egg variant"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's words are `organism` (§9.2) and `instance` (§9.4)"}, "session": {"status": "live", "where": "§9.2 egg variant"}, "swarm": {"status": "live", "where": "§7.2 kind family"}, "sealed": {"status": "live", "where": "§9.2 sealed egg variant and §9.2.1 profile"}, "rapp-cicd": {"status": "live", "where": "§11.2 and protocols/rapp-cicd/1/SPEC.md"}, "rapp-deploy": {"status": "live", "where": "§11.2 and protocols/rapp-deploy/1/SPEC.md"}, "offspring": {"status": "live", "where": "§9.4 typed lineage and PHILOSOPHY.md"}, "cross": {"status": "live", "where": "§9.4 typed multi-parent lineage and PHILOSOPHY.md"}, "wire-freeze": {"status": "live", "where": "§12 and Constitution Article 18 — the rapp/1 verified forms never change; a change is rapp/2"}}, "philosophy": {"canonical_repository": "https://github.com/kody-w/RAPP", "canonical_commit": "cb921ae59b5d762ce0bdd5493764cbb1c8b539fe", "canonical_path": "PHILOSOPHY.md", "canonical_sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c", "mirror_path": "PHILOSOPHY.md", "mirror_sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c"}, "operational_profiles": {"rapp-cicd/1": {"status": "live", "spec_path": "protocols/rapp-cicd/1/SPEC.md", "spec_sha256": "6d27d10103a3204f3b65a2e246462d197016bce5203dd510ba3ce209740e8278", "schema_path": "protocols/rapp-cicd/1/schema.json", "schema_sha256": "5936057868f46fc74afa00532f4aea60cfbb667c7c2f09998e1e86a0c2e629cc"}, "rapp-deploy/1": {"status": "live", "spec_path": "protocols/rapp-deploy/1/SPEC.md", "spec_sha256": "b5fc84465fb201fd97d7059997490a8fae5bf79ec55e935b0cfd9b4c787108e5", "schema_path": "protocols/rapp-deploy/1/schema.json", "schema_sha256": "aca783f3274cd865926f6b943163189fa93a7bbc4c7d4258856a54779a4a71ba"}}, "constitution": {"path": "CONSTITUTION.md", "sha256": "59b600d63e329de5adf11aa6dd103c82e62c72882edd899788e80fd316b21d43", "size_bytes": 17403}, "foundation": {"schema": "rapp-foundation-pointer/1", "status": "canonical-product-home", "repository": "https://github.com/kody-w/RAPP", "commit": "cb921ae59b5d762ce0bdd5493764cbb1c8b539fe", "path": "PHILOSOPHY.md", "sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c", "size_bytes": 2633, "relationship": "kody-w/RAPP is the public RAPP foundation and product home; kody-w/rapp-1 is the interoperable protocol authority"}, "schema": "rapp-spec-revision/1", "previous_revision": "rev-14", "previous_normative_sha256": "d345235be5bc698d78c5893285abd09f2e62a398f781123d1de8da313a01c7de", "normative": {"media_type": "text/markdown; charset=utf-8", "text": "# The RAPP Protocol Suite\n### Unified normative specification of identity, canonicalization, the frame, the wire, and the egg\n\n> **Generated/materialized view.** These exact UTF-8 bytes are carried inside\n> the selected specification-revision frame in `anchor/chain.jsonl`. The frame\n> chain proves integrity and lineage; canonical owner-ratified publication\n> selects authority. Change the protocol by appending a successor frame, not by\n> treating this file as independent authority.\n\n**Status:** Owner-ratified RAPP/1 **rev-15 amendment**. It is effective iff the\nprepared chain snapshot has been accepted onto canonical protected main under\nthe transition in §12.2. **Obsoletes / consolidates:**\n`rapp-frame/2.0`, `rapp-frame/2.1`, `rapp-rappid-spec/2.0`, `rapp-protocol/1.0`, all scattered egg specs\n(§9 subsumes them), and `OSI.md`. This is the current materialized view of the single living standard;\nthe consolidated specs are retired historical record (Protocol Constitution Article 6). Rev-14 becomes\nthe published current revision when the source merge and append-only anchor update carrying these exact\nbytes complete.\n\n**Rides existing standards; invents nothing:** requirement terms [RFC 2119]/[RFC 8174]; JSON restricted to\nI-JSON [RFC 7493] over [RFC 8259]; canonicalization [RFC 8785] (JCS); hashing SHA-256 [FIPS 180-4] with\ngit-style domain separation; identifiers on the [RFC 3986] URI model; case-sensitive grammar [RFC 7405]\nover [RFC 5234] ABNF; keyless entropy UUIDv4 [RFC 9562]; keyed identity X.509 SPKI [RFC 5280]; signatures\ndetached unencoded JWS [RFC 7515]/[RFC 7797], EdDSA [RFC 8037] / ES256 [RFC 7518]/[RFC 6979]. RAPP is a\n*profile* over these, as HTTP profiles TCP/URIs/MIME.\n\n---\n\n## 1. Introduction\nRAPP is a content-addressed distributed organism. Its integrity rests on one invariant: **the same\nconcept has the same bytes everywhere.** This document specifies, normatively and completely, five\nload-bearing primitives so any two independent implementations interoperate **byte-for-byte with no\nout-of-band agreement**: canonicalization (§4), content addressing (§5), identity (§6), the frame (§7),\nthe egg (§9) — all riding one wire (§8): `POST /chat`, or a signed append-only frame. Implementations add\nagents, cartridges, and registered `kind`s — never new endpoints, never new envelopes.\n\n**Repository scope.** `kody-w/RAPP` is the canonical public RAPP foundation,\nproduct home, reference implementation, organism model, and philosophy.\n`kody-w/rapp-1` is the canonical interoperable protocol authority. This\nspecification governs wire-compatible bytes and conformance; it does not absorb\nthe RAPP product or any downstream Rappter/RapterBox LLC product.\n\n**Specification authority.** The append-only DOGG chain at\n`anchor/chain.jsonl` carries the normative revision content. Its hashes prove\nintegrity, not authority or ratification. Until an authenticated RAPP\nregistry/checkpoint exists, the chain accepted by the owner onto protected\ncanonical `kody-w/rapp-1` main is authoritative; an immutable accepted commit\nplus head frame hash is the portable checkpoint. `SPEC.md` is the byte-exact\nmaterialized human view, and `orient.json` is only a discovery beacon. The\nselected chain-frame hash, not a mutable path or `rev-N` label, is the durable\nidentity of a protocol revision (§12.2).\n\n### 1.1 The layered model\n```\n  L5  EGG        cartridge packaging (§9)          — MIME-multipart analogue\n  L4  FRAME      universal event envelope (§7)     — the IP packet of RAPP\n  L3  WIRE       transport: /chat + frames (§8)    — HTTP-analogue single method\n  L2  IDENTITY   rappid namespace + trust (§6,§10) — URI + PKI analogue\n  L1  ADDRESS    canonicalization + hash (§4,§5)   — the git object model\n```\nA higher layer **MUST NOT** redefine a lower one. Every layer names exactly one canonical form.\n\n## 2. Requirements language\nThe key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHOULD**, **MAY** are as in [RFC 2119]/\n[RFC 8174] when in **bold caps**. (The Federal Constitution adopts the same clause.)\n\n## 3. Terminology\n**organism** — a running brainstem with persistent identity. **rappid** — the eternal, mint-once name of an\norganism/door/object (§6): minted once from a UUIDv4 or a public key, never derived from content or name.\n**frame** — one immutable content-addressed event (§7). **stream** — an append-only hash-chained frame\nsequence sharing one `stream_id`. **particle / wave** — a frame's two domain-separated addresses:\npayload-hash / whole-frame-hash (§7.3). **canonical form** — the one [RFC 8785] byte string for a value\n(§4). **legacy form** — any other historical encoding; legacy is drift and **MUST** be migrated out\n(Fed. Const. Art. III), except sealed re-genesis history (§12.1).\n**Grail kernel** — an estate-declared, byte-pinned runtime substrate. Its `grail_id` is\n`\"grail:\" || Hb(\"rapp/1:grail\", kernel_bytes)`; repository, immutable ref, commit, path, raw SHA-256,\nand byte length are provenance and verification data, not alternate identities. Once activated through\n§13.3, those bytes are permanent (Protocol Constitution Art. 15); capabilities evolve outside them.\n**release capsule** — the canonical `rapp-cicd/1-release` payload identifying one immutable candidate.\n**serving lineage** — the sequence of qualified release identities that have received user traffic;\nthe currently served release is immutable even while a separate candidate lineage grows.\n**deployment cell** — an independently observable and isolatable runtime failure domain governed by\n`rapp-deploy/1`.\n\n## 4. Canonicalization (L1)\n`canonical(v)` is the UTF-8 byte string produced by **[RFC 8785] JCS** for the value `v`, defined **only**\nover I-JSON [RFC 7493]. JCS fixes member-name ordering (UTF-16 code-unit), string escaping, and number\nserialization (ECMAScript `Number::toString`, [ECMA-262]); there is no insignificant whitespace and no\nbyte-order mark.\n\n**RAPP input-domain profile (parse-side interoperability — this is a RAPP rule, not a JCS mandate).** An\nimplementation **MUST** refuse (never repair) any JSON value that, at any depth, contains: (a) duplicate\nmember names in one object; (b) an unpaired UTF-16 surrogate in any string; (c) a number token that does\nnot survive the binary64 round-trip — let `d` be the token's nearest binary64 value under `roundTiesToEven`\n(the IEEE-754 default; ±∞ are admissible results); the token is refused iff `d` is not finite, or the\n[RFC 8785] serialization of `d` (ECMA-262 `Number::toString`) denotes a different mathematical value than\nthe token (so `0.1` is accepted — it round-trips — while `9007199254740993` and `1e999` (→ +∞) are refused); (d) canonical form exceeding 1 MiB or JSON nesting depth\nexceeding 64 (the root value is depth 1; each nested object/array adds 1). Refusal is whole (§7.5-style),\nnever partial.\n\n**No normalization.** RAPP applies **no** Unicode normalization when hashing, storing, or re-emitting an\nexisting value; strings are code-point sequences preserved verbatim and equality everywhere is code-point\nequality (no canonical-equivalence matching). A producer creating a **new** human-or-identifier string\n(slug, kind, label, `payload` object key) **MUST** emit it in Unicode NFC.\n\n> **Migration note (drift C4):** the `twin`/`rapp-body` `_frame.mjs::canonicalize()` (sorted-key\n> `JSON.stringify`) coincides with JCS only for string-only payloads; it **MUST** be replaced by the JCS\n> implementation of record, imported (not re-typed) by every repo that content-addresses.\n\n## 5. Content addressing (L1) — domain-separated\nEvery hash is **domain-separated** (git's `type\\0`, Nix's tagged store — collisions across address spaces\nare made unconstructible):\n```\nH(space, v) = lowercase_hex( SHA-256( utf8(space) || 0x0A || canonical(v) ) )     ; v a value (§4)\nHb(space, b) = lowercase_hex( SHA-256( utf8(space) || 0x0A || b ) )                ; b raw octets\n```\n`space` is an exact ASCII tag, none containing `0x0A`: `\"rapp/1:particle\"`, `\"rapp/1:wave\"`, `\"rapp/1:egg\"`,\n`\"rapp/1:egg-manifest\"`, `\"rapp/1:rappid\"`, `\"rapp/1:grail\"`, `\"rapp/1:seal\"`,\n`\"rapp/1:sealed-aad\"`, `\"rapp/1:sealed-key-request\"`. A tag is used by either `H` or `Hb`, never\nboth. Output is always exactly 64 lowercase hex, **never truncated or uppercased**. Two values\nare treated as the same object iff their same-space hashes are equal; SHA-256 collision resistance\n[FIPS 180-4] is a security assumption of this standard (§14). A `name/X.Y` label is never identity — only\na hash is. A bare 64-hex is meaningful **only** within its space; an implementation **MUST NOT** dereference\na hash from one space as an object of another, and content-addressed stores **MUST** key by `(space, hash)`.\n\n## 6. Identity — the rappid (L2)\n### 6.1 Grammar (case-sensitive, [RFC 7405])\n```abnf\nrappid    = %s\"rappid:@\" owner \"/\" slug \":\" hash\nowner     = lclabel                       ; the lowercase GitHub login (1-39 chars)\nslug      = lclabel                        ; 1-100 chars\nlclabel   = lcalnum *( [\"-\"] lcalnum )     ; no leading/trailing/adjacent hyphen\nlcalnum   = LCALPHA / DIGIT\nLCALPHA   = %x61-7A                         ; a-z\nhash      = 64HEXDIGLC\nHEXDIGLC  = DIGIT / %x61-66                 ; 0-9 a-f\n```\n`owner` **MUST** be the lowercase form of the GitHub login (logins are case-insensitive; display casing is\npresentation, never identity). Lengths are normative: `owner` 1–39, `slug` 1–100; an implementation\n**MUST** refuse longer. This self-locating form is the **only** conformant rappid; `rappid:<slug>:<hash>`,\n`rappid:v2:…`, bare UUIDs, `moment:`/name-hash derivations are legacy and **MUST** be migrated out\n(Art. III), not read forever.\n\n### 6.1.1 stream_id and kind grammar\n```abnf\nstream_id   = memory-stream / body-stream / swarm-stream\nmemory-stream = rappid \":\" instance      ; one organism instance's memory\nbody-stream   = rappid                    ; an organism's biography\nswarm-stream  = %s\"net:\" lclabel          ; a planetary-wire stream\ninstance      = lclabel                   ; 1-64 chars\nkind          = lclabel \".\" lclabel       ; each label 1-64 chars\n```\nA `kind` string carries **no intrinsic family**; the §13 registry binds each registered `kind` to exactly\none family. Membership is tested by exact-match against the registry — never prefix inference, never wildcards.\n\n### 6.2 Minting (mint-once)\nThe 64-hex tail is minted **exactly once** per identity, then immutable:\n- **keyless:** `tail = Hb(\"rapp/1:rappid\", uuid4_octets)`, where `uuid4_octets` is the 16-octet binary\n  UUIDv4 [RFC 9562] §5.4 (field/byte order per §4 of that RFC).\n- **keyed:** `tail = Hb(\"rapp/1:rappid\", SPKI_DER)`, the DER `SubjectPublicKeyInfo` [RFC 5280] of the master key.\n\nA producer **MUST NOT** derive the tail from owner/slug or any name (`sha256(\"owner/slug\")` is prohibited —\ndrift ID-01/C3). On read of an existing `rappid.json` an implementation **MUST** reuse the stored tail\n(canonicalize-on-read) and **MUST NOT** re-mint — with exactly one mechanism: the owner-authorized\n**re-anchor** (§6.3), which mints a fresh 64-hex tail once per authorization and records the superseded id\nin `_migrated_from`. Re-anchor is lawful in exactly three cases: (a) a 128→256-bit provisional upgrade\n(§6.3); (b) §10 key rotation or compromise; (c) migrating a pre-rev-3 keyed tail minted with the un-tagged\n`sha256(SPKI)` formula (which fails §10 discovery and **MUST** be re-anchored like a provisional identity).\n\n### 6.3 Canonicalization on read; provisional identifiers\n`canonicalize_rappid(s)` restructures any legacy form into §6.1, **preserving the existing hash** (never\ninventing one). A restructured identifier whose tail is not exactly 64 lowercase hex (e.g. a legacy 32-hex\ntail) is **provisional**: it exists only inside the reading process and **MUST NOT** appear in any emitted\nframe, `stream_id`, egg, or registry entry. The one-time owner-authorized 128→256-bit re-anchor mints a\nfresh 64-hex, records the old id in `_migrated_from`, and is the only way a provisional identity becomes\nusable. A provisional identifier found in a stored artifact is a drift finding (Art. III). Re-anchor is the\nsingle re-mint mechanism (§6.2), lawful only in the enumerated cases: provisional 128→256-bit upgrade,\n§10 key rotation/compromise, and pre-rev-3 un-tagged-`sha256(SPKI)` keyed-tail migration.\n\n**A re-anchor is valid only with a verifiable authorization** — a self-asserted `_migrated_from` is\ninsufficient (it would let anyone hijack an identity). A re-anchor **MUST** be recorded as an owner-signed\n§13.3 **re-anchor record** `{old_rappid, new_rappid, case, utc, sig, old_key_sig?}`; a consumer **MUST**\nrefuse a `new_rappid` (and treat `_migrated_from` as drift) unless that record is present and:\n- `case:\"rotation\"` (uncompromised): `old_key_sig` (a §10 JWS by the **old** key) verifies — proof of\n  continuity;\n- `case:\"compromise\"`: `old_key_sig` is waived but a §10 **tombstone** for `old_rappid` is registered in the\n  same append;\n- `case:\"tag-migrate\"` (pre-rev-3 keyed tail): the verifier checks `lowercase_hex(SHA-256(SPKI_DER_old))` ==\n  the old tail;\n- `case:\"upgrade\"` (provisional 128→256): the old provisional id resolved to this owner at read time.\nEach mints one fresh tail. The **estate_owner's own** re-anchor record **MUST** be signed by the outgoing\n`estate_owner` key (§13.2); root-key compromise is recovered only by out-of-band re-anchoring (§13.1).\n\n## 7. The Frame (L4)\n### 7.1 The envelope — exactly eleven keys\n```json\n{\n  \"spec\":         \"rapp/1\",\n  \"kind\":         \"<klabel.klabel>\",\n  \"stream_id\":    \"<stream_id>\",\n  \"seq\":          <uint53>,\n  \"utc\":          \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"payload\":      { },\n  \"payload_hash\": \"<64hex>\",\n  \"frame_hash\":   \"<64hex>\",\n  \"prev\":         \"<64hex|null>\",\n  \"prev_wave\":    \"<64hex|null>\",\n  \"sig\":          \"<jws|null>\"\n}\n```\n- **`spec` MUST be the exact string `\"rapp/1\"`** in every frame. `rapp-frame/2.0`/`2.1` are legacy tokens\n  and **MUST NOT** be emitted. Any revision changing the key set, any field's grammar, or either hash rule\n  **MUST** change this token and land an Art. III total migration; revisions adding only new registered\n  `kind`s/registry entries keep the token (Fed. Const. Art. II).\n- **Exactly these eleven keys, always present**, none missing, none extra. A field that does not apply is\n  present with value `null` (`prev`/`prev_wave` at genesis and on non-swarm streams; `sig` when unsigned) — never omitted,\n  because [RFC 8785] hashes `null` and an absent key differently. Extra or missing keys are refused (§7.5).\n- **`payload` MUST be a JSON object** (possibly empty `{}`); never `null`, array, string, number, or bool.\n- `seq` is `uint53` (§7.4). A producer **MUST NOT** emit a frame whose canonical form exceeds 1 MiB or\n  nesting depth 64 (§4).\n\n### 7.2 Kind families (one envelope, registry-bound families)\n| family | example registered kinds | `stream_id` form | logs |\n|---|---|---|---|\n| `memory` | `memory.chat-turn`, `memory.tool-call`, `memory.save`, `memory.reconstructed` | memory-stream | one organism's life |\n| `swarm`  | `swarm.guidance`, `swarm.echo`, `swarm.telemetry`, `swarm.reconstructed` | swarm-stream | the planetary wire |\n| `body`   | `body.pulse`, `body.twin-pulse`, `body.reconstructed`, `body.re-genesis` | body-stream | an organism's biography |\nEach family also has a `*.re-genesis` kind (`memory.re-genesis`, `swarm.re-genesis`, `body.re-genesis`)\nused only by §12.1. The family is **not** the kind's prefix — it is the §13 registry binding (so\n`body.twin-pulse` is family `body`). Adding a family or event is a new registered `kind` on the **same** envelope (Art. IV), never a\nnew frame type. A frame's `kind` family **MUST** be compatible with its `stream_id` form (table column 3).\n\n### 7.3 Particle and wave (the unification)\nA frame carries **both** of its domain-separated addresses; a reader collapses it to whichever it needs.\nComputed in order:\n- **particle** — `payload_hash = H(\"rapp/1:particle\", payload)`. The **worldline identity and chain link**.\n- **wave** — `frame_hash = H(\"rapp/1:wave\", frame \\ {frame_hash, sig})` — the frame with **exactly** the\n  `frame_hash` and `sig` keys removed, all nine remaining keys (including `payload_hash`) present.\nBecause `payload_hash` is in the wave pre-image, `frame_hash` attests the particle; because only\n`frame_hash` (cannot hash itself) and `sig` (signs the result) are removed, the pre-image is unambiguous\nand non-circular. Both hashes are always present (never `null`).\n\n### 7.4 Chaining, time, and merge order\n- **`utc`** **MUST** be exactly the 24-byte form `YYYY-MM-DDTHH:MM:SS.mmmZ` — uppercase `T`/`Z`, exactly\n  three fractional digits, no numeric offset; the seconds field **MUST NOT** be `60` (a leap second clamps\n  to `59.999`). All `utc` comparisons are **bytewise** over this fixed form (identical to chronological order).\n- **Worldline chain (particle):** the **genesis** frame has `seq`=0 and `prev`=null; every later frame has\n  `seq` = predecessor's `seq`+1 (contiguous) and `prev` = predecessor's `payload_hash`. `seq` is `uint53`\n  (JSON integer, 0 ≤ seq ≤ 2^53−1, no fraction/exponent; a stream nearing 2^53−1 converges by re-genesis).\n- **Wire chain (wave):** `prev_wave` **MUST** be non-null **iff** `stream_id` is a swarm-stream **and**\n  `seq` > 0, in which case it equals the predecessor's `frame_hash`; in every other frame (all memory/body\n  streams, every genesis) it **MUST** be `null`. (Presence is a function of stream family, not transport.)\n- A frame is **immutable**: a new state is a new frame at a new hash; the head pointer (§7.6) re-points.\n- **Cross-stream merge order** (Dream-Catcher) is the total order: ascending `utc` (bytewise), ties broken\n  by ascending `frame_hash` (bytewise); no further ties are possible (§5).\n\n### 7.5 Verification (the complete consumer checklist)\nBefore accepting a frame, a consumer **MUST**, in order, **refuse** (never repair/reparent) on any failure:\n1. **Shape & types:** exactly the eleven §7.1 keys; `spec`==`\"rapp/1\"`; `kind` a string matching §6.1.1\n   ABNF and registered (§13); `stream_id` a string matching §6.1.1; `seq` a `uint53`; `utc` matching the\n   §7.4 fixed form **and** a calendar-valid [RFC 3339] `date-time` (so `2026-13-45T25:61:61.999Z` is\n   refused); `payload` a JSON object; `payload_hash`/`frame_hash` `64HEXDIGLC`; `prev`/`prev_wave` each\n   `null` or `64HEXDIGLC`; `sig` `null` or a §10 JWS string.\n1a. **Stream binding:** `frame.stream_id` **MUST** byte-equal the identifier of the stream being extended\n   or read (its declared `stream_id` at the head pointer / repo path of record). A genesis frame is\n   accepted only for the stream it names. (Defeats cross-stream genesis/segment replay — §14.)\n2. **Particle:** `payload_hash` == `H(\"rapp/1:particle\", payload)`.\n3. **Wave:** `frame_hash` == `H(\"rapp/1:wave\", frame \\ {frame_hash, sig})`.\n4. **Chain:** `seq`==head.`seq`+1 and `prev`==head.`payload_hash` (or `seq`==0 ∧ `prev`==null at genesis);\n   `utc` ≥ head.`utc` (bytewise).\n5. **Wire:** if `stream_id` is a swarm-stream and `seq`>0, `prev_wave`==head.`frame_hash`; else\n   `prev_wave`==null.\n6. **Signature:** if `sig`≠null, verify per §10 (present-but-invalid is refusal); a swarm-stream frame with\n   `sig`==null is refused (§8/§10).\nSteps 1–5 are **time-independent** (kind lookups only append, §13), so a frame passing them passes forever;\nstep 6 alone may flip pass→fail when a §10 tombstone with `revoked_utc` ≤ the frame's `utc` is later\nregistered — the one time-dependent check.\n\n### 7.6 Heads and forks\nA stream's **head** is the frame with the greatest verified `seq` descending from its registered genesis\n(§13). A consumer **MUST** persist, per stream, the highest `(seq, frame_hash)` it verified and **MUST**\nrefuse any presented head with lower `seq`, or a different `frame_hash` at an already-verified `seq` (no\nrollback, no silent reorg). Two distinct valid frames with equal `stream_id`, `seq`, and `prev` are a\n**fork**: a consumer **MUST** refuse both branches past the fork point and surface a drift finding; only\nthe owner resolves a fork (Art. X), by re-genesis (§12.1) if needed.\n\n**Exception (re-genesis head reset).** The no-rollback rule above refuses a lower-`seq` head — but a\nlegitimate §12.1 re-genesis presents a new genesis at `seq`=0. When (and only when) the §13 registry maps a\n`stream_id` to a new genesis `frame_hash` (§12.1 step 3), a consumer **MUST** verify that registered\ngenesis (§7.5) and then **reset** its persisted head for that `stream_id` to it. Only a registry-published\ngenesis authorizes a reset; any other lower-`seq` head remains a refused rollback.\n\n## 8. The Wire (L3)\nAll interaction rides one of exactly two forms:\n1. **Synchronous — `POST /chat`, `application/json` both ways.** Request: `user_input` (string, REQUIRED);\n   `session_id` (string, OPTIONAL — omit to start a session); `idempotency_key` (string, OPTIONAL — a repeat\n   with the same key returns the original response, not a new turn or duplicate session; scoped to\n   `session_id` when present, else to the key alone so session-creation is also de-duplicated); unrecognized members **MUST** be\n   ignored, never refused. Success: HTTP 200 with **exactly** `{response:string, agent_logs:[string],\n   session_id:string}` (no extra members). An unknown `session_id`, a refusal, or a malformed request\n   **MUST** be HTTP 422, `{error:{code:string, step:string|null}}` where `code` is a §13-registered error\n   code (e.g. `\"unknown-session\"`) and `step` is the failing §7.5 step as a string — one of\n   `\"1\",\"1a\",\"2\",\"3\",\"4\",\"5\",\"6\"` — or `null`. No other shape is conformant. New capability is a new agent\n   behind `/chat`, never a sibling REST route.\n2. **Asynchronous — an append-only frame (§7) published to a stream** (a repo path, an `events/` log). A\n   frame on a **swarm-stream MUST** carry `sig`≠null (§10); memory/body-stream frames **MAY** be unsigned.\n   Any *history* is safe to read given a trusted head (§14); the hash chain (§5) makes tampering\n   detectable.\n\n## 9. The Egg (L5) — the single egg spec of record\nAn **egg** is a cartridge packing a unit of the estate. **RAPP §9 is the one egg spec of record** (it\nsubsumes and retires `EGG_FAMILY.md`, `NEIGHBORHOOD_EGG_SPEC.md`, `ESTATE_SPEC.md`, `rappterbook/EGG_SPEC.md`,\nand the rest — drift C7). No other document may re-specify eggs; they cite this section.\n\n### 9.1 Container, manifest, and egg address\nAn egg is either a JSON object (`invite`/`session` variants) or a ZIP whose root is `manifest.json` (tree\nvariants). The manifest is a §4 value with exactly these members:\n```json\n{ \"schema\": \"rapp/1-egg\", \"variant\": \"<variant>\", \"rappid\": \"<§6.1 rappid>\",\n  \"created_utc\": \"<§7.4 utc>\", \"contents\": [ {\"path\":\"<rel>\",\"hash\":\"<64hex>\"}, … ], \"payload\": { },\n  \"sig\": \"<jws|null>\" }\n```\n- `contents` **MUST** list every packed file **except `manifest.json` itself**, exactly once each, with\n  `hash = Hb(\"rapp/1:egg\", file_octets)` (§5) over the raw stored octets. `contents` is **always present**;\n  for JSON (pointer/session) variants it **MUST** be exactly `[]`.\n- `path` **MUST** be a relative POSIX path: `/`-separated NFC UTF-8 segments, no `.`/`..` segment, no\n  leading `/`, no backslash, no Windows drive-qualified first segment (`ALPHA \":\"`), no duplicate `path`\n  in one manifest. A segment **MUST NOT** end in a period/space, contain `:`, contain a C0 control, or have\n  a case-insensitive basename equal to `CON`, `PRN`, `AUX`, `NUL`, `COM1`–`COM9`, or `LPT1`–`LPT9`.\n  `contents` **MUST** be sorted ascending\n  by the UTF-8 bytes of `path`.\n- `payload` is a §4 object (variant-specific). `sig` is a §10 JWS over `canonical(manifest \\ {sig})`, or\n  `null`. For the `invite` variant `sig` is REQUIRED and **MUST** verify with `kid` in the §13.2 estate-owner\n  succession (invites are estate-issued; a `sig` by any other key, even a validly registered one, is\n  refused — otherwise an attacker mints a fresh rappid and forges invites). For other variants a non-null\n  `sig` **MUST** verify per §10 with `kid` == a keyed rappid the consumer resolves via §13; a consumer\n  presented a signed egg **MUST** verify it.\n- **The egg's one §5 address is** `egg_hash = H(\"rapp/1:egg-manifest\", manifest \\ {sig})` — the manifest with\n  exactly the `sig` key removed (mirroring §7.3's wave rule: `sig` authenticates the egg, `egg_hash` names\n  it, so re-signing never changes identity). Stores key eggs by `(\"rapp/1:egg-manifest\", egg_hash)`.\n  (`\"rapp/1:egg\"` addresses file octets; `\"rapp/1:egg-manifest\"` addresses the egg as a whole.)\n- **Container determinism.** A ZIP variant **MUST** use compression method `stored` (0) for **every** entry\n  — no deflate in any variant (deflate is library-dependent, so it cannot be byte-reproducible; transport\n  compression, if any, wraps the egg and is not the egg). Entries appear in `contents` order with\n  `manifest.json` first; the `manifest.json` entry's octets **MUST** be exactly `canonical(manifest)`; all\n  timestamps `1980-01-01 00:00:00`; no extra fields; UTF-8 filename flag set; `contents[].hash` is over the\n  file octets (identical to the archive octets under method 0). A JSON-variant egg's serialized form\n  **MUST** be exactly `canonical(manifest)`. Two conformant packers of the **same manifest value** thus emit\n  byte-identical eggs.\n\n### 9.2 Variants (the ratified set — closes EGG-01)\n| variant | container | packs | required members |\n|---|---|---|---|\n| `organism` | ZIP | a full brainstem instance | contents (sorted) MUST include `rappid.json`, `soul.md`; MAY include `agents/*`, `organs/*`, memory files |\n| `rapplication` | ZIP | one rapp | contents MUST include `rappid.json` and exactly one `agent.py` at the root (the agent of record); MAY include one `ui.html` and files under `state/` |\n| `session` | JSON | one runtime + transcript | `payload` = `{runtime:<string>, transcript:[<object>]}`; contents `[]` |\n| `invite` | JSON | a QR-sized pointer (**no packed files**) | `payload` = `{target_rappid:<rappid>, target_url:<string>, target_kind:(\"neighborhood\" / \"estate\")}`; contents `[]`; `sig` REQUIRED |\n| `neighborhood` | ZIP | several organisms meant to live together | `payload` = `{members:[<rappid>,…]}`; contents = one sub-egg per member, named `<owner>--<slug>.egg` at the root, matched by the sub-egg manifest's `rappid` == the `payload.members[]` entry |\n| `estate` | ZIP | several neighborhoods | `payload` = `{neighborhoods:[<rappid>,…]}`; contents = one sub-egg per neighborhood, named `<owner>--<slug>.egg` at root, matched by sub-egg `rappid` |\n| `sealed` | ZIP | publicly mirrorable ciphertext with scoped key release | contents MUST be exactly `ciphertext.bin`; payload is the closed `rapp-sealed-artifact/1` profile in §9.2.1; `sig` REQUIRED |\n\nThe QR-sized invite that caused EGG-01 is the **`invite`** variant: a signed pointer object, not a\nmember-packing `neighborhood` egg. The banned legacy stamps (`brainstem-egg/2.3-neighborhood`,\n`neighborhood-egg/1.0`) migrate to `{schema:\"rapp/1-egg\", variant:\"invite\" / \"neighborhood\"}` (Art. III).\n\n### 9.2.1 Sealed artifact profile\n\nThe `sealed` variant lets any unauthenticated mirror, including a commit-pinned\n`raw.githubusercontent.com` URL, distribute an encrypted artifact globally without distributing its\ndecryption key.\n\nThe public bytes are **ciphertext, not access control**. Bytecode or obfuscation alone provides no\nconfidentiality. A conformant producer **MUST** use a random 256-bit data-encryption key (DEK) per artifact,\n**MUST NOT** embed that DEK or a shared master key in the egg/client/URL, and **MUST NOT** place a password\nin a URL. A password, passkey, device assertion, or account credential may authenticate to the key service;\nit is not the artifact encryption key.\n\nThe ZIP contents are exactly one file:\n\n```text\nciphertext.bin = AES-256-GCM ciphertext || 16-byte authentication tag\n```\n\nThe manifest `payload` has exactly:\n\n```json\n{\n  \"schema\": \"rapp-sealed-artifact/1\",\n  \"cipher\": \"A256GCM\",\n  \"nonce\": \"<12 bytes, unpadded base64url>\",\n  \"plaintext_commitment\": \"<64hex>\",\n  \"plaintext_bytes\": 1234,\n  \"media_type\": \"application/wasm\",\n  \"key_id\": \"<64hex>\",\n  \"key_service_rappid\": \"rappid:@owner/key-service:64hex\",\n  \"key_service_url\": \"https://keys.example.com/chat\",\n  \"access\": \"scoped-key-release\",\n  \"aad_hash\": \"<64hex>\"\n}\n```\n\n`plaintext_commitment` is a keyed commitment that cannot be tested without the DEK:\n\n```text\nprk = HMAC-SHA-256(32 zero octets, DEK)\ncommitment_key = HMAC-SHA-256(prk, utf8(\"rapp/1:sealed-commitment\") || 0x01)\nplaintext_commitment = lowercase_hex(HMAC-SHA-256(commitment_key, plaintext_octets))\n```\n\nThis is the [RFC 5869] HKDF-Extract/HKDF-Expand construction with an empty salt, one 32-byte output block,\nand the exact info string `rapp/1:sealed-commitment`. The commitment is public but does not permit an\noffline dictionary attack without the random 256-bit DEK.\n\nThe exact authenticated-data descriptor is:\n\n```json\n{\n  \"schema\": \"rapp-sealed-artifact/1\",\n  \"artifact_rappid\": \"<manifest.rappid>\",\n  \"created_utc\": \"<manifest.created_utc>\",\n  \"key_id\": \"<payload.key_id>\",\n  \"plaintext_commitment\": \"<payload.plaintext_commitment>\",\n  \"plaintext_bytes\": 1234,\n  \"media_type\": \"<payload.media_type>\"\n}\n```\n\n`aad_hash = H(\"rapp/1:sealed-aad\", descriptor)`, and `canonical(descriptor)` is supplied as AES-GCM\nadditional authenticated data. `nonce` decodes to exactly 12 bytes. `plaintext_bytes` is an integer from\nzero through `2^30` (1 GiB), a RAPP safety ceiling below both the [NIST SP 800-38D] per-invocation limit\nand the deterministic non-ZIP64 container boundary.\n`ciphertext.bin` length is exactly `plaintext_bytes + 16`. The sealed egg's manifest signature is REQUIRED\nand verifies per §10 with `kid` exactly equal to `manifest.rappid`. A sealed artifact therefore uses a\nkeyed §6.2 rappid controlled by its authorized publisher; another valid registry key cannot sign on its\nbehalf.\n\n`key_service_rappid` identifies the RAPP organism authorizing key release. `key_service_url` is its absolute\nHTTPS §8 `POST /chat` URL and **MUST** end in `/chat`. The URL is location, not authority: the service\nresponse is accepted only when its signatures and identifiers bind to `key_service_rappid`.\n\nThe caller sends the following canonical JSON object as the `user_input` string:\n\n```json\n{\n  \"schema\": \"rapp-sealed-key-request/1\",\n  \"egg_hash\": \"<64hex>\",\n  \"key_id\": \"<64hex>\",\n  \"recipient_rappid\": \"rappid:@owner/device:64hex\",\n  \"recipient_spki_der_b64\": \"<standard base64>\",\n  \"request_nonce\": \"<64hex>\",\n  \"expires_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"sig\": \"<recipient detached JWS>\"\n}\n```\n\n`sig` is over `canonical(request \\ {sig})` and verifies under `recipient_rappid`; `egg_hash` is the §9.1\nsealed egg address. The key service verifies entitlement, exact `(egg_hash,key_id)`, request expiry,\nrecipient key binding, and nonce non-reuse.\n\nThe §8 `response` string is canonical JSON:\n\n```json\n{\n  \"schema\": \"rapp-sealed-key-release/1\",\n  \"egg_hash\": \"<request.egg_hash>\",\n  \"key_id\": \"<request.key_id>\",\n  \"recipient_rappid\": \"<request.recipient_rappid>\",\n  \"request_hash\": \"<H('rapp/1:sealed-key-request', request without sig)>\",\n  \"wrap_alg\": \"ECDH-ES+A256KW\",\n  \"wrapped_key_jwe\": \"<JWE Compact Serialization>\",\n  \"issued_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"expires_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"service_sig\": \"<key-service detached JWS>\"\n}\n```\n\n`service_sig` is over `canonical(release \\ {service_sig})` and verifies under `key_service_rappid`.\n`wrapped_key_jwe` uses [RFC 7516] with `alg:\"ECDH-ES+A256KW\"` and `enc:\"A256GCM\"` for the declared\nrecipient SPKI. The service **MUST NOT** return a global raw DEK. Authorization, expiry, device scope, and\nkey rotation are service policy recorded in signed frames, not fields that alter the sealed egg's content\naddress.\n\nA mirror URL **SHOULD** be immutable (for GitHub Raw, pin a commit SHA rather than a moving branch). URL\nsecrecy is never assumed: integrity comes from the egg address and signature, confidentiality from\nAES-GCM, and use authorization from scoped key release.\n\nRevocation prevents future key release. It cannot erase ciphertext or plaintext already downloaded and\ndecrypted by an authorized recipient. A conformant product **MUST** state this limit plainly. It also\n**MUST NOT** claim that encrypted bytecode cannot be inspected after decryption; legal/license controls and\nbounded server authority remain separate from cryptographic confidentiality.\n\n### 9.3 Conformance\n- **Producer** **MUST** emit only `schema:\"rapp/1-egg\"` with a variant from §9.2, a §6.1 rappid, and, for\n  ZIP variants, a `contents` list whose every hash verifies. It **MUST NOT** emit any legacy egg schema.\n- **Consumer** **MUST** read every §9.2 variant, dispatch on `variant`, verify **integrity then viability** —\n  (0) the manifest is a §4 value satisfying **every §9.1 rule** — exact member set, `path` grammar (no `..`,\n  no leading `/`, no backslash), no duplicate paths, sort order, and for ZIP variants the archive entry set\n  equals `contents` ∪ {`manifest.json`} in the §9.1 deterministic order (this is the zip-slip defense; an\n  unenforced path grammar defends nothing); (1) every `contents[].hash` recomputes per §5; (2) the variant's\n  §9.2 structural requirements hold — and refuse whole on any failure; it **MUST NOT** reparent on transport.\n\n### 9.4 Instantiation — instance identity and `grown_from` lineage (rev-6; closes the hatch seam)\nAn egg names an **artifact**; a hatch creates an **instance**. Rev-5 specified packing and reading but\nleft instantiation identity unwritten, so every implementation had to invent its own — this section is\nthat missing word.\n\n- The `rappid` in a packed egg's `rappid.json` (§9.2) names the **artifact**. Every hatch of the same\n  egg reads the **same** artifact identity (§6.2 canonicalize-on-read); re-minting it on hatch is\n  prohibited (§6.2).\n- A consumer that instantiates an egg into a live installation **MUST** mint a **fresh §6.2 identity\n  for the instance**, exactly once, at first boot — from entropy, never derived from the artifact\n  identity, host name, or path. Two instances of one egg share the artifact identity and **MUST NOT**\n  share an instance identity.\n- The instance's identity document **SHOULD** record **`grown_from`**: the §9.1 egg address\n  (64 lowercase hex) of the egg it was instantiated from. `grown_from` is written at mint time and is\n  **immutable** thereafter; it is `null` when the source is unknown; a producer **MUST NOT** fabricate\n  it — lineage is a fact about a birth, never a claim to invent. An instance that cannot say where it\n  came from says `null`.\n- `grown_from` is **lineage, not inheritance**: it confers no authority, no trust, and no §10 key\n  material. A reader **MUST** treat it as an unverified assertion unless the named egg is available and\n  its address recomputes per §9.1/§5.\n- A newly authored artifact produced from one or more existing RAPP objects **MAY** record\n  `crossed_from` in its packaged `rappid.json`. The value is a sorted, duplicate-free array of typed\n  addresses `{space, hash}`, where `space` is `\"rapp/1:particle\"` or `\"rapp/1:egg-manifest\"` and `hash`\n  is 64 lowercase hex. One parent denotes an **offspring**; two or more denote a **cross**. The new\n  artifact **MUST** mint its own §6.2 rappid; parent artifacts and identities remain unchanged.\n  `crossed_from` is lineage only: it transfers no signature authority, ownership, entitlement, secret,\n  or trust. A verifier treats each parent as unverified until the addressed object is available and\n  recomputes in its declared space.\n\n## 10. Trust and signatures (L2)\n`sig` is OPTIONAL on memory/body streams and REQUIRED on swarm streams (§8). Chain integrity comes from the\nhash links (§5), not signatures. When present, `sig` **MUST** be JWS Compact Serialization with **detached,\nunencoded payload** ([RFC 7515] App. F + [RFC 7797]):\n- protected header members are **exactly** `alg` (`\"EdDSA\"` or `\"ES256\"`), `b64` (`false`), `crit`\n  (`[\"b64\"]`), `kid` (signer's §6.1 rappid), no others; the header octets **MUST** be `canonical(header)`\n  (§4 — JCS orders them `alg`, `b64`, `crit`, `kid`, no whitespace);\n- the `sig` string is the detached compact form `BASE64URL(canonical(header)) || \"..\" || BASE64URL(signature)`;\n- JWS signing input = `BASE64URL(canonical(header)) || \".\" || canonical(frame \\ {sig})`;\n- `alg`: `EdDSA`/Ed25519 [RFC 8037] or `ES256` [RFC 7518]; ES256 signers **SHOULD** sign deterministically\n  [RFC 6979] (Ed25519 is deterministic by construction) so signed frame files stay byte-reproducible.\n\n**Key discovery.** A keyed rappid's tail is one-way (`Hb(\"rapp/1:rappid\",SPKI)`). A verifier resolves the\nsigner's SPKI (DER) **from the §13 registry** entry (`rappid` → `spki_der_b64`); the door-of-record\n`rappid.json` is the publication venue the registry entry is generated from, not itself a verification\nsource. The verifier **MUST** check `Hb(\"rapp/1:rappid\", SPKI_DER)` == the rappid's tail and refuse on\nmismatch or registry absence.\n\n**Key lifecycle.** Rotation is an identity re-anchor (§6.3, case `rotation`) with new `tail =\nHb(\"rapp/1:rappid\", newSPKI)` and a §13.3 re-anchor record. A re-anchor **deprecates** the superseded\nrappid's §13 `spki` entry: a verifier **MUST** refuse a `sig` whose `kid` is a superseded rappid on any\nframe with `utc` ≥ the re-anchor record's `utc` (rotation gives forward security; earlier frames verify as\nbefore). Compromise is declared by an owner-signed **tombstone** in the §13 registry `{rappid, revoked_utc}`; a verifier **MUST** refuse any `sig` by a\ntombstoned key on a frame whose `utc` ≥ `revoked_utc`, checking tombstones at verification time (§7.5 step\n6). \"Owner-signed\" means a `sig` verifying with `kid` == the registry's designated `estate_owner` rappid\n(§13). A consumer **MUST NOT** infer authorship from an unsigned frame (keyless rappids assert location,\nnot authorship).\n\n## 11. Conformance classes\n- **Producer:** emits only §4 JCS/I-JSON bytes, §5 domain-separated full-SHA-256 addresses, §6 rappids\n  minted per §6.2, §7.1 eleven-key frames, §9 `rapp/1-egg` variants — and **no legacy form**.\n- **Consumer:** runs the full §7.5 checklist (incl. 1a binding), §9.3 egg verification, §10 signature +\n  key-discovery + tombstone checks, canonicalizes legacy ids on read (§6.3), refuses on any failure, never\n  repairs/reparents/rolls back (§7.6).\n- **Router/Mirror:** invents no endpoints (§8), declares subordination to\n  `kody-w/rapp-1` for protocol semantics, and serves only\n  provenance-stamped hash-matching mirrors. Estate-specific product scope is\n  resolved separately through that estate's signed registry and master plan.\n\n### 11.1 Immutable Grail kernel conformance\nAn estate declares a Grail kernel through the exact §13.3 `grail-kernel` entry. Its `release_scope`\nselects the release family to which the pin applies; a registry **MUST** contain at most one\n`grail-kernel` entry for any release scope. Its entry-level `sig`\n**MUST** verify under `declared_by`, which **MUST** be the estate owner in effect at `activated_utc`\n(§13.2); `activated_utc` **MUST NOT** be more than 300 seconds after the verifier's first-seen time for\nthat entry. The pin activates locally when a consumer first accepts an authenticated, non-rollback\nregistry containing that valid declaration. Until then it is structural evidence only. The Grail is\nidentified by `grail_id`, never by a mutable branch, tag, repository name, or product label. Once\nactivated, the pin is a permanent compatibility anchor, not a moving release channel:\n\n1. Every conformance evaluation **MUST** receive `release_scope` from an authenticated owner-controlled\n   release policy, never from candidate bytes or candidate-controlled configuration, then resolve its\n   one `grail_id` exclusively from the activated, persisted §13.3 binding. If the policy repeats\n   `grail_id`, that value is only a consistency assertion and **MUST** byte-equal the registry result; it\n   cannot select or rebind the pin. Every ring and release/deployment stage, including development,\n   qualification, Preprod, installation, and production verification, **MUST** compare the candidate's\n   Grail path to that exact binding, SHA-256, and byte length.\n2. A missing, changed, substituted, or unmeasured Grail byte is `kernel-drift` and **MUST** fail closed.\n   Approval, urgency, compatibility claims, and semantic equivalence cannot waive byte inequality.\n3. A pipeline **MUST NOT** silently restore the pinned file after testing a different file. The exact\n   release-shaped artifact containing the immutable Grail bytes **MUST** itself pass the release gates.\n4. Every gate **MUST** resolve every archive, container, wrapper, environment override, symlink, and\n   filesystem indirection to one regular runtime entry-point file under the immutable release root;\n   refuse links and ambiguous alternatives; verify its bytes; and bind the release digest, resolved\n   entry-point path, `release_scope`, `grail_id`, raw SHA-256, and byte length into its evidence.\n5. Every gate that executes the kernel **MUST** bind verification atomically to execution from a sealed\n   immutable object or snapshot. An already-open descriptor is sufficient only when its backing bytes\n   are under platform-enforced write exclusion for the entire verification-through-consumption interval\n   and the interpreter/loader consumes that exact descriptor without reopening a pathname. An immutable\n   content-addressed release root is sufficient only when no concurrent principal can modify it. A\n   hash-then-path-launch without one of those guarantees is nonconformant. At least one execution gate for\n   every supported production platform **MUST** perform this proof before release approval. Merely\n   carrying an unused matching file is insufficient. A stored transpiled, bundled, generated, or patched\n   derivative is different kernel bytes and requires a new `grail_id`; ordinary interpreter/JIT\n   compilation directly from the pinned bytes is permitted when no alternate stored kernel is selected.\n6. New implementation behavior **MUST** live outside the Grail kernel and **MUST NOT** alter any\n   RAPP-visible canonical form or wire semantic except through the registration and evolution rules of\n   §§7, 9, 12, and 13.\n7. If required behavior cannot be expressed outside the pin, the implementation **MUST** report an\n   incompatibility. It **MUST NOT** edit the Grail and continue under the same identity.\n8. Different kernel bytes produce a different `grail_id` and therefore are a different Grail. A new\n   `grail-kernel` entry may coexist and may name the old `grail_id` as `predecessor`, but it **MUST NOT**\n   overwrite, retag, alias, or redefine the prior Grail. A successor uses a new `release_scope`; an\n   existing scope is never rebound. A non-null `predecessor` **MUST** name an earlier accepted\n   `grail-kernel` entry and **MUST NOT** form a cycle. A registry **MUST** contain at most one\n   `grail-kernel` entry for each `grail_id`.\n9. On first activation a consumer **MUST** persist the full canonical `grail-kernel` entry. Every later\n   accepted registry **MUST** retain that entry byte-for-byte. Removal, mutation, or a second entry for\n   the same `grail_id` is a permanent `kernel-drift` refusal even when `registry_seq` increased.\n\nThis rule governs release topology rather than the §8 wire shape, so it does not add a frame member,\nendpoint, compatibility shim, or alternate `rapp/1` encoding.\n\n### 11.2 Operational conformance profiles\nRAPP/1 defines the substrate. Two subordinate operational profiles define how a production AI changes\nwithout mutating that substrate or the serving system underneath users:\n\n- **RAPP CI/CD** (`rapp-cicd/1`) — `protocols/rapp-cicd/1/SPEC.md`; immutable release capsules,\n  ordered qualification evidence, exact-candidate promotion, Preprod, and rollback/restore proof.\n- **RAPP Deploy** (`rapp-deploy/1`) — `protocols/rapp-deploy/1/SPEC.md`; isolated serving/candidate\n  lineages, cellular rollout, progressive exposure, expiring AI-health evidence, quarantine, and exact\n  rollback.\n\nThe profiles are RAPP/1 applications, not alternate wire versions:\n\n1. Their payloads **MUST** be §4 canonical I-JSON and are identified by\n   `H(\"rapp/1:particle\", payload)`.\n2. Authoritative profile payloads **MUST** travel in signed RAPP/1 frames using a registered compatible\n   kind. Local unsigned files are drafts, fixtures, or caches and cannot authorize promotion or traffic.\n3. They **MUST NOT** add a transport endpoint beside §8 `POST /chat`, redefine any RAPP/1 primitive, or\n   weaken §11.1.\n4. An estate activates a profile through an authenticated §13.3 `protocol` entry pinning its exact\n   repository, path, and SHA-256. A moving branch is discovery, never authority.\n5. A claim of **RAPP production conformance** requires both profiles. Core Producer, Consumer, and\n   Router/Mirror implementations remain conformant without implementing production operations.\n6. Fixed envelope keys carry the safety invariants. Policy-defined check identifiers, component kinds,\n   health objectives, and resilience controls are extension points; adding one does not change the\n   profile token or the RAPP/1 wire.\n7. A consumer **MUST** refuse unknown required policy semantics. It may preserve and relay unknown\n   optional evidence, but may not treat it as satisfying a requirement it does not implement.\n\nThe executable reference validators are `rapp_cicd.py` and `rapp_deploy.py`; controlled profile vectors\nare in `operations_conformance.py`. JSON Schemas define structural shape, while the reference validators\nenforce ordering, identity, temporal, and cross-document rules that JSON Schema cannot express.\n\n## 12. Versioning, evolution, no-legacy\nRAPP is a **living standard** (WHATWG): revised in place, never forked into parallel versions; a `name/X.Y`\nlabel **MUST NOT** ever denote two shapes (Art. II) — a shape change moves the token (§7.1). Published\ncontent-addressed artifacts are **immutable** (SemVer/crates). Within an estate there is **no perpetual\nbackward compatibility** for the estate's own artifacts and retired legacy encodings (Art. III): a change\nto such a form is a **total migration** of every instance + **deletion** of the old form. Sealed re-genesis\nhistory (§12.1) is the retained live-stream exception and is not \"legacy compatibility.\"\n\n**The `rapp/1` wire is frozen (rev-15, Art. 18).** No revision of this standard may change a form a\n`rapp/1` artifact is verified by: canonicalization (§4), the hash function and its tags (§5), the rappid\ngrammar and mint (§6.1, §6.2), the eleven-key envelope and its two addresses (§7.1, §7.3), the consumer\nchecklist (§7.5), the two wire forms and the `/chat` shapes (§8), or the egg container and address (§9.1).\nA change to any of those is not a revision; it moves the token to `rapp/2`, specified beside this\ndocument, and `rapp/1` artifacts keep verifying under this document forever. A consumer **MUST NOT**\nrefuse a `rapp/1` artifact because a later token exists. Everything Art. IV names still grows under\n`rapp/1`: registered kinds, egg variants, error codes, registry entry types, vocabulary, subordinate\nprofiles, and the registry itself. The frozen forms are what a stranger's implementation, written once\nand never updated, relies on; they are the reason an independent implementation can be finished.\n\nImmutable specification-governance history is a separate narrow exception:\nrev-5 through rev-13 anchor frames retain interpretable immutable pointer\npayloads so their ratified normative bytes remain resolvable. They are\nhistorical authority records, not accepted live legacy protocol forms. A\nproducer **MUST NOT** emit the pointer-only revision profile after rev-13.\n\n### 12.1 Re-genesis (converging an immutable chain — one owner-authorized operation)\n1. **Terminal seal:** `seal = Hb(\"rapp/1:seal\", head_octets)`. `head_octets` is the exact octets of the old\n   head's record **as retained under `legacy/`** (step 4): for a one-frame-per-file store, the retired\n   file's full octets; for a line-oriented log, the head's line **excluding** its trailing terminator. The\n   retained `legacy/` artifact is the verification reference for the seal, and retirement **MUST** preserve\n   those octets bit-exact. The step-3 `genesis` registry entry **SHOULD** record the `legacy/` artifact's\n   repo+path so a consumer **MAY** verify the seal against it. (Defined for every legacy shape, including\n   ones that cannot be §7.3-hashed.)\n2. **New genesis:** emit `seq`=0, `prev`=null, `kind` = the registered re-genesis kind **of the stream's\n   family** — `memory.re-genesis`, `swarm.re-genesis`, or `body.re-genesis` (three §13 kinds, used only\n   here) so the frame satisfies §7.2 family↔stream compatibility for any stream — `sig`≠null owner-signed\n   (§10, §13 `estate_owner`), `payload` = `{\"migrated_from\":{\"stream_id\":<old>,\"terminal_seal\":<seal>,\n   \"terminal_seq\":<n>}}` and no other members. A consumer **MUST** treat any `*.re-genesis` kind as the sole\n   re-genesis marker for its family and refuse an unsigned/non-owner one.\n3. **Register (the linearization point):** append a §13.3 `genesis` entry mapping the `stream_id` to the new\n   genesis's `frame_hash`, **and flag every prior `genesis` entry for that `stream_id` `deprecated`** — the\n   first convergence included (it deprecates the creation-time genesis), so exactly one non-deprecated entry\n   always remains. A consumer resolves the current genesis **only** via that sole non-deprecated entry. A\n   **concurrent** second registration fails closed (the append is the linearization point, Art. IX); a\n   later fork/brick (§7.6/§14) is a fresh owner-authorized convergence that appends again and re-deprecates.\n4. **Retire:** move old frames under `legacy/` — retained as immutable sealed history, never served as\n   current, never extended, never read as live chain. No live frame may set `prev`/`prev_wave` to a retired\n   hash (a dangling ref is a drift finding).\n5. Keep the old `stream_id` unless the identity itself re-anchored (§6.3), in which case the registry entry\n   also records `old_stream_id → new_stream_id`.\n6. Two frames with equal `stream_id`+`seq` from different eras are disambiguated **solely** by descent from\n   the current registered genesis. Re-genesis is one-time per convergence; a repeat *of the same\n   convergence* is the concurrent case (step 3, fails closed).\n\n### 12.2 DOGG specification revision chain\n\nThe RAPP/1 revision content is the append-only JSONL stream at\n`anchor/chain.jsonl`. The chain's particle, wave, and predecessor hashes prove\nbyte integrity and linear history; they do **not** authenticate who selected a\nhead or ratified an amendment. Until a separately authenticated RAPP\nregistry/checkpoint is ratified, authority is selected by owner-ratified\nacceptance of a chain snapshot onto protected canonical\n`refs/heads/main` at `https://github.com/kody-w/rapp-1`. A consumer starting\nfrom an out-of-band pinned accepted commit and head frame hash has the same\nimmutable selection evidence. An internally valid fork is not authoritative\nmerely because its hashes verify.\n\nEvery protocol adjustment **MUST** append exactly one valid successor frame:\n\n- `spec` remains `\"rapp/1\"`, the envelope remains exactly eleven keys, and the\n  allowed registered anchor kind is `body.pulse`; this profile does not create\n  a new kind or alter canonicalization, hashing, or registered-kind semantics;\n- `stream_id` remains the bootstrap-pinned anchor stream, `seq` is contiguous,\n  `prev` names the predecessor's `payload_hash`, `prev_wave` and `sig` are\n  `null`, and the applicable §7.5 integrity checks hold;\n- the frame's `frame_hash` is the durable protocol-revision identity.\n  Human names such as `rev-14` are lookup labels/views, never identities.\n\n#### 12.2.1 Immutable bootstrap boundary\n\nVerification begins from the frozen `rapp-anchor-bootstrap/1` profile published\nthrough `anchor/bootstrap/index.json`. The index names a\n`anchor/bootstrap/sha256-<raw-profile-sha256>.json` object and pins the exact\nstdlib verifier at `anchor/bootstrap_verify.py` by raw SHA-256 and byte length.\nThe profile fixes the exact-integer JCS subset and limits, particle/wave\ndomains, eleven frame keys, timestamp/sequence/predecessor rules, canonical\nrepository and protected ref, anchor stream ID, genesis frame and payload\nhashes, `body.pulse` anchor profile, null signature/wave fields, and byte/depth\nlimits needed to verify this chain.\n\nThe content-addressed bootstrap profile is immutable. Changing it requires a\nnew bootstrap schema/version and a new external ratification; mutating\n`rapp-anchor-bootstrap/1` in place is refusal. Its initial authenticity is\nnecessarily external — owner-ratified protected canonical main or an\nout-of-band pinned profile hash/immutable commit — because neither a chain nor\ncode fetched with that chain can circularly authenticate its own parser.\n`rapp.py` remains the complete reference implementation and is cross-checked,\nbut it is not the mutable bootstrap trust pin.\n\n#### 12.2.2 Revision payloads and historical exception\n\nFrames through rev-13 retain their immutable legacy pointer fields:\n`canonical_repo`, a full 40-lowercase-hex `commit`, safe relative\n`normative_path`, raw-file `normative_sha256`, and decimal-string\n`normative_bytes`. A resolver **MUST** construct only an immutable\ncommit-pinned GitHub Raw URL from those fields, fetch the bytes, and verify\nlength and raw SHA-256 before use. A branch or tag name in `commit`, an unsafe\npath, malformed UTF-8, a byte-order mark, or a hash/length mismatch is refusal.\nPath validation occurs on the original string before path-library\nnormalization: empty, absolute, `.`/`..`, empty components, repeated slash,\nleading `./`, trailing slash, backslash, percent-encoded ambiguity, or any\nvalue whose reconstructed POSIX form differs is refused.\nThese pointer payloads are immutable governance history under Article 3's\nnarrow exception; they **MUST NOT** be emitted for rev-14 or later.\n\nRev-14 and each successor using this profile carries all normative text inside\nthe chain frame. Its payload **MUST** include\n`schema:\"rapp-spec-revision/1\"`, a unique `revision`, and both\n`previous_revision` and `previous_normative_sha256` matching the immediate\npredecessor. It preserves the useful legacy fields above, carries the\npublication/ratification metadata defined below, and adds exactly this\n`normative` object:\n\n```json\n{\n  \"media_type\": \"text/markdown; charset=utf-8\",\n  \"text\": \"<exact normative SPEC.md Unicode text>\",\n  \"sha256\": \"<lowercase SHA-256 of text encoded as UTF-8>\",\n  \"bytes\": 123\n}\n```\n\n`normative.text` **MUST** encode as UTF-8 without a byte-order mark;\n`normative.sha256` and `normative.bytes` **MUST** match those exact octets and\nthe corresponding legacy `normative_sha256` and `normative_bytes`. The complete\ncanonical frame remains subject to §4's 1 MiB limit. Inline revisions require\nonly the selected, verified chain bytes once fetched; their commit/path fields\nare immutable provenance, not a second source for normative text.\n\nThe payload's `publication` object, repeated in the beacon and revision index,\nrecords: canonical repository `https://github.com/kody-w/rapp-1`; protected ref\n`refs/heads/main`; selection by owner-ratified acceptance; the accepted\ncanonical-main commit as linearization point; prohibition of history\nreplacement; mandatory rebase/regeneration for a competing append; rev-14\nratification under rev-13 Article 14; application of this chain-append process\nfrom rev-15 onward; and `authenticated_registry_checkpoint:null` until one\nactually exists. This metadata **MUST NOT** be interpreted as a signature or\nauthenticated registry.\n\n#### 12.2.3 Content-addressed publication and resolution\n\nEvery chain frame **MUST** also be published, without a trailing line\nterminator, at:\n\n```text\nanchor/frames/<frame_hash>.json\n```\n\nA fetch through mutable main is discovery only. Given frame hash `F`, a\nstranger may fetch\n`https://raw.githubusercontent.com/kody-w/rapp-1/main/anchor/frames/F.json`,\nparse it under the pinned bootstrap, and accept the object only if its computed\nwave equals `F`. For accepted snapshot commit `C`, the immutable URL is\n`https://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/frames/F.json`.\nWrong content at the correct hash-derived path is refusal.\n\n`anchor/index.json` is a deterministic generated index from `seq`, revision\nlabel, frame hash, and payload hash to those objects. It carries no independent\nauthority: a consumer **MUST** verify each selected object and match the index\nand beacon to the fully verified chain. Resolution by frame hash uses the path\nalgorithm directly; resolution by payload hash or sequence uses the verified\nindex; resolution by revision label is a view over it. The fixed pre-profile\nrev-5 pulses share one historical label, so the `rev-5` view resolves to the\ngreatest matching `seq`, while every pulse remains directly resolvable by\nsequence and hashes.\n\nA consumer **MUST** verify the chain from the bootstrap-pinned genesis before\nusing a revision as selected history. It **MUST** refuse an invalid frame shape,\nparticle, wave, or `prev`; a fork or duplicate `seq`; duplicate frame/payload\nhashes; a duplicate profiled revision; an unsupported schema; a legacy\npointer-only frame after rev-13; malformed UTF-8; normative hash/length drift;\nbootstrap/index/object drift; or an object absent from the selected chain.\n\n`orient.json` is only a beacon to the head. Its sequence, frame hash, payload\nhash, bootstrap/index pins, authority-selection metadata, and every retained\nhead mirror — including `registered_kinds`, vocabulary, operational profiles,\nfoundation, philosophy, and Constitution metadata — **MUST** be regenerated\nfrom and match the verified head. While the beacon schema remains\n`rapp/1-anchor`, `spec.normative_path` **MUST** remain as a compatibility alias\nequal to `spec.materialized_path`. `SPEC.md` **MUST** reproduce the selected\nhead byte-for-byte. The Atom feed and mutable main URLs are discovery only.\n\nMaterialization and immutable-pointer caching **MUST** use bounded reads and\nsame-directory atomic replacement without following a symlink in the\ndestination leaf or path. A symlink, unsafe directory component, oversized\ncache entry, content change during read/write, or compare-and-swap mismatch is\nrefusal; the requested leaf is replaced, never the symlink target.\n\nAfter acceptance, let `C` be the full 40-hex canonical-main commit containing\nthe accepted snapshot. The immutable checkpoint URLs are:\n\n```text\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/chain.jsonl\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/orient.json\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/index.json\n```\n\nThe authority linearization point is the owner-ratified acceptance of `C` onto\nprotected canonical main, not creation of a local frame, a feed event, or a\nhash alone. A stale competing append **MUST** rebase onto the accepted head and\nregenerate. Force-push or history replacement of accepted authority is\nprohibited.\n\n#### 12.2.4 Rev-14 transition and draft replacement\n\nRev-14 is ratified under rev-13 Article 14. Owner acceptance of the prepared\nchange onto canonical protected main makes the final rev-14 frame effective;\nthe new chain-append process governs rev-15 onward. Before that acceptance,\nrev-14 artifacts are unpublished drafts. A later commit in the same\nowner-ratified change may deterministically replace the one unpublished rev-14\ndraft line/object and update dependent hashes, but **MUST** preserve every\nrev-5 through rev-13 line byte-for-byte and **MUST NOT** represent the replaced\ndraft as accepted history.\n\nThe publication generator **MUST** hold one cross-process exclusive lock across\nread, verification, generation, comparison, and publication. Immediately\nbefore replacing `chain.jsonl` it **MUST** re-read and verify the on-disk head\nand compare the complete expected prefix; a stale writer or changed prefix is\nrefused. Supporting content-addressed artifacts are published first, the\nauthority chain is compare-and-swap replaced next, and the beacon is replaced\nlast, with file and parent-directory synchronization. Because the chain is\nauthority content and the beacon is only a derived view, interruption after a\nvalid chain replacement may leave a stale or missing beacon; the next locked\nrun **MUST** deterministically regenerate it from the verified chain rather\nthan refusing the valid head forever.\n\nThis chain and beacon are unsigned. They provide integrity after authority\nselection, not authorship, and implementations **MUST NOT** fabricate a\nsignature or authenticated registry/checkpoint state for them.\n\n## 13. The registry — an estate's signed root of trust (append-only)\nEach estate selects an owner-controlled `canonical_source` for its\n`schema:\"rapp/1-registry\"` document. The kody-w reference estate may publish\nits registry through `kody-w/RAPP` or another owner-authorized location, but\nthat estate instance cannot alter this protocol. Because §7.6 head resets, §10\nkey discovery, tombstone revocation, and ownership all resolve through the\nselected registry, it is the **root of trust for that estate** and is itself\nauthenticated (an unsigned mutable file at the root of the trust graph would\nforge that estate).\n\n### 13.1 Trust anchor and registry authentication\n- The one bootstrap axiom is the **`estate_owner` rappid string** itself: since a keyed tail is\n  `Hb(\"rapp/1:rappid\", SPKI_DER)`, the rappid **is** a self-certifying key fingerprint, distributed\n  out-of-band exactly once (QR, invite, docs) the way a root-CA certificate is.\n- The registry document **MUST** carry a top-level `registry_seq` (uint53) and a detached §10 JWS `sig` over\n  `canonical(registry \\ {sig})` with `kid` = the `estate_owner` rappid. A consumer **MUST** verify this\n  signature against an SPKI whose `Hb(\"rapp/1:rappid\", SPKI_DER)` equals the anchor rappid's tail (the SPKI\n  may travel alongside the registry — the tail check authenticates it) and **MUST** refuse an unsigned or\n  non-verifying registry.\n- **No rollback:** a consumer persists the highest `registry_seq` it verified and refuses any registry with\n  a lower one (mirrors §7.6). **Freshness:** a consumer **MUST** obtain the registry from `canonical_source`\n  or a provenance-stamped (Art. VIII) mirror of it, **SHOULD** refresh before any §7.5-step-6 or §7.6\n  head-reset decision, and **MUST** report a verification made against a registry older than its staleness\n  policy as *stale*, not *clean*.\n\n### 13.2 Owner succession (time-scoped authority)\n\"Owner-signed\" means: the `sig` verifies per §10 **and** `kid` is the estate-owner **in effect at the\nartifact's `utc`** — the current `estate_owner` or any predecessor reachable through the registry's\nre-anchor records (§13.3), with the artifact's `utc` inside that owner's tenure `[record.utc, successor.utc)`.\nVerification uses the owner in effect at the artifact's time, **never only the current one** (so a routine\nowner key rotation never invalidates historical re-genesis frames or tombstones). Estate-owner **root-key\ncompromise** is recovered only by re-distributing a new trust anchor out-of-band (§13.1) — it cannot be\nexpressed inside the registry it signs.\n\n### 13.3 Entry types (each a §4 value; document `schema:\"rapp/1-registry\"`)\nThe registry is an I-JSON document; every entry is append-only (never removed/renamed; retirement is a\n`deprecated:true` flag). Entry types and their exact members:\n- **protocol** `{type:\"protocol\", name, spec_repo, spec_path, spec_hash, deprecated}` — an estate\n  adoption pin, never a power to redefine a protocol. An entry with `name:\"rapp/1\"` that is used for a\n  current-conformance claim **MUST** set `spec_repo:\"https://github.com/kody-w/rapp-1\"`,\n  `spec_path:\"SPEC.md\"`, and `spec_hash` to a normative SHA-256 published by a verified frame in this\n  repository's anchor chain. A historical RAPP/1 pin may be retained only as `deprecated:true`; it does\n  not override the current anchor. Other protocol entries are subordinate to their own canonical\n  authorities and **MUST NOT** claim the `rapp/1` name or namespace.\n- **kind** `{type:\"kind\", kind, family, deprecated}` (incl. the three `*.re-genesis` kinds)\n- **egg-variant** `{type:\"egg-variant\", variant, deprecated}` · **error-code** `{type:\"error-code\", code}`\n  (both closed namespaces; unregistered value = not conformant)\n- **genesis** `{type:\"genesis\", stream_id, frame_hash, deprecated, old_stream_id?, new_stream_id?}` — **every**\n  stream registers its creation genesis; re-genesis appends a new one and deprecates all prior (§12.1 step 3);\n  §7.6's \"registered genesis\" is the sole non-deprecated `genesis` for a `stream_id`.\n- **spki** `{type:\"spki\", rappid, spki_der_b64, deprecated}` — the §10 key-discovery source.\n- **tombstone** `{type:\"tombstone\", rappid, revoked_utc, sig}`, `sig` owner-signed over `canonical(entry \\ {sig})`.\n- **re-anchor** `{type:\"re-anchor\", old_rappid, new_rappid, case:(\"upgrade\"|\"rotation\"|\"compromise\"|\"tag-migrate\"),\n  utc, sig, old_key_sig?}` — `sig` owner-signed; `old_key_sig` a §10 JWS by the **old** key over\n  `canonical(entry \\ {sig,old_key_sig})`, REQUIRED for `case:\"rotation\"`. This is the normative succession record (§13.2).\n- **grail-kernel** `{type:\"grail-kernel\", release_scope, grail_id, repository, immutable_ref,\n  object_format, commit, path, mode, blob, sha256, size_bytes, activated_utc, predecessor, declared_by,\n  sig}` — exactly these members. `release_scope` is an absolute HTTPS URI selected by the estate owner;\n  no two entries may share it. `grail_id` is\n  `\"grail:\" || Hb(\"rapp/1:grail\", kernel_bytes)`; `repository` is an absolute HTTPS URI;\n  `immutable_ref` is a full `refs/tags/...` name that **MUST** resolve exactly to `commit`;\n  `object_format` is `\"sha1\"` or `\"sha256\"` and fixes the required lowercase hexadecimal length of\n  `commit` and `blob`; `path` at `commit` **MUST** resolve through the repository tree to exactly one\n  regular blob with `mode` `\"100644\"` or `\"100755\"` and object id `blob`;\n  `path` is a relative NFC POSIX path with no empty, `\".\"`, or `\"..\"` component; `sha256` is the raw\n  kernel bytes' 64-lowercase-hex SHA-256; `size_bytes` is their positive `uint53` length;\n  `activated_utc` has the exact §7.4 form; `predecessor` is null or another `grail_id`; `declared_by` is\n  a keyed rappid; and `sig` is a detached §10 JWS whose protected `kid` equals `declared_by`, over\n  `canonical(entry \\ {sig})`. The entry is additionally covered by the registry's §13.1 signature. A\n  consumer verifies the entry signer as the estate owner in effect at `activated_utc`, verifies the\n  referenced bytes, recomputes both hashes, persists the canonical entry on first activation, applies\n  §11.1, and refuses a missing/mutated prior binding, duplicate `grail_id`, or locator whose bytes\n  disagree.\n- **estate_owner** `{type:\"estate_owner\", rappid}` (exactly one non-deprecated) · **master-plan**\n  `{type:\"master-plan\", repo, path}` (Fed. Const. Art. VII).\n\n§7.5 steps 1–5 are time-independent (append-only lookups); **only** step 6 (tombstones) and §13.2 owner\ntenure are time-scoped, and both are monotone given the §13.1 no-rollback rule.\n\n## 14. Security considerations\n- **Integrity:** every object is domain-separated content-addressed (§5); a hostile mirror cannot alter\n  bytes without breaking the hash, so *history is safe given a trusted head*.\n- **Head freshness is not self-certifying:** the chain authenticates history, not which head is current; a\n  hostile mirror may serve a stale/forked head. Consumers counter with the §7.6 monotonic-head rule; swarm\n  heads **SHOULD** be owner-signed.\n- **Cross-stream replay:** without §7.5 step 1a, any genesis/segment of stream A replays as stream B (seq=0,\n  prev=null always pass). Step 1a's stream binding is mandatory.\n- **Address-space confusion:** §5 domain tags make a particle, wave, egg, or rappid tail with equal hex\n  non-interchangeable; stores key by `(space, hash)`.\n- **Canonicalization attacks:** the §4 I-JSON input-domain profile (no duplicate keys, no lone surrogates,\n  exact binary64, no normalization ambiguity) removes hash-splitting and NFC-twin vectors.\n- **Identity forgery / key compromise:** authorship requires a keyed rappid + valid §10 `sig`; rotation is\n  §6.3 re-anchor (verifiable authorization, §6.3/§13.3 — a self-asserted `_migrated_from` is refused);\n  compromise is a §13 tombstone enforced at verify time. Because a tombstone gates on the frame's\n  producer-controlled `utc`, a compromised key can still emit frames stamped just below `revoked_utc`; after\n  a compromise the owner **SHOULD** advance affected stream heads (or re-genesis) past `revoked_utc`.\n- **Root of trust:** the registry is the estate's signed root (§13.1); it is authenticated by an owner\n  signature anchored to the out-of-band `estate_owner` rappid fingerprint, `registry_seq`-monotonic against\n  rollback, and freshness-checked (a stale registry silently un-revokes keys and hides re-geneses).\n- **Producer-controlled `utc` (DoS/merge bias):** a future-dated head can brick a stream (successors refused\n  as earlier) and bias UTC-first merges. A consumer **SHOULD** refuse a frame whose `utc` exceeds receipt\n  time by >300 s, and adversarial-scope merges **SHOULD** rank by `min(utc, first-seen)`; a bricked stream\n  converges by re-genesis (§12.1).\n- **Sealed-artifact limits:** a public mirror sees ciphertext and metadata. AES-GCM protects confidentiality\n  only while the DEK remains secret; a recipient that has lawfully decrypted plaintext can copy it.\n  Revocation stops future wrapped-key release, not prior possession. Shared passwords, embedded master keys,\n  moving-branch URLs, nonce reuse under one DEK, and claims that bytecode cannot be inspected after\n  decryption are non-conformant security postures (§9.2.1).\n- **Kernel substitution:** testing mutable ring bytes and restoring the Grail only after approval creates\n  an untested release. §11.1 requires the release-shaped artifact to contain the pinned bytes before its\n  tests, attestations, and approval; a digest mismatch is a blocking `kernel-drift` finding.\n- **Kernel registry rollback/rebinding:** persisting only `registry_seq` does not preserve an activated\n  Grail declaration across a malicious higher-sequence registry. Consumers also persist every activated\n  canonical `grail-kernel` entry and reject its later removal, mutation, or duplication (§11.1).\n\n## 15. References\n[RFC 2119] [RFC 8174] requirement terms · [RFC 8259] JSON · [RFC 7493] I-JSON · [RFC 8785] JCS ·\n[FIPS 180-4] SHA-256 · [RFC 3986] URI · [RFC 5234] ABNF · [RFC 7405] case-sensitive ABNF · [RFC 9562] UUID\n(obsoletes RFC 4122) · [RFC 5280] X.509 SPKI · [RFC 7515] JWS · [RFC 7797] unencoded JWS payload ·\n[RFC 7518] JWA/ES256 · [RFC 8037] EdDSA in JOSE · [RFC 6979] deterministic ECDSA · [RFC 3339] timestamps ·\n[NIST SP 800-38D] AES-GCM · [RFC 2104] HMAC · [RFC 5869] HKDF · [RFC 7516] JWE · [ECMA-262] ECMAScript.\n\n---\n\n### Revision log\n- **rev-15 (the wire freeze)** — §12 freezes every form a `rapp/1` artifact is verified by (§4, §5,\n  §6.1–6.2, §7.1, §7.3, §7.5, §8, §9.1); a change to any of them is `rapp/2` beside this document, never a\n  revision of it, and `rapp/1` artifacts verify forever. Art. III is scoped to an estate's own artifacts.\n  Registration, vocabulary, profiles, and the registry keep growing under `rapp/1` (Art. IV). Constitution\n  Article 18 restates the rule.\n- **rev-14 (DOGG specification-chain authority)** — makes the append-only\n  `anchor/chain.jsonl` frame history carry normative specification content\n  while protected canonical-main acceptance selects authority; defines the\n  frame hash as durable revision identity; embeds the normative Markdown in a\n  normal `body.pulse`; retains immutable rev-5–rev-13 pointer history; freezes\n  a content-addressed bootstrap verifier profile; publishes hash-addressed\n  frame objects and a deterministic index; makes `SPEC.md` a materialized\n  selected-head view; and records the rev-13 Article 14 transition without\n  inventing signatures or changing any RAPP/1 wire primitive.\n- **rev-13 (public governance closure)** — makes the ratified public Protocol\n  Constitution final for protocol governance; limits private governance and\n  master plans to estate/product concerns; makes registry `protocol` entries\n  subordinate adoption pins; verifies the exact canonical RAPP foundation\n  object before anchoring; and aligns every public teaching surface with\n  estate-specific registry authority.\n- **rev-12 (foundation/protocol boundary)** — records `kody-w/RAPP` as the\n  canonical public foundation and product home; limits `kody-w/rapp-1` to\n  protocol authority; ratifies the complete public Protocol Constitution; makes\n  registries explicit estate instances rather than protocol authorities; pins\n  the canonical foundation commit and philosophy hash; and removes any\n  implication that protocol publication transfers product, brand, company, or\n  ownership authority.\n- **rev-11 (planetary operations profiles)** — constitutionalized immutable candidate/serving lineage\n  separation; defined RAPP CI/CD (`rapp-cicd/1`) and RAPP Deploy (`rapp-deploy/1`) as subordinate,\n  registry-pinned production profiles; required exact-candidate qualification, production-shaped\n  Preprod, cellular progressive exposure, expiring AI-health evidence, state/data continuity,\n  automatic containment, and exact rollback while retaining policy-defined extension points; and\n  defined typed, non-authoritative offspring/cross lineage without changing the egg or frame envelopes.\n- **rev-10 (sealed artifact + Grail execution closure)** — registered the `sealed` egg variant for\n  globally mirrorable public ciphertext with signed manifests and scoped recipient key release (§9.2.1);\n  added the `rapp/1:sealed-aad` and `rapp/1:sealed-key-request` address spaces; retained rev-9's exclusive\n  `release_scope` selection, persisted Grail binding, and verification-to-execution protections; and made\n  both confidentiality limits and kernel drift release-blocking.\n- **rev-9 (Grail selection and execution closure)** — makes release policy select only\n  `release_scope`, resolves `grail_id` exclusively through the activated persisted registry binding,\n  and closes verification-to-execution races by requiring a sealed immutable object/snapshot or\n  platform-enforced write exclusion through byte consumption.\n- **rev-8 (immutable Grail closure)** — makes pin selection deterministic through `release_scope`,\n  defines the exact signed §13.3 `grail-kernel` entry and owner-at-time activation, requires consumers\n  to persist every accepted binding, and specifies repository-object and executed-entry-point\n  verification across interpreted and derived runtimes.\n- **rev-7 (immutable Grail constitution)** — defines the Grail kernel by the SHA-256 of its exact bytes\n  (§3), makes every ring and release/deployment stage verify both the pin and the actually executed entry\n  point (§11.1), forbids post-test substitution, and makes changed bytes a different Grail rather than a\n  mutation. This is release governance only; the RAPP wire and existing canonical forms are unchanged.\n- **rev-6 (instantiation lineage)** — added §9.4's fresh per-install instance identity and immutable\n  `grown_from` lineage, closing the hatch seam without changing the frame or egg envelopes.\n- **rev-5 (war-game round 3 fold)** — folded 5 blockers + 7 majors + 7 minors, all clustered on the trust\n  model that rev-4's fixes made load-bearing: the **registry is now a signed root of trust** (§13.1) —\n  owner-signed, anchored to the out-of-band `estate_owner` rappid fingerprint, `registry_seq`-monotonic,\n  freshness-checked (B-1); **re-anchor requires a verifiable §13.3 authorization record** with old-key\n  continuity proof / tombstone / SPKI-tail check (B-2, mint-once now enforceable); **owner-succession is\n  time-scoped** so a key rotation never invalidates historical signatures (B-3); **eggs are `stored`-only**\n  (deflate is non-deterministic) with `canonical(manifest)` bytes (B-4); **invites sign under the\n  estate-owner succession** not the egg's own rappid (B-5); `egg_hash` excludes `sig` (M-1); first\n  re-genesis deprecates the creation genesis (M-2); full **registry entry schema** §13.3 (M-3); registry\n  freshness rule (M-4); egg consumer enforces §9.1 (zip-slip, M-5); rotated key refused on new frames (M-6);\n  `rapplication` exact `agent.py` (M-7); rev label, `invite` naming, sub-egg collision, rounding rule,\n  idempotency, compromise-window, seal-path (m-1…m-7).\n- **rev-4 (war-game round 2 fold)** — folded 6 blockers + 14 majors + 8 minors: domain-tagged mint\n  reconciled across Constitution/ledger (B1); §4(c) binary64 round-trip test so `0.1` is accepted (B2);\n  re-genesis head-reset exception so it isn't refused as rollback (B3); family-matched `*.re-genesis` kinds\n  so memory/swarm streams can converge (B4); whole-egg address `H(\"rapp/1:egg-manifest\",…)` + signed invites\n  + manifest self-reference resolved + deterministic ZIP/`contents` ordering (B5, M2–M4); re-anchor\n  enumerated three cases incl. key rotation (B6, M-rotation); `head_octets` pinned to the retained `legacy/`\n  artifact (M6); subsequent-convergence via `deprecated` (M7); every stream registers its genesis (M8); JWS\n  header canonical bytes + registry key-discovery + `estate_owner` designation (M9–M11); `/chat` error `step`\n  as string incl. `\"1a\"` + code namespace + session semantics (M12, m5); tombstone as the one time-dependent\n  verify check (M13); egg draft-artifact + dangling `§4` reference removed (M1, M5); calendar-valid `utc`,\n  depth convention, kind dedup/bounds (m2, m7, m8).\n- **rev-3 (war-game round 1 fold)** — folded 7 blockers + 19 majors + 12 minors from the Fable adversarial last-call:\n  I-JSON input domain + no-normalization/NFC (§4); **domain-separated hashing** (§5, the stronger option);\n  fixed `utc` byte form (§7.4); `prev_wave` by stream family not transport (§7.4); **stream-binding**\n  anti-replay (§7.5.1a); `spec` token pinned to `rapp/1` (§7.1); full JWS profile + key discovery + rotation/\n  tombstone (§10); hardened re-genesis with raw-byte terminal seal + registry linearization (§12.1); heads &\n  forks (§7.6); `/chat` fully specified (§8); **egg variants ratified into the standard**, killing the\n  6-spec collision and closing EGG-01 (§9); registry append-only (§13); type-validated verify (§7.5.1);\n  cross-stream merge tie-break (§7.4); provisional-identifier rule (§6.3); all references added (§15).\n- **rev-2** — first last-call tightening (7 self-review defects).\n- **rev-1** — initial unified draft.\n\n*The canonical protocol authority is the owner-selected, verified\nspecification chain in this repository. The canonical public RAPP foundation\nand product home remain at `kody-w/RAPP`.*\n", "sha256": "348e7d5baa94aaf2ce4c5354f3cb261f389298a04af65e271a686d3b62f7c384", "bytes": 79692}, "publication": {"canonical_repository": "https://github.com/kody-w/rapp-1", "protected_ref": "refs/heads/main", "selection": "owner-ratified acceptance of the chain snapshot onto protected canonical main", "linearization": "the accepted canonical-main commit containing the new frame", "history_replacement": "prohibited", "competing_append": "must rebase onto the accepted head and regenerate", "transition": "rev-14-ratified-under-rev-13-article-14", "chain_append_process": "governs-rev-15-and-later", "authenticated_registry_checkpoint": null}}, "payload_hash": "1ac47416e9caf174c4fdc00265ca187c244fb701ae2a7fb7211ba1385a951310", "prev": "c7549bbd3e133b833930e24e008817ea295734b870f41706455d3f45821aba3a", "prev_wave": null, "sig": null, "frame_hash": "83ca275f35cca96e43d75c99d338326c1a39b2240eabf57eb7c29ac96cc90818"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 16, "utc": "2026-09-02T01:31:21.000Z", "payload": {"canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "58058d08c9f0e340fae07c9865647f599c32634d", "commit_utc": "2026-09-01T21:31:21-04:00", "default_profile": "interop", "exchange": {"carrier": "POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward.", "idempotence": "keyed on the request's payload_hash — a retry returns the existing reply, never a second one.", "rule": "the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.", "shape": "push a frame in, get a frame back shaped by what you pushed — ONE hop."}, "frame_keys": ["spec", "kind", "stream_id", "seq", "utc", "payload", "payload_hash", "prev", "prev_wave", "sig", "frame_hash"], "kind_families": {"body": {"kinds": ["body.pulse", "body.twin-pulse", "body.reconstructed", "body.re-genesis"], "logs": "an organism's biography", "stream": "body-stream (bare rappid)"}, "memory": {"kinds": ["memory.chat-turn", "memory.tool-call", "memory.save", "memory.reconstructed", "memory.re-genesis"], "logs": "one organism's life", "stream": "memory-stream"}, "swarm": {"kinds": ["swarm.guidance", "swarm.echo", "swarm.telemetry", "swarm.reconstructed", "swarm.re-genesis"], "logs": "the planetary wire", "stream": "swarm-stream (net:label)"}}, "moods": {"clear": {"profile": "interop", "when": {"conditions": "clear,sunny"}, "why": "good conditions, normal posture"}, "early": {"profile": "minimal", "when": {"hour_lt": "6"}, "why": "same"}, "night": {"profile": "minimal", "when": {"hour_gte": "22"}, "why": "low-attention hours; smallest honest context"}, "storm": {"profile": "audit", "when": {"conditions": "storm,rain,snow"}, "why": "degraded links are when drift hides; lead with verification"}}, "normative_bytes": "79692", "normative_path": "SPEC.md", "normative_sha256": "348e7d5baa94aaf2ce4c5354f3cb261f389298a04af65e271a686d3b62f7c384", "observed_utc": "2026-09-02T01:31:21.000Z", "profile_signals": {"author": "authoring", "build": "authoring", "check": "audit", "conform": "audit", "drift": "audit", "handshake": "interop", "install": "onboarding", "join": "onboarding", "mint": "authoring", "new": "onboarding", "stranger": "interop", "unknown-peer": "interop", "verify": "audit", "write": "authoring"}, "profiles": {"audit": {"max_rules": "8", "show": ["keys", "stale_terms"], "types": ["pattern", "gotcha"], "why": "judging conformance; refuse-never-repair and the identity law govern"}, "authoring": {"max_rules": "8", "show": ["keys", "eggs"], "types": ["gotcha", "fact"], "why": "hand-building a frame; the envelope rules are what bite"}, "interop": {"max_rules": "6", "show": ["keys", "stale_terms", "pointer"], "types": ["gotcha"], "why": "a peer may be out of date; lead with what it can get WRONG"}, "minimal": {"max_rules": "0", "show": ["stale_terms"], "types": [], "why": "smallest honest context"}, "onboarding": {"max_rules": "5", "show": ["keys", "eggs", "stale_terms", "pointer"], "types": ["fact"], "why": "new organism; needs the shape of the world, not the edge cases"}}, "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "revision": "rev-16", "rules": [{"c": "spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted.", "t": "fact"}, {"c": "Canonical form is RFC 8785 JCS and FORBIDS floats — numbers ride as strings. A float silently breaks byte-reproducibility.", "t": "gotcha"}, {"c": "payload_hash = H(\"rapp/1:particle\", payload) — content only, reproducible across instances.", "t": "fact"}, {"c": "frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) — unique per stream instance.", "t": "fact"}, {"c": "prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable.", "t": "gotcha"}, {"c": "§6.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name — sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint.", "t": "gotcha"}, {"c": "Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed.", "t": "pattern"}, {"c": "A swarm-stream frame with sig==null is refused (§7.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null.", "t": "gotcha"}, {"c": "Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs.", "t": "fact"}, {"c": "Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise — this is how N streams compose into one view.", "t": "pattern"}, {"c": "One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct.", "t": "pattern"}, {"c": "§9.4 (rev-6): hatching an egg MUST mint a fresh §6.2 identity for the INSTANCE — the artifact rappid rides the egg unchanged and is shared by every install; the instance identity never is. The instance SHOULD record grown_from = the §9.1 egg address it grew from: written at mint, immutable, null when unknown, NEVER fabricated. Lineage, not inheritance — it confers no authority, no trust, no key material.", "t": "fact"}, {"c": "§11.1 / Constitution Article 15: owner policy selects only release_scope; the activated registry selects grail_id; every ring rejects kernel-drift; execution consumes bytes from a sealed immutable object or equivalent write-excluded snapshot.", "t": "gotcha"}, {"t": "gotcha", "c": "A sealed egg is public ciphertext, not password-protected hosting: the signed manifest binds AES-256-GCM data and a scoped key service; no shared DEK belongs in the egg, URL, client, log, or frame."}, {"t": "fact", "c": "RAPP CI/CD promotes one immutable release payload hash through an ordered evidence chain; no ring may rebuild, patch, substitute, or skip the candidate."}, {"t": "gotcha", "c": "RAPP Deploy forbids in-place serving mutation: growth happens in an isolated candidate lineage and reaches users only through bounded, reversible waves."}, {"t": "pattern", "c": "A new encounter may produce an offspring or cross with a fresh identity and typed parent addresses; lineage may continue indefinitely, but every attempt is bounded and parent authority never transfers implicitly."}, {"t": "fact", "c": "kody-w/RAPP remains the public foundation and product home; kody-w/rapp-1 defines the interoperable protocol only."}, {"t": "fact", "c": "The rapp/1 wire is frozen: §4, §5, §6.1-6.2, §7.1, §7.3, §7.5, §8 and §9.1 never change under the rapp/1 token; a change is rapp/2 beside it, and rapp/1 artifacts verify forever."}, {"t": "fact", "c": "RAPP Work uses seven registered body kinds on the unchanged eleven-key frame; catalog locators, Portable Neurons, Git, raw paths, and static API documents remain inert evidence or discovery rather than authority."}, {"t": "gotcha", "c": "A completed RAPP Work migration verifies retained intent, signed evidence, unchanged source, exact rollback, and key custody before any mutation."}], "vocabulary": {"body": {"status": "live", "where": "§7.2 kind family"}, "estate": {"status": "live", "where": "§9.2 egg variant"}, "grail": {"status": "live", "where": "§3 terminology; §11.1 immutable Grail kernel conformance; Constitution Article 15"}, "grown_from": {"status": "live", "where": "§9.4 instantiation — instance lineage key"}, "instance": {"status": "live", "where": "§9.4 instantiation — a hatched install; fresh §6.2 identity, never shared"}, "invite": {"status": "live", "where": "§9.2 egg variant"}, "memory": {"status": "live", "where": "§7.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate — bytes only at git 24c8fdc, sha256 690f6109…"}, "neighborhood": {"status": "live", "where": "§9.2 egg variant"}, "organism": {"status": "live", "where": "§9.2 egg variant"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 §6"}, "rapplication": {"status": "live", "where": "§9.2 egg variant"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's words are `organism` (§9.2) and `instance` (§9.4)"}, "session": {"status": "live", "where": "§9.2 egg variant"}, "swarm": {"status": "live", "where": "§7.2 kind family"}, "sealed": {"status": "live", "where": "§9.2 sealed egg variant and §9.2.1 profile"}, "rapp-cicd": {"status": "live", "where": "§11.2 and protocols/rapp-cicd/1/SPEC.md"}, "rapp-deploy": {"status": "live", "where": "§11.2 and protocols/rapp-deploy/1/SPEC.md"}, "offspring": {"status": "live", "where": "§9.4 typed lineage and PHILOSOPHY.md"}, "cross": {"status": "live", "where": "§9.4 typed multi-parent lineage and PHILOSOPHY.md"}, "wire-freeze": {"status": "live", "where": "§12 and Constitution Article 18 — the rapp/1 verified forms never change; a change is rapp/2"}, "rapp-work": {"status": "live", "where": "protocols/rapp-work/1/SPEC.md — additive organization, Hive high-water, migration, custody, and rollback"}}, "philosophy": {"canonical_repository": "https://github.com/kody-w/RAPP", "canonical_commit": "cb921ae59b5d762ce0bdd5493764cbb1c8b539fe", "canonical_path": "PHILOSOPHY.md", "canonical_sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c", "mirror_path": "PHILOSOPHY.md", "mirror_sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c"}, "operational_profiles": {"rapp-cicd/1": {"status": "live", "spec_path": "protocols/rapp-cicd/1/SPEC.md", "spec_sha256": "6d27d10103a3204f3b65a2e246462d197016bce5203dd510ba3ce209740e8278", "schema_path": "protocols/rapp-cicd/1/schema.json", "schema_sha256": "5936057868f46fc74afa00532f4aea60cfbb667c7c2f09998e1e86a0c2e629cc"}, "rapp-deploy/1": {"status": "live", "spec_path": "protocols/rapp-deploy/1/SPEC.md", "spec_sha256": "b5fc84465fb201fd97d7059997490a8fae5bf79ec55e935b0cfd9b4c787108e5", "schema_path": "protocols/rapp-deploy/1/schema.json", "schema_sha256": "aca783f3274cd865926f6b943163189fa93a7bbc4c7d4258856a54779a4a71ba"}, "rapp-work/1": {"status": "live", "spec_path": "protocols/rapp-work/1/SPEC.md", "spec_sha256": "283359355c3fe2858e28744368255683af3ed28a68e290e56c231e7d4b13c08e", "schema_path": "protocols/rapp-work/1/schema.json", "schema_sha256": "ff30f9878f12fa4ad7d93c4c205eb1cb580137a7dee87aa9d23c88a93466d19e"}}, "constitution": {"path": "CONSTITUTION.md", "sha256": "59b600d63e329de5adf11aa6dd103c82e62c72882edd899788e80fd316b21d43", "size_bytes": 17403}, "foundation": {"schema": "rapp-foundation-pointer/1", "status": "canonical-product-home", "repository": "https://github.com/kody-w/RAPP", "commit": "cb921ae59b5d762ce0bdd5493764cbb1c8b539fe", "path": "PHILOSOPHY.md", "sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c", "size_bytes": 2633, "relationship": "kody-w/RAPP is the public RAPP foundation and product home; kody-w/rapp-1 is the interoperable protocol authority"}, "schema": "rapp-spec-revision/1", "previous_revision": "rev-15", "previous_normative_sha256": "348e7d5baa94aaf2ce4c5354f3cb261f389298a04af65e271a686d3b62f7c384", "normative": {"media_type": "text/markdown; charset=utf-8", "text": "# The RAPP Protocol Suite\n### Unified normative specification of identity, canonicalization, the frame, the wire, and the egg\n\n> **Generated/materialized view.** These exact UTF-8 bytes are carried inside\n> the selected specification-revision frame in `anchor/chain.jsonl`. The frame\n> chain proves integrity and lineage; canonical owner-ratified publication\n> selects authority. Change the protocol by appending a successor frame, not by\n> treating this file as independent authority.\n\n**Status:** Owner-ratified RAPP/1 **rev-15 amendment**. It is effective iff the\nprepared chain snapshot has been accepted onto canonical protected main under\nthe transition in §12.2. **Obsoletes / consolidates:**\n`rapp-frame/2.0`, `rapp-frame/2.1`, `rapp-rappid-spec/2.0`, `rapp-protocol/1.0`, all scattered egg specs\n(§9 subsumes them), and `OSI.md`. This is the current materialized view of the single living standard;\nthe consolidated specs are retired historical record (Protocol Constitution Article 6). Rev-14 becomes\nthe published current revision when the source merge and append-only anchor update carrying these exact\nbytes complete.\n\n**Rides existing standards; invents nothing:** requirement terms [RFC 2119]/[RFC 8174]; JSON restricted to\nI-JSON [RFC 7493] over [RFC 8259]; canonicalization [RFC 8785] (JCS); hashing SHA-256 [FIPS 180-4] with\ngit-style domain separation; identifiers on the [RFC 3986] URI model; case-sensitive grammar [RFC 7405]\nover [RFC 5234] ABNF; keyless entropy UUIDv4 [RFC 9562]; keyed identity X.509 SPKI [RFC 5280]; signatures\ndetached unencoded JWS [RFC 7515]/[RFC 7797], EdDSA [RFC 8037] / ES256 [RFC 7518]/[RFC 6979]. RAPP is a\n*profile* over these, as HTTP profiles TCP/URIs/MIME.\n\n---\n\n## 1. Introduction\nRAPP is a content-addressed distributed organism. Its integrity rests on one invariant: **the same\nconcept has the same bytes everywhere.** This document specifies, normatively and completely, five\nload-bearing primitives so any two independent implementations interoperate **byte-for-byte with no\nout-of-band agreement**: canonicalization (§4), content addressing (§5), identity (§6), the frame (§7),\nthe egg (§9) — all riding one wire (§8): `POST /chat`, or a signed append-only frame. Implementations add\nagents, cartridges, and registered `kind`s — never new endpoints, never new envelopes.\n\n**Repository scope.** `kody-w/RAPP` is the canonical public RAPP foundation,\nproduct home, reference implementation, organism model, and philosophy.\n`kody-w/rapp-1` is the canonical interoperable protocol authority. This\nspecification governs wire-compatible bytes and conformance; it does not absorb\nthe RAPP product or any downstream Rappter/RapterBox LLC product.\n\n**Specification authority.** The append-only DOGG chain at\n`anchor/chain.jsonl` carries the normative revision content. Its hashes prove\nintegrity, not authority or ratification. Until an authenticated RAPP\nregistry/checkpoint exists, the chain accepted by the owner onto protected\ncanonical `kody-w/rapp-1` main is authoritative; an immutable accepted commit\nplus head frame hash is the portable checkpoint. `SPEC.md` is the byte-exact\nmaterialized human view, and `orient.json` is only a discovery beacon. The\nselected chain-frame hash, not a mutable path or `rev-N` label, is the durable\nidentity of a protocol revision (§12.2).\n\n### 1.1 The layered model\n```\n  L5  EGG        cartridge packaging (§9)          — MIME-multipart analogue\n  L4  FRAME      universal event envelope (§7)     — the IP packet of RAPP\n  L3  WIRE       transport: /chat + frames (§8)    — HTTP-analogue single method\n  L2  IDENTITY   rappid namespace + trust (§6,§10) — URI + PKI analogue\n  L1  ADDRESS    canonicalization + hash (§4,§5)   — the git object model\n```\nA higher layer **MUST NOT** redefine a lower one. Every layer names exactly one canonical form.\n\n## 2. Requirements language\nThe key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHOULD**, **MAY** are as in [RFC 2119]/\n[RFC 8174] when in **bold caps**. (The Federal Constitution adopts the same clause.)\n\n## 3. Terminology\n**organism** — a running brainstem with persistent identity. **rappid** — the eternal, mint-once name of an\norganism/door/object (§6): minted once from a UUIDv4 or a public key, never derived from content or name.\n**frame** — one immutable content-addressed event (§7). **stream** — an append-only hash-chained frame\nsequence sharing one `stream_id`. **particle / wave** — a frame's two domain-separated addresses:\npayload-hash / whole-frame-hash (§7.3). **canonical form** — the one [RFC 8785] byte string for a value\n(§4). **legacy form** — any other historical encoding; legacy is drift and **MUST** be migrated out\n(Fed. Const. Art. III), except sealed re-genesis history (§12.1).\n**Grail kernel** — an estate-declared, byte-pinned runtime substrate. Its `grail_id` is\n`\"grail:\" || Hb(\"rapp/1:grail\", kernel_bytes)`; repository, immutable ref, commit, path, raw SHA-256,\nand byte length are provenance and verification data, not alternate identities. Once activated through\n§13.3, those bytes are permanent (Protocol Constitution Art. 15); capabilities evolve outside them.\n**release capsule** — the canonical `rapp-cicd/1-release` payload identifying one immutable candidate.\n**serving lineage** — the sequence of qualified release identities that have received user traffic;\nthe currently served release is immutable even while a separate candidate lineage grows.\n**deployment cell** — an independently observable and isolatable runtime failure domain governed by\n`rapp-deploy/1`.\n\n## 4. Canonicalization (L1)\n`canonical(v)` is the UTF-8 byte string produced by **[RFC 8785] JCS** for the value `v`, defined **only**\nover I-JSON [RFC 7493]. JCS fixes member-name ordering (UTF-16 code-unit), string escaping, and number\nserialization (ECMAScript `Number::toString`, [ECMA-262]); there is no insignificant whitespace and no\nbyte-order mark.\n\n**RAPP input-domain profile (parse-side interoperability — this is a RAPP rule, not a JCS mandate).** An\nimplementation **MUST** refuse (never repair) any JSON value that, at any depth, contains: (a) duplicate\nmember names in one object; (b) an unpaired UTF-16 surrogate in any string; (c) a number token that does\nnot survive the binary64 round-trip — let `d` be the token's nearest binary64 value under `roundTiesToEven`\n(the IEEE-754 default; ±∞ are admissible results); the token is refused iff `d` is not finite, or the\n[RFC 8785] serialization of `d` (ECMA-262 `Number::toString`) denotes a different mathematical value than\nthe token (so `0.1` is accepted — it round-trips — while `9007199254740993` and `1e999` (→ +∞) are refused); (d) canonical form exceeding 1 MiB or JSON nesting depth\nexceeding 64 (the root value is depth 1; each nested object/array adds 1). Refusal is whole (§7.5-style),\nnever partial.\n\n**No normalization.** RAPP applies **no** Unicode normalization when hashing, storing, or re-emitting an\nexisting value; strings are code-point sequences preserved verbatim and equality everywhere is code-point\nequality (no canonical-equivalence matching). A producer creating a **new** human-or-identifier string\n(slug, kind, label, `payload` object key) **MUST** emit it in Unicode NFC.\n\n> **Migration note (drift C4):** the `twin`/`rapp-body` `_frame.mjs::canonicalize()` (sorted-key\n> `JSON.stringify`) coincides with JCS only for string-only payloads; it **MUST** be replaced by the JCS\n> implementation of record, imported (not re-typed) by every repo that content-addresses.\n\n## 5. Content addressing (L1) — domain-separated\nEvery hash is **domain-separated** (git's `type\\0`, Nix's tagged store — collisions across address spaces\nare made unconstructible):\n```\nH(space, v) = lowercase_hex( SHA-256( utf8(space) || 0x0A || canonical(v) ) )     ; v a value (§4)\nHb(space, b) = lowercase_hex( SHA-256( utf8(space) || 0x0A || b ) )                ; b raw octets\n```\n`space` is an exact ASCII tag, none containing `0x0A`: `\"rapp/1:particle\"`, `\"rapp/1:wave\"`, `\"rapp/1:egg\"`,\n`\"rapp/1:egg-manifest\"`, `\"rapp/1:rappid\"`, `\"rapp/1:grail\"`, `\"rapp/1:seal\"`,\n`\"rapp/1:sealed-aad\"`, `\"rapp/1:sealed-key-request\"`. A tag is used by either `H` or `Hb`, never\nboth. Output is always exactly 64 lowercase hex, **never truncated or uppercased**. Two values\nare treated as the same object iff their same-space hashes are equal; SHA-256 collision resistance\n[FIPS 180-4] is a security assumption of this standard (§14). A `name/X.Y` label is never identity — only\na hash is. A bare 64-hex is meaningful **only** within its space; an implementation **MUST NOT** dereference\na hash from one space as an object of another, and content-addressed stores **MUST** key by `(space, hash)`.\n\n## 6. Identity — the rappid (L2)\n### 6.1 Grammar (case-sensitive, [RFC 7405])\n```abnf\nrappid    = %s\"rappid:@\" owner \"/\" slug \":\" hash\nowner     = lclabel                       ; the lowercase GitHub login (1-39 chars)\nslug      = lclabel                        ; 1-100 chars\nlclabel   = lcalnum *( [\"-\"] lcalnum )     ; no leading/trailing/adjacent hyphen\nlcalnum   = LCALPHA / DIGIT\nLCALPHA   = %x61-7A                         ; a-z\nhash      = 64HEXDIGLC\nHEXDIGLC  = DIGIT / %x61-66                 ; 0-9 a-f\n```\n`owner` **MUST** be the lowercase form of the GitHub login (logins are case-insensitive; display casing is\npresentation, never identity). Lengths are normative: `owner` 1–39, `slug` 1–100; an implementation\n**MUST** refuse longer. This self-locating form is the **only** conformant rappid; `rappid:<slug>:<hash>`,\n`rappid:v2:…`, bare UUIDs, `moment:`/name-hash derivations are legacy and **MUST** be migrated out\n(Art. III), not read forever.\n\n### 6.1.1 stream_id and kind grammar\n```abnf\nstream_id   = memory-stream / body-stream / swarm-stream\nmemory-stream = rappid \":\" instance      ; one organism instance's memory\nbody-stream   = rappid                    ; an organism's biography\nswarm-stream  = %s\"net:\" lclabel          ; a planetary-wire stream\ninstance      = lclabel                   ; 1-64 chars\nkind          = lclabel \".\" lclabel       ; each label 1-64 chars\n```\nA `kind` string carries **no intrinsic family**; the §13 registry binds each registered `kind` to exactly\none family. Membership is tested by exact-match against the registry — never prefix inference, never wildcards.\n\n### 6.2 Minting (mint-once)\nThe 64-hex tail is minted **exactly once** per identity, then immutable:\n- **keyless:** `tail = Hb(\"rapp/1:rappid\", uuid4_octets)`, where `uuid4_octets` is the 16-octet binary\n  UUIDv4 [RFC 9562] §5.4 (field/byte order per §4 of that RFC).\n- **keyed:** `tail = Hb(\"rapp/1:rappid\", SPKI_DER)`, the DER `SubjectPublicKeyInfo` [RFC 5280] of the master key.\n\nA producer **MUST NOT** derive the tail from owner/slug or any name (`sha256(\"owner/slug\")` is prohibited —\ndrift ID-01/C3). On read of an existing `rappid.json` an implementation **MUST** reuse the stored tail\n(canonicalize-on-read) and **MUST NOT** re-mint — with exactly one mechanism: the owner-authorized\n**re-anchor** (§6.3), which mints a fresh 64-hex tail once per authorization and records the superseded id\nin `_migrated_from`. Re-anchor is lawful in exactly three cases: (a) a 128→256-bit provisional upgrade\n(§6.3); (b) §10 key rotation or compromise; (c) migrating a pre-rev-3 keyed tail minted with the un-tagged\n`sha256(SPKI)` formula (which fails §10 discovery and **MUST** be re-anchored like a provisional identity).\n\n### 6.3 Canonicalization on read; provisional identifiers\n`canonicalize_rappid(s)` restructures any legacy form into §6.1, **preserving the existing hash** (never\ninventing one). A restructured identifier whose tail is not exactly 64 lowercase hex (e.g. a legacy 32-hex\ntail) is **provisional**: it exists only inside the reading process and **MUST NOT** appear in any emitted\nframe, `stream_id`, egg, or registry entry. The one-time owner-authorized 128→256-bit re-anchor mints a\nfresh 64-hex, records the old id in `_migrated_from`, and is the only way a provisional identity becomes\nusable. A provisional identifier found in a stored artifact is a drift finding (Art. III). Re-anchor is the\nsingle re-mint mechanism (§6.2), lawful only in the enumerated cases: provisional 128→256-bit upgrade,\n§10 key rotation/compromise, and pre-rev-3 un-tagged-`sha256(SPKI)` keyed-tail migration.\n\n**A re-anchor is valid only with a verifiable authorization** — a self-asserted `_migrated_from` is\ninsufficient (it would let anyone hijack an identity). A re-anchor **MUST** be recorded as an owner-signed\n§13.3 **re-anchor record** `{old_rappid, new_rappid, case, utc, sig, old_key_sig?}`; a consumer **MUST**\nrefuse a `new_rappid` (and treat `_migrated_from` as drift) unless that record is present and:\n- `case:\"rotation\"` (uncompromised): `old_key_sig` (a §10 JWS by the **old** key) verifies — proof of\n  continuity;\n- `case:\"compromise\"`: `old_key_sig` is waived but a §10 **tombstone** for `old_rappid` is registered in the\n  same append;\n- `case:\"tag-migrate\"` (pre-rev-3 keyed tail): the verifier checks `lowercase_hex(SHA-256(SPKI_DER_old))` ==\n  the old tail;\n- `case:\"upgrade\"` (provisional 128→256): the old provisional id resolved to this owner at read time.\nEach mints one fresh tail. The **estate_owner's own** re-anchor record **MUST** be signed by the outgoing\n`estate_owner` key (§13.2); root-key compromise is recovered only by out-of-band re-anchoring (§13.1).\n\n## 7. The Frame (L4)\n### 7.1 The envelope — exactly eleven keys\n```json\n{\n  \"spec\":         \"rapp/1\",\n  \"kind\":         \"<klabel.klabel>\",\n  \"stream_id\":    \"<stream_id>\",\n  \"seq\":          <uint53>,\n  \"utc\":          \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"payload\":      { },\n  \"payload_hash\": \"<64hex>\",\n  \"frame_hash\":   \"<64hex>\",\n  \"prev\":         \"<64hex|null>\",\n  \"prev_wave\":    \"<64hex|null>\",\n  \"sig\":          \"<jws|null>\"\n}\n```\n- **`spec` MUST be the exact string `\"rapp/1\"`** in every frame. `rapp-frame/2.0`/`2.1` are legacy tokens\n  and **MUST NOT** be emitted. Any revision changing the key set, any field's grammar, or either hash rule\n  **MUST** change this token and land an Art. III total migration; revisions adding only new registered\n  `kind`s/registry entries keep the token (Fed. Const. Art. II).\n- **Exactly these eleven keys, always present**, none missing, none extra. A field that does not apply is\n  present with value `null` (`prev`/`prev_wave` at genesis and on non-swarm streams; `sig` when unsigned) — never omitted,\n  because [RFC 8785] hashes `null` and an absent key differently. Extra or missing keys are refused (§7.5).\n- **`payload` MUST be a JSON object** (possibly empty `{}`); never `null`, array, string, number, or bool.\n- `seq` is `uint53` (§7.4). A producer **MUST NOT** emit a frame whose canonical form exceeds 1 MiB or\n  nesting depth 64 (§4).\n\n### 7.2 Kind families (one envelope, registry-bound families)\n| family | example registered kinds | `stream_id` form | logs |\n|---|---|---|---|\n| `memory` | `memory.chat-turn`, `memory.tool-call`, `memory.save`, `memory.reconstructed` | memory-stream | one organism's life |\n| `swarm`  | `swarm.guidance`, `swarm.echo`, `swarm.telemetry`, `swarm.reconstructed` | swarm-stream | the planetary wire |\n| `body`   | `body.pulse`, `body.twin-pulse`, `body.reconstructed`, `body.re-genesis` | body-stream | an organism's biography |\nEach family also has a `*.re-genesis` kind (`memory.re-genesis`, `swarm.re-genesis`, `body.re-genesis`)\nused only by §12.1. The family is **not** the kind's prefix — it is the §13 registry binding (so\n`body.twin-pulse` is family `body`). Adding a family or event is a new registered `kind` on the **same** envelope (Art. IV), never a\nnew frame type. A frame's `kind` family **MUST** be compatible with its `stream_id` form (table column 3).\n\n### 7.3 Particle and wave (the unification)\nA frame carries **both** of its domain-separated addresses; a reader collapses it to whichever it needs.\nComputed in order:\n- **particle** — `payload_hash = H(\"rapp/1:particle\", payload)`. The **worldline identity and chain link**.\n- **wave** — `frame_hash = H(\"rapp/1:wave\", frame \\ {frame_hash, sig})` — the frame with **exactly** the\n  `frame_hash` and `sig` keys removed, all nine remaining keys (including `payload_hash`) present.\nBecause `payload_hash` is in the wave pre-image, `frame_hash` attests the particle; because only\n`frame_hash` (cannot hash itself) and `sig` (signs the result) are removed, the pre-image is unambiguous\nand non-circular. Both hashes are always present (never `null`).\n\n### 7.4 Chaining, time, and merge order\n- **`utc`** **MUST** be exactly the 24-byte form `YYYY-MM-DDTHH:MM:SS.mmmZ` — uppercase `T`/`Z`, exactly\n  three fractional digits, no numeric offset; the seconds field **MUST NOT** be `60` (a leap second clamps\n  to `59.999`). All `utc` comparisons are **bytewise** over this fixed form (identical to chronological order).\n- **Worldline chain (particle):** the **genesis** frame has `seq`=0 and `prev`=null; every later frame has\n  `seq` = predecessor's `seq`+1 (contiguous) and `prev` = predecessor's `payload_hash`. `seq` is `uint53`\n  (JSON integer, 0 ≤ seq ≤ 2^53−1, no fraction/exponent; a stream nearing 2^53−1 converges by re-genesis).\n- **Wire chain (wave):** `prev_wave` **MUST** be non-null **iff** `stream_id` is a swarm-stream **and**\n  `seq` > 0, in which case it equals the predecessor's `frame_hash`; in every other frame (all memory/body\n  streams, every genesis) it **MUST** be `null`. (Presence is a function of stream family, not transport.)\n- A frame is **immutable**: a new state is a new frame at a new hash; the head pointer (§7.6) re-points.\n- **Cross-stream merge order** (Dream-Catcher) is the total order: ascending `utc` (bytewise), ties broken\n  by ascending `frame_hash` (bytewise); no further ties are possible (§5).\n\n### 7.5 Verification (the complete consumer checklist)\nBefore accepting a frame, a consumer **MUST**, in order, **refuse** (never repair/reparent) on any failure:\n1. **Shape & types:** exactly the eleven §7.1 keys; `spec`==`\"rapp/1\"`; `kind` a string matching §6.1.1\n   ABNF and registered (§13); `stream_id` a string matching §6.1.1; `seq` a `uint53`; `utc` matching the\n   §7.4 fixed form **and** a calendar-valid [RFC 3339] `date-time` (so `2026-13-45T25:61:61.999Z` is\n   refused); `payload` a JSON object; `payload_hash`/`frame_hash` `64HEXDIGLC`; `prev`/`prev_wave` each\n   `null` or `64HEXDIGLC`; `sig` `null` or a §10 JWS string.\n1a. **Stream binding:** `frame.stream_id` **MUST** byte-equal the identifier of the stream being extended\n   or read (its declared `stream_id` at the head pointer / repo path of record). A genesis frame is\n   accepted only for the stream it names. (Defeats cross-stream genesis/segment replay — §14.)\n2. **Particle:** `payload_hash` == `H(\"rapp/1:particle\", payload)`.\n3. **Wave:** `frame_hash` == `H(\"rapp/1:wave\", frame \\ {frame_hash, sig})`.\n4. **Chain:** `seq`==head.`seq`+1 and `prev`==head.`payload_hash` (or `seq`==0 ∧ `prev`==null at genesis);\n   `utc` ≥ head.`utc` (bytewise).\n5. **Wire:** if `stream_id` is a swarm-stream and `seq`>0, `prev_wave`==head.`frame_hash`; else\n   `prev_wave`==null.\n6. **Signature:** if `sig`≠null, verify per §10 (present-but-invalid is refusal); a swarm-stream frame with\n   `sig`==null is refused (§8/§10).\nSteps 1–5 are **time-independent** (kind lookups only append, §13), so a frame passing them passes forever;\nstep 6 alone may flip pass→fail when a §10 tombstone with `revoked_utc` ≤ the frame's `utc` is later\nregistered — the one time-dependent check.\n\n### 7.6 Heads and forks\nA stream's **head** is the frame with the greatest verified `seq` descending from its registered genesis\n(§13). A consumer **MUST** persist, per stream, the highest `(seq, frame_hash)` it verified and **MUST**\nrefuse any presented head with lower `seq`, or a different `frame_hash` at an already-verified `seq` (no\nrollback, no silent reorg). Two distinct valid frames with equal `stream_id`, `seq`, and `prev` are a\n**fork**: a consumer **MUST** refuse both branches past the fork point and surface a drift finding; only\nthe owner resolves a fork (Art. X), by re-genesis (§12.1) if needed.\n\n**Exception (re-genesis head reset).** The no-rollback rule above refuses a lower-`seq` head — but a\nlegitimate §12.1 re-genesis presents a new genesis at `seq`=0. When (and only when) the §13 registry maps a\n`stream_id` to a new genesis `frame_hash` (§12.1 step 3), a consumer **MUST** verify that registered\ngenesis (§7.5) and then **reset** its persisted head for that `stream_id` to it. Only a registry-published\ngenesis authorizes a reset; any other lower-`seq` head remains a refused rollback.\n\n## 8. The Wire (L3)\nAll interaction rides one of exactly two forms:\n1. **Synchronous — `POST /chat`, `application/json` both ways.** Request: `user_input` (string, REQUIRED);\n   `session_id` (string, OPTIONAL — omit to start a session); `idempotency_key` (string, OPTIONAL — a repeat\n   with the same key returns the original response, not a new turn or duplicate session; scoped to\n   `session_id` when present, else to the key alone so session-creation is also de-duplicated); unrecognized members **MUST** be\n   ignored, never refused. Success: HTTP 200 with **exactly** `{response:string, agent_logs:[string],\n   session_id:string}` (no extra members). An unknown `session_id`, a refusal, or a malformed request\n   **MUST** be HTTP 422, `{error:{code:string, step:string|null}}` where `code` is a §13-registered error\n   code (e.g. `\"unknown-session\"`) and `step` is the failing §7.5 step as a string — one of\n   `\"1\",\"1a\",\"2\",\"3\",\"4\",\"5\",\"6\"` — or `null`. No other shape is conformant. New capability is a new agent\n   behind `/chat`, never a sibling REST route.\n2. **Asynchronous — an append-only frame (§7) published to a stream** (a repo path, an `events/` log). A\n   frame on a **swarm-stream MUST** carry `sig`≠null (§10); memory/body-stream frames **MAY** be unsigned.\n   Any *history* is safe to read given a trusted head (§14); the hash chain (§5) makes tampering\n   detectable.\n\n## 9. The Egg (L5) — the single egg spec of record\nAn **egg** is a cartridge packing a unit of the estate. **RAPP §9 is the one egg spec of record** (it\nsubsumes and retires `EGG_FAMILY.md`, `NEIGHBORHOOD_EGG_SPEC.md`, `ESTATE_SPEC.md`, `rappterbook/EGG_SPEC.md`,\nand the rest — drift C7). No other document may re-specify eggs; they cite this section.\n\n### 9.1 Container, manifest, and egg address\nAn egg is either a JSON object (`invite`/`session` variants) or a ZIP whose root is `manifest.json` (tree\nvariants). The manifest is a §4 value with exactly these members:\n```json\n{ \"schema\": \"rapp/1-egg\", \"variant\": \"<variant>\", \"rappid\": \"<§6.1 rappid>\",\n  \"created_utc\": \"<§7.4 utc>\", \"contents\": [ {\"path\":\"<rel>\",\"hash\":\"<64hex>\"}, … ], \"payload\": { },\n  \"sig\": \"<jws|null>\" }\n```\n- `contents` **MUST** list every packed file **except `manifest.json` itself**, exactly once each, with\n  `hash = Hb(\"rapp/1:egg\", file_octets)` (§5) over the raw stored octets. `contents` is **always present**;\n  for JSON (pointer/session) variants it **MUST** be exactly `[]`.\n- `path` **MUST** be a relative POSIX path: `/`-separated NFC UTF-8 segments, no `.`/`..` segment, no\n  leading `/`, no backslash, no Windows drive-qualified first segment (`ALPHA \":\"`), no duplicate `path`\n  in one manifest. A segment **MUST NOT** end in a period/space, contain `:`, contain a C0 control, or have\n  a case-insensitive basename equal to `CON`, `PRN`, `AUX`, `NUL`, `COM1`–`COM9`, or `LPT1`–`LPT9`.\n  `contents` **MUST** be sorted ascending\n  by the UTF-8 bytes of `path`.\n- `payload` is a §4 object (variant-specific). `sig` is a §10 JWS over `canonical(manifest \\ {sig})`, or\n  `null`. For the `invite` variant `sig` is REQUIRED and **MUST** verify with `kid` in the §13.2 estate-owner\n  succession (invites are estate-issued; a `sig` by any other key, even a validly registered one, is\n  refused — otherwise an attacker mints a fresh rappid and forges invites). For other variants a non-null\n  `sig` **MUST** verify per §10 with `kid` == a keyed rappid the consumer resolves via §13; a consumer\n  presented a signed egg **MUST** verify it.\n- **The egg's one §5 address is** `egg_hash = H(\"rapp/1:egg-manifest\", manifest \\ {sig})` — the manifest with\n  exactly the `sig` key removed (mirroring §7.3's wave rule: `sig` authenticates the egg, `egg_hash` names\n  it, so re-signing never changes identity). Stores key eggs by `(\"rapp/1:egg-manifest\", egg_hash)`.\n  (`\"rapp/1:egg\"` addresses file octets; `\"rapp/1:egg-manifest\"` addresses the egg as a whole.)\n- **Container determinism.** A ZIP variant **MUST** use compression method `stored` (0) for **every** entry\n  — no deflate in any variant (deflate is library-dependent, so it cannot be byte-reproducible; transport\n  compression, if any, wraps the egg and is not the egg). Entries appear in `contents` order with\n  `manifest.json` first; the `manifest.json` entry's octets **MUST** be exactly `canonical(manifest)`; all\n  timestamps `1980-01-01 00:00:00`; no extra fields; UTF-8 filename flag set; `contents[].hash` is over the\n  file octets (identical to the archive octets under method 0). A JSON-variant egg's serialized form\n  **MUST** be exactly `canonical(manifest)`. Two conformant packers of the **same manifest value** thus emit\n  byte-identical eggs.\n\n### 9.2 Variants (the ratified set — closes EGG-01)\n| variant | container | packs | required members |\n|---|---|---|---|\n| `organism` | ZIP | a full brainstem instance | contents (sorted) MUST include `rappid.json`, `soul.md`; MAY include `agents/*`, `organs/*`, memory files |\n| `rapplication` | ZIP | one rapp | contents MUST include `rappid.json` and exactly one `agent.py` at the root (the agent of record); MAY include one `ui.html` and files under `state/` |\n| `session` | JSON | one runtime + transcript | `payload` = `{runtime:<string>, transcript:[<object>]}`; contents `[]` |\n| `invite` | JSON | a QR-sized pointer (**no packed files**) | `payload` = `{target_rappid:<rappid>, target_url:<string>, target_kind:(\"neighborhood\" / \"estate\")}`; contents `[]`; `sig` REQUIRED |\n| `neighborhood` | ZIP | several organisms meant to live together | `payload` = `{members:[<rappid>,…]}`; contents = one sub-egg per member, named `<owner>--<slug>.egg` at the root, matched by the sub-egg manifest's `rappid` == the `payload.members[]` entry |\n| `estate` | ZIP | several neighborhoods | `payload` = `{neighborhoods:[<rappid>,…]}`; contents = one sub-egg per neighborhood, named `<owner>--<slug>.egg` at root, matched by sub-egg `rappid` |\n| `sealed` | ZIP | publicly mirrorable ciphertext with scoped key release | contents MUST be exactly `ciphertext.bin`; payload is the closed `rapp-sealed-artifact/1` profile in §9.2.1; `sig` REQUIRED |\n\nThe QR-sized invite that caused EGG-01 is the **`invite`** variant: a signed pointer object, not a\nmember-packing `neighborhood` egg. The banned legacy stamps (`brainstem-egg/2.3-neighborhood`,\n`neighborhood-egg/1.0`) migrate to `{schema:\"rapp/1-egg\", variant:\"invite\" / \"neighborhood\"}` (Art. III).\n\n### 9.2.1 Sealed artifact profile\n\nThe `sealed` variant lets any unauthenticated mirror, including a commit-pinned\n`raw.githubusercontent.com` URL, distribute an encrypted artifact globally without distributing its\ndecryption key.\n\nThe public bytes are **ciphertext, not access control**. Bytecode or obfuscation alone provides no\nconfidentiality. A conformant producer **MUST** use a random 256-bit data-encryption key (DEK) per artifact,\n**MUST NOT** embed that DEK or a shared master key in the egg/client/URL, and **MUST NOT** place a password\nin a URL. A password, passkey, device assertion, or account credential may authenticate to the key service;\nit is not the artifact encryption key.\n\nThe ZIP contents are exactly one file:\n\n```text\nciphertext.bin = AES-256-GCM ciphertext || 16-byte authentication tag\n```\n\nThe manifest `payload` has exactly:\n\n```json\n{\n  \"schema\": \"rapp-sealed-artifact/1\",\n  \"cipher\": \"A256GCM\",\n  \"nonce\": \"<12 bytes, unpadded base64url>\",\n  \"plaintext_commitment\": \"<64hex>\",\n  \"plaintext_bytes\": 1234,\n  \"media_type\": \"application/wasm\",\n  \"key_id\": \"<64hex>\",\n  \"key_service_rappid\": \"rappid:@owner/key-service:64hex\",\n  \"key_service_url\": \"https://keys.example.com/chat\",\n  \"access\": \"scoped-key-release\",\n  \"aad_hash\": \"<64hex>\"\n}\n```\n\n`plaintext_commitment` is a keyed commitment that cannot be tested without the DEK:\n\n```text\nprk = HMAC-SHA-256(32 zero octets, DEK)\ncommitment_key = HMAC-SHA-256(prk, utf8(\"rapp/1:sealed-commitment\") || 0x01)\nplaintext_commitment = lowercase_hex(HMAC-SHA-256(commitment_key, plaintext_octets))\n```\n\nThis is the [RFC 5869] HKDF-Extract/HKDF-Expand construction with an empty salt, one 32-byte output block,\nand the exact info string `rapp/1:sealed-commitment`. The commitment is public but does not permit an\noffline dictionary attack without the random 256-bit DEK.\n\nThe exact authenticated-data descriptor is:\n\n```json\n{\n  \"schema\": \"rapp-sealed-artifact/1\",\n  \"artifact_rappid\": \"<manifest.rappid>\",\n  \"created_utc\": \"<manifest.created_utc>\",\n  \"key_id\": \"<payload.key_id>\",\n  \"plaintext_commitment\": \"<payload.plaintext_commitment>\",\n  \"plaintext_bytes\": 1234,\n  \"media_type\": \"<payload.media_type>\"\n}\n```\n\n`aad_hash = H(\"rapp/1:sealed-aad\", descriptor)`, and `canonical(descriptor)` is supplied as AES-GCM\nadditional authenticated data. `nonce` decodes to exactly 12 bytes. `plaintext_bytes` is an integer from\nzero through `2^30` (1 GiB), a RAPP safety ceiling below both the [NIST SP 800-38D] per-invocation limit\nand the deterministic non-ZIP64 container boundary.\n`ciphertext.bin` length is exactly `plaintext_bytes + 16`. The sealed egg's manifest signature is REQUIRED\nand verifies per §10 with `kid` exactly equal to `manifest.rappid`. A sealed artifact therefore uses a\nkeyed §6.2 rappid controlled by its authorized publisher; another valid registry key cannot sign on its\nbehalf.\n\n`key_service_rappid` identifies the RAPP organism authorizing key release. `key_service_url` is its absolute\nHTTPS §8 `POST /chat` URL and **MUST** end in `/chat`. The URL is location, not authority: the service\nresponse is accepted only when its signatures and identifiers bind to `key_service_rappid`.\n\nThe caller sends the following canonical JSON object as the `user_input` string:\n\n```json\n{\n  \"schema\": \"rapp-sealed-key-request/1\",\n  \"egg_hash\": \"<64hex>\",\n  \"key_id\": \"<64hex>\",\n  \"recipient_rappid\": \"rappid:@owner/device:64hex\",\n  \"recipient_spki_der_b64\": \"<standard base64>\",\n  \"request_nonce\": \"<64hex>\",\n  \"expires_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"sig\": \"<recipient detached JWS>\"\n}\n```\n\n`sig` is over `canonical(request \\ {sig})` and verifies under `recipient_rappid`; `egg_hash` is the §9.1\nsealed egg address. The key service verifies entitlement, exact `(egg_hash,key_id)`, request expiry,\nrecipient key binding, and nonce non-reuse.\n\nThe §8 `response` string is canonical JSON:\n\n```json\n{\n  \"schema\": \"rapp-sealed-key-release/1\",\n  \"egg_hash\": \"<request.egg_hash>\",\n  \"key_id\": \"<request.key_id>\",\n  \"recipient_rappid\": \"<request.recipient_rappid>\",\n  \"request_hash\": \"<H('rapp/1:sealed-key-request', request without sig)>\",\n  \"wrap_alg\": \"ECDH-ES+A256KW\",\n  \"wrapped_key_jwe\": \"<JWE Compact Serialization>\",\n  \"issued_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"expires_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"service_sig\": \"<key-service detached JWS>\"\n}\n```\n\n`service_sig` is over `canonical(release \\ {service_sig})` and verifies under `key_service_rappid`.\n`wrapped_key_jwe` uses [RFC 7516] with `alg:\"ECDH-ES+A256KW\"` and `enc:\"A256GCM\"` for the declared\nrecipient SPKI. The service **MUST NOT** return a global raw DEK. Authorization, expiry, device scope, and\nkey rotation are service policy recorded in signed frames, not fields that alter the sealed egg's content\naddress.\n\nA mirror URL **SHOULD** be immutable (for GitHub Raw, pin a commit SHA rather than a moving branch). URL\nsecrecy is never assumed: integrity comes from the egg address and signature, confidentiality from\nAES-GCM, and use authorization from scoped key release.\n\nRevocation prevents future key release. It cannot erase ciphertext or plaintext already downloaded and\ndecrypted by an authorized recipient. A conformant product **MUST** state this limit plainly. It also\n**MUST NOT** claim that encrypted bytecode cannot be inspected after decryption; legal/license controls and\nbounded server authority remain separate from cryptographic confidentiality.\n\n### 9.3 Conformance\n- **Producer** **MUST** emit only `schema:\"rapp/1-egg\"` with a variant from §9.2, a §6.1 rappid, and, for\n  ZIP variants, a `contents` list whose every hash verifies. It **MUST NOT** emit any legacy egg schema.\n- **Consumer** **MUST** read every §9.2 variant, dispatch on `variant`, verify **integrity then viability** —\n  (0) the manifest is a §4 value satisfying **every §9.1 rule** — exact member set, `path` grammar (no `..`,\n  no leading `/`, no backslash), no duplicate paths, sort order, and for ZIP variants the archive entry set\n  equals `contents` ∪ {`manifest.json`} in the §9.1 deterministic order (this is the zip-slip defense; an\n  unenforced path grammar defends nothing); (1) every `contents[].hash` recomputes per §5; (2) the variant's\n  §9.2 structural requirements hold — and refuse whole on any failure; it **MUST NOT** reparent on transport.\n\n### 9.4 Instantiation — instance identity and `grown_from` lineage (rev-6; closes the hatch seam)\nAn egg names an **artifact**; a hatch creates an **instance**. Rev-5 specified packing and reading but\nleft instantiation identity unwritten, so every implementation had to invent its own — this section is\nthat missing word.\n\n- The `rappid` in a packed egg's `rappid.json` (§9.2) names the **artifact**. Every hatch of the same\n  egg reads the **same** artifact identity (§6.2 canonicalize-on-read); re-minting it on hatch is\n  prohibited (§6.2).\n- A consumer that instantiates an egg into a live installation **MUST** mint a **fresh §6.2 identity\n  for the instance**, exactly once, at first boot — from entropy, never derived from the artifact\n  identity, host name, or path. Two instances of one egg share the artifact identity and **MUST NOT**\n  share an instance identity.\n- The instance's identity document **SHOULD** record **`grown_from`**: the §9.1 egg address\n  (64 lowercase hex) of the egg it was instantiated from. `grown_from` is written at mint time and is\n  **immutable** thereafter; it is `null` when the source is unknown; a producer **MUST NOT** fabricate\n  it — lineage is a fact about a birth, never a claim to invent. An instance that cannot say where it\n  came from says `null`.\n- `grown_from` is **lineage, not inheritance**: it confers no authority, no trust, and no §10 key\n  material. A reader **MUST** treat it as an unverified assertion unless the named egg is available and\n  its address recomputes per §9.1/§5.\n- A newly authored artifact produced from one or more existing RAPP objects **MAY** record\n  `crossed_from` in its packaged `rappid.json`. The value is a sorted, duplicate-free array of typed\n  addresses `{space, hash}`, where `space` is `\"rapp/1:particle\"` or `\"rapp/1:egg-manifest\"` and `hash`\n  is 64 lowercase hex. One parent denotes an **offspring**; two or more denote a **cross**. The new\n  artifact **MUST** mint its own §6.2 rappid; parent artifacts and identities remain unchanged.\n  `crossed_from` is lineage only: it transfers no signature authority, ownership, entitlement, secret,\n  or trust. A verifier treats each parent as unverified until the addressed object is available and\n  recomputes in its declared space.\n\n## 10. Trust and signatures (L2)\n`sig` is OPTIONAL on memory/body streams and REQUIRED on swarm streams (§8). Chain integrity comes from the\nhash links (§5), not signatures. When present, `sig` **MUST** be JWS Compact Serialization with **detached,\nunencoded payload** ([RFC 7515] App. F + [RFC 7797]):\n- protected header members are **exactly** `alg` (`\"EdDSA\"` or `\"ES256\"`), `b64` (`false`), `crit`\n  (`[\"b64\"]`), `kid` (signer's §6.1 rappid), no others; the header octets **MUST** be `canonical(header)`\n  (§4 — JCS orders them `alg`, `b64`, `crit`, `kid`, no whitespace);\n- the `sig` string is the detached compact form `BASE64URL(canonical(header)) || \"..\" || BASE64URL(signature)`;\n- JWS signing input = `BASE64URL(canonical(header)) || \".\" || canonical(frame \\ {sig})`;\n- `alg`: `EdDSA`/Ed25519 [RFC 8037] or `ES256` [RFC 7518]; ES256 signers **SHOULD** sign deterministically\n  [RFC 6979] (Ed25519 is deterministic by construction) so signed frame files stay byte-reproducible.\n\n**Key discovery.** A keyed rappid's tail is one-way (`Hb(\"rapp/1:rappid\",SPKI)`). A verifier resolves the\nsigner's SPKI (DER) **from the §13 registry** entry (`rappid` → `spki_der_b64`); the door-of-record\n`rappid.json` is the publication venue the registry entry is generated from, not itself a verification\nsource. The verifier **MUST** check `Hb(\"rapp/1:rappid\", SPKI_DER)` == the rappid's tail and refuse on\nmismatch or registry absence.\n\n**Key lifecycle.** Rotation is an identity re-anchor (§6.3, case `rotation`) with new `tail =\nHb(\"rapp/1:rappid\", newSPKI)` and a §13.3 re-anchor record. A re-anchor **deprecates** the superseded\nrappid's §13 `spki` entry: a verifier **MUST** refuse a `sig` whose `kid` is a superseded rappid on any\nframe with `utc` ≥ the re-anchor record's `utc` (rotation gives forward security; earlier frames verify as\nbefore). Compromise is declared by an owner-signed **tombstone** in the §13 registry `{rappid, revoked_utc}`; a verifier **MUST** refuse any `sig` by a\ntombstoned key on a frame whose `utc` ≥ `revoked_utc`, checking tombstones at verification time (§7.5 step\n6). \"Owner-signed\" means a `sig` verifying with `kid` == the registry's designated `estate_owner` rappid\n(§13). A consumer **MUST NOT** infer authorship from an unsigned frame (keyless rappids assert location,\nnot authorship).\n\n## 11. Conformance classes\n- **Producer:** emits only §4 JCS/I-JSON bytes, §5 domain-separated full-SHA-256 addresses, §6 rappids\n  minted per §6.2, §7.1 eleven-key frames, §9 `rapp/1-egg` variants — and **no legacy form**.\n- **Consumer:** runs the full §7.5 checklist (incl. 1a binding), §9.3 egg verification, §10 signature +\n  key-discovery + tombstone checks, canonicalizes legacy ids on read (§6.3), refuses on any failure, never\n  repairs/reparents/rolls back (§7.6).\n- **Router/Mirror:** invents no endpoints (§8), declares subordination to\n  `kody-w/rapp-1` for protocol semantics, and serves only\n  provenance-stamped hash-matching mirrors. Estate-specific product scope is\n  resolved separately through that estate's signed registry and master plan.\n\n### 11.1 Immutable Grail kernel conformance\nAn estate declares a Grail kernel through the exact §13.3 `grail-kernel` entry. Its `release_scope`\nselects the release family to which the pin applies; a registry **MUST** contain at most one\n`grail-kernel` entry for any release scope. Its entry-level `sig`\n**MUST** verify under `declared_by`, which **MUST** be the estate owner in effect at `activated_utc`\n(§13.2); `activated_utc` **MUST NOT** be more than 300 seconds after the verifier's first-seen time for\nthat entry. The pin activates locally when a consumer first accepts an authenticated, non-rollback\nregistry containing that valid declaration. Until then it is structural evidence only. The Grail is\nidentified by `grail_id`, never by a mutable branch, tag, repository name, or product label. Once\nactivated, the pin is a permanent compatibility anchor, not a moving release channel:\n\n1. Every conformance evaluation **MUST** receive `release_scope` from an authenticated owner-controlled\n   release policy, never from candidate bytes or candidate-controlled configuration, then resolve its\n   one `grail_id` exclusively from the activated, persisted §13.3 binding. If the policy repeats\n   `grail_id`, that value is only a consistency assertion and **MUST** byte-equal the registry result; it\n   cannot select or rebind the pin. Every ring and release/deployment stage, including development,\n   qualification, Preprod, installation, and production verification, **MUST** compare the candidate's\n   Grail path to that exact binding, SHA-256, and byte length.\n2. A missing, changed, substituted, or unmeasured Grail byte is `kernel-drift` and **MUST** fail closed.\n   Approval, urgency, compatibility claims, and semantic equivalence cannot waive byte inequality.\n3. A pipeline **MUST NOT** silently restore the pinned file after testing a different file. The exact\n   release-shaped artifact containing the immutable Grail bytes **MUST** itself pass the release gates.\n4. Every gate **MUST** resolve every archive, container, wrapper, environment override, symlink, and\n   filesystem indirection to one regular runtime entry-point file under the immutable release root;\n   refuse links and ambiguous alternatives; verify its bytes; and bind the release digest, resolved\n   entry-point path, `release_scope`, `grail_id`, raw SHA-256, and byte length into its evidence.\n5. Every gate that executes the kernel **MUST** bind verification atomically to execution from a sealed\n   immutable object or snapshot. An already-open descriptor is sufficient only when its backing bytes\n   are under platform-enforced write exclusion for the entire verification-through-consumption interval\n   and the interpreter/loader consumes that exact descriptor without reopening a pathname. An immutable\n   content-addressed release root is sufficient only when no concurrent principal can modify it. A\n   hash-then-path-launch without one of those guarantees is nonconformant. At least one execution gate for\n   every supported production platform **MUST** perform this proof before release approval. Merely\n   carrying an unused matching file is insufficient. A stored transpiled, bundled, generated, or patched\n   derivative is different kernel bytes and requires a new `grail_id`; ordinary interpreter/JIT\n   compilation directly from the pinned bytes is permitted when no alternate stored kernel is selected.\n6. New implementation behavior **MUST** live outside the Grail kernel and **MUST NOT** alter any\n   RAPP-visible canonical form or wire semantic except through the registration and evolution rules of\n   §§7, 9, 12, and 13.\n7. If required behavior cannot be expressed outside the pin, the implementation **MUST** report an\n   incompatibility. It **MUST NOT** edit the Grail and continue under the same identity.\n8. Different kernel bytes produce a different `grail_id` and therefore are a different Grail. A new\n   `grail-kernel` entry may coexist and may name the old `grail_id` as `predecessor`, but it **MUST NOT**\n   overwrite, retag, alias, or redefine the prior Grail. A successor uses a new `release_scope`; an\n   existing scope is never rebound. A non-null `predecessor` **MUST** name an earlier accepted\n   `grail-kernel` entry and **MUST NOT** form a cycle. A registry **MUST** contain at most one\n   `grail-kernel` entry for each `grail_id`.\n9. On first activation a consumer **MUST** persist the full canonical `grail-kernel` entry. Every later\n   accepted registry **MUST** retain that entry byte-for-byte. Removal, mutation, or a second entry for\n   the same `grail_id` is a permanent `kernel-drift` refusal even when `registry_seq` increased.\n\nThis rule governs release topology rather than the §8 wire shape, so it does not add a frame member,\nendpoint, compatibility shim, or alternate `rapp/1` encoding.\n\n### 11.2 Operational conformance profiles\nRAPP/1 defines the substrate. Two subordinate operational profiles define how a production AI changes\nwithout mutating that substrate or the serving system underneath users:\n\n- **RAPP CI/CD** (`rapp-cicd/1`) — `protocols/rapp-cicd/1/SPEC.md`; immutable release capsules,\n  ordered qualification evidence, exact-candidate promotion, Preprod, and rollback/restore proof.\n- **RAPP Deploy** (`rapp-deploy/1`) — `protocols/rapp-deploy/1/SPEC.md`; isolated serving/candidate\n  lineages, cellular rollout, progressive exposure, expiring AI-health evidence, quarantine, and exact\n  rollback.\n\nThe profiles are RAPP/1 applications, not alternate wire versions:\n\n1. Their payloads **MUST** be §4 canonical I-JSON and are identified by\n   `H(\"rapp/1:particle\", payload)`.\n2. Authoritative profile payloads **MUST** travel in signed RAPP/1 frames using a registered compatible\n   kind. Local unsigned files are drafts, fixtures, or caches and cannot authorize promotion or traffic.\n3. They **MUST NOT** add a transport endpoint beside §8 `POST /chat`, redefine any RAPP/1 primitive, or\n   weaken §11.1.\n4. An estate activates a profile through an authenticated §13.3 `protocol` entry pinning its exact\n   repository, path, and SHA-256. A moving branch is discovery, never authority.\n5. A claim of **RAPP production conformance** requires both profiles. Core Producer, Consumer, and\n   Router/Mirror implementations remain conformant without implementing production operations.\n6. Fixed envelope keys carry the safety invariants. Policy-defined check identifiers, component kinds,\n   health objectives, and resilience controls are extension points; adding one does not change the\n   profile token or the RAPP/1 wire.\n7. A consumer **MUST** refuse unknown required policy semantics. It may preserve and relay unknown\n   optional evidence, but may not treat it as satisfying a requirement it does not implement.\n\nThe executable reference validators are `rapp_cicd.py` and `rapp_deploy.py`; controlled profile vectors\nare in `operations_conformance.py`. JSON Schemas define structural shape, while the reference validators\nenforce ordering, identity, temporal, and cross-document rules that JSON Schema cannot express.\n\n## 12. Versioning, evolution, no-legacy\nRAPP is a **living standard** (WHATWG): revised in place, never forked into parallel versions; a `name/X.Y`\nlabel **MUST NOT** ever denote two shapes (Art. II) — a shape change moves the token (§7.1). Published\ncontent-addressed artifacts are **immutable** (SemVer/crates). Within an estate there is **no perpetual\nbackward compatibility** for the estate's own artifacts and retired legacy encodings (Art. III): a change\nto such a form is a **total migration** of every instance + **deletion** of the old form. Sealed re-genesis\nhistory (§12.1) is the retained live-stream exception and is not \"legacy compatibility.\"\n\n**The `rapp/1` wire is frozen (rev-15, Art. 18).** No revision of this standard may change a form a\n`rapp/1` artifact is verified by: canonicalization (§4), the hash function and its tags (§5), the rappid\ngrammar and mint (§6.1, §6.2), the eleven-key envelope and its two addresses (§7.1, §7.3), the consumer\nchecklist (§7.5), the two wire forms and the `/chat` shapes (§8), or the egg container and address (§9.1).\nA change to any of those is not a revision; it moves the token to `rapp/2`, specified beside this\ndocument, and `rapp/1` artifacts keep verifying under this document forever. A consumer **MUST NOT**\nrefuse a `rapp/1` artifact because a later token exists. Everything Art. IV names still grows under\n`rapp/1`: registered kinds, egg variants, error codes, registry entry types, vocabulary, subordinate\nprofiles, and the registry itself. The frozen forms are what a stranger's implementation, written once\nand never updated, relies on; they are the reason an independent implementation can be finished.\n\nImmutable specification-governance history is a separate narrow exception:\nrev-5 through rev-13 anchor frames retain interpretable immutable pointer\npayloads so their ratified normative bytes remain resolvable. They are\nhistorical authority records, not accepted live legacy protocol forms. A\nproducer **MUST NOT** emit the pointer-only revision profile after rev-13.\n\n### 12.1 Re-genesis (converging an immutable chain — one owner-authorized operation)\n1. **Terminal seal:** `seal = Hb(\"rapp/1:seal\", head_octets)`. `head_octets` is the exact octets of the old\n   head's record **as retained under `legacy/`** (step 4): for a one-frame-per-file store, the retired\n   file's full octets; for a line-oriented log, the head's line **excluding** its trailing terminator. The\n   retained `legacy/` artifact is the verification reference for the seal, and retirement **MUST** preserve\n   those octets bit-exact. The step-3 `genesis` registry entry **SHOULD** record the `legacy/` artifact's\n   repo+path so a consumer **MAY** verify the seal against it. (Defined for every legacy shape, including\n   ones that cannot be §7.3-hashed.)\n2. **New genesis:** emit `seq`=0, `prev`=null, `kind` = the registered re-genesis kind **of the stream's\n   family** — `memory.re-genesis`, `swarm.re-genesis`, or `body.re-genesis` (three §13 kinds, used only\n   here) so the frame satisfies §7.2 family↔stream compatibility for any stream — `sig`≠null owner-signed\n   (§10, §13 `estate_owner`), `payload` = `{\"migrated_from\":{\"stream_id\":<old>,\"terminal_seal\":<seal>,\n   \"terminal_seq\":<n>}}` and no other members. A consumer **MUST** treat any `*.re-genesis` kind as the sole\n   re-genesis marker for its family and refuse an unsigned/non-owner one.\n3. **Register (the linearization point):** append a §13.3 `genesis` entry mapping the `stream_id` to the new\n   genesis's `frame_hash`, **and flag every prior `genesis` entry for that `stream_id` `deprecated`** — the\n   first convergence included (it deprecates the creation-time genesis), so exactly one non-deprecated entry\n   always remains. A consumer resolves the current genesis **only** via that sole non-deprecated entry. A\n   **concurrent** second registration fails closed (the append is the linearization point, Art. IX); a\n   later fork/brick (§7.6/§14) is a fresh owner-authorized convergence that appends again and re-deprecates.\n4. **Retire:** move old frames under `legacy/` — retained as immutable sealed history, never served as\n   current, never extended, never read as live chain. No live frame may set `prev`/`prev_wave` to a retired\n   hash (a dangling ref is a drift finding).\n5. Keep the old `stream_id` unless the identity itself re-anchored (§6.3), in which case the registry entry\n   also records `old_stream_id → new_stream_id`.\n6. Two frames with equal `stream_id`+`seq` from different eras are disambiguated **solely** by descent from\n   the current registered genesis. Re-genesis is one-time per convergence; a repeat *of the same\n   convergence* is the concurrent case (step 3, fails closed).\n\n### 12.2 DOGG specification revision chain\n\nThe RAPP/1 revision content is the append-only JSONL stream at\n`anchor/chain.jsonl`. The chain's particle, wave, and predecessor hashes prove\nbyte integrity and linear history; they do **not** authenticate who selected a\nhead or ratified an amendment. Until a separately authenticated RAPP\nregistry/checkpoint is ratified, authority is selected by owner-ratified\nacceptance of a chain snapshot onto protected canonical\n`refs/heads/main` at `https://github.com/kody-w/rapp-1`. A consumer starting\nfrom an out-of-band pinned accepted commit and head frame hash has the same\nimmutable selection evidence. An internally valid fork is not authoritative\nmerely because its hashes verify.\n\nEvery protocol adjustment **MUST** append exactly one valid successor frame:\n\n- `spec` remains `\"rapp/1\"`, the envelope remains exactly eleven keys, and the\n  allowed registered anchor kind is `body.pulse`; this profile does not create\n  a new kind or alter canonicalization, hashing, or registered-kind semantics;\n- `stream_id` remains the bootstrap-pinned anchor stream, `seq` is contiguous,\n  `prev` names the predecessor's `payload_hash`, `prev_wave` and `sig` are\n  `null`, and the applicable §7.5 integrity checks hold;\n- the frame's `frame_hash` is the durable protocol-revision identity.\n  Human names such as `rev-14` are lookup labels/views, never identities.\n\n#### 12.2.1 Immutable bootstrap boundary\n\nVerification begins from the frozen `rapp-anchor-bootstrap/1` profile published\nthrough `anchor/bootstrap/index.json`. The index names a\n`anchor/bootstrap/sha256-<raw-profile-sha256>.json` object and pins the exact\nstdlib verifier at `anchor/bootstrap_verify.py` by raw SHA-256 and byte length.\nThe profile fixes the exact-integer JCS subset and limits, particle/wave\ndomains, eleven frame keys, timestamp/sequence/predecessor rules, canonical\nrepository and protected ref, anchor stream ID, genesis frame and payload\nhashes, `body.pulse` anchor profile, null signature/wave fields, and byte/depth\nlimits needed to verify this chain.\n\nThe content-addressed bootstrap profile is immutable. Changing it requires a\nnew bootstrap schema/version and a new external ratification; mutating\n`rapp-anchor-bootstrap/1` in place is refusal. Its initial authenticity is\nnecessarily external — owner-ratified protected canonical main or an\nout-of-band pinned profile hash/immutable commit — because neither a chain nor\ncode fetched with that chain can circularly authenticate its own parser.\n`rapp.py` remains the complete reference implementation and is cross-checked,\nbut it is not the mutable bootstrap trust pin.\n\n#### 12.2.2 Revision payloads and historical exception\n\nFrames through rev-13 retain their immutable legacy pointer fields:\n`canonical_repo`, a full 40-lowercase-hex `commit`, safe relative\n`normative_path`, raw-file `normative_sha256`, and decimal-string\n`normative_bytes`. A resolver **MUST** construct only an immutable\ncommit-pinned GitHub Raw URL from those fields, fetch the bytes, and verify\nlength and raw SHA-256 before use. A branch or tag name in `commit`, an unsafe\npath, malformed UTF-8, a byte-order mark, or a hash/length mismatch is refusal.\nPath validation occurs on the original string before path-library\nnormalization: empty, absolute, `.`/`..`, empty components, repeated slash,\nleading `./`, trailing slash, backslash, percent-encoded ambiguity, or any\nvalue whose reconstructed POSIX form differs is refused.\nThese pointer payloads are immutable governance history under Article 3's\nnarrow exception; they **MUST NOT** be emitted for rev-14 or later.\n\nRev-14 and each successor using this profile carries all normative text inside\nthe chain frame. Its payload **MUST** include\n`schema:\"rapp-spec-revision/1\"`, a unique `revision`, and both\n`previous_revision` and `previous_normative_sha256` matching the immediate\npredecessor. It preserves the useful legacy fields above, carries the\npublication/ratification metadata defined below, and adds exactly this\n`normative` object:\n\n```json\n{\n  \"media_type\": \"text/markdown; charset=utf-8\",\n  \"text\": \"<exact normative SPEC.md Unicode text>\",\n  \"sha256\": \"<lowercase SHA-256 of text encoded as UTF-8>\",\n  \"bytes\": 123\n}\n```\n\n`normative.text` **MUST** encode as UTF-8 without a byte-order mark;\n`normative.sha256` and `normative.bytes` **MUST** match those exact octets and\nthe corresponding legacy `normative_sha256` and `normative_bytes`. The complete\ncanonical frame remains subject to §4's 1 MiB limit. Inline revisions require\nonly the selected, verified chain bytes once fetched; their commit/path fields\nare immutable provenance, not a second source for normative text.\n\nThe payload's `publication` object, repeated in the beacon and revision index,\nrecords: canonical repository `https://github.com/kody-w/rapp-1`; protected ref\n`refs/heads/main`; selection by owner-ratified acceptance; the accepted\ncanonical-main commit as linearization point; prohibition of history\nreplacement; mandatory rebase/regeneration for a competing append; rev-14\nratification under rev-13 Article 14; application of this chain-append process\nfrom rev-15 onward; and `authenticated_registry_checkpoint:null` until one\nactually exists. This metadata **MUST NOT** be interpreted as a signature or\nauthenticated registry.\n\n#### 12.2.3 Content-addressed publication and resolution\n\nEvery chain frame **MUST** also be published, without a trailing line\nterminator, at:\n\n```text\nanchor/frames/<frame_hash>.json\n```\n\nA fetch through mutable main is discovery only. Given frame hash `F`, a\nstranger may fetch\n`https://raw.githubusercontent.com/kody-w/rapp-1/main/anchor/frames/F.json`,\nparse it under the pinned bootstrap, and accept the object only if its computed\nwave equals `F`. For accepted snapshot commit `C`, the immutable URL is\n`https://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/frames/F.json`.\nWrong content at the correct hash-derived path is refusal.\n\n`anchor/index.json` is a deterministic generated index from `seq`, revision\nlabel, frame hash, and payload hash to those objects. It carries no independent\nauthority: a consumer **MUST** verify each selected object and match the index\nand beacon to the fully verified chain. Resolution by frame hash uses the path\nalgorithm directly; resolution by payload hash or sequence uses the verified\nindex; resolution by revision label is a view over it. The fixed pre-profile\nrev-5 pulses share one historical label, so the `rev-5` view resolves to the\ngreatest matching `seq`, while every pulse remains directly resolvable by\nsequence and hashes.\n\nA consumer **MUST** verify the chain from the bootstrap-pinned genesis before\nusing a revision as selected history. It **MUST** refuse an invalid frame shape,\nparticle, wave, or `prev`; a fork or duplicate `seq`; duplicate frame/payload\nhashes; a duplicate profiled revision; an unsupported schema; a legacy\npointer-only frame after rev-13; malformed UTF-8; normative hash/length drift;\nbootstrap/index/object drift; or an object absent from the selected chain.\n\n`orient.json` is only a beacon to the head. Its sequence, frame hash, payload\nhash, bootstrap/index pins, authority-selection metadata, and every retained\nhead mirror — including `registered_kinds`, vocabulary, operational profiles,\nfoundation, philosophy, and Constitution metadata — **MUST** be regenerated\nfrom and match the verified head. While the beacon schema remains\n`rapp/1-anchor`, `spec.normative_path` **MUST** remain as a compatibility alias\nequal to `spec.materialized_path`. `SPEC.md` **MUST** reproduce the selected\nhead byte-for-byte. The Atom feed and mutable main URLs are discovery only.\n\nMaterialization and immutable-pointer caching **MUST** use bounded reads and\nsame-directory atomic replacement without following a symlink in the\ndestination leaf or path. A symlink, unsafe directory component, oversized\ncache entry, content change during read/write, or compare-and-swap mismatch is\nrefusal; the requested leaf is replaced, never the symlink target.\n\nAfter acceptance, let `C` be the full 40-hex canonical-main commit containing\nthe accepted snapshot. The immutable checkpoint URLs are:\n\n```text\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/chain.jsonl\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/orient.json\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/index.json\n```\n\nThe authority linearization point is the owner-ratified acceptance of `C` onto\nprotected canonical main, not creation of a local frame, a feed event, or a\nhash alone. A stale competing append **MUST** rebase onto the accepted head and\nregenerate. Force-push or history replacement of accepted authority is\nprohibited.\n\n#### 12.2.4 Rev-14 transition and draft replacement\n\nRev-14 is ratified under rev-13 Article 14. Owner acceptance of the prepared\nchange onto canonical protected main makes the final rev-14 frame effective;\nthe new chain-append process governs rev-15 onward. Before that acceptance,\nrev-14 artifacts are unpublished drafts. A later commit in the same\nowner-ratified change may deterministically replace the one unpublished rev-14\ndraft line/object and update dependent hashes, but **MUST** preserve every\nrev-5 through rev-13 line byte-for-byte and **MUST NOT** represent the replaced\ndraft as accepted history.\n\nThe publication generator **MUST** hold one cross-process exclusive lock across\nread, verification, generation, comparison, and publication. Immediately\nbefore replacing `chain.jsonl` it **MUST** re-read and verify the on-disk head\nand compare the complete expected prefix; a stale writer or changed prefix is\nrefused. Supporting content-addressed artifacts are published first, the\nauthority chain is compare-and-swap replaced next, and the beacon is replaced\nlast, with file and parent-directory synchronization. Because the chain is\nauthority content and the beacon is only a derived view, interruption after a\nvalid chain replacement may leave a stale or missing beacon; the next locked\nrun **MUST** deterministically regenerate it from the verified chain rather\nthan refusing the valid head forever.\n\nThis chain and beacon are unsigned. They provide integrity after authority\nselection, not authorship, and implementations **MUST NOT** fabricate a\nsignature or authenticated registry/checkpoint state for them.\n\n## 13. The registry — an estate's signed root of trust (append-only)\nEach estate selects an owner-controlled `canonical_source` for its\n`schema:\"rapp/1-registry\"` document. The kody-w reference estate may publish\nits registry through `kody-w/RAPP` or another owner-authorized location, but\nthat estate instance cannot alter this protocol. Because §7.6 head resets, §10\nkey discovery, tombstone revocation, and ownership all resolve through the\nselected registry, it is the **root of trust for that estate** and is itself\nauthenticated (an unsigned mutable file at the root of the trust graph would\nforge that estate).\n\n### 13.1 Trust anchor and registry authentication\n- The one bootstrap axiom is the **`estate_owner` rappid string** itself: since a keyed tail is\n  `Hb(\"rapp/1:rappid\", SPKI_DER)`, the rappid **is** a self-certifying key fingerprint, distributed\n  out-of-band exactly once (QR, invite, docs) the way a root-CA certificate is.\n- The registry document **MUST** carry a top-level `registry_seq` (uint53) and a detached §10 JWS `sig` over\n  `canonical(registry \\ {sig})` with `kid` = the `estate_owner` rappid. A consumer **MUST** verify this\n  signature against an SPKI whose `Hb(\"rapp/1:rappid\", SPKI_DER)` equals the anchor rappid's tail (the SPKI\n  may travel alongside the registry — the tail check authenticates it) and **MUST** refuse an unsigned or\n  non-verifying registry.\n- **No rollback:** a consumer persists the highest `registry_seq` it verified and refuses any registry with\n  a lower one (mirrors §7.6). **Freshness:** a consumer **MUST** obtain the registry from `canonical_source`\n  or a provenance-stamped (Art. VIII) mirror of it, **SHOULD** refresh before any §7.5-step-6 or §7.6\n  head-reset decision, and **MUST** report a verification made against a registry older than its staleness\n  policy as *stale*, not *clean*.\n\n### 13.2 Owner succession (time-scoped authority)\n\"Owner-signed\" means: the `sig` verifies per §10 **and** `kid` is the estate-owner **in effect at the\nartifact's `utc`** — the current `estate_owner` or any predecessor reachable through the registry's\nre-anchor records (§13.3), with the artifact's `utc` inside that owner's tenure `[record.utc, successor.utc)`.\nVerification uses the owner in effect at the artifact's time, **never only the current one** (so a routine\nowner key rotation never invalidates historical re-genesis frames or tombstones). Estate-owner **root-key\ncompromise** is recovered only by re-distributing a new trust anchor out-of-band (§13.1) — it cannot be\nexpressed inside the registry it signs.\n\n### 13.3 Entry types (each a §4 value; document `schema:\"rapp/1-registry\"`)\nThe registry is an I-JSON document; every entry is append-only (never removed/renamed; retirement is a\n`deprecated:true` flag). Entry types and their exact members:\n- **protocol** `{type:\"protocol\", name, spec_repo, spec_path, spec_hash, deprecated}` — an estate\n  adoption pin, never a power to redefine a protocol. An entry with `name:\"rapp/1\"` that is used for a\n  current-conformance claim **MUST** set `spec_repo:\"https://github.com/kody-w/rapp-1\"`,\n  `spec_path:\"SPEC.md\"`, and `spec_hash` to a normative SHA-256 published by a verified frame in this\n  repository's anchor chain. A historical RAPP/1 pin may be retained only as `deprecated:true`; it does\n  not override the current anchor. Other protocol entries are subordinate to their own canonical\n  authorities and **MUST NOT** claim the `rapp/1` name or namespace.\n- **kind** `{type:\"kind\", kind, family, deprecated}` (incl. the three `*.re-genesis` kinds)\n- **egg-variant** `{type:\"egg-variant\", variant, deprecated}` · **error-code** `{type:\"error-code\", code}`\n  (both closed namespaces; unregistered value = not conformant)\n- **genesis** `{type:\"genesis\", stream_id, frame_hash, deprecated, old_stream_id?, new_stream_id?}` — **every**\n  stream registers its creation genesis; re-genesis appends a new one and deprecates all prior (§12.1 step 3);\n  §7.6's \"registered genesis\" is the sole non-deprecated `genesis` for a `stream_id`.\n- **spki** `{type:\"spki\", rappid, spki_der_b64, deprecated}` — the §10 key-discovery source.\n- **tombstone** `{type:\"tombstone\", rappid, revoked_utc, sig}`, `sig` owner-signed over `canonical(entry \\ {sig})`.\n- **re-anchor** `{type:\"re-anchor\", old_rappid, new_rappid, case:(\"upgrade\"|\"rotation\"|\"compromise\"|\"tag-migrate\"),\n  utc, sig, old_key_sig?}` — `sig` owner-signed; `old_key_sig` a §10 JWS by the **old** key over\n  `canonical(entry \\ {sig,old_key_sig})`, REQUIRED for `case:\"rotation\"`. This is the normative succession record (§13.2).\n- **grail-kernel** `{type:\"grail-kernel\", release_scope, grail_id, repository, immutable_ref,\n  object_format, commit, path, mode, blob, sha256, size_bytes, activated_utc, predecessor, declared_by,\n  sig}` — exactly these members. `release_scope` is an absolute HTTPS URI selected by the estate owner;\n  no two entries may share it. `grail_id` is\n  `\"grail:\" || Hb(\"rapp/1:grail\", kernel_bytes)`; `repository` is an absolute HTTPS URI;\n  `immutable_ref` is a full `refs/tags/...` name that **MUST** resolve exactly to `commit`;\n  `object_format` is `\"sha1\"` or `\"sha256\"` and fixes the required lowercase hexadecimal length of\n  `commit` and `blob`; `path` at `commit` **MUST** resolve through the repository tree to exactly one\n  regular blob with `mode` `\"100644\"` or `\"100755\"` and object id `blob`;\n  `path` is a relative NFC POSIX path with no empty, `\".\"`, or `\"..\"` component; `sha256` is the raw\n  kernel bytes' 64-lowercase-hex SHA-256; `size_bytes` is their positive `uint53` length;\n  `activated_utc` has the exact §7.4 form; `predecessor` is null or another `grail_id`; `declared_by` is\n  a keyed rappid; and `sig` is a detached §10 JWS whose protected `kid` equals `declared_by`, over\n  `canonical(entry \\ {sig})`. The entry is additionally covered by the registry's §13.1 signature. A\n  consumer verifies the entry signer as the estate owner in effect at `activated_utc`, verifies the\n  referenced bytes, recomputes both hashes, persists the canonical entry on first activation, applies\n  §11.1, and refuses a missing/mutated prior binding, duplicate `grail_id`, or locator whose bytes\n  disagree.\n- **estate_owner** `{type:\"estate_owner\", rappid}` (exactly one non-deprecated) · **master-plan**\n  `{type:\"master-plan\", repo, path}` (Fed. Const. Art. VII).\n\n§7.5 steps 1–5 are time-independent (append-only lookups); **only** step 6 (tombstones) and §13.2 owner\ntenure are time-scoped, and both are monotone given the §13.1 no-rollback rule.\n\n## 14. Security considerations\n- **Integrity:** every object is domain-separated content-addressed (§5); a hostile mirror cannot alter\n  bytes without breaking the hash, so *history is safe given a trusted head*.\n- **Head freshness is not self-certifying:** the chain authenticates history, not which head is current; a\n  hostile mirror may serve a stale/forked head. Consumers counter with the §7.6 monotonic-head rule; swarm\n  heads **SHOULD** be owner-signed.\n- **Cross-stream replay:** without §7.5 step 1a, any genesis/segment of stream A replays as stream B (seq=0,\n  prev=null always pass). Step 1a's stream binding is mandatory.\n- **Address-space confusion:** §5 domain tags make a particle, wave, egg, or rappid tail with equal hex\n  non-interchangeable; stores key by `(space, hash)`.\n- **Canonicalization attacks:** the §4 I-JSON input-domain profile (no duplicate keys, no lone surrogates,\n  exact binary64, no normalization ambiguity) removes hash-splitting and NFC-twin vectors.\n- **Identity forgery / key compromise:** authorship requires a keyed rappid + valid §10 `sig`; rotation is\n  §6.3 re-anchor (verifiable authorization, §6.3/§13.3 — a self-asserted `_migrated_from` is refused);\n  compromise is a §13 tombstone enforced at verify time. Because a tombstone gates on the frame's\n  producer-controlled `utc`, a compromised key can still emit frames stamped just below `revoked_utc`; after\n  a compromise the owner **SHOULD** advance affected stream heads (or re-genesis) past `revoked_utc`.\n- **Root of trust:** the registry is the estate's signed root (§13.1); it is authenticated by an owner\n  signature anchored to the out-of-band `estate_owner` rappid fingerprint, `registry_seq`-monotonic against\n  rollback, and freshness-checked (a stale registry silently un-revokes keys and hides re-geneses).\n- **Producer-controlled `utc` (DoS/merge bias):** a future-dated head can brick a stream (successors refused\n  as earlier) and bias UTC-first merges. A consumer **SHOULD** refuse a frame whose `utc` exceeds receipt\n  time by >300 s, and adversarial-scope merges **SHOULD** rank by `min(utc, first-seen)`; a bricked stream\n  converges by re-genesis (§12.1).\n- **Sealed-artifact limits:** a public mirror sees ciphertext and metadata. AES-GCM protects confidentiality\n  only while the DEK remains secret; a recipient that has lawfully decrypted plaintext can copy it.\n  Revocation stops future wrapped-key release, not prior possession. Shared passwords, embedded master keys,\n  moving-branch URLs, nonce reuse under one DEK, and claims that bytecode cannot be inspected after\n  decryption are non-conformant security postures (§9.2.1).\n- **Kernel substitution:** testing mutable ring bytes and restoring the Grail only after approval creates\n  an untested release. §11.1 requires the release-shaped artifact to contain the pinned bytes before its\n  tests, attestations, and approval; a digest mismatch is a blocking `kernel-drift` finding.\n- **Kernel registry rollback/rebinding:** persisting only `registry_seq` does not preserve an activated\n  Grail declaration across a malicious higher-sequence registry. Consumers also persist every activated\n  canonical `grail-kernel` entry and reject its later removal, mutation, or duplication (§11.1).\n\n## 15. References\n[RFC 2119] [RFC 8174] requirement terms · [RFC 8259] JSON · [RFC 7493] I-JSON · [RFC 8785] JCS ·\n[FIPS 180-4] SHA-256 · [RFC 3986] URI · [RFC 5234] ABNF · [RFC 7405] case-sensitive ABNF · [RFC 9562] UUID\n(obsoletes RFC 4122) · [RFC 5280] X.509 SPKI · [RFC 7515] JWS · [RFC 7797] unencoded JWS payload ·\n[RFC 7518] JWA/ES256 · [RFC 8037] EdDSA in JOSE · [RFC 6979] deterministic ECDSA · [RFC 3339] timestamps ·\n[NIST SP 800-38D] AES-GCM · [RFC 2104] HMAC · [RFC 5869] HKDF · [RFC 7516] JWE · [ECMA-262] ECMAScript.\n\n---\n\n### Revision log\n- **rev-15 (the wire freeze)** — §12 freezes every form a `rapp/1` artifact is verified by (§4, §5,\n  §6.1–6.2, §7.1, §7.3, §7.5, §8, §9.1); a change to any of them is `rapp/2` beside this document, never a\n  revision of it, and `rapp/1` artifacts verify forever. Art. III is scoped to an estate's own artifacts.\n  Registration, vocabulary, profiles, and the registry keep growing under `rapp/1` (Art. IV). Constitution\n  Article 18 restates the rule.\n- **rev-14 (DOGG specification-chain authority)** — makes the append-only\n  `anchor/chain.jsonl` frame history carry normative specification content\n  while protected canonical-main acceptance selects authority; defines the\n  frame hash as durable revision identity; embeds the normative Markdown in a\n  normal `body.pulse`; retains immutable rev-5–rev-13 pointer history; freezes\n  a content-addressed bootstrap verifier profile; publishes hash-addressed\n  frame objects and a deterministic index; makes `SPEC.md` a materialized\n  selected-head view; and records the rev-13 Article 14 transition without\n  inventing signatures or changing any RAPP/1 wire primitive.\n- **rev-13 (public governance closure)** — makes the ratified public Protocol\n  Constitution final for protocol governance; limits private governance and\n  master plans to estate/product concerns; makes registry `protocol` entries\n  subordinate adoption pins; verifies the exact canonical RAPP foundation\n  object before anchoring; and aligns every public teaching surface with\n  estate-specific registry authority.\n- **rev-12 (foundation/protocol boundary)** — records `kody-w/RAPP` as the\n  canonical public foundation and product home; limits `kody-w/rapp-1` to\n  protocol authority; ratifies the complete public Protocol Constitution; makes\n  registries explicit estate instances rather than protocol authorities; pins\n  the canonical foundation commit and philosophy hash; and removes any\n  implication that protocol publication transfers product, brand, company, or\n  ownership authority.\n- **rev-11 (planetary operations profiles)** — constitutionalized immutable candidate/serving lineage\n  separation; defined RAPP CI/CD (`rapp-cicd/1`) and RAPP Deploy (`rapp-deploy/1`) as subordinate,\n  registry-pinned production profiles; required exact-candidate qualification, production-shaped\n  Preprod, cellular progressive exposure, expiring AI-health evidence, state/data continuity,\n  automatic containment, and exact rollback while retaining policy-defined extension points; and\n  defined typed, non-authoritative offspring/cross lineage without changing the egg or frame envelopes.\n- **rev-10 (sealed artifact + Grail execution closure)** — registered the `sealed` egg variant for\n  globally mirrorable public ciphertext with signed manifests and scoped recipient key release (§9.2.1);\n  added the `rapp/1:sealed-aad` and `rapp/1:sealed-key-request` address spaces; retained rev-9's exclusive\n  `release_scope` selection, persisted Grail binding, and verification-to-execution protections; and made\n  both confidentiality limits and kernel drift release-blocking.\n- **rev-9 (Grail selection and execution closure)** — makes release policy select only\n  `release_scope`, resolves `grail_id` exclusively through the activated persisted registry binding,\n  and closes verification-to-execution races by requiring a sealed immutable object/snapshot or\n  platform-enforced write exclusion through byte consumption.\n- **rev-8 (immutable Grail closure)** — makes pin selection deterministic through `release_scope`,\n  defines the exact signed §13.3 `grail-kernel` entry and owner-at-time activation, requires consumers\n  to persist every accepted binding, and specifies repository-object and executed-entry-point\n  verification across interpreted and derived runtimes.\n- **rev-7 (immutable Grail constitution)** — defines the Grail kernel by the SHA-256 of its exact bytes\n  (§3), makes every ring and release/deployment stage verify both the pin and the actually executed entry\n  point (§11.1), forbids post-test substitution, and makes changed bytes a different Grail rather than a\n  mutation. This is release governance only; the RAPP wire and existing canonical forms are unchanged.\n- **rev-6 (instantiation lineage)** — added §9.4's fresh per-install instance identity and immutable\n  `grown_from` lineage, closing the hatch seam without changing the frame or egg envelopes.\n- **rev-5 (war-game round 3 fold)** — folded 5 blockers + 7 majors + 7 minors, all clustered on the trust\n  model that rev-4's fixes made load-bearing: the **registry is now a signed root of trust** (§13.1) —\n  owner-signed, anchored to the out-of-band `estate_owner` rappid fingerprint, `registry_seq`-monotonic,\n  freshness-checked (B-1); **re-anchor requires a verifiable §13.3 authorization record** with old-key\n  continuity proof / tombstone / SPKI-tail check (B-2, mint-once now enforceable); **owner-succession is\n  time-scoped** so a key rotation never invalidates historical signatures (B-3); **eggs are `stored`-only**\n  (deflate is non-deterministic) with `canonical(manifest)` bytes (B-4); **invites sign under the\n  estate-owner succession** not the egg's own rappid (B-5); `egg_hash` excludes `sig` (M-1); first\n  re-genesis deprecates the creation genesis (M-2); full **registry entry schema** §13.3 (M-3); registry\n  freshness rule (M-4); egg consumer enforces §9.1 (zip-slip, M-5); rotated key refused on new frames (M-6);\n  `rapplication` exact `agent.py` (M-7); rev label, `invite` naming, sub-egg collision, rounding rule,\n  idempotency, compromise-window, seal-path (m-1…m-7).\n- **rev-4 (war-game round 2 fold)** — folded 6 blockers + 14 majors + 8 minors: domain-tagged mint\n  reconciled across Constitution/ledger (B1); §4(c) binary64 round-trip test so `0.1` is accepted (B2);\n  re-genesis head-reset exception so it isn't refused as rollback (B3); family-matched `*.re-genesis` kinds\n  so memory/swarm streams can converge (B4); whole-egg address `H(\"rapp/1:egg-manifest\",…)` + signed invites\n  + manifest self-reference resolved + deterministic ZIP/`contents` ordering (B5, M2–M4); re-anchor\n  enumerated three cases incl. key rotation (B6, M-rotation); `head_octets` pinned to the retained `legacy/`\n  artifact (M6); subsequent-convergence via `deprecated` (M7); every stream registers its genesis (M8); JWS\n  header canonical bytes + registry key-discovery + `estate_owner` designation (M9–M11); `/chat` error `step`\n  as string incl. `\"1a\"` + code namespace + session semantics (M12, m5); tombstone as the one time-dependent\n  verify check (M13); egg draft-artifact + dangling `§4` reference removed (M1, M5); calendar-valid `utc`,\n  depth convention, kind dedup/bounds (m2, m7, m8).\n- **rev-3 (war-game round 1 fold)** — folded 7 blockers + 19 majors + 12 minors from the Fable adversarial last-call:\n  I-JSON input domain + no-normalization/NFC (§4); **domain-separated hashing** (§5, the stronger option);\n  fixed `utc` byte form (§7.4); `prev_wave` by stream family not transport (§7.4); **stream-binding**\n  anti-replay (§7.5.1a); `spec` token pinned to `rapp/1` (§7.1); full JWS profile + key discovery + rotation/\n  tombstone (§10); hardened re-genesis with raw-byte terminal seal + registry linearization (§12.1); heads &\n  forks (§7.6); `/chat` fully specified (§8); **egg variants ratified into the standard**, killing the\n  6-spec collision and closing EGG-01 (§9); registry append-only (§13); type-validated verify (§7.5.1);\n  cross-stream merge tie-break (§7.4); provisional-identifier rule (§6.3); all references added (§15).\n- **rev-2** — first last-call tightening (7 self-review defects).\n- **rev-1** — initial unified draft.\n\n*The canonical protocol authority is the owner-selected, verified\nspecification chain in this repository. The canonical public RAPP foundation\nand product home remain at `kody-w/RAPP`.*\n", "sha256": "348e7d5baa94aaf2ce4c5354f3cb261f389298a04af65e271a686d3b62f7c384", "bytes": 79692}, "publication": {"canonical_repository": "https://github.com/kody-w/rapp-1", "protected_ref": "refs/heads/main", "selection": "owner-ratified acceptance of the chain snapshot onto protected canonical main", "linearization": "the accepted canonical-main commit containing the new frame", "history_replacement": "prohibited", "competing_append": "must rebase onto the accepted head and regenerate", "transition": "rev-14-ratified-under-rev-13-article-14", "chain_append_process": "governs-rev-15-and-later", "authenticated_registry_checkpoint": null}}, "payload_hash": "61a01808240e16066bdf0437933ac16b6530c939e9f31f67fac44d517f1e580c", "prev": "1ac47416e9caf174c4fdc00265ca187c244fb701ae2a7fb7211ba1385a951310", "prev_wave": null, "sig": null, "frame_hash": "6fddd2370220ca195fdbee3a7ae46a2686fc745d8e88debda26c5a6497e5756a"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 17, "utc": "2026-09-27T18:49:55.000Z", "payload": {"canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "848987cf9cb6a6534abc82a7502bea14b610911d", "commit_utc": "2026-09-27T14:49:55-04:00", "default_profile": "interop", "exchange": {"carrier": "POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward.", "idempotence": "keyed on the request's payload_hash — a retry returns the existing reply, never a second one.", "rule": "the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.", "shape": "push a frame in, get a frame back shaped by what you pushed — ONE hop."}, "frame_keys": ["spec", "kind", "stream_id", "seq", "utc", "payload", "payload_hash", "prev", "prev_wave", "sig", "frame_hash"], "kind_families": {"body": {"kinds": ["body.pulse", "body.twin-pulse", "body.reconstructed", "body.re-genesis"], "logs": "an organism's biography", "stream": "body-stream (bare rappid)"}, "memory": {"kinds": ["memory.chat-turn", "memory.tool-call", "memory.save", "memory.reconstructed", "memory.re-genesis"], "logs": "one organism's life", "stream": "memory-stream"}, "swarm": {"kinds": ["swarm.guidance", "swarm.echo", "swarm.telemetry", "swarm.reconstructed", "swarm.re-genesis"], "logs": "the planetary wire", "stream": "swarm-stream (net:label)"}}, "moods": {"clear": {"profile": "interop", "when": {"conditions": "clear,sunny"}, "why": "good conditions, normal posture"}, "early": {"profile": "minimal", "when": {"hour_lt": "6"}, "why": "same"}, "night": {"profile": "minimal", "when": {"hour_gte": "22"}, "why": "low-attention hours; smallest honest context"}, "storm": {"profile": "audit", "when": {"conditions": "storm,rain,snow"}, "why": "degraded links are when drift hides; lead with verification"}}, "normative_bytes": "88831", "normative_path": "SPEC.md", "normative_sha256": "768aeefbf779925b6c937bd497ff628a5061b1e20a82a29892f6cdd5481178e1", "observed_utc": "2026-09-27T18:49:55.000Z", "profile_signals": {"author": "authoring", "build": "authoring", "check": "audit", "conform": "audit", "drift": "audit", "handshake": "interop", "install": "onboarding", "join": "onboarding", "mint": "authoring", "new": "onboarding", "stranger": "interop", "unknown-peer": "interop", "verify": "audit", "write": "authoring"}, "profiles": {"audit": {"max_rules": "8", "show": ["keys", "stale_terms"], "types": ["pattern", "gotcha"], "why": "judging conformance; refuse-never-repair and the identity law govern"}, "authoring": {"max_rules": "8", "show": ["keys", "eggs"], "types": ["gotcha", "fact"], "why": "hand-building a frame; the envelope rules are what bite"}, "interop": {"max_rules": "6", "show": ["keys", "stale_terms", "pointer"], "types": ["gotcha"], "why": "a peer may be out of date; lead with what it can get WRONG"}, "minimal": {"max_rules": "0", "show": ["stale_terms"], "types": [], "why": "smallest honest context"}, "onboarding": {"max_rules": "5", "show": ["keys", "eggs", "stale_terms", "pointer"], "types": ["fact"], "why": "new organism; needs the shape of the world, not the edge cases"}}, "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "revision": "rev-17", "rules": [{"c": "spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted.", "t": "fact"}, {"c": "Canonical form is RFC 8785 JCS and FORBIDS floats — numbers ride as strings. A float silently breaks byte-reproducibility.", "t": "gotcha"}, {"c": "payload_hash = H(\"rapp/1:particle\", payload) — content only, reproducible across instances.", "t": "fact"}, {"c": "frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) — unique per stream instance.", "t": "fact"}, {"c": "prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable.", "t": "gotcha"}, {"c": "§6.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name — sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint.", "t": "gotcha"}, {"c": "Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed.", "t": "pattern"}, {"c": "A swarm-stream frame with sig==null is refused (§7.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null.", "t": "gotcha"}, {"c": "Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs.", "t": "fact"}, {"c": "Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise — this is how N streams compose into one view.", "t": "pattern"}, {"c": "One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct.", "t": "pattern"}, {"c": "§9.4 (rev-6): hatching an egg MUST mint a fresh §6.2 identity for the INSTANCE — the artifact rappid rides the egg unchanged and is shared by every install; the instance identity never is. The instance SHOULD record grown_from = the §9.1 egg address it grew from: written at mint, immutable, null when unknown, NEVER fabricated. Lineage, not inheritance — it confers no authority, no trust, no key material.", "t": "fact"}, {"c": "§11.1 / Constitution Article 15: owner policy selects only release_scope; the activated registry selects grail_id; every ring rejects kernel-drift; execution consumes bytes from a sealed immutable object or equivalent write-excluded snapshot.", "t": "gotcha"}, {"t": "gotcha", "c": "A sealed egg is public ciphertext, not password-protected hosting: the signed manifest binds AES-256-GCM data and a scoped key service; no shared DEK belongs in the egg, URL, client, log, or frame."}, {"t": "fact", "c": "RAPP CI/CD promotes one immutable release payload hash through an ordered evidence chain; no ring may rebuild, patch, substitute, or skip the candidate."}, {"t": "gotcha", "c": "RAPP Deploy forbids in-place serving mutation: growth happens in an isolated candidate lineage and reaches users only through bounded, reversible waves."}, {"t": "pattern", "c": "A new encounter may produce an offspring or cross with a fresh identity and typed parent addresses; lineage may continue indefinitely, but every attempt is bounded and parent authority never transfers implicitly."}, {"t": "fact", "c": "kody-w/RAPP remains the public foundation and product home; kody-w/rapp-1 defines the interoperable protocol only."}, {"t": "fact", "c": "The rapp/1 wire is frozen: §4, §5, §6.1-6.2, §7.1, §7.3, §7.5, §8 and §9.1 never change under the rapp/1 token; a change is rapp/2 beside it, and rapp/1 artifacts verify forever."}, {"t": "fact", "c": "RAPP Work uses seven registered body kinds on the unchanged eleven-key frame; catalog locators, Portable Neurons, Git, raw paths, and static API documents remain inert evidence or discovery rather than authority."}, {"t": "gotcha", "c": "A completed RAPP Work migration verifies retained intent, signed evidence, unchanged source, exact rollback, and key custody before any mutation."}, {"t": "gotcha", "c": "rev-17 clarifies without changing the wire: utc digits are ASCII; noncharacters, a byte-order mark and UTF-16 input are outside §4; a §4-valid seq such as 2^53 or -0 is refused at §7.5 step 1, never before the checklist."}, {"t": "fact", "c": "Two conformant packers of one manifest emit byte-identical eggs: every ZIP header field is pinned (version needed 20, made by 0x0014, flags 0x0800, attributes 0); a consumer accepts any value only in version made by, version needed and the attributes."}, {"t": "pattern", "c": "A producer refuses what a consumer refuses: a frame builder or egg packer runs the consumer's registry-free checks on its own output and refuses rather than emit or repair."}], "vocabulary": {"body": {"status": "live", "where": "§7.2 kind family"}, "estate": {"status": "live", "where": "§9.2 egg variant"}, "grail": {"status": "live", "where": "§3 terminology; §11.1 immutable Grail kernel conformance; Constitution Article 15"}, "grown_from": {"status": "live", "where": "§9.4 instantiation — instance lineage key"}, "instance": {"status": "live", "where": "§9.4 instantiation — a hatched install; fresh §6.2 identity, never shared"}, "invite": {"status": "live", "where": "§9.2 egg variant"}, "memory": {"status": "live", "where": "§7.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate — bytes only at git 24c8fdc, sha256 690f6109…"}, "neighborhood": {"status": "live", "where": "§9.2 egg variant"}, "organism": {"status": "live", "where": "§9.2 egg variant"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 §6"}, "rapplication": {"status": "live", "where": "§9.2 egg variant"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's words are `organism` (§9.2) and `instance` (§9.4)"}, "session": {"status": "live", "where": "§9.2 egg variant"}, "swarm": {"status": "live", "where": "§7.2 kind family"}, "sealed": {"status": "live", "where": "§9.2 sealed egg variant and §9.2.1 profile"}, "rapp-cicd": {"status": "live", "where": "§11.2 and protocols/rapp-cicd/1/SPEC.md"}, "rapp-deploy": {"status": "live", "where": "§11.2 and protocols/rapp-deploy/1/SPEC.md"}, "offspring": {"status": "live", "where": "§9.4 typed lineage and PHILOSOPHY.md"}, "cross": {"status": "live", "where": "§9.4 typed multi-parent lineage and PHILOSOPHY.md"}, "wire-freeze": {"status": "live", "where": "§12 and Constitution Article 18 — the rapp/1 verified forms never change; a change is rapp/2"}, "rapp-work": {"status": "live", "where": "protocols/rapp-work/1/SPEC.md — additive organization, Hive high-water, migration, custody, and rollback"}}, "philosophy": {"canonical_repository": "https://github.com/kody-w/RAPP", "canonical_commit": "cb921ae59b5d762ce0bdd5493764cbb1c8b539fe", "canonical_path": "PHILOSOPHY.md", "canonical_sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c", "mirror_path": "PHILOSOPHY.md", "mirror_sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c"}, "operational_profiles": {"rapp-cicd/1": {"status": "live", "spec_path": "protocols/rapp-cicd/1/SPEC.md", "spec_sha256": "6d27d10103a3204f3b65a2e246462d197016bce5203dd510ba3ce209740e8278", "schema_path": "protocols/rapp-cicd/1/schema.json", "schema_sha256": "5936057868f46fc74afa00532f4aea60cfbb667c7c2f09998e1e86a0c2e629cc"}, "rapp-deploy/1": {"status": "live", "spec_path": "protocols/rapp-deploy/1/SPEC.md", "spec_sha256": "b5fc84465fb201fd97d7059997490a8fae5bf79ec55e935b0cfd9b4c787108e5", "schema_path": "protocols/rapp-deploy/1/schema.json", "schema_sha256": "aca783f3274cd865926f6b943163189fa93a7bbc4c7d4258856a54779a4a71ba"}, "rapp-work/1": {"status": "live", "spec_path": "protocols/rapp-work/1/SPEC.md", "spec_sha256": "283359355c3fe2858e28744368255683af3ed28a68e290e56c231e7d4b13c08e", "schema_path": "protocols/rapp-work/1/schema.json", "schema_sha256": "ff30f9878f12fa4ad7d93c4c205eb1cb580137a7dee87aa9d23c88a93466d19e"}}, "constitution": {"path": "CONSTITUTION.md", "sha256": "59b600d63e329de5adf11aa6dd103c82e62c72882edd899788e80fd316b21d43", "size_bytes": 17403}, "foundation": {"schema": "rapp-foundation-pointer/1", "status": "canonical-product-home", "repository": "https://github.com/kody-w/RAPP", "commit": "cb921ae59b5d762ce0bdd5493764cbb1c8b539fe", "path": "PHILOSOPHY.md", "sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c", "size_bytes": 2633, "relationship": "kody-w/RAPP is the public RAPP foundation and product home; kody-w/rapp-1 is the interoperable protocol authority"}, "schema": "rapp-spec-revision/1", "previous_revision": "rev-16", "previous_normative_sha256": "348e7d5baa94aaf2ce4c5354f3cb261f389298a04af65e271a686d3b62f7c384", "normative": {"media_type": "text/markdown; charset=utf-8", "text": "# The RAPP Protocol Suite\n### Unified normative specification of identity, canonicalization, the frame, the wire, and the egg\n\n> **Generated/materialized view.** These exact UTF-8 bytes are carried inside\n> the selected specification-revision frame in `anchor/chain.jsonl`. The frame\n> chain proves integrity and lineage; canonical owner-ratified publication\n> selects authority. Change the protocol by appending a successor frame, not by\n> treating this file as independent authority.\n\n**Status:** Owner-ratified RAPP/1 **rev-17 amendment**. It is effective iff the\nprepared chain snapshot has been accepted onto canonical protected main under\nthe transition in §12.2. **Obsoletes / consolidates:**\n`rapp-frame/2.0`, `rapp-frame/2.1`, `rapp-rappid-spec/2.0`, `rapp-protocol/1.0`, all scattered egg specs\n(§9 subsumes them), and `OSI.md`. This is the current materialized view of the single living standard;\nthe consolidated specs are retired historical record (Protocol Constitution Article 6). Rev-14 becomes\nthe published current revision when the source merge and append-only anchor update carrying these exact\nbytes complete.\n\n**Rides existing standards; invents nothing:** requirement terms [RFC 2119]/[RFC 8174]; JSON restricted to\nI-JSON [RFC 7493] over [RFC 8259]; canonicalization [RFC 8785] (JCS); hashing SHA-256 [FIPS 180-4] with\ngit-style domain separation; identifiers on the [RFC 3986] URI model; case-sensitive grammar [RFC 7405]\nover [RFC 5234] ABNF; keyless entropy UUIDv4 [RFC 9562]; keyed identity X.509 SPKI [RFC 5280]; signatures\ndetached unencoded JWS [RFC 7515]/[RFC 7797], EdDSA [RFC 8037] / ES256 [RFC 7518]/[RFC 6979]. RAPP is a\n*profile* over these, as HTTP profiles TCP/URIs/MIME.\n\n---\n\n## 1. Introduction\nRAPP is a content-addressed distributed organism. Its integrity rests on one invariant: **the same\nconcept has the same bytes everywhere.** This document specifies, normatively and completely, five\nload-bearing primitives so any two independent implementations interoperate **byte-for-byte with no\nout-of-band agreement**: canonicalization (§4), content addressing (§5), identity (§6), the frame (§7),\nthe egg (§9) — all riding one wire (§8): `POST /chat`, or a signed append-only frame. Implementations add\nagents, cartridges, and registered `kind`s — never new endpoints, never new envelopes.\n\n**Repository scope.** `kody-w/RAPP` is the canonical public RAPP foundation,\nproduct home, reference implementation, organism model, and philosophy.\n`kody-w/rapp-1` is the canonical interoperable protocol authority. This\nspecification governs wire-compatible bytes and conformance; it does not absorb\nthe RAPP product or any downstream Rappter/RapterBox LLC product.\n\n**Specification authority.** The append-only DOGG chain at\n`anchor/chain.jsonl` carries the normative revision content. Its hashes prove\nintegrity, not authority or ratification. Until an authenticated RAPP\nregistry/checkpoint exists, the chain accepted by the owner onto protected\ncanonical `kody-w/rapp-1` main is authoritative; an immutable accepted commit\nplus head frame hash is the portable checkpoint. `SPEC.md` is the byte-exact\nmaterialized human view, and `orient.json` is only a discovery beacon. The\nselected chain-frame hash, not a mutable path or `rev-N` label, is the durable\nidentity of a protocol revision (§12.2).\n\n### 1.1 The layered model\n```\n  L5  EGG        cartridge packaging (§9)          — MIME-multipart analogue\n  L4  FRAME      universal event envelope (§7)     — the IP packet of RAPP\n  L3  WIRE       transport: /chat + frames (§8)    — HTTP-analogue single method\n  L2  IDENTITY   rappid namespace + trust (§6,§10) — URI + PKI analogue\n  L1  ADDRESS    canonicalization + hash (§4,§5)   — the git object model\n```\nA higher layer **MUST NOT** redefine a lower one. Every layer names exactly one canonical form.\n\n## 2. Requirements language\nThe key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHOULD**, **MAY** are as in [RFC 2119]/\n[RFC 8174] when in **bold caps**. (The Federal Constitution adopts the same clause.)\n\n## 3. Terminology\n**organism** — a running brainstem with persistent identity. **rappid** — the eternal, mint-once name of an\norganism/door/object (§6): minted once from a UUIDv4 or a public key, never derived from content or name.\n**frame** — one immutable content-addressed event (§7). **stream** — an append-only hash-chained frame\nsequence sharing one `stream_id`. **particle / wave** — a frame's two domain-separated addresses:\npayload-hash / whole-frame-hash (§7.3). **canonical form** — the one [RFC 8785] byte string for a value\n(§4). **legacy form** — any other historical encoding; legacy is drift and **MUST** be migrated out\n(Fed. Const. Art. III), except sealed re-genesis history (§12.1).\n**Grail kernel** — an estate-declared, byte-pinned runtime substrate. Its `grail_id` is\n`\"grail:\" || Hb(\"rapp/1:grail\", kernel_bytes)`; repository, immutable ref, commit, path, raw SHA-256,\nand byte length are provenance and verification data, not alternate identities. Once activated through\n§13.3, those bytes are permanent (Protocol Constitution Art. 15); capabilities evolve outside them.\n**release capsule** — the canonical `rapp-cicd/1-release` payload identifying one immutable candidate.\n**serving lineage** — the sequence of qualified release identities that have received user traffic;\nthe currently served release is immutable even while a separate candidate lineage grows.\n**deployment cell** — an independently observable and isolatable runtime failure domain governed by\n`rapp-deploy/1`.\n\n## 4. Canonicalization (L1)\n`canonical(v)` is the UTF-8 byte string produced by **[RFC 8785] JCS** for the value `v`, defined **only**\nover I-JSON [RFC 7493]. JCS fixes member-name ordering (UTF-16 code-unit), string escaping, and number\nserialization (ECMAScript `Number::toString`, [ECMA-262]); there is no insignificant whitespace and no\nbyte-order mark. Input JSON text **MUST** be well-formed UTF-8 [RFC 7493] §2.1; an implementation **MUST**\nrefuse (not strip) a leading byte-order mark and **MUST NOT** transcode UTF-16 or UTF-32 input.\n(Insignificant whitespace in input text is accepted; it is absent only from the canonical form.)\n\n**RAPP input-domain profile (parse-side interoperability — this is a RAPP rule, not a JCS mandate).** An\nimplementation **MUST** refuse (never repair) any JSON value that, at any depth, contains: (a) duplicate\nmember names in one object; (b) an unpaired UTF-16 surrogate, or a Unicode noncharacter (U+FDD0-U+FDEF, or\nany code point whose low 16 bits are FFFE or FFFF) [RFC 7493] §2.1, in any string or member name; (c) a number token that does\nnot survive the binary64 round-trip — let `d` be the token's nearest binary64 value under `roundTiesToEven`\n(the IEEE-754 default; ±∞ are admissible results); the token is refused iff `d` is not finite, or the\n[RFC 8785] serialization of `d` (ECMA-262 `Number::toString`) denotes a different mathematical value than\nthe token (so `0.1` is accepted — it round-trips — while `9007199254740993` and `1e999` (→ +∞) are refused;\nfield range and type rules, such as `uint53`, are not part of this domain: the rule that types the field\napplies them); (d) canonical form exceeding 1 MiB or JSON nesting depth\nexceeding 64 (the root value is depth 1; each nested object/array adds 1). Refusal is whole (§7.5-style),\nnever partial.\n\n**No normalization.** RAPP applies **no** Unicode normalization when hashing, storing, or re-emitting an\nexisting value; strings are code-point sequences preserved verbatim and equality everywhere is code-point\nequality (no canonical-equivalence matching). A producer creating a **new** human-or-identifier string\n(slug, kind, label, `payload` object key) **MUST** emit it in Unicode NFC. A producer that builds a frame or\npacks an egg from given fields treats every `payload` object member name, at any depth, as new: it\n**MUST** refuse (never normalize) a name that is not in NFC. Consumers do not test frame contents for NFC\n(egg paths excepted, §9.1). NFC is Unicode Normalization Form C [UAX #15] in the Unicode version the\nproducer implements. A producer **MUST** also refuse a name containing a code point that is unassigned\n(General_Category `Cn`) in that version. By the Unicode normalization stability policy, a name that passes\nthis test for one producer then passes it for every producer on the same or a later Unicode version.\n\n> **Migration note (drift C4):** the `twin`/`rapp-body` `_frame.mjs::canonicalize()` (sorted-key\n> `JSON.stringify`) coincides with JCS only for string-only payloads; it **MUST** be replaced by the JCS\n> implementation of record, imported (not re-typed) by every repo that content-addresses.\n\n## 5. Content addressing (L1) — domain-separated\nEvery hash is **domain-separated** (git's `type\\0`, Nix's tagged store — collisions across address spaces\nare made unconstructible):\n```\nH(space, v) = lowercase_hex( SHA-256( utf8(space) || 0x0A || canonical(v) ) )     ; v a value (§4)\nHb(space, b) = lowercase_hex( SHA-256( utf8(space) || 0x0A || b ) )                ; b raw octets\n```\n`space` is an exact ASCII tag, none containing `0x0A`: `\"rapp/1:particle\"`, `\"rapp/1:wave\"`, `\"rapp/1:egg\"`,\n`\"rapp/1:egg-manifest\"`, `\"rapp/1:rappid\"`, `\"rapp/1:grail\"`, `\"rapp/1:seal\"`,\n`\"rapp/1:sealed-aad\"`, `\"rapp/1:sealed-key-request\"`. A tag is used by either `H` or `Hb`, never\nboth: `H` uses `rapp/1:particle`, `rapp/1:wave`, `rapp/1:egg-manifest`, `rapp/1:sealed-aad` and\n`rapp/1:sealed-key-request`; `Hb` uses `rapp/1:egg`, `rapp/1:rappid`, `rapp/1:grail` and `rapp/1:seal`. An\nimplementation **MUST** refuse to compute a hash under any other tag or with the other function. Output is always exactly 64 lowercase hex, **never truncated or uppercased**. Two values\nare treated as the same object iff their same-space hashes are equal; SHA-256 collision resistance\n[FIPS 180-4] is a security assumption of this standard (§14). A `name/X.Y` label is never identity — only\na hash is. A bare 64-hex is meaningful **only** within its space; an implementation **MUST NOT** dereference\na hash from one space as an object of another, and content-addressed stores **MUST** key by `(space, hash)`.\n\n## 6. Identity — the rappid (L2)\n### 6.1 Grammar (case-sensitive, [RFC 7405])\n```abnf\nrappid    = %s\"rappid:@\" owner \"/\" slug \":\" hash\nowner     = lclabel                       ; the lowercase GitHub login (1-39 chars)\nslug      = lclabel                        ; 1-100 chars\nlclabel   = lcalnum *( [\"-\"] lcalnum )     ; no leading/trailing/adjacent hyphen\nlcalnum   = LCALPHA / DIGIT\nLCALPHA   = %x61-7A                         ; a-z\nhash      = 64HEXDIGLC\nHEXDIGLC  = DIGIT / %x61-66                 ; 0-9 a-f\n```\n`owner` **MUST** be the lowercase form of the GitHub login (logins are case-insensitive; display casing is\npresentation, never identity). Lengths are normative: `owner` 1–39, `slug` 1–100; an implementation\n**MUST** refuse longer. This self-locating form is the **only** conformant rappid; `rappid:<slug>:<hash>`,\n`rappid:v2:…`, bare UUIDs, `moment:`/name-hash derivations are legacy and **MUST** be migrated out\n(Art. III), not read forever.\n\n### 6.1.1 stream_id and kind grammar\n```abnf\nstream_id   = memory-stream / body-stream / swarm-stream\nmemory-stream = rappid \":\" instance      ; one organism instance's memory\nbody-stream   = rappid                    ; an organism's biography\nswarm-stream  = %s\"net:\" lclabel          ; a planetary-wire stream\ninstance      = lclabel                   ; 1-64 chars\nkind          = lclabel \".\" lclabel       ; each label 1-64 chars\n```\nA `kind` string carries **no intrinsic family**; the §13 registry binds each registered `kind` to exactly\none family. Membership is tested by exact-match against the registry — never prefix inference, never wildcards.\n\n### 6.2 Minting (mint-once)\nThe 64-hex tail is minted **exactly once** per identity, then immutable:\n- **keyless:** `tail = Hb(\"rapp/1:rappid\", uuid4_octets)`, where `uuid4_octets` is the 16-octet binary\n  UUIDv4 [RFC 9562] §5.4 (field/byte order per §4 of that RFC).\n- **keyed:** `tail = Hb(\"rapp/1:rappid\", SPKI_DER)`, the DER `SubjectPublicKeyInfo` [RFC 5280] of the master key.\n  A minter **MUST** refuse octets that are not the DER SPKI of a §10 key (an id-Ed25519 key [RFC 8410], or an\n  id-ecPublicKey prime256v1 key with an uncompressed point); likewise a keyless mint **MUST** refuse 16 octets\n  whose [RFC 9562] version is not 4 or whose variant is not 0b10.\n\nA producer **MUST NOT** derive the tail from owner/slug or any name (`sha256(\"owner/slug\")` is prohibited —\ndrift ID-01/C3). On read of an existing `rappid.json` an implementation **MUST** reuse the stored tail\n(canonicalize-on-read) and **MUST NOT** re-mint — with exactly one mechanism: the owner-authorized\n**re-anchor** (§6.3), which mints a fresh 64-hex tail once per authorization and records the superseded id\nin `_migrated_from`. Re-anchor is lawful in exactly three cases: (a) a 128→256-bit provisional upgrade\n(§6.3); (b) §10 key rotation or compromise; (c) migrating a pre-rev-3 keyed tail minted with the un-tagged\n`sha256(SPKI)` formula (which fails §10 discovery and **MUST** be re-anchored like a provisional identity).\n\n### 6.3 Canonicalization on read; provisional identifiers\n`canonicalize_rappid(s)` restructures any legacy form into §6.1, **preserving the existing hash** (never\ninventing one). A restructured identifier whose tail is not exactly 64 lowercase hex (e.g. a legacy 32-hex\ntail) is **provisional**: it exists only inside the reading process and **MUST NOT** appear in any emitted\nframe, `stream_id`, egg, or registry entry. The one-time owner-authorized 128→256-bit re-anchor mints a\nfresh 64-hex, records the old id in `_migrated_from`, and is the only way a provisional identity becomes\nusable. A provisional identifier found in a stored artifact is a drift finding (Art. III). Re-anchor is the\nsingle re-mint mechanism (§6.2), lawful only in the enumerated cases: provisional 128→256-bit upgrade,\n§10 key rotation/compromise, and pre-rev-3 un-tagged-`sha256(SPKI)` keyed-tail migration.\n\n**A re-anchor is valid only with a verifiable authorization** — a self-asserted `_migrated_from` is\ninsufficient (it would let anyone hijack an identity). A re-anchor **MUST** be recorded as an owner-signed\n§13.3 **re-anchor record** `{old_rappid, new_rappid, case, utc, sig, old_key_sig?}`; a consumer **MUST**\nrefuse a `new_rappid` (and treat `_migrated_from` as drift) unless that record is present and:\n- `case:\"rotation\"` (uncompromised): `old_key_sig` (a §10 JWS by the **old** key) verifies — proof of\n  continuity;\n- `case:\"compromise\"`: `old_key_sig` is waived but a §10 **tombstone** for `old_rappid` is registered in the\n  same append;\n- `case:\"tag-migrate\"` (pre-rev-3 keyed tail): the verifier checks `lowercase_hex(SHA-256(SPKI_DER_old))` ==\n  the old tail;\n- `case:\"upgrade\"` (provisional 128→256): the old provisional id resolved to this owner at read time.\nEach mints one fresh tail. The **estate_owner's own** re-anchor record **MUST** be signed by the outgoing\n`estate_owner` key (§13.2); root-key compromise is recovered only by out-of-band re-anchoring (§13.1).\n\n## 7. The Frame (L4)\n### 7.1 The envelope — exactly eleven keys\n```json\n{\n  \"spec\":         \"rapp/1\",\n  \"kind\":         \"<klabel.klabel>\",\n  \"stream_id\":    \"<stream_id>\",\n  \"seq\":          <uint53>,\n  \"utc\":          \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"payload\":      { },\n  \"payload_hash\": \"<64hex>\",\n  \"frame_hash\":   \"<64hex>\",\n  \"prev\":         \"<64hex|null>\",\n  \"prev_wave\":    \"<64hex|null>\",\n  \"sig\":          \"<jws|null>\"\n}\n```\n- **`spec` MUST be the exact string `\"rapp/1\"`** in every frame. `rapp-frame/2.0`/`2.1` are legacy tokens\n  and **MUST NOT** be emitted. Any revision changing the key set, any field's grammar, or either hash rule\n  **MUST** change this token and land an Art. III total migration; revisions adding only new registered\n  `kind`s/registry entries keep the token (Fed. Const. Art. II).\n- **Exactly these eleven keys, always present**, none missing, none extra. A field that does not apply is\n  present with value `null` (`prev`/`prev_wave` at genesis and on non-swarm streams; `sig` when unsigned) — never omitted,\n  because [RFC 8785] hashes `null` and an absent key differently. Extra or missing keys are refused (§7.5).\n- **`payload` MUST be a JSON object** (possibly empty `{}`); never `null`, array, string, number, or bool.\n- `seq` is `uint53` (§7.4). A producer **MUST NOT** emit a frame whose canonical form exceeds 1 MiB or\n  nesting depth 64 (§4).\n\n### 7.2 Kind families (one envelope, registry-bound families)\n| family | example registered kinds | `stream_id` form | logs |\n|---|---|---|---|\n| `memory` | `memory.chat-turn`, `memory.tool-call`, `memory.save`, `memory.reconstructed` | memory-stream | one organism's life |\n| `swarm`  | `swarm.guidance`, `swarm.echo`, `swarm.telemetry`, `swarm.reconstructed` | swarm-stream | the planetary wire |\n| `body`   | `body.pulse`, `body.twin-pulse`, `body.reconstructed`, `body.re-genesis` | body-stream | an organism's biography |\nEach family also has a `*.re-genesis` kind (`memory.re-genesis`, `swarm.re-genesis`, `body.re-genesis`)\nused only by §12.1. The family is **not** the kind's prefix — it is the §13 registry binding (so\n`body.twin-pulse` is family `body`). Adding a family or event is a new registered `kind` on the **same** envelope (Art. IV), never a\nnew frame type. A frame's `kind` family **MUST** be compatible with its `stream_id` form (table column 3).\n\n### 7.3 Particle and wave (the unification)\nA frame carries **both** of its domain-separated addresses; a reader collapses it to whichever it needs.\nComputed in order:\n- **particle** — `payload_hash = H(\"rapp/1:particle\", payload)`. The **worldline identity and chain link**.\n- **wave** — `frame_hash = H(\"rapp/1:wave\", frame \\ {frame_hash, sig})` — the frame with **exactly** the\n  `frame_hash` and `sig` keys removed, all nine remaining keys (including `payload_hash`) present.\nBecause `payload_hash` is in the wave pre-image, `frame_hash` attests the particle; because only\n`frame_hash` (cannot hash itself) and `sig` (signs the result) are removed, the pre-image is unambiguous\nand non-circular. Both hashes are always present (never `null`).\n\n### 7.4 Chaining, time, and merge order\n- **`utc`** **MUST** be exactly the 24-byte form `YYYY-MM-DDTHH:MM:SS.mmmZ` — every `Y`, `M`, `D`, `H`,\n  `S` and `m` is an ASCII digit (%x30-39; Unicode digits such as U+0660-0669 or U+FF10-FF19 are refused),\n  `YYYY` is any year 0000-9999, uppercase `T`/`Z`, exactly three fractional digits, no numeric offset; the\n  seconds field **MUST NOT** be `60` (a leap second clamps\n  to `59.999`). All `utc` comparisons are **bytewise** over this fixed form (identical to chronological order).\n- **Worldline chain (particle):** the **genesis** frame has `seq`=0 and `prev`=null; every later frame has\n  `seq` = predecessor's `seq`+1 (contiguous) and `prev` = predecessor's `payload_hash`. `seq` is `uint53`: a\n  number token matching `0 / %x31-39 *DIGIT` (no sign, fraction or exponent, so `-0` is refused) whose value\n  is ≤ 2^53−1; a stream nearing 2^53−1 converges by re-genesis.\n- **Wire chain (wave):** `prev_wave` **MUST** be non-null **iff** `stream_id` is a swarm-stream **and**\n  `seq` > 0, in which case it equals the predecessor's `frame_hash`; in every other frame (all memory/body\n  streams, every genesis) it **MUST** be `null`. (Presence is a function of stream family, not transport.)\n- A frame is **immutable**: a new state is a new frame at a new hash; the head pointer (§7.6) re-points.\n- **Cross-stream merge order** (Dream-Catcher) is the total order: ascending `utc` (bytewise), ties broken\n  by ascending `frame_hash` (bytewise); no further ties are possible (§5).\n\n### 7.5 Verification (the complete consumer checklist)\nBefore accepting a frame, a consumer **MUST**, in order, **refuse** (never repair/reparent) on any failure:\n1. **Shape & types:** exactly the eleven §7.1 keys; `spec`==`\"rapp/1\"`; `kind` a string matching §6.1.1\n   ABNF, registered (§13), and bound to a family whose §7.2 column-3 form is the form of `stream_id` (a\n   family outside the §7.2 table fits no form); `stream_id` a string matching §6.1.1; `seq` a `uint53`\n   (§7.4); `utc` matching the\n   §7.4 fixed form **and** a calendar-valid [RFC 3339] `date-time` (so `2026-13-45T25:61:61.999Z` is\n   refused); `payload` a JSON object; `payload_hash`/`frame_hash` `64HEXDIGLC`; `prev`/`prev_wave` each\n   `null` or `64HEXDIGLC`; `sig` `null` or a §10 JWS string: the detached compact form with strict unpadded\n   base64url parts, a protected header whose octets are `canonical(header)` and whose members are exactly\n   the §10 `alg`, `b64`, `crit` and `kid` (a §6.1 rappid) values, and a signature of exactly 64 octets.\n   A number token that passes §4 (c) but is not a `uint53` — `9007199254740992` (2^53), `0.0`, `1e0`, a\n   negative value — leaves the frame a §4 value, so it is refused here, at step 1, never before the\n   checklist; only a token that §4 (c) itself refuses (`9007199254740993`, `1e999`) makes the octets fail\n   before step 1.\n1a. **Stream binding:** `frame.stream_id` **MUST** byte-equal the identifier of the stream being extended\n   or read (its declared `stream_id` at the head pointer / repo path of record). A genesis frame is\n   accepted only for the stream it names. (Defeats cross-stream genesis/segment replay — §14.)\n2. **Particle:** `payload_hash` == `H(\"rapp/1:particle\", payload)`.\n3. **Wave:** `frame_hash` == `H(\"rapp/1:wave\", frame \\ {frame_hash, sig})`.\n4. **Chain:** `seq`==head.`seq`+1 and `prev`==head.`payload_hash` (or `seq`==0 ∧ `prev`==null at genesis);\n   `utc` ≥ head.`utc` (bytewise). With no head, a consumer holding the §13 registry **MUST** refuse a\n   `seq`=0 frame whose `frame_hash` differs from the stream's registered genesis (its sole non-deprecated\n   `genesis` entry) when the registry has one; a registry without a `genesis` entry for the stream does not\n   refuse on this ground. The comparison opens a chain: a later re-genesis resets the head (§7.6) and does\n   not revoke frames already verified.\n5. **Wire:** if `stream_id` is a swarm-stream and `seq`>0, `prev_wave`==head.`frame_hash`; else\n   `prev_wave`==null.\n6. **Signature:** if `sig`≠null, discover the key and verify per §10 (registry key discovery, tail check,\n   key lifecycle, the signature equation; present-but-invalid is refusal); a swarm-stream frame with\n   `sig`==null is refused (§8/§10).\nSteps 1–5 are **time-independent** (kind lookups only append, §13), so a frame passing them passes forever;\nstep 6 alone may flip pass→fail when a §10 tombstone with `revoked_utc` ≤ the frame's `utc` is later\nregistered — the one time-dependent check.\n\n### 7.6 Heads and forks\nA stream's **head** is the frame with the greatest verified `seq` descending from its registered genesis\n(§13). A consumer **MUST** persist, per stream, the highest `(seq, frame_hash)` it verified and **MUST**\nrefuse any presented head with lower `seq`, or a different `frame_hash` at an already-verified `seq` (no\nrollback, no silent reorg). Two distinct valid frames with equal `stream_id`, `seq`, and `prev` are a\n**fork**: a consumer **MUST** refuse both branches past the fork point and surface a drift finding; only\nthe owner resolves a fork (Art. X), by re-genesis (§12.1) if needed.\n\n**Exception (re-genesis head reset).** The no-rollback rule above refuses a lower-`seq` head — but a\nlegitimate §12.1 re-genesis presents a new genesis at `seq`=0. When (and only when) the §13 registry maps a\n`stream_id` to a new genesis `frame_hash` (§12.1 step 3), a consumer **MUST** verify that registered\ngenesis (§7.5) and then **reset** its persisted head for that `stream_id` to it. Only a registry-published\ngenesis authorizes a reset; any other lower-`seq` head remains a refused rollback.\n\n## 8. The Wire (L3)\nAll interaction rides one of exactly two forms:\n1. **Synchronous — `POST /chat`, `application/json` both ways.** Request: `user_input` (string, REQUIRED);\n   `session_id` (string, OPTIONAL — omit to start a session); `idempotency_key` (string, OPTIONAL — a repeat\n   with the same key returns the original response, not a new turn or duplicate session; scoped to\n   `session_id` when present, else to the key alone so session-creation is also de-duplicated); unrecognized members **MUST** be\n   ignored, never refused. Success: HTTP 200 with **exactly** `{response:string, agent_logs:[string],\n   session_id:string}` (no extra members). An unknown `session_id`, a refusal, or a malformed request\n   **MUST** be HTTP 422, `{error:{code:string, step:string|null}}` where `code` is a §13-registered error\n   code (e.g. `\"unknown-session\"`) and `step` is the failing §7.5 step as a string — one of\n   `\"1\",\"1a\",\"2\",\"3\",\"4\",\"5\",\"6\"` — or `null`. No other shape is conformant. New capability is a new agent\n   behind `/chat`, never a sibling REST route.\n2. **Asynchronous — an append-only frame (§7) published to a stream** (a repo path, an `events/` log). A\n   frame on a **swarm-stream MUST** carry `sig`≠null (§10); memory/body-stream frames **MAY** be unsigned.\n   Any *history* is safe to read given a trusted head (§14); the hash chain (§5) makes tampering\n   detectable.\n\n## 9. The Egg (L5) — the single egg spec of record\nAn **egg** is a cartridge packing a unit of the estate. **RAPP §9 is the one egg spec of record** (it\nsubsumes and retires `EGG_FAMILY.md`, `NEIGHBORHOOD_EGG_SPEC.md`, `ESTATE_SPEC.md`, `rappterbook/EGG_SPEC.md`,\nand the rest — drift C7). No other document may re-specify eggs; they cite this section.\n\n### 9.1 Container, manifest, and egg address\nAn egg is either a JSON object (`invite`/`session` variants) or a ZIP whose root is `manifest.json` (tree\nvariants). The manifest is a §4 value with exactly these members:\n```json\n{ \"schema\": \"rapp/1-egg\", \"variant\": \"<variant>\", \"rappid\": \"<§6.1 rappid>\",\n  \"created_utc\": \"<§7.4 utc>\", \"contents\": [ {\"path\":\"<rel>\",\"hash\":\"<64hex>\"}, … ], \"payload\": { },\n  \"sig\": \"<jws|null>\" }\n```\n- `contents` **MUST** list every packed file **except `manifest.json` itself**, exactly once each, with\n  `hash = Hb(\"rapp/1:egg\", file_octets)` (§5) over the raw stored octets. `contents` is **always present**;\n  for JSON (pointer/session) variants it **MUST** be exactly `[]`.\n- `path` **MUST** be a relative POSIX path: `/`-separated non-empty NFC UTF-8 segments, no `.`/`..`\n  segment, no leading `/`, no backslash, no Windows drive-qualified first segment (`ALPHA \":\"`), not the\n  root path `manifest.json`, and no two `path` values in one manifest equal as code-point sequences. Paths\n  that differ only in case or normalization, or where one path is a directory prefix of another (`docs`,\n  `docs/a.md`), are distinct and valid; a consumer that extracts to a filesystem where they would collide\n  refuses the extraction, not the egg. A segment **MUST NOT** end in a period/space, contain `:`, contain a\n  C0 control (U+0000-U+001F), or have a basename (the segment up to its first `.`), compared ASCII\n  case-insensitively, equal to `CON`, `PRN`, `AUX`, `NUL`, `COM1`–`COM9`, or `LPT1`–`LPT9`. §9.3's 'no\n  `..`' means no `..` segment.\n  `contents` **MUST** be sorted ascending\n  by the UTF-8 bytes of `path`.\n- `payload` is a §4 object (variant-specific). `sig` is a §10 JWS over `canonical(manifest \\ {sig})`, or\n  `null`. For the `invite` variant `sig` is REQUIRED and **MUST** verify with `kid` in the §13.2 estate-owner\n  succession (invites are estate-issued; a `sig` by any other key, even a validly registered one, is\n  refused — otherwise an attacker mints a fresh rappid and forges invites). For other variants a non-null\n  `sig` **MUST** verify per §10 with `kid` == a keyed rappid the consumer resolves via §13; a consumer\n  presented a signed egg **MUST** verify it.\n- **The egg's one §5 address is** `egg_hash = H(\"rapp/1:egg-manifest\", manifest \\ {sig})` — the manifest with\n  exactly the `sig` key removed (mirroring §7.3's wave rule: `sig` authenticates the egg, `egg_hash` names\n  it, so re-signing never changes identity). Stores key eggs by `(\"rapp/1:egg-manifest\", egg_hash)`.\n  (`\"rapp/1:egg\"` addresses file octets; `\"rapp/1:egg-manifest\"` addresses the egg as a whole.)\n- **Container determinism.** A ZIP variant **MUST** use compression method `stored` (0) for **every** entry\n  — no deflate in any variant (deflate is library-dependent, so it cannot be byte-reproducible; transport\n  compression, if any, wraps the egg and is not the egg). Entries appear in `contents` order with\n  `manifest.json` first; the `manifest.json` entry's octets **MUST** be exactly `canonical(manifest)`.\n  Every local and central header carries: version needed to extract 20 (0x0014); general-purpose flags\n  exactly 0x0800 (UTF-8 filename; no data descriptor, no encryption); DOS time 0x0000 and date 0x0021\n  (`1980-01-01 00:00:00`); no extra field. Every central header also carries version made by 0x0014, no\n  file comment, disk number start 0, internal and external attributes 0. Every field present in both the\n  local and the central header holds the same value in both. The archive is the local records in entry\n  order with no gap, then the central directory, then an end-of-central-directory record with disk numbers\n  0, equal entry counts and no comment; no ZIP64 record, and no octet precedes the first local header or\n  follows the end record. `contents[].hash` is over the file octets (identical to the archive octets under\n  method 0). A JSON-variant egg's serialized form **MUST** be exactly `canonical(manifest)`. A producer\n  **MUST** write exactly these values, so two conformant packers of the same manifest value emit\n  byte-identical eggs. A consumer **MUST** refuse any other violation of this paragraph, but **MUST** accept\n  any value of version made by, version needed (when both headers agree) and the internal and external\n  attributes, and **MUST NOT** interpret them.\n\n### 9.2 Variants (the ratified set — closes EGG-01)\n| variant | container | packs | required members |\n|---|---|---|---|\n| `organism` | ZIP | a full brainstem instance | contents (sorted) MUST include the root paths `rappid.json` and `soul.md`; MAY include `agents/*`, `organs/*`, memory files |\n| `rapplication` | ZIP | one rapp | contents MUST include `rappid.json` and exactly one `agent.py` at the root (the agent of record); MAY include one `ui.html`, files under `state/`, and other files: this MAY list, like the organism row's, is not exhaustive |\n| `session` | JSON | one runtime + transcript | `payload` = `{runtime:<string>, transcript:[<object>]}`; contents `[]` |\n| `invite` | JSON | a QR-sized pointer (**no packed files**) | `payload` = `{target_rappid:<rappid>, target_url:<string>, target_kind:(\"neighborhood\" / \"estate\")}`; contents `[]`; `sig` REQUIRED |\n| `neighborhood` | ZIP | several organisms meant to live together | `payload` = `{members:[<rappid>,…]}`; contents = one sub-egg per member, named `<owner>--<slug>.egg` at the root, matched by the sub-egg manifest's `rappid` == the `payload.members[]` entry |\n| `estate` | ZIP | several neighborhoods | `payload` = `{neighborhoods:[<rappid>,…]}`; contents = one sub-egg per neighborhood, named `<owner>--<slug>.egg` at root, matched by sub-egg `rappid` |\n| `sealed` | ZIP | publicly mirrorable ciphertext with scoped key release | contents MUST be exactly `ciphertext.bin`; payload is the closed `rapp-sealed-artifact/1` profile in §9.2.1; `sig` REQUIRED |\n\nFor `organism` and `rapplication` eggs, `rappid.json` **MUST** be a §4 object whose `rappid` member equals\n`manifest.rappid` (code points) and whose `schema`, when present, is `\"rapp/1\"`; a consumer refuses the egg\nat §9.3 step (2) otherwise (this is the §9.3 no-reparent rule applied to the packed identity).\n`payload.members` (neighborhood) and `payload.neighborhoods` (estate) are arrays of distinct §6.1 rappids,\npossibly empty; an empty list packs no files. \"Several\" describes use, not a minimum.\n\nThe QR-sized invite that caused EGG-01 is the **`invite`** variant: a signed pointer object, not a\nmember-packing `neighborhood` egg. The banned legacy stamps (`brainstem-egg/2.3-neighborhood`,\n`neighborhood-egg/1.0`) migrate to `{schema:\"rapp/1-egg\", variant:\"invite\" / \"neighborhood\"}` (Art. III).\n\n### 9.2.1 Sealed artifact profile\n\nThe `sealed` variant lets any unauthenticated mirror, including a commit-pinned\n`raw.githubusercontent.com` URL, distribute an encrypted artifact globally without distributing its\ndecryption key.\n\nThe public bytes are **ciphertext, not access control**. Bytecode or obfuscation alone provides no\nconfidentiality. A conformant producer **MUST** use a random 256-bit data-encryption key (DEK) per artifact,\n**MUST NOT** embed that DEK or a shared master key in the egg/client/URL, and **MUST NOT** place a password\nin a URL. A password, passkey, device assertion, or account credential may authenticate to the key service;\nit is not the artifact encryption key.\n\nThe ZIP contents are exactly one file:\n\n```text\nciphertext.bin = AES-256-GCM ciphertext || 16-byte authentication tag\n```\n\nThe manifest `payload` has exactly:\n\n```json\n{\n  \"schema\": \"rapp-sealed-artifact/1\",\n  \"cipher\": \"A256GCM\",\n  \"nonce\": \"<12 bytes, unpadded base64url>\",\n  \"plaintext_commitment\": \"<64hex>\",\n  \"plaintext_bytes\": 1234,\n  \"media_type\": \"application/wasm\",\n  \"key_id\": \"<64hex>\",\n  \"key_service_rappid\": \"rappid:@owner/key-service:64hex\",\n  \"key_service_url\": \"https://keys.example.com/chat\",\n  \"access\": \"scoped-key-release\",\n  \"aad_hash\": \"<64hex>\"\n}\n```\n\nIn this template `schema`, `cipher` and `access` are literals that a consumer **MUST** match exactly\n(`access` is always `scoped-key-release`); a `<…>` value is a placeholder of the stated form; the values\nshown for `plaintext_bytes`, `media_type`, `key_service_rappid` and `key_service_url` are examples, and only\nthe member's type is fixed by the template (the rules below still bound each value).\n\n`plaintext_commitment` is a keyed commitment that cannot be tested without the DEK:\n\n```text\nprk = HMAC-SHA-256(32 zero octets, DEK)\ncommitment_key = HMAC-SHA-256(prk, utf8(\"rapp/1:sealed-commitment\") || 0x01)\nplaintext_commitment = lowercase_hex(HMAC-SHA-256(commitment_key, plaintext_octets))\n```\n\nThis is the [RFC 5869] HKDF-Extract/HKDF-Expand construction with an empty salt, one 32-byte output block,\nand the exact info string `rapp/1:sealed-commitment`. The commitment is public but does not permit an\noffline dictionary attack without the random 256-bit DEK.\n\nThe exact authenticated-data descriptor is:\n\n```json\n{\n  \"schema\": \"rapp-sealed-artifact/1\",\n  \"artifact_rappid\": \"<manifest.rappid>\",\n  \"created_utc\": \"<manifest.created_utc>\",\n  \"key_id\": \"<payload.key_id>\",\n  \"plaintext_commitment\": \"<payload.plaintext_commitment>\",\n  \"plaintext_bytes\": 1234,\n  \"media_type\": \"<payload.media_type>\"\n}\n```\n\n`aad_hash = H(\"rapp/1:sealed-aad\", descriptor)`, and `canonical(descriptor)` is supplied as AES-GCM\nadditional authenticated data. `nonce` decodes to exactly 12 bytes. `plaintext_bytes` is an integer from\nzero through `2^30` (1 GiB), a RAPP safety ceiling below both the [NIST SP 800-38D] per-invocation limit\nand the deterministic non-ZIP64 container boundary.\n`ciphertext.bin` length is exactly `plaintext_bytes + 16`. The sealed egg's manifest signature is REQUIRED\nand verifies per §10 with `kid` exactly equal to `manifest.rappid`. A sealed artifact therefore uses a\nkeyed §6.2 rappid controlled by its authorized publisher; another valid registry key cannot sign on its\nbehalf.\n\n`key_service_rappid` identifies the RAPP organism authorizing key release. `key_service_url` is its absolute\nHTTPS §8 `POST /chat` URL and **MUST** end in `/chat`. The URL is location, not authority: the service\nresponse is accepted only when its signatures and identifiers bind to `key_service_rappid`.\n\nThe caller sends the following canonical JSON object as the `user_input` string:\n\n```json\n{\n  \"schema\": \"rapp-sealed-key-request/1\",\n  \"egg_hash\": \"<64hex>\",\n  \"key_id\": \"<64hex>\",\n  \"recipient_rappid\": \"rappid:@owner/device:64hex\",\n  \"recipient_spki_der_b64\": \"<standard base64>\",\n  \"request_nonce\": \"<64hex>\",\n  \"expires_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"sig\": \"<recipient detached JWS>\"\n}\n```\n\n`sig` is over `canonical(request \\ {sig})` and verifies under `recipient_rappid`; `egg_hash` is the §9.1\nsealed egg address. The key service verifies entitlement, exact `(egg_hash,key_id)`, request expiry,\nrecipient key binding, and nonce non-reuse.\n\nThe §8 `response` string is canonical JSON:\n\n```json\n{\n  \"schema\": \"rapp-sealed-key-release/1\",\n  \"egg_hash\": \"<request.egg_hash>\",\n  \"key_id\": \"<request.key_id>\",\n  \"recipient_rappid\": \"<request.recipient_rappid>\",\n  \"request_hash\": \"<H('rapp/1:sealed-key-request', request without sig)>\",\n  \"wrap_alg\": \"ECDH-ES+A256KW\",\n  \"wrapped_key_jwe\": \"<JWE Compact Serialization>\",\n  \"issued_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"expires_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"service_sig\": \"<key-service detached JWS>\"\n}\n```\n\n`service_sig` is over `canonical(release \\ {service_sig})` and verifies under `key_service_rappid`.\n`wrapped_key_jwe` uses [RFC 7516] with `alg:\"ECDH-ES+A256KW\"` and `enc:\"A256GCM\"` for the declared\nrecipient SPKI. The service **MUST NOT** return a global raw DEK. Authorization, expiry, device scope, and\nkey rotation are service policy recorded in signed frames, not fields that alter the sealed egg's content\naddress.\n\nA mirror URL **SHOULD** be immutable (for GitHub Raw, pin a commit SHA rather than a moving branch). URL\nsecrecy is never assumed: integrity comes from the egg address and signature, confidentiality from\nAES-GCM, and use authorization from scoped key release.\n\nRevocation prevents future key release. It cannot erase ciphertext or plaintext already downloaded and\ndecrypted by an authorized recipient. A conformant product **MUST** state this limit plainly. It also\n**MUST NOT** claim that encrypted bytecode cannot be inspected after decryption; legal/license controls and\nbounded server authority remain separate from cryptographic confidentiality.\n\n### 9.3 Conformance\n- **Producer** **MUST** emit only `schema:\"rapp/1-egg\"` with a variant from §9.2, a §6.1 rappid, and, for\n  ZIP variants, a `contents` list whose every hash verifies. Every egg it emits, and every sub-egg it packs\n  into one, **MUST** pass consumer steps (0)-(2) below; a REQUIRED `sig` **MUST** be present and be a §10\n  JWS (a producer without the signer's key context need not verify it). Given input that cannot meet these\n  rules, a producer **MUST** refuse rather than emit or repair. It **MUST NOT** emit any legacy egg schema.\n- **Consumer** **MUST** read every §9.2 variant, dispatch on `variant`, verify **integrity then viability** —\n  (0) the manifest is a §4 value satisfying **every §9.1 rule** — exact member set, `path` grammar (no `..`,\n  no leading `/`, no backslash), no duplicate paths, sort order, and for ZIP variants the archive entry set\n  equals `contents` ∪ {`manifest.json`} in the §9.1 deterministic order (this is the zip-slip defense; an\n  unenforced path grammar defends nothing); (1) every `contents[].hash` recomputes per §5; (2) the variant's\n  §9.2 structural requirements hold — and refuse whole on any failure; it **MUST NOT** reparent on transport.\n\n### 9.4 Instantiation — instance identity and `grown_from` lineage (rev-6; closes the hatch seam)\nAn egg names an **artifact**; a hatch creates an **instance**. Rev-5 specified packing and reading but\nleft instantiation identity unwritten, so every implementation had to invent its own — this section is\nthat missing word.\n\n- The `rappid` in a packed egg's `rappid.json` (§9.2) names the **artifact**. Every hatch of the same\n  egg reads the **same** artifact identity (§6.2 canonicalize-on-read); re-minting it on hatch is\n  prohibited (§6.2).\n- A consumer that instantiates an egg into a live installation **MUST** mint a **fresh §6.2 identity\n  for the instance**, exactly once, at first boot — from entropy, never derived from the artifact\n  identity, host name, or path. Two instances of one egg share the artifact identity and **MUST NOT**\n  share an instance identity.\n- The instance's identity document **SHOULD** record **`grown_from`**: the §9.1 egg address\n  (64 lowercase hex) of the egg it was instantiated from. `grown_from` is written at mint time and is\n  **immutable** thereafter; it is `null` when the source is unknown; a producer **MUST NOT** fabricate\n  it — lineage is a fact about a birth, never a claim to invent. An instance that cannot say where it\n  came from says `null`.\n- `grown_from` is **lineage, not inheritance**: it confers no authority, no trust, and no §10 key\n  material. A reader **MUST** treat it as an unverified assertion unless the named egg is available and\n  its address recomputes per §9.1/§5.\n- A newly authored artifact produced from one or more existing RAPP objects **MAY** record\n  `crossed_from` in its packaged `rappid.json`. The value is a sorted, duplicate-free array of typed\n  addresses `{space, hash}`, where `space` is `\"rapp/1:particle\"` or `\"rapp/1:egg-manifest\"` and `hash`\n  is 64 lowercase hex. One parent denotes an **offspring**; two or more denote a **cross**. The new\n  artifact **MUST** mint its own §6.2 rappid; parent artifacts and identities remain unchanged.\n  `crossed_from` is lineage only: it transfers no signature authority, ownership, entitlement, secret,\n  or trust. A verifier treats each parent as unverified until the addressed object is available and\n  recomputes in its declared space.\n\n## 10. Trust and signatures (L2)\n`sig` is OPTIONAL on memory/body streams and REQUIRED on swarm streams (§8). Chain integrity comes from the\nhash links (§5), not signatures. When present, `sig` **MUST** be JWS Compact Serialization with **detached,\nunencoded payload** ([RFC 7515] App. F + [RFC 7797]):\n- protected header members are **exactly** `alg` (`\"EdDSA\"` or `\"ES256\"`), `b64` (`false`), `crit`\n  (`[\"b64\"]`), `kid` (signer's §6.1 rappid), no others; the header octets **MUST** be `canonical(header)`\n  (§4 — JCS orders them `alg`, `b64`, `crit`, `kid`, no whitespace);\n- the `sig` string is the detached compact form `BASE64URL(canonical(header)) || \"..\" || BASE64URL(signature)`;\n- JWS signing input = `BASE64URL(canonical(header)) || \".\" || canonical(frame \\ {sig})`;\n- `alg`: `EdDSA`/Ed25519 [RFC 8037] or `ES256` [RFC 7518]; Ed25519 verification is [RFC 8032] §5.1.7 with\n  `S < L` required and the cofactorless check `encode([S]B - [k]A) == R`, where `k` is SHA-512(`R` || `A` ||\n  message) read as a little-endian integer and reduced mod `L` (as in [RFC 8032]'s §6 reference code); public\n  keys that decode (including small-order points) are not refused for their order; ES256 signers **SHOULD** sign deterministically\n  [RFC 6979] (Ed25519 is deterministic by construction) so signed frame files stay byte-reproducible.\n\n**Key discovery.** A keyed rappid's tail is one-way (`Hb(\"rapp/1:rappid\",SPKI)`). A verifier resolves the\nsigner's SPKI (DER) **from the §13 registry** entry (`rappid` → `spki_der_b64`); the door-of-record\n`rappid.json` is the publication venue the registry entry is generated from, not itself a verification\nsource. The verifier **MUST** check `Hb(\"rapp/1:rappid\", SPKI_DER)` == the rappid's tail and refuse on\nmismatch or registry absence.\n\n**Key lifecycle.** Rotation is an identity re-anchor (§6.3, case `rotation`) with new `tail =\nHb(\"rapp/1:rappid\", newSPKI)` and a §13.3 re-anchor record. A re-anchor **deprecates** the superseded\nrappid's §13 `spki` entry: a verifier **MUST** refuse a `sig` whose `kid` is a superseded rappid on any\nframe with `utc` ≥ the re-anchor record's `utc` (rotation gives forward security; earlier frames verify as\nbefore). The `deprecated` flag of an `spki` entry does not by itself refuse a `sig`: the entry still\nresolves the key (entries are append-only, §13.3), and a `sig` by it is refused only by the re-anchor rule\nabove or by a tombstone. To stop a key without rotating, the owner registers a tombstone. Compromise is declared by an owner-signed **tombstone** in the §13 registry `{rappid, revoked_utc}`; a verifier **MUST** refuse any `sig` by a\ntombstoned key on a frame whose `utc` ≥ `revoked_utc`, checking tombstones at verification time (§7.5 step\n6). \"Owner-signed\" means a `sig` verifying with `kid` == the registry's designated `estate_owner` rappid\n(§13). A consumer **MUST NOT** infer authorship from an unsigned frame (keyless rappids assert location,\nnot authorship).\n\n## 11. Conformance classes\n- **Producer:** emits only §4 JCS/I-JSON bytes, §5 domain-separated full-SHA-256 addresses, §6 rappids\n  minted per §6.2, §7.1 eleven-key frames, §9 `rapp/1-egg` variants — and **no legacy form**.\n- **Consumer:** runs the full §7.5 checklist (incl. 1a binding), §9.3 egg verification, §10 signature +\n  key-discovery + tombstone checks, canonicalizes legacy ids on read (§6.3), refuses on any failure, never\n  repairs/reparents/rolls back (§7.6).\n- **Router/Mirror:** invents no endpoints (§8), declares subordination to\n  `kody-w/rapp-1` for protocol semantics, and serves only\n  provenance-stamped hash-matching mirrors. Estate-specific product scope is\n  resolved separately through that estate's signed registry and master plan.\n\n### 11.1 Immutable Grail kernel conformance\nAn estate declares a Grail kernel through the exact §13.3 `grail-kernel` entry. Its `release_scope`\nselects the release family to which the pin applies; a registry **MUST** contain at most one\n`grail-kernel` entry for any release scope. Its entry-level `sig`\n**MUST** verify under `declared_by`, which **MUST** be the estate owner in effect at `activated_utc`\n(§13.2); `activated_utc` **MUST NOT** be more than 300 seconds after the verifier's first-seen time for\nthat entry. The pin activates locally when a consumer first accepts an authenticated, non-rollback\nregistry containing that valid declaration. Until then it is structural evidence only. The Grail is\nidentified by `grail_id`, never by a mutable branch, tag, repository name, or product label. Once\nactivated, the pin is a permanent compatibility anchor, not a moving release channel:\n\n1. Every conformance evaluation **MUST** receive `release_scope` from an authenticated owner-controlled\n   release policy, never from candidate bytes or candidate-controlled configuration, then resolve its\n   one `grail_id` exclusively from the activated, persisted §13.3 binding. If the policy repeats\n   `grail_id`, that value is only a consistency assertion and **MUST** byte-equal the registry result; it\n   cannot select or rebind the pin. Every ring and release/deployment stage, including development,\n   qualification, Preprod, installation, and production verification, **MUST** compare the candidate's\n   Grail path to that exact binding, SHA-256, and byte length.\n2. A missing, changed, substituted, or unmeasured Grail byte is `kernel-drift` and **MUST** fail closed.\n   Approval, urgency, compatibility claims, and semantic equivalence cannot waive byte inequality.\n3. A pipeline **MUST NOT** silently restore the pinned file after testing a different file. The exact\n   release-shaped artifact containing the immutable Grail bytes **MUST** itself pass the release gates.\n4. Every gate **MUST** resolve every archive, container, wrapper, environment override, symlink, and\n   filesystem indirection to one regular runtime entry-point file under the immutable release root;\n   refuse links and ambiguous alternatives; verify its bytes; and bind the release digest, resolved\n   entry-point path, `release_scope`, `grail_id`, raw SHA-256, and byte length into its evidence.\n5. Every gate that executes the kernel **MUST** bind verification atomically to execution from a sealed\n   immutable object or snapshot. An already-open descriptor is sufficient only when its backing bytes\n   are under platform-enforced write exclusion for the entire verification-through-consumption interval\n   and the interpreter/loader consumes that exact descriptor without reopening a pathname. An immutable\n   content-addressed release root is sufficient only when no concurrent principal can modify it. A\n   hash-then-path-launch without one of those guarantees is nonconformant. At least one execution gate for\n   every supported production platform **MUST** perform this proof before release approval. Merely\n   carrying an unused matching file is insufficient. A stored transpiled, bundled, generated, or patched\n   derivative is different kernel bytes and requires a new `grail_id`; ordinary interpreter/JIT\n   compilation directly from the pinned bytes is permitted when no alternate stored kernel is selected.\n6. New implementation behavior **MUST** live outside the Grail kernel and **MUST NOT** alter any\n   RAPP-visible canonical form or wire semantic except through the registration and evolution rules of\n   §§7, 9, 12, and 13.\n7. If required behavior cannot be expressed outside the pin, the implementation **MUST** report an\n   incompatibility. It **MUST NOT** edit the Grail and continue under the same identity.\n8. Different kernel bytes produce a different `grail_id` and therefore are a different Grail. A new\n   `grail-kernel` entry may coexist and may name the old `grail_id` as `predecessor`, but it **MUST NOT**\n   overwrite, retag, alias, or redefine the prior Grail. A successor uses a new `release_scope`; an\n   existing scope is never rebound. A non-null `predecessor` **MUST** name an earlier accepted\n   `grail-kernel` entry and **MUST NOT** form a cycle. A registry **MUST** contain at most one\n   `grail-kernel` entry for each `grail_id`.\n9. On first activation a consumer **MUST** persist the full canonical `grail-kernel` entry. Every later\n   accepted registry **MUST** retain that entry byte-for-byte. Removal, mutation, or a second entry for\n   the same `grail_id` is a permanent `kernel-drift` refusal even when `registry_seq` increased.\n\nThis rule governs release topology rather than the §8 wire shape, so it does not add a frame member,\nendpoint, compatibility shim, or alternate `rapp/1` encoding.\n\n### 11.2 Operational conformance profiles\nRAPP/1 defines the substrate. Two subordinate operational profiles define how a production AI changes\nwithout mutating that substrate or the serving system underneath users:\n\n- **RAPP CI/CD** (`rapp-cicd/1`) — `protocols/rapp-cicd/1/SPEC.md`; immutable release capsules,\n  ordered qualification evidence, exact-candidate promotion, Preprod, and rollback/restore proof.\n- **RAPP Deploy** (`rapp-deploy/1`) — `protocols/rapp-deploy/1/SPEC.md`; isolated serving/candidate\n  lineages, cellular rollout, progressive exposure, expiring AI-health evidence, quarantine, and exact\n  rollback.\n\nThe profiles are RAPP/1 applications, not alternate wire versions:\n\n1. Their payloads **MUST** be §4 canonical I-JSON and are identified by\n   `H(\"rapp/1:particle\", payload)`.\n2. Authoritative profile payloads **MUST** travel in signed RAPP/1 frames using a registered compatible\n   kind. Local unsigned files are drafts, fixtures, or caches and cannot authorize promotion or traffic.\n3. They **MUST NOT** add a transport endpoint beside §8 `POST /chat`, redefine any RAPP/1 primitive, or\n   weaken §11.1.\n4. An estate activates a profile through an authenticated §13.3 `protocol` entry pinning its exact\n   repository, path, and SHA-256. A moving branch is discovery, never authority.\n5. A claim of **RAPP production conformance** requires both profiles. Core Producer, Consumer, and\n   Router/Mirror implementations remain conformant without implementing production operations.\n6. Fixed envelope keys carry the safety invariants. Policy-defined check identifiers, component kinds,\n   health objectives, and resilience controls are extension points; adding one does not change the\n   profile token or the RAPP/1 wire.\n7. A consumer **MUST** refuse unknown required policy semantics. It may preserve and relay unknown\n   optional evidence, but may not treat it as satisfying a requirement it does not implement.\n\nThe executable reference validators are `rapp_cicd.py` and `rapp_deploy.py`; controlled profile vectors\nare in `operations_conformance.py`. JSON Schemas define structural shape, while the reference validators\nenforce ordering, identity, temporal, and cross-document rules that JSON Schema cannot express.\n\n## 12. Versioning, evolution, no-legacy\nRAPP is a **living standard** (WHATWG): revised in place, never forked into parallel versions; a `name/X.Y`\nlabel **MUST NOT** ever denote two shapes (Art. II) — a shape change moves the token (§7.1). Published\ncontent-addressed artifacts are **immutable** (SemVer/crates). Within an estate there is **no perpetual\nbackward compatibility** for the estate's own artifacts and retired legacy encodings (Art. III): a change\nto such a form is a **total migration** of every instance + **deletion** of the old form. Sealed re-genesis\nhistory (§12.1) is the retained live-stream exception and is not \"legacy compatibility.\"\n\n**The `rapp/1` wire is frozen (rev-15, Art. 18).** No revision of this standard may change a form a\n`rapp/1` artifact is verified by: canonicalization (§4), the hash function and its tags (§5), the rappid\ngrammar and mint (§6.1, §6.2), the eleven-key envelope and its two addresses (§7.1, §7.3), the consumer\nchecklist (§7.5), the two wire forms and the `/chat` shapes (§8), or the egg container and address (§9.1).\nA change to any of those is not a revision; it moves the token to `rapp/2`, specified beside this\ndocument, and `rapp/1` artifacts keep verifying under this document forever. A consumer **MUST NOT**\nrefuse a `rapp/1` artifact because a later token exists. Everything Art. IV names still grows under\n`rapp/1`: registered kinds, egg variants, error codes, registry entry types, vocabulary, subordinate\nprofiles, and the registry itself. The frozen forms are what a stranger's implementation, written once\nand never updated, relies on; they are the reason an independent implementation can be finished.\n\nImmutable specification-governance history is a separate narrow exception:\nrev-5 through rev-13 anchor frames retain interpretable immutable pointer\npayloads so their ratified normative bytes remain resolvable. They are\nhistorical authority records, not accepted live legacy protocol forms. A\nproducer **MUST NOT** emit the pointer-only revision profile after rev-13.\n\n### 12.1 Re-genesis (converging an immutable chain — one owner-authorized operation)\n1. **Terminal seal:** `seal = Hb(\"rapp/1:seal\", head_octets)`. `head_octets` is the exact octets of the old\n   head's record **as retained under `legacy/`** (step 4): for a one-frame-per-file store, the retired\n   file's full octets; for a line-oriented log, the head's line **excluding** its trailing terminator. The\n   retained `legacy/` artifact is the verification reference for the seal, and retirement **MUST** preserve\n   those octets bit-exact. The step-3 `genesis` registry entry **SHOULD** record the `legacy/` artifact's\n   repo+path so a consumer **MAY** verify the seal against it. (Defined for every legacy shape, including\n   ones that cannot be §7.3-hashed.)\n2. **New genesis:** emit `seq`=0, `prev`=null, `kind` = the registered re-genesis kind **of the stream's\n   family** — `memory.re-genesis`, `swarm.re-genesis`, or `body.re-genesis` (three §13 kinds, used only\n   here) so the frame satisfies §7.2 family↔stream compatibility for any stream — `sig`≠null owner-signed\n   (§10, §13 `estate_owner`), `payload` = `{\"migrated_from\":{\"stream_id\":<old>,\"terminal_seal\":<seal>,\n   \"terminal_seq\":<n>}}` and no other members. A consumer **MUST** treat any `*.re-genesis` kind as the sole\n   re-genesis marker for its family and refuse an unsigned/non-owner one. A consumer **MUST** also refuse,\n   at §7.5 step 1, a `*.re-genesis` frame whose `payload` is not exactly this object: `migrated_from` with\n   exactly `stream_id` (a §6.1.1 stream_id), `terminal_seal` (64HEXDIGLC) and `terminal_seq` (a `uint53`);\n   and, at step 4, one with `seq`≠0 or `prev`≠null.\n3. **Register (the linearization point):** append a §13.3 `genesis` entry mapping the `stream_id` to the new\n   genesis's `frame_hash`, **and flag every prior `genesis` entry for that `stream_id` `deprecated`** — the\n   first convergence included (it deprecates the creation-time genesis), so exactly one non-deprecated entry\n   always remains. A consumer resolves the current genesis **only** via that sole non-deprecated entry. A\n   **concurrent** second registration fails closed (the append is the linearization point, Art. IX); a\n   later fork/brick (§7.6/§14) is a fresh owner-authorized convergence that appends again and re-deprecates.\n4. **Retire:** move old frames under `legacy/` — retained as immutable sealed history, never served as\n   current, never extended, never read as live chain. No live frame may set `prev`/`prev_wave` to a retired\n   hash (a dangling ref is a drift finding).\n5. Keep the old `stream_id` unless the identity itself re-anchored (§6.3), in which case the registry entry\n   also records `old_stream_id → new_stream_id`.\n6. Two frames with equal `stream_id`+`seq` from different eras are disambiguated **solely** by descent from\n   the current registered genesis. Re-genesis is one-time per convergence; a repeat *of the same\n   convergence* is the concurrent case (step 3, fails closed).\n\n### 12.2 DOGG specification revision chain\n\nThe RAPP/1 revision content is the append-only JSONL stream at\n`anchor/chain.jsonl`. The chain's particle, wave, and predecessor hashes prove\nbyte integrity and linear history; they do **not** authenticate who selected a\nhead or ratified an amendment. Until a separately authenticated RAPP\nregistry/checkpoint is ratified, authority is selected by owner-ratified\nacceptance of a chain snapshot onto protected canonical\n`refs/heads/main` at `https://github.com/kody-w/rapp-1`. A consumer starting\nfrom an out-of-band pinned accepted commit and head frame hash has the same\nimmutable selection evidence. An internally valid fork is not authoritative\nmerely because its hashes verify.\n\nEvery protocol adjustment **MUST** append exactly one valid successor frame:\n\n- `spec` remains `\"rapp/1\"`, the envelope remains exactly eleven keys, and the\n  allowed registered anchor kind is `body.pulse`; this profile does not create\n  a new kind or alter canonicalization, hashing, or registered-kind semantics;\n- `stream_id` remains the bootstrap-pinned anchor stream, `seq` is contiguous,\n  `prev` names the predecessor's `payload_hash`, `prev_wave` and `sig` are\n  `null`, and the applicable §7.5 integrity checks hold;\n- the frame's `frame_hash` is the durable protocol-revision identity.\n  Human names such as `rev-14` are lookup labels/views, never identities.\n\n#### 12.2.1 Immutable bootstrap boundary\n\nVerification begins from the frozen `rapp-anchor-bootstrap/1` profile published\nthrough `anchor/bootstrap/index.json`. The index names a\n`anchor/bootstrap/sha256-<raw-profile-sha256>.json` object and pins the exact\nstdlib verifier at `anchor/bootstrap_verify.py` by raw SHA-256 and byte length.\nThe profile fixes the exact-integer JCS subset and limits, particle/wave\ndomains, eleven frame keys, timestamp/sequence/predecessor rules, canonical\nrepository and protected ref, anchor stream ID, genesis frame and payload\nhashes, `body.pulse` anchor profile, null signature/wave fields, and byte/depth\nlimits needed to verify this chain.\n\nThe content-addressed bootstrap profile is immutable. Changing it requires a\nnew bootstrap schema/version and a new external ratification; mutating\n`rapp-anchor-bootstrap/1` in place is refusal. Its initial authenticity is\nnecessarily external — owner-ratified protected canonical main or an\nout-of-band pinned profile hash/immutable commit — because neither a chain nor\ncode fetched with that chain can circularly authenticate its own parser.\n`rapp.py` remains the complete reference implementation and is cross-checked,\nbut it is not the mutable bootstrap trust pin.\n\n#### 12.2.2 Revision payloads and historical exception\n\nFrames through rev-13 retain their immutable legacy pointer fields:\n`canonical_repo`, a full 40-lowercase-hex `commit`, safe relative\n`normative_path`, raw-file `normative_sha256`, and decimal-string\n`normative_bytes`. A resolver **MUST** construct only an immutable\ncommit-pinned GitHub Raw URL from those fields, fetch the bytes, and verify\nlength and raw SHA-256 before use. A branch or tag name in `commit`, an unsafe\npath, malformed UTF-8, a byte-order mark, or a hash/length mismatch is refusal.\nPath validation occurs on the original string before path-library\nnormalization: empty, absolute, `.`/`..`, empty components, repeated slash,\nleading `./`, trailing slash, backslash, percent-encoded ambiguity, or any\nvalue whose reconstructed POSIX form differs is refused.\nThese pointer payloads are immutable governance history under Article 3's\nnarrow exception; they **MUST NOT** be emitted for rev-14 or later.\n\nRev-14 and each successor using this profile carries all normative text inside\nthe chain frame. Its payload **MUST** include\n`schema:\"rapp-spec-revision/1\"`, a unique `revision`, and both\n`previous_revision` and `previous_normative_sha256` matching the immediate\npredecessor. It preserves the useful legacy fields above, carries the\npublication/ratification metadata defined below, and adds exactly this\n`normative` object:\n\n```json\n{\n  \"media_type\": \"text/markdown; charset=utf-8\",\n  \"text\": \"<exact normative SPEC.md Unicode text>\",\n  \"sha256\": \"<lowercase SHA-256 of text encoded as UTF-8>\",\n  \"bytes\": 123\n}\n```\n\n`normative.text` **MUST** encode as UTF-8 without a byte-order mark;\n`normative.sha256` and `normative.bytes` **MUST** match those exact octets and\nthe corresponding legacy `normative_sha256` and `normative_bytes`. The complete\ncanonical frame remains subject to §4's 1 MiB limit. Inline revisions require\nonly the selected, verified chain bytes once fetched; their commit/path fields\nare immutable provenance, not a second source for normative text.\n\nThe payload's `publication` object, repeated in the beacon and revision index,\nrecords: canonical repository `https://github.com/kody-w/rapp-1`; protected ref\n`refs/heads/main`; selection by owner-ratified acceptance; the accepted\ncanonical-main commit as linearization point; prohibition of history\nreplacement; mandatory rebase/regeneration for a competing append; rev-14\nratification under rev-13 Article 14; application of this chain-append process\nfrom rev-15 onward; and `authenticated_registry_checkpoint:null` until one\nactually exists. This metadata **MUST NOT** be interpreted as a signature or\nauthenticated registry.\n\n#### 12.2.3 Content-addressed publication and resolution\n\nEvery chain frame **MUST** also be published, without a trailing line\nterminator, at:\n\n```text\nanchor/frames/<frame_hash>.json\n```\n\nA fetch through mutable main is discovery only. Given frame hash `F`, a\nstranger may fetch\n`https://raw.githubusercontent.com/kody-w/rapp-1/main/anchor/frames/F.json`,\nparse it under the pinned bootstrap, and accept the object only if its computed\nwave equals `F`. For accepted snapshot commit `C`, the immutable URL is\n`https://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/frames/F.json`.\nWrong content at the correct hash-derived path is refusal.\n\n`anchor/index.json` is a deterministic generated index from `seq`, revision\nlabel, frame hash, and payload hash to those objects. It carries no independent\nauthority: a consumer **MUST** verify each selected object and match the index\nand beacon to the fully verified chain. Resolution by frame hash uses the path\nalgorithm directly; resolution by payload hash or sequence uses the verified\nindex; resolution by revision label is a view over it. The fixed pre-profile\nrev-5 pulses share one historical label, so the `rev-5` view resolves to the\ngreatest matching `seq`, while every pulse remains directly resolvable by\nsequence and hashes.\n\nA consumer **MUST** verify the chain from the bootstrap-pinned genesis before\nusing a revision as selected history. It **MUST** refuse an invalid frame shape,\nparticle, wave, or `prev`; a fork or duplicate `seq`; duplicate frame/payload\nhashes; a duplicate profiled revision; an unsupported schema; a legacy\npointer-only frame after rev-13; malformed UTF-8; normative hash/length drift;\nbootstrap/index/object drift; or an object absent from the selected chain.\n\n`orient.json` is only a beacon to the head. Its sequence, frame hash, payload\nhash, bootstrap/index pins, authority-selection metadata, and every retained\nhead mirror — including `registered_kinds`, vocabulary, operational profiles,\nfoundation, philosophy, and Constitution metadata — **MUST** be regenerated\nfrom and match the verified head. While the beacon schema remains\n`rapp/1-anchor`, `spec.normative_path` **MUST** remain as a compatibility alias\nequal to `spec.materialized_path`. `SPEC.md` **MUST** reproduce the selected\nhead byte-for-byte. The Atom feed and mutable main URLs are discovery only.\n\nMaterialization and immutable-pointer caching **MUST** use bounded reads and\nsame-directory atomic replacement without following a symlink in the\ndestination leaf or path. A symlink, unsafe directory component, oversized\ncache entry, content change during read/write, or compare-and-swap mismatch is\nrefusal; the requested leaf is replaced, never the symlink target.\n\nAfter acceptance, let `C` be the full 40-hex canonical-main commit containing\nthe accepted snapshot. The immutable checkpoint URLs are:\n\n```text\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/chain.jsonl\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/orient.json\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/index.json\n```\n\nThe authority linearization point is the owner-ratified acceptance of `C` onto\nprotected canonical main, not creation of a local frame, a feed event, or a\nhash alone. A stale competing append **MUST** rebase onto the accepted head and\nregenerate. Force-push or history replacement of accepted authority is\nprohibited.\n\n#### 12.2.4 Rev-14 transition and draft replacement\n\nRev-14 is ratified under rev-13 Article 14. Owner acceptance of the prepared\nchange onto canonical protected main makes the final rev-14 frame effective;\nthe new chain-append process governs rev-15 onward. Before that acceptance,\nrev-14 artifacts are unpublished drafts. A later commit in the same\nowner-ratified change may deterministically replace the one unpublished rev-14\ndraft line/object and update dependent hashes, but **MUST** preserve every\nrev-5 through rev-13 line byte-for-byte and **MUST NOT** represent the replaced\ndraft as accepted history.\n\nThe publication generator **MUST** hold one cross-process exclusive lock across\nread, verification, generation, comparison, and publication. Immediately\nbefore replacing `chain.jsonl` it **MUST** re-read and verify the on-disk head\nand compare the complete expected prefix; a stale writer or changed prefix is\nrefused. Supporting content-addressed artifacts are published first, the\nauthority chain is compare-and-swap replaced next, and the beacon is replaced\nlast, with file and parent-directory synchronization. Because the chain is\nauthority content and the beacon is only a derived view, interruption after a\nvalid chain replacement may leave a stale or missing beacon; the next locked\nrun **MUST** deterministically regenerate it from the verified chain rather\nthan refusing the valid head forever.\n\nThis chain and beacon are unsigned. They provide integrity after authority\nselection, not authorship, and implementations **MUST NOT** fabricate a\nsignature or authenticated registry/checkpoint state for them.\n\n## 13. The registry — an estate's signed root of trust (append-only)\nEach estate selects an owner-controlled `canonical_source` for its\n`schema:\"rapp/1-registry\"` document. The kody-w reference estate may publish\nits registry through `kody-w/RAPP` or another owner-authorized location, but\nthat estate instance cannot alter this protocol. Because §7.6 head resets, §10\nkey discovery, tombstone revocation, and ownership all resolve through the\nselected registry, it is the **root of trust for that estate** and is itself\nauthenticated (an unsigned mutable file at the root of the trust graph would\nforge that estate).\n\n### 13.1 Trust anchor and registry authentication\n- The one bootstrap axiom is the **`estate_owner` rappid string** itself: since a keyed tail is\n  `Hb(\"rapp/1:rappid\", SPKI_DER)`, the rappid **is** a self-certifying key fingerprint, distributed\n  out-of-band exactly once (QR, invite, docs) the way a root-CA certificate is.\n- The registry document **MUST** carry a top-level `registry_seq` (uint53) and a detached §10 JWS `sig` over\n  `canonical(registry \\ {sig})` with `kid` = the `estate_owner` rappid. A consumer **MUST** verify this\n  signature against an SPKI whose `Hb(\"rapp/1:rappid\", SPKI_DER)` equals the anchor rappid's tail (the SPKI\n  may travel alongside the registry — the tail check authenticates it) and **MUST** refuse an unsigned or\n  non-verifying registry.\n- **No rollback:** a consumer persists the highest `registry_seq` it verified and refuses any registry with\n  a lower one (mirrors §7.6). **Freshness:** a consumer **MUST** obtain the registry from `canonical_source`\n  or a provenance-stamped (Art. VIII) mirror of it, **SHOULD** refresh before any §7.5-step-6 or §7.6\n  head-reset decision, and **MUST** report a verification made against a registry older than its staleness\n  policy as *stale*, not *clean*.\n\n### 13.2 Owner succession (time-scoped authority)\n\"Owner-signed\" means: the `sig` verifies per §10 **and** `kid` is the estate-owner **in effect at the\nartifact's `utc`** — the current `estate_owner` or any predecessor reachable through the registry's\nre-anchor records (§13.3), with the artifact's `utc` inside that owner's tenure `[record.utc, successor.utc)`.\nVerification uses the owner in effect at the artifact's time, **never only the current one** (so a routine\nowner key rotation never invalidates historical re-genesis frames or tombstones). Estate-owner **root-key\ncompromise** is recovered only by re-distributing a new trust anchor out-of-band (§13.1) — it cannot be\nexpressed inside the registry it signs.\n\n### 13.3 Entry types (each a §4 value; document `schema:\"rapp/1-registry\"`)\nThe registry is an I-JSON document; every entry is append-only (never removed/renamed; retirement is a\n`deprecated:true` flag). Entry types and their exact members:\n- **protocol** `{type:\"protocol\", name, spec_repo, spec_path, spec_hash, deprecated}` — an estate\n  adoption pin, never a power to redefine a protocol. An entry with `name:\"rapp/1\"` that is used for a\n  current-conformance claim **MUST** set `spec_repo:\"https://github.com/kody-w/rapp-1\"`,\n  `spec_path:\"SPEC.md\"`, and `spec_hash` to a normative SHA-256 published by a verified frame in this\n  repository's anchor chain. A historical RAPP/1 pin may be retained only as `deprecated:true`; it does\n  not override the current anchor. Other protocol entries are subordinate to their own canonical\n  authorities and **MUST NOT** claim the `rapp/1` name or namespace.\n- **kind** `{type:\"kind\", kind, family, deprecated}` (incl. the three `*.re-genesis` kinds). A\n  `deprecated:true` kind entry still registers `kind` and its `family` for §7.5 step 1 (steps 1–5 are\n  time-independent); deprecation only tells producers to stop emitting new frames of that kind.\n- **egg-variant** `{type:\"egg-variant\", variant, deprecated}` · **error-code** `{type:\"error-code\", code}`\n  (both closed namespaces; unregistered value = not conformant)\n- **genesis** `{type:\"genesis\", stream_id, frame_hash, deprecated, old_stream_id?, new_stream_id?}` — **every**\n  stream registers its creation genesis; re-genesis appends a new one and deprecates all prior (§12.1 step 3);\n  §7.6's \"registered genesis\" is the sole non-deprecated `genesis` for a `stream_id`.\n- **spki** `{type:\"spki\", rappid, spki_der_b64, deprecated}` — the §10 key-discovery source.\n- **tombstone** `{type:\"tombstone\", rappid, revoked_utc, sig}`, `sig` owner-signed over `canonical(entry \\ {sig})`.\n- **re-anchor** `{type:\"re-anchor\", old_rappid, new_rappid, case:(\"upgrade\"|\"rotation\"|\"compromise\"|\"tag-migrate\"),\n  utc, sig, old_key_sig?}` — `sig` owner-signed; `old_key_sig` a §10 JWS by the **old** key over\n  `canonical(entry \\ {sig,old_key_sig})`, REQUIRED for `case:\"rotation\"`. This is the normative succession record (§13.2).\n- **grail-kernel** `{type:\"grail-kernel\", release_scope, grail_id, repository, immutable_ref,\n  object_format, commit, path, mode, blob, sha256, size_bytes, activated_utc, predecessor, declared_by,\n  sig}` — exactly these members. `release_scope` is an absolute HTTPS URI selected by the estate owner;\n  no two entries may share it. `grail_id` is\n  `\"grail:\" || Hb(\"rapp/1:grail\", kernel_bytes)`; `repository` is an absolute HTTPS URI;\n  `immutable_ref` is a full `refs/tags/...` name that **MUST** resolve exactly to `commit`;\n  `object_format` is `\"sha1\"` or `\"sha256\"` and fixes the required lowercase hexadecimal length of\n  `commit` and `blob`; `path` at `commit` **MUST** resolve through the repository tree to exactly one\n  regular blob with `mode` `\"100644\"` or `\"100755\"` and object id `blob`;\n  `path` is a relative NFC POSIX path with no empty, `\".\"`, or `\"..\"` component; `sha256` is the raw\n  kernel bytes' 64-lowercase-hex SHA-256; `size_bytes` is their positive `uint53` length;\n  `activated_utc` has the exact §7.4 form; `predecessor` is null or another `grail_id`; `declared_by` is\n  a keyed rappid; and `sig` is a detached §10 JWS whose protected `kid` equals `declared_by`, over\n  `canonical(entry \\ {sig})`. The entry is additionally covered by the registry's §13.1 signature. A\n  consumer verifies the entry signer as the estate owner in effect at `activated_utc`, verifies the\n  referenced bytes, recomputes both hashes, persists the canonical entry on first activation, applies\n  §11.1, and refuses a missing/mutated prior binding, duplicate `grail_id`, or locator whose bytes\n  disagree.\n- **estate_owner** `{type:\"estate_owner\", rappid}` (exactly one non-deprecated) · **master-plan**\n  `{type:\"master-plan\", repo, path}` (Fed. Const. Art. VII).\n\n§7.5 steps 1–5 are time-independent (append-only lookups); **only** step 6 (tombstones) and §13.2 owner\ntenure are time-scoped, and both are monotone given the §13.1 no-rollback rule.\n\n## 14. Security considerations\n- **Integrity:** every object is domain-separated content-addressed (§5); a hostile mirror cannot alter\n  bytes without breaking the hash, so *history is safe given a trusted head*.\n- **Head freshness is not self-certifying:** the chain authenticates history, not which head is current; a\n  hostile mirror may serve a stale/forked head. Consumers counter with the §7.6 monotonic-head rule; swarm\n  heads **SHOULD** be owner-signed.\n- **Cross-stream replay:** without §7.5 step 1a, any genesis/segment of stream A replays as stream B (seq=0,\n  prev=null always pass). Step 1a's stream binding is mandatory.\n- **Address-space confusion:** §5 domain tags make a particle, wave, egg, or rappid tail with equal hex\n  non-interchangeable; stores key by `(space, hash)`.\n- **Canonicalization attacks:** the §4 I-JSON input-domain profile (no duplicate keys, no lone surrogates,\n  exact binary64, no normalization ambiguity) removes hash-splitting and NFC-twin vectors.\n- **Identity forgery / key compromise:** authorship requires a keyed rappid + valid §10 `sig`; rotation is\n  §6.3 re-anchor (verifiable authorization, §6.3/§13.3 — a self-asserted `_migrated_from` is refused);\n  compromise is a §13 tombstone enforced at verify time. Because a tombstone gates on the frame's\n  producer-controlled `utc`, a compromised key can still emit frames stamped just below `revoked_utc`; after\n  a compromise the owner **SHOULD** advance affected stream heads (or re-genesis) past `revoked_utc`.\n- **Root of trust:** the registry is the estate's signed root (§13.1); it is authenticated by an owner\n  signature anchored to the out-of-band `estate_owner` rappid fingerprint, `registry_seq`-monotonic against\n  rollback, and freshness-checked (a stale registry silently un-revokes keys and hides re-geneses).\n- **Producer-controlled `utc` (DoS/merge bias):** a future-dated head can brick a stream (successors refused\n  as earlier) and bias UTC-first merges. A consumer **SHOULD** refuse a frame whose `utc` exceeds receipt\n  time by >300 s, and adversarial-scope merges **SHOULD** rank by `min(utc, first-seen)`; a bricked stream\n  converges by re-genesis (§12.1).\n- **Sealed-artifact limits:** a public mirror sees ciphertext and metadata. AES-GCM protects confidentiality\n  only while the DEK remains secret; a recipient that has lawfully decrypted plaintext can copy it.\n  Revocation stops future wrapped-key release, not prior possession. Shared passwords, embedded master keys,\n  moving-branch URLs, nonce reuse under one DEK, and claims that bytecode cannot be inspected after\n  decryption are non-conformant security postures (§9.2.1).\n- **Kernel substitution:** testing mutable ring bytes and restoring the Grail only after approval creates\n  an untested release. §11.1 requires the release-shaped artifact to contain the pinned bytes before its\n  tests, attestations, and approval; a digest mismatch is a blocking `kernel-drift` finding.\n- **Kernel registry rollback/rebinding:** persisting only `registry_seq` does not preserve an activated\n  Grail declaration across a malicious higher-sequence registry. Consumers also persist every activated\n  canonical `grail-kernel` entry and reject its later removal, mutation, or duplication (§11.1).\n\n## 15. References\n[RFC 2119] [RFC 8174] requirement terms · [RFC 8259] JSON · [RFC 7493] I-JSON · [RFC 8785] JCS ·\n[FIPS 180-4] SHA-256 · [RFC 3986] URI · [RFC 5234] ABNF · [RFC 7405] case-sensitive ABNF · [RFC 9562] UUID\n(obsoletes RFC 4122) · [RFC 5280] X.509 SPKI · [RFC 7515] JWS · [RFC 7797] unencoded JWS payload ·\n[RFC 7518] JWA/ES256 · [RFC 8037] EdDSA in JOSE · [RFC 6979] deterministic ECDSA · [RFC 3339] timestamps ·\n[NIST SP 800-38D] AES-GCM · [RFC 2104] HMAC · [RFC 5869] HKDF · [RFC 7516] JWE · [ECMA-262] ECMAScript ·\n[RFC 8032] EdDSA (Ed25519) · [RFC 8410] Ed25519 keys in X.509 SPKI · [UAX #15] Unicode normalization forms.\n\n---\n\n### Revision log\n- **rev-17 (the five-implementation erratum: 23 clarifications, no wire change)** — five clean-room\n  implementations (Python, TypeScript, Go, Swift, Rust) built from this text alone, run against a\n  434-vector suite and 20,000 differential fuzz probes, located every place the text let conformant\n  readers split. Each item restates or pins what the frozen forms already require (Art. 18), so no\n  conformant artifact changes verdict: `utc` digits are ASCII and years run 0000–9999 (§7.4, E-1); a\n  §4-valid but non-`uint53` `seq` is refused at §7.5 step 1, and `-0` is not a `uint53` (§7.4, §7.5, E-2,\n  E-9); noncharacters, a byte-order mark and UTF-16/UTF-32 input are outside the §4 domain (E-3, E-4); the\n  producer carries the NFC duty for `payload` member names and refuses unassigned code points (§4, E-5,\n  E-6); the tag table says which function uses each tag (§5, E-7); a minter validates its SPKI and UUIDv4\n  octets (§6.2, E-8); step 1 checks the JWS form and the §7.2 family/stream fit, step 4 the registered\n  genesis when there is no head, and step 6 the key and the equation (§7.5, E-10–E-12); every ZIP header\n  field is pinned, so byte identity holds (§9.1, E-13); path equality is code-point equality (§9.1, E-14);\n  the rapplication MAY list is open, `rappid.json` binds the packed identity, and empty neighborhood and\n  estate lists are valid (§9.2, E-15–E-17); a producer emits only eggs a consumer accepts (§9.3, E-18); the\n  sealed payload template separates literals from examples (§9.2.1, E-19); Ed25519 verification is the\n  cofactorless RFC 8032 check (§10, E-20); a deprecated `spki` flag alone refuses nothing (§10, E-21); the\n  re-genesis payload shape is a consumer check (§12.1, E-22); and a deprecated kind stays registered for\n  step 1 (§13.3, E-23). The reference implementation's deviations from the text are fixed alongside.\n- **rev-15 (the wire freeze)** — §12 freezes every form a `rapp/1` artifact is verified by (§4, §5,\n  §6.1–6.2, §7.1, §7.3, §7.5, §8, §9.1); a change to any of them is `rapp/2` beside this document, never a\n  revision of it, and `rapp/1` artifacts verify forever. Art. III is scoped to an estate's own artifacts.\n  Registration, vocabulary, profiles, and the registry keep growing under `rapp/1` (Art. IV). Constitution\n  Article 18 restates the rule.\n- **rev-14 (DOGG specification-chain authority)** — makes the append-only\n  `anchor/chain.jsonl` frame history carry normative specification content\n  while protected canonical-main acceptance selects authority; defines the\n  frame hash as durable revision identity; embeds the normative Markdown in a\n  normal `body.pulse`; retains immutable rev-5–rev-13 pointer history; freezes\n  a content-addressed bootstrap verifier profile; publishes hash-addressed\n  frame objects and a deterministic index; makes `SPEC.md` a materialized\n  selected-head view; and records the rev-13 Article 14 transition without\n  inventing signatures or changing any RAPP/1 wire primitive.\n- **rev-13 (public governance closure)** — makes the ratified public Protocol\n  Constitution final for protocol governance; limits private governance and\n  master plans to estate/product concerns; makes registry `protocol` entries\n  subordinate adoption pins; verifies the exact canonical RAPP foundation\n  object before anchoring; and aligns every public teaching surface with\n  estate-specific registry authority.\n- **rev-12 (foundation/protocol boundary)** — records `kody-w/RAPP` as the\n  canonical public foundation and product home; limits `kody-w/rapp-1` to\n  protocol authority; ratifies the complete public Protocol Constitution; makes\n  registries explicit estate instances rather than protocol authorities; pins\n  the canonical foundation commit and philosophy hash; and removes any\n  implication that protocol publication transfers product, brand, company, or\n  ownership authority.\n- **rev-11 (planetary operations profiles)** — constitutionalized immutable candidate/serving lineage\n  separation; defined RAPP CI/CD (`rapp-cicd/1`) and RAPP Deploy (`rapp-deploy/1`) as subordinate,\n  registry-pinned production profiles; required exact-candidate qualification, production-shaped\n  Preprod, cellular progressive exposure, expiring AI-health evidence, state/data continuity,\n  automatic containment, and exact rollback while retaining policy-defined extension points; and\n  defined typed, non-authoritative offspring/cross lineage without changing the egg or frame envelopes.\n- **rev-10 (sealed artifact + Grail execution closure)** — registered the `sealed` egg variant for\n  globally mirrorable public ciphertext with signed manifests and scoped recipient key release (§9.2.1);\n  added the `rapp/1:sealed-aad` and `rapp/1:sealed-key-request` address spaces; retained rev-9's exclusive\n  `release_scope` selection, persisted Grail binding, and verification-to-execution protections; and made\n  both confidentiality limits and kernel drift release-blocking.\n- **rev-9 (Grail selection and execution closure)** — makes release policy select only\n  `release_scope`, resolves `grail_id` exclusively through the activated persisted registry binding,\n  and closes verification-to-execution races by requiring a sealed immutable object/snapshot or\n  platform-enforced write exclusion through byte consumption.\n- **rev-8 (immutable Grail closure)** — makes pin selection deterministic through `release_scope`,\n  defines the exact signed §13.3 `grail-kernel` entry and owner-at-time activation, requires consumers\n  to persist every accepted binding, and specifies repository-object and executed-entry-point\n  verification across interpreted and derived runtimes.\n- **rev-7 (immutable Grail constitution)** — defines the Grail kernel by the SHA-256 of its exact bytes\n  (§3), makes every ring and release/deployment stage verify both the pin and the actually executed entry\n  point (§11.1), forbids post-test substitution, and makes changed bytes a different Grail rather than a\n  mutation. This is release governance only; the RAPP wire and existing canonical forms are unchanged.\n- **rev-6 (instantiation lineage)** — added §9.4's fresh per-install instance identity and immutable\n  `grown_from` lineage, closing the hatch seam without changing the frame or egg envelopes.\n- **rev-5 (war-game round 3 fold)** — folded 5 blockers + 7 majors + 7 minors, all clustered on the trust\n  model that rev-4's fixes made load-bearing: the **registry is now a signed root of trust** (§13.1) —\n  owner-signed, anchored to the out-of-band `estate_owner` rappid fingerprint, `registry_seq`-monotonic,\n  freshness-checked (B-1); **re-anchor requires a verifiable §13.3 authorization record** with old-key\n  continuity proof / tombstone / SPKI-tail check (B-2, mint-once now enforceable); **owner-succession is\n  time-scoped** so a key rotation never invalidates historical signatures (B-3); **eggs are `stored`-only**\n  (deflate is non-deterministic) with `canonical(manifest)` bytes (B-4); **invites sign under the\n  estate-owner succession** not the egg's own rappid (B-5); `egg_hash` excludes `sig` (M-1); first\n  re-genesis deprecates the creation genesis (M-2); full **registry entry schema** §13.3 (M-3); registry\n  freshness rule (M-4); egg consumer enforces §9.1 (zip-slip, M-5); rotated key refused on new frames (M-6);\n  `rapplication` exact `agent.py` (M-7); rev label, `invite` naming, sub-egg collision, rounding rule,\n  idempotency, compromise-window, seal-path (m-1…m-7).\n- **rev-4 (war-game round 2 fold)** — folded 6 blockers + 14 majors + 8 minors: domain-tagged mint\n  reconciled across Constitution/ledger (B1); §4(c) binary64 round-trip test so `0.1` is accepted (B2);\n  re-genesis head-reset exception so it isn't refused as rollback (B3); family-matched `*.re-genesis` kinds\n  so memory/swarm streams can converge (B4); whole-egg address `H(\"rapp/1:egg-manifest\",…)` + signed invites\n  + manifest self-reference resolved + deterministic ZIP/`contents` ordering (B5, M2–M4); re-anchor\n  enumerated three cases incl. key rotation (B6, M-rotation); `head_octets` pinned to the retained `legacy/`\n  artifact (M6); subsequent-convergence via `deprecated` (M7); every stream registers its genesis (M8); JWS\n  header canonical bytes + registry key-discovery + `estate_owner` designation (M9–M11); `/chat` error `step`\n  as string incl. `\"1a\"` + code namespace + session semantics (M12, m5); tombstone as the one time-dependent\n  verify check (M13); egg draft-artifact + dangling `§4` reference removed (M1, M5); calendar-valid `utc`,\n  depth convention, kind dedup/bounds (m2, m7, m8).\n- **rev-3 (war-game round 1 fold)** — folded 7 blockers + 19 majors + 12 minors from the Fable adversarial last-call:\n  I-JSON input domain + no-normalization/NFC (§4); **domain-separated hashing** (§5, the stronger option);\n  fixed `utc` byte form (§7.4); `prev_wave` by stream family not transport (§7.4); **stream-binding**\n  anti-replay (§7.5.1a); `spec` token pinned to `rapp/1` (§7.1); full JWS profile + key discovery + rotation/\n  tombstone (§10); hardened re-genesis with raw-byte terminal seal + registry linearization (§12.1); heads &\n  forks (§7.6); `/chat` fully specified (§8); **egg variants ratified into the standard**, killing the\n  6-spec collision and closing EGG-01 (§9); registry append-only (§13); type-validated verify (§7.5.1);\n  cross-stream merge tie-break (§7.4); provisional-identifier rule (§6.3); all references added (§15).\n- **rev-2** — first last-call tightening (7 self-review defects).\n- **rev-1** — initial unified draft.\n\n*The canonical protocol authority is the owner-selected, verified\nspecification chain in this repository. The canonical public RAPP foundation\nand product home remain at `kody-w/RAPP`.*\n", "sha256": "768aeefbf779925b6c937bd497ff628a5061b1e20a82a29892f6cdd5481178e1", "bytes": 88831}, "publication": {"canonical_repository": "https://github.com/kody-w/rapp-1", "protected_ref": "refs/heads/main", "selection": "owner-ratified acceptance of the chain snapshot onto protected canonical main", "linearization": "the accepted canonical-main commit containing the new frame", "history_replacement": "prohibited", "competing_append": "must rebase onto the accepted head and regenerate", "transition": "rev-14-ratified-under-rev-13-article-14", "chain_append_process": "governs-rev-15-and-later", "authenticated_registry_checkpoint": null}}, "payload_hash": "831f1f0d378f0d6e1362f2333e9bd9f5db3066ee4fc2ae65d39d564a5ea57316", "prev": "61a01808240e16066bdf0437933ac16b6530c939e9f31f67fac44d517f1e580c", "prev_wave": null, "sig": null, "frame_hash": "84f1975daf09010b8880b9da930841054700ee3f401ccedf0d333dc44453f7ed"}
{"spec": "rapp/1", "kind": "body.pulse", "stream_id": "rappid:@kody-w/rapp-1-anchor:a4298c417789ecff68b7be3df4d8b90d397c43f972eaf839977db16dbe02acc6", "seq": 18, "utc": "2026-10-07T21:19:01.000Z", "payload": {"canonical_repo": "https://github.com/kody-w/rapp-1", "commit": "49a62e82a64d04e174ed8677338b2e417d5ab44e", "commit_utc": "2026-10-07T17:19:01-04:00", "default_profile": "interop", "exchange": {"carrier": "POST /chat with {\"user_input\": <envelope>}; the reply is in the `response` field. Offline, the identical frames ride store-and-forward.", "idempotence": "keyed on the request's payload_hash — a retry returns the existing reply, never a second one.", "rule": "the responder appends its reply to its OWN chain BEFORE returning it, so the synchronous answer and the replicated answer are the same frame with the same frame_hash. A fast path must never state a fact the durable path disagrees with.", "shape": "push a frame in, get a frame back shaped by what you pushed — ONE hop."}, "frame_keys": ["spec", "kind", "stream_id", "seq", "utc", "payload", "payload_hash", "prev", "prev_wave", "sig", "frame_hash"], "kind_families": {"body": {"kinds": ["body.pulse", "body.twin-pulse", "body.reconstructed", "body.re-genesis"], "logs": "an organism's biography", "stream": "body-stream (bare rappid)"}, "memory": {"kinds": ["memory.chat-turn", "memory.tool-call", "memory.save", "memory.reconstructed", "memory.re-genesis"], "logs": "one organism's life", "stream": "memory-stream"}, "swarm": {"kinds": ["swarm.guidance", "swarm.echo", "swarm.telemetry", "swarm.reconstructed", "swarm.re-genesis"], "logs": "the planetary wire", "stream": "swarm-stream (net:label)"}}, "moods": {"clear": {"profile": "interop", "when": {"conditions": "clear,sunny"}, "why": "good conditions, normal posture"}, "early": {"profile": "minimal", "when": {"hour_lt": "6"}, "why": "same"}, "night": {"profile": "minimal", "when": {"hour_gte": "22"}, "why": "low-attention hours; smallest honest context"}, "storm": {"profile": "audit", "when": {"conditions": "storm,rain,snow"}, "why": "degraded links are when drift hides; lead with verification"}}, "normative_bytes": "89846", "normative_path": "SPEC.md", "normative_sha256": "e81e20ba9402ee96422f73e9ef737eba100264155c8f77521600766be8fb21e9", "observed_utc": "2026-10-07T21:19:01.000Z", "profile_signals": {"author": "authoring", "build": "authoring", "check": "audit", "conform": "audit", "drift": "audit", "handshake": "interop", "install": "onboarding", "join": "onboarding", "mint": "authoring", "new": "onboarding", "stranger": "interop", "unknown-peer": "interop", "verify": "audit", "write": "authoring"}, "profiles": {"audit": {"max_rules": "8", "show": ["keys", "stale_terms"], "types": ["pattern", "gotcha"], "why": "judging conformance; refuse-never-repair and the identity law govern"}, "authoring": {"max_rules": "8", "show": ["keys", "eggs"], "types": ["gotcha", "fact"], "why": "hand-building a frame; the envelope rules are what bite"}, "interop": {"max_rules": "6", "show": ["keys", "stale_terms", "pointer"], "types": ["gotcha"], "why": "a peer may be out of date; lead with what it can get WRONG"}, "minimal": {"max_rules": "0", "show": ["stale_terms"], "types": [], "why": "smallest honest context"}, "onboarding": {"max_rules": "5", "show": ["keys", "eggs", "stale_terms", "pointer"], "types": ["fact"], "why": "new organism; needs the shape of the world, not the edge cases"}}, "registered_kinds": ["body.pulse", "body.re-genesis", "body.reconstructed", "body.twin-pulse", "memory.chat-turn", "memory.re-genesis", "memory.reconstructed", "memory.save", "memory.tool-call", "swarm.echo", "swarm.guidance", "swarm.re-genesis", "swarm.reconstructed", "swarm.telemetry"], "revision": "rev-18", "rules": [{"c": "spec MUST be exactly \"rapp/1\"; exactly the eleven keys, none missing, none extra; a field that does not apply is present as null, never omitted.", "t": "fact"}, {"c": "Canonical form is RFC 8785 JCS and FORBIDS floats — numbers ride as strings. A float silently breaks byte-reproducibility.", "t": "gotcha"}, {"c": "payload_hash = H(\"rapp/1:particle\", payload) — content only, reproducible across instances.", "t": "fact"}, {"c": "frame_hash = H(\"rapp/1:wave\", frame minus {frame_hash, sig}) — unique per stream instance.", "t": "fact"}, {"c": "prev_wave is non-null IFF the stream is a swarm-stream AND seq>0; null everywhere else, including EVERY genesis. Setting it on an ordinary chain makes the frame unverifiable.", "t": "gotcha"}, {"c": "§6.2 MINT-ONCE: the 64-hex tail is minted from uuid4 entropy exactly once. A producer MUST NOT derive it from owner/slug or any name — sha256(\"owner/slug\") is prohibited (drift ID-01/C3). On read, reuse the stored tail; never re-mint.", "t": "gotcha"}, {"c": "Verification REFUSES, never repairs or reparents. A frame that does not verify is quarantined and reported, not fixed.", "t": "pattern"}, {"c": "A swarm-stream frame with sig==null is refused (§7.5 step 6), so unsigned coordination belongs on body/memory streams, which permit sig==null.", "t": "gotcha"}, {"c": "Eggs are byte-reproducible: ZIP method `stored` only, timestamps 1980-01-01, contents sorted by UTF-8 path bytes. Two conformant packers of the same manifest emit BYTE-IDENTICAL eggs.", "t": "fact"}, {"c": "Cross-stream merge order (Dream-Catcher) is ascending utc bytewise, ties broken by ascending frame_hash bytewise — this is how N streams compose into one view.", "t": "pattern"}, {"c": "One writer per stream. Two writers computing seq=head.seq+1 produce duplicate seqs; distinct streams stay distinct.", "t": "pattern"}, {"c": "§9.4 (rev-6): hatching an egg MUST mint a fresh §6.2 identity for the INSTANCE — the artifact rappid rides the egg unchanged and is shared by every install; the instance identity never is. The instance SHOULD record grown_from = the §9.1 egg address it grew from: written at mint, immutable, null when unknown, NEVER fabricated. Lineage, not inheritance — it confers no authority, no trust, no key material.", "t": "fact"}, {"c": "§11.1 / Constitution Article 15: owner policy selects only release_scope; the activated registry selects grail_id; every ring rejects kernel-drift; execution consumes bytes from a sealed immutable object or equivalent write-excluded snapshot.", "t": "gotcha"}, {"t": "gotcha", "c": "A sealed egg is public ciphertext, not password-protected hosting: the signed manifest binds AES-256-GCM data and a scoped key service; no shared DEK belongs in the egg, URL, client, log, or frame."}, {"t": "fact", "c": "RAPP CI/CD promotes one immutable release payload hash through an ordered evidence chain; no ring may rebuild, patch, substitute, or skip the candidate."}, {"t": "gotcha", "c": "RAPP Deploy forbids in-place serving mutation: growth happens in an isolated candidate lineage and reaches users only through bounded, reversible waves."}, {"t": "pattern", "c": "A new encounter may produce an offspring or cross with a fresh identity and typed parent addresses; lineage may continue indefinitely, but every attempt is bounded and parent authority never transfers implicitly."}, {"t": "fact", "c": "kody-w/RAPP remains the public foundation and product home; kody-w/rapp-1 defines the interoperable protocol only."}, {"t": "fact", "c": "The rapp/1 wire is frozen: §4, §5, §6.1-6.2, §7.1, §7.3, §7.5, §8 and §9.1 never change under the rapp/1 token; a change is rapp/2 beside it, and rapp/1 artifacts verify forever."}, {"t": "fact", "c": "RAPP Work uses seven registered body kinds on the unchanged eleven-key frame; catalog locators, Portable Neurons, Git, raw paths, and static API documents remain inert evidence or discovery rather than authority."}, {"t": "gotcha", "c": "A completed RAPP Work migration verifies retained intent, signed evidence, unchanged source, exact rollback, and key custody before any mutation."}, {"t": "gotcha", "c": "rev-17 clarifies without changing the wire: utc digits are ASCII; noncharacters, a byte-order mark and UTF-16 input are outside §4; a §4-valid seq such as 2^53 or -0 is refused at §7.5 step 1, never before the checklist."}, {"t": "fact", "c": "Two conformant packers of one manifest emit byte-identical eggs: every ZIP header field is pinned (version needed 20, made by 0x0014, flags 0x0800, attributes 0); a consumer accepts any value only in version made by, version needed and the attributes."}, {"t": "pattern", "c": "A producer refuses what a consumer refuses: a frame builder or egg packer runs the consumer's registry-free checks on its own output and refuses rather than emit or repair."}], "vocabulary": {"body": {"status": "live", "where": "§7.2 kind family"}, "estate": {"status": "live", "where": "§9.2 egg variant"}, "grail": {"status": "live", "where": "§3 terminology; §11.1 immutable Grail kernel conformance; Constitution Article 15"}, "grown_from": {"status": "live", "where": "§9.4 instantiation — instance lineage key"}, "instance": {"status": "live", "where": "§9.4 instantiation — a hatched install; fresh §6.2 identity, never shared"}, "invite": {"status": "live", "where": "§9.2 egg variant"}, "memory": {"status": "live", "where": "§7.2 kind family"}, "metropolis": {"status": "retired", "where": "rapp-metropolis/1.0 tier 3; that doc is now a retirement notice in kody-w/rapp-estate — bytes only at git 24c8fdc, sha256 690f6109…"}, "neighborhood": {"status": "live", "where": "§9.2 egg variant"}, "organism": {"status": "live", "where": "§9.2 egg variant"}, "rapp-frame/2.0": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-frame/2.1": {"status": "retired", "where": "legacy envelope token, superseded by rapp/1 (§7.1)"}, "rapp-protocol/1.0": {"status": "retired", "where": "legacy, superseded by rapp/1"}, "rapp-rappid-spec/2.0": {"status": "retired", "where": "legacy, superseded by rapp/1 §6"}, "rapplication": {"status": "live", "where": "§9.2 egg variant"}, "rbox": {"status": "not-in-spec", "where": "operator's working word for a machine running an organism; the spec's words are `organism` (§9.2) and `instance` (§9.4)"}, "session": {"status": "live", "where": "§9.2 egg variant"}, "swarm": {"status": "live", "where": "§7.2 kind family"}, "sealed": {"status": "live", "where": "§9.2 sealed egg variant and §9.2.1 profile"}, "rapp-cicd": {"status": "live", "where": "§11.2 and protocols/rapp-cicd/1/SPEC.md"}, "rapp-deploy": {"status": "live", "where": "§11.2 and protocols/rapp-deploy/1/SPEC.md"}, "offspring": {"status": "live", "where": "§9.4 typed lineage and PHILOSOPHY.md"}, "cross": {"status": "live", "where": "§9.4 typed multi-parent lineage and PHILOSOPHY.md"}, "wire-freeze": {"status": "live", "where": "§12 and Constitution Article 18 — the rapp/1 verified forms never change; a change is rapp/2"}, "rapp-work": {"status": "live", "where": "protocols/rapp-work/1/SPEC.md — additive organization, Hive high-water, migration, custody, and rollback"}}, "philosophy": {"canonical_repository": "https://github.com/kody-w/RAPP", "canonical_commit": "cb921ae59b5d762ce0bdd5493764cbb1c8b539fe", "canonical_path": "PHILOSOPHY.md", "canonical_sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c", "mirror_path": "PHILOSOPHY.md", "mirror_sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c"}, "operational_profiles": {"rapp-cicd/1": {"status": "live", "spec_path": "protocols/rapp-cicd/1/SPEC.md", "spec_sha256": "6d27d10103a3204f3b65a2e246462d197016bce5203dd510ba3ce209740e8278", "schema_path": "protocols/rapp-cicd/1/schema.json", "schema_sha256": "5936057868f46fc74afa00532f4aea60cfbb667c7c2f09998e1e86a0c2e629cc"}, "rapp-deploy/1": {"status": "live", "spec_path": "protocols/rapp-deploy/1/SPEC.md", "spec_sha256": "b5fc84465fb201fd97d7059997490a8fae5bf79ec55e935b0cfd9b4c787108e5", "schema_path": "protocols/rapp-deploy/1/schema.json", "schema_sha256": "aca783f3274cd865926f6b943163189fa93a7bbc4c7d4258856a54779a4a71ba"}, "rapp-work/1": {"status": "live", "spec_path": "protocols/rapp-work/1/SPEC.md", "spec_sha256": "283359355c3fe2858e28744368255683af3ed28a68e290e56c231e7d4b13c08e", "schema_path": "protocols/rapp-work/1/schema.json", "schema_sha256": "ff30f9878f12fa4ad7d93c4c205eb1cb580137a7dee87aa9d23c88a93466d19e"}}, "constitution": {"path": "CONSTITUTION.md", "sha256": "59b600d63e329de5adf11aa6dd103c82e62c72882edd899788e80fd316b21d43", "size_bytes": 17403}, "foundation": {"schema": "rapp-foundation-pointer/1", "status": "canonical-product-home", "repository": "https://github.com/kody-w/RAPP", "commit": "cb921ae59b5d762ce0bdd5493764cbb1c8b539fe", "path": "PHILOSOPHY.md", "sha256": "901826afd8be6e4b4bc24f83777b6d75ee29aabbff2a12655d2ab64a4e8e489c", "size_bytes": 2633, "relationship": "kody-w/RAPP is the public RAPP foundation and product home; kody-w/rapp-1 is the interoperable protocol authority"}, "schema": "rapp-spec-revision/1", "previous_revision": "rev-17", "previous_normative_sha256": "768aeefbf779925b6c937bd497ff628a5061b1e20a82a29892f6cdd5481178e1", "normative": {"media_type": "text/markdown; charset=utf-8", "text": "# The RAPP Protocol Suite\n### Unified normative specification of identity, canonicalization, the frame, the wire, and the egg\n\n> **Generated/materialized view.** These exact UTF-8 bytes are carried inside\n> the selected specification-revision frame in `anchor/chain.jsonl`. The frame\n> chain proves integrity and lineage; canonical owner-ratified publication\n> selects authority. Change the protocol by appending a successor frame, not by\n> treating this file as independent authority.\n\n**Status:** Owner-ratified RAPP/1 **rev-18 erratum**. It is effective iff the\nprepared chain snapshot has been accepted onto canonical protected main under\nthe transition in §12.2. **Obsoletes / consolidates:**\n`rapp-frame/2.0`, `rapp-frame/2.1`, `rapp-rappid-spec/2.0`, `rapp-protocol/1.0`, all scattered egg specs\n(§9 subsumes them), and `OSI.md`. This is the current materialized view of the single living standard;\nthe consolidated specs are retired historical record (Protocol Constitution Article 6). Rev-14 becomes\nthe published current revision when the source merge and append-only anchor update carrying these exact\nbytes complete.\n\n**Rides existing standards; invents nothing:** requirement terms [RFC 2119]/[RFC 8174]; JSON restricted to\nI-JSON [RFC 7493] over [RFC 8259]; canonicalization [RFC 8785] (JCS); hashing SHA-256 [FIPS 180-4] with\ngit-style domain separation; identifiers on the [RFC 3986] URI model; case-sensitive grammar [RFC 7405]\nover [RFC 5234] ABNF; keyless entropy UUIDv4 [RFC 9562]; keyed identity X.509 SPKI [RFC 5280]; signatures\ndetached unencoded JWS [RFC 7515]/[RFC 7797], EdDSA [RFC 8037] / ES256 [RFC 7518]/[RFC 6979]. RAPP is a\n*profile* over these, as HTTP profiles TCP/URIs/MIME.\n\n---\n\n## 1. Introduction\nRAPP is a content-addressed distributed organism. Its integrity rests on one invariant: **the same\nconcept has the same bytes everywhere.** This document specifies, normatively and completely, five\nload-bearing primitives so any two independent implementations interoperate **byte-for-byte with no\nout-of-band agreement**: canonicalization (§4), content addressing (§5), identity (§6), the frame (§7),\nthe egg (§9) — all riding one wire (§8): `POST /chat`, or a signed append-only frame. Implementations add\nagents, cartridges, and registered `kind`s — never new endpoints, never new envelopes.\n\n**Repository scope.** `kody-w/RAPP` is the canonical public RAPP foundation,\nproduct home, reference implementation, organism model, and philosophy.\n`kody-w/rapp-1` is the canonical interoperable protocol authority. This\nspecification governs wire-compatible bytes and conformance; it does not absorb\nthe RAPP product or any downstream Rappter/RapterBox LLC product.\n\n**Specification authority.** The append-only DOGG chain at\n`anchor/chain.jsonl` carries the normative revision content. Its hashes prove\nintegrity, not authority or ratification. Until an authenticated RAPP\nregistry/checkpoint exists, the chain accepted by the owner onto protected\ncanonical `kody-w/rapp-1` main is authoritative; an immutable accepted commit\nplus head frame hash is the portable checkpoint. `SPEC.md` is the byte-exact\nmaterialized human view, and `orient.json` is only a discovery beacon. The\nselected chain-frame hash, not a mutable path or `rev-N` label, is the durable\nidentity of a protocol revision (§12.2).\n\n### 1.1 The layered model\n```\n  L5  EGG        cartridge packaging (§9)          — MIME-multipart analogue\n  L4  FRAME      universal event envelope (§7)     — the IP packet of RAPP\n  L3  WIRE       transport: /chat + frames (§8)    — HTTP-analogue single method\n  L2  IDENTITY   rappid namespace + trust (§6,§10) — URI + PKI analogue\n  L1  ADDRESS    canonicalization + hash (§4,§5)   — the git object model\n```\nA higher layer **MUST NOT** redefine a lower one. Every layer names exactly one canonical form.\n\n## 2. Requirements language\nThe key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHOULD**, **MAY** are as in [RFC 2119]/\n[RFC 8174] when in **bold caps**. (The Federal Constitution adopts the same clause.)\n\n## 3. Terminology\n**organism** — a running brainstem with persistent identity. **rappid** — the eternal, mint-once name of an\norganism/door/object (§6): minted once from a UUIDv4 or a public key, never derived from content or name.\n**frame** — one immutable content-addressed event (§7). **stream** — an append-only hash-chained frame\nsequence sharing one `stream_id`. **particle / wave** — a frame's two domain-separated addresses:\npayload-hash / whole-frame-hash (§7.3). **canonical form** — the one [RFC 8785] byte string for a value\n(§4). **legacy form** — any other historical encoding; legacy is drift and **MUST** be migrated out\n(Fed. Const. Art. III), except sealed re-genesis history (§12.1).\n**Grail kernel** — an estate-declared, byte-pinned runtime substrate. Its `grail_id` is\n`\"grail:\" || Hb(\"rapp/1:grail\", kernel_bytes)`; repository, immutable ref, commit, path, raw SHA-256,\nand byte length are provenance and verification data, not alternate identities. Once activated through\n§13.3, those bytes are permanent (Protocol Constitution Art. 15); capabilities evolve outside them.\n**release capsule** — the canonical `rapp-cicd/1-release` payload identifying one immutable candidate.\n**serving lineage** — the sequence of qualified release identities that have received user traffic;\nthe currently served release is immutable even while a separate candidate lineage grows.\n**deployment cell** — an independently observable and isolatable runtime failure domain governed by\n`rapp-deploy/1`.\n\n## 4. Canonicalization (L1)\n`canonical(v)` is the UTF-8 byte string produced by **[RFC 8785] JCS** for the value `v`, defined **only**\nover I-JSON [RFC 7493]. JCS fixes member-name ordering (UTF-16 code-unit), string escaping, and number\nserialization (ECMAScript `Number::toString`, [ECMA-262]); there is no insignificant whitespace and no\nbyte-order mark. Input JSON text **MUST** be well-formed UTF-8 [RFC 7493] §2.1; an implementation **MUST**\nrefuse (not strip) a leading byte-order mark and **MUST NOT** transcode UTF-16 or UTF-32 input.\n(Insignificant whitespace in input text is accepted; it is absent only from the canonical form.)\n\n**RAPP input-domain profile (parse-side interoperability — this is a RAPP rule, not a JCS mandate).** An\nimplementation **MUST** refuse (never repair) any JSON value that, at any depth, contains: (a) duplicate\nmember names in one object; (b) an unpaired UTF-16 surrogate, or a Unicode noncharacter (U+FDD0-U+FDEF, or\nany code point whose low 16 bits are FFFE or FFFF) [RFC 7493] §2.1, in any string or member name; (c) a number token that does\nnot survive the binary64 round-trip — let `d` be the token's nearest binary64 value under `roundTiesToEven`\n(the IEEE-754 default; ±∞ are admissible results); the token is refused iff `d` is not finite, or the\n[RFC 8785] serialization of `d` (ECMA-262 `Number::toString`) denotes a different mathematical value than\nthe token (so `0.1` is accepted — it round-trips — while `9007199254740993` and `1e999` (→ +∞) are refused;\nfield range and type rules, such as `uint53`, are not part of this domain: the rule that types the field\napplies them); (d) canonical form exceeding 1 MiB or JSON nesting depth\nexceeding 64 (the root value is depth 1; each nested object/array adds 1). Refusal is whole (§7.5-style),\nnever partial.\n\n**No normalization.** RAPP applies **no** Unicode normalization when hashing, storing, or re-emitting an\nexisting value; strings are code-point sequences preserved verbatim and equality everywhere is code-point\nequality (no canonical-equivalence matching). A producer creating a **new** human-or-identifier string\n(slug, kind, label, `payload` object key) **MUST** emit it in Unicode NFC. A producer that builds a frame or\npacks an egg from given fields treats every `payload` object member name, at any depth, as new: it\n**MUST** refuse (never normalize) a name that is not in NFC. Consumers do not test frame contents for NFC\n(egg paths excepted, §9.1). NFC is Unicode Normalization Form C [UAX #15] in the Unicode version the\nproducer implements. A producer **MUST** also refuse a name containing a code point that is unassigned\n(General_Category `Cn`) in that version. By the Unicode normalization stability policy, a name that passes\nthis test for one producer then passes it for every producer on the same or a later Unicode version.\n\n> **Migration note (drift C4):** the `twin`/`rapp-body` `_frame.mjs::canonicalize()` (sorted-key\n> `JSON.stringify`) coincides with JCS only for string-only payloads; it **MUST** be replaced by the JCS\n> implementation of record, imported (not re-typed) by every repo that content-addresses.\n\n## 5. Content addressing (L1) — domain-separated\nEvery hash is **domain-separated** (git's `type\\0`, Nix's tagged store — collisions across address spaces\nare made unconstructible):\n```\nH(space, v) = lowercase_hex( SHA-256( utf8(space) || 0x0A || canonical(v) ) )     ; v a value (§4)\nHb(space, b) = lowercase_hex( SHA-256( utf8(space) || 0x0A || b ) )                ; b raw octets\n```\n`space` is an exact ASCII tag, none containing `0x0A`: `\"rapp/1:particle\"`, `\"rapp/1:wave\"`, `\"rapp/1:egg\"`,\n`\"rapp/1:egg-manifest\"`, `\"rapp/1:rappid\"`, `\"rapp/1:grail\"`, `\"rapp/1:seal\"`,\n`\"rapp/1:sealed-aad\"`, `\"rapp/1:sealed-key-request\"`. A tag is used by either `H` or `Hb`, never\nboth: `H` uses `rapp/1:particle`, `rapp/1:wave`, `rapp/1:egg-manifest`, `rapp/1:sealed-aad` and\n`rapp/1:sealed-key-request`; `Hb` uses `rapp/1:egg`, `rapp/1:rappid`, `rapp/1:grail` and `rapp/1:seal`. An\nimplementation **MUST** refuse to compute a hash under any other tag or with the other function. Output is always exactly 64 lowercase hex, **never truncated or uppercased**. Two values\nare treated as the same object iff their same-space hashes are equal; SHA-256 collision resistance\n[FIPS 180-4] is a security assumption of this standard (§14). A `name/X.Y` label is never identity — only\na hash is. A bare 64-hex is meaningful **only** within its space; an implementation **MUST NOT** dereference\na hash from one space as an object of another, and content-addressed stores **MUST** key by `(space, hash)`.\n\n## 6. Identity — the rappid (L2)\n### 6.1 Grammar (case-sensitive, [RFC 7405])\n```abnf\nrappid    = %s\"rappid:@\" owner \"/\" slug \":\" hash\nowner     = lclabel                       ; the lowercase GitHub login (1-39 chars)\nslug      = lclabel                        ; 1-100 chars\nlclabel   = lcalnum *( [\"-\"] lcalnum )     ; no leading/trailing/adjacent hyphen\nlcalnum   = LCALPHA / DIGIT\nLCALPHA   = %x61-7A                         ; a-z\nhash      = 64HEXDIGLC\nHEXDIGLC  = DIGIT / %x61-66                 ; 0-9 a-f\n```\n`owner` **MUST** be the lowercase form of the GitHub login (logins are case-insensitive; display casing is\npresentation, never identity). Lengths are normative: `owner` 1–39, `slug` 1–100; an implementation\n**MUST** refuse longer. This self-locating form is the **only** conformant rappid; `rappid:<slug>:<hash>`,\n`rappid:v2:…`, bare UUIDs, `moment:`/name-hash derivations are legacy and **MUST** be migrated out\n(Art. III), not read forever.\n\n### 6.1.1 stream_id and kind grammar\n```abnf\nstream_id   = memory-stream / body-stream / swarm-stream\nmemory-stream = rappid \":\" instance      ; one organism instance's memory\nbody-stream   = rappid                    ; an organism's biography\nswarm-stream  = %s\"net:\" lclabel          ; a planetary-wire stream\ninstance      = lclabel                   ; 1-64 chars\nkind          = lclabel \".\" lclabel       ; each label 1-64 chars\n```\nA `kind` string carries **no intrinsic family**; the §13 registry binds each registered `kind` to exactly\none family. Membership is tested by exact-match against the registry — never prefix inference, never wildcards.\n\n### 6.2 Minting (mint-once)\nThe 64-hex tail is minted **exactly once** per identity, then immutable:\n- **keyless:** `tail = Hb(\"rapp/1:rappid\", uuid4_octets)`, where `uuid4_octets` is the 16-octet binary\n  UUIDv4 [RFC 9562] §5.4 (field/byte order per §4 of that RFC).\n- **keyed:** `tail = Hb(\"rapp/1:rappid\", SPKI_DER)`, the DER `SubjectPublicKeyInfo` [RFC 5280] of the master key.\n  A minter **MUST** refuse octets that are not the DER SPKI of a §10 key (an id-Ed25519 key [RFC 8410], or an\n  id-ecPublicKey prime256v1 key with an uncompressed point); likewise a keyless mint **MUST** refuse 16 octets\n  whose [RFC 9562] version is not 4 or whose variant is not 0b10.\n\nA producer **MUST NOT** derive the tail from owner/slug or any name (`sha256(\"owner/slug\")` is prohibited —\ndrift ID-01/C3). On read of an existing `rappid.json` an implementation **MUST** reuse the stored tail\n(canonicalize-on-read) and **MUST NOT** re-mint — with exactly one mechanism: the owner-authorized\n**re-anchor** (§6.3), which mints a fresh 64-hex tail once per authorization and records the superseded id\nin `_migrated_from`. Re-anchor is lawful in exactly three cases: (a) a 128→256-bit provisional upgrade\n(§6.3); (b) §10 key rotation or compromise; (c) migrating a pre-rev-3 keyed tail minted with the un-tagged\n`sha256(SPKI)` formula (which fails §10 discovery and **MUST** be re-anchored like a provisional identity).\n\n### 6.3 Canonicalization on read; provisional identifiers\n`canonicalize_rappid(s)` restructures any legacy form into §6.1, **preserving the existing hash** (never\ninventing one). A restructured identifier whose tail is not exactly 64 lowercase hex (e.g. a legacy 32-hex\ntail) is **provisional**: it exists only inside the reading process and **MUST NOT** appear in any emitted\nframe, `stream_id`, egg, or registry entry. The one-time owner-authorized 128→256-bit re-anchor mints a\nfresh 64-hex, records the old id in `_migrated_from`, and is the only way a provisional identity becomes\nusable. A provisional identifier found in a stored artifact is a drift finding (Art. III). Re-anchor is the\nsingle re-mint mechanism (§6.2), lawful only in the enumerated cases: provisional 128→256-bit upgrade,\n§10 key rotation/compromise, and pre-rev-3 un-tagged-`sha256(SPKI)` keyed-tail migration.\n\n**A re-anchor is valid only with a verifiable authorization** — a self-asserted `_migrated_from` is\ninsufficient (it would let anyone hijack an identity). A re-anchor **MUST** be recorded as an owner-signed\n§13.3 **re-anchor record** `{old_rappid, new_rappid, case, utc, sig, old_key_sig?}`; a consumer **MUST**\nrefuse a `new_rappid` (and treat `_migrated_from` as drift) unless that record is present and:\n- `case:\"rotation\"` (uncompromised): `old_key_sig` (a §10 JWS by the **old** key) verifies — proof of\n  continuity;\n- `case:\"compromise\"`: `old_key_sig` is waived but a §10 **tombstone** for `old_rappid` is registered in the\n  same append;\n- `case:\"tag-migrate\"` (pre-rev-3 keyed tail): the verifier checks `lowercase_hex(SHA-256(SPKI_DER_old))` ==\n  the old tail;\n- `case:\"upgrade\"` (provisional 128→256): the old provisional id resolved to this owner at read time.\nEach mints one fresh tail. The **estate_owner's own** re-anchor record **MUST** be signed by the outgoing\n`estate_owner` key (§13.2); root-key compromise is recovered only by out-of-band re-anchoring (§13.1).\n\n## 7. The Frame (L4)\n### 7.1 The envelope — exactly eleven keys\n```json\n{\n  \"spec\":         \"rapp/1\",\n  \"kind\":         \"<klabel.klabel>\",\n  \"stream_id\":    \"<stream_id>\",\n  \"seq\":          <uint53>,\n  \"utc\":          \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"payload\":      { },\n  \"payload_hash\": \"<64hex>\",\n  \"frame_hash\":   \"<64hex>\",\n  \"prev\":         \"<64hex|null>\",\n  \"prev_wave\":    \"<64hex|null>\",\n  \"sig\":          \"<jws|null>\"\n}\n```\n- **`spec` MUST be the exact string `\"rapp/1\"`** in every frame. `rapp-frame/2.0`/`2.1` are legacy tokens\n  and **MUST NOT** be emitted. Any revision changing the key set, any field's grammar, or either hash rule\n  **MUST** change this token and land an Art. III total migration; revisions adding only new registered\n  `kind`s/registry entries keep the token (Fed. Const. Art. II).\n- **Exactly these eleven keys, always present**, none missing, none extra. A field that does not apply is\n  present with value `null` (`prev`/`prev_wave` at genesis and on non-swarm streams; `sig` when unsigned) — never omitted,\n  because [RFC 8785] hashes `null` and an absent key differently. Extra or missing keys are refused (§7.5).\n- **`payload` MUST be a JSON object** (possibly empty `{}`); never `null`, array, string, number, or bool.\n- `seq` is `uint53` (§7.4). A producer **MUST NOT** emit a frame whose canonical form exceeds 1 MiB or\n  nesting depth 64 (§4).\n\n### 7.2 Kind families (one envelope, registry-bound families)\n| family | example registered kinds | `stream_id` form | logs |\n|---|---|---|---|\n| `memory` | `memory.chat-turn`, `memory.tool-call`, `memory.save`, `memory.reconstructed` | memory-stream | one organism's life |\n| `swarm`  | `swarm.guidance`, `swarm.echo`, `swarm.telemetry`, `swarm.reconstructed` | swarm-stream | the planetary wire |\n| `body`   | `body.pulse`, `body.twin-pulse`, `body.reconstructed`, `body.re-genesis` | body-stream | an organism's biography |\nEach family also has a `*.re-genesis` kind (`memory.re-genesis`, `swarm.re-genesis`, `body.re-genesis`)\nused only by §12.1. The family is **not** the kind's prefix — it is the §13 registry binding (so\n`body.twin-pulse` is family `body`). Adding a family or event is a new registered `kind` on the **same** envelope (Art. IV), never a\nnew frame type. A frame's `kind` family **MUST** be compatible with its `stream_id` form (table column 3).\n\n### 7.3 Particle and wave (the unification)\nA frame carries **both** of its domain-separated addresses; a reader collapses it to whichever it needs.\nComputed in order:\n- **particle** — `payload_hash = H(\"rapp/1:particle\", payload)`. The **worldline identity and chain link**.\n- **wave** — `frame_hash = H(\"rapp/1:wave\", frame \\ {frame_hash, sig})` — the frame with **exactly** the\n  `frame_hash` and `sig` keys removed, all nine remaining keys (including `payload_hash`) present.\nBecause `payload_hash` is in the wave pre-image, `frame_hash` attests the particle; because only\n`frame_hash` (cannot hash itself) and `sig` (signs the result) are removed, the pre-image is unambiguous\nand non-circular. Both hashes are always present (never `null`).\n\n### 7.4 Chaining, time, and merge order\n- **`utc`** **MUST** be exactly the 24-byte form `YYYY-MM-DDTHH:MM:SS.mmmZ` — every `Y`, `M`, `D`, `H`,\n  `S` and `m` is an ASCII digit (%x30-39; Unicode digits such as U+0660-0669 or U+FF10-FF19 are refused),\n  `YYYY` is any year 0000-9999, uppercase `T`/`Z`, exactly three fractional digits, no numeric offset; the\n  seconds field **MUST NOT** be `60` (a leap second clamps\n  to `59.999`). All `utc` comparisons are **bytewise** over this fixed form (identical to chronological order).\n- **Worldline chain (particle):** the **genesis** frame has `seq`=0 and `prev`=null; every later frame has\n  `seq` = predecessor's `seq`+1 (contiguous) and `prev` = predecessor's `payload_hash`. `seq` is `uint53`: a\n  number token matching `0 / %x31-39 *DIGIT` (no sign, fraction or exponent, so `-0` is refused) whose value\n  is ≤ 2^53−1; a stream nearing 2^53−1 converges by re-genesis.\n- **Wire chain (wave):** `prev_wave` **MUST** be non-null **iff** `stream_id` is a swarm-stream **and**\n  `seq` > 0, in which case it equals the predecessor's `frame_hash`; in every other frame (all memory/body\n  streams, every genesis) it **MUST** be `null`. (Presence is a function of stream family, not transport.)\n- A frame is **immutable**: a new state is a new frame at a new hash; the head pointer (§7.6) re-points.\n- **Cross-stream merge order** (Dream-Catcher) is the total order: ascending `utc` (bytewise), ties broken\n  by ascending `frame_hash` (bytewise); no further ties are possible (§5).\n\n### 7.5 Verification (the complete consumer checklist)\nBefore accepting a frame, a consumer **MUST**, in order, **refuse** (never repair/reparent) on any failure:\n1. **Shape & types:** exactly the eleven §7.1 keys; `spec`==`\"rapp/1\"`; `kind` a string matching §6.1.1\n   ABNF, registered (§13), and bound to a family whose §7.2 column-3 form is the form of `stream_id` (a\n   family outside the §7.2 table fits no form); `stream_id` a string matching §6.1.1; `seq` a `uint53`\n   (§7.4); `utc` matching the\n   §7.4 fixed form **and** a calendar-valid [RFC 3339] `date-time` (so `2026-13-45T25:61:61.999Z` is\n   refused); `payload` a JSON object; `payload_hash`/`frame_hash` `64HEXDIGLC`; `prev`/`prev_wave` each\n   `null` or `64HEXDIGLC`; `sig` `null` or a §10 JWS string: the detached compact form with strict unpadded\n   base64url parts, a protected header whose octets are `canonical(header)` and whose members are exactly\n   the §10 `alg`, `b64`, `crit` and `kid` (a §6.1 rappid) values, and a signature of exactly 64 octets.\n   A number token that passes §4 (c) but is not a `uint53` — `9007199254740992` (2^53), `0.0`, `1e0`, a\n   negative value — leaves the frame a §4 value, so it is refused here, at step 1, never before the\n   checklist; only a token that §4 (c) itself refuses (`9007199254740993`, `1e999`) makes the octets fail\n   before step 1.\n1a. **Stream binding:** `frame.stream_id` **MUST** byte-equal the identifier of the stream being extended\n   or read (its declared `stream_id` at the head pointer / repo path of record). A genesis frame is\n   accepted only for the stream it names. (Defeats cross-stream genesis/segment replay — §14.)\n2. **Particle:** `payload_hash` == `H(\"rapp/1:particle\", payload)`.\n3. **Wave:** `frame_hash` == `H(\"rapp/1:wave\", frame \\ {frame_hash, sig})`.\n4. **Chain:** `seq`==head.`seq`+1 and `prev`==head.`payload_hash` (or `seq`==0 ∧ `prev`==null at genesis);\n   `utc` ≥ head.`utc` (bytewise). With no head, a consumer holding the §13 registry **MUST** refuse a\n   `seq`=0 frame whose `frame_hash` differs from the stream's registered genesis (its sole non-deprecated\n   `genesis` entry) when the registry has one; a registry without a `genesis` entry for the stream does not\n   refuse on this ground. The comparison opens a chain: a later re-genesis resets the head (§7.6) and does\n   not revoke frames already verified.\n5. **Wire:** if `stream_id` is a swarm-stream and `seq`>0, `prev_wave`==head.`frame_hash`; else\n   `prev_wave`==null.\n6. **Signature:** if `sig`≠null, discover the key and verify per §10 (registry key discovery, tail check,\n   key lifecycle, the signature equation; present-but-invalid is refusal); a swarm-stream frame with\n   `sig`==null is refused (§8/§10).\nSteps 1–5 are **time-independent** (kind lookups only append, §13), so a frame passing them passes forever;\nstep 6 alone may flip pass→fail when a §10 tombstone with `revoked_utc` ≤ the frame's `utc` is later\nregistered — the one time-dependent check.\n\n### 7.6 Heads and forks\nA stream's **head** is the frame with the greatest verified `seq` descending from its registered genesis\n(§13). A consumer **MUST** persist, per stream, the highest `(seq, frame_hash)` it verified and **MUST**\nrefuse any presented head with lower `seq`, or a different `frame_hash` at an already-verified `seq` (no\nrollback, no silent reorg). Two distinct valid frames with equal `stream_id`, `seq`, and `prev` are a\n**fork**: a consumer **MUST** refuse both branches past the fork point and surface a drift finding; only\nthe owner resolves a fork (Art. X), by re-genesis (§12.1) if needed.\n\n**Exception (re-genesis head reset).** The no-rollback rule above refuses a lower-`seq` head — but a\nlegitimate §12.1 re-genesis presents a new genesis at `seq`=0. When (and only when) the §13 registry maps a\n`stream_id` to a new genesis `frame_hash` (§12.1 step 3), a consumer **MUST** verify that registered\ngenesis (§7.5) and then **reset** its persisted head for that `stream_id` to it. Only a registry-published\ngenesis authorizes a reset; any other lower-`seq` head remains a refused rollback.\n\n## 8. The Wire (L3)\nAll interaction rides one of exactly two forms:\n1. **Synchronous — `POST /chat`, `application/json` both ways. The Grail is the reference:** an endpoint\n   conforms when it answers every scenario of the Grail conformance suite (`conformance/grail/`) the way\n   the Grail pinned in that suite does — same HTTP status and members, the same `response` and `session_id`\n   values, and for a refusal the same status and members (the `error` text is compared only against the\n   same Grail version).\n   - Request: a JSON object. `user_input` (string, REQUIRED; empty or whitespace-only counts as missing).\n     `conversation_history` (OPTIONAL array; each item an object with `role` one of `\"user\"`, `\"assistant\"`,\n     `\"tool\"` and `content` a string). `session_id` (string, OPTIONAL). Unrecognized members **MUST** be\n     ignored, never refused.\n   - Success: HTTP 200, a JSON object with at least `response` (string), `agent_logs` (string: one line per\n     agent call, newline-separated, empty when no agent ran), and `session_id` (string). An endpoint\n     **MAY** add other members (the Grail adds `model`, `requested_model`, `voice_mode`); a consumer\n     **MUST** ignore members it does not recognize.\n   - Refusal of a malformed request: HTTP 400 with exactly `{\"error\": string}`, a human-readable message.\n     The status and the shape are fixed; the message text is not part of the frozen form (a Grail bug-fix\n     release may reword it).\n   - New capability is a new agent behind `/chat`, never a sibling REST route. `GET /health` is the\n     liveness probe (HTTP 200 JSON object with `status`); it carries no RAPP semantics.\n2. **Asynchronous — an append-only frame (§7) published to a stream** (a repo path, an `events/` log). A\n   frame on a **swarm-stream MUST** carry `sig`≠null (§10); memory/body-stream frames **MAY** be unsigned.\n   Any *history* is safe to read given a trusted head (§14); the hash chain (§5) makes tampering\n   detectable.\n\n## 9. The Egg (L5) — the single egg spec of record\nAn **egg** is a cartridge packing a unit of the estate. **RAPP §9 is the one egg spec of record** (it\nsubsumes and retires `EGG_FAMILY.md`, `NEIGHBORHOOD_EGG_SPEC.md`, `ESTATE_SPEC.md`, `rappterbook/EGG_SPEC.md`,\nand the rest — drift C7). No other document may re-specify eggs; they cite this section.\n\n### 9.1 Container, manifest, and egg address\nAn egg is either a JSON object (`invite`/`session` variants) or a ZIP whose root is `manifest.json` (tree\nvariants). The manifest is a §4 value with exactly these members:\n```json\n{ \"schema\": \"rapp/1-egg\", \"variant\": \"<variant>\", \"rappid\": \"<§6.1 rappid>\",\n  \"created_utc\": \"<§7.4 utc>\", \"contents\": [ {\"path\":\"<rel>\",\"hash\":\"<64hex>\"}, … ], \"payload\": { },\n  \"sig\": \"<jws|null>\" }\n```\n- `contents` **MUST** list every packed file **except `manifest.json` itself**, exactly once each, with\n  `hash = Hb(\"rapp/1:egg\", file_octets)` (§5) over the raw stored octets. `contents` is **always present**;\n  for JSON (pointer/session) variants it **MUST** be exactly `[]`.\n- `path` **MUST** be a relative POSIX path: `/`-separated non-empty NFC UTF-8 segments, no `.`/`..`\n  segment, no leading `/`, no backslash, no Windows drive-qualified first segment (`ALPHA \":\"`), not the\n  root path `manifest.json`, and no two `path` values in one manifest equal as code-point sequences. Paths\n  that differ only in case or normalization, or where one path is a directory prefix of another (`docs`,\n  `docs/a.md`), are distinct and valid; a consumer that extracts to a filesystem where they would collide\n  refuses the extraction, not the egg. A segment **MUST NOT** end in a period/space, contain `:`, contain a\n  C0 control (U+0000-U+001F), or have a basename (the segment up to its first `.`), compared ASCII\n  case-insensitively, equal to `CON`, `PRN`, `AUX`, `NUL`, `COM1`–`COM9`, or `LPT1`–`LPT9`. §9.3's 'no\n  `..`' means no `..` segment.\n  `contents` **MUST** be sorted ascending\n  by the UTF-8 bytes of `path`.\n- `payload` is a §4 object (variant-specific). `sig` is a §10 JWS over `canonical(manifest \\ {sig})`, or\n  `null`. For the `invite` variant `sig` is REQUIRED and **MUST** verify with `kid` in the §13.2 estate-owner\n  succession (invites are estate-issued; a `sig` by any other key, even a validly registered one, is\n  refused — otherwise an attacker mints a fresh rappid and forges invites). For other variants a non-null\n  `sig` **MUST** verify per §10 with `kid` == a keyed rappid the consumer resolves via §13; a consumer\n  presented a signed egg **MUST** verify it.\n- **The egg's one §5 address is** `egg_hash = H(\"rapp/1:egg-manifest\", manifest \\ {sig})` — the manifest with\n  exactly the `sig` key removed (mirroring §7.3's wave rule: `sig` authenticates the egg, `egg_hash` names\n  it, so re-signing never changes identity). Stores key eggs by `(\"rapp/1:egg-manifest\", egg_hash)`.\n  (`\"rapp/1:egg\"` addresses file octets; `\"rapp/1:egg-manifest\"` addresses the egg as a whole.)\n- **Container determinism.** A ZIP variant **MUST** use compression method `stored` (0) for **every** entry\n  — no deflate in any variant (deflate is library-dependent, so it cannot be byte-reproducible; transport\n  compression, if any, wraps the egg and is not the egg). Entries appear in `contents` order with\n  `manifest.json` first; the `manifest.json` entry's octets **MUST** be exactly `canonical(manifest)`.\n  Every local and central header carries: version needed to extract 20 (0x0014); general-purpose flags\n  exactly 0x0800 (UTF-8 filename; no data descriptor, no encryption); DOS time 0x0000 and date 0x0021\n  (`1980-01-01 00:00:00`); no extra field. Every central header also carries version made by 0x0014, no\n  file comment, disk number start 0, internal and external attributes 0. Every field present in both the\n  local and the central header holds the same value in both. The archive is the local records in entry\n  order with no gap, then the central directory, then an end-of-central-directory record with disk numbers\n  0, equal entry counts and no comment; no ZIP64 record, and no octet precedes the first local header or\n  follows the end record. `contents[].hash` is over the file octets (identical to the archive octets under\n  method 0). A JSON-variant egg's serialized form **MUST** be exactly `canonical(manifest)`. A producer\n  **MUST** write exactly these values, so two conformant packers of the same manifest value emit\n  byte-identical eggs. A consumer **MUST** refuse any other violation of this paragraph, but **MUST** accept\n  any value of version made by, version needed (when both headers agree) and the internal and external\n  attributes, and **MUST NOT** interpret them.\n\n### 9.2 Variants (the ratified set — closes EGG-01)\n| variant | container | packs | required members |\n|---|---|---|---|\n| `organism` | ZIP | a full brainstem instance | contents (sorted) MUST include the root paths `rappid.json` and `soul.md`; MAY include `agents/*`, `organs/*`, memory files |\n| `rapplication` | ZIP | one rapp | contents MUST include `rappid.json` and exactly one `agent.py` at the root (the agent of record); MAY include one `ui.html`, files under `state/`, and other files: this MAY list, like the organism row's, is not exhaustive |\n| `session` | JSON | one runtime + transcript | `payload` = `{runtime:<string>, transcript:[<object>]}`; contents `[]` |\n| `invite` | JSON | a QR-sized pointer (**no packed files**) | `payload` = `{target_rappid:<rappid>, target_url:<string>, target_kind:(\"neighborhood\" / \"estate\")}`; contents `[]`; `sig` REQUIRED |\n| `neighborhood` | ZIP | several organisms meant to live together | `payload` = `{members:[<rappid>,…]}`; contents = one sub-egg per member, named `<owner>--<slug>.egg` at the root, matched by the sub-egg manifest's `rappid` == the `payload.members[]` entry |\n| `estate` | ZIP | several neighborhoods | `payload` = `{neighborhoods:[<rappid>,…]}`; contents = one sub-egg per neighborhood, named `<owner>--<slug>.egg` at root, matched by sub-egg `rappid` |\n| `sealed` | ZIP | publicly mirrorable ciphertext with scoped key release | contents MUST be exactly `ciphertext.bin`; payload is the closed `rapp-sealed-artifact/1` profile in §9.2.1; `sig` REQUIRED |\n\nFor `organism` and `rapplication` eggs, `rappid.json` **MUST** be a §4 object whose `rappid` member equals\n`manifest.rappid` (code points) and whose `schema`, when present, is `\"rapp/1\"`; a consumer refuses the egg\nat §9.3 step (2) otherwise (this is the §9.3 no-reparent rule applied to the packed identity).\n`payload.members` (neighborhood) and `payload.neighborhoods` (estate) are arrays of distinct §6.1 rappids,\npossibly empty; an empty list packs no files. \"Several\" describes use, not a minimum.\n\nThe QR-sized invite that caused EGG-01 is the **`invite`** variant: a signed pointer object, not a\nmember-packing `neighborhood` egg. The banned legacy stamps (`brainstem-egg/2.3-neighborhood`,\n`neighborhood-egg/1.0`) migrate to `{schema:\"rapp/1-egg\", variant:\"invite\" / \"neighborhood\"}` (Art. III).\n\n### 9.2.1 Sealed artifact profile\n\nThe `sealed` variant lets any unauthenticated mirror, including a commit-pinned\n`raw.githubusercontent.com` URL, distribute an encrypted artifact globally without distributing its\ndecryption key.\n\nThe public bytes are **ciphertext, not access control**. Bytecode or obfuscation alone provides no\nconfidentiality. A conformant producer **MUST** use a random 256-bit data-encryption key (DEK) per artifact,\n**MUST NOT** embed that DEK or a shared master key in the egg/client/URL, and **MUST NOT** place a password\nin a URL. A password, passkey, device assertion, or account credential may authenticate to the key service;\nit is not the artifact encryption key.\n\nThe ZIP contents are exactly one file:\n\n```text\nciphertext.bin = AES-256-GCM ciphertext || 16-byte authentication tag\n```\n\nThe manifest `payload` has exactly:\n\n```json\n{\n  \"schema\": \"rapp-sealed-artifact/1\",\n  \"cipher\": \"A256GCM\",\n  \"nonce\": \"<12 bytes, unpadded base64url>\",\n  \"plaintext_commitment\": \"<64hex>\",\n  \"plaintext_bytes\": 1234,\n  \"media_type\": \"application/wasm\",\n  \"key_id\": \"<64hex>\",\n  \"key_service_rappid\": \"rappid:@owner/key-service:64hex\",\n  \"key_service_url\": \"https://keys.example.com/chat\",\n  \"access\": \"scoped-key-release\",\n  \"aad_hash\": \"<64hex>\"\n}\n```\n\nIn this template `schema`, `cipher` and `access` are literals that a consumer **MUST** match exactly\n(`access` is always `scoped-key-release`); a `<…>` value is a placeholder of the stated form; the values\nshown for `plaintext_bytes`, `media_type`, `key_service_rappid` and `key_service_url` are examples, and only\nthe member's type is fixed by the template (the rules below still bound each value).\n\n`plaintext_commitment` is a keyed commitment that cannot be tested without the DEK:\n\n```text\nprk = HMAC-SHA-256(32 zero octets, DEK)\ncommitment_key = HMAC-SHA-256(prk, utf8(\"rapp/1:sealed-commitment\") || 0x01)\nplaintext_commitment = lowercase_hex(HMAC-SHA-256(commitment_key, plaintext_octets))\n```\n\nThis is the [RFC 5869] HKDF-Extract/HKDF-Expand construction with an empty salt, one 32-byte output block,\nand the exact info string `rapp/1:sealed-commitment`. The commitment is public but does not permit an\noffline dictionary attack without the random 256-bit DEK.\n\nThe exact authenticated-data descriptor is:\n\n```json\n{\n  \"schema\": \"rapp-sealed-artifact/1\",\n  \"artifact_rappid\": \"<manifest.rappid>\",\n  \"created_utc\": \"<manifest.created_utc>\",\n  \"key_id\": \"<payload.key_id>\",\n  \"plaintext_commitment\": \"<payload.plaintext_commitment>\",\n  \"plaintext_bytes\": 1234,\n  \"media_type\": \"<payload.media_type>\"\n}\n```\n\n`aad_hash = H(\"rapp/1:sealed-aad\", descriptor)`, and `canonical(descriptor)` is supplied as AES-GCM\nadditional authenticated data. `nonce` decodes to exactly 12 bytes. `plaintext_bytes` is an integer from\nzero through `2^30` (1 GiB), a RAPP safety ceiling below both the [NIST SP 800-38D] per-invocation limit\nand the deterministic non-ZIP64 container boundary.\n`ciphertext.bin` length is exactly `plaintext_bytes + 16`. The sealed egg's manifest signature is REQUIRED\nand verifies per §10 with `kid` exactly equal to `manifest.rappid`. A sealed artifact therefore uses a\nkeyed §6.2 rappid controlled by its authorized publisher; another valid registry key cannot sign on its\nbehalf.\n\n`key_service_rappid` identifies the RAPP organism authorizing key release. `key_service_url` is its absolute\nHTTPS §8 `POST /chat` URL and **MUST** end in `/chat`. The URL is location, not authority: the service\nresponse is accepted only when its signatures and identifiers bind to `key_service_rappid`.\n\nThe caller sends the following canonical JSON object as the `user_input` string:\n\n```json\n{\n  \"schema\": \"rapp-sealed-key-request/1\",\n  \"egg_hash\": \"<64hex>\",\n  \"key_id\": \"<64hex>\",\n  \"recipient_rappid\": \"rappid:@owner/device:64hex\",\n  \"recipient_spki_der_b64\": \"<standard base64>\",\n  \"request_nonce\": \"<64hex>\",\n  \"expires_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"sig\": \"<recipient detached JWS>\"\n}\n```\n\n`sig` is over `canonical(request \\ {sig})` and verifies under `recipient_rappid`; `egg_hash` is the §9.1\nsealed egg address. The key service verifies entitlement, exact `(egg_hash,key_id)`, request expiry,\nrecipient key binding, and nonce non-reuse.\n\nThe §8 `response` string is canonical JSON:\n\n```json\n{\n  \"schema\": \"rapp-sealed-key-release/1\",\n  \"egg_hash\": \"<request.egg_hash>\",\n  \"key_id\": \"<request.key_id>\",\n  \"recipient_rappid\": \"<request.recipient_rappid>\",\n  \"request_hash\": \"<H('rapp/1:sealed-key-request', request without sig)>\",\n  \"wrap_alg\": \"ECDH-ES+A256KW\",\n  \"wrapped_key_jwe\": \"<JWE Compact Serialization>\",\n  \"issued_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"expires_utc\": \"YYYY-MM-DDTHH:MM:SS.mmmZ\",\n  \"service_sig\": \"<key-service detached JWS>\"\n}\n```\n\n`service_sig` is over `canonical(release \\ {service_sig})` and verifies under `key_service_rappid`.\n`wrapped_key_jwe` uses [RFC 7516] with `alg:\"ECDH-ES+A256KW\"` and `enc:\"A256GCM\"` for the declared\nrecipient SPKI. The service **MUST NOT** return a global raw DEK. Authorization, expiry, device scope, and\nkey rotation are service policy recorded in signed frames, not fields that alter the sealed egg's content\naddress.\n\nA mirror URL **SHOULD** be immutable (for GitHub Raw, pin a commit SHA rather than a moving branch). URL\nsecrecy is never assumed: integrity comes from the egg address and signature, confidentiality from\nAES-GCM, and use authorization from scoped key release.\n\nRevocation prevents future key release. It cannot erase ciphertext or plaintext already downloaded and\ndecrypted by an authorized recipient. A conformant product **MUST** state this limit plainly. It also\n**MUST NOT** claim that encrypted bytecode cannot be inspected after decryption; legal/license controls and\nbounded server authority remain separate from cryptographic confidentiality.\n\n### 9.3 Conformance\n- **Producer** **MUST** emit only `schema:\"rapp/1-egg\"` with a variant from §9.2, a §6.1 rappid, and, for\n  ZIP variants, a `contents` list whose every hash verifies. Every egg it emits, and every sub-egg it packs\n  into one, **MUST** pass consumer steps (0)-(2) below; a REQUIRED `sig` **MUST** be present and be a §10\n  JWS (a producer without the signer's key context need not verify it). Given input that cannot meet these\n  rules, a producer **MUST** refuse rather than emit or repair. It **MUST NOT** emit any legacy egg schema.\n- **Consumer** **MUST** read every §9.2 variant, dispatch on `variant`, verify **integrity then viability** —\n  (0) the manifest is a §4 value satisfying **every §9.1 rule** — exact member set, `path` grammar (no `..`,\n  no leading `/`, no backslash), no duplicate paths, sort order, and for ZIP variants the archive entry set\n  equals `contents` ∪ {`manifest.json`} in the §9.1 deterministic order (this is the zip-slip defense; an\n  unenforced path grammar defends nothing); (1) every `contents[].hash` recomputes per §5; (2) the variant's\n  §9.2 structural requirements hold — and refuse whole on any failure; it **MUST NOT** reparent on transport.\n\n### 9.4 Instantiation — instance identity and `grown_from` lineage (rev-6; closes the hatch seam)\nAn egg names an **artifact**; a hatch creates an **instance**. Rev-5 specified packing and reading but\nleft instantiation identity unwritten, so every implementation had to invent its own — this section is\nthat missing word.\n\n- The `rappid` in a packed egg's `rappid.json` (§9.2) names the **artifact**. Every hatch of the same\n  egg reads the **same** artifact identity (§6.2 canonicalize-on-read); re-minting it on hatch is\n  prohibited (§6.2).\n- A consumer that instantiates an egg into a live installation **MUST** mint a **fresh §6.2 identity\n  for the instance**, exactly once, at first boot — from entropy, never derived from the artifact\n  identity, host name, or path. Two instances of one egg share the artifact identity and **MUST NOT**\n  share an instance identity.\n- The instance's identity document **SHOULD** record **`grown_from`**: the §9.1 egg address\n  (64 lowercase hex) of the egg it was instantiated from. `grown_from` is written at mint time and is\n  **immutable** thereafter; it is `null` when the source is unknown; a producer **MUST NOT** fabricate\n  it — lineage is a fact about a birth, never a claim to invent. An instance that cannot say where it\n  came from says `null`.\n- `grown_from` is **lineage, not inheritance**: it confers no authority, no trust, and no §10 key\n  material. A reader **MUST** treat it as an unverified assertion unless the named egg is available and\n  its address recomputes per §9.1/§5.\n- A newly authored artifact produced from one or more existing RAPP objects **MAY** record\n  `crossed_from` in its packaged `rappid.json`. The value is a sorted, duplicate-free array of typed\n  addresses `{space, hash}`, where `space` is `\"rapp/1:particle\"` or `\"rapp/1:egg-manifest\"` and `hash`\n  is 64 lowercase hex. One parent denotes an **offspring**; two or more denote a **cross**. The new\n  artifact **MUST** mint its own §6.2 rappid; parent artifacts and identities remain unchanged.\n  `crossed_from` is lineage only: it transfers no signature authority, ownership, entitlement, secret,\n  or trust. A verifier treats each parent as unverified until the addressed object is available and\n  recomputes in its declared space.\n\n## 10. Trust and signatures (L2)\n`sig` is OPTIONAL on memory/body streams and REQUIRED on swarm streams (§8). Chain integrity comes from the\nhash links (§5), not signatures. When present, `sig` **MUST** be JWS Compact Serialization with **detached,\nunencoded payload** ([RFC 7515] App. F + [RFC 7797]):\n- protected header members are **exactly** `alg` (`\"EdDSA\"` or `\"ES256\"`), `b64` (`false`), `crit`\n  (`[\"b64\"]`), `kid` (signer's §6.1 rappid), no others; the header octets **MUST** be `canonical(header)`\n  (§4 — JCS orders them `alg`, `b64`, `crit`, `kid`, no whitespace);\n- the `sig` string is the detached compact form `BASE64URL(canonical(header)) || \"..\" || BASE64URL(signature)`;\n- JWS signing input = `BASE64URL(canonical(header)) || \".\" || canonical(frame \\ {sig})`;\n- `alg`: `EdDSA`/Ed25519 [RFC 8037] or `ES256` [RFC 7518]; Ed25519 verification is [RFC 8032] §5.1.7 with\n  `S < L` required and the cofactorless check `encode([S]B - [k]A) == R`, where `k` is SHA-512(`R` || `A` ||\n  message) read as a little-endian integer and reduced mod `L` (as in [RFC 8032]'s §6 reference code); public\n  keys that decode (including small-order points) are not refused for their order; ES256 signers **SHOULD** sign deterministically\n  [RFC 6979] (Ed25519 is deterministic by construction) so signed frame files stay byte-reproducible.\n\n**Key discovery.** A keyed rappid's tail is one-way (`Hb(\"rapp/1:rappid\",SPKI)`). A verifier resolves the\nsigner's SPKI (DER) **from the §13 registry** entry (`rappid` → `spki_der_b64`); the door-of-record\n`rappid.json` is the publication venue the registry entry is generated from, not itself a verification\nsource. The verifier **MUST** check `Hb(\"rapp/1:rappid\", SPKI_DER)` == the rappid's tail and refuse on\nmismatch or registry absence.\n\n**Key lifecycle.** Rotation is an identity re-anchor (§6.3, case `rotation`) with new `tail =\nHb(\"rapp/1:rappid\", newSPKI)` and a §13.3 re-anchor record. A re-anchor **deprecates** the superseded\nrappid's §13 `spki` entry: a verifier **MUST** refuse a `sig` whose `kid` is a superseded rappid on any\nframe with `utc` ≥ the re-anchor record's `utc` (rotation gives forward security; earlier frames verify as\nbefore). The `deprecated` flag of an `spki` entry does not by itself refuse a `sig`: the entry still\nresolves the key (entries are append-only, §13.3), and a `sig` by it is refused only by the re-anchor rule\nabove or by a tombstone. To stop a key without rotating, the owner registers a tombstone. Compromise is declared by an owner-signed **tombstone** in the §13 registry `{rappid, revoked_utc}`; a verifier **MUST** refuse any `sig` by a\ntombstoned key on a frame whose `utc` ≥ `revoked_utc`, checking tombstones at verification time (§7.5 step\n6). \"Owner-signed\" means a `sig` verifying with `kid` == the registry's designated `estate_owner` rappid\n(§13). A consumer **MUST NOT** infer authorship from an unsigned frame (keyless rappids assert location,\nnot authorship).\n\n## 11. Conformance classes\n- **Producer:** emits only §4 JCS/I-JSON bytes, §5 domain-separated full-SHA-256 addresses, §6 rappids\n  minted per §6.2, §7.1 eleven-key frames, §9 `rapp/1-egg` variants — and **no legacy form**.\n- **Consumer:** runs the full §7.5 checklist (incl. 1a binding), §9.3 egg verification, §10 signature +\n  key-discovery + tombstone checks, canonicalizes legacy ids on read (§6.3), refuses on any failure, never\n  repairs/reparents/rolls back (§7.6).\n- **Router/Mirror:** invents no endpoints (§8), declares subordination to\n  `kody-w/rapp-1` for protocol semantics, and serves only\n  provenance-stamped hash-matching mirrors. Estate-specific product scope is\n  resolved separately through that estate's signed registry and master plan.\n\n### 11.1 Immutable Grail kernel conformance\nAn estate declares a Grail kernel through the exact §13.3 `grail-kernel` entry. Its `release_scope`\nselects the release family to which the pin applies; a registry **MUST** contain at most one\n`grail-kernel` entry for any release scope. Its entry-level `sig`\n**MUST** verify under `declared_by`, which **MUST** be the estate owner in effect at `activated_utc`\n(§13.2); `activated_utc` **MUST NOT** be more than 300 seconds after the verifier's first-seen time for\nthat entry. The pin activates locally when a consumer first accepts an authenticated, non-rollback\nregistry containing that valid declaration. Until then it is structural evidence only. The Grail is\nidentified by `grail_id`, never by a mutable branch, tag, repository name, or product label. Once\nactivated, the pin is a permanent compatibility anchor, not a moving release channel:\n\n1. Every conformance evaluation **MUST** receive `release_scope` from an authenticated owner-controlled\n   release policy, never from candidate bytes or candidate-controlled configuration, then resolve its\n   one `grail_id` exclusively from the activated, persisted §13.3 binding. If the policy repeats\n   `grail_id`, that value is only a consistency assertion and **MUST** byte-equal the registry result; it\n   cannot select or rebind the pin. Every ring and release/deployment stage, including development,\n   qualification, Preprod, installation, and production verification, **MUST** compare the candidate's\n   Grail path to that exact binding, SHA-256, and byte length.\n2. A missing, changed, substituted, or unmeasured Grail byte is `kernel-drift` and **MUST** fail closed.\n   Approval, urgency, compatibility claims, and semantic equivalence cannot waive byte inequality.\n3. A pipeline **MUST NOT** silently restore the pinned file after testing a different file. The exact\n   release-shaped artifact containing the immutable Grail bytes **MUST** itself pass the release gates.\n4. Every gate **MUST** resolve every archive, container, wrapper, environment override, symlink, and\n   filesystem indirection to one regular runtime entry-point file under the immutable release root;\n   refuse links and ambiguous alternatives; verify its bytes; and bind the release digest, resolved\n   entry-point path, `release_scope`, `grail_id`, raw SHA-256, and byte length into its evidence.\n5. Every gate that executes the kernel **MUST** bind verification atomically to execution from a sealed\n   immutable object or snapshot. An already-open descriptor is sufficient only when its backing bytes\n   are under platform-enforced write exclusion for the entire verification-through-consumption interval\n   and the interpreter/loader consumes that exact descriptor without reopening a pathname. An immutable\n   content-addressed release root is sufficient only when no concurrent principal can modify it. A\n   hash-then-path-launch without one of those guarantees is nonconformant. At least one execution gate for\n   every supported production platform **MUST** perform this proof before release approval. Merely\n   carrying an unused matching file is insufficient. A stored transpiled, bundled, generated, or patched\n   derivative is different kernel bytes and requires a new `grail_id`; ordinary interpreter/JIT\n   compilation directly from the pinned bytes is permitted when no alternate stored kernel is selected.\n6. New implementation behavior **MUST** live outside the Grail kernel and **MUST NOT** alter any\n   RAPP-visible canonical form or wire semantic except through the registration and evolution rules of\n   §§7, 9, 12, and 13.\n7. If required behavior cannot be expressed outside the pin, the implementation **MUST** report an\n   incompatibility. It **MUST NOT** edit the Grail and continue under the same identity.\n8. Different kernel bytes produce a different `grail_id` and therefore are a different Grail. A new\n   `grail-kernel` entry may coexist and may name the old `grail_id` as `predecessor`, but it **MUST NOT**\n   overwrite, retag, alias, or redefine the prior Grail. A successor uses a new `release_scope`; an\n   existing scope is never rebound. A non-null `predecessor` **MUST** name an earlier accepted\n   `grail-kernel` entry and **MUST NOT** form a cycle. A registry **MUST** contain at most one\n   `grail-kernel` entry for each `grail_id`.\n9. On first activation a consumer **MUST** persist the full canonical `grail-kernel` entry. Every later\n   accepted registry **MUST** retain that entry byte-for-byte. Removal, mutation, or a second entry for\n   the same `grail_id` is a permanent `kernel-drift` refusal even when `registry_seq` increased.\n\nThis rule governs release topology rather than the §8 wire shape, so it does not add a frame member,\nendpoint, compatibility shim, or alternate `rapp/1` encoding.\n\n### 11.2 Operational conformance profiles\nRAPP/1 defines the substrate. Two subordinate operational profiles define how a production AI changes\nwithout mutating that substrate or the serving system underneath users:\n\n- **RAPP CI/CD** (`rapp-cicd/1`) — `protocols/rapp-cicd/1/SPEC.md`; immutable release capsules,\n  ordered qualification evidence, exact-candidate promotion, Preprod, and rollback/restore proof.\n- **RAPP Deploy** (`rapp-deploy/1`) — `protocols/rapp-deploy/1/SPEC.md`; isolated serving/candidate\n  lineages, cellular rollout, progressive exposure, expiring AI-health evidence, quarantine, and exact\n  rollback.\n\nThe profiles are RAPP/1 applications, not alternate wire versions:\n\n1. Their payloads **MUST** be §4 canonical I-JSON and are identified by\n   `H(\"rapp/1:particle\", payload)`.\n2. Authoritative profile payloads **MUST** travel in signed RAPP/1 frames using a registered compatible\n   kind. Local unsigned files are drafts, fixtures, or caches and cannot authorize promotion or traffic.\n3. They **MUST NOT** add a transport endpoint beside §8 `POST /chat`, redefine any RAPP/1 primitive, or\n   weaken §11.1.\n4. An estate activates a profile through an authenticated §13.3 `protocol` entry pinning its exact\n   repository, path, and SHA-256. A moving branch is discovery, never authority.\n5. A claim of **RAPP production conformance** requires both profiles. Core Producer, Consumer, and\n   Router/Mirror implementations remain conformant without implementing production operations.\n6. Fixed envelope keys carry the safety invariants. Policy-defined check identifiers, component kinds,\n   health objectives, and resilience controls are extension points; adding one does not change the\n   profile token or the RAPP/1 wire.\n7. A consumer **MUST** refuse unknown required policy semantics. It may preserve and relay unknown\n   optional evidence, but may not treat it as satisfying a requirement it does not implement.\n\nThe executable reference validators are `rapp_cicd.py` and `rapp_deploy.py`; controlled profile vectors\nare in `operations_conformance.py`. JSON Schemas define structural shape, while the reference validators\nenforce ordering, identity, temporal, and cross-document rules that JSON Schema cannot express.\n\n## 12. Versioning, evolution, no-legacy\nRAPP is a **living standard** (WHATWG): revised in place, never forked into parallel versions; a `name/X.Y`\nlabel **MUST NOT** ever denote two shapes (Art. II) — a shape change moves the token (§7.1). Published\ncontent-addressed artifacts are **immutable** (SemVer/crates). Within an estate there is **no perpetual\nbackward compatibility** for the estate's own artifacts and retired legacy encodings (Art. III): a change\nto such a form is a **total migration** of every instance + **deletion** of the old form. Sealed re-genesis\nhistory (§12.1) is the retained live-stream exception and is not \"legacy compatibility.\"\n\n**The `rapp/1` wire is frozen (rev-15, Art. 18).** No revision of this standard may change a form a\n`rapp/1` artifact is verified by: canonicalization (§4), the hash function and its tags (§5), the rappid\ngrammar and mint (§6.1, §6.2), the eleven-key envelope and its two addresses (§7.1, §7.3), the consumer\nchecklist (§7.5), the two wire forms and the `/chat` shapes (§8), or the egg container and address (§9.1).\nA change to any of those is not a revision; it moves the token to `rapp/2`, specified beside this\ndocument, and `rapp/1` artifacts keep verifying under this document forever. A consumer **MUST NOT**\nrefuse a `rapp/1` artifact because a later token exists. Everything Art. IV names still grows under\n`rapp/1`: registered kinds, egg variants, error codes, registry entry types, vocabulary, subordinate\nprofiles, and the registry itself. The frozen forms are what a stranger's implementation, written once\nand never updated, relies on; they are the reason an independent implementation can be finished.\n\nImmutable specification-governance history is a separate narrow exception:\nrev-5 through rev-13 anchor frames retain interpretable immutable pointer\npayloads so their ratified normative bytes remain resolvable. They are\nhistorical authority records, not accepted live legacy protocol forms. A\nproducer **MUST NOT** emit the pointer-only revision profile after rev-13.\n\n### 12.1 Re-genesis (converging an immutable chain — one owner-authorized operation)\n1. **Terminal seal:** `seal = Hb(\"rapp/1:seal\", head_octets)`. `head_octets` is the exact octets of the old\n   head's record **as retained under `legacy/`** (step 4): for a one-frame-per-file store, the retired\n   file's full octets; for a line-oriented log, the head's line **excluding** its trailing terminator. The\n   retained `legacy/` artifact is the verification reference for the seal, and retirement **MUST** preserve\n   those octets bit-exact. The step-3 `genesis` registry entry **SHOULD** record the `legacy/` artifact's\n   repo+path so a consumer **MAY** verify the seal against it. (Defined for every legacy shape, including\n   ones that cannot be §7.3-hashed.)\n2. **New genesis:** emit `seq`=0, `prev`=null, `kind` = the registered re-genesis kind **of the stream's\n   family** — `memory.re-genesis`, `swarm.re-genesis`, or `body.re-genesis` (three §13 kinds, used only\n   here) so the frame satisfies §7.2 family↔stream compatibility for any stream — `sig`≠null owner-signed\n   (§10, §13 `estate_owner`), `payload` = `{\"migrated_from\":{\"stream_id\":<old>,\"terminal_seal\":<seal>,\n   \"terminal_seq\":<n>}}` and no other members. A consumer **MUST** treat any `*.re-genesis` kind as the sole\n   re-genesis marker for its family and refuse an unsigned/non-owner one. A consumer **MUST** also refuse,\n   at §7.5 step 1, a `*.re-genesis` frame whose `payload` is not exactly this object: `migrated_from` with\n   exactly `stream_id` (a §6.1.1 stream_id), `terminal_seal` (64HEXDIGLC) and `terminal_seq` (a `uint53`);\n   and, at step 4, one with `seq`≠0 or `prev`≠null.\n3. **Register (the linearization point):** append a §13.3 `genesis` entry mapping the `stream_id` to the new\n   genesis's `frame_hash`, **and flag every prior `genesis` entry for that `stream_id` `deprecated`** — the\n   first convergence included (it deprecates the creation-time genesis), so exactly one non-deprecated entry\n   always remains. A consumer resolves the current genesis **only** via that sole non-deprecated entry. A\n   **concurrent** second registration fails closed (the append is the linearization point, Art. IX); a\n   later fork/brick (§7.6/§14) is a fresh owner-authorized convergence that appends again and re-deprecates.\n4. **Retire:** move old frames under `legacy/` — retained as immutable sealed history, never served as\n   current, never extended, never read as live chain. No live frame may set `prev`/`prev_wave` to a retired\n   hash (a dangling ref is a drift finding).\n5. Keep the old `stream_id` unless the identity itself re-anchored (§6.3), in which case the registry entry\n   also records `old_stream_id → new_stream_id`.\n6. Two frames with equal `stream_id`+`seq` from different eras are disambiguated **solely** by descent from\n   the current registered genesis. Re-genesis is one-time per convergence; a repeat *of the same\n   convergence* is the concurrent case (step 3, fails closed).\n\n### 12.2 DOGG specification revision chain\n\nThe RAPP/1 revision content is the append-only JSONL stream at\n`anchor/chain.jsonl`. The chain's particle, wave, and predecessor hashes prove\nbyte integrity and linear history; they do **not** authenticate who selected a\nhead or ratified an amendment. Until a separately authenticated RAPP\nregistry/checkpoint is ratified, authority is selected by owner-ratified\nacceptance of a chain snapshot onto protected canonical\n`refs/heads/main` at `https://github.com/kody-w/rapp-1`. A consumer starting\nfrom an out-of-band pinned accepted commit and head frame hash has the same\nimmutable selection evidence. An internally valid fork is not authoritative\nmerely because its hashes verify.\n\nEvery protocol adjustment **MUST** append exactly one valid successor frame:\n\n- `spec` remains `\"rapp/1\"`, the envelope remains exactly eleven keys, and the\n  allowed registered anchor kind is `body.pulse`; this profile does not create\n  a new kind or alter canonicalization, hashing, or registered-kind semantics;\n- `stream_id` remains the bootstrap-pinned anchor stream, `seq` is contiguous,\n  `prev` names the predecessor's `payload_hash`, `prev_wave` and `sig` are\n  `null`, and the applicable §7.5 integrity checks hold;\n- the frame's `frame_hash` is the durable protocol-revision identity.\n  Human names such as `rev-14` are lookup labels/views, never identities.\n\n#### 12.2.1 Immutable bootstrap boundary\n\nVerification begins from the frozen `rapp-anchor-bootstrap/1` profile published\nthrough `anchor/bootstrap/index.json`. The index names a\n`anchor/bootstrap/sha256-<raw-profile-sha256>.json` object and pins the exact\nstdlib verifier at `anchor/bootstrap_verify.py` by raw SHA-256 and byte length.\nThe profile fixes the exact-integer JCS subset and limits, particle/wave\ndomains, eleven frame keys, timestamp/sequence/predecessor rules, canonical\nrepository and protected ref, anchor stream ID, genesis frame and payload\nhashes, `body.pulse` anchor profile, null signature/wave fields, and byte/depth\nlimits needed to verify this chain.\n\nThe content-addressed bootstrap profile is immutable. Changing it requires a\nnew bootstrap schema/version and a new external ratification; mutating\n`rapp-anchor-bootstrap/1` in place is refusal. Its initial authenticity is\nnecessarily external — owner-ratified protected canonical main or an\nout-of-band pinned profile hash/immutable commit — because neither a chain nor\ncode fetched with that chain can circularly authenticate its own parser.\n`rapp.py` remains the complete reference implementation and is cross-checked,\nbut it is not the mutable bootstrap trust pin.\n\n#### 12.2.2 Revision payloads and historical exception\n\nFrames through rev-13 retain their immutable legacy pointer fields:\n`canonical_repo`, a full 40-lowercase-hex `commit`, safe relative\n`normative_path`, raw-file `normative_sha256`, and decimal-string\n`normative_bytes`. A resolver **MUST** construct only an immutable\ncommit-pinned GitHub Raw URL from those fields, fetch the bytes, and verify\nlength and raw SHA-256 before use. A branch or tag name in `commit`, an unsafe\npath, malformed UTF-8, a byte-order mark, or a hash/length mismatch is refusal.\nPath validation occurs on the original string before path-library\nnormalization: empty, absolute, `.`/`..`, empty components, repeated slash,\nleading `./`, trailing slash, backslash, percent-encoded ambiguity, or any\nvalue whose reconstructed POSIX form differs is refused.\nThese pointer payloads are immutable governance history under Article 3's\nnarrow exception; they **MUST NOT** be emitted for rev-14 or later.\n\nRev-14 and each successor using this profile carries all normative text inside\nthe chain frame. Its payload **MUST** include\n`schema:\"rapp-spec-revision/1\"`, a unique `revision`, and both\n`previous_revision` and `previous_normative_sha256` matching the immediate\npredecessor. It preserves the useful legacy fields above, carries the\npublication/ratification metadata defined below, and adds exactly this\n`normative` object:\n\n```json\n{\n  \"media_type\": \"text/markdown; charset=utf-8\",\n  \"text\": \"<exact normative SPEC.md Unicode text>\",\n  \"sha256\": \"<lowercase SHA-256 of text encoded as UTF-8>\",\n  \"bytes\": 123\n}\n```\n\n`normative.text` **MUST** encode as UTF-8 without a byte-order mark;\n`normative.sha256` and `normative.bytes` **MUST** match those exact octets and\nthe corresponding legacy `normative_sha256` and `normative_bytes`. The complete\ncanonical frame remains subject to §4's 1 MiB limit. Inline revisions require\nonly the selected, verified chain bytes once fetched; their commit/path fields\nare immutable provenance, not a second source for normative text.\n\nThe payload's `publication` object, repeated in the beacon and revision index,\nrecords: canonical repository `https://github.com/kody-w/rapp-1`; protected ref\n`refs/heads/main`; selection by owner-ratified acceptance; the accepted\ncanonical-main commit as linearization point; prohibition of history\nreplacement; mandatory rebase/regeneration for a competing append; rev-14\nratification under rev-13 Article 14; application of this chain-append process\nfrom rev-15 onward; and `authenticated_registry_checkpoint:null` until one\nactually exists. This metadata **MUST NOT** be interpreted as a signature or\nauthenticated registry.\n\n#### 12.2.3 Content-addressed publication and resolution\n\nEvery chain frame **MUST** also be published, without a trailing line\nterminator, at:\n\n```text\nanchor/frames/<frame_hash>.json\n```\n\nA fetch through mutable main is discovery only. Given frame hash `F`, a\nstranger may fetch\n`https://raw.githubusercontent.com/kody-w/rapp-1/main/anchor/frames/F.json`,\nparse it under the pinned bootstrap, and accept the object only if its computed\nwave equals `F`. For accepted snapshot commit `C`, the immutable URL is\n`https://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/frames/F.json`.\nWrong content at the correct hash-derived path is refusal.\n\n`anchor/index.json` is a deterministic generated index from `seq`, revision\nlabel, frame hash, and payload hash to those objects. It carries no independent\nauthority: a consumer **MUST** verify each selected object and match the index\nand beacon to the fully verified chain. Resolution by frame hash uses the path\nalgorithm directly; resolution by payload hash or sequence uses the verified\nindex; resolution by revision label is a view over it. The fixed pre-profile\nrev-5 pulses share one historical label, so the `rev-5` view resolves to the\ngreatest matching `seq`, while every pulse remains directly resolvable by\nsequence and hashes.\n\nA consumer **MUST** verify the chain from the bootstrap-pinned genesis before\nusing a revision as selected history. It **MUST** refuse an invalid frame shape,\nparticle, wave, or `prev`; a fork or duplicate `seq`; duplicate frame/payload\nhashes; a duplicate profiled revision; an unsupported schema; a legacy\npointer-only frame after rev-13; malformed UTF-8; normative hash/length drift;\nbootstrap/index/object drift; or an object absent from the selected chain.\n\n`orient.json` is only a beacon to the head. Its sequence, frame hash, payload\nhash, bootstrap/index pins, authority-selection metadata, and every retained\nhead mirror — including `registered_kinds`, vocabulary, operational profiles,\nfoundation, philosophy, and Constitution metadata — **MUST** be regenerated\nfrom and match the verified head. While the beacon schema remains\n`rapp/1-anchor`, `spec.normative_path` **MUST** remain as a compatibility alias\nequal to `spec.materialized_path`. `SPEC.md` **MUST** reproduce the selected\nhead byte-for-byte. The Atom feed and mutable main URLs are discovery only.\n\nMaterialization and immutable-pointer caching **MUST** use bounded reads and\nsame-directory atomic replacement without following a symlink in the\ndestination leaf or path. A symlink, unsafe directory component, oversized\ncache entry, content change during read/write, or compare-and-swap mismatch is\nrefusal; the requested leaf is replaced, never the symlink target.\n\nAfter acceptance, let `C` be the full 40-hex canonical-main commit containing\nthe accepted snapshot. The immutable checkpoint URLs are:\n\n```text\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/chain.jsonl\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/orient.json\nhttps://raw.githubusercontent.com/kody-w/rapp-1/C/anchor/index.json\n```\n\nThe authority linearization point is the owner-ratified acceptance of `C` onto\nprotected canonical main, not creation of a local frame, a feed event, or a\nhash alone. A stale competing append **MUST** rebase onto the accepted head and\nregenerate. Force-push or history replacement of accepted authority is\nprohibited.\n\n#### 12.2.4 Rev-14 transition and draft replacement\n\nRev-14 is ratified under rev-13 Article 14. Owner acceptance of the prepared\nchange onto canonical protected main makes the final rev-14 frame effective;\nthe new chain-append process governs rev-15 onward. Before that acceptance,\nrev-14 artifacts are unpublished drafts. A later commit in the same\nowner-ratified change may deterministically replace the one unpublished rev-14\ndraft line/object and update dependent hashes, but **MUST** preserve every\nrev-5 through rev-13 line byte-for-byte and **MUST NOT** represent the replaced\ndraft as accepted history.\n\nThe publication generator **MUST** hold one cross-process exclusive lock across\nread, verification, generation, comparison, and publication. Immediately\nbefore replacing `chain.jsonl` it **MUST** re-read and verify the on-disk head\nand compare the complete expected prefix; a stale writer or changed prefix is\nrefused. Supporting content-addressed artifacts are published first, the\nauthority chain is compare-and-swap replaced next, and the beacon is replaced\nlast, with file and parent-directory synchronization. Because the chain is\nauthority content and the beacon is only a derived view, interruption after a\nvalid chain replacement may leave a stale or missing beacon; the next locked\nrun **MUST** deterministically regenerate it from the verified chain rather\nthan refusing the valid head forever.\n\nThis chain and beacon are unsigned. They provide integrity after authority\nselection, not authorship, and implementations **MUST NOT** fabricate a\nsignature or authenticated registry/checkpoint state for them.\n\n## 13. The registry — an estate's signed root of trust (append-only)\nEach estate selects an owner-controlled `canonical_source` for its\n`schema:\"rapp/1-registry\"` document. The kody-w reference estate may publish\nits registry through `kody-w/RAPP` or another owner-authorized location, but\nthat estate instance cannot alter this protocol. Because §7.6 head resets, §10\nkey discovery, tombstone revocation, and ownership all resolve through the\nselected registry, it is the **root of trust for that estate** and is itself\nauthenticated (an unsigned mutable file at the root of the trust graph would\nforge that estate).\n\n### 13.1 Trust anchor and registry authentication\n- The one bootstrap axiom is the **`estate_owner` rappid string** itself: since a keyed tail is\n  `Hb(\"rapp/1:rappid\", SPKI_DER)`, the rappid **is** a self-certifying key fingerprint, distributed\n  out-of-band exactly once (QR, invite, docs) the way a root-CA certificate is.\n- The registry document **MUST** carry a top-level `registry_seq` (uint53) and a detached §10 JWS `sig` over\n  `canonical(registry \\ {sig})` with `kid` = the `estate_owner` rappid. A consumer **MUST** verify this\n  signature against an SPKI whose `Hb(\"rapp/1:rappid\", SPKI_DER)` equals the anchor rappid's tail (the SPKI\n  may travel alongside the registry — the tail check authenticates it) and **MUST** refuse an unsigned or\n  non-verifying registry.\n- **No rollback:** a consumer persists the highest `registry_seq` it verified and refuses any registry with\n  a lower one (mirrors §7.6). **Freshness:** a consumer **MUST** obtain the registry from `canonical_source`\n  or a provenance-stamped (Art. VIII) mirror of it, **SHOULD** refresh before any §7.5-step-6 or §7.6\n  head-reset decision, and **MUST** report a verification made against a registry older than its staleness\n  policy as *stale*, not *clean*.\n\n### 13.2 Owner succession (time-scoped authority)\n\"Owner-signed\" means: the `sig` verifies per §10 **and** `kid` is the estate-owner **in effect at the\nartifact's `utc`** — the current `estate_owner` or any predecessor reachable through the registry's\nre-anchor records (§13.3), with the artifact's `utc` inside that owner's tenure `[record.utc, successor.utc)`.\nVerification uses the owner in effect at the artifact's time, **never only the current one** (so a routine\nowner key rotation never invalidates historical re-genesis frames or tombstones). Estate-owner **root-key\ncompromise** is recovered only by re-distributing a new trust anchor out-of-band (§13.1) — it cannot be\nexpressed inside the registry it signs.\n\n### 13.3 Entry types (each a §4 value; document `schema:\"rapp/1-registry\"`)\nThe registry is an I-JSON document; every entry is append-only (never removed/renamed; retirement is a\n`deprecated:true` flag). Entry types and their exact members:\n- **protocol** `{type:\"protocol\", name, spec_repo, spec_path, spec_hash, deprecated}` — an estate\n  adoption pin, never a power to redefine a protocol. An entry with `name:\"rapp/1\"` that is used for a\n  current-conformance claim **MUST** set `spec_repo:\"https://github.com/kody-w/rapp-1\"`,\n  `spec_path:\"SPEC.md\"`, and `spec_hash` to a normative SHA-256 published by a verified frame in this\n  repository's anchor chain. A historical RAPP/1 pin may be retained only as `deprecated:true`; it does\n  not override the current anchor. Other protocol entries are subordinate to their own canonical\n  authorities and **MUST NOT** claim the `rapp/1` name or namespace.\n- **kind** `{type:\"kind\", kind, family, deprecated}` (incl. the three `*.re-genesis` kinds). A\n  `deprecated:true` kind entry still registers `kind` and its `family` for §7.5 step 1 (steps 1–5 are\n  time-independent); deprecation only tells producers to stop emitting new frames of that kind.\n- **egg-variant** `{type:\"egg-variant\", variant, deprecated}` · **error-code** `{type:\"error-code\", code}`\n  (both closed namespaces; unregistered value = not conformant)\n- **genesis** `{type:\"genesis\", stream_id, frame_hash, deprecated, old_stream_id?, new_stream_id?}` — **every**\n  stream registers its creation genesis; re-genesis appends a new one and deprecates all prior (§12.1 step 3);\n  §7.6's \"registered genesis\" is the sole non-deprecated `genesis` for a `stream_id`.\n- **spki** `{type:\"spki\", rappid, spki_der_b64, deprecated}` — the §10 key-discovery source.\n- **tombstone** `{type:\"tombstone\", rappid, revoked_utc, sig}`, `sig` owner-signed over `canonical(entry \\ {sig})`.\n- **re-anchor** `{type:\"re-anchor\", old_rappid, new_rappid, case:(\"upgrade\"|\"rotation\"|\"compromise\"|\"tag-migrate\"),\n  utc, sig, old_key_sig?}` — `sig` owner-signed; `old_key_sig` a §10 JWS by the **old** key over\n  `canonical(entry \\ {sig,old_key_sig})`, REQUIRED for `case:\"rotation\"`. This is the normative succession record (§13.2).\n- **grail-kernel** `{type:\"grail-kernel\", release_scope, grail_id, repository, immutable_ref,\n  object_format, commit, path, mode, blob, sha256, size_bytes, activated_utc, predecessor, declared_by,\n  sig}` — exactly these members. `release_scope` is an absolute HTTPS URI selected by the estate owner;\n  no two entries may share it. `grail_id` is\n  `\"grail:\" || Hb(\"rapp/1:grail\", kernel_bytes)`; `repository` is an absolute HTTPS URI;\n  `immutable_ref` is a full `refs/tags/...` name that **MUST** resolve exactly to `commit`;\n  `object_format` is `\"sha1\"` or `\"sha256\"` and fixes the required lowercase hexadecimal length of\n  `commit` and `blob`; `path` at `commit` **MUST** resolve through the repository tree to exactly one\n  regular blob with `mode` `\"100644\"` or `\"100755\"` and object id `blob`;\n  `path` is a relative NFC POSIX path with no empty, `\".\"`, or `\"..\"` component; `sha256` is the raw\n  kernel bytes' 64-lowercase-hex SHA-256; `size_bytes` is their positive `uint53` length;\n  `activated_utc` has the exact §7.4 form; `predecessor` is null or another `grail_id`; `declared_by` is\n  a keyed rappid; and `sig` is a detached §10 JWS whose protected `kid` equals `declared_by`, over\n  `canonical(entry \\ {sig})`. The entry is additionally covered by the registry's §13.1 signature. A\n  consumer verifies the entry signer as the estate owner in effect at `activated_utc`, verifies the\n  referenced bytes, recomputes both hashes, persists the canonical entry on first activation, applies\n  §11.1, and refuses a missing/mutated prior binding, duplicate `grail_id`, or locator whose bytes\n  disagree.\n- **estate_owner** `{type:\"estate_owner\", rappid}` (exactly one non-deprecated) · **master-plan**\n  `{type:\"master-plan\", repo, path}` (Fed. Const. Art. VII).\n\n§7.5 steps 1–5 are time-independent (append-only lookups); **only** step 6 (tombstones) and §13.2 owner\ntenure are time-scoped, and both are monotone given the §13.1 no-rollback rule.\n\n## 14. Security considerations\n- **Integrity:** every object is domain-separated content-addressed (§5); a hostile mirror cannot alter\n  bytes without breaking the hash, so *history is safe given a trusted head*.\n- **Head freshness is not self-certifying:** the chain authenticates history, not which head is current; a\n  hostile mirror may serve a stale/forked head. Consumers counter with the §7.6 monotonic-head rule; swarm\n  heads **SHOULD** be owner-signed.\n- **Cross-stream replay:** without §7.5 step 1a, any genesis/segment of stream A replays as stream B (seq=0,\n  prev=null always pass). Step 1a's stream binding is mandatory.\n- **Address-space confusion:** §5 domain tags make a particle, wave, egg, or rappid tail with equal hex\n  non-interchangeable; stores key by `(space, hash)`.\n- **Canonicalization attacks:** the §4 I-JSON input-domain profile (no duplicate keys, no lone surrogates,\n  exact binary64, no normalization ambiguity) removes hash-splitting and NFC-twin vectors.\n- **Identity forgery / key compromise:** authorship requires a keyed rappid + valid §10 `sig`; rotation is\n  §6.3 re-anchor (verifiable authorization, §6.3/§13.3 — a self-asserted `_migrated_from` is refused);\n  compromise is a §13 tombstone enforced at verify time. Because a tombstone gates on the frame's\n  producer-controlled `utc`, a compromised key can still emit frames stamped just below `revoked_utc`; after\n  a compromise the owner **SHOULD** advance affected stream heads (or re-genesis) past `revoked_utc`.\n- **Root of trust:** the registry is the estate's signed root (§13.1); it is authenticated by an owner\n  signature anchored to the out-of-band `estate_owner` rappid fingerprint, `registry_seq`-monotonic against\n  rollback, and freshness-checked (a stale registry silently un-revokes keys and hides re-geneses).\n- **Producer-controlled `utc` (DoS/merge bias):** a future-dated head can brick a stream (successors refused\n  as earlier) and bias UTC-first merges. A consumer **SHOULD** refuse a frame whose `utc` exceeds receipt\n  time by >300 s, and adversarial-scope merges **SHOULD** rank by `min(utc, first-seen)`; a bricked stream\n  converges by re-genesis (§12.1).\n- **Sealed-artifact limits:** a public mirror sees ciphertext and metadata. AES-GCM protects confidentiality\n  only while the DEK remains secret; a recipient that has lawfully decrypted plaintext can copy it.\n  Revocation stops future wrapped-key release, not prior possession. Shared passwords, embedded master keys,\n  moving-branch URLs, nonce reuse under one DEK, and claims that bytecode cannot be inspected after\n  decryption are non-conformant security postures (§9.2.1).\n- **Kernel substitution:** testing mutable ring bytes and restoring the Grail only after approval creates\n  an untested release. §11.1 requires the release-shaped artifact to contain the pinned bytes before its\n  tests, attestations, and approval; a digest mismatch is a blocking `kernel-drift` finding.\n- **Kernel registry rollback/rebinding:** persisting only `registry_seq` does not preserve an activated\n  Grail declaration across a malicious higher-sequence registry. Consumers also persist every activated\n  canonical `grail-kernel` entry and reject its later removal, mutation, or duplication (§11.1).\n\n## 15. References\n[RFC 2119] [RFC 8174] requirement terms · [RFC 8259] JSON · [RFC 7493] I-JSON · [RFC 8785] JCS ·\n[FIPS 180-4] SHA-256 · [RFC 3986] URI · [RFC 5234] ABNF · [RFC 7405] case-sensitive ABNF · [RFC 9562] UUID\n(obsoletes RFC 4122) · [RFC 5280] X.509 SPKI · [RFC 7515] JWS · [RFC 7797] unencoded JWS payload ·\n[RFC 7518] JWA/ES256 · [RFC 8037] EdDSA in JOSE · [RFC 6979] deterministic ECDSA · [RFC 3339] timestamps ·\n[NIST SP 800-38D] AES-GCM · [RFC 2104] HMAC · [RFC 5869] HKDF · [RFC 7516] JWE · [ECMA-262] ECMAScript ·\n[RFC 8032] EdDSA (Ed25519) · [RFC 8410] Ed25519 keys in X.509 SPKI · [UAX #15] Unicode normalization forms.\n\n---\n\n### Revision log\n- **rev-18 (erratum, §8)** — §8 described a `/chat` shape no implementation served; the Grail, the\n  reference since rev-1, never did. §8 now states the Grail's wire and names the Grail conformance suite\n  as its test. This corrects the text to the form implementations were verified against; it does not move\n  the token (§12). Removed with it: the never-implemented HTTP 422 `{error:{code,step}}` envelope and\n  `idempotency_key`.\n- **rev-17 (the five-implementation erratum: 23 clarifications, no wire change)** — five clean-room\n  implementations (Python, TypeScript, Go, Swift, Rust) built from this text alone, run against a\n  434-vector suite and 20,000 differential fuzz probes, located every place the text let conformant\n  readers split. Each item restates or pins what the frozen forms already require (Art. 18), so no\n  conformant artifact changes verdict: `utc` digits are ASCII and years run 0000–9999 (§7.4, E-1); a\n  §4-valid but non-`uint53` `seq` is refused at §7.5 step 1, and `-0` is not a `uint53` (§7.4, §7.5, E-2,\n  E-9); noncharacters, a byte-order mark and UTF-16/UTF-32 input are outside the §4 domain (E-3, E-4); the\n  producer carries the NFC duty for `payload` member names and refuses unassigned code points (§4, E-5,\n  E-6); the tag table says which function uses each tag (§5, E-7); a minter validates its SPKI and UUIDv4\n  octets (§6.2, E-8); step 1 checks the JWS form and the §7.2 family/stream fit, step 4 the registered\n  genesis when there is no head, and step 6 the key and the equation (§7.5, E-10–E-12); every ZIP header\n  field is pinned, so byte identity holds (§9.1, E-13); path equality is code-point equality (§9.1, E-14);\n  the rapplication MAY list is open, `rappid.json` binds the packed identity, and empty neighborhood and\n  estate lists are valid (§9.2, E-15–E-17); a producer emits only eggs a consumer accepts (§9.3, E-18); the\n  sealed payload template separates literals from examples (§9.2.1, E-19); Ed25519 verification is the\n  cofactorless RFC 8032 check (§10, E-20); a deprecated `spki` flag alone refuses nothing (§10, E-21); the\n  re-genesis payload shape is a consumer check (§12.1, E-22); and a deprecated kind stays registered for\n  step 1 (§13.3, E-23). The reference implementation's deviations from the text are fixed alongside.\n- **rev-15 (the wire freeze)** — §12 freezes every form a `rapp/1` artifact is verified by (§4, §5,\n  §6.1–6.2, §7.1, §7.3, §7.5, §8, §9.1); a change to any of them is `rapp/2` beside this document, never a\n  revision of it, and `rapp/1` artifacts verify forever. Art. III is scoped to an estate's own artifacts.\n  Registration, vocabulary, profiles, and the registry keep growing under `rapp/1` (Art. IV). Constitution\n  Article 18 restates the rule.\n- **rev-14 (DOGG specification-chain authority)** — makes the append-only\n  `anchor/chain.jsonl` frame history carry normative specification content\n  while protected canonical-main acceptance selects authority; defines the\n  frame hash as durable revision identity; embeds the normative Markdown in a\n  normal `body.pulse`; retains immutable rev-5–rev-13 pointer history; freezes\n  a content-addressed bootstrap verifier profile; publishes hash-addressed\n  frame objects and a deterministic index; makes `SPEC.md` a materialized\n  selected-head view; and records the rev-13 Article 14 transition without\n  inventing signatures or changing any RAPP/1 wire primitive.\n- **rev-13 (public governance closure)** — makes the ratified public Protocol\n  Constitution final for protocol governance; limits private governance and\n  master plans to estate/product concerns; makes registry `protocol` entries\n  subordinate adoption pins; verifies the exact canonical RAPP foundation\n  object before anchoring; and aligns every public teaching surface with\n  estate-specific registry authority.\n- **rev-12 (foundation/protocol boundary)** — records `kody-w/RAPP` as the\n  canonical public foundation and product home; limits `kody-w/rapp-1` to\n  protocol authority; ratifies the complete public Protocol Constitution; makes\n  registries explicit estate instances rather than protocol authorities; pins\n  the canonical foundation commit and philosophy hash; and removes any\n  implication that protocol publication transfers product, brand, company, or\n  ownership authority.\n- **rev-11 (planetary operations profiles)** — constitutionalized immutable candidate/serving lineage\n  separation; defined RAPP CI/CD (`rapp-cicd/1`) and RAPP Deploy (`rapp-deploy/1`) as subordinate,\n  registry-pinned production profiles; required exact-candidate qualification, production-shaped\n  Preprod, cellular progressive exposure, expiring AI-health evidence, state/data continuity,\n  automatic containment, and exact rollback while retaining policy-defined extension points; and\n  defined typed, non-authoritative offspring/cross lineage without changing the egg or frame envelopes.\n- **rev-10 (sealed artifact + Grail execution closure)** — registered the `sealed` egg variant for\n  globally mirrorable public ciphertext with signed manifests and scoped recipient key release (§9.2.1);\n  added the `rapp/1:sealed-aad` and `rapp/1:sealed-key-request` address spaces; retained rev-9's exclusive\n  `release_scope` selection, persisted Grail binding, and verification-to-execution protections; and made\n  both confidentiality limits and kernel drift release-blocking.\n- **rev-9 (Grail selection and execution closure)** — makes release policy select only\n  `release_scope`, resolves `grail_id` exclusively through the activated persisted registry binding,\n  and closes verification-to-execution races by requiring a sealed immutable object/snapshot or\n  platform-enforced write exclusion through byte consumption.\n- **rev-8 (immutable Grail closure)** — makes pin selection deterministic through `release_scope`,\n  defines the exact signed §13.3 `grail-kernel` entry and owner-at-time activation, requires consumers\n  to persist every accepted binding, and specifies repository-object and executed-entry-point\n  verification across interpreted and derived runtimes.\n- **rev-7 (immutable Grail constitution)** — defines the Grail kernel by the SHA-256 of its exact bytes\n  (§3), makes every ring and release/deployment stage verify both the pin and the actually executed entry\n  point (§11.1), forbids post-test substitution, and makes changed bytes a different Grail rather than a\n  mutation. This is release governance only; the RAPP wire and existing canonical forms are unchanged.\n- **rev-6 (instantiation lineage)** — added §9.4's fresh per-install instance identity and immutable\n  `grown_from` lineage, closing the hatch seam without changing the frame or egg envelopes.\n- **rev-5 (war-game round 3 fold)** — folded 5 blockers + 7 majors + 7 minors, all clustered on the trust\n  model that rev-4's fixes made load-bearing: the **registry is now a signed root of trust** (§13.1) —\n  owner-signed, anchored to the out-of-band `estate_owner` rappid fingerprint, `registry_seq`-monotonic,\n  freshness-checked (B-1); **re-anchor requires a verifiable §13.3 authorization record** with old-key\n  continuity proof / tombstone / SPKI-tail check (B-2, mint-once now enforceable); **owner-succession is\n  time-scoped** so a key rotation never invalidates historical signatures (B-3); **eggs are `stored`-only**\n  (deflate is non-deterministic) with `canonical(manifest)` bytes (B-4); **invites sign under the\n  estate-owner succession** not the egg's own rappid (B-5); `egg_hash` excludes `sig` (M-1); first\n  re-genesis deprecates the creation genesis (M-2); full **registry entry schema** §13.3 (M-3); registry\n  freshness rule (M-4); egg consumer enforces §9.1 (zip-slip, M-5); rotated key refused on new frames (M-6);\n  `rapplication` exact `agent.py` (M-7); rev label, `invite` naming, sub-egg collision, rounding rule,\n  idempotency, compromise-window, seal-path (m-1…m-7).\n- **rev-4 (war-game round 2 fold)** — folded 6 blockers + 14 majors + 8 minors: domain-tagged mint\n  reconciled across Constitution/ledger (B1); §4(c) binary64 round-trip test so `0.1` is accepted (B2);\n  re-genesis head-reset exception so it isn't refused as rollback (B3); family-matched `*.re-genesis` kinds\n  so memory/swarm streams can converge (B4); whole-egg address `H(\"rapp/1:egg-manifest\",…)` + signed invites\n  + manifest self-reference resolved + deterministic ZIP/`contents` ordering (B5, M2–M4); re-anchor\n  enumerated three cases incl. key rotation (B6, M-rotation); `head_octets` pinned to the retained `legacy/`\n  artifact (M6); subsequent-convergence via `deprecated` (M7); every stream registers its genesis (M8); JWS\n  header canonical bytes + registry key-discovery + `estate_owner` designation (M9–M11); `/chat` error `step`\n  as string incl. `\"1a\"` + code namespace + session semantics (M12, m5); tombstone as the one time-dependent\n  verify check (M13); egg draft-artifact + dangling `§4` reference removed (M1, M5); calendar-valid `utc`,\n  depth convention, kind dedup/bounds (m2, m7, m8).\n- **rev-3 (war-game round 1 fold)** — folded 7 blockers + 19 majors + 12 minors from the Fable adversarial last-call:\n  I-JSON input domain + no-normalization/NFC (§4); **domain-separated hashing** (§5, the stronger option);\n  fixed `utc` byte form (§7.4); `prev_wave` by stream family not transport (§7.4); **stream-binding**\n  anti-replay (§7.5.1a); `spec` token pinned to `rapp/1` (§7.1); full JWS profile + key discovery + rotation/\n  tombstone (§10); hardened re-genesis with raw-byte terminal seal + registry linearization (§12.1); heads &\n  forks (§7.6); `/chat` fully specified (§8); **egg variants ratified into the standard**, killing the\n  6-spec collision and closing EGG-01 (§9); registry append-only (§13); type-validated verify (§7.5.1);\n  cross-stream merge tie-break (§7.4); provisional-identifier rule (§6.3); all references added (§15).\n- **rev-2** — first last-call tightening (7 self-review defects).\n- **rev-1** — initial unified draft.\n\n*The canonical protocol authority is the owner-selected, verified\nspecification chain in this repository. The canonical public RAPP foundation\nand product home remain at `kody-w/RAPP`.*\n", "sha256": "e81e20ba9402ee96422f73e9ef737eba100264155c8f77521600766be8fb21e9", "bytes": 89846}, "publication": {"canonical_repository": "https://github.com/kody-w/rapp-1", "protected_ref": "refs/heads/main", "selection": "owner-ratified acceptance of the chain snapshot onto protected canonical main", "linearization": "the accepted canonical-main commit containing the new frame", "history_replacement": "prohibited", "competing_append": "must rebase onto the accepted head and regenerate", "transition": "rev-14-ratified-under-rev-13-article-14", "chain_append_process": "governs-rev-15-and-later", "authenticated_registry_checkpoint": null}}, "payload_hash": "a4856862f73571853561e8c812be537bb1a04ee6f462b7ffbe01db74bf7c0a66", "prev": "831f1f0d378f0d6e1362f2333e9bd9f5db3066ee4fc2ae65d39d564a5ea57316", "prev_wave": null, "sig": null, "frame_hash": "83bec7762a04959dc91e252055d79f67690c605383018d23b26b99982916dd6a"}
