ADR-0211accepted

Gateway Behavior Control Plane

Status

Accepted

Context and Problem Statement

Gateway behavior quality is currently inconsistent in how it is preserved and applied. When behavior is good (tight check-ins, low-noise heartbeats, good delegation cadence), there is no deterministic actuator that guarantees those patterns are applied in future turns.

Today, behavior influence is split across static prompt text, memory recall, and ad-hoc steering hints. That is useful but not deterministic.

For operator trust, behavior controls must be:

  1. Explicit — Joel can state KEEP/MORE/LESS/STOP/START directly.
  2. Deterministic at runtime — active controls are injected on every gateway turn.
  3. Learnable over time — passive daily review can propose patterns, but proposals do not auto-activate.

Decision

Implement a dedicated gateway behavior control plane with two lanes:

  • Control lane (deterministic): explicit directives from Joel become active gateway behavior contract.
  • Learning lane (advisory): passive daily review of sessions proposes candidate patterns for promotion.

Runtime behavior is driven by the control lane only.

Core Decision Points

  1. Gateway extension as capture actuator

    • A gateway pi extension passively scans inbound operator messages for directive syntax:
      • KEEP: ...
      • MORE: ...
      • LESS: ...
      • STOP: ...
      • START: ...
    • On match, extension calls a canonical CLI command (joelclaw gateway behavior add ...) rather than mutating prompt state directly.
  2. CLI as single write authority

    • All behavior directives are validated, normalized, and persisted via joelclaw gateway behavior commands.
    • No side-channel writes from extensions directly to Redis/Typesense.
  3. Dual persistence model

    • Redis stores the active behavior contract for low-latency runtime injection.
    • Typesense stores immutable history and review candidates for analysis, trend detection, and promotion workflows.
  4. Deterministic prompt injection location

    • Active behavior contract is injected below Identity and above Role in gateway prompt assembly.
    • Injection occurs at least in before_agent_start; optional per-turn refresh in turn_start for hot updates.
  5. Passive daily review is advisory-only

    • A daily review function analyzes gateway sessions + OTEL and emits good_patterns / bad_patterns candidates.
    • Candidates do not affect runtime behavior until promoted via explicit operator action.

Architecture

Data model

interface BehaviorDirective {
  id: string;
  type: "keep" | "more" | "less" | "stop" | "start";
  text: string;
  source: "operator" | "daily-review";
  confidence?: number;
  evidence?: string[];
  createdAt: string;
}
 
interface ActiveBehaviorContract {
  version: number;
  generatedAt: string;
  directives: BehaviorDirective[]; // operator-promoted only
  hash: string;                    // injected hash for OTEL correlation
}

Lanes

Operator message
  -> gateway extension regex/parser
  -> joelclaw gateway behavior add (CLI)
  -> Redis(active contract) + Typesense(history)
  -> prompt injector (below identity / above role)
 
Daily cron review
  -> session + OTEL analysis
  -> Typesense(candidate observations)
  -> optional digest to operator
  -> manual promote required
  -> Redis(active contract)

Injection contract block

<GATEWAY_BEHAVIOR_CONTRACT version=... hash=...>
- KEEP: frequent status handoffs during delegated/background work
- LESS: long strategy monologues during active ops windows
- STOP: redundant heartbeat verbosity
...
</GATEWAY_BEHAVIOR_CONTRACT>

Non-Goals

  • Auto-promoting passive candidates into active behavior without operator confirmation.
  • Replacing existing memory observation pipeline (this ADR integrates with it; does not supersede it).
  • Encoding behavior controls as skills.

Implementation Plan

Required skills preflight (load before implementation)

  • gateway — gateway runtime, extension wiring, daemon behavior.
  • cli-design — deterministic command contract and JSON/HATEOAS responses.
  • memory-system — candidate observation flow and write-gate compatibility.
  • inngest-durable-functions — daily review workflow.
  • inngest-steps — extraction/analysis/promote step orchestration.
  • inngest-events — event schema for behavior review outputs.
  • inngest-flow-control — debounce/aggregation controls for daily review.
  • system-architecture — prompt assembly and cross-system signal flow.

Phase 1 — Control lane

  • Add joelclaw gateway behavior command group:
    • add, list, promote, remove, apply, stats.
  • Define canonical directive schema and validation.
  • Persist active contract in Redis and append history to Typesense.

Phase 2 — Gateway extension capture + injector

  • Add passive parser in gateway extension for directive syntax.
  • Route accepted directives to CLI command (single write authority).
  • Inject active contract at prompt assembly point below identity and above role.
  • Emit OTEL event per run with behavior_contract_hash.

Phase 3 — Passive daily review

  • Add daily Inngest function to evaluate gateway sessions and OTEL:
    • identify positive/negative behavior candidates,
    • compute confidence and evidence snippets,
    • store candidates in Typesense.
  • Add digest output format for operator review.

Phase 4 — Promotion and governance

  • Implement manual promotion path from candidate -> active directive.
  • Add stale candidate expiry and duplicate merge policy.
  • Add conflict detection (e.g., KEEP vs STOP on equivalent text).

Verification

  • joelclaw gateway behavior add writes normalized directive and returns deterministic JSON envelope.
  • Active behavior contract exists in Redis and is retrievable.
  • History/candidates are queryable in Typesense.
  • Gateway prompt includes behavior contract block below identity and above role.
  • OTEL events contain behavior_contract_hash for each injected run.
  • Daily reviewer emits candidate set with confidence + evidence and does not auto-activate candidates.
  • Promotion command updates active Redis contract and next run reflects the update.
  • Conflicting directives are rejected or merged with explicit operator-visible reason.

Consequences

Positive

  • Gateway behavior can be preserved intentionally when Joel likes it.
  • Runtime behavior becomes deterministic and auditable.
  • Passive learning improves behavior suggestions without surprise behavior flips.
  • Behavior changes can be traced from operator directive -> contract hash -> observed turn behavior.

Negative

  • Additional control-plane complexity (CLI + Redis + Typesense + extension + review job).
  • Requires governance for conflicting directives and stale rule cleanup.

Risks and Mitigations

  • Risk: Regex capture misfires on ordinary conversation text.
    • Mitigation: strict parser grammar + CLI validation + explicit parse telemetry.
  • Risk: Directive sprawl degrades prompt clarity.
    • Mitigation: contract cap, dedupe, and stale expiry policy.
  • Risk: Passive review produces low-signal suggestions.
    • Mitigation: confidence thresholds + evidence requirement + human promotion gate.
  • ADR-0018: Redis event-bridge foundations.
  • ADR-0021: memory pipeline contract (observe -> write-gate -> store -> retrieve).
  • ADR-0189: gateway guardrails and operator-facing cadence.
  • ADR-0199: reflection loop and pattern capture discipline.
  • ADR-0210: channel intelligence pipeline and cross-channel signal handling.