
Confluence Expert
- 722 installs
- 23.5k repo stars
- Updated July 17, 2026
- alirezarezvani/claude-skills
confluence-expert is an agent skill that designs Atlassian Confluence spaces, templates, permissions, and documentation governance for developers who need a wiki structure that matches how their team ships software.
About
confluence-expert is a skill from alirezarezvani/claude-skills that provides master-level Confluence space management for engineering documentation. It configures space permissions and hierarchies, creates page templates with macros, sets documentation taxonomies, designs layouts, embeds Jira reports, and runs knowledge-base audits. Developers reach for it when building or restructuring a Confluence space, standardizing templates, establishing documentation standards, or aligning wiki governance with shipping workflows. The skill targets collaborative documentation systems rather than in-repo markdown alone.
- End-to-end Confluence space lifecycle: create spaces, pages, updates, deletes, and CQL search
- Atlassian MCP operations for pages, versions, labels, and parent-child hierarchies
- Page templates with macros plus documentation taxonomy and layout design
- Space permission structures and content governance workflows
- Jira report embedding and knowledge-base audit guidance
Confluence Expert by the numbers
- 722 all-time installs (skills.sh)
- Ranked #327 of 1,881 Documentation skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Jul 31, 2026 (Skillselion catalog sync)
npx skills add https://github.com/alirezarezvani/claude-skills --skill confluence-expertAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 722 |
|---|---|
| repo stars | ★ 23.5k |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 17, 2026 |
| Repository | alirezarezvani/claude-skills ↗ |
How do you structure a Confluence space for engineering docs?
Structure Confluence spaces, templates, permissions, and governance so your team wiki matches how you actually ship software.
Who is it for?
Developers or tech leads setting up or overhauling Confluence as the team's primary engineering knowledge base.
Skip if: Teams documenting solely in-repo with Markdown or wikis that do not use Atlassian Confluence.
When should I use this skill?
The user needs to build, restructure, audit, or standardize a Confluence space, templates, or documentation governance.
What you get
Confluence space hierarchy, page templates with macros, permission model, and documentation governance standards.
- space hierarchy plan
- page templates
- governance standards
Files
Atlassian Confluence Expert
Master-level expertise in Confluence space management, documentation architecture, content creation, macros, templates, and collaborative knowledge management.
Atlassian MCP Integration
Primary Tool: Atlassian Remote MCP server (bundled .mcp.json, server key atlassian). Tools are camelCase and surface as mcp__atlassian__<toolName>. Canonical tool list: project-management/references/atlassian-mcp-tools.md. Never invent tool names — if a capability isn't in that list, it is not available via MCP.
Key Operations (obtain cloudId once via mcp__atlassian__getAccessibleAtlassianResources):
// List spaces (space CREATION is not available via MCP — see below)
mcp__atlassian__getConfluenceSpaces (cloudId)
// Create a page under a parent — body must be storage-format XHTML or ADF, never wiki markup
mcp__atlassian__createConfluencePage (cloudId, space, title="Sprint 42 Notes", parent page id, body="<p>Meeting notes in storage-format XHTML</p>")
// Update an existing page (fetch current version with getConfluencePage, then supply version + 1)
mcp__atlassian__updateConfluencePage (cloudId, pageId="789012", version=5, body="<p>Updated content</p>")
// Read a page (body + current version)
mcp__atlassian__getConfluencePage (cloudId, pageId="789012")
// Search with CQL
mcp__atlassian__searchConfluenceUsingCql (cloudId, cql='space = "TEAM" AND label = "meeting-notes" ORDER BY lastModified DESC')
// Retrieve child pages for hierarchy inspection
mcp__atlassian__getConfluencePageDescendants (cloudId, pageId="123456")
// Comments
mcp__atlassian__getConfluencePageFooterComments / mcp__atlassian__createConfluenceFooterComment (cloudId, pageId)Not available via MCP — use the web UI or REST API instead:
- Create/delete a space → Confluence UI
Spaces > Create spaceorPOST /wiki/api/v2/spaces - Delete a page → Confluence UI or
DELETE /wiki/api/v2/pages/{id} - Apply labels → Confluence UI or
/wiki/rest/api/content/{id}/label - Space permissions, templates/blueprints as first-class objects → Confluence space settings UI
Integration Points:
- Create documentation for Senior PM projects
- Support Scrum Master with ceremony templates
- Link to Jira issues for Jira Expert
- Provide templates for Template Creator
See also:references/macro-cheat-sheet.mdfor storage-format macro syntax,references/templates.mdfor the template library,references/space-architecture-patterns.mdfor space structure and permission patterns.
Workflows
Space Creation
Space creation is not available via MCP — create the space in the Confluence UI (Spaces > Create space) or via REST (POST /wiki/api/v2/spaces). The page tree inside it CAN be built via MCP (mcp__atlassian__createConfluencePage).
0. Generate the recommended hierarchy from a team description:
python3 scripts/space_structure_generator.py team_info.json --format jsonInput: JSON with team name, size, type, projects. Consume the output: use the emitted page tree as the creation plan for step 5 — one mcp__atlassian__createConfluencePage call per node, passing the parent page id to nest children. 1. Determine space type (Team, Project, Knowledge Base, Personal) 2. Create space with clear name and description (web UI / REST) 3. Set space homepage with overview 4. Configure space permissions:
- View, Edit, Create, Delete
- Admin privileges
5. Create initial page tree structure 6. Add space shortcuts for navigation 7. Verify: Navigate to the space URL and confirm the homepage loads; check that a non-admin test user sees the correct permission level 8. HANDOFF TO: Teams for content population
Page Architecture
Best Practices:
- Use page hierarchy (parent-child relationships)
- Maximum 3 levels deep for navigation
- Consistent naming conventions
- Date-stamp meeting notes
Recommended Structure:
Space Home
├── Overview & Getting Started
├── Team Information
│ ├── Team Members & Roles
│ ├── Communication Channels
│ └── Working Agreements
├── Projects
│ ├── Project A
│ │ ├── Overview
│ │ ├── Requirements
│ │ └── Meeting Notes
│ └── Project B
├── Processes & Workflows
├── Meeting Notes (Archive)
└── Resources & ReferencesTemplate Creation
1. Identify repeatable content pattern 2. Create page with structure and placeholders 3. Add instructions in placeholders 4. Format with appropriate macros 5. Save as template 6. Share with space or make global 7. Verify: Create a test page from the template and confirm all placeholders render correctly before sharing with the team 8. USE: References for advanced template patterns
Documentation Strategy
1. Assess current documentation state 2. Define documentation goals and audience 3. Organize content taxonomy and structure 4. Create templates and guidelines 5. Migrate existing documentation 6. Train teams on best practices 7. Monitor usage and adoption 8. REPORT TO: Senior PM on documentation health
Knowledge Base Management
Run a content health audit before any restructure or governance review:
python3 scripts/content_audit_analyzer.py pages.json --format jsonInput: a JSON page inventory (title, last_modified, view_count, author, labels, word_count) — build it by exporting page metadata via mcp__atlassian__getPagesInConfluenceSpace / mcp__atlassian__searchConfluenceUsingCql. Consume the output: the stale/orphaned/low-engagement findings become the archive list (label + move via UI, since label tools aren't on the MCP) and the update backlog for the quality standards below.
Article Types:
- How-to guides
- Troubleshooting docs
- FAQs
- Reference documentation
- Process documentation
Quality Standards:
- Clear title and description
- Structured with headings
- Updated date visible
- Owner identified
- Reviewed quarterly
Essential Macros
Syntax note: The{macro}shorthand below is legacy wiki-markup notation, shown for readability only. Confluence Cloud pages created via MCP (createConfluencePage/updateConfluencePage) require storage format (XHTML) — e.g.{info}is really<ac:structured-macro ac:name="info"><ac:rich-text-body>...</ac:rich-text-body></ac:structured-macro>. For the storage-format syntax of every macro listed here, seereferences/macro-cheat-sheet.md; for ready-made storage-format page bodies, run the atlassian-templates scaffolder (python3 ../atlassian-templates/scripts/template_scaffolder.py meeting-notes).
Content Macros
Info, Note, Warning, Tip:
{info}
Important information here
{info}Expand:
{expand:title=Click to expand}
Hidden content here
{expand}Table of Contents:
{toc:maxLevel=3}Excerpt & Excerpt Include:
{excerpt}
Reusable content
{excerpt}
{excerpt-include:Page Name}Dynamic Content
Jira Issues:
{jira:JQL=project = PROJ AND status = "In Progress"}Jira Chart:
{jirachart:type=pie|jql=project = PROJ|statType=statuses}Recently Updated:
{recently-updated:spaces=@all|max=10}Content by Label:
{contentbylabel:label=meeting-notes|maxResults=20}Collaboration Macros
Status:
{status:colour=Green|title=Approved}Task List:
{tasks}
- [ ] Task 1
- [x] Task 2 completed
{tasks}User Mention:
@usernameDate:
{date:format=dd MMM yyyy}Page Layouts & Formatting
Two-Column Layout:
{section}
{column:width=50%}
Left content
{column}
{column:width=50%}
Right content
{column}
{section}Panel:
{panel:title=Panel Title|borderColor=#ccc}
Panel content
{panel}Code Block:
{code:javascript}
const example = "code here";
{code}Templates Library
Full template library with complete markup: see references/templates.md. Key templates summarised below.| Template | Purpose | Key Sections |
|---|---|---|
| Meeting Notes | Sprint/team meetings | Agenda, Discussion, Decisions, Action Items (tasks macro) |
| Project Overview | Project kickoff & status | Quick Facts panel, Objectives, Stakeholders table, Milestones (Jira macro), Risks |
| Decision Log | Architectural/strategic decisions | Context, Options Considered, Decision, Consequences, Next Steps |
| Sprint Retrospective | Agile ceremony docs | What Went Well (info), What Didn't (warning), Action Items (tasks), Metrics |
Space Permissions
Permission patterns by space type: seereferences/space-architecture-patterns.md. Note: space permissions are configured in the Confluence UI (Space settings > Permissions) — not via MCP.
Permission Schemes
Public Space:
- All users: View
- Team members: Edit, Create
- Space admins: Admin
Team Space:
- Team members: View, Edit, Create
- Team leads: Admin
- Others: No access
Project Space:
- Stakeholders: View
- Project team: Edit, Create
- PM: Admin
Content Governance
Review Cycles:
- Critical docs: Monthly
- Standard docs: Quarterly
- Archive docs: Annually
Archiving Strategy:
- Move outdated content to Archive space
- Label with "archived" and date
- Maintain for 2 years, then delete
- Keep audit trail
Content Quality Checklist:
- [ ] Clear, descriptive title
- [ ] Owner/author identified
- [ ] Last updated date visible
- [ ] Appropriate labels applied
- [ ] Links functional
- [ ] Formatting consistent
- [ ] No sensitive data exposed
Decision Framework
When to Escalate to Atlassian Admin:
- Need org-wide template
- Require cross-space permissions
- Blueprint configuration
- Global automation rules
- Space export/import
When to Collaborate with Jira Expert:
- Embed Jira queries and charts
- Link pages to Jira issues
- Create Jira-based reports
- Sync documentation with tickets
When to Support Scrum Master:
- Sprint documentation templates
- Retrospective pages
- Team working agreements
- Process documentation
When to Support Senior PM:
- Executive report pages
- Portfolio documentation
- Stakeholder communication
- Strategic planning docs
Handoff Protocols
FROM Senior PM:
- Documentation requirements
- Space structure needs
- Template requirements
- Knowledge management strategy
TO Senior PM:
- Documentation coverage reports
- Content usage analytics
- Knowledge gaps identified
- Template adoption metrics
FROM Scrum Master:
- Sprint ceremony templates
- Team documentation needs
- Meeting notes structure
- Retrospective format
TO Scrum Master:
- Configured templates
- Space for team docs
- Training on best practices
- Documentation guidelines
WITH Jira Expert:
- Jira-Confluence linking
- Embedded Jira reports
- Issue-to-page connections
- Cross-tool workflow
Best Practices
Organization:
- Consistent naming conventions
- Meaningful labels
- Logical page hierarchy
- Related pages linked
- Clear navigation
Maintenance:
- Regular content audits
- Remove duplication
- Update outdated information
- Archive obsolete content
- Monitor page analytics
Analytics & Metrics
Usage Metrics:
- Page views per space
- Most visited pages
- Search queries
- Contributor activity
- Orphaned pages
Health Indicators:
- Pages without recent updates
- Pages without owners
- Duplicate content
- Broken links
- Empty spaces
Related Skills
- Jira Expert (
project-management/jira-expert/) — Jira issue macros and linking complement Confluence docs - Atlassian Templates (
project-management/atlassian-templates/) — Template patterns for Confluence content creation
Confluence Macro Cheat Sheet
Overview
Quick reference for the most commonly used Confluence macros. Each entry includes the macro name, storage format syntax, primary use case, and practical tips.
Navigation & Structure Macros
Table of Contents
- Purpose: Auto-generate a linked table of contents from page headings
- Syntax:
<ac:structured-macro ac:name="toc" /> - Parameters:
maxLevel(1-6),minLevel(1-6),style(disc, circle, square, none),type(list, flat) - Use case: Long documentation pages, meeting notes, specifications
- Tip: Set
maxLevel="3"to avoid overly deep TOC entries
Children Display
- Purpose: List child pages of the current page
- Syntax:
<ac:structured-macro ac:name="children" /> - Parameters:
depth(1-999),sort(title, creation, modified),style(h2-h6),all(true/false) - Use case: Parent hub pages, project homepages, documentation indexes
- Tip: Use
depth="1"for clean navigation,all="true"for deep hierarchies
Include Page
- Purpose: Embed content from another page inline
- Syntax:
<ac:structured-macro ac:name="include"><ac:parameter ac:name=""><ac:link><ri:page ri:content-title="Page Name" /></ac:link></ac:parameter></ac:structured-macro> - Use case: Reusable content blocks (headers, footers, disclaimers)
- Tip: Changes to the source page are reflected everywhere it is included
Page Properties
- Purpose: Define structured metadata on a page (key-value pairs)
- Syntax:
<ac:structured-macro ac:name="details">with table inside - Use case: Project metadata, status tracking, structured page data
- Tip: Combine with Page Properties Report macro to create dashboards
Page Properties Report
- Purpose: Display a table of Page Properties from child pages
- Syntax:
<ac:structured-macro ac:name="detailssummary" /> - Parameters:
cql(CQL filter),labels(filter by label) - Use case: Project dashboards, status rollups, portfolio views
- Tip: Use labels to scope the report to relevant pages only
Visual & Formatting Macros
Info Panel
- Purpose: Blue information callout box
- Syntax:
<ac:structured-macro ac:name="info"><ac:rich-text-body>Content</ac:rich-text-body></ac:structured-macro> - Use case: Helpful notes, additional context, best practices
Warning Panel
- Purpose: Yellow warning callout box
- Syntax:
<ac:structured-macro ac:name="warning"><ac:rich-text-body>Content</ac:rich-text-body></ac:structured-macro> - Use case: Important caveats, deprecation notices, breaking changes
Note Panel
- Purpose: Yellow note callout box
- Syntax:
<ac:structured-macro ac:name="note"><ac:rich-text-body>Content</ac:rich-text-body></ac:structured-macro> - Use case: Reminders, action items, things to watch
Tip Panel
- Purpose: Green tip callout box
- Syntax:
<ac:structured-macro ac:name="tip"><ac:rich-text-body>Content</ac:rich-text-body></ac:structured-macro> - Use case: Pro tips, shortcuts, recommended approaches
Expand
- Purpose: Collapsible content section (click to expand)
- Syntax:
<ac:structured-macro ac:name="expand"><ac:parameter ac:name="title">Click to expand</ac:parameter><ac:rich-text-body>Hidden content</ac:rich-text-body></ac:structured-macro> - Use case: Long sections, FAQs, detailed explanations, optional reading
- Tip: Use for content that not all readers need
Status
- Purpose: Colored status lozenge (inline label)
- Syntax:
<ac:structured-macro ac:name="status"><ac:parameter ac:name="colour">Green</ac:parameter><ac:parameter ac:name="title">DONE</ac:parameter></ac:structured-macro> - Colors: Grey, Red, Yellow, Green, Blue
- Use case: Task status, review state, approval status
- Tip: Standardize status values across your team (e.g., TODO, IN PROGRESS, DONE)
Integration Macros
Jira Issues
- Purpose: Display Jira issues or JQL query results
- Syntax:
<ac:structured-macro ac:name="jira"><ac:parameter ac:name="jqlQuery">project = PROJ AND status = Open</ac:parameter></ac:structured-macro> - Parameters:
jqlQuery,columns(key, summary, status, assignee, etc.),count(true/false),serverId - Use case: Sprint boards in documentation, requirement traceability, release notes
- Tip: Use
columnsparameter to show only relevant fields
Roadmap Planner
- Purpose: Visual timeline/Gantt view of items
- Syntax: Available via macro browser (Roadmap Planner)
- Use case: Project timelines, release planning, milestone tracking
- Tip: Link roadmap items to Jira epics for automatic status updates
Chart Macro
- Purpose: Create charts from table data on the page
- Syntax:
<ac:structured-macro ac:name="chart"><ac:parameter ac:name="type">pie</ac:parameter><ac:rich-text-body>Table data</ac:rich-text-body></ac:structured-macro> - Types: pie, bar, line, area, scatter, timeSeries
- Use case: Status distribution, metrics dashboards, trend visualization
- Tip: Place a Confluence table inside the macro body as data source
Content Reuse Macros
Excerpt
- Purpose: Mark a section of content for reuse via Excerpt Include
- Syntax:
<ac:structured-macro ac:name="excerpt"><ac:rich-text-body>Reusable content</ac:rich-text-body></ac:structured-macro> - Use case: Define canonical content blocks (product descriptions, team info)
Excerpt Include
- Purpose: Display an Excerpt from another page
- Syntax:
<ac:structured-macro ac:name="excerpt-include"><ac:parameter ac:name=""><ac:link><ri:page ri:content-title="Source Page" /></ac:link></ac:parameter></ac:structured-macro> - Use case: Embed product descriptions, standard disclaimers, shared definitions
Advanced Macros
Code Block
- Purpose: Display formatted code with syntax highlighting
- Syntax:
<ac:structured-macro ac:name="code"><ac:parameter ac:name="language">python</ac:parameter><ac:plain-text-body>code here</ac:plain-text-body></ac:structured-macro> - Languages: java, python, javascript, sql, bash, xml, json, and many more
- Use case: API documentation, configuration examples, code snippets
Anchor
- Purpose: Create a named anchor point for deep linking
- Syntax:
<ac:structured-macro ac:name="anchor"><ac:parameter ac:name="">anchor-name</ac:parameter></ac:structured-macro> - Use case: Link directly to specific sections within long pages
- Tip: Use with TOC macro for custom navigation
Recently Updated
- Purpose: Show recently modified pages in a space
- Syntax:
<ac:structured-macro ac:name="recently-updated" /> - Parameters:
spaces,labels,types,max - Use case: Team dashboards, space homepages, activity feeds
Macro Selection Guide
| Need | Recommended Macro |
|---|---|
| Page navigation | Table of Contents |
| List child pages | Children Display |
| Reuse content | Include Page or Excerpt Include |
| Status tracking | Status + Page Properties |
| Project dashboard | Page Properties Report |
| Hide optional content | Expand |
| Show Jira data | Jira Issues |
| Visualize data | Chart |
| Code documentation | Code Block |
| Important callouts | Info/Warning/Note/Tip panels |
Confluence Space Architecture Patterns
Overview
Well-organized Confluence spaces dramatically improve information discoverability and team productivity. This guide covers proven space organization patterns, page hierarchy best practices, and governance strategies.
Space Organization Patterns
Pattern 1: By Team
Each team or department gets its own space.
Structure:
Engineering Space (ENG)
Product Space (PROD)
Marketing Space (MKT)
Design Space (DES)
Support Space (SUP)Pros:
- Clear ownership and permissions
- Teams control their own content
- Natural permission boundaries
- Easy to find team-specific content
Cons:
- Cross-team content duplication
- Silos between departments
- Hard to find project-spanning information
- Inconsistent practices across spaces
Best for: Organizations with stable teams and clear departmental boundaries
Pattern 2: By Project
Each major project or product gets its own space.
Structure:
Project Alpha Space (ALPHA)
Project Beta Space (BETA)
Platform Infrastructure Space (PLAT)
Internal Tools Space (TOOLS)Pros:
- All project context in one place
- Easy onboarding for project members
- Clean archival when project completes
- Natural lifecycle management
Cons:
- Team knowledge scattered across spaces
- Permission management per project
- Space proliferation over time
- Ongoing vs project work separation unclear
Best for: Project-based organizations, agencies, consulting firms
Pattern 3: By Domain (Hybrid)
Combine functional spaces with cross-cutting project spaces.
Structure:
Company Wiki (WIKI) - Shared knowledge
Engineering Standards (ENG) - Team practices
Product Specs (PROD) - Requirements and roadmap
Project Alpha (ALPHA) - Cross-team project
Project Beta (BETA) - Cross-team project
Archive (ARCH) - Completed projectsPros:
- Balances team and project needs
- Shared knowledge has a home
- Clear archival path
- Scales with organization growth
Cons:
- More complex to set up initially
- Requires governance to maintain
- Some ambiguity about where content belongs
Best for: Growing organizations, 50-500 people, multiple concurrent projects
Page Hierarchy Best Practices
Recommended Depth
- Maximum 4 levels deep - Deeper hierarchies become hard to navigate
- 3 levels ideal for most content types
- Use flat structures with labels for categorization beyond 4 levels
Standard Page Hierarchy
Space Home (overview, quick links, recent updates)
├── Getting Started
│ ├── Onboarding Guide
│ ├── Tool Setup
│ └── Key Contacts
├── Projects
│ ├── Project Alpha
│ │ ├── Requirements
│ │ ├── Design
│ │ └── Meeting Notes
│ └── Project Beta
├── Processes
│ ├── Development Workflow
│ ├── Release Process
│ └── On-Call Runbook
├── References
│ ├── Architecture Decisions
│ ├── API Documentation
│ └── Glossary
└── Archive
├── 2025 Projects
└── Deprecated ProcessesPage Naming Conventions
- Use clear, descriptive titles (not abbreviations)
- Include date for time-sensitive content: "2025-Q1 Planning"
- Prefix meeting notes with date: "2025-03-15 Sprint Review"
- Use consistent casing (Title Case or Sentence case, not both)
- Avoid special characters that break URLs
Space Homepage Design
Every space homepage should include: 1. Space purpose - One paragraph describing what this space is for 2. Quick links - 5-7 most accessed pages 3. Recent updates - Recently Updated macro filtered to this space 4. Getting started - Link to onboarding content for new members 5. Contact info - Space owner, key contributors
Labeling Taxonomy
Label Categories
- Content type:
meeting-notes,decision,specification,runbook,retrospective - Status:
draft,in-review,approved,deprecated,archived - Team:
team-engineering,team-product,team-design - Project:
project-alpha,project-beta - Priority:
high-priority,p1,critical
Labeling Best Practices
- Use lowercase, hyphenated labels (no spaces or camelCase)
- Define a standard label vocabulary and document it
- Use labels for cross-space categorization
- Combine labels with CQL for powerful search and reporting
- Audit labels quarterly to remove unused or inconsistent labels
- Limit to 3-5 labels per page (over-labeling reduces value)
CQL Examples for Label-Based Queries
# All meeting notes in a space
type = page AND space = "ENG" AND label = "meeting-notes"
# All approved specifications
type = page AND label = "specification" AND label = "approved"
# Recent decisions across all spaces
type = page AND label = "decision" AND lastModified > now("-30d")Cross-Space Linking
When to Link vs Duplicate
- Link when content has a single source of truth
- Duplicate (Include Page macro) when content must appear in multiple contexts
- Excerpt Include when only a portion of a page is needed elsewhere
Linking Best Practices
- Use full page titles in links for clarity
- Add context around links ("See the [Architecture Decision Record] for rationale")
- Avoid orphan pages - every page should be reachable from space navigation
- Use the Recently Updated macro on hub pages for activity visibility
- Create "Related Pages" sections at the bottom of content pages
Archive Strategy
When to Archive
- Project completed more than 90 days ago
- Process or document officially deprecated
- Content not updated in 12+ months
- Replaced by newer content
Archive Process
1. Add archived label to the page 2. Move to Archive section within the space (or dedicated Archive space) 3. Add a note at the top: "This page is archived as of [date]. See [replacement] for current information." 4. Update any incoming links to point to current content 5. Do NOT delete - archived content has historical value
Archive Space Pattern
- Create a dedicated
Archivespace for completed projects - Move entire project page trees to Archive space on completion
- Set Archive space to read-only permissions
- Review Archive space annually for content that can be deleted
Permission Inheritance Patterns
Pattern 1: Open by Default
- All spaces readable by all employees
- Edit restricted to space members
- Admin restricted to space owners
- Best for: Transparency-focused organizations
Pattern 2: Restricted by Default
- Spaces accessible only to specific groups
- Request access via space admin
- Best for: Regulated industries, confidential projects
Pattern 3: Tiered Access
- Public tier: Company wiki, shared processes
- Team tier: Team-specific spaces with team access
- Restricted tier: HR, finance, legal with limited access
- Best for: Most organizations (balanced approach)
Permission Tips
- Use Confluence groups, not individual users, for permissions
- Align groups with LDAP/SSO groups where possible
- Audit permissions quarterly
- Document permission model on the space homepage
- Use page-level restrictions sparingly (breaks inheritance, hard to audit)
Scaling Considerations
< 50 People
- 3-5 spaces total
- Simple by-team pattern
- Light governance
50-200 People
- 10-20 spaces
- Hybrid pattern (team + project)
- Formal labeling taxonomy
- Quarterly content reviews
200+ People
- 20-50+ spaces
- Full domain pattern with governance
- Space owners and content stewards
- Automated archival policies
- Regular information architecture reviews
Confluence Page Templates
Meeting Notes Template
# [Meeting Title] - [Date]
**Date:** [YYYY-MM-DD]
**Time:** [HH:MM - HH:MM]
**Location:** [Room/Video link]
**Attendees:** @[Name1], @[Name2], @[Name3]
**Note Taker:** @[Name]
## Agenda
1. [Topic 1]
2. [Topic 2]
3. [Topic 3]
## Discussion
### [Topic 1]
**Summary:**
[Key points discussed]
**Decisions:**
- [Decision 1]
- [Decision 2]
**Action Items:**
- [ ] [Action] - @[Owner] - [Due Date]
- [ ] [Action] - @[Owner] - [Due Date]
### [Topic 2]
**Summary:**
[Key points discussed]
**Decisions:**
- [Decision 1]
**Action Items:**
- [ ] [Action] - @[Owner] - [Due Date]
## Parking Lot
- [Item to discuss later]
- [Future topic]
## Next Meeting
**Date:** [YYYY-MM-DD]
**Agenda Topics:**
- [Topic 1]
- [Topic 2]---
Decision Log Template
# [Decision Title]
| Field | Value |
|-------|-------|
| **Status** | 🟢 Accepted / 🟡 Proposed / 🔴 Deprecated |
| **Date** | [YYYY-MM-DD] |
| **Deciders** | @[Name1], @[Name2] |
| **Stakeholders** | @[Name3], @[Name4] |
| **Related Decisions** | [Link to related decisions] |
## Context and Problem Statement
[Describe the context and problem that requires a decision. 2-3 paragraphs explaining:
- What situation led to this decision?
- What problem are we trying to solve?
- What constraints exist?]
## Decision
[Clearly state the decision made in 1-2 sentences]
### Details
[Provide additional details about the decision:
- What exactly will we do?
- How will it be implemented?
- What timeline?]
## Rationale
[Explain why this decision was made:
- What were the key factors?
- What evidence supports this?
- Why is this the best choice?]
## Consequences
### Positive Consequences
- ✅ [Benefit 1]
- ✅ [Benefit 2]
- ✅ [Benefit 3]
### Negative Consequences / Trade-offs
- ⚠️ [Trade-off 1]
- ⚠️ [Trade-off 2]
### Risks
- 🔴 [Risk 1] - Mitigation: [How we'll handle it]
- 🟡 [Risk 2] - Mitigation: [How we'll handle it]
## Alternatives Considered
### Alternative 1: [Name]
**Description:** [What is this alternative?]
**Pros:**
- [Pro 1]
- [Pro 2]
**Cons:**
- [Con 1]
- [Con 2]
**Why Not Chosen:** [Reason]
### Alternative 2: [Name]
[Same structure as above]
## Implementation Plan
1. [Step 1] - @[Owner] - [Date]
2. [Step 2] - @[Owner] - [Date]
3. [Step 3] - @[Owner] - [Date]
## Success Metrics
- [Metric 1]: [Target]
- [Metric 2]: [Target]
## Review Date
**Next Review:** [YYYY-MM-DD]
**Review Notes:** [Link to review page]
## References
- [Link 1]
- [Link 2]
- [Link 3]
---
*Updated: [Date] by @[Name]*---
Technical Specification Template
# [Feature/Component Name] Technical Specification
| Field | Value |
|-------|-------|
| **Status** | 🟡 Draft / 🟢 Approved / 🔴 Archived |
| **Author** | @[Name] |
| **Reviewers** | @[Name1], @[Name2] |
| **Date Created** | [YYYY-MM-DD] |
| **Last Updated** | [YYYY-MM-DD] |
| **JIRA Epic** | [ABC-123](link) |
## Overview
[1-2 paragraph summary of what this spec covers and why it matters]
## Goals and Non-Goals
### Goals
- [Goal 1]
- [Goal 2]
- [Goal 3]
### Non-Goals (Out of Scope)
- [Non-goal 1]
- [Non-goal 2]
## Background
[Context needed to understand this spec:
- What problem are we solving?
- What's the current state?
- Why now?]
## High-Level Design
### Architecture Diagram
[Insert diagram here]
### System Components
1. **[Component 1 Name]**
- Purpose: [What it does]
- Technology: [What it uses]
- Interfaces: [How it connects]
2. **[Component 2 Name]**
- Purpose: [What it does]
- Technology: [What it uses]
- Interfaces: [How it connects]
### Data Flow
[Describe how data flows through the system]
## Detailed Design
### Component 1: [Name]
**Purpose:** [Detailed purpose]
**Responsibilities:**
- [Responsibility 1]
- [Responsibility 2]
**API/Interface:**[API spec or interface definition]
**Data Model:**[Schema or data structure]
**Key Algorithms/Logic:**
[Describe any complex logic]
### Component 2: [Name]
[Same structure as Component 1]
## Database Schema
### Table: [table_name]
| Column | Type | Constraints | Description |
|--------|------|-------------|-------------|
| id | UUID | PRIMARY KEY | Unique identifier |
| name | VARCHAR(255) | NOT NULL | Entity name |
| created_at | TIMESTAMP | NOT NULL | Creation timestamp |
### Indexes
- `idx_name` on `name` - For fast lookups
- `idx_created` on `created_at` - For temporal queries
## API Specification
### Endpoint: [Method] /api/path
**Purpose:** [What this endpoint does]
**Request:**{ "param1": "value", "param2": 123 }
**Response:**{ "result": "success", "data": {} }
**Error Handling:**
- 400: [Reason]
- 404: [Reason]
- 500: [Reason]
## Security Considerations
- [Security consideration 1]
- [Security consideration 2]
- [Authentication/Authorization approach]
- [Data encryption requirements]
## Performance Considerations
- [Expected load/throughput]
- [Scalability approach]
- [Caching strategy]
- [Performance targets]
## Testing Strategy
### Unit Tests
- [Test area 1]
- [Test area 2]
### Integration Tests
- [Test scenario 1]
- [Test scenario 2]
### Performance Tests
- [Load test plan]
- [Performance benchmarks]
## Deployment Plan
1. [Deployment step 1]
2. [Deployment step 2]
3. [Deployment step 3]
### Rollback Plan
[How to revert if issues occur]
## Monitoring and Alerting
- [Metric 1] - Alert threshold: [Value]
- [Metric 2] - Alert threshold: [Value]
- [Log tracking]
## Migration Plan (if applicable)
[How to migrate from current system]
## Dependencies
- [Dependency 1] - Why needed
- [Dependency 2] - Why needed
## Open Questions
- [ ] [Question 1] - @[Owner]
- [ ] [Question 2] - @[Owner]
## Future Considerations
- [Future enhancement 1]
- [Future enhancement 2]
## References
- [Link to related specs]
- [Link to design docs]
- [Link to JIRA epics]
---
*For questions, contact @[Author]*---
How-To Guide Template
# How to [Task Name]
## Overview
[1-2 sentences explaining what this guide covers and who it's for]
**Estimated Time:** [X minutes]
**Difficulty:** [Beginner/Intermediate/Advanced]
## Prerequisites
Before you begin, ensure you have:
- [ ] [Prerequisite 1]
- [ ] [Prerequisite 2]
- [ ] [Prerequisite 3]
## Quick Summary (TL;DR)
[One paragraph with the essence of the guide for those who just need a reminder]
## Step-by-Step Instructions
### Step 1: [Action]
[Detailed description of what to do]
**Commands/Code:**command here
**Expected Result:**
[What you should see if it worked]
**Screenshot:**
[Add screenshot if helpful]
### Step 2: [Action]
[Detailed description]
**Tips:**
- 💡 [Helpful tip]
- ⚠️ [Warning about common mistake]
### Step 3: [Action]
[Continue pattern...]
## Verification
To verify everything worked:
1. [Check 1]
2. [Check 2]
## Troubleshooting
### Problem: [Common issue]
**Symptoms:** [What you see]
**Cause:** [Why it happens]
**Solution:**
1. [Fix step 1]
2. [Fix step 2]
### Problem: [Another issue]
[Same structure as above]
## Best Practices
- [Best practice 1]
- [Best practice 2]
- [Best practice 3]
## Related Guides
- [Link to related guide 1]
- [Link to related guide 2]
## Need Help?
- Questions? Ask in #[channel]
- Issues? Create ticket in [JIRA project]
- Contact: @[Expert name]
---
*Last updated: [Date] by @[Name]*---
Requirements Document Template
# [Feature/Project Name] Requirements
| Field | Value |
|-------|-------|
| **Status** | 🟡 Draft / 🟢 Approved / 🔵 In Progress / ✅ Complete |
| **Product Owner** | @[Name] |
| **Stakeholders** | @[Name1], @[Name2] |
| **Target Release** | [Release version] |
| **JIRA Epic** | [ABC-123](link) |
| **Created** | [YYYY-MM-DD] |
| **Last Updated** | [YYYY-MM-DD] |
## Executive Summary
[2-3 sentences describing the feature and its business value]
## Business Goals
- [Goal 1]: [Metric]
- [Goal 2]: [Metric]
- [Goal 3]: [Metric]
## User Stories
### Story 1: [Title]
**As a** [user type]
**I want** [goal]
**So that** [benefit]
**Acceptance Criteria:**
- [ ] [Criterion 1]
- [ ] [Criterion 2]
- [ ] [Criterion 3]
**Priority:** [High/Medium/Low]
**Effort:** [Story points]
### Story 2: [Title]
[Same structure as Story 1]
## Functional Requirements
### FR-001: [Requirement Title]
**Description:** [What the system must do]
**Rationale:** [Why this is needed]
**Acceptance Criteria:**
- [Criterion 1]
- [Criterion 2]
**Priority:** [Must Have / Should Have / Could Have / Won't Have]
### FR-002: [Requirement Title]
[Same structure as FR-001]
## Non-Functional Requirements
### Performance
- [Requirement 1]
- [Requirement 2]
### Security
- [Requirement 1]
- [Requirement 2]
### Scalability
- [Requirement 1]
- [Requirement 2]
### Accessibility
- [Requirement 1]
- [Requirement 2]
## User Experience
### Wireframes
[Insert wireframes or link to Figma]
### User Flow
[Diagram showing user journey]
### UI Requirements
- [UI requirement 1]
- [UI requirement 2]
## Technical Constraints
- [Constraint 1]
- [Constraint 2]
- [Constraint 3]
## Dependencies
| Dependency | Owner | Status | Impact if Blocked |
|------------|-------|--------|-------------------|
| [Dep 1] | @[Name] | 🟢 Ready | [Impact] |
| [Dep 2] | @[Name] | 🟡 In Progress | [Impact] |
## Success Metrics
| Metric | Baseline | Target | How Measured |
|--------|----------|--------|--------------|
| [Metric 1] | [Current] | [Goal] | [Method] |
| [Metric 2] | [Current] | [Goal] | [Method] |
## Risks and Mitigations
| Risk | Impact | Probability | Mitigation |
|------|--------|-------------|------------|
| [Risk 1] | High | Medium | [Strategy] |
| [Risk 2] | Medium | Low | [Strategy] |
## Out of Scope
- [Explicitly excluded 1]
- [Explicitly excluded 2]
## Open Questions
- [ ] [Question 1] - @[Owner] - [Due date]
- [ ] [Question 2] - @[Owner] - [Due date]
## Timeline
| Phase | Start Date | End Date | Deliverables |
|-------|-----------|----------|--------------|
| Design | [Date] | [Date] | [Deliverable] |
| Development | [Date] | [Date] | [Deliverable] |
| Testing | [Date] | [Date] | [Deliverable] |
| Launch | [Date] | [Date] | [Deliverable] |
## Approval
### Reviewers
- [ ] Product Owner: @[Name]
- [ ] Engineering Lead: @[Name]
- [ ] Design Lead: @[Name]
- [ ] Stakeholder: @[Name]
**Approved Date:** [YYYY-MM-DD]
## References
- [Market research]
- [User feedback]
- [Technical specs]
- [Related features]
---
*For questions, contact @[Product Owner]*---
Retrospective Template
# Sprint [N] Retrospective - [Team Name]
**Date:** [YYYY-MM-DD]
**Sprint:** [Sprint N]
**Sprint Dates:** [Start Date] - [End Date]
**Facilitator:** @[Name]
**Participants:** @[Name1], @[Name2], @[Name3]
## Sprint Metrics
- **Velocity:** [X points] (Average: [Y points])
- **Committed:** [X points / N issues]
- **Completed:** [Y points / M issues]
- **Sprint Goal Met:** ✅ Yes / ❌ No
## What Went Well 😊
- [Positive 1]
- [Positive 2]
- [Positive 3]
## What Didn't Go Well 😞
- [Challenge 1]
- [Challenge 2]
- [Challenge 3]
## Action Items from Last Retro
- [✅ / ❌] [Action item 1] - @[Owner]
- Status: [Done / In Progress / Not Done]
- Notes: [Update]
- [✅ / ❌] [Action item 2] - @[Owner]
- Status: [Done / In Progress / Not Done]
- Notes: [Update]
## Discussion Themes
### Theme 1: [Topic]
**What we discussed:**
[Summary of discussion]
**Root cause:**
[What's really causing this issue?]
**Ideas for improvement:**
- [Idea 1]
- [Idea 2]
### Theme 2: [Topic]
[Same structure as Theme 1]
## Action Items for Next Sprint
| Action | Owner | Due Date | Success Criteria |
|--------|-------|----------|------------------|
| [Action 1] | @[Name] | [Date] | [How we know it's done] |
| [Action 2] | @[Name] | [Date] | [How we know it's done] |
| [Action 3] | @[Name] | [Date] | [How we know it's done] |
## Shout-Outs 🎉
- @[Name] for [what they did]
- @[Name] for [what they did]
## Notes
[Any additional notes or observations]
---
*Next Retrospective: [Date]*---
Status Report Template
# [Project Name] Status Report - [Week of Date]
**Report Date:** [YYYY-MM-DD]
**Reporting Period:** [Start Date] - [End Date]
**Project Manager:** @[Name]
**Overall Status:** 🟢 On Track / 🟡 At Risk / 🔴 Off Track
## Executive Summary
[2-3 sentences: What's the current state? What are the key achievements? What needs attention?]
## Project Health
| Metric | Status | Details |
|--------|--------|---------|
| **Scope** | 🟢 / 🟡 / 🔴 | [Comment] |
| **Schedule** | 🟢 / 🟡 / 🔴 | [Comment] |
| **Budget** | 🟢 / 🟡 / 🔴 | [Comment] |
| **Quality** | 🟢 / 🟡 / 🔴 | [Comment] |
| **Team Morale** | 🟢 / 🟡 / 🔴 | [Comment] |
## Key Accomplishments
- ✅ [Accomplishment 1]
- ✅ [Accomplishment 2]
- ✅ [Accomplishment 3]
## Milestones Status
| Milestone | Target Date | Status | Actual/Forecast | Notes |
|-----------|-------------|--------|-----------------|-------|
| [Milestone 1] | [Date] | ✅ Complete | [Date] | [Notes] |
| [Milestone 2] | [Date] | 🔄 In Progress | On track | [Notes] |
| [Milestone 3] | [Date] | ⏳ Not Started | [Forecast] | [Notes] |
## Active Risks
### 🔴 Critical Risks
| Risk | Impact | Mitigation | Owner | Status |
|------|--------|------------|-------|--------|
| [Risk 1] | High | [Strategy] | @[Name] | [Update] |
### 🟡 Medium Risks
| Risk | Impact | Mitigation | Owner | Status |
|------|--------|------------|-------|--------|
| [Risk 2] | Medium | [Strategy] | @[Name] | [Update] |
## Issues & Blockers
### 🚨 Blockers
- [Blocker 1] - @[Owner] - **Escalated to:** [Person]
- Impact: [What's blocked]
- ETA to resolve: [Date]
### ⚠️ Issues
- [Issue 1] - @[Owner]
- Status: [Update]
## Upcoming in Next Period
- [Activity 1]
- [Activity 2]
- [Activity 3]
## Budget Update (if applicable)
- **Total Budget:** [Amount]
- **Spent to Date:** [Amount] ([%])
- **Forecast to Complete:** [Amount]
- **Variance:** [Amount] ([%])
## Decisions Needed
| Decision | Why Needed | Deadline | Stakeholder |
|----------|-----------|----------|-------------|
| [Decision 1] | [Reason] | [Date] | @[Name] |
## Team Update
- **Current Team Size:** [N people]
- **Open Positions:** [N] ([Roles])
- **Recent Additions:** @[Name] - [Role]
- **Upcoming Departures:** [Names/Dates]
## Metrics (if applicable)
| Metric | This Period | Last Period | Trend | Target |
|--------|-------------|-------------|-------|--------|
| [Metric 1] | [Value] | [Value] | ↗️ / ↘️ / → | [Target] |
| [Metric 2] | [Value] | [Value] | ↗️ / ↘️ / → | [Target] |
## Links
- [Jira Project](link)
- [Roadmap](link)
- [Technical Docs](link)
---
*Next Status Report: [Date]*#!/usr/bin/env python3
"""
Content Audit Analyzer
Analyzes Confluence page inventory for content health. Identifies stale pages,
low-engagement content, orphaned pages, oversized documents, and produces a
health score with actionable recommendations.
Usage:
python content_audit_analyzer.py pages.json
python content_audit_analyzer.py pages.json --format json
"""
import argparse
import json
import sys
from datetime import datetime, timedelta
from typing import Any, Dict, List, Optional, Tuple
# ---------------------------------------------------------------------------
# Audit Configuration
# ---------------------------------------------------------------------------
STALE_THRESHOLD_DAYS = 90
OUTDATED_THRESHOLD_DAYS = 180
LOW_VIEW_THRESHOLD = 5
OVERSIZED_WORD_THRESHOLD = 5000
IDEAL_WORD_RANGE = (200, 3000)
HEALTH_WEIGHTS = {
"freshness": 0.30,
"engagement": 0.25,
"organization": 0.20,
"size_balance": 0.15,
"completeness": 0.10,
}
# ---------------------------------------------------------------------------
# Audit Checks
# ---------------------------------------------------------------------------
def check_stale_pages(
pages: List[Dict[str, Any]],
reference_date: datetime,
) -> Dict[str, Any]:
"""Identify pages not updated within the stale threshold."""
stale = []
outdated = []
for page in pages:
last_modified = _parse_date(page.get("last_modified", ""))
if not last_modified:
continue
days_since_update = (reference_date - last_modified).days
if days_since_update > OUTDATED_THRESHOLD_DAYS:
outdated.append({
"title": page.get("title", "Untitled"),
"days_since_update": days_since_update,
"last_modified": page.get("last_modified", ""),
"author": page.get("author", "unknown"),
})
elif days_since_update > STALE_THRESHOLD_DAYS:
stale.append({
"title": page.get("title", "Untitled"),
"days_since_update": days_since_update,
"last_modified": page.get("last_modified", ""),
"author": page.get("author", "unknown"),
})
total = len(pages)
stale_count = len(stale) + len(outdated)
fresh_ratio = 1 - (stale_count / total) if total > 0 else 1
score = max(0, fresh_ratio * 100)
return {
"score": score,
"stale_pages": stale,
"outdated_pages": outdated,
"stale_count": len(stale),
"outdated_count": len(outdated),
"fresh_count": total - stale_count,
}
def check_engagement(pages: List[Dict[str, Any]]) -> Dict[str, Any]:
"""Identify low-engagement pages based on view counts."""
low_engagement = []
view_counts = []
for page in pages:
views = page.get("view_count", 0)
view_counts.append(views)
if views < LOW_VIEW_THRESHOLD:
low_engagement.append({
"title": page.get("title", "Untitled"),
"view_count": views,
"author": page.get("author", "unknown"),
})
total = len(pages)
avg_views = sum(view_counts) / total if total > 0 else 0
engaged_ratio = 1 - (len(low_engagement) / total) if total > 0 else 1
score = max(0, engaged_ratio * 100)
return {
"score": score,
"low_engagement_pages": low_engagement,
"low_engagement_count": len(low_engagement),
"average_views": round(avg_views, 1),
"max_views": max(view_counts) if view_counts else 0,
"min_views": min(view_counts) if view_counts else 0,
}
def check_organization(pages: List[Dict[str, Any]]) -> Dict[str, Any]:
"""Identify orphaned pages with no labels."""
orphaned = []
for page in pages:
labels = page.get("labels", [])
if not labels:
orphaned.append({
"title": page.get("title", "Untitled"),
"author": page.get("author", "unknown"),
})
total = len(pages)
labeled_ratio = 1 - (len(orphaned) / total) if total > 0 else 1
score = max(0, labeled_ratio * 100)
# Collect label distribution
label_counts = {}
for page in pages:
for label in page.get("labels", []):
label_counts[label] = label_counts.get(label, 0) + 1
return {
"score": score,
"orphaned_pages": orphaned,
"orphaned_count": len(orphaned),
"labeled_count": total - len(orphaned),
"label_distribution": dict(sorted(label_counts.items(), key=lambda x: -x[1])[:20]),
}
def check_size_balance(pages: List[Dict[str, Any]]) -> Dict[str, Any]:
"""Check for oversized or undersized pages."""
oversized = []
undersized = []
word_counts = []
for page in pages:
word_count = page.get("word_count", 0)
word_counts.append(word_count)
if word_count > OVERSIZED_WORD_THRESHOLD:
oversized.append({
"title": page.get("title", "Untitled"),
"word_count": word_count,
"recommendation": "Split into multiple focused pages",
})
elif word_count < 50 and word_count > 0:
undersized.append({
"title": page.get("title", "Untitled"),
"word_count": word_count,
"recommendation": "Expand content or merge with related page",
})
total = len(pages)
well_sized = total - len(oversized) - len(undersized)
balance_ratio = well_sized / total if total > 0 else 1
score = max(0, balance_ratio * 100)
avg_words = sum(word_counts) / total if total > 0 else 0
return {
"score": score,
"oversized_pages": oversized,
"undersized_pages": undersized,
"oversized_count": len(oversized),
"undersized_count": len(undersized),
"average_word_count": round(avg_words),
}
def check_completeness(pages: List[Dict[str, Any]]) -> Dict[str, Any]:
"""Check pages for required metadata completeness."""
incomplete = []
required_fields = ["title", "last_modified", "author"]
for page in pages:
missing = [f for f in required_fields if not page.get(f)]
if missing:
incomplete.append({
"title": page.get("title", "Untitled"),
"missing_fields": missing,
})
total = len(pages)
complete_ratio = 1 - (len(incomplete) / total) if total > 0 else 1
score = max(0, complete_ratio * 100)
return {
"score": score,
"incomplete_pages": incomplete,
"incomplete_count": len(incomplete),
"complete_count": total - len(incomplete),
}
# ---------------------------------------------------------------------------
# Main Analysis
# ---------------------------------------------------------------------------
def analyze_content_health(data: Dict[str, Any]) -> Dict[str, Any]:
"""Run full content audit analysis."""
pages = data.get("pages", [])
if not pages:
return {
"health_score": 0,
"grade": "invalid",
"error": "No pages found in input data",
"dimensions": {},
"action_items": [],
}
reference_date = datetime.now()
# Run all checks
dimensions = {
"freshness": check_stale_pages(pages, reference_date),
"engagement": check_engagement(pages),
"organization": check_organization(pages),
"size_balance": check_size_balance(pages),
"completeness": check_completeness(pages),
}
# Calculate weighted health score
weighted_scores = []
for dim_name, dim_result in dimensions.items():
weight = HEALTH_WEIGHTS.get(dim_name, 0.1)
weighted_scores.append(dim_result["score"] * weight)
health_score = sum(weighted_scores)
if health_score >= 85:
grade = "excellent"
elif health_score >= 70:
grade = "good"
elif health_score >= 55:
grade = "fair"
else:
grade = "poor"
# Generate action items
action_items = _generate_action_items(dimensions)
return {
"health_score": round(health_score, 1),
"grade": grade,
"total_pages": len(pages),
"dimensions": dimensions,
"action_items": action_items,
}
def _generate_action_items(dimensions: Dict[str, Any]) -> List[Dict[str, str]]:
"""Generate prioritized action items from audit findings."""
items = []
# Freshness actions
freshness = dimensions.get("freshness", {})
if freshness.get("outdated_count", 0) > 0:
items.append({
"priority": "high",
"action": f"Review and update or archive {freshness['outdated_count']} outdated pages (>180 days old)",
"category": "freshness",
})
if freshness.get("stale_count", 0) > 0:
items.append({
"priority": "medium",
"action": f"Review {freshness['stale_count']} stale pages (90-180 days old) for relevance",
"category": "freshness",
})
# Engagement actions
engagement = dimensions.get("engagement", {})
if engagement.get("low_engagement_count", 0) > 0:
items.append({
"priority": "medium",
"action": f"Investigate {engagement['low_engagement_count']} low-engagement pages - consider improving discoverability or archiving",
"category": "engagement",
})
# Organization actions
organization = dimensions.get("organization", {})
if organization.get("orphaned_count", 0) > 0:
items.append({
"priority": "medium",
"action": f"Add labels to {organization['orphaned_count']} orphaned pages for better categorization",
"category": "organization",
})
# Size actions
size = dimensions.get("size_balance", {})
if size.get("oversized_count", 0) > 0:
items.append({
"priority": "low",
"action": f"Split {size['oversized_count']} oversized pages (>5000 words) into focused sub-pages",
"category": "size",
})
# Completeness actions
completeness = dimensions.get("completeness", {})
if completeness.get("incomplete_count", 0) > 0:
items.append({
"priority": "low",
"action": f"Fill in missing metadata for {completeness['incomplete_count']} incomplete pages",
"category": "completeness",
})
return items
def _parse_date(date_str: str) -> Optional[datetime]:
"""Parse date string in common formats."""
formats = [
"%Y-%m-%d",
"%Y-%m-%dT%H:%M:%S",
"%Y-%m-%dT%H:%M:%SZ",
"%Y-%m-%dT%H:%M:%S.%f",
"%Y-%m-%dT%H:%M:%S.%fZ",
"%d/%m/%Y",
"%m/%d/%Y",
]
for fmt in formats:
try:
return datetime.strptime(date_str, fmt)
except ValueError:
continue
return None
# ---------------------------------------------------------------------------
# Output Formatting
# ---------------------------------------------------------------------------
def format_text_output(result: Dict[str, Any]) -> str:
"""Format results as readable text report."""
lines = []
lines.append("=" * 60)
lines.append("CONTENT AUDIT REPORT")
lines.append("=" * 60)
lines.append("")
if "error" in result:
lines.append(f"ERROR: {result['error']}")
return "\n".join(lines)
lines.append("HEALTH SUMMARY")
lines.append("-" * 30)
lines.append(f"Health Score: {result['health_score']}/100")
lines.append(f"Grade: {result['grade'].title()}")
lines.append(f"Total Pages Analyzed: {result['total_pages']}")
lines.append("")
# Dimension scores
lines.append("DIMENSION SCORES")
lines.append("-" * 30)
for dim_name, dim_data in result.get("dimensions", {}).items():
weight = HEALTH_WEIGHTS.get(dim_name, 0)
lines.append(f"{dim_name.replace('_', ' ').title()} (Weight: {weight:.0%})")
lines.append(f" Score: {dim_data['score']:.1f}/100")
if dim_name == "freshness":
lines.append(f" Stale: {dim_data.get('stale_count', 0)}, Outdated: {dim_data.get('outdated_count', 0)}, Fresh: {dim_data.get('fresh_count', 0)}")
elif dim_name == "engagement":
lines.append(f" Low Engagement: {dim_data.get('low_engagement_count', 0)}, Avg Views: {dim_data.get('average_views', 0)}")
elif dim_name == "organization":
lines.append(f" Orphaned (no labels): {dim_data.get('orphaned_count', 0)}, Labeled: {dim_data.get('labeled_count', 0)}")
elif dim_name == "size_balance":
lines.append(f" Oversized: {dim_data.get('oversized_count', 0)}, Undersized: {dim_data.get('undersized_count', 0)}, Avg Words: {dim_data.get('average_word_count', 0)}")
elif dim_name == "completeness":
lines.append(f" Incomplete: {dim_data.get('incomplete_count', 0)}, Complete: {dim_data.get('complete_count', 0)}")
lines.append("")
# Action items
action_items = result.get("action_items", [])
if action_items:
lines.append("ACTION ITEMS")
lines.append("-" * 30)
for i, item in enumerate(action_items, 1):
priority = item["priority"].upper()
lines.append(f"{i}. [{priority}] {item['action']}")
lines.append("")
return "\n".join(lines)
def format_json_output(result: Dict[str, Any]) -> Dict[str, Any]:
"""Format results as JSON."""
return result
# ---------------------------------------------------------------------------
# CLI Interface
# ---------------------------------------------------------------------------
def main() -> int:
"""Main CLI entry point."""
parser = argparse.ArgumentParser(
description="Analyze Confluence page inventory for content health"
)
parser.add_argument(
"pages_file",
help="JSON file with page list (title, last_modified, view_count, author, labels, word_count)",
)
parser.add_argument(
"--format",
choices=["text", "json"],
default="text",
help="Output format (default: text)",
)
args = parser.parse_args()
try:
with open(args.pages_file, "r") as f:
data = json.load(f)
result = analyze_content_health(data)
if args.format == "json":
print(json.dumps(format_json_output(result), indent=2))
else:
print(format_text_output(result))
return 0
except FileNotFoundError:
print(f"Error: File '{args.pages_file}' not found", file=sys.stderr)
return 1
except json.JSONDecodeError as e:
print(f"Error: Invalid JSON in '{args.pages_file}': {e}", file=sys.stderr)
return 1
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
return 1
if __name__ == "__main__":
sys.exit(main())
#!/usr/bin/env python3
"""
Space Structure Generator
Generates recommended Confluence space hierarchy from team or project
descriptions. Produces page tree structures, labels, and permission
suggestions based on team type and size.
Usage:
python space_structure_generator.py team_info.json
python space_structure_generator.py team_info.json --format json
"""
import argparse
import json
import sys
from typing import Any, Dict, List, Optional
# ---------------------------------------------------------------------------
# Space Templates
# ---------------------------------------------------------------------------
BASE_SECTIONS = [
{
"title": "Home",
"description": "Space landing page with quick links and team overview",
"labels": ["home", "landing"],
"children": [],
},
{
"title": "Getting Started",
"description": "Onboarding guide for new team members",
"labels": ["onboarding", "getting-started"],
"children": [
{"title": "Team Charter", "labels": ["charter"]},
{"title": "Tools & Access", "labels": ["tools", "access"]},
{"title": "Communication Guidelines", "labels": ["communication"]},
{"title": "Key Contacts", "labels": ["contacts"]},
],
},
{
"title": "Meeting Notes",
"description": "Recurring and ad-hoc meeting documentation",
"labels": ["meetings"],
"children": [
{"title": "Weekly Standups", "labels": ["standup", "recurring"]},
{"title": "Team Syncs", "labels": ["sync", "recurring"]},
{"title": "Ad-hoc Meetings", "labels": ["ad-hoc"]},
],
},
{
"title": "Templates",
"description": "Reusable page templates for the team",
"labels": ["templates"],
"children": [],
},
{
"title": "Archive",
"description": "Archived and deprecated content",
"labels": ["archive"],
"children": [],
},
]
TEAM_TYPE_SECTIONS = {
"engineering": [
{
"title": "Architecture",
"description": "System architecture, design decisions, and technical standards",
"labels": ["architecture", "technical"],
"children": [
{"title": "Architecture Decision Records", "labels": ["adr", "decisions"]},
{"title": "System Design Documents", "labels": ["design", "system"]},
{"title": "API Documentation", "labels": ["api", "reference"]},
{"title": "Tech Stack", "labels": ["tech-stack"]},
],
},
{
"title": "Development",
"description": "Development workflows, coding standards, and CI/CD",
"labels": ["development"],
"children": [
{"title": "Coding Standards", "labels": ["standards", "code"]},
{"title": "Git Workflow", "labels": ["git", "workflow"]},
{"title": "CI/CD Pipeline", "labels": ["ci-cd", "devops"]},
{"title": "Environment Setup", "labels": ["environment", "setup"]},
],
},
{
"title": "Runbooks",
"description": "Operational runbooks and incident response",
"labels": ["runbooks", "operations"],
"children": [
{"title": "Incident Response", "labels": ["incident", "response"]},
{"title": "Deployment Procedures", "labels": ["deployment"]},
{"title": "Troubleshooting Guides", "labels": ["troubleshooting"]},
],
},
],
"product": [
{
"title": "Strategy",
"description": "Product vision, roadmap, and strategic planning",
"labels": ["strategy", "product"],
"children": [
{"title": "Product Vision", "labels": ["vision"]},
{"title": "Roadmap", "labels": ["roadmap"]},
{"title": "OKRs & Goals", "labels": ["okr", "goals"]},
{"title": "Competitive Analysis", "labels": ["competitive", "analysis"]},
],
},
{
"title": "Research",
"description": "User research, personas, and market analysis",
"labels": ["research"],
"children": [
{"title": "User Personas", "labels": ["personas"]},
{"title": "User Interview Notes", "labels": ["interviews", "research"]},
{"title": "Survey Results", "labels": ["surveys"]},
{"title": "Usability Testing", "labels": ["usability", "testing"]},
],
},
{
"title": "Requirements",
"description": "Product requirements and feature specifications",
"labels": ["requirements", "specs"],
"children": [
{"title": "Feature Specifications", "labels": ["features", "specs"]},
{"title": "User Stories", "labels": ["user-stories"]},
{"title": "Acceptance Criteria", "labels": ["acceptance-criteria"]},
],
},
],
"marketing": [
{
"title": "Strategy",
"description": "Marketing strategy, brand guidelines, and campaign plans",
"labels": ["strategy", "marketing"],
"children": [
{"title": "Brand Guidelines", "labels": ["brand", "guidelines"]},
{"title": "Marketing Plan", "labels": ["plan"]},
{"title": "Target Audiences", "labels": ["audience", "targeting"]},
{"title": "Channel Strategy", "labels": ["channels"]},
],
},
{
"title": "Campaigns",
"description": "Active and past campaign documentation",
"labels": ["campaigns"],
"children": [
{"title": "Active Campaigns", "labels": ["active"]},
{"title": "Campaign Results", "labels": ["results", "analytics"]},
{"title": "Campaign Templates", "labels": ["templates"]},
],
},
{
"title": "Content",
"description": "Content calendar, assets, and style guides",
"labels": ["content"],
"children": [
{"title": "Content Calendar", "labels": ["calendar"]},
{"title": "Content Assets", "labels": ["assets"]},
{"title": "Style Guide", "labels": ["style-guide"]},
],
},
],
"project": [
{
"title": "Project Overview",
"description": "Project charter, scope, and stakeholders",
"labels": ["project", "overview"],
"children": [
{"title": "Project Charter", "labels": ["charter"]},
{"title": "Scope & Deliverables", "labels": ["scope", "deliverables"]},
{"title": "Stakeholder Map", "labels": ["stakeholders"]},
{"title": "Timeline & Milestones", "labels": ["timeline", "milestones"]},
],
},
{
"title": "Status & Reporting",
"description": "Project status updates and reports",
"labels": ["status", "reporting"],
"children": [
{"title": "Weekly Status Reports", "labels": ["status", "weekly"]},
{"title": "Risk Register", "labels": ["risks"]},
{"title": "Decision Log", "labels": ["decisions"]},
],
},
{
"title": "Resources",
"description": "Project resources, documentation, and references",
"labels": ["resources"],
"children": [
{"title": "Technical Documentation", "labels": ["technical", "docs"]},
{"title": "Vendor Information", "labels": ["vendor"]},
{"title": "Budget & Financials", "labels": ["budget"]},
],
},
],
}
# Permission suggestions by team type
PERMISSION_TEMPLATES = {
"engineering": {
"admins": ["team-leads", "engineering-managers"],
"contributors": ["developers", "qa-engineers"],
"viewers": ["product-team", "stakeholders"],
"restrictions": [
"Restrict 'Runbooks' section to engineering team only",
"Allow product team view-only access to Architecture",
],
},
"product": {
"admins": ["product-managers", "product-leads"],
"contributors": ["product-designers", "product-analysts"],
"viewers": ["engineering-team", "marketing-team", "stakeholders"],
"restrictions": [
"Restrict 'Research' raw data to product team only",
"Share 'Strategy' with leadership and stakeholders",
],
},
"marketing": {
"admins": ["marketing-managers", "marketing-leads"],
"contributors": ["content-creators", "designers"],
"viewers": ["sales-team", "product-team"],
"restrictions": [
"Restrict campaign budgets to marketing leadership",
"Share brand guidelines broadly",
],
},
"project": {
"admins": ["project-managers"],
"contributors": ["project-team-members"],
"viewers": ["stakeholders", "sponsors"],
"restrictions": [
"Restrict 'Budget & Financials' to project managers and sponsors",
"Share status reports with all stakeholders",
],
},
}
# ---------------------------------------------------------------------------
# Structure Generator
# ---------------------------------------------------------------------------
def generate_space_structure(team_info: Dict[str, Any]) -> Dict[str, Any]:
"""Generate Confluence space structure from team information."""
team_name = team_info.get("name", "Team")
team_type = team_info.get("type", "project").lower()
team_size = team_info.get("size", 5)
projects = team_info.get("projects", [])
if team_type not in TEAM_TYPE_SECTIONS:
team_type = "project"
# Build page tree
page_tree = []
# Add base sections
for section in BASE_SECTIONS:
page_tree.append(_deep_copy_section(section))
# Add team-type-specific sections
type_sections = TEAM_TYPE_SECTIONS.get(team_type, [])
for section in type_sections:
page_tree.append(_deep_copy_section(section))
# Add project-specific pages if projects are listed
if projects:
project_section = {
"title": "Projects",
"description": "Individual project documentation",
"labels": ["projects"],
"children": [],
}
for project in projects:
project_name = project if isinstance(project, str) else project.get("name", "Project")
project_section["children"].append({
"title": project_name,
"labels": ["project", _slugify(project_name)],
"children": [
{"title": f"{project_name} - Overview", "labels": ["overview"]},
{"title": f"{project_name} - Requirements", "labels": ["requirements"]},
{"title": f"{project_name} - Status", "labels": ["status"]},
],
})
page_tree.append(project_section)
# Get permissions
permissions = PERMISSION_TEMPLATES.get(team_type, PERMISSION_TEMPLATES["project"])
# Generate label taxonomy
all_labels = set()
_collect_labels(page_tree, all_labels)
# Build recommendations
recommendations = _generate_recommendations(team_name, team_type, team_size, projects)
return {
"space_key": _generate_space_key(team_name),
"space_name": f"{team_name} Space",
"team_type": team_type,
"team_size": team_size,
"page_tree": page_tree,
"total_pages": _count_pages(page_tree),
"labels": sorted(all_labels),
"permissions": permissions,
"recommendations": recommendations,
}
def _deep_copy_section(section: Dict[str, Any]) -> Dict[str, Any]:
"""Create a deep copy of a section dict."""
copy = {
"title": section["title"],
"labels": list(section.get("labels", [])),
}
if "description" in section:
copy["description"] = section["description"]
if "children" in section:
copy["children"] = [_deep_copy_section(child) for child in section["children"]]
return copy
def _slugify(text: str) -> str:
"""Convert text to a URL-safe slug."""
return text.lower().replace(" ", "-").replace("_", "-")
def _generate_space_key(team_name: str) -> str:
"""Generate a space key from team name."""
words = team_name.upper().split()
if len(words) == 1:
return words[0][:10]
return "".join(w[0] for w in words[:5])
def _collect_labels(pages: List[Dict], labels: set) -> None:
"""Recursively collect all labels from page tree."""
for page in pages:
for label in page.get("labels", []):
labels.add(label)
children = page.get("children", [])
if children:
_collect_labels(children, labels)
def _count_pages(pages: List[Dict]) -> int:
"""Count total pages in tree."""
count = len(pages)
for page in pages:
children = page.get("children", [])
if children:
count += _count_pages(children)
return count
def _generate_recommendations(
team_name: str,
team_type: str,
team_size: int,
projects: List,
) -> List[str]:
"""Generate setup recommendations."""
recs = []
recs.append(f"Create the space with key '{_generate_space_key(team_name)}' and enable the blog feature for announcements.")
if team_size > 10:
recs.append("Large team detected. Consider sub-spaces or restricted sections for sub-teams.")
if team_size <= 3:
recs.append("Small team. Simplify the structure by merging low-traffic sections.")
if len(projects) > 5:
recs.append("Many projects listed. Consider a separate space per project for better isolation.")
if team_type == "engineering":
recs.append("Set up page templates for ADRs, runbooks, and design docs.")
recs.append("Enable the Jira macro on Architecture pages for traceability.")
elif team_type == "product":
recs.append("Set up page templates for feature specs and user research notes.")
recs.append("Link roadmap pages to Jira epics for real-time status.")
elif team_type == "marketing":
recs.append("Enable the calendar macro on the Content Calendar page.")
recs.append("Use labels consistently to enable filtered content views.")
recs.append("Review and update space permissions quarterly.")
recs.append("Archive pages older than 6 months that are no longer actively referenced.")
return recs
# ---------------------------------------------------------------------------
# Output Formatting
# ---------------------------------------------------------------------------
def _format_page_tree(pages: List[Dict], indent: int = 0) -> List[str]:
"""Format page tree as indented text."""
lines = []
prefix = " " * indent
for page in pages:
title = page["title"]
labels = page.get("labels", [])
label_str = f" [{', '.join(labels)}]" if labels else ""
lines.append(f"{prefix}|- {title}{label_str}")
if page.get("description"):
lines.append(f"{prefix} {page['description']}")
children = page.get("children", [])
if children:
lines.extend(_format_page_tree(children, indent + 1))
return lines
def format_text_output(result: Dict[str, Any]) -> str:
"""Format results as readable text report."""
lines = []
lines.append("=" * 60)
lines.append("CONFLUENCE SPACE STRUCTURE")
lines.append("=" * 60)
lines.append("")
lines.append("SPACE INFO")
lines.append("-" * 30)
lines.append(f"Space Name: {result['space_name']}")
lines.append(f"Space Key: {result['space_key']}")
lines.append(f"Team Type: {result['team_type'].title()}")
lines.append(f"Team Size: {result['team_size']}")
lines.append(f"Total Pages: {result['total_pages']}")
lines.append("")
lines.append("PAGE TREE")
lines.append("-" * 30)
lines.extend(_format_page_tree(result["page_tree"]))
lines.append("")
lines.append("LABELS")
lines.append("-" * 30)
lines.append(", ".join(result["labels"]))
lines.append("")
permissions = result.get("permissions", {})
if permissions:
lines.append("PERMISSION SUGGESTIONS")
lines.append("-" * 30)
lines.append(f"Admins: {', '.join(permissions.get('admins', []))}")
lines.append(f"Contributors: {', '.join(permissions.get('contributors', []))}")
lines.append(f"Viewers: {', '.join(permissions.get('viewers', []))}")
for restriction in permissions.get("restrictions", []):
lines.append(f" - {restriction}")
lines.append("")
recommendations = result.get("recommendations", [])
if recommendations:
lines.append("RECOMMENDATIONS")
lines.append("-" * 30)
for i, rec in enumerate(recommendations, 1):
lines.append(f"{i}. {rec}")
return "\n".join(lines)
def format_json_output(result: Dict[str, Any]) -> Dict[str, Any]:
"""Format results as JSON."""
return result
# ---------------------------------------------------------------------------
# CLI Interface
# ---------------------------------------------------------------------------
def main() -> int:
"""Main CLI entry point."""
parser = argparse.ArgumentParser(
description="Generate Confluence space hierarchy from team/project description"
)
parser.add_argument(
"team_file",
help="JSON file with team info (name, size, type, projects)",
)
parser.add_argument(
"--format",
choices=["text", "json"],
default="text",
help="Output format (default: text)",
)
args = parser.parse_args()
try:
with open(args.team_file, "r") as f:
data = json.load(f)
result = generate_space_structure(data)
if args.format == "json":
print(json.dumps(format_json_output(result), indent=2))
else:
print(format_text_output(result))
return 0
except FileNotFoundError:
print(f"Error: File '{args.team_file}' not found", file=sys.stderr)
return 1
except json.JSONDecodeError as e:
print(f"Error: Invalid JSON in '{args.team_file}': {e}", file=sys.stderr)
return 1
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
return 1
if __name__ == "__main__":
sys.exit(main())
Related skills
How it compares
Use confluence-expert for Atlassian wiki architecture; use in-repo docs skills when documentation lives in Git markdown instead.
FAQ
What does confluence-expert help configure?
confluence-expert helps configure Confluence spaces, permission hierarchies, page templates with macros, documentation taxonomies, page layouts, Jira report embeds, knowledge-base audits, and collaborative documentation standards for engineering teams.
When should confluence-expert be invoked?
confluence-expert should be invoked when building or restructuring a Confluence space, designing page hierarchies, authoring templates, embedding Jira reports, or establishing documentation governance and audit workflows.
Is Confluence Expert safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.