---
name: cse-confluence-maintenance
description: Keep CSE Confluence pages accurate and in-voice. Audits for drift, plans safe edits, rewrites sections with critic review, and snapshots page writes through cse-tools Confluence MCP.
argument-hint: "[audit|edit|rewrite|github-surface] <page-or-scope> [--execute]"
---

# CSE Confluence Maintenance

Use this skill for targeted Confluence maintenance across CSE and adjacent spaces: homepage updates, stale-fact sweeps, factual catalog additions, and section rewrites that need the shared Confluence documentation register.

## Compact MCP routing

- Follow the shared [compact MCP routing contract](../../shared/compact-mcp-routing.md) and [read strategy](../../shared/read-strategy.md). Interactive facade tools are `cse_capabilities`, `cse_read`, `cse_apply`, `context_assemble`, and `cse_session_info`; named operations are capability ids. Call reads through `cse_read` with the capability id. Every write goes through `cse_apply` twice: dry-run preview first, then the identical capability and arguments with `execute:true`, justification of at least 16 characters, and the returned `preview_digest`. Use `cse_session_info` directly for auth recovery.
- **`context_assemble`: N/A.** These are structural page reads and mutations, not person/account/ticket entity packs. Call Confluence operations directly.

```bash
source "${PLUGIN_ROOT:-${DROID_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT:-$PWD/plugins/cse-tools}}}/.agents/shared/skill-bootstrap.sh"
```

Confluence create, update, reparent, and attachment operations are dual-mode. Dry-run first; execute only with `execute: true`, a concrete justification, and the dry-run's `preview_digest`. Check the tool's inputSchema in `tools/list` for uncertain contracts.

## Hard boundaries

- Default mode is read-only dry-run.
- Do not perform bulk tree moves; hand those to `cse-confluence-migrate`.
- Do not use scratch `/tmp/cse-confluence/*.py` scripts as durable implementation. Use the local MCP tools so snapshots, version checks, and GET-back verification stay in the normal path.
- Do not install diagram tooling during a page edit. Mermaid rendering is optional and only runs when `mmdc` is already available.

## Modes

### 1. Audit

Use for drift/content-quality scans. No writes.

1. Define scope: spaces/pages, drift type, and whether the user wants factual drift or tone/format review.
2. Use Confluence read tools (`confluence_search`, `confluence_get_page`) and Kepler semantic search only as supplemental discovery, never as the storage source of truth.
3. Return severity-tagged findings with page title, page id, quote, and suggested fix.

### 2. Targeted factual edit

Use for one-row catalog additions, dead links, typo fixes, sunset channel references, stale role names.

1. Fetch the current page with storage body and version.
2. Build a minimal replacement or insertion using structural anchors, not `local-id`/`macro-id` values.
3. Preview `confluence_update_page` via the two-phase dry-run/execute contract with `dry_run: true`; inspect the request and raw pre-write snapshot, retain its `preview_digest`, then record local `must_contain` and `must_not_contain` assertions for verification.
4. If execution is authorized, apply the same arguments with `execute: true` and the dry-run's digest. Persist the raw pre-write page JSON locally with mode `0600` when rollback evidence is required; the runtime does not persist a snapshot id.
5. GET the page back via `confluence_get_page` and assert version, title, and the exact intended storage-body change.

### Draft-file workflow for long bodies

Confluence sends are file-only: inline `body_storage` is rejected. Author the body once in a `/tmp` file and pass `body_storage_path`.

1. Write the storage XHTML to a `/tmp` file (e.g. `/tmp/<page>.storage.xhtml`). Editing it there also draws non-blocking line guidance from the voice guard.
2. Submit via `body_storage_path` on `confluence_create_page` / `confluence_update_page`. If the send is blocked, follow the block reason: edit the named lines in the same `/tmp` file and re-call with the same `body_storage_path`.

### Worked dual-mode calls

Preview first through `cse_apply` (outer `execute: true` and justification; omit underlying `arguments.execute`); preserve the exact reviewed arguments for apply with underlying `arguments.execute: true` and `preview_digest`.

**Create**

```js
cse_apply({
  capability: "confluence_create_page",
  arguments: {
    title: "CSE Playbook",
    space_id: "123",
    parent_id: "456",
    body_storage_path: "/tmp/cse-playbook.storage.xhtml"
  },
  execute: true,
  justification: "Preview the approved CSE playbook create under parent 456"
})
```

After approval, apply:

```js
cse_apply({
  capability: "confluence_create_page",
  arguments: {
    title: "CSE Playbook",
    space_id: "123",
    parent_id: "456",
    body_storage_path: "/tmp/cse-playbook.storage.xhtml",
    execute: true,
    preview_digest: "<digest-from-preview>"
  },
  execute: true,
  justification: "Create the approved CSE playbook under parent 456"
})
```

**Update**

```js
cse_apply({
  capability: "confluence_update_page",
  arguments: {
    page_id: "789",
    expected_version: 12,
    title: "CSE Playbook",
    body_storage_path: "/tmp/cse-playbook.storage.xhtml",
    message: "Refresh intake guidance"
  },
  execute: true,
  justification: "Preview the approved intake guidance refresh"
})
```

Then apply:

```js
cse_apply({
  capability: "confluence_update_page",
  arguments: {
    page_id: "789",
    expected_version: 12,
    title: "CSE Playbook",
    body_storage_path: "/tmp/cse-playbook.storage.xhtml",
    message: "Refresh intake guidance",
    execute: true,
    preview_digest: "<digest-from-preview>"
  },
  execute: true,
  justification: "Publish the approved intake guidance refresh"
})
```

**Reparent (migration handoff only)**

```js
cse_apply({
  capability: "confluence_reparent_page",
  arguments: {
    page_id: "789",
    target_parent_id: "654",
    expected_version: 13
  },
  execute: true,
  justification: "Preview reparent of page 789 under 654"
})
```

This skill may preview the operation, but execution belongs to `cse-confluence-migrate`. The handoff's apply call is:

```js
cse_apply({
  capability: "confluence_reparent_page",
  arguments: {
    page_id: "789",
    target_parent_id: "654",
    expected_version: 13,
    execute: true,
    preview_digest: "<digest-from-preview>"
  },
  execute: true,
  justification: "Reparent page 789 under 654 per the approved migration plan"
})
```

Before every apply to an existing page, require the preview's raw pre-write snapshot and digest. After every apply, GET back the affected page:

```js
cse_read({
  capability: "confluence_get_page",
  arguments: { page_id: "789", body_format: "storage" }
})
```

For create, substitute the returned created page id. Verify title, version, parent, and storage body as applicable; do not treat a successful mutation response alone as verification.

### Attachment-aware edits

Use only when the page body references local files or rendered diagrams.

1. Verify every referenced file exists and is under the operation's attachment cap.
2. List attachments first with `confluence_list_attachments`.
3. Do not replace an existing same-name attachment unless original bytes were captured through a supported read. The current capability surface exposes metadata only, so normally upload under a new filename.
4. Preview the attachment upload via the two-phase dry-run/execute contract with `dry_run: true`, then apply via the two-phase dry-run/execute contract with its `preview_digest`, outer `execute: true`, and justification.
5. GET the page and list its attachments after upload; assert the page is unchanged except for the intended reference and that the expected new filename resolves.

### Native no-app content patterns

When Marketplace/Forge apps are unavailable, use storage generated by `confluence_markdown_to_storage` and these Markdown hints:

- callouts: `> [!info]`, `> [!note]`, `> [!tip]`, `> [!warning]`
- speaker panels: `> [!quote postman] **Hammad**` on the first line, the quote on following `>` lines. Tokens `postman` (amber), `good` (green), `push` (purple) select the panel color; the operator picks the token per quote.
- status lozenges: `{{status:green\|READY}}`, `{{status:red\|BLOCKED}}`
- expanders: `<details><summary>Decision log</summary>...</details>`
- tasks: `- [ ] Follow up`, `- [x] Complete`
- dashboards: Markdown tables plus status lozenges
- navigation/macros: `{{toc}}`, `{{children:2}}`, `{{jira:CSE-123}}`, `{{jira-jql:project = CSE ORDER BY updated DESC}}`

Prefer rendered diagrams/images as attachments referenced by `<ac:image>` over app-only diagram macros. Generate them outside this skill, then use the supported attachment capability.

### CSE + v12 Playbook Suite page conventions

Recorded after Jared's 2026-05 homepage tune-up and the `v12: Platform Activation Discovery` readability pass. Follow these on CSE-owned pages: the CSE homepage, CSE Team parent, v12 Playbook Suite parent, **and v12 Playbook Suite child playbooks / pitch pages**. Do not override without explicit user direction.

Layout and storage form:

- **Callout (info panel) position.** Put the info callout BELOW the lead paragraph, not above. The eye should hit the lead first; the callout is a secondary affordance that surfaces the intake path.
- **Callout headings go in body text as a bold first line.** Use `> [!info]` then on the next `>` line `**Requesting a CSE engagement?**` as the first body paragraph. The converter puts everything after the marker straight into the panel body and never emits a `title` parameter, so author the heading as `**bold**`. When writing storage directly, put `<p><strong>Heading</strong></p>` inside `<ac:rich-text-body>`.
- **Do NOT collapse primary content into expand macros.** Jared prefers inline scroll depth over click-to-reveal. The Postman-managed Actions list is the canonical example: keep all 5 inline as a nested `<ul>` under a bold `<strong>Public Postman-managed GitHub Actions</strong>` label, NOT wrapped in `<ac:structured-macro ac:name="expand">`. Reserve expand macros for genuinely tangential detail (long appendices, rollback procedures, decision logs, full question banks after the scannable summary).
- **JQL macros use full-width layout.** Add `data-layout="full-width"` on the `<ac:structured-macro ac:name="jira">` wrapper so the issue table has room to breathe. In markdown this means editing the converted storage body after `confluence_markdown_to_storage` — the converter emits default layout.
- **Internal page links use `<ac:link-body>`.** Both `<ac:link-body>` and `<ac:plain-text-link-body>` render the same, but Jared prefers `<ac:link-body>Link text</ac:link-body>`. When patching storage bodies, rewrite `<ac:plain-text-link-body><![CDATA[X]]></ac:plain-text-link-body>` to `<ac:link-body>X</ac:link-body>`.
- **`<ac:link>` for intra-space pages; `<a href>` for everything else.** Internal Confluence pages: `<ac:link><ri:page ri:content-title="X" /><ac:link-body>X</ac:link-body></ac:link>`. External URLs, Jira tickets (unless using the `{{jira:}}` macro), Slack channels, GitHub: plain `<a href>`. The markdown converter emits `<a href>` for every link, including relative `/wiki/...` paths; rewrite intra-space links to the `<ac:link>` form by hand after conversion.
- **Live data macros belong near the bottom, above navigation.** Order: lead → sections → `Live Engagement Activity` (JQL) → `Sub-Pages` (children). Puts the freshest signal below the durable structure so the page doesn't reshuffle every time Jira updates.
- **`confluence_markdown_to_storage` coverage and hand-fixes.** The converter handles headings, bold, italic, strikethrough, inline and fenced code, ordered and unordered lists, tables, links, images, rules, blockquote callouts (`[!info|note|tip|warning]`), speaker panels (`[!quote ...]`), and the `{{status}}`/`{{toc}}`/`{{children}}`/`{{jira}}`/`{{jira-jql}}` hints. Pulling a page back decodes HTML entities (`Nestl&eacute;` becomes `Nestlé`) and lowers recognized macros to those hints; unrecognized `ac:`/`ri:` macros survive as raw XHTML. Two storage details still need a hand pass after conversion: rewrite intra-space page links from `<a href>` to the `<ac:link><ri:page .../></ac:link>` form, and add `data-layout="full-width"` to the `{{jira}}` macro wrapper. Inspect the storage body before writing.

Heading case and voice:

- **Heading case is Title Case on this tenant, and it extends to v12 Playbook Suite child pages.** `What We Own`, `Where Things Live`, `Live Engagement Activity`, `Quick Qualify`, `Fit Gates`, `Routing Decision`, `CSE Consult Intake Fields`, `Workshop Readiness`, `Success Metrics & Reference Patterns`, `Appendix: Full Question Bank`. The general Confluence documentation register rule in `prose-voice.md` says sentence case; CSE-owned pages override that. Match existing headings when editing; do not "fix" Title Case to sentence case without explicit user direction. Trailing generic nouns may stay lowercase when it reads naturally (`Service / Repo / Spec shape`, `Workspace and Catalog model`); capitalize the primary entity terms and keep the qualifier lowercase rather than forcing uppercase on every word.
- **Playbook intros use direct customer-facing framing.** When a section lists discovery questions, open with `Questions to ask the customer:` or the equivalent action-first phrasing for the audience. Avoid `Ten questions to run before routing the account` or other counts/process framing; Jared reverts that. The questions should feel like the first line of the customer conversation.
- **Prefer inclusive team voice over imperative prohibition.** `We can't schedule a hands-on workshop until…` lands better than `Do not schedule a hands-on workshop until…`. The first reads as a shared working constraint; the second reads as a compliance rule. Keep imperatives for hard compliance boundaries only.
- **Blockquotes are for secondary emphasis.** Reserve `<blockquote>` for pattern callouts (`Pattern 1:`, `Pattern 2:`), reference-example callouts (`Reference pattern — GoodLeap.`, `Reference pattern — Deloitte.`), and similar side-notes that sit next to the main body. Keep actual body paragraphs as plain paragraphs with an inline `<strong>` lead.
- **Number parallel patterns explicitly.** When a blockquote or callout enumerates multiple related patterns, label them `Pattern 1:` / `Pattern 2:` rather than `Pattern:` / `Pattern:` or bare em-dashes. Numbering disambiguates when a reader skims the callouts out of order.

### 3. Section rewrite with critic review

Use for homepage-grade or strategy-facing prose.

1. Draft in storage HTML or markdown-to-storage scratch, then inspect the exact storage body before writing.
2. Run a critic pass against `plugins/cse-tools/.agents/shared/prose-voice.md`, specifically the Confluence documentation register.
3. Apply requested changes and repeat until the critic returns approve/no-blockers.
4. Execute through the local Confluence MCP write surface only after approval.

### 4. GitHub org surfacing

Use when public CSE assets need to be reflected in Confluence.

1. Inventory the GitHub org with GitHub API/CLI.
2. Filter noise and identify source-of-truth README openers.
3. Cross-check existing CSRI/CSE catalogs before writing.
4. Draft short, concrete glosses and run the section rewrite critic gate when publishing to a homepage or owned landing page.

## Voice

Use the shared Confluence documentation register in `prose-voice.md`.

Minimum checks before publish:

- no bot identity tells
- no unresolved mentions
- no copied calibration strings
- no unsupported stale intake channels (`#cse-requests`, `#cse-intake`)
- no active `CSM` role unless the source explicitly requires historical context

Em dashes, `Source:`, formal negation, and business-day counters are warnings in generic Confluence pages, but elevate them for homepage/owned-page polish unless the page is a policy/runbook where formal wording is needed.

## Success criteria

- Audit mode returns report only.
- Write mode has a plan/diff, the raw pre-write snapshot when rollback evidence is required, version before/after, preview digest, and GET-back assertions.
- Rewrite mode has critic approval before the write.
- Any skipped write names the exact blocker and next step.
