Command Palette
Search for a command to run...
Decision Relationships
Core ConceptRelationships are the edges in your decision graph. They show how decisions connect.
The Six Relationship Types
Arbtr supports six relationship types. Each has a specific semantic meaning.
| Type | Meaning | Example |
|---|---|---|
depends_on | B requires A to be true | "Use TypeScript" depends_on "Use Node.js" |
conflicts_with | A and B are mutually exclusive | "Use MySQL" conflicts_with "Use PostgreSQL" |
supersedes | B replaces A | "Use React 18" supersedes "Use React 17" |
enables | A makes B possible | "Add auth" enables "Add user profiles" |
constrains | A limits options for B | "HIPAA compliance" constrains "Data storage" |
derived_from | B is based on A | "API design" derived_from "REST vs GraphQL" |
depends_on vs enables
These two relationships are often confused. Here's the key difference:
depends_onTechnical requirement. The dependent decision literally cannot work without the parent.
"React Query depends_on React" — You can't use React Query without React installed.
enablesStrategic enablement. The first decision opens up possibilities for the second.
"Auth system enables User profiles" — Auth makes profiles possible, but profiles aren't technically dependent on auth.
depends_on. If no (but it wouldn't make strategic sense), use enables.When to Use Each Type
depends_on
Use when one decision cannot exist without another. The dependent decision assumes the parent decision is true.
Good examples:
- • "Supabase" depends_on "PostgreSQL" (Supabase requires Postgres)
- • "React Query" depends_on "React" (library requires framework)
- • "Deploy to Vercel" depends_on "Next.js" (platform requires framework)
conflicts_with
Use when two decisions are mutually exclusive. Approving one effectively rejects the other.
Good examples:
- • "Use MySQL" conflicts_with "Use PostgreSQL" (can't use both as primary)
- • "Monolith" conflicts_with "Microservices" (architectural choice)
- • "REST API" conflicts_with "GraphQL API" (if only one allowed)
supersedes
Use when one decision replaces another. The old decision is effectively deprecated.
Good examples:
- • "Use React 18" supersedes "Use React 17" (version upgrade)
- • "New auth system" supersedes "Legacy auth" (replacement)
- • "Zustand" supersedes "Redux" (library migration)
enables
Use when one decision makes another possible. The enabled decision couldn't happen without the enabler.
Good examples:
- • "Add auth system" enables "User profiles" (can't have profiles without auth)
- • "Internationalization" enables "Launch in EU" (requirement for expansion)
- • "API versioning" enables "Breaking changes safely" (process enablement)
constrains
Use when one decision limits the options for another. The constrained decision must work within boundaries set by the constraint.
Good examples:
- • "HIPAA compliance" constrains "Data storage choices"
- • "Budget: $5k/month" constrains "Infrastructure decisions"
- • "Must support IE11" constrains "Frontend framework choice"
derived_from
Use when one decision is loosely related to another. This is the default for general connections.
Good examples:
- • "API design guidelines" derived_from "REST vs GraphQL decision"
- • "Component library choice" derived_from "Design system decision"
- • "Testing strategy" derived_from "Code quality standards"
Visual Representation
In the decision graph, relationships are displayed as colored lines connecting nodes. Each relationship type has a distinct color for easy identification.
Committed relationships in the main graph. These are real, established connections.
Proposed relationships in a branch. These are hypothetical and not yet merged.
Technical Details
Directionality
Relationships are stored as directed edges from source_id to target_id. The direction semantics differ by type:
- •
depends_on: Target depends on Source (A → B means B depends on A) - •
supersedes: Source replaces Target (A → B means A supersedes B) - •
conflicts_with: Symmetric — if A conflicts with B, B conflicts with A (only store once) - •
enables: Source enables Target (A → B means A enables B) - •
constrains: Source constrains Target (A → B means A constrains B) - •
derived_from: Source is based on Target (A → B means A is derived from B)
Cascade Behavior
When a decision is deleted, all its relationships are also deleted (ON DELETE CASCADE). Archiving preserves relationships but hides them from the default graph view.
Multiple Relationships
You can have multiple relationships between the same two decisions. For example, A can both depend_on and constrains B. Each relationship is stored as a separate row with its own note field.
Data Model
Database table: decision_relationships
type RelationshipType =
| "depends_on" // Target requires source to be true
| "supersedes" // Source replaces target (target is deprecated)
| "conflicts_with" // Mutually exclusive (symmetric)
| "enables" // Source makes target possible
| "constrains" // Source limits options for target
| "derived_from" // Source is based on or related to target
interface DecisionRelationship {
id: string
source_id: string // Decision UUID (from)
target_id: string // Decision UUID (to)
type: RelationshipType
note?: string // Optional annotation (shown on edge label)
created_by: string // User ID who created this relationship
created_at: Date
team_id: string // For RLS
// Scenario support
scenario_id?: string // NULL = live, UUID = ghost in scenario
}
// Graph query returns relationships with decision details
interface RelationshipWithDecisions extends DecisionRelationship {
source: { id: string; title: string; slug: string; status: DecisionStatus }
target: { id: string; title: string; slug: string; status: DecisionStatus }
}decision_audit_logwith event types relationship.dependency_added, relationship.dependency_removed, etc.