# Observation Schema — Layer 3 Reusable Entity Type # KNO Schema Version: 0.1.0 # # Layer 3 reusable schema for AGENT-PERCEPTION observations — structured # events derived from AS2 activities that agents consume to perceive # the running system. The F3 tap (services/pspace-api/src/lib/observations.ts) # converts qualifying activities into observation .kno entities; agents # read the resulting stream to drive their DISCOVER phase. # # DOMAIN: Agent perception of system events # PURPOSE: Bridge "things happen" (AS2 activities) → "agents notice things" # (.kno observations). Without this bridge, agents have no # real-time feed of the platform's behaviour. # # DISTINCTION FROM "LEARNING OBSERVATION" (M14 #462): # - learning_observations (postgres, services/pspace-api/src/lib/learning/) # are usage-signal records for the schema-evolution lifecycle — query # patterns, gap discoveries, user feedback, and aggregated usage # signals. They feed pattern detection and schema-evolution # proposals. # - Agent-perception observations (this schema, content/observations/*.kno) # are activity-derived events for agent personas to read. They feed # the DISCOVER phase of the agent loop and are routed to subscribed # personas via perception-domain matching (P10). # # Both surfaces are legitimate; both will continue to exist. The two # stores never share rows. Agents that need raw usage signals consult # the learning store; agents that need real-time activity-derived # events consult this archive. # # DESIGN DECISIONS: # - DD-O-01: Observations are first-class .kno entities, NOT postgres # rows. .kno keeps the read path consistent with other agent inputs # (agent cards, decisions, perception domains) and gives observations # the same VCS history as other kno entities (RFC-019). # - DD-O-02: Capability-based routing per #2018 carry-forward A-5. # Rules name a perception-domain slug, not an agent ID. The # `perception-domain → agent` projection (F1, agents-by-domain.ts) # resolves to the actual subscriber set at runtime, mitigating # blindspot B-004 (hardcoded persona IDs). # - DD-O-03: Open `observation_type` field. Closed enums force a # schema PR for every new observation class (B-001 schema inflation). # Each rule declares its own observation_type; rules are .kno files. # - DD-O-04: Tap is asynchronous + non-blocking per #2019 spike. # Activity write and observation write are independent failures # (B-003 mitigation): observation write may fail without taking # activity logging down. # - DD-O-05: `severity` follows OTel/Activity Streams conventions # (info / notice / warning / attention). Used by the agent loop's # priority queue: higher-severity observations preempt lower. # - DD-O-06: `data` is a free-form object — observations carry # domain-specific payload. The rule that produced the observation # determines the shape; subscribers know which rules they consume # and what each rule's data shape looks like. # # Created for: M22-P2 F3 (#851), per #2018 futro carry-forward A-5. # ============================================================================= # SCHEMA DECLARATION # ============================================================================= $schema: kno@0.0.9 # ============================================================================= # BASIC TIER # ============================================================================= id: 01KQ43X04ATJZM6KN9ZFAC48RA slug: observation-schema type: spec version: 0.1.0 # ============================================================================= # STANDARD TIER # ============================================================================= title: "Observation Schema" purpose: | Define the schema for agent-perception observation entities — the structured events derived from AS2 activities that agents consume to drive their perception loop. **Lifecycle:** ``` Code calls logActivity() │ ▼ pspace-api logActivity() — fires the AS2 emit (HTTP to pspace-activity) AND in parallel runs the F3 observation tap │ ▼ Promise.allSettled ├──→ AS2 activity persisted in pspace-activity DB └──→ F3 tap evaluates rules: for each rule in content/observation-rules/*.kno: if rule matches activity: build observation per rule.observation_type saveEntity(observation) // VCS-Mandatory via Hive done ``` Failures are independent. Activity write failing does not block the observation write; observation write failing does not block the activity write. Both fall back to logged warnings (graceful degradation). **Routing model (DD-O-02):** Each observation has a `routing.domains[]` array of perception-domain slugs. The runtime resolves "which agents want this?" by walking agent cards' `perception.domains[]` (F1) and finding subscribers. No hardcoded agent IDs anywhere — adding a new agent that subscribes to an existing domain requires zero changes to rules. **Data shape:** | Field | Required? | Purpose | |---|---|---| | `source_activity` | Yes | XRI of the originating AS2 activity | | `observed_at` | Yes | ISO-8601 timestamp when the observation was created | | `observation_type` | Yes | Free-form slug naming the observation class (e.g. "schema-change", "decision-recorded", "entity-lifecycle") | | `severity` | Yes (default `info`) | One of: info, notice, warning, attention | | `data` | Yes | Free-form domain-specific payload | | `routing.domains[]` | Yes (default `[]`) | Perception-domain slugs that should receive this observation | | `produced_by_rule` | Yes | XRI of the observation-rule .kno that produced this observation | **Layer 3 position:** Layer 3 reusable. Extends document-schema (Layer 2). # ============================================================================= # RICH TIER — Provenance & Taxonomy # ============================================================================= provenance: origin: id: 01KQ43X04ATJZM6KN9ZFAC48RA timestamp: "2026-04-25T23:10:00Z" tool: manual issue: "https://github.com/PossibilityTruthy/possibility-space/issues/851" taxonomy: topics: - observations - agents - perception - activity-streams - m22 keywords: - observation - tap - activity-derived - perception - capability-routing # ============================================================================= # RICH TIER — Relationships # ============================================================================= relationships: extends: - xri: "kno://specs/document-schema" reason: "Layer 2 base type" composes: - xri: "kno://specs/identity-schema" reason: "id, slug, type, version" - xri: "kno://specs/history-schema" reason: "_history + VCS commit metadata" related_to: - xri: "kno://specs/activity-schema" reason: "Observations are derived from AS2 activities; source_activity points back at the originating activity" - xri: "kno://specs/observation-rule-schema" reason: "Each observation is produced by an observation-rule .kno; routing/observation_type are determined by the rule" - xri: "kno://specs/agent-card-schema" reason: "Agents declare perception.domains[]; this schema's routing.domains[] resolve subscribers via that mechanism" - xri: "kno://specs/perception-domain-schema" reason: "routing.domains[] entries are slugs into the perception-domain vocabulary" - xri: "kno://specs/decision-schema" reason: "Decision recordings produce a 'decision-recorded' observation (per the demo rule)" quality: completeness: 0.9 last_reviewed: "2026-04-25" review_status: draft # ============================================================================= # HISTORY # ============================================================================= _history: version: 1 created: "2026-04-25T23:10:00Z" created_by: "claude" modified: "2026-04-25T23:10:00Z" modified_by: "claude" # ============================================================================= # SPECIFICATION # ============================================================================= spec: status: Draft changelog: - version: "0.1.0" date: "2026-04-25" changes: - "Initial creation for M22-P2 F3 (#851)" - "Capability-based routing (DD-O-02) — routing.domains[] not target_agents[] (B-004 mitigation)" - "Open observation_type (DD-O-03) — rules declare types via .kno (B-001 mitigation)" - "Severity enum: info / notice / warning / attention (DD-O-05)" - "Free-form data (DD-O-06) — rules document their data shape" schema: type: object required: - id - slug - type - version - source_activity - observed_at - observation_type - severity - data - routing - produced_by_rule properties: $schema: type: string const: "observation@0.1.0" id: type: string description: "Unique identifier (ULID)" slug: type: string description: | Auto-generated kebab-case slug. Convention: {observation_type}-{ulid_short} e.g. "decision-recorded-01KQ43X0". type: type: string const: "observation" version: type: string description: "Always '0.1.0' for v0.1.0 schema instances" # ----------------------------------------------------------------------- # CORE FIELDS # ----------------------------------------------------------------------- source_activity: type: string description: | XRI of the AS2 activity this observation was derived from. Format: pspace://activity/{id} The activity must exist in pspace-activity at the moment of observation creation; the tap fires the observation write AFTER the activity payload is constructed (so the activity ID is stable) but does NOT wait for the activity HTTP POST to complete (independent writes per B-003). observed_at: type: string format: date-time description: "ISO-8601 timestamp (UTC) when the observation was created" observation_type: type: string description: | Free-form slug naming the observation class. Open enum (DD-O-03). Examples in use: - schema-change (an entity in specs/ changed) - decision-recorded (a Decide AS2 activity was emitted) - entity-lifecycle (an entity was created, updated, or deleted) - drift-finding (A13 Drift Detective surfaced a finding) - capability-installed (a capability was installed) severity: type: string enum: - info - notice - warning - attention default: info description: | Priority level for the agent loop's queue: - info: routine; no escalation needed - notice: noteworthy; agents may log but don't act immediately - warning: agent attention warranted within the loop's normal cadence - attention: preempts lower-priority observations; agents should react in their next tick data: type: object description: | Free-form payload. Shape determined by the observation-rule that produced this observation. Subscribers know which rules they consume and what data shape each rule emits. routing: type: object required: - domains description: | Capability-based routing (DD-O-02). The runtime resolves subscribers by walking agent cards' perception.domains[] for any match in routing.domains[]. properties: domains: type: array items: type: string description: | Slugs of content/perception-domains/*.kno entities. Subscriber resolution: getAgentsForDomain(slug) walks the agent index. Empty array means no targeted routing — observation persists but no agent attention is requested. examples: - ["schemas"] - ["entity-health"] - ["activities", "drift-surfaces"] recommended_priority: type: string enum: - low - normal - high description: | Optional hint for the agent's priority queue. Independent of `severity`: severity describes what kind of event; priority describes how urgently agents should attend. produced_by_rule: type: string description: | XRI of the observation-rule .kno that produced this observation. Format: kno://observation-rules/{slug} Used by drift-guard to assert no orphan observations (observations whose rule no longer exists). # ----------------------------------------------------------------------- # OPTIONAL FIELDS # ----------------------------------------------------------------------- affects: type: array items: type: string description: | Optional XRIs of entities the observation refers to (e.g. the entity whose change triggered the observation). Distinct from `data` — affects[] is for graph traversal; data is for payload. ttl_seconds: type: integer minimum: 0 description: | Optional time-to-live. Observations older than ttl_seconds may be archived/garbage-collected. Set when the observation represents a transient state (e.g. a fleeting metric), not a permanent record. Most observations omit this and persist indefinitely (subject to A6 Entity Lifecycle Guardian). # ============================================================================= # EXAMPLES # ============================================================================= examples: - title: "Decision-recorded observation" description: "Emitted by the F3 tap when a Decide AS2 activity is logged" content: | $schema: observation@0.1.0 id: 01KQ43X05DEMO0001OBSERVATION slug: decision-recorded-01KQ43X0 type: observation version: 0.1.0 source_activity: "pspace://activity/act_01ABCXYZ" observed_at: "2026-04-25T22:55:13Z" observation_type: decision-recorded severity: info data: decision_xri: "pspace://decision/01KQ42A1J6V98HXMD43BGDG4H8" decision_type: schema-evolution decision_subtype: composition-pattern chosen: option-c-strict-additive confidence: 0.95 decided_by: "pspace://user/max" routing: domains: - acceptance-criteria-history # consumed by A12 Hindsight Reviewer recommended_priority: normal produced_by_rule: "kno://observation-rules/decision-recorded" - title: "Schema-change observation" description: "Emitted when a Create or Update activity targets specs/*.kno" content: | $schema: observation@0.1.0 id: 01KQ43X06DEMO0002OBSERVATION slug: schema-change-01KQ43X1 type: observation version: 0.1.0 source_activity: "pspace://activity/act_01DEFXYZ" observed_at: "2026-04-25T23:00:42Z" observation_type: schema-change severity: notice data: entity_xri: "pspace://schema/agent-card-schema" change_type: field-added previous_version: "0.1.0" new_version: "0.2.0" added_fields: - perception - goals - boundaries routing: domains: - schemas recommended_priority: normal produced_by_rule: "kno://observation-rules/schema-change" affects: - kno://specs/agent-card-schema