ADRs
ADR-0030: Directive versioning strategy
Accepted — immutable directive_versions with active_version_id pointer; one config per agent; SHA-256 content_hash; 32KB cap; org RLS.
ADR-0030: Directive versioning strategy
- Status: Accepted (schema in 2.3.1; read path in 2.3.2)
- Date: 2026-07-23
- Authors: IBEX Harness team
- Milestone: 2.3.1 Directive migrations
Context
An agent directive is the system-level instruction IBEX injects into every LLM request for that agent. Operators need safe updates with rollback and an audit trail. Mutable in-place edits lose history and complicate cache invalidation on the proxy hot path.
Phase 2 needs a minimal agent-scoped schema. A fuller marketplace-oriented model (named org-level directives, installs, tags) remains documented in DATABASE_SCHEMA.md but is out of scope until later phases.
Decision
- Immutable versions:
directive_versionsrows are append-only. Content is never updated after insert. Rollback = repointdirectives.active_version_idto a prior version. - One config per agent:
UNIQUE(agent_id)ondirectives. Each agent has at most one directive configuration row; version history hangs off that row. - Injection mode:
injection_modeenum (system_first,system_append,user_prepend) stored ondirectives. Behavior is implemented in 2.3.3. - Content integrity:
content_hashis SHA-256 ofcontent(application-computed). CHECKs enforce non-empty content andoctet_length(content) <= 32768(32KB byte cap). - Tenant isolation: Both tables have
org_id,ENABLE+FORCE ROW LEVEL SECURITY, NULLIF-safe org setting, and service-account bypass viaibex_core.rls_org_visible— matching the agents pattern. Ownership is structural via composite FKs(agent_id, org_id)and(directive_id, org_id), plus a trigger ensuringactive_version_idbelongs to the same directive and org (single-column FK withON DELETE SET NULLfor cascade-safe cleanup). - Append-only versions:
ibex_apphas onlySELECT, INSERTondirective_versions(noUPDATE/DELETE); a BEFORE UPDATE trigger rejects mutations. ParentON DELETE CASCADEcleanup runs as table owner. - Deferred circular FK:
active_version_idFK is addedNOT VALIDthenVALIDATEafterdirective_versionsexists. - Proxy read path: Deferred to 2.3.2. This ADR covers persistence only.
Consequences
- Migration
000009_create_directivesapplies the Phase 2 subset underibex_core. - Cache keys in 2.3.2 can key on
(org_id, agent_id, active_version_id)/content_hashwithout worrying about silent content mutation. - Marketplace / multi-directive-per-org features require a later expand migration; they must not break the one-config-per-agent contract without an explicit ADR.
Alternatives considered
- Mutable single-row directive — simpler schema; no rollback/audit. Rejected.
- Git-like parent_version_id DAG — useful for forks; unnecessary for Phase 2 linear history. Deferred with marketplace schema.
- Org-level named directives with agent installs — matches long-term
DATABASE_SCHEMA.md; too large for Goal 2.3. Deferred.
Was this page helpful?
Edit on GitHub
Last updated on