メインコンテンツまでスキップ

Observer Agents — The Universal Sensor

The Observer Agent is Zeq's universal sensor. It is not a tracker. A tracker measures the user; an observer measures the state of the system that the user is part of, and posts that state to a state machine which folds it into the entangled state.

One wire contract. Four form factors. Identical JSON envelope on the network in every case, so a pacemaker, a Python AI loop, a browser session, and a Linux network daemon all speak the same protocol to the same /api/chain/<slug>/event endpoint.

That is the load-bearing claim of the framework: language-agnostic because everything moves as JSON; substrate-agnostic because the ZeqAuth-V3 equation-as-credential does not care what computed the observation; tamper-evident because every observation eventually folds into a hash-linked row that R1 (atomic writer), R2 (awareness), and R3 (phase-locked cipher + HZC archiver) defend.

The four form factors

Form factorFileDrops intoTypical use
Web JSzeq-observer-client.jsAny HTML pageWeb apps, dashboards, IoT consoles
Pythonzeq-observer-client.pyAny Python processAI/ML training loops, robotics, scientific compute
Embedded Czeq-observer.cAny C-linkable runtimePacemakers, aerospace, microwaves, medical devices
Network Tapzeq-observer-tap.pyAny Linux/macOS hostSOC 2 / NIST AU-12 audit gold — interface state, listening ports, established connections

All four serve from https://zeqapi.com/zeq-observer-client.js (etc.) so you can drop them into a project with one <script> tag, one pip download, one curl -O, or one git pull.

The wire contract

Every observation, regardless of form factor, flattens to the same body:

POST /api/chain/<slug>/event
Authorization: Bearer zsm_<state-machine-key>
Content-Type: application/json

{
"type": "observation",
"payload": {
"observation": "<short label>",
"state_hash": "<sha256 of the observed state>",
"zeqond": "2287568432",
"phase": 0.523,
"meta": { /* free-form, agent-specific */ },
"agent_signals": {
"HF6": 0.142,
"HF8": 0.0,
"HF12": 0.881,
"HF14": 1.0,
"HF18": 0.029
},
"_zeq": {
"session": "<random per-process id>",
"agent": "zeq-observer-py/1.287.5"
}
}
}

The endpoint authenticates with the state-machine key (zsm_*) on the Authorization: Bearer header. The body is plaintext JSON by default. When the agent has the machine as originId, it can flip into phase-locked mode and send payload_ct instead — a single hex ciphertext built with R3's zeqEncryptPhaseLocked(plaintext, zeqond, originId). The server recomputes the same nonce from (zeqond, slug) and the row commits.

That single shape is why a C agent on a pacemaker, a Python loop on a training server, a browser tab, and a network tap can all post into the same entangled state without the writer ever needing to know who they are.

Local HF computation

Each observation carries a small bundle of HF forensic signals that the agent computes locally before the row leaves the device. The five that ship in every form factor:

SignalMeaning
HF6Phase-bucket entropy — Shannon entropy of how the agent's emissions distribute across the 8-bucket phase wheel
HF8Cadence drift — |observed_dt − τ_z| / τ_z — how far the agent's own ticker has drifted from 0.777 s
HF12Run-length anomaly — longest streak of identical state hashes in the local outbox
HF14Network-loss flag — 0/1 set when the agent had to retry past one outbox flush
HF18Local-clock skew — agent's now() / τ_z vs the last successful server-acknowledged zeqond

These five mean the entangled state row carries forensic posture as observed at the source — independent of anything the server adds. R2's awareness operators (ZEQ-PROTECT-001, XI1, MK1) compute a server-side view on top, and the two views combined are what compliance auditors get.

The full 20-operator HF ladder (HF1–HF20 + the S_forensic composite) runs server-side in api-core/lib/awareness.ts; the agent ships the five most useful of them so a row never lacks forensic context, even if the entangled state row arrives late.

The fallback ticker

An observer is always ticking, even with no events. Each form factor carries a heartbeat that emits a typed row every 8 zeqonds ≈ 6.2 seconds of wall time. Reasons:

  1. Liveness proof — an entangled state that sees a heartbeat row every 8z is provably online. The State Observer page renders the cadence as "● awareness firing" in the footer.
  2. Cold-row anchor — the heartbeat row carries the agent's current _zeq.session, last user-event zeqond, and outbox depth. Replaying the entangled state forward is sufficient to reconstruct the agent's liveness window without any side state.
  3. Network-failure recovery — if the agent goes offline, the outbox queues observations locally. When the next heartbeat succeeds, the queued events drain in order. The row that finally succeeds carries the gap explicitly: meta.gap_zeqonds: <count>.

The heartbeat is fire-and-forget; failure to land does not block the agent's next observation.

Encryption (R3 phase-locked)

Every form factor supports the optional R3 phase-locked encryption layer. With data-encrypt="true" (Web JS) or encrypt=True (Python / C / Tap), the agent encrypts the JSON payload with AES-256-GCM using a deterministic 12-byte nonce derived as:

nonce = sha256("phase-lock|" + zeqond + "|" + slug)[0:12]

The ciphertext is sent as payload_ct (hex, no IV component) and the server recomputes the same nonce from (zeqond, originId) to decrypt. Tamper either of those two fields and the GCM auth tag fails — the row is rejected.

This means even if the network transport is hostile (a public WiFi, a shared corporate proxy, a hostile cellular provider), the device's state stream is sealed end-to-end. See R3 — Cipher + HZC for the full nonce derivation, the six verified properties, and the HZC cold-row archiver that uses the same primitive at rest.

Substrate composition

LayerWhat it providesHow the agent participates
R1 — Atomic writerpg_advisory_xact_lock per origin + UNIQUE (origin_id, zeqond_number)Agent posts to /event; R1 serialises against any other writer hitting the same entangled state
R2 — Awareness1024-row trailing window, ZEQ-PROTECT-001, XI1, MK1, forward-relink self-healAgent sends HF6/HF8/HF12/HF14/HF18 in the row; server fills in the rest
R3 — Cipher + HZCPhase-locked AES-256-GCM, deterministic nonce, HZC cold archivesAgent uses zeqEncryptPhaseLocked when encrypt=true; archived rows decrypt with the same recipe
ZeqCompliance v113-standard regulatory envelope returned per-callAgent observations feed actor.user_id, action.input_digest, temporal.zeqond_tick

Choosing a form factor

  • Web JS — when the device is a browser tab or any V8/JSCore runtime. One script tag.
  • Python — when the agent runs inside a long-lived process: training loops, robotic controllers, scientific pipelines.
  • Embedded C — when the device cannot host Python or JS: medical implants, RTOS-bound microcontrollers, aerospace flight software. Single-file, cc -O2 -pthread.
  • Network Tap — when the goal is observing the host itself: interface state, listening ports, established connections. Privacy-first (SHA-256 hashed IPs).

You can run multiple form factors against the same state machine. A web tab and a python loop and a network tap all posting to zeq07792026349 produce a single chain that interleaves all three agents' emissions. The R1 atomic lock guarantees no two rows collide even at full concurrency.

File map

  • apps/zeq-dev/public/zeq-observer-client.js — Web JS form factor (25 KB)
  • apps/zeq-dev/public/zeq-observer-client.py — Python form factor (17 KB)
  • apps/zeq-dev/public/zeq-observer.c — Embedded C form factor (18 KB)
  • apps/zeq-dev/public/zeq-observer-tap.py — Network tap daemon (12 KB)
  • shared/api-core/src/routes/chain.ts/api/chain/:slug/event writer
  • shared/api-core/src/lib/awareness.ts — server-side HF ladder