Skip to content

[EPIC] Wiki Settings Generalization #322

@jsbattig

Description

@jsbattig

[Conversation Reference: "User provided audit showing wiki module is ~85% generic but has 6 hard-coded knowledge-base assumptions from Salesforce migration origin"]
[Post-audit correction: Finding #4 (visibility badge logic) was invalid -- the described code does not exist in the current codebase. Visibility renders as plain text with no badge CSS classes. Epic scope reduced from 6 to 5 findings, 3 to 2 stories.]

Executive Summary

Epic Objective: Make the CIDX wiki module fully generic by converting 5 hard-coded knowledge-base assumptions into settings-driven behavior exposed through the Config Web UI.

Business Value: The wiki module originated from a Salesforce Knowledge Base migration and carries 5 hard-coded assumptions (header block parsing, article numbering, publication status, views seeding from front matter, and metadata panel display order). These assumptions prevent the wiki from serving as a general-purpose documentation system. This epic externalizes all 5 as configurable settings, enabling administrators to tailor the wiki to any project's content structure without code changes.

Architecture Impact: A new WikiConfig dataclass is added as a nested field on ServerConfig (same pattern as LangfuseConfig, CacheConfig, etc.), persisted to ~/.cidx-server/config.json. The wiki module reads config per-request via ConfigService -- no server restart required. All defaults match current behavior for backward compatibility.

Scope Correction: The original audit identified 6 findings. Finding #4 (hard-coded visibility states with CSS badges) was invalidated during code review -- the described get_visibility_class() function and badge CSS classes do not exist in the current codebase. Visibility is rendered as plain text in the metadata panel. Story #324 was dropped. See #324 for details.

Epic Scope and Objectives

Primary Objectives

[Conversation Reference: "User said 'defaults match current behavior for backward compatibility' and 'good regression tests for every conceptual change'"]

  • Externalize 5 knowledge-base-specific behaviors into settings on the Config Web UI
  • Ensure default settings produce identical behavior to the current codebase (backward compatible)
  • Ensure a fresh deployment with all toggles OFF behaves as a clean generic wiki
  • Provide comprehensive regression tests for every conceptual change

Measured Success Criteria

  • All 5 valid idiosyncrasies are controlled by Config Web UI settings
  • Default configuration produces behavior identical to current codebase (golden regression test)
  • All toggles OFF produces a clean generic wiki with no KB-specific artifacts
  • Every setting change takes effect without server restart
  • Each conceptual change has dedicated regression tests covering ON and OFF states
  • Zero breaking changes for existing deployments (auto-migration fills defaults)

Architecture Overview

Key Architecture Decisions

Decision Choice Rationale
Config location WikiConfig nested dataclass on ServerConfig Follows established pattern (LangfuseConfig, CacheConfig, etc.)
Persistence ~/.cidx-server/config.json Single source of truth, auto-migration for existing installs
Config injection wiki_config=None parameter on service methods None = current behavior; WikiService stays stateless
Restart requirement None (per-request via ConfigService) Wiki routes call _get_wiki_config() helper on each request
Display order format Comma-separated string, default "" (empty = current order) Precedent: indexable_extensions uses comma-separated strings. Empty default ensures golden regression passes — current code uses dict iteration order, not a fixed sort.
Metadata panel data 2-tuple (label, value) Unchanged from current implementation

Component Architecture

Config Web UI (config_section.html)
        |
        v
ConfigService.get_config() --> ServerConfig.wiki_config (WikiConfig dataclass)
        |
        v
Wiki Routes (_get_wiki_config() helper)
        |
        v
WikiService methods (wiki_config=None parameter)
  - render_article()           --> conditional header block parsing
  - prepare_metadata_context() --> conditional field inclusion, ordering
  - populate_views_from_front_matter() --> conditional no-op
        |
        v
article.html template (2-tuple rendering, unchanged)

WikiConfig Dataclass

@dataclass
class WikiConfig:
    # Story 1: Metadata field toggles (all default True = current behavior)
    enable_header_block_parsing: bool = True
    enable_article_number: bool = True
    enable_publication_status: bool = True
    enable_views_seeding: bool = True

    # Story 2: Metadata panel display order (comma-separated string)
    # Empty string = preserve current iteration order (article_number first, rest in YAML key order)
    # Non-empty = sort according to specified order, unlisted fields appended alphabetically
    metadata_display_order: str = ""

Features and Stories Implementation Order

Feature 1: Wiki Metadata Fields Configuration (HIGH priority)

[Conversation Reference: "Groups findings 1,2,3,5 -- header block parsing, article_number, publication_status, views seeding"]

Feature 2: Configurable Visibility States (DROPPED)

[Post-audit correction: Finding #4 was invalid -- visibility badge logic does not exist in the codebase. See #324.]

Feature 2: Metadata Panel Display Order (LOW priority)

[Conversation Reference: "Groups finding 6 -- metadata panel prioritizes KB fields over generic wiki fields"]

Implementation Dependencies

  • Story 1 (Feature 1) MUST be implemented first -- it establishes the WikiConfig dataclass, the config injection pattern (wiki_config=None parameter), and the _get_wiki_config() route helper that Story 2 depends on.
  • Story 2 depends on Story 1.

Technical Implementation Standards

Config Injection Pattern

  • All WikiService methods that depend on wiki settings accept a wiki_config=None parameter
  • None means "use current hard-coded behavior" (backward compatible, zero risk for callers that do not pass config)
  • Wiki routes obtain config via a _get_wiki_config() helper that reads from ConfigService on each request
  • No circular import risk: wiki --> config is one-way

Testing Standards

[Conversation Reference: "User said 'good regression tests for every conceptual change'"]

  • Every toggle must have paired ON/OFF regression tests
  • A "golden regression" test verifies that default config produces identical output to the current codebase
  • A "clean generic" test verifies that all-toggles-OFF produces a wiki with no KB-specific artifacts
  • Config persistence round-trip tests verify JSON serialization/deserialization
  • Default config migration tests verify existing installs auto-populate WikiConfig defaults

Backward Compatibility

  • All defaults match current behavior exactly
  • __post_init__ on ServerConfig initializes WikiConfig() with defaults when missing from config.json
  • ServerConfigManager.load_config() converts wiki_config dict to WikiConfig instance inline (same pattern as LangfuseConfig, PasswordSecurityConfig, etc.)
  • No server restart required -- config changes take effect on next wiki request

Files That Change

Story Files Modified
Story 1 (#323) config_manager.py, config_service.py, config_section.html, web/routes.py, wiki_service.py, wiki/routes.py + new test file
Story 2 (#325) config_manager.py, config_service.py, config_section.html, wiki_service.py + new test file

Risk Assessment and Mitigation

Technical Risks

Risk: Config migration breaks existing deployments with custom config.json
Mitigation: __post_init__ pattern guarantees WikiConfig() defaults are populated when field is absent from JSON. This is the same proven pattern used for all 20+ existing nested configs.

Operational Risks

Risk: Admin changes wiki config and gets unexpected behavior
Mitigation: Config Web UI includes help text explaining each setting. All defaults match current behavior, so administrators must opt-in to changes.

Dependencies and Prerequisites

Technical Dependencies

  • Existing ServerConfig / ServerConfigManager infrastructure (well-established, 20+ nested configs)
  • Existing ConfigService and Config Web UI (config_section.html)
  • Existing WikiService methods: render_article(), _strip_header_block(), prepare_metadata_context(), populate_views_from_front_matter()
  • Existing article.html template with metadata panel rendering (2-tuple (label, value) format)

Implementation Dependencies

Success Metrics and Validation

Functional Metrics

  • 5/5 valid idiosyncrasies converted to settings-driven behavior
  • 100% backward compatibility with default config (golden regression test passes)
  • Clean generic wiki behavior with all toggles OFF (no KB-specific artifacts)

Quality Metrics

  • Regression test coverage for every toggle ON/OFF state
  • Golden regression test: default config produces output identical to current codebase
  • Config persistence round-trip tests pass for all WikiConfig fields
  • Default config migration tests pass for existing installs without wiki_config in JSON
  • Zero lint/typecheck warnings introduced
  • fast-automation.sh passes with zero failures

Epic Completion Criteria

Definition of Done

  • Both stories implemented, code-reviewed, and manually tested
  • WikiConfig dataclass added to ServerConfig with auto-migration in __post_init__
  • Config Web UI "Wiki" section with all settings exposed (4 toggles, text input)
  • All settings take effect without server restart
  • Default configuration produces identical behavior to current codebase
  • All toggles OFF produces clean generic wiki
  • Comprehensive regression tests for every conceptual change (ON/OFF pairs)
  • fast-automation.sh passes with zero failures
  • No lint or typecheck warnings introduced

Acceptance Validation

  • Existing deployment with populated config.json auto-migrates WikiConfig defaults
  • Fresh deployment with default config behaves identically to current codebase
  • Admin can toggle each of the 4 boolean settings and see immediate effect
  • Admin can reorder metadata panel fields via comma-separated text input
  • All regression tests pass for every toggle combination

Epic Owner: CIDX Development
Stakeholders: CIDX Server Administrators
Success Measurement: All 5 KB-specific behaviors configurable via Web UI with zero backward compatibility breaks

Metadata

Metadata

Assignees

No one assigned

    Labels

    backlogepicEpic-level issue tracking multiple storiespriority-2

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions