Skip to content

Decision Graph

The .trurlic/ directory is the on-disk representation of your architecture. It is meant to be committed to git — it is your architecture’s source of truth.

.trurlic/
project.toml Project metadata and format version
graph.toml Compiled edge index (derived, rebuildable)
components/
auth.toml Component definition
database.toml
rate-limiter.toml
decisions/
auth-jwt-with-dpop-binding.toml
database-postgresql-15.toml
rate-limiter-redis-sliding-window.toml
patterns/
state-in-redis.toml
.state/ Scratch (gitignored, not versioned)
tmp/ Temp files for atomic writes
.trurlic/project.toml
trurlic_version = "0.4.0"
[project]
name = "my-project"
description = "A brief description of the project"
.trurlic/components/auth.toml
[component]
name = "auth"
description = "Authentication and token management"

Component names must be valid kebab-case. The filename must match the name field.

.trurlic/decisions/auth-jwt-with-dpop-binding.toml
[decision]
component = "auth"
choice = "JWT with DPoP binding"
reason = "Stateless, no session store needed"
alternatives = [
"Session cookies — rejected: requires server-side state",
"Opaque tokens — rejected: requires a token introspection endpoint"
]
tags = ["security", "authentication"]
attribution = "user"
created = 2025-06-10T14:30:00Z
[[decision.code_refs]]
file = "src/auth/token.rs"
symbol = "issue_token"

Project-wide decisions (rules) use component = "project". These appear in every component’s context brief as inviolable constraints.

FieldRequiredDescription
componentYesOwning component name, or "project" for rules
choiceYesConcise decision title
reasonYesReasoning behind the decision
alternativesNoRejected options with reasons
tagsNoCategorical tags for filtering and search
attributionYes"user" (human authored) or "agent" (autonomous)
createdYesUTC timestamp in RFC 3339 format
code_refsNo{ file, symbol? } locations where the decision manifests — powers query file / get_decisions_for_file
historyNoPrior { choice, reason, changed_at } versions, appended on each revise
.trurlic/patterns/state-in-redis.toml
[pattern]
name = "state-in-redis"
description = "Shared Redis pool via app state, no per-component connections"
decisions = ["auth-jwt-with-dpop-binding", "rate-limiter-redis-sliding-window"]
components = ["auth", "rate-limiter"]
tags = ["infrastructure", "state"]

Patterns require at least two source decisions. Components are inferred from decisions if omitted.

graph.toml is a compiled edge index — a derived file rebuilt deterministically from node files. It maps every node to its edges and stores BLAKE3 content hashes for integrity verification.

Do not hand-edit graph.toml. It is rebuilt on every write and on trurlic check --rebuild. Edit node files instead, then run trurlic check to reconcile.

EdgeMeaning
BelongsToDecision → Component
ConnectsToComponent → Component (directional data/control flow)
DependsOnDecision → Decision (logical dependency)
ConstrainsDecision → Decision (restriction)
SupersedesDecision → Decision (replacement)

.trurlic/ is designed for version control. Commit the entire directory — except .trurlic/.state/, which trurlic init adds to .gitignore automatically. The .state/ directory holds only temp files for atomic writes, local to each developer’s machine.

Merge conflicts in TOML files resolve naturally — if two branches add different decisions, both files appear after merge. Run trurlic check --rebuild after merging to reconcile the index.