---
description: "Canonical required-reading list for outward-facing payloads (PR body, Jira comment, closing report) plus the markup dialect per surface. Loaded by every mode that runs Phase 6 or Phase 7."
---

# Outward-facing payload contracts

> Every mode that opens a PR, comments on a tracker, or closes out a run reads this file first. It does not restate the contracts  -  it names them, so no mode has to carry its own copy and drift from the others.

## Read before Phase 6

| Read | Before | Governs |
|---|---|---|
| [`channels/pr.md`]($HOME/.claude/multi-agent-refs/channels/pr.md) | assembling the PR body | fixed section set (`summary` → `changes` → `architecture` cond. → `verification` → `dependencies` cond. → `related`), Markdown-only rule, reviewer-preserving Bitbucket PUT payload |
| [`phases/phase-6-commit.md`]($HOME/.claude/multi-agent-refs/phases/phase-6-commit.md) | committing | commit convention, default-reviewer fetch, draft/ready prompt, push-must-succeed loop |
| [`rules.md`]($HOME/.claude/multi-agent-refs/rules.md) "External System Outputs" | any REST payload | real newlines, no HTML entities, no hand-rolled JSON, markup dialect per surface |

## Read before Phase 7

| Read | Before | Governs |
|---|---|---|
| [`channels/jira.md`]($HOME/.claude/multi-agent-refs/channels/jira.md) | posting the Jira comment | fixed section set incl. **Test Scenarios** (Given/When/Then, always present), markdown→wiki conversion table |
| [`channels/confluence.md`]($HOME/.claude/multi-agent-refs/channels/confluence.md) | writing a Confluence page | storage-format conversion, endpoint flavor |
| [`phases/phase-7-report.md`]($HOME/.claude/multi-agent-refs/phases/phase-7-report.md) | closing out | Timeline + Agent Activity + Cost Breakdown tables, missing-telemetry disclosure |
| [`tracker-contract.md`]($HOME/.claude/multi-agent-refs/tracker-contract.md) | every phase boundary | per-phase token narration, completion tile suffix |

## Markup dialect per surface

Language is not the only axis an external payload has. Every surface also has a markup dialect, and they are not interchangeable  -  the same body shipped to the wrong dialect renders as visible garbage, not as a slightly-off style.

| Surface | Dialect | Converter | Section set owned by |
|---|---|---|---|
| PR description (GitHub / Bitbucket / GitLab) | **Markdown**, no conversion | none  -  post the assembled markdown verbatim | `channels/pr.md` |
| GitHub issue body + comment | **Markdown**, no conversion | none | `channels/issue-comment.md` |
| Jira comment + issue description | **Jira wiki markup** | the table in `channels/jira.md`, applied by the model; the emoticon escape that follows it is a program, `scripts/jira-wiki-escape.mjs`, and is required before every POST/PUT; description writes go through `lib/jira-publish.sh`, which backs the field up and refuses a blind replace | `channels/jira.md` |
| Confluence page body | **storage format** (XHTML) | `lib/md2confluence-v3.py` | `channels/confluence.md` |
| Wiki pages (`.md` files in a git repo) | **Markdown** | none | `channels/wiki.md` |
| Commit message | plain text | none | `rules/git-conventions.md` |

Assemble every body once in Markdown, then convert **only** on the branches that require it. The recurring defect is the reverse: the Jira wiki table is the only text-markup table in the doc set, so it reads like the default and gets applied to a PR body. In a Markdown target, `h2. Title` renders as literal text, `{{identifier}}` keeps its braces, `#` starts an H1 instead of a numbered list, and `*bold*` comes out italic. In a Jira target the mirror-image failure applies: `## Heading` and `**bold**` render literally.

A payload that is in the right language but the wrong dialect is a defect of the same severity as one that never posted. Both need a fix, not a follow-up ticket.

## Closing report (required)

The run ends with the phase tracker glyph block **and** the numbers behind it  -  per-phase duration and token spend, plus totals.

- Record spend as you go: `phase-tracker.sh tokens <N> <in> <out> [cached]` after **every** LLM call, including each Phase 4 reviewer subagent and each Phase 3 chunk. Counts are additive and nothing reconstructs them after the fact.
- Tag the model once per phase (`phase-tracker.sh model <N> <name>`) or the cost helper cannot price it and prints `-`.
- Durations come from the phase timestamps and survive a missed `tokens` call; token spend does not.
- If any phase has no token data, name those phases and say their cost is unavailable. Never print a report whose cost section is simply absent  -  the reader cannot tell "cheap run" from "nobody recorded it".

### Missing-telemetry disclosure (Phase 7, required)

Before composing the report, compute which phases carry no token data:

```bash
STATE="$HOME/.claude/logs/multi-agent/$TASK_ID/tracker-state.json"
UNTRACKED=$(jq -r '[.phases[] | select((.tokens_in // 0) + (.tokens_out // 0) == 0) | .id] | join(", ")' "$STATE")
```

Non-empty `UNTRACKED` → both the agent-log report and the closing chat summary carry one line in `outputLanguage` naming those phase ids as cost-unavailable. Durations come from the phase timestamps and are reported either way.

`smoke-tracker-tokens-invocation.sh` only lints that the phase docs *mention* `phase-tracker.sh tokens`. It cannot observe a run that read the doc and skipped the call, so this run-time disclosure is the only thing between a dropped `tokens` call and an invisible failure.

## Fast modes are not exempt

A Short run skips Analysis and Planning, and the autopilot and local entries skip the interactive test gate. They run Phase 6 and Phase 7 **unchanged**. A short pipeline is not a licence for an improvised payload shape, a missing Test Scenarios section, or a report without numbers.
