Skip to content

ADR-070: Polarity Axis Analysis for Bidirectional Semantic Dimensions

Status: Accepted Date: 2025-11-29 Implementation Date: 2025-11-30 Deciders: System Architect Related ADRs: - ADR-044: Probabilistic Truth Convergence (grounding calculation) - ADR-045: Unified Embedding Generation - ADR-048: GraphQueryFacade (namespace safety) - ADR-058: Polarity Axis Triangulation for Grounding (explains relationship to this ADR) - ADR-068: Unified Embedding Regeneration

Overview

Imagine asking your knowledge graph "Where does 'Agile' fall on the spectrum between modern and traditional approaches?" Your graph might have hundreds of concepts related to organizational practices, but there's no explicit MODERN or TRADITIONAL relationship type labeling each one. How do you answer this question? Traditional graph traversal won't help—there are no edges to follow. Full-text search won't help either—the word "modern" might not appear in the concept description.

This is where semantic dimensions come in. Think of them as invisible spectrums that organize your concepts even when explicit relationships don't capture them. Your knowledge base might contain dozens of concepts that naturally vary along a modern-versus-traditional dimension, not because someone tagged them that way, but because their semantic embeddings reveal that pattern. "Agile" sits closer to "modern operating models" in vector space, while "waterfall methodology" sits closer to "traditional hierarchies."

The challenge is making these implicit dimensions explicit and measurable. You can't just compare embeddings pairwise—that doesn't tell you where a concept falls on a spectrum, only that two concepts are similar. What you need is a ruler: take two opposing concepts (like "modern operating models" and "traditional hierarchies"), treat them as opposite ends of an axis, and project other concepts onto that axis to see where they land. Maybe "Agile" projects at +72% (strongly modern), "DevOps" at +58% (moderately modern), "matrix organization" at +8% (nearly neutral), and "command-and-control" at -81% (strongly traditional).

This ADR implements polarity axis analysis as a query capability, building on the same mathematical technique from ADR-058 but applying it to concepts instead of relationships. The key difference: ADR-058 uses polarity axes to calculate how reliable a concept is (grounding), while this ADR uses them to explore where concepts fall on semantic spectrums (positioning). Both use vector projection, but they answer different questions: "how grounded is this?" versus "where does this fall on this dimension?" The result is a new way to navigate your knowledge graph—not by following explicit edges, but by discovering the emergent conceptual dimensions that organize your ideas.


Context

The knowledge graph captures concepts and relationships with semantic embeddings, but lacks tools to explore bidirectional semantic dimensions - conceptual spectrums along which concepts vary. While ADR-058 introduced polarity axes for calculating grounding strength by projecting relationship edges onto axes, this ADR explores a complementary capability: using polarity axes to discover and navigate semantic dimensions by projecting concept embeddings themselves.

Understanding the Relationship to ADR-058

ADR-058 uses polarity axes formed by opposing relationship types (SUPPORTS/CONTRADICTS, VALIDATES/REFUTES) to calculate how grounded a concept is based on its incoming relationship edges. This ADR uses polarity axes formed by opposing concepts (Modern Operating Model ↔ Traditional Operating Models) to determine where concepts fall on semantic spectrums. Both use the same mathematical technique (vector projection onto an axis) but apply it to different problems: ADR-058 answers "how reliable is this concept?" while this ADR answers "where does this concept fall on this conceptual spectrum?"

Problem Statement

Users need capabilities beyond relationship traversal and grounding assessment. They need to understand the semantic landscape of their knowledge - discovering implicit dimensions that organize concepts even when explicit relationships don't capture them. For example, a knowledge base about organizational transformation might contain dozens of concepts that vary along a "modern versus traditional" spectrum, but this dimension emerges from semantic similarities rather than explicit MODERN_VS_TRADITIONAL relationship edges.

Consider the question "Where does 'Agile' fall on the spectrum between modern and traditional approaches?" The graph might contain PREVENTS relationships (Legacy Systems -PREVENTS-> Digital Transformation) that hint at this dimension, but there's no direct way to position concepts along it quantitatively. Similarly, users might want to find "middle ground" or "synthesis" concepts that balance two opposing poles, but relationship traversal alone can't identify these neutral positions.

The grounding scores calculated by ADR-058 provide a clue - concepts with positive grounding tend to be beneficial while negative grounding suggests problems - but grounding is a measure of reliability, not semantic position. A highly reliable concept (strong grounding) might still sit anywhere on a modern-traditional spectrum. What's missing is the ability to project concepts onto semantic dimensions and measure their position explicitly

Research Foundation

Experimental validation (experiment/semantic-path-gradients branch): - Polarity axis projection using vector mathematics works with real embeddings - Grounding correlates strongly with axis position (r > 0.8 for PREVENTS relationships) - High curvature (sharp semantic pivots) is normal for technical concepts - PREVENTS/CONTRADICTS relationships create natural bidirectional axes

Large Concept Models (Meta, Dec 2024): - Operating in sentence-embedding space (not tokens) enables semantic reasoning - Gradient-based analysis reveals directional semantic flow - Multi-hop reasoning paths have measurable coherence

Key Finding: Projecting concepts onto polarity axes formed by opposing concepts (positive ↔ negative poles) reveals: - Position: Scalar location on spectrum (-1 to +1, 0 = midpoint) - Distance: Orthogonality (concepts far from axis are multi-dimensional) - Direction: Which pole the concept aligns with

Decision

Implement polarity axis analysis as a direct query pattern with on-demand calculation, similar to the /query/connect endpoint. This approach provides flexibility for user-defined axes while maintaining fast response times (~2-3 seconds).

Architecture Pattern - Direct Query (Not Job Queue):

After initial implementation and testing, we discovered that polarity axis analysis executes quickly enough (~2.36 seconds for 20 concepts) to use the direct query pattern instead of background workers. This decision was made after observing: - Fast execution time with existing embeddings (no external API calls) - Read-only operations with no side effects - Similar performance profile to /query/connect endpoint - User preference for immediate results over job tracking overhead

The /query/connect endpoint serves as the architectural precedent - it performs similar embedding-heavy computations (multi-hop graph traversal with semantic matching) and returns results directly within 2-5 seconds. Polarity axis analysis fits the same performance envelope, making background workers unnecessary complexity.

Future Consideration: For large-scale analyses (100+ candidates, multiple concurrent requests), a "large polarity" job-based execution pattern could be added similar to how we might add "large connect" for expensive graph traversals. The current direct pattern handles typical use cases efficiently.

Primary API Endpoint:

POST /query/polarity-axis analyzes a specific axis given two opposing concept IDs, returning positions of candidate concepts along that spectrum. Request includes: - positive_pole_id: Concept ID for positive pole - negative_pole_id: Concept ID for negative pole - candidate_ids (optional): Specific concepts to project - auto_discover (default: true): Automatically find related concepts if no candidates specified - max_candidates (default: 20): Limit for auto-discovery - max_hops (default: 2): Graph traversal depth for discovery

Response includes axis metadata, concept projections with positions/directions/grounding, statistical summary, and grounding correlation analysis.

Reuse of existing infrastructure keeps implementation focused. The grounding correlation validation uses AGEClient.calculate_grounding_strength_semantic() (from ADR-058) to measure whether axes represent value polarities. Structured JSON responses follow established patterns from other query endpoints. Auto-discovery uses graph traversal patterns similar to related concepts queries.

Performance characteristics: Execution time ~2-3 seconds for 20 candidates with 768-dimensional embeddings. Fast enough for direct query pattern without job queue overhead. Future optimization through global embedding cache (if needed) would benefit all embedding-dependent queries holistically.

Consequences

Positive

New semantic exploration capability: - Users can navigate conceptual dimensions, not just relationship graphs - "Show me where 'Agile' falls on the Modern ↔ Traditional spectrum" - "Find neutral concepts between 'Centralized' and 'Decentralized'"

Grounding correlation makes sense: - Positive grounding → aligns with positive pole - Negative grounding → aligns with negative pole - Grounding values now have spatial meaning

Missing link detection: - Concepts with high axis distance are orthogonal (different dimension) - Suggests they might bridge gaps or add new dimensions

Learning path optimization: - Order concepts along axis for pedagogical progression - Smooth semantic transitions (low curvature paths)

Relationship validation: - PREVENTS relationships should create strong axes - Weak axes suggest relationship might be incorrect or multi-dimensional

Negative

Performance cost: - Embedding operations are expensive (768-dimensional dot products across potentially hundreds of concepts) - Each axis calculation requires fetching embeddings and computing projections for all candidates - Background workers mitigate API blocking but don't eliminate computation cost - Note: A future global caching system for embedding-dependent queries would address this across all query types

Interpretation complexity: - Position values (-1 to +1) require explanation for users unfamiliar with vector projection - Axis distance needs context (what constitutes "high" orthogonality varies by domain) - Direction classification thresholds (±0.3) are somewhat arbitrary - Mitigated by: Clear documentation, diverse examples, visual aids in interfaces

API surface growth: - Adds 3 new endpoints to query layer - Introduces new worker type (PolarityAxisWorker) - Increases cognitive load for API users learning the system - Mitigated by: Clear separation from existing endpoints, consistent patterns with other query types

Neutral

Not a replacement for relationship traversal: - Polarity axes complement (don't replace) graph navigation - Relationships capture explicit knowledge, axes capture implicit dimensions

Dimensionality reduction: - Projects multi-dimensional embeddings onto 1D axis - Loses nuance, but gains interpretability - Future: Could extend to 2D projections (two orthogonal axes)

Example Use Cases Across Domains

To illustrate the versatility of polarity axis analysis, consider how it would apply to different knowledge domains:

Software Architecture

Axis: Monolith ↔ Microservices

Monolith ●────────────────────────────────────● Microservices
         │                                    │
    Grounding: -0.15                    Grounding: +0.08
    (problematic)                       (beneficial)

Projected Concepts:
  Modular Monolith        (+0.35) - Neutral/Synthesis
  Service-Oriented Arch   (+0.72) - Toward Microservices
  Layered Architecture    (-0.18) - Toward Monolith
  Serverless             (+0.91) - Strongly Microservices

Insight: "Modular Monolith" positioned at +0.35 reveals it as a synthesis concept - borrowing from both paradigms. High axis distance would indicate it's introducing a third dimension (deployment model vs design pattern).

Political Philosophy

Axis: Individualism ↔ Collectivism

Individualism ●────────────────────────────────● Collectivism
              │                                │
         Grounding: 0.0                   Grounding: 0.0
         (neutral)                        (neutral)

Projected Concepts:
  Libertarianism         (-0.82) - Strongly Individual
  Social Democracy       (+0.41) - Leaning Collective
  Communitarianism       (+0.68) - Toward Collective
  Anarchism              (-0.15) - Slightly Individual (surprising!)

Insight: Anarchism's near-neutral position (-0.15) despite expectations reveals semantic nuance - anarchist philosophy contains both individualist and collective strains. The axis exposes this complexity that relationship-only navigation might miss.

Design Principles

Axis: Minimalism ↔ Maximalism

Minimalism ●──────────────────────────────────● Maximalism
           │                                  │
      Grounding: +0.22                  Grounding: -0.05
      (preferred)                       (contested)

Projected Concepts:
  Brutalism              (-0.91) - Strongly Minimal
  Bauhaus                (-0.73) - Toward Minimal
  Art Deco               (+0.58) - Toward Maximal
  Baroque                (+0.89) - Strongly Maximal
  Scandinavian Design    (-0.62) - Toward Minimal

Insight: Grounding correlation (r=0.87) shows cultural preference for minimalism in this knowledge base. "Art Deco" at +0.58 but still having moderate grounding suggests it's valued maximalism - controlled ornamentation vs excess.

Research Methodology

Axis: Empirical ↔ Theoretical

Empirical ●───────────────────────────────────● Theoretical
          │                                   │
     Grounding: +0.31                   Grounding: +0.18
     (valued)                           (valued)

Projected Concepts:
  Experimental Science   (-0.88) - Strongly Empirical
  Mathematical Proof     (+0.94) - Strongly Theoretical
  Case Study             (-0.42) - Toward Empirical
  Simulation             (+0.12) - Slightly Theoretical
  Meta-Analysis          (+0.03) - Nearly Neutral

Insight: Both poles have positive grounding - not all axes are value polarities. "Meta-Analysis" at +0.03 is almost perfectly balanced, which matches its nature as synthesis of empirical studies with theoretical frameworks.

Business Strategy

Axis: Exploitation ↔ Exploration

Exploitation ●────────────────────────────────● Exploration
             │                                │
        Grounding: +0.15                 Grounding: +0.28
        (stable)                         (growth-oriented)

Projected Concepts:
  Process Optimization   (-0.79) - Strongly Exploitation
  Market Research        (+0.67) - Toward Exploration
  Innovation             (+0.85) - Strongly Exploration
  Continuous Improvement (-0.33) - Leaning Exploitation
  Blue Ocean Strategy    (+0.92) - Extreme Exploration

Insight: Weak axis distance for "Continuous Improvement" (-0.33 on axis but low axis distance) suggests it's on the spectrum rather than orthogonal. This validates it as an exploitation activity, not a third dimension.

Environmental Science

Axis: Anthropocentric ↔ Ecocentric

Anthropocentric ●─────────────────────────────● Ecocentric
                │                             │
           Grounding: -0.42              Grounding: +0.51
           (problematic)                 (sustainable)

Projected Concepts:
  Human Supremacy        (-0.95) - Extreme Anthropocentric
  Sustainable Dev        (+0.38) - Leaning Ecocentric
  Deep Ecology           (+0.91) - Strongly Ecocentric
  Conservation           (+0.44) - Toward Ecocentric
  Wise Use               (-0.28) - Toward Anthropocentric

Insight: Strong grounding correlation (r=0.91) reflects value shift in environmental discourse. "Sustainable Development" at +0.38 positions it as pragmatic ecocentrism - balancing human needs with ecological health.

Education Philosophy

Axis: Teacher-Centered ↔ Student-Centered

Teacher-Centered ●────────────────────────────● Student-Centered
                 │                            │
            Grounding: -0.18              Grounding: +0.37
            (traditional)                 (progressive)

Projected Concepts:
  Lecture-Based          (-0.81) - Strongly Teacher-Centered
  Socratic Method        (+0.15) - Slightly Student-Centered
  Project-Based Learning (+0.76) - Strongly Student-Centered
  Apprenticeship         (+0.42) - Leaning Student-Centered
  Montessori             (+0.88) - Extreme Student-Centered

Insight: "Socratic Method" at +0.15 is surprisingly near neutral despite being ancient - reveals it has student-centered elements (questioning, dialogue) within teacher-controlled structure. Axis exposes this duality.

Cognitive Science

Axis: Nature ↔ Nurture

Nature ●──────────────────────────────────────● Nurture
       │                                      │
  Grounding: 0.0                         Grounding: 0.0
  (genetic)                              (environmental)

Projected Concepts:
  Nativism               (-0.89) - Strongly Nature
  Behaviorism            (+0.84) - Strongly Nurture
  Epigenetics            (+0.22) - Leaning Nurture (!)
  Gene-Environment       (+0.05) - Nearly Neutral
  Developmental Systems  (+0.18) - Slightly Nurture

Insight: "Epigenetics" at +0.22 positioned toward Nurture despite involving genes - semantically correct because epigenetics studies how environment influences gene expression. Axis captures this subtle distinction that "genetics-related" tagging would miss.

Key Patterns Revealed

1. Synthesis Concepts Cluster Near Zero - Modular Monolith, Meta-Analysis, Sustainable Development - Position ~0.0 to ±0.4 indicates integration of both poles

2. Grounding Correlation Indicates Value Polarity - Strong correlation (r > 0.7): Value-laden axis (good ↔ bad) - Weak correlation (r < 0.3): Descriptive axis (two valid approaches)

3. High Axis Distance Reveals Orthogonal Concerns - Concept far from axis introduces third dimension - Example: "Secure by Default" might be orthogonal to Monolith ↔ Microservices axis (security ≠ architecture)

4. Unexpected Positions Expose Semantic Nuance - Anarchism near-neutral on Individualism ↔ Collectivism - Socratic Method near-neutral on Teacher ↔ Student-Centered - Reveals concepts are more complex than simple categorization

Alternatives Considered

Approach: Pre-calculate axes for known oppositions (Modern ↔ Traditional, etc.)

Pros: - Instant results (no computation delay) - Predictable performance

Cons: - Can't handle user-defined axes (major limitation for exploratory use) - Requires maintenance (which axes to pre-compute? how to update?) - Stale data if graph changes (embeddings regenerate, concepts added/removed) - Assumes we know what axes users want (contradicts exploratory nature)

Decision: ❌ Rejected Reason: On-demand calculation provides flexibility for arbitrary user-defined axes without maintenance burden of predicting interesting axes

Alternative 2: Client-Side Computation

Approach: Return embeddings to client, let them calculate projections

Pros: - No server load - Full flexibility for client

Cons: - Exposes 768-dimensional embeddings (large payloads, privacy concern) - Duplicates computation across clients (inefficient) - No central optimization or future caching possible

Decision: ❌ Rejected Reason: Server-side calculation keeps embeddings private, enables future optimization, and provides consistent results across all clients

Alternative 3: Persist Axis Definitions

Approach: Store axes as graph vertices (:PolarityAxis node type)

Pros: - Historical tracking (axis evolution over time) - Faster retrieval (no re-computation) - Can link concepts to axes explicitly - Enables querying "which axes use this concept as a pole?"

Cons: - Schema complexity (new vertex type + edges) - Invalidation complexity when embeddings regenerate - Storage overhead for one-off exploratory axes - Premature commitment to persistence before understanding usage patterns

Decision: ⏸️ Deferred Reason: Start with on-demand computation only, add persistence if usage patterns reveal value. Can add later without breaking changes to API contracts.

Approach: Add polarityAxis parameter to /queries/concepts/search

Pros: - No new endpoints - Integrated with existing workflows

Cons: - Overloads search endpoint (already complex) - Different performance characteristics (search is fast, axis analysis is slow) - Confusing parameter semantics

Decision: ❌ Rejected Reason: Dedicated endpoints provide clearer semantics and separate performance profiles

Technical Design

Polarity Axis Calculation

Input: Two concept IDs (positive pole, negative pole)

Algorithm:

# 1. Fetch embeddings
positive_emb = get_embedding(positive_pole_id)  # 768-dim vector
negative_emb = get_embedding(negative_pole_id)  # 768-dim vector

# 2. Calculate axis vector (gradient from negative → positive)
axis_vector = positive_emb - negative_emb
axis_magnitude = ||axis_vector||  # L2 norm
axis_unit_vector = axis_vector / axis_magnitude

# 3. For each candidate concept:
candidate_emb = get_embedding(candidate_id)

# Vector from negative pole to candidate
candidate_vector = candidate_emb - negative_emb

# Project onto axis (dot product)
projection_scalar = candidate_vector · axis_unit_vector

# Normalize to [-1, +1] (0 = midpoint)
position = (projection_scalar / axis_magnitude) * 2 - 1

# Calculate orthogonal distance (how far off-axis)
projection_vector = projection_scalar * axis_unit_vector
orthogonal_vector = candidate_vector - projection_vector
axis_distance = ||orthogonal_vector||

# 4. Determine direction
if position > 0.3:
    direction = "positive"
elif position < -0.3:
    direction = "negative"
else:
    direction = "neutral"

Output: - Position: -1 (negative pole) to +1 (positive pole), 0 = midpoint - Axis distance: Orthogonal component (higher = more multi-dimensional) - Direction: Categorical alignment

Grounding Correlation

Hypothesis: Grounding should correlate with axis position

Validation:

# For each projected concept:
positions = [p.position for p in projections]
groundings = [p.grounding for p in projections]

# Calculate Pearson correlation
r, p_value = pearsonr(positions, groundings)

# Interpret:
# r > 0.7: Strong correlation (good axis)
# r < 0.3: Weak correlation (weak axis or orthogonal concern)

Example (from experiments): - Legacy Systems (-0.075 grounding) → position -0.124 (toward negative pole) - Agile (+0.227 grounding) → position +0.194 (toward positive pole) - Correlation: r = 0.85 (strong!)

Implementation Phases

Phase 1: Core Analysis Function & API Endpoint ✅ COMPLETED

  • [x] Refactor experimental code into api/lib/polarity_axis.py as direct query function
  • [x] Implement analyze_polarity_axis() with auto-discovery capability
  • [x] Add POST /query/polarity-axis endpoint in api/routes/queries.py
  • [x] Create Pydantic models (PolarityAxisRequest, PolarityAxisResponse) in api/models/queries.py
  • [x] OpenAPI documentation (auto-generated from FastAPI schemas)
  • [x] Testing with real embeddings (Modern Ways of Working ↔ Traditional Operating Models)
  • [x] Validation: ~2.36 seconds for 20 concepts, confirmed direct query pattern viability

Implementation Notes: - Decision to use direct query pattern instead of background workers based on fast execution time - Followed /query/connect pattern for consistency - AGE Cypher syntax limitations required workarounds (no type filters in variable-length paths)

Phase 2: CLI Command ✅ COMPLETED

  • [x] Add kg polarity analyze command in cli/src/cli/polarity.ts
  • [x] Client method client.analyzePolarityAxis() in cli/src/api/client.ts
  • [x] Colored output with formatted tables (positive/neutral/negative sections)
  • [x] JSON mode support for scripting
  • [x] Command registration in cli/src/cli/commands.ts

Phase 3: MCP Server Integration ✅ COMPLETED

  • [x] Add analyze_polarity_axis tool to MCP server (cli/src/mcp-server.ts)
  • [x] Token-efficient markdown formatter (formatPolarityAxisResults in cli/src/mcp/formatters.ts)
  • [x] Comprehensive tool description with use cases and performance characteristics
  • [x] Testing via Claude Desktop integration
  • [x] Rich output: axis metadata, statistics, grounding correlation, organized projections

Phase 4: Documentation & Web UI ⏳ IN PROGRESS

  • [x] Update ADR-070 with production implementation details (this document)
  • [ ] Add usage examples and interpretation guide
  • [ ] Update ARCHITECTURE_DECISIONS.md index
  • [ ] Web workstation "Polarity Axis Explorer" panel (deferred - future enhancement)

Deferred Items: - POST /queries/discover-polarity-axes (auto-discover axes from relationships) - Could be added as future enhancement - GET /queries/polarity-axis/{axis_id}/project/{concept_id} (project onto saved axis) - Not needed without axis persistence - Axis persistence (:PolarityAxis nodes) - Deferred per Alternative 3 discussion

User Interface Specifications

MCP Server Integration ✅ IMPLEMENTED

Tool: analyze_polarity_axis - Analyze bidirectional semantic dimension between two concept poles

Parameters: - positive_pole_id (required): Concept ID for positive pole - negative_pole_id (required): Concept ID for negative pole - candidate_ids (optional): Specific concept IDs to project onto axis - auto_discover (default: true): Auto-discover related concepts if no candidates specified - max_candidates (default: 20): Maximum candidates for auto-discovery - max_hops (default: 2): Maximum graph hops for auto-discovery

Output Format: Token-efficient markdown optimized for AI consumption with: - Axis definition (poles, grounding, magnitude, quality indicator) - Statistical summary (position range, mean, distribution) - Grounding correlation with practical interpretation - Concept projections organized by direction (positive/neutral/negative) - Usage guide explaining positions and orthogonality

Example Usage:

analyze_polarity_axis(
  positive_pole_id="sha256:0d5be_chunk1_a2ccadba",  # Modern Ways of Working
  negative_pole_id="sha256:0f72d_chunk1_9a13bb20",  # Traditional Operating Models
  auto_discover=true,
  max_candidates=20
)

CLI Tool (kg) ✅ IMPLEMENTED

Command:

kg polarity analyze --positive <concept-id> --negative <concept-id> [options]

Options: - --positive <id> - Positive pole concept ID (required) - --negative <id> - Negative pole concept ID (required) - --candidates <ids...> - Specific concept IDs to project (space-separated) - --no-auto-discover - Disable auto-discovery of related concepts - --max-candidates <N> - Maximum candidates for auto-discovery (default: 20) - --max-hops <N> - Maximum graph hops for auto-discovery (default: 2) - --json - Output raw JSON instead of formatted text

Output Format: Colored terminal output with: - Axis header with pole labels and grounding strength - Axis quality indicator (strong/weak based on magnitude) - Statistics table (position range, mean, distribution, correlation) - Three sections: Positive Direction, Neutral, Negative Direction - Each concept shows: label, position, grounding, axis distance, concept ID

Example:

kg polarity analyze \
  --positive sha256:0d5be_chunk1_a2ccadba \
  --negative sha256:0f72d_chunk1_9a13bb20 \
  --max-candidates 20

Web Workstation ⏳ DEFERRED

New Explorer Panel: "Polarity Axis Explorer" (future enhancement)

Deferred Features: - Interactive visualization with drag-and-drop - Custom axis creator with search - Concept integration tabs - Export options (JSON, PNG, SVG)

Reason for Deferral: Core functionality (API, CLI, MCP) provides complete access to polarity axis analysis. Web UI adds convenience but isn't required for feature adoption. Can be added based on user feedback and usage patterns.

Success Criteria

Functional: - ✅ Polarity axis calculation produces stable results (±0.05 across runs) - ✅ Grounding correlation r > 0.7 for PREVENTS/CONTRADICTS axes - ✅ Direction accuracy >90% vs human spot checks - ✅ Graceful handling of edge cases (single concept, no candidates, invalid concept IDs)

Performance: - ✅ Axis calculation <5s for 20 candidates (initial implementation without caching) - ✅ Background worker processing prevents API blocking - ✅ No performance regression on existing endpoints - ✅ Job queue handles concurrent polarity analysis requests

Adoption: - ✅ 10+ polarity axis analyses per week (within first month) - ✅ User feedback positive (clear value, understandable results) - ✅ Zero critical bugs or data corruption - ✅ Documentation enables self-service usage

Risks & Mitigations

Risk Impact Probability Mitigation
Expensive computation affects user experience High Medium Background workers, job queue, progress tracking
Results are unintuitive to users Medium Medium Clear docs, diverse examples, visual aids in interfaces
Grounding correlation weak for some axes Medium Low Document when axes are weak, suggest alternatives, show correlation strength
Users discover axes that don't make semantic sense Low Medium Provide correlation metrics, allow filtering by correlation strength

References

Decision Record

Status: Accepted & Implemented Proposed By: System Architect Implementation Date: 2025-11-30 Approval Date: 2025-11-30

Key Implementation Decisions: 1. Direct Query Pattern: Chose direct query over background workers based on fast execution time (~2-3s) 2. Simplified Scope: Implemented single endpoint (POST /query/polarity-axis) rather than three endpoints 3. Auto-Discovery: Included graph traversal-based candidate discovery in initial release 4. No Persistence: Deferred axis persistence (:PolarityAxis nodes) - compute on demand only 5. Web UI Deferred: Core functionality (API/CLI/MCP) sufficient for initial adoption

Implementation Files: - api/api/lib/polarity_axis.py - Core analysis function (419 lines) - api/api/models/queries.py - Pydantic request/response models - api/api/routes/queries.py - FastAPI endpoint - cli/src/cli/polarity.ts - CLI command (166 lines) - cli/src/api/client.ts - Client method - cli/src/mcp-server.ts - MCP tool registration - cli/src/mcp/formatters.ts - Markdown formatter

Testing Results: - Execution time: ~2.36 seconds for 20 concepts - Axis quality: Strong (magnitude 0.9735) - Grounding correlation: Validated with real-world examples - MCP integration: Tested via Claude Desktop - CLI integration: Tested with multiple pole pairs


Completed: 1. ✅ Core analysis function with auto-discovery 2. ✅ API endpoint with comprehensive request/response models 3. ✅ CLI command with colored output 4. ✅ MCP tool with rich markdown formatting 5. ✅ ADR documentation update 6. ✅ Testing and validation

Future Enhancements: 1. Web UI "Polarity Axis Explorer" panel 2. Auto-discovery endpoint (POST /queries/discover-polarity-axes) 3. Axis persistence if usage patterns warrant it 4. Global embedding cache for performance optimization