[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
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
Acceptance Validation
Epic Owner: CIDX Development
Stakeholders: CIDX Server Administrators
Success Measurement: All 5 KB-specific behaviors configurable via Web UI with zero backward compatibility breaks
[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
WikiConfigdataclass is added as a nested field onServerConfig(same pattern asLangfuseConfig,CacheConfig, etc.), persisted to~/.cidx-server/config.json. The wiki module reads config per-request viaConfigService-- 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'"]
Measured Success Criteria
Architecture Overview
Key Architecture Decisions
WikiConfignested dataclass onServerConfigLangfuseConfig,CacheConfig, etc.)~/.cidx-server/config.jsonwiki_config=Noneparameter on service methodsNone= current behavior; WikiService stays stateless_get_wiki_config()helper on each request""(empty = current order)indexable_extensionsuses comma-separated strings. Empty default ensures golden regression passes — current code uses dict iteration order, not a fixed sort.(label, value)Component Architecture
WikiConfig Dataclass
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.]
[STORY] Configurable Visibility States #324 [STORY] Configurable Visibility States(DROPPED -- invalid finding)Feature 2: Metadata Panel Display Order (LOW priority)
[Conversation Reference: "Groups finding 6 -- metadata panel prioritizes KB fields over generic wiki fields"]
Implementation Dependencies
WikiConfigdataclass, the config injection pattern (wiki_config=Noneparameter), and the_get_wiki_config()route helper that Story 2 depends on.Technical Implementation Standards
Config Injection Pattern
wiki_config=NoneparameterNonemeans "use current hard-coded behavior" (backward compatible, zero risk for callers that do not pass config)_get_wiki_config()helper that reads fromConfigServiceon each requestTesting Standards
[Conversation Reference: "User said 'good regression tests for every conceptual change'"]
Backward Compatibility
__post_init__onServerConfiginitializesWikiConfig()with defaults when missing from config.jsonServerConfigManager.load_config()convertswiki_configdict toWikiConfiginstance inline (same pattern asLangfuseConfig,PasswordSecurityConfig, etc.)Files That Change
config_manager.py,config_service.py,config_section.html,web/routes.py,wiki_service.py,wiki/routes.py+ new test fileconfig_manager.py,config_service.py,config_section.html,wiki_service.py+ new test fileRisk Assessment and Mitigation
Technical Risks
Risk: Config migration breaks existing deployments with custom config.json
Mitigation:
__post_init__pattern guaranteesWikiConfig()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
ServerConfig/ServerConfigManagerinfrastructure (well-established, 20+ nested configs)ConfigServiceand Config Web UI (config_section.html)WikiServicemethods:render_article(),_strip_header_block(),prepare_metadata_context(),populate_views_from_front_matter()article.htmltemplate with metadata panel rendering (2-tuple(label, value)format)Implementation Dependencies
Success Metrics and Validation
Functional Metrics
Quality Metrics
Epic Completion Criteria
Definition of Done
__post_init__Acceptance Validation
Epic Owner: CIDX Development
Stakeholders: CIDX Server Administrators
Success Measurement: All 5 KB-specific behaviors configurable via Web UI with zero backward compatibility breaks