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:
- Explicit — Joel can state
KEEP/MORE/LESS/STOP/STARTdirectly. - Deterministic at runtime — active controls are injected on every gateway turn.
- 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
-
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.
- A gateway pi extension passively scans inbound operator messages for directive syntax:
-
CLI as single write authority
- All behavior directives are validated, normalized, and persisted via
joelclaw gateway behaviorcommands. - No side-channel writes from extensions directly to Redis/Typesense.
- All behavior directives are validated, normalized, and persisted via
-
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.
-
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 inturn_startfor hot updates.
-
Passive daily review is advisory-only
- A daily review function analyzes gateway sessions + OTEL and emits
good_patterns/bad_patternscandidates. - Candidates do not affect runtime behavior until promoted via explicit operator action.
- A daily review function analyzes gateway sessions + OTEL and emits
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 behaviorcommand 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.,
KEEPvsSTOPon equivalent text).
Verification
-
joelclaw gateway behavior addwrites 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_hashfor 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.
Related
- 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.