-
Notifications
You must be signed in to change notification settings - Fork 0
Description
[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"]
- [STORY] Wiki Metadata Fields Configuration via Web UI #323 [STORY] Wiki Metadata Fields Configuration via Web UI
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"]
- [STORY] Configurable Metadata Panel Display Order #325 [STORY] Configurable Metadata Panel Display Order
Implementation Dependencies
- Story 1 (Feature 1) MUST be implemented first -- it establishes the
WikiConfigdataclass, the config injection pattern (wiki_config=Noneparameter), 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=Noneparameter Nonemeans "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 fromConfigServiceon 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__onServerConfiginitializesWikiConfig()with defaults when missing from config.jsonServerConfigManager.load_config()convertswiki_configdict toWikiConfiginstance inline (same pattern asLangfuseConfig,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/ServerConfigManagerinfrastructure (well-established, 20+ nested configs) - Existing
ConfigServiceand Config Web UI (config_section.html) - Existing
WikiServicemethods:render_article(),_strip_header_block(),prepare_metadata_context(),populate_views_from_front_matter() - Existing
article.htmltemplate with metadata panel rendering (2-tuple(label, value)format)
Implementation Dependencies
- Story 1 ([STORY] Wiki Metadata Fields Configuration via Web UI #323) must complete before Story 2 ([STORY] Configurable Metadata Panel Display Order #325) (establishes WikiConfig foundation)
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