Understand how ideas evolved over time to find old solutions for new problems and avoid repeating past failures
Ideas have history. Understanding why we arrived at current approaches - and what was tried before - prevents repeating failures and rediscovers abandoned solutions.
Core principle: Before judging current approaches or proposing "new" ones, trace their lineage.
Trace before:
Red flags triggering lineage tracing:
Search for when/why current approach was chosen:
docs/decisions/, docs/adr/, .decisions/, architecture decision records)git log --all --full-history -- path/to/file)Document:
## Lineage: [Current Approach]
**When adopted:** [Date/commit]
**Why adopted:** [Original problem it solved]
**What it replaced:** [Previous approach]
**Why replaced:** [What was wrong with old approach]
**Context that drove change:** [External factors, new requirements]
When someone says "we tried X and it didn't work":
Don't assume: X is fundamentally flawed Instead trace:
Document:
## Failed Attempt: [Approach]
**When attempted:** [Timeframe]
**Why attempted:** [Original motivation]
**What failed:** [Specific failure mode]
**Why it failed:** [Root cause, not symptoms]
**Context at time:** [Constraints that existed then]
**Context now:** [What's different today]
**Worth reconsidering?:** [Yes/No + reasoning]
When evaluating "new" approaches:
Common revival patterns:
Ask: "What did we learn from the previous incarnation?"
When major architectural changes occurred:
Map the transition:
## Paradigm Shift: From [Old] to [New]
**Pre-shift thinking:** [How we thought about problem]
**Catalyst:** [What triggered the shift]
**Post-shift thinking:** [How we think now]
**What was gained:** [New capabilities]
**What was lost:** [Old capabilities sacrificed]
**Lessons preserved:** [What we kept from old paradigm]
**Lessons forgotten:** [What we might need to relearn]
Where to look for lineage:
docs/decisions/, docs/adr/, .adr/, or search for "ADR", "decision record")git log --grep="keyword", git blame)git log -- docs/)Search patterns:
# Find when approach was introduced
git log --all --grep="introduce.*caching"
# Find what file replaced
git log --diff-filter=D --summary | grep pattern
# Find discussion of abandoned approach
git log --all --grep="remove.*websocket"
All of these mean: STOP. Trace the lineage first.
You CAN ignore lineage when:
Context fundamentally changed
We learned critical lessons
Original reasoning was flawed
But document WHY you're overriding: Future you needs to know this was deliberate, not ignorant.
When proposing changes, include lineage:
## Proposal: Switch from [Old] to [New]
### Current Approach Lineage
- **Adopted:** [When/why]
- **Replaced:** [What it replaced]
- **Worked because:** [Its strengths]
- **Struggling because:** [Current problems]
### Previous Attempts at [New]
- **Attempted:** [When, if ever]
- **Failed because:** [Why it didn't work then]
- **Context change:** [What's different now]
### Decision
[Proceed/Defer/Abandon] because [reasoning with historical context]
"We used XML before JSON. XML died because verbosity hurt developer experience. But XML namespaces solved a real problem. If we hit namespace conflicts in JSON, we should study how XML solved it, not reinvent."
"REST is old, let's use GraphQL." (Ignores: Why did REST win over SOAP? What problems does it solve well? Are those problems gone?)
"We tried client-side routing in 2010, abandoned it due to poor browser support. Now that support is universal and we have better tools, worth reconsidering with lessons learned."