Decision History Feed UI (M71)
1. Executive Summary
| Field | Description |
|---|---|
| Feature Name | Decision History Feed UI |
| Milestone | M71 |
| Current Status | 0% → Target: 100% |
| Architectural Goal | Create a comprehensive, searchable timeline of all organizational decisions with full audit trail visibility, Socratic inquiry history, and outcome tracking. |
| System Impact | Enables organizational learning by surfacing decision patterns, recurring challenges, and reasoning evolution over time. |
| Target Users | Executives (holistic view), Planners (domain-specific view), Auditors (compliance view) |
| MVP Success Metric | Users can view decision history, filter by type/outcome, and drill down into full Socratic dialogue + scenario selection. |
2. Strategic Context
Why This Matters
The Decision History Feed transforms ChainAlign from a "point-in-time decision tool" to a Decision Intelligence Memory System. Key benefits:
- Organizational Learning: "What did we decide when we faced X before?"
- Pattern Recognition: "We keep making the same trade-off—is this intentional?"
- Audit Compliance: "Show me all regulatory compliance decisions in Q3 2024"
- Leadership Alignment: "How has our strategic priority shifted over time?"
- AI Training Data: Proprietary corpus of human reasoning for adaptive learning
Integration with SIE (M70)
The Decision History Feed is the output view of the Socratic Inquiry Engine (SIE):
- SIE generates strategic questions and captures human judgment
- Decision History Feed displays the questions asked, answers given, and decisions made
- Together, they create a closed loop: Ask → Answer → Decide → Learn → Ask Better Next Time
3. Functional Requirements
3.1. Core Views
View 1: Timeline Feed (Default)
| ID | Requirement | Details |
|---|---|---|
| FR-1.1 | Chronological Display | Display all decisions in reverse chronological order (newest first) |
| FR-1.2 | Decision Card | Each decision shown as a card with: - Decision title - Decision type (S&OP, Compliance, MRP II Override, etc.) - Initiator (user name + role) - Date/time initiated and finalized - Status (Draft, In Review, Approved, Rejected, Executed) - Outcome indicator (Success, Failed, Pending, Unknown) |
| FR-1.3 | Infinite Scroll | Load decisions in batches of 20, infinite scroll for performance |
| FR-1.4 | Collapse/Expand | Cards collapsed by default, expand to show summary preview |
View 2: Decision Detail Drill-Down
| ID | Requirement | Details |
|---|---|---|
| FR-2.1 | Socratic Questions Section | Show all Socratic questions asked (5 categories) |
| FR-2.2 | Human Judgment Display | Show user's responses to each question, with timestamp |
| FR-2.3 | Problem State Vector | Display the calculated strategic priorities, acknowledged trade-offs, unresolved uncertainties |
| FR-2.4 | Scenario Comparison | Show all scenarios generated, with the selected one highlighted |
| FR-2.5 | Trade-Off Analysis | Display "What we optimized for" vs "What we sacrificed" for selected scenario |
| FR-2.6 | Unresolved Questions | Show the 3-5 uncertainties that remained at decision time |
| FR-2.7 | Outcome Tracking | If outcome known, show: - Did decision achieve goal? (Yes/No/Partial) - Lessons learned (free text input post-decision) - Impact rating (1-5 stars) |
| FR-2.8 | Audit Trail | Full immutable log of all actions (timestamps, user IDs, changes) |
View 3: Analytics Dashboard (Phase 2)
| ID | Requirement | Details |
|---|---|---|
| FR-3.1 | Decision Velocity | Chart: Decisions per week/month |
| FR-3.2 | Outcome Distribution | Pie chart: Success/Failed/Pending decisions |
| FR-3.3 | Common Trade-Offs | Word cloud of most frequently sacrificed goals |
| FR-3.4 | Question Impact Heatmap | Which Socratic questions most often led to decision changes? |
3.2. Filtering & Search
| ID | Requirement | Details |
|---|---|---|
| FR-4.1 | Filter by Decision Type | Dropdown: S&OP Alignment, Regulatory Compliance, MRP II Override, Supply Chain Disruption, etc. |
| FR-4.2 | Filter by Status | Dropdown: Draft, In Review, Approved, Rejected, Executed |
| FR-4.3 | Filter by Outcome | Dropdown: Success, Failed, Pending, Unknown |
| FR-4.4 | Filter by Date Range | Date picker: Start date → End date |
| FR-4.5 | Filter by Initiator | Dropdown: User names (RBAC-filtered) |
| FR-4.6 | Full-Text Search | Search across decision titles, Socratic questions, human judgments, scenarios |
| FR-4.7 | Saved Filters | Allow users to save filter combinations (e.g., "My Q4 Compliance Decisions") |
3.3. RBAC (Role-Based Access Control)
| Role | Access Level |
|---|---|
| Executive | See all decisions across all domains, all users |
| Planner (Domain-Specific) | See decisions in their domain only (e.g., Supply Planner sees supply decisions) |
| Viewer | Read-only access to final decisions, no Socratic question details |
| Auditor | Full access to audit trail, cannot edit or create decisions |
4. Technical Architecture
4.1. Backend API
GraphQL Queries
query GetDecisionHistory(
$filters: DecisionHistoryFilters
$pagination: PaginationInput
$sort: SortInput
) {
decisionHistory(filters: $filters, pagination: $pagination, sort: $sort) {
decisions {
id
title
decisionType
status
outcome
initiator {
id
name
role
}
initiatedAt
finalizedAt
summary
# Collapsed by default, expanded on click:
socraticQuestions {
id
questionText
category
humanJudgment {
responseText
impactRating
answeredAt
}
}
problemStateVector {
strategicPriorities
acknowledgedTradeoffs
unresolvedUncertainties
}
scenarios {
id
title
isSelected
tradeOffs {
optimizesFor
sacrifices
}
unresolvedQuestions
}
outcomeTracking {
achievedGoal
lessonsLearned
impactRating
recordedAt
}
auditTrail {
id
action
userId
timestamp
changes
}
}
totalCount
hasNextPage
}
}
query GetDecisionDetail($decisionId: ID!) {
decision(id: $decisionId) {
# Full details for drill-down view
# (Same fields as above, but not paginated)
}
}
GraphQL Mutations
mutation RecordDecisionOutcome($input: DecisionOutcomeInput!) {
recordDecisionOutcome(input: $input) {
success
decision {
id
outcome
outcomeTracking {
achievedGoal
lessonsLearned
impactRating
}
}
}
}
mutation SaveFilterPreset($input: FilterPresetInput!) {
saveFilterPreset(input: $input) {
id
name
filters
}
}
Backend Service
DecisionHistoryService.js (new service)
Methods:
getDecisionHistory(filters, pagination, sort, tenantId, userId, userRole)- Main query with RBAC filteringgetDecisionDetail(decisionId, tenantId, userId, userRole)- Full decision detailsrecordOutcome(decisionId, outcomeData, userId)- Post-decision outcome trackingsaveFilterPreset(userId, presetName, filters)- Save user filter preferencesgetFilterPresets(userId)- Load user's saved filters
RBAC Logic:
// In getDecisionHistory()
if (userRole === 'Planner') {
filters.domain = getUserDomain(userId); // Restrict to user's domain
}
if (userRole === 'Viewer') {
// Exclude Socratic questions and human judgments
excludeFields = ['socraticQuestions', 'humanJudgments'];
}
4.2. Database Schema
4.2.1. decisions Table (Existing, Enhanced)
-- Extend existing decisions table
ALTER TABLE decisions ADD COLUMN IF NOT EXISTS outcome VARCHAR(50) CHECK (outcome IN ('success', 'failed', 'pending', 'unknown'));
ALTER TABLE decisions ADD COLUMN IF NOT EXISTS lessons_learned TEXT;
ALTER TABLE decisions ADD COLUMN IF NOT EXISTS impact_rating INT CHECK (impact_rating BETWEEN 1 AND 5);
ALTER TABLE decisions ADD COLUMN IF NOT EXISTS outcome_recorded_at TIMESTAMP;
ALTER TABLE decisions ADD COLUMN IF NOT EXISTS outcome_recorded_by UUID REFERENCES users(id);
4.2.2. decision_filter_presets Table (New)
CREATE TABLE decision_filter_presets (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id),
tenant_id UUID NOT NULL REFERENCES tenants(id),
preset_name VARCHAR(255) NOT NULL,
filters JSONB NOT NULL, -- Stored filter configuration
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(user_id, preset_name)
);
CREATE INDEX idx_decision_filter_presets_user ON decision_filter_presets(user_id);
4.3. Frontend Components
Component Hierarchy
DecisionHistoryPage (Container)
├── DecisionHistoryFilters (Sidebar)
│ ├── DecisionTypeFilter (Dropdown)
│ ├── StatusFilter (Dropdown)
│ ├── OutcomeFilter (Dropdown)
│ ├── DateRangeFilter (Date Picker)
│ ├── InitiatorFilter (Dropdown)
│ ├── SearchBar (Full-text search)
│ └── SavedFilters (Preset manager)
│
├── DecisionTimeline (Main View)
│ ├── DecisionCard (Collapsed state)
│ │ ├── DecisionCardHeader (Title, Type, Status, Date)
│ │ ├── DecisionCardSummary (Preview)
│ │ └── ExpandButton (Click to drill down)
│ │
│ └── DecisionDetailView (Expanded state)
│ ├── SocraticQuestionsSection
│ │ └── QuestionResponseCard (x5 categories)
│ ├── ProblemStateVectorDisplay
│ ├── ScenarioComparisonTable
│ ├── TradeOffAnalysis
│ ├── UnresolvedQuestionsPanel
│ ├── OutcomeTrackingForm (if not recorded)
│ └── AuditTrailTable
│
└── AnalyticsDashboard (Phase 2)
├── DecisionVelocityChart
├── OutcomeDistributionChart
├── CommonTradeOffsWordCloud
└── QuestionImpactHeatmap
5. UI/UX Requirements
5.1. Decision Card (Collapsed State)
Visual Design:
- Card with subtle shadow, rounded corners
- Left border color-coded by decision type (e.g., blue = S&OP, red = Compliance)
- Status badge (green = Approved, yellow = In Review, gray = Draft)
- Outcome icon (✅ Success, ❌ Failed, ⏳ Pending, ❓ Unknown)
Information Displayed:
┌─────────────────────────────────────────────────────┐
│ [S&OP] PFAS Compliance Response Plan [✅] │ ← Title + Outcome
│ Initiated by: John Smith (Supply Planner) │ ← Initiator
│ Date: 2024-11-10 | Status: Approved │ ← Date + Status
│ ───────────────────────────────────────────────── │
│ Summary: Evaluated 3 scenarios for PFAS ban... │ ← Summary (truncated)
│ [Expand Details ▼] │ ← Expand button
└─────────────────────────────────────────────────────┘
5.2. Decision Detail View (Expanded State)
Tabbed Interface:
- Overview - Summary, initiator, dates, status
- Socratic Dialogue - Questions asked, user responses
- Scenarios - All scenarios with trade-off comparison
- Outcome - Post-decision tracking (if recorded)
- Audit Trail - Immutable log
Socratic Dialogue Tab Example:
┌─────────────────────────────────────────────────────┐
│ QUESTIONS CONSIDERED (5) │
│ ───────────────────────────────────────────────── │
│ 1. Assumptions Challenge │
│ Q: "What assumptions are we making about...?" │
│ A: [User's response text] │
│ Impact Rating: ⭐⭐⭐⭐⭐ (Highly impactful) │
│ Context: [Board Memo Q3 2024 snippet] │
│ ───────────────────────────────────────────────── │
│ 2. Perspectives │
│ Q: "Whose voice haven't we considered?" │
│ A: [User's response text] │
│ Impact Rating: ⭐⭐⭐ (Moderately impactful) │
│ ───────────────────────────────────────────────── │
│ ... (3 more questions) │
└─────────────────────────────────────────────────────┘
Scenarios Tab Example:
┌─────────────────────────────────────────────────────┐
│ SCENARIOS EVALUATED (3) │
│ ───────────────────────────────────────────────── │
│ ✅ [SELECTED] Scenario A: Dual-Source Strategy │
│ Optimizes for: Market access, long-term margin │
│ Sacrifices: Short-term cost increase │
│ Unresolved: Metco qualification timeline │
│ ───────────────────────────────────────────────── │
│ ❌ Scenario B: Status Quo with Spot Buys │
│ Optimizes for: Minimal disruption │
│ Sacrifices: Regulatory compliance risk │
│ ───────────────────────────────────────────────── │
│ ❌ Scenario C: Full Exit from PFAS │
│ Optimizes for: Compliance certainty │
│ Sacrifices: Customer relationships, revenue │
└─────────────────────────────────────────────────────┘
6. Performance Requirements
| Metric | Target | Rationale |
|---|---|---|
| Initial Page Load | < 2 seconds | Timeline feed must load quickly |
| Filter Application | < 500ms | Instant feedback on filter changes |
| Card Expansion | < 300ms | Smooth drill-down experience |
| Full-Text Search | < 1 second | Acceptable for complex search |
| Infinite Scroll (Next Batch) | < 1 second | Load 20 more decisions |
| Database Query (Paginated) | < 800ms | Indexed queries on decisions table |
Optimization Strategies:
- Use PostgreSQL indexes on
decision_type,status,outcome,initiatedAt,tenant_id - Cache filter presets in Redis
- Use GraphQL DataLoader to batch fetch related data (users, scenarios, questions)
- Frontend: React.memo for DecisionCard components to prevent unnecessary re-renders
7. Security & Compliance
7.1. RBAC Enforcement
Backend (GraphQL Resolver Level):
// In decisionHistoryResolvers.js
Query: {
decisionHistory: async (parent, { filters, pagination }, context) => {
const { user, tenant } = context;
// Enforce role-based filtering
if (user.role === 'Planner') {
filters.domain = user.domain; // Only show user's domain decisions
}
if (user.role === 'Viewer') {
// Exclude sensitive fields
const decisions = await DecisionHistoryService.getDecisionHistory(filters, pagination, tenant.id, user.id, user.role);
return decisions.map(d => ({
...d,
socraticQuestions: null, // Hide from viewers
humanJudgments: null
}));
}
return DecisionHistoryService.getDecisionHistory(filters, pagination, tenant.id, user.id, user.role);
}
}
7.2. Audit Trail Immutability
- All views are read-only (except outcome recording)
- No DELETE or UPDATE operations on historical decisions
- Soft deletes only (add
deleted_atcolumn) - Cryptographic hash verification on audit trail records
7.3. Data Retention
- Decision history retained for 7 years (regulatory compliance)
- Audit trails retained indefinitely
- Outcome tracking optional but encouraged
8. Testing Requirements
8.1. Unit Tests (80% coverage)
DecisionHistoryService.getDecisionHistory()with various filters- RBAC filtering logic (Executive vs Planner vs Viewer)
- Filter preset save/load functionality
- Outcome recording validation
8.2. Integration Tests
- E2E: Create decision → Complete Socratic dialogue → Record outcome → View in history feed
- Filter by decision type, status, outcome, date range
- Search across decision titles and human judgments
- Pagination (fetch 60 decisions in 3 batches of 20)
8.3. Performance Tests
- Load test: 1,000 decisions in database, fetch first 20 in < 2s
- Filter test: Apply 3 filters, results in < 500ms
- Search test: Full-text search across 10,000 decisions in < 1s
9. Migration Strategy
9.1. Existing Data Backfill
If decisions already exist without Socratic questions:
- Display legacy decisions with "Pre-Socratic Era" badge
- Show available data only (no questions/judgments section)
- Allow outcome recording on legacy decisions
9.2. Phased Rollout
Week 1: Timeline feed view (read-only) Week 2: Decision detail drill-down Week 3: Filters and search Week 4: Outcome recording Phase 2: Analytics dashboard
10. Success Criteria
M71 is complete when: ✅ Users can view chronological decision history ✅ Filters (type, status, outcome, date, initiator) functional ✅ Full-text search operational ✅ Decision detail drill-down shows Socratic questions, scenarios, trade-offs ✅ Outcome recording functional ✅ RBAC correctly restricts access by role ✅ Performance targets met (< 2s page load) ✅ Unit test coverage ≥ 80% ✅ Integration tests passing
11. Dependencies
| Dependency | Status | Required For |
|---|---|---|
| M70 (Socratic Inquiry Engine) | ✅ FSD Complete, Implementation Pending | Socratic questions data |
| Decisions Table | ✅ Exists, needs enhancement | Base data structure |
| Audit Trail System | ✅ Operational | Immutable logging |
| GraphQL API | ✅ Operational | Query layer |
12. Future Enhancements (Post-M71)
Phase 2 Features:
- Analytics Dashboard: Decision velocity, outcome distribution, common trade-offs
- Collaborative Annotations: Users can comment on past decisions
- Decision Templates: "Use this decision as a template for new one"
- AI-Powered Insights: "You're facing a similar decision to CHA-123 from Q2 2024"
- Export to PDF: Generate executive summary report of decision history
Document Status: Complete FSD Last Updated: 2025-11-14 Milestone: M71 - Decision History Feed UI Estimated Implementation: 2 weeks (single frontend + backend developer)