---
title: "§7 Sense"
description: "Normative definition of the outbound loop: trigger declaration, isolation from Execute, the sense.enable grant, activation, and what a runtime may and may not deliver."
canonical: https://harnesscontextprotocol.io/docs/specification/sense
---

# §7 Sense

> Normative definition of the outbound loop: trigger declaration, isolation from Execute, the sense.enable grant, activation, and what a runtime may and may not deliver.

Sense is the outbound loop: a pack announces a world change.

## 7.1 Declaration

1. A pack declares triggers in the manifest as `stimulusTriggers: [{ ref }]`.
2. `ref` MUST be non-empty, lower-case, and MAY contain `.` as a separator.
3. Every `ref` MUST have a Policy `stimuli` entry with `operation: read` and a
   land (§4.4). Runtimes MUST fail lint otherwise.
4. A pack MUST NOT declare a trigger for a condition it can only obtain by
   polling.

## 7.2 Isolation

1. A trigger MUST NOT cause a command to execute.
2. A trigger MUST NOT mint credentials or bypass Binding.
3. Delivery of a trigger MUST NOT spend, send, or mutate anything outside the
   runtime's sink.
4. Execute and Sense MUST share the pack's Policy, Binding, and Principal scope.
   They MUST NOT be merged into a single tool or command.
5. A recorded trigger MAY lead an Invoker to run Execute. That Execute MUST pass
   the full pipeline of §6.3 under its own grants.

## 7.3 Grant

1. A runtime MUST NOT deliver a trigger to a sink unless the Principal holds
   `sense.enable` for the pack.
2. Without the grant, the runtime MUST acknowledge the producer and drop.
3. A runtime MUST drop a trigger whose `ref` the pack does not declare and
   SHOULD report it.
4. A runtime MUST drop a trigger when the pack has no connected Binding for the
   Principal (any mode other than `public`), or when the trigger's land differs
   from its Policy entry. Sense fails closed, as Execute does (§9.4).

## 7.4 Activation

1. Sense activation MUST be independent of Execute activation. Deactivating
   Sense MUST NOT affect installed, activated, or connected state.
2. When activation is `on`, the runtime routes to a sink, either surfaced
   (`inbox`) or recorded (`silent`). When `off`, the route is `drop`.
3. Route selection and sink implementation are runtime concerns.

## 7.5 Recording

1. A sink record MUST be attributable to `Principal + Binding identity + land +
   pack_id + ref`.
2. When land is `brain`, the runtime MUST require project membership before
   surfacing the record.
3. Sink records are inert: reading one grants no capability.

## 7.6 Delivery mechanism

*Informative.* How a trigger reaches the runtime (signed ingress, vendor push
mapping, message queue, a `sense_only` pack's stdout) is not an HCP type.
Runtimes document it in their own profile.

## 7.7 Binding health

1. A pack with Binding mode `user`, `local`, or `mothership` SHOULD declare the
   trigger `binding.degraded`.
2. Its payload SHOULD carry a `state` from `linked`, `stale`, `needs_reauth`,
   `pending`, `error`.
3. The runtime's hub SHOULD be the producer of `binding.degraded`.

## 7.8 What is not Sense

*Informative.* Polling a read command; a runtime's uptime monitor; UI refresh
timers; control-plane scheduler ticks. None of these are pack triggers and a
runtime MUST NOT deliver them as such.

## 7.9 Sense-only packs

1. A pack with `kind: sense_only` MUST declare at least one trigger and MAY
   declare no commands.
2. Such a pack SHOULD have Binding mode `public`, or a Binding whose hub is
   `none` (§8.3), and MUST NOT require a
   user command to install a webhook unless the upstream requires a
   registration call.

## Sitemap

- [Documentation](https://harnesscontextprotocol.io/docs)
- [Packs](https://harnesscontextprotocol.io/packs)
- [Glossary](https://harnesscontextprotocol.io/docs/reference/glossary)
- [llms.txt](https://harnesscontextprotocol.io/llms.txt)
- [llms-full.txt](https://harnesscontextprotocol.io/llms-full.txt)
- [OpenAPI](https://harnesscontextprotocol.io/openapi.json)
- [MCP](https://harnesscontextprotocol.io/mcp)
