Why guidelines alone are not enough
From Guidelines to Executable Rules — How architectural intent becomes enforceable in practice.
Why guidelines alone are not enough
Most data teams have guidelines. They live in:
- Wikis
- Confluence pages
- Readme files
- Slide decks
They are usually well-intended, carefully written, and widely ignored. Not because people disagree with them — but because guidelines that rely on memory and discipline do not scale , especially under delivery pressure.
MDDE made a deliberate shift:
If a guideline matters, it must be executable.
This article explains what that means in practice.

The problem with “best practices”
Best practices tend to fail in predictable ways:
- They are applied inconsistently
- They depend on code reviews
- They are interpreted differently by different people
- They erode over time
The result is architectural drift — not because anyone chose it, but because nothing actively prevented it.
Executable guidelines change that dynamic.
What is an executable guideline?
An executable guideline is:
- Derived from an architectural decision
- Expressed as a concrete rule
- Automatically evaluated
- Produces observable outcomes
It does not replace human judgment.
It encodes the minimum acceptable standard.
In MDDE, executable guidelines sit directly between architecture and implementation.
From ADR → Guideline → Rule
The flow looks like this:
Architectural Decision (ADR)
→ defines what must hold
Guideline
→ describes how this shows up in practice
Executable Rule
→ enforces it automatically
Let’s make this concrete.
Example 1 — “No SELECT * in production queries”
Architectural intent
SELECT * hides schema changes, breaks determinism, and complicates validation.
Guideline
Production queries must explicitly list selected columns.
Executable rule
class NoSelectStarRule:
def validate(self, ast):
if ast.select_clause.contains_star():
return "SELECT * is not allowed in production queries"
Outcome
- No discussion in reviews
- No accidental violations
- Clear, immediate feedback
Example 2 — “Joins must be explicit and qualified”
Architectural intent
Implicit joins hide semantics and make lineage unclear.
Guideline
All joins must specify join type and condition explicitly.
Executable rule
class RequireExplicitJoinsRule:
def validate(self, ast):
for join in ast.joins:
if not join.is_explicit():
return "Implicit joins are not allowed"
Outcome
- Predictable SQL structure
- Clear join semantics
- Better lineage extraction
Example 3 — “Filters must be deterministic”
Architectural intent
Non-deterministic filters break regression testing and reproducibility.
Guideline
Filters must not depend on implicit system state.
Executable rule
class DeterministicFilterRule:
def validate(self, ast):
if ast.filters.contains_nondeterminism():
return "Non-deterministic filters detected"
Outcome
- Safer migration
- Reliable comparison
- Fewer surprises in validation
Rule engines change how teams work
Once rules exist, something subtle but important happens.
Reviews shift from:
“Did you remember to…?”
To:
“Is this rule still the right rule?”
Architecture moves upstream , where it belongs.
Developers stop debating whether something is allowed and start discussing why the rule exists.
Rules don’t replace judgment — they encode it
Executable guidelines are sometimes perceived as rigid.
In practice, they do the opposite:
- They remove low-value decisions
- They reduce review fatigue
- They surface exceptions explicitly
When a rule needs to be broken, it becomes:
- A conscious choice
- A documented exception
- Often a new ADR
This creates a healthy feedback loop between practice and architecture.
Making rules observable
In MDDE, rules never fail silently.
Each rule emits:
- Which rule was applied
- Whether it passed or failed
-
Why
result = rule_engine.validate(ast)
emit_diagnostics(
rules_applied=result.rules,
violations=result.violations
)
Rules become part of:
- Generated documentation
- CI feedback
- Migration diagnostics
Architecture becomes visible in motion.
Start small
You don’t need dozens of rules.
Start with:
- One guideline people keep forgetting
- One mistake that keeps recurring
- One assumption that must never be violated
Encode it once.
Let the system enforce it forever.
What’s next
In the next practical articles, I’ll cover:
- A minimal MDDE project structure
- How rules integrate with SQL generation
- Validation pipelines you can reuse
- How ADRs, rules, and generators evolve together
All focused on turning architectural intent into something executable, observable, and durable.