# Activity Schema — Layer 3 Domain Type # This file defines the schema for activity records. # An activity is a semantic description of an action — past, present, or future. # # Version: 0.5.0 # Status: Draft # Last Updated: 2026-04-23 # # CHANGELOG: # - 0.5.0 (2026-04-23): Added 7 admin activity types from Phase 3.3 (#1579): # PossibilityAuthProvisioned, PossibilityAuthDeprovisioned, # PossibilityAuthUpdated, PossibilityAuthSecretRotated, # PossibilityAssetUploaded, PossibilityStyleGuideBootstrapped, # ProvisioningFailureResolved. All admin-initiated; user-anchored per # FP §0.7.1 (admin-on-behalf-of, not persona-anchored). # DC-2 (Minimalism) rationale: 7 narrow types were chosen over a single # discriminated `PossibilityAdminAction` with `context.subaction` because # (a) consumers (audit dashboards, AS2 inboxes, downstream A2A bridges) # can filter by `type` directly without parsing `context`, and # (b) cardinality-7 is below the "too many to remember" threshold while # preserving the canonical AS2 verbs (Create/Update/Delete) as base types # each `pspace:Possibility*` activity extends. Future admin endpoints # should reuse these 7 types via `context.action` discrimination rather # than expanding the vocabulary further. # - 0.4.0 (2026-04-23): Added 3 cross-realm collaboration activity types from # Possibility Collaboration v2 X2.1 (#1720, DD-COL2-09): EstablishRelationship, # DispatchHelperEnvoy, MeterResourceGrant. These are the only verbs v2 needs # beyond existing AS2 vocabulary; all other v2 events (relationship # propose/accept/decline/revoke, grant offer/accept/revoke, A2A # request/honor/deny/reconcile) reuse Offer/Accept/Reject/Undo/Activity per # the DD-COL2-09 mapping table. # - 0.3.0 (2026-04-23): Added 11 domain-lifecycle activity types from Phase 3.2 (#1578): # TestEmailSent, EmailDomainConfigured, EmailDomainRemoved, # EmailDomainVerifyTriggered, EmailDomainVerified, EmailDnsRecordCreated, # CustomDomainConfigured, CustomDomainRemoved, CustomDomainVerified, # CustomDomainFailed, CustomDomainDnsRecordCreated. # # EMBRACE-AND-EXTEND: This schema extends W3C Activity Streams 2.0 (AS2). # All Possibility activities are valid AS2 documents with Possibility-specific extensions. # https://www.w3.org/TR/activitystreams-core/ # # KEY RELATIONSHIP: Activities are PRODUCED BY workflows. # When a workflow executes, each step generates one or more activity records. # ============================================================================= # @kno:manifest # ============================================================================= $schema: kno@0.0.9 id: 01KGK3V73G5X99QDZWKDEEWEE1 slug: activity-schema type: spec version: 0.4.0 title: "Activity Schema" purpose: | Define the schema for activity records — semantic descriptions of actions following W3C Activity Streams 2.0 with Possibility extensions. **AS2 Compliance:** All Possibility activities are valid AS2 documents: ```yaml "@context": - "https://www.w3.org/ns/activitystreams" - "https://possibility.space/ns/pspace" ``` **Possibility Extensions:** - `pspace:persona` — Which persona context the actor used - `pspace:onBehalfOf` — Acting on behalf of an organization - `pspace:federationContext` — Cross-org activity metadata - `pspace:consentRef` — Link to consent record - `pspace:auditMetadata` — Audit trail (IP, user agent, request ID) - `workflow` — Correlation to originating workflow # ============================================================================= # @kno:taxonomy # ============================================================================= taxonomy: topics: - activities - events - audit-trails - observability - federation keywords: - activity - actor - object - W3C - AS2 - JSON-LD - audit # ============================================================================= # @kno:relationships # ============================================================================= # ============================================================================= # RICH TIER (provenance) # ============================================================================= provenance: origin: id: 01KGK3V73G5X99QDZWKDEEWEE1 timestamp: "2026-02-04T01:47:56Z" tool: manual-migration relationships: extends: - xri: "kno://specs/document-schema" reason: "Layer 2 base type for all documents" - url: "https://www.w3.org/ns/activitystreams" reason: "W3C Activity Streams 2.0 (embrace-and-extend)" depends_on: - xri: "kno://specs/kno-spec" reason: "Conforms to KNO format specification" composes: - xri: "kno://specs/identity-schema" reason: "Layer 1: id, canonical_id, local_ids" - xri: "kno://specs/history-schema" reason: "Layer 1: _history, changelog" - xri: "kno://specs/quality-schema" reason: "Layer 1: quality, validation" produced_by: - xri: "kno://specs/workflow-schema" reason: "Workflows produce activity records when executed" related_to: - xri: "kno://specs/user-schema" reason: "Users are common actors" - xri: "kno://specs/organization-schema" reason: "Organizations can be actors or targets" - xri: "kno://specs/otel-spec" reason: "Activities link to OTel traces via trace_id (cross-system bridge)" - xri: "kno://services/pspace-activity" reason: "Activity logging service stores these" # ============================================================================= # @kno:quality # ============================================================================= quality: completeness: 0.85 last_reviewed: "2026-01-27" review_status: draft reviewed_by: "claude" # ============================================================================= # @kno:history # ============================================================================= _history: version: 1 created: "2026-01-27T12:00:00Z" created_by: "claude" modified: "2026-01-27T12:00:00Z" modified_by: "claude" # ============================================================================= # @kno:index # Navigation index for agent-optimized retrieval # ============================================================================= _index: - path: "overview" line: 140 keywords: [activity, AS2, W3C, embrace-extend] - path: "as2-core" line: 220 keywords: [actor, object, target, AS2, types] - path: "pspace-extensions" line: 320 keywords: [persona, federation, consent, audit] - path: "schema" line: 400 keywords: [fields, required, properties] - path: "activity-types" line: 500 keywords: [Create, Update, Import, pspace] - path: "examples" line: 600 keywords: [simple, extended, import] # ============================================================================= # @kno:contains # What this container holds (discovery manifest) # ============================================================================= contains: - xri: "#overview" role: section title: "Overview" keywords: [activity, AS2, produces] - xri: "#as2-core" role: section title: "AS2 Core Model" keywords: [actor, object, W3C] - xri: "#pspace-extensions" role: section title: "Possibility Extensions" keywords: [persona, federation] - xri: "#schema" role: section title: "Schema Definition" keywords: [fields, validation] - xri: "#activity-types" role: section title: "Activity Types" keywords: [AS2, pspace, types] - xri: "#examples" role: section title: "Examples" keywords: [usage, code] # ============================================================================= # NESTED CONTENT # ============================================================================= _contains: # =========================================================================== # @kno:overview # =========================================================================== overview: $schema: kno-section@0.0.1 id: overview title: "Overview" content: definition: | An **activity** is a semantic description of an action. The W3C Activity Streams 2.0 (AS2) specification defines the core model: - **Actor**: Who performed the action - **Object**: What was acted upon - **Target**: Where the action was directed - **Result**: What the action produced embrace_and_extend: | Possibility activities are 100% AS2-compliant. Any AS2 consumer can parse them. Possibility extensions are namespaced with `pspace:` to avoid conflicts: "@context": - "https://www.w3.org/ns/activitystreams" # Standard AS2 - "https://possibility.space/ns/pspace" # Possibility extensions produced_by_relationship: | Activities are PRODUCED BY workflows. This semantic link enables workflow correlation and audit trails: ┌──────────────────────┐ ┌──────────────────────┐ │ workflow-schema.kno │─────────│ activity-schema.kno │ │ (Layer 3) │ produces│ (Layer 3) │ └──────────────────────┘ └──────────────────────┘ workflow_correlation: | Activities reference their originating workflow: workflow: id: "user-invite" # Workflow definition ID instanceId: "wf-abc123" # Unique execution instance step: "generate-code" # Step that produced this # =========================================================================== # @kno:as2-core # =========================================================================== as2-core: $schema: kno-section@0.0.1 id: as2-core title: "AS2 Core Model" content: description: | W3C Activity Streams 2.0 defines these core types. activity_types: - type: Create description: "Creating a new object" - type: Update description: "Modifying an existing object" - type: Delete description: "Removing an object" - type: Add description: "Adding to a collection" - type: Remove description: "Removing from a collection" - type: Follow description: "Following another actor" - type: Like description: "Liking an object" - type: Announce description: "Sharing/boosting an object" - type: Accept description: "Accepting something" - type: Reject description: "Rejecting something" - type: Undo description: "Reversing a previous activity" - type: Decide description: | Recording a decision (the "WHAT" event corresponding to a decision .kno entity, the "WHY"). Emitted by recordDecision() in pspace-api. The activity's object.xri points to the decision entity. Added in M22-P2 F2 (#850). actor_types: - type: Person description: "A human user" - type: Organization description: "An organization entity" - type: Application description: "User-facing software" - type: Service description: "A deployed service" - type: Group description: "A group of actors" # =========================================================================== # @kno:pspace-extensions # =========================================================================== pspace-extensions: $schema: kno-section@0.0.1 id: pspace-extensions title: "Possibility Extensions" content: description: | Possibility extends AS2 with these namespaced properties. actor_extension: - type: System description: | Automated system component (scanner, scheduler). Distinguished from Service (deployed application) and Application (user-facing software). examples: - "pspace-api:stale-scanner" - "pspace-api:graceful-shutdown" properties: - name: "pspace:persona" type: object description: "Persona context for the activity" properties: id: type: string name: type: string representing_org: type: string - name: "pspace:onBehalfOf" type: object description: "Organization actor is acting for" properties: id: type: string name: type: string - name: "pspace:federationContext" type: object description: "Cross-org activity metadata" properties: source_node: type: string target_nodes: type: array federation_id: type: string - name: "pspace:consentRef" type: object description: "Consent record reference" properties: consent_id: type: string purpose: type: string granted_at: type: string - name: "pspace:auditMetadata" type: object description: "Audit trail and observability metadata" properties: trace_id: type: string description: "OTel trace ID linking this activity to its execution trace" format: "32-character lowercase hex (W3C Trace Context)" notes: | Cross-system semantic bridge: links the semantic activity record (stored in PostgreSQL) to the execution trace (stored in ClickHouse/SigNoz). Enables "show me what happened" (activity) → "show me how it happened" (trace) navigation. Extracted via @opentelemetry/api: trace.getActiveSpan()?.spanContext().traceId ip_address: type: string description: "Client IP address from request headers" user_agent: type: string description: "Client user agent string" session_id: type: string description: "Authentication session ID" request_id: type: string description: "Unique request correlation ID (UUID v4)" # =========================================================================== # @kno:schema # =========================================================================== schema: $schema: kno-section@0.0.1 id: schema title: "Schema Definition" content: required_fields: - "@context" - type - actor properties: "@context": oneOf: - type: string const: "https://www.w3.org/ns/activitystreams" - type: array items: type: string description: "JSON-LD context (AS2 + Possibility extensions)" id: type: string format: uri description: "Globally unique identifier (IRI)" type: oneOf: - type: string - type: array description: "Activity type (AS2 or Possibility extension)" actor: oneOf: - type: string - type: object description: "Entity performing the activity" object: oneOf: - type: string - type: object description: "Primary object of the activity" target: oneOf: - type: string - type: object description: "Target of the activity" result: oneOf: - type: string - type: object description: "Result of the activity" summary: type: string description: "Human-readable summary" published: type: string format: date-time description: "When published (RFC3339)" workflow: type: object description: "Reference to originating workflow" properties: id: type: string instanceId: type: string step: type: string source: type: object description: "Source service" properties: service: type: string version: type: string # =========================================================================== # @kno:activity-types # =========================================================================== activity-types: $schema: kno-section@0.0.1 id: activity-types title: "Possibility Activity Types" content: description: | Possibility-specific activity types extending AS2. types: - type: "pspace:PersonaSwitch" extends: Activity description: "User switched active persona" - type: "pspace:ConsentGrant" extends: Accept description: "User granted consent" - type: "pspace:ConsentRevoke" extends: Undo description: "User revoked consent" - type: "pspace:FederationJoin" extends: Join description: "Organization joined federation" - type: "pspace:Authorization" extends: Accept description: "Org authorized another for access" - type: "pspace:ImportStarted" extends: Create description: "Import run initiated" - type: "pspace:FileTransferred" extends: Add description: "File transferred to storage" - type: "pspace:FileTransformed" extends: Update description: "File transformed to .kno" - type: "pspace:FileStored" extends: Add description: "File stored to Hive" - type: "pspace:FileFailed" extends: Reject description: "File failed during import" - type: "pspace:ImportCompleted" extends: Update description: "Import run completed" - type: "pspace:ImportFailed" extends: Reject description: "Import run failed" - type: "pspace:Interrupt" extends: Activity description: "System-initiated pause" # ------------------------------------------------------------------- # Email operations (Phase 3.2, #1578) # ------------------------------------------------------------------- - type: "pspace:TestEmailSent" extends: Create description: "Admin-initiated test email delivery" # ------------------------------------------------------------------- # Email sender domain lifecycle (Phase 3.2, #1578) # # Persona-anchored when member-initiated; user-anchored for # admin-on-behalf-of; system-anchored for background-poll terminal # transitions. There is no EmailDomainFailed type today because the # email_sender_domains table has no background failure path; add it # here AND wire the emit site at the same time if/when one is added. # ------------------------------------------------------------------- - type: "pspace:EmailDomainConfigured" extends: Create description: "Email sender domain registered for a possibility (POST /possibilities/:slug/email-domain)" - type: "pspace:EmailDomainRemoved" extends: Delete description: "Email sender domain removed from a possibility (DELETE /possibilities/:slug/email-domain)" - type: "pspace:EmailDomainVerifyTriggered" extends: Activity description: "Member-initiated re-verification of an email sender domain" - type: "pspace:EmailDomainVerified" extends: Update description: "Background poll observed email domain transition to active (dns_pending|verifying → active)" - type: "pspace:EmailDnsRecordCreated" extends: Add description: "DNS provider successfully created a single email-related DNS record (per-record event during provisioning)" # ------------------------------------------------------------------- # Custom domain lifecycle (Phase 3.2, #1578) # # Same actor model as email domains. CUSTOM_DOMAIN_FAILED carries a # `reason` discriminator in context (verification_timeout | # ownership_lost) emitted by the background poller. # ------------------------------------------------------------------- - type: "pspace:CustomDomainConfigured" extends: Create description: "Custom domain registered for a possibility (POST /possibilities/:slug/custom-domain)" - type: "pspace:CustomDomainRemoved" extends: Delete description: "Custom domain removed from a possibility (DELETE /possibilities/:slug/custom-domain)" - type: "pspace:CustomDomainVerified" extends: Update description: "Custom domain reached active state (immediate-verify path or background-poll terminal transition)" - type: "pspace:CustomDomainFailed" extends: Reject description: "Custom domain background-poll terminal failure; context.reason is verification_timeout or ownership_lost" - type: "pspace:CustomDomainDnsRecordCreated" extends: Add description: "DNS provider successfully created a single custom-domain DNS record (per-record event during provisioning)" # ------------------------------------------------------------------- # Possibility lifecycle & admin auth provisioning # (Phase 3.3, Q-COL-14, #1579) # # All admin-initiated. Per FP §0.7.1 anchor-decision rule, these are # user-anchored (admin acting on the platform), not persona-anchored # (members acting inside a possibility). Emit sites use # actorFromUser(c.get("user")) with admin: true marker in context. # ------------------------------------------------------------------- - type: "pspace:PossibilityAuthProvisioned" extends: Create description: "Admin provisioned auth (OIDC client + realm config) for a possibility (POST /admin/possibilities/:id/auth, both standard and idempotent paths emit this on first creation)" - type: "pspace:PossibilityAuthDeprovisioned" extends: Delete description: "Admin deprovisioned auth for a possibility (DELETE /admin/possibilities/:id/auth)" - type: "pspace:PossibilityAuthUpdated" extends: Update description: "Admin updated auth configuration for a possibility (PATCH /admin/possibilities/:id/auth, or idempotent provision when an existing auth config drifts)" - type: "pspace:PossibilityAuthSecretRotated" extends: Update description: "Admin rotated the OIDC client secret for a possibility (POST /admin/possibilities/:id/auth/rotate-secret)" - type: "pspace:PossibilityAssetUploaded" extends: Add description: "Admin uploaded a branding asset (favicon, logo, og-image) for a possibility (POST /admin/possibilities/:id/assets)" - type: "pspace:PossibilityStyleGuideBootstrapped" extends: Create description: "Admin bootstrapped a {slug}-style-guide.kno from brand discovery (POST /admin/possibilities/:id/style-guide/bootstrap)" - type: "pspace:ProvisioningFailureResolved" extends: Update description: "Admin resolved a recorded provisioning failure (POST /admin/possibilities/provisioning-failures/:id/resolve). Object is a ProvisioningFailure, not scoped to a single possibility." # ------------------------------------------------------------------- # Possibility Collaboration v2 (X2.1, #1720; DD-COL2-09) # # Only THREE new verbs are required by v2; all other v2 events reuse # existing AS2 vocabulary (Offer/Accept/Reject/Undo/Activity) per the # DD-COL2-09 mapping table. These three exist because no AS2 base verb # captures the meaning cleanly: # # EstablishRelationship — bilateral typed connection between two # Possibilities (Add/Offer describe one side only). # DispatchHelperEnvoy — provisioning of a per-edge helper agent # (Create is too generic; this is a specific lifecycle event). # MeterResourceGrant — recording consumption against a grant # (Update is too broad; meters carry quantity + period semantics). # ------------------------------------------------------------------- - type: "pspace:EstablishRelationship" extends: Activity description: "A typed bilateral relationship edge transitioned to active between two Possibilities. Emitted alongside the per-side Accept verb to provide a single canonical activity for the established state." - type: "pspace:DispatchHelperEnvoy" extends: Create description: "An Envoy or Liaison helper was auto-provisioned for a consented relationship edge (per-edge cross-realm helper)." - type: "pspace:MeterResourceGrant" extends: Update description: "Recorded consumption against a typed resource grant. Carries quantity, units, and grant period context. Emitted by the enforcement hook on each metered consumption event." # =========================================================================== # @kno:examples # =========================================================================== examples: $schema: kno-section@0.0.1 id: examples title: "Examples" content: simple_as2: | "@context": "https://www.w3.org/ns/activitystreams" id: "https://possibility.space/activities/act_001" type: "Create" actor: type: "Person" id: "https://possibility.space/users/max" name: "Max Engel" object: type: "Note" id: "https://possibility.space/notes/note_123" content: "Hello, Possibility federation!" published: "2026-01-27T10:30:00Z" summary: "Max created a note" with_pspace_extensions: | "@context": - "https://www.w3.org/ns/activitystreams" - "https://possibility.space/ns/pspace" id: "https://possibility.space/activities/act_002" type: "Create" actor: type: "Person" id: "https://possibility.space/users/max" xri: "pspace://user:usr_01HXYZ" name: "Max Engel" object: type: "pspace:Possibility" id: "poss_01ABC" xri: "pspace://possibility:poss_01ABC" name: "AI-Powered Art Generator" published: "2026-01-27T11:00:00Z" summary: "Max created a new possibility" "pspace:persona": id: "persona_max_awecelot" name: "Awecelot Founder" representing_org: "org_awecelot" workflow: id: "possibility-creation" instanceId: "wf-xyz789" step: "create-entity" source: service: "pspace-api" version: "0.3.0" import_activity: | "@context": - "https://www.w3.org/ns/activitystreams" - "https://possibility.space/ns/pspace" id: "pspace://activity:act_import_001" type: "pspace:FileTransferred" actor: type: "System" id: "pspace://system:pspace-api" name: "pspace-api" object: type: "File" id: "readme.md" name: "README.md" target: type: "Collection" id: "minio://raw/corpus_01ABC/" name: "MinIO raw bucket" published: "2026-01-27T14:30:00Z" summary: "Transferred README.md to raw storage" workflow: id: "corpus-import" instanceId: "wf-import-01XYZ" step: "transfer" context: import_id: "01HXYZ123ABC" corpus_id: "corpus_01ABC" phase: "transfer" # ============================================================================= # DESIGN NOTES # ============================================================================= _design_notes: decisions: - "Embrace-and-extend AS2 — all activities are valid AS2 documents" - "PRODUCED_BY is the key relationship to workflows" - "Actor includes System type for automated components" - "Import pipeline has dedicated activity types" - "Context field holds type-specific data" service_architecture: | The pspace-activity service stores and queries activities: - POST /activities — Create activity - GET /activities — List with filtering - GET /activities/:id — Get specific - GET /activities/workflow/:instanceId — Get by workflow future: - "Federation delivery via AS2 inbox/outbox" - "Annotations as specialized activities" - "Per-type schema validation"