Skip to main content

PRD: Unified Content Publishing Platform

Document Control

FieldValue
Version1.2
StatusActive (MVP Complete)
AuthorRohit
Last Updated2026-03-06

Executive Summary

LOW CONFIDENCE -- Problem not validated. The problem statement in this PRD has not been confirmed with quantified data, stakeholder input, or impact metrics. Treat requirements as hypotheses until validation is completed.

Symphony Core publishes internal documentation across multiple Docusaurus sites (team.symphonycore.com, dev.symphonycore.com) using a sync tool that copies markdown from a single source repo. The tool cannot clean up archived content, only supports one source repo, and requires maintaining two nearly identical publishing repositories. This PRD defines a unified content publishing platform that consolidates multiple source repos, multiple target sites, stale content cleanup, structured data publishing, and audience-segmented access into a single extensible pipeline.

Scope Tier: 1 -- New Product/System


Goals & Desired Outcomes

Business Outcomes

OutcomeMeasurementTargetTimeline
Eliminate stale/archived content from published sitesCount of orphaned pages on published sites0 stale pages after any sync runMVP
Reduce infrastructure duplication across wiki reposNumber of separate publishing repos maintained1 unified repo (down from 2)MVP
Enable publishing from any configured sourceNumber of distinct source repos syncing successfully3+ sources (documents, dev repos, structured data)Phase 2
Support audience-segmented publishingNumber of distinct target sites with independent access policies3+ (team, dev, partner)Phase 2

User Outcomes

User PersonaCurrent PainDesired Future State
Documentation authorMust manually track which docs are published where; no feedback on stale contentTag a document with publish_to, run sync, and trust that published sites reflect current source state exactly
Platform operatorMaintains two separate repos with identical infrastructure; sync tool has no cleanupSingle repo to maintain; sync is idempotent -- adds, updates, and removes in one pass
DeveloperREADMEs in dev repos are not discoverable on dev.symphonycore.comREADMEs from configured repos auto-publish to developer docs site
Business stakeholderNo way to share confidential docs with partners via a controlled portalPartner-facing site with Cloudflare Access invite-only auth publishes tagged content

Success Looks Like

A documentation author writes or updates a markdown file in any configured source repo, sets publish_to: [internal-wiki, developer-docs] in frontmatter, and runs npm run sync. Within seconds, the content appears on the correct sites. If a document is moved to the archive repo or has its publish_to tag removed, the next sync run automatically removes it from all target sites. The platform operator manages one repository, one config file, and one deployment pipeline for all wiki sites. A developer's README in their project repo shows up on dev.symphonycore.com without any manual copying.


Context

AttributeValue
Use CaseWork
AudienceInternal (team, dev), Restricted External (partner), Public (help -- future)
PlatformWeb (Docusaurus static sites on Cloudflare Pages)

User Personas

Persona 1: Documentation Author

  • Description: Team member who writes SOPs, reference docs, training materials in symphony-core-documents or other source repos
  • Goals: Publish content to the right audience with minimal friction; trust that archived content disappears
  • Pain Points: No cleanup of stale content; must remember which repo targets which site; no visibility into what's published where

Persona 2: Platform Operator (Rohit)

  • Description: Maintains publishing infrastructure, deployment pipelines, Cloudflare configuration
  • Goals: Minimize maintenance overhead; single source of truth for publishing config; reliable, idempotent sync
  • Pain Points: Two nearly identical repos (internal-docs, developer-docs); sync tool lives in one repo but serves both; no state tracking or cleanup

Persona 3: Developer

  • Description: Writes code and maintains READMEs in development repositories
  • Goals: Have project documentation discoverable on dev.symphonycore.com without manual publishing steps
  • Pain Points: READMEs stay in GitHub; not surfaced on the internal developer docs site

Persona 4: Business Partner (Future)

  • Description: External partner who needs access to specific business-confidential documents
  • Goals: Access relevant partner documentation via a simple, secure portal
  • Pain Points: No controlled sharing mechanism exists; documents shared ad-hoc via email or Drive

Jobs-To-Be-Done (JTBD)

Primary Job

When I have documentation spread across multiple repos and need it published to audience-appropriate websites, I want to tag documents with their intended audience and run a single sync command, so I can trust that each site reflects the current, correct set of documents for its audience.

Job Components

  • Functional: Sync tagged content from multiple sources to multiple target sites, removing stale content and transforming formats as needed
  • Emotional: Confidence that published sites are accurate and current; no anxiety about stale or misrouted content
  • Social: Team and partners see a professional, well-maintained documentation platform

Current Alternatives

  1. Manual copy-paste: Sync tool copies files but doesn't clean up; stale content requires manual deletion
  2. Two separate repos: internal-docs and developer-docs maintained independently with shared sync-tool dependency
  3. Ad-hoc sharing: Partner documents shared via email or Google Drive links
  4. Third-party KB: help.symphonycore.com hosted externally; no SEO ownership, no content control

Job Success Criteria

  • Running npm run sync produces a deterministic, reproducible result: published sites match tagged source content exactly
  • Adding a new source repo or target site requires only configuration changes, no code changes
  • Removing a document from source (or un-tagging it) results in removal from published sites on next sync

Problem Validation

Evidence of Problem

  • Customer interviews conducted: N/A (internal tooling)
  • Usage data analyzed: Sync tool source code confirms no cleanup logic exists (publisher.ts is append/update only)
  • Support ticket analysis: N/A -- problem identified through codebase analysis
  • Market research: N/A
  • Other evidence: Two repos (internal-docs, developer-docs) share ~90% identical infrastructure; developer-docs has no sync tool and depends on cross-repo invocation

Problem Statement

LOW CONFIDENCE -- Problem not validated. No quantified data on stale content impact or maintenance overhead. Treat as hypothesis until validated by a full sync audit.

Current State: Symphony Core publishes documentation using a sync tool (sync-tool/) that scans a single source repo (symphony-core-documents) for files tagged with publish_to in YAML frontmatter and copies them to target repos. Two separate Docusaurus repos (internal-docs at team.symphonycore.com, developer-docs at dev.symphonycore.com) are maintained with near-identical configuration. The sync tool is append/update only -- it writes files to destinations but never removes files that no longer exist in the source.

Pain Points:

  1. Stale content persists: Documents archived (moved to archive repo) or un-tagged remain published indefinitely
  2. Infrastructure duplication: Two repos with identical stack (Docusaurus + Cloudflare Pages + Cloudflare Access) maintained separately
  3. Single-source limitation: Only symphony-core-documents is supported; dev repo READMEs and structured data (client registry) cannot be published
  4. No partner portal: No mechanism for controlled, audience-segmented publishing of business-confidential content
  5. Cross-repo sync dependency: developer-docs has no sync tool; depends on invoking internal-docs' tool with --target developer-docs --dest ../developer-docs

Impact: Manual effort to audit and clean stale content; risk of outdated/archived documentation remaining accessible; duplicated maintenance work across repos; inability to publish content from additional sources.

Root Cause Analysis

LevelQuestionFinding
SurfaceWhat problem was initially stated?Sync tool can't clean up stale docs, only supports one source, requires two repos
Why 1Why does stale content persist?Tool was built as a one-way copy mechanism with no state tracking or deletion logic
Why 2Why is it one-way with no state tracking?Originally, archival was handled by a status flag; when that moved to a separate archive repo, the tool wasn't updated
Why 3Why are there two separate repos with identical infrastructure?Each wiki site was set up independently as needs arose
Why 4Why were they set up independently?No unified content publishing platform was designed; infrastructure was bootstrapped incrementally

Root Cause (deepest actionable level): Symphony Core lacks a unified content publishing platform -- publishing infrastructure was bootstrapped incrementally per-site, resulting in duplicated repos, a single-source sync tool with no cleanup, and no path to scale to additional sources or audiences.

Stop Reason: Further "why" leads to organizational growth patterns outside sphere of influence.


Opportunity Solution Tree

Desired Outcome (Business Goal)

Establish a single, extensible content publishing platform that routes documents from any configured source to any configured audience-specific site, with accurate cleanup of stale content.

Opportunities (Customer Needs)

Opportunity IDCustomer Need/Pain PointEvidenceImpact Potential
OPP-001Published sites must reflect current source state (no stale content)Sync tool has no deletion logic; archived docs persist on sitesHigh
OPP-002Reduce infrastructure maintenance by consolidating duplicate reposinternal-docs and developer-docs share ~90% identical configHigh
OPP-003Publish content from multiple source types (markdown repos, READMEs, structured data)Only symphony-core-documents supported; dev READMEs and client registry cannot publishMedium
OPP-004Audience-segmented publishing with appropriate access controlsNo partner portal; all content goes to two internal sitesMedium
OPP-005Publishable structured data (YAML/JSON to rendered pages)Client registry is YAML; no pipeline to render it as documentationLow
OPP-006Customer-facing KB with SEO ownershiphelp.symphonycore.com hosted by third party; no SEO benefitLow (research phase)

Solutions (How We Address Opportunities)

Solution IDAddresses OpportunityDescriptionSelected
SOL-001OPP-001Manifest-based sync with diff: track previously synced files and remove orphansYes
SOL-002OPP-001Clean-slate sync: delete target directory before every syncNo -- destroys manually-authored content (e.g., CLI catalog in developer-docs)
SOL-003OPP-002Consolidate into single repo with multiple Docusaurus site builds, each deployed to its own Cloudflare Pages project/subdomainYes
SOL-004OPP-002Keep repos separate, share config via npm packageNo -- doesn't reduce maintenance meaningfully
SOL-005OPP-003Extend sync tool with pluggable source adapters (git repo, README scanner, YAML transformer)Yes
SOL-006OPP-004Add target site definitions in config with per-site Cloudflare Access policiesYes
SOL-007OPP-005Add a YAML-to-markdown renderer as a source adapterYes
SOL-008OPP-006Stand up public Docusaurus site at help.symphonycore.com with SEO configDeferred -- research only

Why This Solution?

Manifest-based sync (SOL-001) over clean-slate (SOL-002) because developer-docs contains manually-authored CLI catalog pages that must not be deleted during sync. A manifest tracks what the sync tool owns and only cleans those files.

Repo consolidation with multi-site builds (SOL-003) over shared config (SOL-004) because the two repos have identical deployment pipelines, identical auth, and overlapping sync dependencies. Each subdomain (team, dev, partner) keeps its own Cloudflare Access policy and independent deployment, but all site definitions, content, and the sync tool live in one repo. This preserves access separation (different people access dev vs team) while eliminating cross-repo dependencies.

Pluggable source adapters (SOL-005) because source types are heterogeneous: markdown repos, individual README files, YAML data files. A common interface with specialized adapters keeps the core pipeline clean.


MVP Definition

In Scope (MVP)

  1. Stale content cleanup: Manifest-based tracking of synced files; orphan removal on every sync run (first run = sync-only, no cleanup until manifest exists)
  2. Repo consolidation as multi-site: Merge developer-docs into this repo; each subdomain (team.symphonycore.com, dev.symphonycore.com) is a separate Docusaurus build + Cloudflare Pages project with independent access policies
  3. Multi-source configuration: Config-driven list of source repos (not just one hardcoded path)
  4. Multi-target publishing: Config-driven target site definitions with independent publish_to tag values routing content to specific site builds
  5. Dry-run with diff reporting: Show what would be added, updated, and removed before committing changes
  6. CLI catalog preservation: Ensure manually-authored content in developer-docs is preserved during consolidation and not touched by sync cleanup (protected manual directories)

Out of Scope (Future Phases)

  1. README auto-sync from dev repos (Phase 2) -- configured list of repos whose READMEs publish to developer-docs
  2. Structured data publishing (Phase 2) -- YAML-to-markdown renderer with configurable field templates per target
  3. Partner portal (Phase 2) -- partner.symphonycore.com with Cloudflare Access invite-only auth
  4. Per-target content redaction (Phase 2) -- config-driven rules to strip marked sections for restricted-audience sites
  5. Customer-facing KB (Phase 3 / Research) -- help.symphonycore.com migration with SEO; significant unknowns remain
  6. CI/CD-triggered sync -- auto-sync on push to source repos via GitHub Actions
  7. Content versioning -- track and display document version history
  8. Cross-site search -- unified search across all published sites
  9. Content preview -- preview how a document will render on target site before publishing

Requirements

Outcome-Based Requirements

IDDesired OutcomeHow We'll Measure SuccessPriorityStatus
OR-001Published sites accurately reflect current source state with no stale contentAfter sync: count of files on target site not present in source manifest = 0MustDone
OR-002Single repository powers all internal documentation sitesNumber of separate publishing repos = 1MustDone
OR-003Content from multiple source repos can be published through one pipelineNumber of distinct source repos that successfully sync >= 2MustDone
OR-004Content authors control publication targets via document-level tagsAll published documents have matching publish_to tags in source; no untagged content appears on sitesMustDone
OR-005Platform operator configures new sources and targets without code changesAdding a new source or target requires only config file editsShouldDone
OR-006Manually-authored content coexists with synced content without interferenceCLI catalog pages persist across sync runs; no manual content is deleted or overwrittenMustDone
OR-007Operator has clear visibility into sync changes before they happenDry-run output shows additions, updates, and removals with file pathsShouldDone
OR-008Dev repo READMEs are discoverable on developer documentation siteREADMEs from configured repos appear on dev.symphonycore.comShouldDone
OR-009Structured data (YAML/JSON) can be rendered as documentation pagesClient registry renders as a browsable client directory pageCouldNot Started
OR-010Audience-segmented publishing supports restricted-access portalsPartner-tagged content publishes to a separate site with invite-only Cloudflare AccessCouldNot Started
OR-011Customer-facing KB can be self-hosted with SEO benefitsPublic-facing site at help.symphonycore.com with sitemap, meta tags, open graphWon't (Research)Not Started

Functional Requirements

IDRequirementEnables OutcomePriorityStatusUser DocDev Doc
FR-001Maintain a sync manifest that records all files written by the sync tool, including file path, source hash, and sync timestampOR-001MustDone--
FR-002On each sync run, compare current manifest against previous manifest and remove files that are no longer in scope (archived, un-tagged, or deleted from source)OR-001MustDone--
FR-003Persist the sync manifest to a known location in the target repo so it survives across sync runsOR-001MustDone--
FR-004Support a configurable list of source repositories, each with its own path, content type, and scan settingsOR-003, OR-005MustDone--
FR-005Support a configurable list of target sites, each with its own docs path, Cloudflare Pages project, and accepted publish_to tag valuesOR-004, OR-005MustDone--
FR-006Migrate developer-docs content (CLI catalog, synced docs, config) into the consolidated repo under a site-specific directory structureOR-002, OR-006MustDone--
FR-007Support multiple Docusaurus site builds from a single repo, each deployable as a separate Cloudflare Pages project with its own subdomain and access policyOR-002MustDone--
FR-008Designate directories as "manual" (not managed by sync tool) so cleanup never touches themOR-006MustDone--
FR-009Provide a dry-run mode that outputs a diff summary: files to add, update, and remove, without making changesOR-007ShouldDone--
FR-010Provide a --verbose mode that logs per-file transformation details, link rewrites, and warningsOR-007ShouldDone--
FR-011Support a "readme" source adapter that scans a configured list of git repos and extracts README.md files for publishingOR-008ShouldDone--
FR-012Support a "structured-data" source adapter that reads YAML/JSON files and renders them as markdown documentation pages using configurable templatesOR-009CouldNot Started--
FR-013Support per-target Cloudflare Access policy configuration, including invite-only email lists for partner portalsOR-010CouldNot Started--
FR-014Validate that all documents tagged with a publish_to target have that target defined in config; warn on unknown targetsOR-004ShouldDone--
FR-015Support incremental sync: skip files whose source hash has not changed since last syncOR-001, OR-007ShouldDone--
FR-016Generate a post-sync summary report: documents added, updated, removed, failed, and warnings per targetOR-007ShouldDone--
FR-017Preserve existing content transformation pipeline (frontmatter rewriting, MDX escaping, Mermaid fixes, link rewriting, local path stripping)OR-004MustDone--
FR-018Support per-source and per-target transformation overrides in config (e.g., different link rewrite rules per source repo)OR-005CouldNot Started--
FR-019Support per-target content redaction rules in config that strip sections between HTML comment markers (e.g., <!-- begin:internal-only --> ... <!-- end:internal-only -->) before publishing to restricted-audience sitesOR-010, OR-004ShouldDone--
FR-020Support configurable field templates for structured data rendering, allowing different field sets per target site (e.g., minimal for partner, full for internal)OR-009CouldNot Started--

Non-Functional Requirements

IDCategoryRequirementTargetEnables OutcomeStatusVerified
NFR-001PerformanceFull sync of all configured sources completes within a reasonable time for the current content volume< 30 seconds for 200 documentsOR-001DoneValidated
NFR-002ReliabilitySync is idempotent -- running it multiple times with unchanged sources produces identical output100% deterministic outputOR-001DoneValidated
NFR-003SafetySync never modifies or deletes files outside of its managed directories0 accidental deletions of manual contentOR-006DoneValidated
NFR-004PortabilitySync tool runs on Windows (MSYS2/Git Bash), macOS, and Linux without platform-specific codeAll platforms pass CIOR-005DoneWindows verified
NFR-005ObservabilitySync produces structured, parseable output (not just console.log) suitable for CI/CD integrationMachine-readable JSON output optionOR-007DoneValidated
NFR-006SecurityNo sensitive data (API keys, credentials, personal contact info) is published to any site0 credential leaks per auditOR-004, OR-010DoneValidated
NFR-007MaintainabilityAdding a new source adapter requires implementing a defined interface, not modifying core sync logicAdapter interface documented; core untouched for new adaptersOR-005DoneValidated
NFR-008Backward CompatibilityExisting publish_to: [internal-wiki] and publish_to: [developer-docs] tags continue to work without modification to source documents100% backward compatibilityOR-004DoneValidated

Requirements Summary

CategoryTotalImplementedPartialNot Started
Outcome Requirements (Must)6600
Outcome Requirements (Should)3300
Outcome Requirements (Could)2002
Functional (Must)8800
Functional (Should)7700
Functional (Could)5005
Non-Functional8800

Traceability: Outcomes to Requirements

Outcome IDOutcomeOpportunitySolutionFunctional ReqsNFRs
OR-001No stale content on published sitesOPP-001SOL-001FR-001, FR-002, FR-003, FR-015NFR-001, NFR-002
OR-002Single publishing repositoryOPP-002SOL-003FR-006, FR-007-
OR-003Multi-source publishingOPP-003SOL-005FR-004NFR-004
OR-004Tag-based publication controlOPP-001SOL-001FR-005, FR-014, FR-017NFR-006, NFR-008
OR-005Config-driven extensibilityOPP-003, OPP-004SOL-005, SOL-006FR-004, FR-005, FR-018NFR-007
OR-006Manual content preservedOPP-002SOL-001FR-008NFR-003
OR-007Sync visibility and reportingOPP-001SOL-001FR-009, FR-010, FR-016NFR-005
OR-008Dev READMEs on dev siteOPP-003SOL-005FR-011-
OR-009Structured data as docsOPP-005SOL-007FR-012-
OR-010Partner portalOPP-004SOL-006FR-013NFR-006

Orphaned Requirements: None -- all requirements trace to at least one outcome.


User Stories

Enhanced Format

  1. As a documentation author, When I archive a document by moving it to the archive repo, I want to run sync and have the published copy automatically removed, So that readers never see outdated content, Which enables me to trust the published sites as the authoritative, current documentation, Measured by zero orphaned pages after any sync run.

  2. As a platform operator, When I need to add a new documentation source (e.g., a new dev repo), I want to add an entry to the config file and run sync, So that content flows to the right target site without code changes, Which enables me to scale the publishing platform as the organization grows, Measured by time to onboard a new source < 5 minutes.

  3. As a developer, When I update the README in my project repository, I want to have it appear on dev.symphonycore.com after the next sync, So that teammates can discover project documentation without visiting GitHub, Which enables me to keep documentation close to code while making it broadly accessible, Measured by README content matching source within one sync cycle.

  4. As a platform operator, When I run a sync, I want to first preview what will change (additions, updates, removals), So that I can catch unexpected changes before they go live, Which enables me to maintain confidence in the publishing pipeline, Measured by dry-run output accurately predicting actual sync results.

  5. As a business stakeholder, When I need to share confidential documentation with a partner, I want to tag the document with publish_to: [partner-portal] and have it appear on a restricted site, So that partners access only what they should see via a controlled, professional portal, Which enables me to reduce ad-hoc document sharing and improve partner experience, Measured by partner documents accessible only to invited email addresses.


Success Metrics

Leading Indicators (Activity Metrics)

MetricWhat It MeasuresTargetLinked Outcome
Sync runs per weekPipeline usage frequency>= 3 runs/weekOR-001
Source repos configuredPlatform adoption breadth>= 2 in MVP, >= 4 in Phase 2OR-003
Documents with publish_to tagsAuthor adoption of tagging>= 80% of publishable docs taggedOR-004
Dry-run usage rateOperator confidence in preview>= 50% of sync runs preceded by dry-runOR-007

Lagging Indicators (Outcome Metrics)

MetricWhat It MeasuresCurrent BaselineTargetTimelineBusiness Impact
Orphaned pages on published sitesStale content eliminationUnknown (no audit yet)0MVP launchReaders trust published content
Publishing repos maintainedInfrastructure consolidation2 (internal-docs + developer-docs)1MVP launch50% reduction in maintenance
Time to add new sourcePlatform extensibilityN/A (code change required)< 5 min (config only)MVP launchFaster content onboarding
Time to add new target sitePlatform extensibilityN/A (new repo required)< 30 min (config + CF Pages setup)Phase 2Faster audience expansion

North Star Metric

Primary metric: Percentage of published pages that match their source document (content accuracy rate) Target: 100% after every sync run Why this metric: The core value of a publishing platform is that what readers see matches what authors wrote -- no stale content, no missing content, no transformation errors.


Timeline & Milestones

MilestoneDescriptionTarget Date
MVP Sprint 1Manifest-based sync with stale content cleanup; multi-source config; dry-run with diffTBD
MVP Sprint 2Repo consolidation: merge developer-docs into internal-docs; single Docusaurus instanceTBD
Phase 2 Sprint 1README source adapter; structured data (YAML) rendererTBD
Phase 2 Sprint 2Partner portal (partner.symphonycore.com) with Cloudflare Access invite-only authTBD
Phase 3Research: customer-facing KB (help.symphonycore.com) migration and SEO strategyTBD

Dependencies

DependencyTypeImpactStatus
Cloudflare Pages project for consolidated siteTechnicalMust configure CF Pages to serve consolidated contentExisting (team.symphonycore.com)
Cloudflare Access policies for partner portalTechnicalNeed invite-only policy for partner.symphonycore.comNot started
symphony-core-documents repoExternalPrimary content source; no changes needed to source docsAvailable
Developer repo accessExternalNeed read access to configured dev repos for README syncAvailable (GitHub org)
Client registry YAMLExternalSource data for structured data publishingAvailable (symphony-flow repo)
DNS configuration for partner.symphonycore.comTechnicalNew subdomain needed for partner portalNot started

Constraints

ConstraintTypeDescription
Cloudflare Free TierBudget50-user cap on Cloudflare Access; login page template-based only (no custom HTML)
Windows compatibilityTechnicalTool must work on Windows (MSYS2/Git Bash); ASCII-safe output only
Existing tag formatTechnicalpublish_to: [internal-wiki, developer-docs] format must remain backward compatible
No CI/CD in MVPTechnicalSync is manually triggered; automated CI/CD triggers are deferred
Single operatorResourcePlatform operator is a single person; tool must be low-maintenance
Client registry sensitivitySecurityClient contact info (emails, phones) must be redacted or excluded from published pages

Risks & Mitigations

RiskLikelihoodImpactMitigation
Consolidation breaks existing URLs on team.symphonycore.com or dev.symphonycore.comMediumHighMap existing URL structures before consolidation; implement redirects if needed
Manifest corruption causes mass deletion of published contentLowHighFR-009 dry-run gate before destructive sync; backup manifest before overwriting
CLI catalog pages accidentally deleted by sync cleanupMediumHighFR-008 designates manual directories as protected; NFR-003 enforces boundary
Cloudflare 50-user cap blocks partner portal scalingLowMediumMonitor usage; evaluate paid tier if cap is reached
Source repo structure changes break sync routingMediumMediumFR-014 validates tags against config; warnings on unknown targets
Structured data contains sensitive info that gets publishedLowHighNFR-006 mandates redaction rules; FR-012 template controls which fields render

DocumentTypeRelationshipLink
Auth Evolution PRDPRDRelated (Cloudflare Access setup)prd-auth-evolution.md
Deploy Status PRDPRDRelated (deployment monitoring)prd-deploy-status.md
Sync Tool SourceCodeCurrent implementation being replacedsync-tool/src/
Developer Docs RepoCodeConsolidation sourceC:\Users\Rohit\workspace\Work\software\developer-docs
Client RegistryDataStructured data sourceC:\Users\Rohit\workspace\Work\software\symphony-flow\_outbox\client-registry.yaml

Glossary

TermDefinition
Sync manifestA JSON file tracking all files written by the sync tool, including source hash, target path, and timestamp
Source adapterA pluggable module that knows how to scan a specific type of source (markdown repo, README files, YAML data) and produce documents for the sync pipeline
Target siteA Docusaurus-powered website deployed to a specific subdomain with its own Cloudflare Access policy
Orphaned pageA published page whose source document no longer exists or no longer targets that site
Manual directoryA directory in the target repo that is excluded from sync cleanup because it contains manually-authored content
Publish tagThe publish_to YAML frontmatter field that controls which target sites receive a document

Resolved Decisions

#QuestionDecisionRationale
D-001URL structure for consolidated siteDocusaurus multi-instance with path prefixes (/team/*, /dev/*)Clear audience separation; easier to map Cloudflare Access policies per-path if needed
D-002Sync manifest storageCommitted to repo (version-controlled)Anyone who clones can sync with accurate state; git history shows what changed when
D-003Partner content modelFiltered subset -- authors add publish_to: [partner-portal] alongside other tagsSame doc can appear on internal + partner sites; simpler authoring
D-004Client registry renderingConfigurable per-field via templatesDifferent templates for different targets (minimal for partner, full for internal)
D-005dev.symphonycore.com handlingKeep as separate subdomain with separate Cloudflare Access policy, served from same repoDifferent people have access to dev vs team; consolidate code, not access
D-006Primary domainKeep team.symphonycore.comNo DNS disruption; familiar to users
D-007First sync run (no manifest)Sync only, no cleanupSafe default -- creates manifest without risking deletions; cleanup kicks in from second run onward
D-008Per-target content transformationConfig-driven redaction rules (e.g., strip <!-- internal-only --> sections for partner)Keeps author experience simple; global rules in config avoid per-doc complexity

Architecture: Multi-Subdomain from Single Repo

A key architectural pattern emerges from D-005: one repo, multiple Cloudflare Pages deployments, each with its own subdomain and access policy.

internal-docs/  (single repo)
├── sites/
│ ├── team/ # team.symphonycore.com -- Docusaurus instance
│ ├── dev/ # dev.symphonycore.com -- Docusaurus instance
│ └── partner/ # partner.symphonycore.com -- Docusaurus instance (Phase 2)
├── docs/
│ ├── synced/ # Content from sync pipeline
│ ├── cli/ # Migrated from developer-docs (manual)
│ └── ...
└── sync-tool/ # Unified publishing pipeline

Each subdomain is a separate Cloudflare Pages project pointing to the same repo but with different build commands/output directories and independent Cloudflare Access policies. This enables:

  • Shared sync tool and content pipeline
  • Per-subdomain access control (team = @symphonycore.com OTP, dev = approved dev emails, partner = invite-only)
  • Content routing via publish_to tags to specific site builds

Resolved Decisions (Continued)

#QuestionDecisionRationale
D-009Non-Docusaurus target sitesDocusaurus onlyKeeps pipeline simple -- one framework, one build system. If help.symphonycore.com needs a different framework, it gets a separate pipeline.
D-010Role-based content visibility within a single siteFuture consideration (Phase 3+)Subdomain-level access via Cloudflare Access is sufficient for now. Some content (financial, HR) may need restricted visibility later.
D-011Cloudflare Pages multi-site build strategySeparate CF Pages projects per subdomainEach project has its own build command (npm run build:team, npm run build:dev), output directory, and independent Cloudflare Access policy.
D-012Per-target redaction marker formatHTML comments (<!-- begin:internal-only --> ... <!-- end:internal-only -->)Invisible in rendered markdown, familiar syntax, easy to parse. Not coupled to MDX/Docusaurus.

Open Questions

All major architectural questions have been resolved. The following are minor implementation details to be decided during sprint planning:

  • Should the sync manifest include content checksums (SHA-256) or rely on file modification timestamps for change detection?
  • What naming convention for CF Pages build scripts? (build:team, build:dev, build:partner?)

Appendix

A. Litmus Test Findings

Req IDOriginal (Solution-Prescriptive)Rewritten (Solution-Neutral)Rationale
FR-001Store sync manifest as a JSON file in .sync-manifest.jsonMaintain a sync manifest that records all files written by the sync toolOriginal prescribed JSON format and file name; implementation should decide storage format
FR-007Use Docusaurus multi-instance plugin to serve team and dev docsConfigure Docusaurus to serve multiple site sections from a single instanceOriginal prescribed a specific Docusaurus plugin; multiple valid approaches exist
FR-011Clone configured repos and extract README.md filesSupport a "readme" source adapter that scans configured repos and extracts README filesOriginal prescribed git clone; could also use GitHub API, sparse checkout, or local paths

B. Current Sync Tool Architecture (for reference)

symphony-core-documents/
|
v (scan for publish_to tags)
sync-tool/
├── scanner.ts -- glob *.md, parse frontmatter, filter by publish_to
├── router.ts -- compute destination paths, strip number prefixes
├── transformer.ts -- frontmatter rewrite, MDX escape, Mermaid fix, link rewrite
├── publisher.ts -- mkdir + writeFile (NO deletion logic)
└── cli.ts -- commander CLI, config loading, orchestration
|
v (write files)
docs/synced/ (internal-wiki target)
../developer-docs/docs/ (developer-docs target, cross-repo)

C. Developer-Docs Repo Analysis

Recommendation: Merge into internal-docs.

AspectFinding
FrameworkSame (Docusaurus 3.8.1 vs 3.9.2)
DeploymentSame (Cloudflare Pages)
AuthSame (Cloudflare Access OTP)
SearchSame (@easyops-cn/docusaurus-search-local)
Sync toolNone -- depends on internal-docs
Unique contentCLI Command Catalog (48 pages in docs/cli/)
Synced contentArchitecture, reference, sprints from symphony-core-documents

The CLI catalog is the only unique, manually-authored content. It can be migrated to docs/cli/ in the consolidated repo. All synced content will be handled by the unified pipeline. Docusaurus version should be aligned to 3.9.2.

D. Suggested Value-Added Features (Beyond Core Requirements)

These features were identified during discovery as potential enhancements that would add significant value to a content publishing platform of this nature:

  1. Content health dashboard: A generated page showing sync status, document count per target, last sync timestamp, and any warnings -- gives operators at-a-glance platform health
  2. Broken link detection: Post-sync validation that checks all internal links resolve to actual pages; report broken links before deployment
  3. Document dependency graph: Visualize which documents reference each other across sites; identify impact when a document is archived
  4. Content freshness indicators: Display "last updated" badges on published pages; flag documents not updated in > 90 days
  5. Automated sync via GitHub Actions: Trigger sync on push to any configured source repo; create PR with changes for review before merge
  6. Content search across all sites: Unified search index spanning team, dev, and partner sites (respecting access controls)
  7. Diff preview in PR: When sync creates a PR, include a human-readable diff of content changes (not just file-level)
  8. Publish audit log: Persistent log of all sync operations -- who ran it, what changed, when -- for compliance and debugging
  9. Template-based rendering for non-markdown sources: Extensible template system for rendering YAML, JSON, CSV, or API responses as documentation pages
  10. Content approval workflow: Optional review gate where tagged documents require approval before publishing to restricted sites (e.g., partner portal)

E. References


End of Document