# Act Schema — Layer 3 Domain Entity Type # KNO Schema Version: 0.1.0 # Status: Draft # Last Updated: 2026-08-04 # # A communicative act: the single entity shape beneath tasks, mail, chat # messages, notifications, and agent feedback (RFC-023 v0.5.0). An act is # a minimal AS2 object (id, actor, audience, body, context) plus an # ordered activity log; everything distinguishing one "kind" of # communication from another rides frame contracts, never subtype schemas. # # STORAGE CLASS (RFC-023 §8.1): act INSTANCES are tenant-stateful # service data in the messaging service's own store — NOT Hive-resident. # This schema (and frame contracts, and the service's Capability # manifest) are the registry-resident, VCS-mandatory layer. An act # promoted into the Hive as a durable knowledge object crosses into # VCS-mandatory territory at promotion time. # # RECORD IDENTITY (RFC-023 §9.1, council ruling forge #3370): an accepted # act revision's assertion identity is its record digest — # `sha256:` over `FRAME = PAE(UTF8(payload_type), canonical_bytes)` where # canonical_bytes are the act's KCF v1 canonical form (kno data model → # I-JSON → JCS/RFC 8785). One digest per revision; it is simultaneously # the revision identity, the RFC-013 layer-2 content hash, and the exact # bytes signatures sign. Bodies live OUTSIDE the signed scope, # referenced by digest (`body_ref`). # # ============================================================================= # THREE-GATE + FIVE-TEST RECORD (bedrock-audit AC, forge #3376) # ============================================================================= # Per kno-foundational-principles § 0.6 (Three-Gate) and § P13-in-DC-2 # (Five-Test Sibling-vs-Extend), recorded BEFORE implementation against # ALL THREE nearest neighbors, ≥2 discriminators each. # # --- Three-Gate (is a new schema needed at all?) --- # Gate 1 (Distinctness): PASS. An act is an addressed, consumable, # chain-positioned communication with an acceptance lifecycle # (audience + consumption state + hop graph + record digest). No # existing schema carries addressed-audience or consumption # semantics: documents are un-addressed narrative knowledge; notices # are broadcast signals scoped by applies_to (no per-audience # consumption); activities describe actions ABOUT things, they are # not themselves addressed communications. # Gate 2 (Reusability): PASS. Three driving consumers at introduction: # agent-feedback acts (J1), the knowledge-gap chain (J2), and the GCN # builder↔validator exchange (RFC-023 §10.1) — with tasks, mail # projections, and notices-migration behind them (sweep catalog: ~90 # messaging-shaped needs). # Gate 3 (Clarity): PASS. One act schema + frame contracts REPLACES the # alternative of N per-kind schemas (task, message, notification, # feedback...) — this schema is the DC-2 minimization move, ending # the four-independent-notification-stacks divergence the sweep # cataloged. # # --- Five-Test vs document-schema (extend candidate: notices extend it) --- # 1. Field overlap: ~20% (id/slug/type/version + quality tier only — # no actor/audience/body_ref/chain/consumption in documents). SIBLING. # 2. Lifecycle: DIVERGENT — acts have an acceptance pipeline # (classify→…→append→prove) + consumption states (Deliver/Ack); # documents have edit/review/publish. # 3. Validation: DIVERGENT — acts fail-shut at the KCF parse boundary # with closed-profile authority fields; documents validate # narrative structure. # 4. Display: DIVERGENT — acts render through frame contracts # (inbox/thread/task); documents render as prose pages. # 5. Resolver: DIVERGENT — acts resolve through the messaging # service's log + lane projections; documents resolve through # Hive/content collections. # Score: 0/5 → SIBLING. (≥2 discriminators: lifecycle, validation, # display, resolver.) # # --- Five-Test vs notice-schema (#1952 family) --- # 1. Field overlap: ~30% (identity tier + severity-adjacent metadata; # no audience/actor/chain/consumption in notices; no # applies_to/affected_by backlink pair in acts). SIBLING. # 2. Lifecycle: DIVERGENT — notice: scheduled→active→resolved # (broadcast window); act: proposed→accepted→delivered→acked per # audience (consumption lifecycle, R3–R5). # 3. Validation: DIVERGENT — notices validate the bidirectional # applies_to backlink (CI lint); acts validate through the # acceptance pipeline (secret-scan, canonicalize, frame/digest). # 4. Display: PARTIAL overlap — both project to feeds/status # surfaces; but notices are un-addressed broadcast render, acts # are audience-scoped frame render. # 5. Resolver: DIVERGENT — notices are Hive/content entities on the # public four-surface; act instances are service-store data, # private, lane-projected. # Score: ≤1/5 → SIBLING. (≥2 discriminators: lifecycle, validation, # resolver.) # MIGRATION NOTE (sweep D7): once the act core is proven, the notice # entity becomes a candidate FRAME over acts (broadcast addressing # regime + scheduled lifecycle) — a projection consolidation, not a # schema merge; tracked estate-side, not in M0. # # --- Five-Test vs activity-schema (AS2 vocabulary sibling) --- # 1. Field overlap: ~40% (AS2 core: type/actor/object/published) — # highest of the three, which is BY DESIGN: pspace-activity's AS2 # vocabulary is adopted as the wire/record shape (service-shape # ruling). Still short of the >50% extend threshold. # 2. Lifecycle: DIVERGENT — an activity is an immutable occurrence # (it happened; no lifecycle); an act is an addressed assertion # WITH a lifecycle driven BY activities. The council's duality # ruling (§9.2) makes this distinction normative: "a record # revision is an immutable assertion; an activity is an immutable # occurrence about one or more exact record revisions." # 3. Validation: DIVERGENT — activities validate verb vocabulary + # actor anchoring; acts validate the full acceptance pipeline # including canonical-form fail-shut and secret-scan. # 4. Display: DIVERGENT — activities render as feed/audit entries; # acts render as the communication itself through frames. # 5. Resolver: DIVERGENT — activities live in pspace-activity's # store (and the act's own log records its lifecycle activities — # same VOCABULARY, separate STORES, no shared tables per the # service-shape ruling); acts resolve via the messaging service. # Score: 1/5 → SIBLING. (≥2 discriminators: lifecycle/duality, # validation, resolver.) # # EXTENDS: nothing (sibling Layer 3 entity; composes Layer 1 primitives) # EMBRACE-AND-EXTEND: W3C Activity Streams 2.0 — an act's wire form is a # valid AS2 Object; its lifecycle events are valid AS2 Activities # (embrace); frame contracts, chain provenance, record digests, and # the consumption lifecycle are the extensions (extend). See # open-standards-stewardship.instructions.md. # # ============================================================================= # KU1 DECISION — M0 BODY CLASS (futro, forge #3376) # ============================================================================= # M0 defines ONE body class: `internal` — platform-realm acts whose # bodies are stored plaintext in the service's body store, digested as # exact bytes (plaintext body digest). # # Rationale: the council's prohibition on plaintext-derived digests # applies to PRIVATE-class content (R-OBS-4: "plaintext-derived digests # of private content are prohibited anywhere durable"). M0's consumers # are platform-realm agent/operator communications (J1 feedback, J2 # knowledge-gap, GCN turns) — reference-grade working data within one # trust domain, not tenant-private communications. Declaring `internal` # as the only M0 class means: # - PBEP v1 + external review TRAILS behind its structural gate: the # `private` class does not exist until PBEP ships (council triage # note: claims-guarding items may trail). # - No private-class claims are made anywhere (honest posture). # - The body_ref carries `class: internal` so the private class is # additive later — no schema break, no re-pour. # Telemetry remains content-free regardless of class (R-OBS-1..3 bind # at the service layer, not per-class). # # ============================================================================= # @kno:manifest # ============================================================================= $schema: kno@0.0.9 id: 01KZ6RTSCZ2PN383SY5YVXY5DK slug: act-schema type: spec version: 0.1.1 title: "Act Schema" purpose: | Define the schema for communicative acts — the single entity shape beneath tasks, mail, chat messages, notifications, and agent feedback (RFC-023 v0.5.0 §2). An act is a minimal AS2 object plus an ordered activity log; addressing regime, lifecycle contract, and consistency class ride frame contracts. **Instance storage:** act instances are tenant-stateful data in the messaging service's own store (single write path, append-only Merkle log per realm) — `.kno`-projectable on demand per RFC-023 §2.1, not Hive-resident. This schema is the registry-resident contract those instances validate against. **Naming:** "act" is the schema noun (provisional window per RFC-023 §12); the service is `pspace-messaging`; product surfaces say what the frame renders (inbox, thread, task, notification). status: draft created: "2026-08-04" authors: - "Possibility Contributors" # ============================================================================= # PROVENANCE # ============================================================================= provenance: origin: id: 01KZ6RTSCZ2PN383SY5YVXY5DK timestamp: "2026-08-04T09:30:00Z" emerged_from: - kno://content/rfcs/023-communicative-acts - kno://research/council-research/2026-08-03-communicative-acts-record-layer - kno://research/2026_08_02-messaging-convergence-sweep/04-cross-session-feedback-use-case tool: ai-assisted-authoring issue: "forge#3376" # ============================================================================= # CLASSIFICATION # ============================================================================= taxonomy: topics: - communicative-acts - messaging - activity-streams - chain-provenance - record-layer keywords: - act - lane - frame - chain - audience - ack - digest relationships: conforms_to: - xri: "kno://specs/kno-spec" reason: "RFC-001 defines kno@0.0.9 schema" depends_on: - xri: "pspace://rfc:rfc-023-communicative-acts" reason: "The design contract — act core §2, chains §4, consumption §5.1, record layer §9" - xri: "pspace://rfc:rfc-013-identity-separation" reason: "id is a ULID; actor/audience/refs are XRIs; wire refs carry {id, digest} pairs" - xri: "kno://specs/activity-schema" reason: "AS2 vocabulary adopted as the wire/record shape for the act's lifecycle activities (shared vocabulary, separate stores)" related_to: - xri: "kno://specs/notice-schema" reason: "Nearest broadcast sibling; five-test 1/5 (see header); future frame-over-acts migration candidate (sweep D7)" - xri: "kno://specs/document-schema" reason: "Five-test 0/5 sibling (see header); acts promoted to Hive become document-class knowledge objects" composes: - xri: "kno://specs/identity-schema" reason: "Layer 1: id, slug" - xri: "kno://specs/kaml-spec" reason: "Body content may use KAML markup (body bytes are outside the signed scope; KAML hashes as exact bytes)" # ============================================================================= # VISIBILITY DECLARATION (REQ-18 / RFC-023 §2.2) # ============================================================================= # THIS SCHEMA (and frame contracts, adapter manifests): visibility public # — reference knowledge on the four-surface contract. # ACT INSTANCES: visibility private — tenant-stateful per-audience # communicative data; the consent-scoped audience field is the access # model; never projected to llms.txt/aggregate-corpus surfaces. # MANAGEMENT APIs: three-surface contract (REST + MCP + A2A, no llms.txt). visibility: public # ============================================================================= # QUALITY # ============================================================================= quality: completeness: 0.6 review_status: draft # ============================================================================= # HISTORY # ============================================================================= _history: retention: full format: snapshot versions: - version: "0.1.1" date: "2026-09-09" author: "Possibility Contributors" summary: "actor description: the identity XRI of any entity that acts; user and agent are the admitted classes today, every other type segment reserved for actors-as-data (M87 #3969); the read floor fails closed for unrecognized classes (#4327 C1 amendment 3, operator-ratified 2026-09-09). Description-only — no field, type or signed-scope change." - version: "0.1.0" date: "2026-08-04" author: "Possibility Contributors" summary: "Initial draft — act core fields per RFC-023 v0.5.0 §2 + §9; Three-Gate/Five-Test record vs all three neighbors in header; KU1 body-class decision (internal-only at M0, private class PBEP-gated)" # ============================================================================= # FIELDS — the act record (the canonicalized, framed, digested payload) # ============================================================================= # The act record is what KCF v1 canonicalizes and the FRAME digest # identifies. Fields marked [signed] are inside the canonical payload; # fields marked [service] are service-maintained record metadata OUTSIDE # the signed scope (rebuildable, unsigned). fields: # --------------------------------------------------------------------------- # IDENTITY [signed] # --------------------------------------------------------------------------- id: type: string format: ulid required: true description: | ULID of this act (immutable birth identity, RFC-013 layer 1). Identity XRI: `pspace://act/`. The revision identity is the record digest (layer 2), not this field. type: type: string enum: [ act ] required: true description: "Top-level kind discriminator" payload_type: type: string required: true pattern: "^pspace://schemas/act-schema/[0-9]+\\.[0-9]+$" description: | Byte-exact registry-pinned schema identifier including version — the DSSE payload_type in FRAME = PAE(UTF8(payload_type), canonical_bytes). No aliases, no generic media types (council N1.3). Example: `pspace://schemas/act-schema/0.1`. schema_hash: type: string pattern: "^sha256:[0-9a-f]{64}$" required: true description: | Content hash of the exact schema version entity this record validates against (council Position 3: every record pins (registry id, version, schema content hash) inside its canonical payload; version entities are immutable). # --------------------------------------------------------------------------- # THE AS2 CORE (RFC-023 §2) [signed] # --------------------------------------------------------------------------- actor: type: string format: xri required: true description: | Persona-attributed author: the identity XRI of the entity that acts (`pspace:///`, §0.7 — the birth ULID, never a name or slug; names are not in verification paths, council Position 2). Classes the platform admits today: `pspace://user/` (platform admins) and `pspace://agent/` (agent entities — a component or an estate that acts is an agent entity whose `ownership` block names whom it acts for; #4327 C1, ratified 2026-09-09). Every other type segment is RESERVED for actors-as-data (M87 #3969): no new actor class is admitted by URI scheme before that work binds tokens to entity XRIs of any type, and the read floor treats any class it does not recognize as non-user (fails closed). audience: type: array required: true min_items: 1 description: | Addressed parties (`to`-semantics); consent-scoped; never a firehose assumption. Members are personas OR lanes (RFC-023 §2.3 — a lane is a work locus keyed by repo + branch, first-class addressable, use-case R1). Private addressing (bto/bcc-class) is envelope-only and MUST NOT appear in this signed field (council Position 4). items: type: object required_fields: - type example: | - type: persona xri: "pspace://agent/01J..." - type: lane lane: "possibility-space@feat/x" body_ref: type: object required: true description: | Content-addressed reference to the body — the body's bytes live OUTSIDE the signed scope in the service's body store (council body-placement ruling; enables erasure without breaking chains, content-free observability, and the anti-channel rule). KAML bodies hash as exact bytes. required_fields: - class - digest - media_type optional_fields: - size_bucket example: | class: internal # M0's only class (KU1); `private` is PBEP-gated, additive digest: "sha256:..." # exact-bytes digest (internal class) media_type: text/markdown size_bucket: small context: type: object required: true description: | Graph edges: `inReplyTo`, chain reference, dependency edges, frame references, structured refs (use-case R6 — refs get structure, body stays prose), and sender provenance (R2). Every act reference in the signed scope carries `{id, digest}` — the verifier recomputes digests; declared digests are never trusted (council Position 2). optional_fields: - inReplyTo # { id, digest } - chain # { id } or { new: true } - refs # [ { type, ref } ] - sender_provenance # { lane, cwd } frame: type: string required: true description: | Frame-contract reference governing view schema, verb set, addressing regime, and consistency class (RFC-023 §3). M0 ships exactly one instance: `message`. The frame MECHANISM is the contract; new kinds of communication are new frames, never new act schemas. published: type: string format: date-time required: true description: "ISO-8601 UTC timestamp of authoring (AS2 published)" # --------------------------------------------------------------------------- # SERVICE RECORD METADATA [service — outside the signed scope] # --------------------------------------------------------------------------- # Maintained by the messaging service per the council pour floor # (§2.6); rebuildable, unsigned, never inside canonical_bytes: # - record digest (sha256: over FRAME; computed at acceptance) # - stored canonical bytes (authoritative; DSSE verified-bytes rule) # - log position + leaf hash (LCP v1; from the first write) # - chain_id + hop position (chain provenance, G9) # - tenant scope # - detached signatures with hint-only sidecars # - lifecycle activities (Deliver / Ack / Route / ... — themselves # canonicalized, framed, digested occurrences per §9.2)