Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This repository is documentation-only. It contains no runtime implementation cod
| Device policy | [device-policy/v1.md](device-policy/v1.md) | Implemented baseline |
| Offline Tier C tokens | [offline-tokens/v1.md](offline-tokens/v1.md) | Implemented baseline |
| Runtime config surface | [runtime-config/v1.md](runtime-config/v1.md) | Implemented baseline |
| Gateway config surface | [gateway-config/v1.md](gateway-config/v1.md) | Implemented baseline |
| Signing contract | [signing/v1.md](signing/v1.md) | Implemented baseline |

## Gaps
Expand Down
11 changes: 2 additions & 9 deletions gaps/open.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,11 @@
- Domain: `gateway-api/v1`
- Status: Contract defined in `ori-gateway` (`internal/contracts/tier_c_enrichment.go`), DECISIONS.md entry recorded. MQTT topic constants and `app.go` handler are not yet wired. Runtime has no client for sending enrichment requests.
- Summary: The advisory Tier C enrichment flow requires topic constants in `contracts.go` and a subscription handler in `app.go` on the gateway side, and a corresponding MQTT client on the runtime side. Until wired, enriched Tier C operator messages are unavailable.
- Tracking: `ori-platform/ori-gateway` — open issue for MQTT wiring.
- Tracking: `ori-platform/ori-gateway#41`

## G-16 — `reasoning_log` export missing from gateway runtimeclient

- Domain: `gateway-api/v1`
- Status: Export type documented in spec and served by runtime. Gateway `runtimeclient/mqtt.go` implements `Health`, `SensorHistory`, `ActionLog`, `TierCDecisionLog` but has no `ReasoningLog` method.
- Summary: The reasoning audit export surface is unusable from the gateway until the runtimeclient method is added.
- Tracking: `ori-platform/ori-gateway` — open issue for runtimeclient gap.

## G-17 — Gateway config surface not spec'd

- Domain: (new) `gateway-config/v1`
- Status: `ori-gateway` has a working `gateway.yaml` config surface (`gateway.broker_url`, `gateway.heartbeat_interval_s`, `provider.*`, `reporting.*`, `sim.*`, `fleet.*`). No corresponding spec document exists.
- Summary: A `gateway-config/v1.md` spec is needed so the CLI, dashboard, and SDK can align with the gateway's configuration surface without reading Go source.
- Tracking: `ori-platform/ori-specs` — create `gateway-config/v1.md`.
- Tracking: `ori-platform/ori-gateway#42`
8 changes: 8 additions & 0 deletions gaps/resolved.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,11 @@ cross-sensor snapshot enrichment. Config lives under `reasoning.context_enricher
default; fail-open. Staleness evaluated at prompt-build time, not event-emit time.
Tier D never reaches the enricher by construction. See `ori-runtime/DECISIONS.md`
2026-06-08 entry and `docs/CAPABILITY_MATRIX.md` for full implementation scope.

## G-17 — Gateway config surface not spec'd

Resolved (2026-06-09): `gateway-config/v1.md` documents all `gateway.yaml` keys,
types, defaults, and validation rules for all five top-level sections: `gateway`,
`provider`, `reporting`, `sim`, `fleet`. Separation between `provider` (Tier 3
reasoning) and `reporting.provider` (advisory/product) is made explicit. Tracked
by `ori-platform/ori-specs#5`.
194 changes: 194 additions & 0 deletions gateway-config/v1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
# Gateway Config v1

> Status: Implemented in `ori-gateway`
> Source of truth: `internal/config/config.go`, `gateway.yaml.example`

This document defines the `gateway.yaml` configuration surface for `ori-gateway`.
It covers all keys recognised by the config loader, their types, defaults, and
validation rules. The MQTT contract between runtime and gateway is in
[`gateway-api/v1.md`](../gateway-api/v1.md).

---

## `gateway`

Core LAN transport settings.

| Key | Type | Default | Required | Notes |
|---|---|---|---|---|
| `broker_url` | `string` | — | Yes | MQTT broker URL, e.g. `tcp://localhost:1883` or `mqtts://broker:8883`. |
| `heartbeat_interval_s` | `int` | `30` | No | Must be positive. Gateway publishes `ori/gateway/health` on this interval. |

---

## `provider`

Tier 3 reasoning provider. This section is intentionally separate from
`reporting.provider`. `provider` routes runtime Tier 3 reasoning requests;
`reporting.provider` drives advisory/product features like weekly reports and
Tier C enrichment. Credentials from one must never flow into the other.

| Key | Type | Default | Required | Notes |
|---|---|---|---|---|
| `name` | `string` | — | Yes | `echo \| llama_cpp \| cloud_llm` |
| `timeout_ms` | `int` | `10000` | No | Must be positive. Per-request provider timeout for Tier 3 reasoning. |

### `provider.llama_cpp`

Required when `provider.name: llama_cpp`.

| Key | Type | Notes |
|---|---|---|
| `url` | `string` | Required. HTTP completion endpoint, e.g. `http://localhost:8080/completion`. |
| `model` | `string` | Fallback model name used when `/props` is unreachable or returns no model name. |

### `provider.cloud_llm`

Required when `provider.name: cloud_llm`.

| Key | Type | Required | Notes |
|---|---|---|---|
| `vendor` | `string` | Yes | `claude \| openai \| gemini \| deepseek \| openai_compatible` |
| `api_key_env` | `string` | Yes | Name of an environment variable holding the API key. Must not contain whitespace. |
| `model` | `string` | Yes | Model identifier, e.g. `claude-sonnet-4-5`. |
| `base_url` | `string` | When `vendor: openai_compatible` | Custom base URL for OpenAI-compatible endpoints. |

Cloud provider API keys are gateway-scoped environment variables. They must not
appear in runtime config (`ori.yaml`) or be carried inside MQTT reasoning envelopes.

---

## `reporting`

Advisory and product features: weekly site reports and Tier C enrichment.
All reporting features are disabled by default. `reporting.provider` must be
set whenever any reporting feature is enabled.

`reporting` is intentionally a separate section from `provider`. Failures in the
reporting path must not affect Tier 3 reasoning, Tier C approval handling, Tier D
safety, or runtime fallback behaviour.

| Key | Type | Default | Required | Notes |
|---|---|---|---|---|
| `provider` | `string` | `""` | When any feature enabled | `gemini` is the only supported value in v1. |

### `reporting.gemini`

Required when `reporting.provider: gemini` and any reporting feature is enabled.

| Key | Type | Notes |
|---|---|---|
| `api_key_env` | `string` | Name of an environment variable holding the Gemini API key. Must not contain whitespace. |
| `model` | `string` | Gemini model identifier, e.g. `gemini-2.5-flash`. |

### `reporting.weekly_report`

Periodic site-level summary generation.

| Key | Type | Default | Notes |
|---|---|---|---|
| `enabled` | `bool` | `false` | Enable weekly report generation. |
| `day` | `string` | — | Weekday name: `monday` through `sunday` (case-insensitive). Required when enabled. |
| `time` | `string` | — | 24-hour `HH:MM` format, e.g. `08:00`. Required when enabled. |
| `timezone` | `string` | — | IANA timezone string, e.g. `Africa/Lagos`. Required when enabled. Validated against the Go timezone database. |

When `enabled: true`, `reporting.provider`, `day`, `time`, and `timezone` must all
be set. The gateway generates reports by consuming bounded runtime exports (via
the MQTT export surface defined in `gateway-api/v1.md`). It does not read runtime
SQLite directly.

### `reporting.tier_c_enrichment`

Advisory enrichment of Tier C operator messages.

| Key | Type | Default | Notes |
|---|---|---|---|
| `enabled` | `bool` | `false` | Enable Tier C enrichment requests. When enabled, the gateway accepts enrichment requests from the runtime, enriches the operator message with advisory LLM context, and returns an advisory-only response. |

Enrichment responses must not change action tier, proposed action, safe default,
approval requirement, or any other runtime authority field. Enrichment failure
must not delay or block the Tier C approval workflow. See `gateway-api/v1.md` for
the enrichment MQTT contract (gap G-15: transport wiring is pending).

---

## `sim`

SIM modem availability probe. Used by the heartbeat publisher to report
`sim_available` in the `ori/gateway/health` payload.

| Key | Type | Default | Notes |
|---|---|---|---|
| `enabled` | `bool` | `false` | Enable SIM modem probe. |
| `modem_path` | `string` | — | Path to the modem device, e.g. `/dev/ttyUSB0`. Required when `enabled: true`. |

---

## `fleet`

> Status: Stub — deferred post-v1.

Fleet coordination client. Currently an inert stub in `internal/fleet/fleet.go`.
Not wired in `app.go`. Config keys are validated but the module performs no
network operations until wiring is complete.

| Key | Type | Default | Notes |
|---|---|---|---|
| `enabled` | `bool` | `false` | Enable fleet coordination. |
| `cloud_url` | `string` | — | Fleet cloud endpoint URL. Required when `enabled: true`. |

---

## Annotated Example

```yaml
gateway:
broker_url: "tcp://localhost:1883"
heartbeat_interval_s: 30

provider:
name: "echo" # echo | llama_cpp | cloud_llm
timeout_ms: 10000
llama_cpp:
url: "http://localhost:8080/completion"
model: "llama-3.2-3b-instruct.gguf" # fallback if /props is unreachable
cloud_llm:
vendor: "claude" # claude | openai | gemini | deepseek | openai_compatible
api_key_env: "ANTHROPIC_API_KEY"
model: "claude-sonnet-4-5"
base_url: "" # required only for openai_compatible

reporting:
provider: "gemini"
gemini:
api_key_env: "GEMINI_API_KEY"
model: "gemini-2.5-flash"
weekly_report:
enabled: false
day: monday
time: "08:00"
timezone: Africa/Lagos
tier_c_enrichment:
enabled: false

sim:
enabled: false
modem_path: "/dev/ttyUSB0"

fleet:
enabled: false
cloud_url: ""
```

---

## Key Separation Invariants

- `provider` is for Tier 3 runtime reasoning requests only. Cloud reasoning
remains a gateway backend — the runtime never calls cloud APIs directly.
- `reporting` is for advisory/product features. Failures here must not affect
the reasoning path.
- API keys (`provider.cloud_llm.api_key_env`, `reporting.gemini.api_key_env`)
must be environment variable **names**, not values. Never commit key values.
- `reporting.*` credentials must not appear in `ori.yaml` (runtime config) and
must not be passed through MQTT reasoning envelopes.
Loading