Purpose: define epics as time-boxed (3–12 week) delivery containers that group backlog items around a coherent outcome. Each epic advances one primary pillar and is closed by a binary exit-criteria check.
If pillars are durable capability layers, epics are the batches of work that build them out. An epic is bigger than an item and smaller than a pillar; it has a charter, an owner, exit criteria, and a finite lifespan.
An epic is a delivery unit with:
Every epic charter names exactly one primary pillar. This is the pillar the epic most clearly advances. The epic may touch other pillars, but the primary anchor is single.
That is usually a sign the epic is too large. Split it. Each resulting epic should have a clear primary.
If splitting genuinely is not possible (the work is integrated by nature), pick the pillar whose most critical capability is being delivered. The other pillar becomes a “Secondary” link in the charter.
Cap the number of simultaneously active epics. Typical cap: 3.
The reason is not bureaucratic. Too many active epics produces a predictable failure mode:
Three active epics is a generous cap for most teams. Smaller teams should run fewer; larger teams with truly independent workstreams can run more, but should still cap explicitly.
An epic is active when work is actively progressing on its items. An epic that has not seen any item state change for two weeks is not active — it is either parked or done in everything but name. Audit the active set monthly.
To move an epic from planned to active, the WIP cap must allow it. If three epics are already active, you cannot start a fourth without first closing or parking one of the existing three. This forces an explicit decision: which epic is more valuable to finish now?
Without this gate, “active” loses meaning.
Each epic gets its own folder at backlog/epics/E<NN>-<slug>/. The folder contains a fixed set of five files:
backlog/
README.md # backlog workflow doc (project-level)
EPICS.md # rollup table (see below)
TEST_BACKLOG.md # cross-epic manual-QA queue (optional)
epics/
E<NN>-<slug>/
README.md # the epic charter
BACKLOG.md # active items (open, ready, in-progress, etc.)
ARCHIVE.md # completed and rejected items
FUTURE.md # items deferred to a later phase (P3 / nice-to-have)
TEST.md # epic-specific acceptance + regression scenarios
The five per-epic files are the standard pattern. An epic should ship all five even if some start empty — the empty-but-present file signals to contributors “this surface exists; add to it.” Empty files are cheap; missing files force every new contributor to re-derive the convention.
README.md — the charter. The single source of truth for what this epic is, why it exists, and when it is done. The full template is below.BACKLOG.md — active items. Every item in the epic that is not yet done lives here. Items are added when filed and moved out when archived or deferred. The format of individual items is defined in 04_backlog_items.md.ARCHIVE.md — completed items. When an item passes the Definition of Done and is marked done, it moves here. Also receives rejected items. Archives are append-only; do not edit history.FUTURE.md — deferred items. P3 / nice-to-have items that are real but not in scope for the current phase. Items here use either monotonic BL-#### IDs (Scheme A) or epic-scoped BL-E<NN>-F## IDs (Scheme B) per 04_backlog_items.md “FUTURE.md numbering”.TEST.md — epic-specific test scenarios. Two-table format: acceptance tests mapping to exit criteria + regression scenarios to protect. Per-item tests live in the item bodies (Test: field); TEST.md holds the epic-scoped scenarios that span multiple items or need manual QA. Template below.TEST_BACKLOG.md (optional)Some projects also keep a backlog/TEST_BACKLOG.md at the backlog root for cross-epic manual-QA scenarios — tests that span ≥ 2 epics, or that operators run on a cadence before milestone declarations. Each epic’s TEST.md covers epic-scoped scenarios; TEST_BACKLOG.md covers the rest. Skip it for small projects where the per-epic TEST.md files are sufficient; add it when QA volume justifies a central queue.
backlog/epics/.done in the rollup; the directory remains intact for audit.E<NN>-<slug>The folder name has two parts:
E<NN> — epic ID with the literal E prefix and a 2-digit zero-padded number (E01, E02, …, E12). The E prefix prevents collisions with item numbering and makes greps for “epic 7” unambiguous (rg "E07" vs rg "07" matching everything from item numbers to dates).<slug> — short kebab-case identifier under ~30 characters. Descriptive but tight: city-expansion not expansion-of-cities-to-new-locations.Together: E01-city-expansion, E02-ai-enrichment, E11-open-beta-launch. Numbering matches the epic ID in EPICS.md: E07 in the rollup → E07-content-protection on disk.
TEST.md is a standard per-epic file (recommended for every epic; required when the epic’s exit criteria need verification beyond what individual item tests cover). It holds the structured test inventory: acceptance scenarios mapping to exit criteria + regression scenarios to protect on every change.
The template is two or three tables:
# E<NN> — <Epic name> — Test scenarios
_Epic-specific acceptance + regression scenarios. The cross-epic
manual-QA queue lives in [../../TEST_BACKLOG.md](../../TEST_BACKLOG.md)._
## Acceptance tests for exit criteria
| ID | Scenario | Status |
|-------|--------------------------------------------------------------|------------|
| AT-01 | <Scenario verifying a binary exit criterion from the charter>| not-tested |
| AT-02 | <Scenario verifying a binary exit criterion> | pass |
## Regression scenarios to protect
| Area | Scenario | Last verified |
|-------------------|-------------------------------------------------------|----------------|
| <surface or flow> | <what to keep working as the epic evolves> | YYYY-MM-DD |
## Manual-QA scenarios (operator-driven, optional)
| Scenario | Cadence | Notes |
|-----------------------------------------------------|----------------------|-------|
| <Scenario that can't be cheaply automated> | Per minor release | <why manual> |
TEST.md can be empty (but should still exist)Even in those cases, ship an empty TEST.md with the two/three table headers. An empty-but-present file signals “this surface exists; add to it as the epic grows” — missing files force every new contributor to re-derive the convention.
AT-## (epic-scoped, monotonic — separate counter per epic). Cross-epic QA in TEST_BACKLOG.md uses QA-##.not-tested / pending / manual-verified / partial / pass / fail: <detail> / regression-needed / n/a. 04 is the only definition; this line names the values because the table is read without it.pass — BL-0428).deprecated if no longer relevant.The file is part of the epic folder. When the epic closes, TEST.md is the audit record of what was verified to support the exit-criteria sign-off.
The README.md inside each epic folder is the charter. The template below is the canonical shape. Paste it verbatim into a new epic and fill in the placeholders.
# E<NN> — <Epic title>
**Pillar (primary):** P<#> — <pillar name>
**Pillar (secondary, optional):** P<#> — <pillar name>
**Status:** planned | active | done | parked
**Phase:** Phase <#>
**Started:** — (or YYYY-MM-DD once Status flips to active)
**Target close:** YYYY-MM-DD or TBD
**Owner:** <human role> + <agent role>
## Assurance and capability owners
**Assurance baseline:** <inherited project profile or higher; see doc 07>
**Capability owners:** <customer intent; product/UX; technical delivery; verification coordination; accountable acceptance; security/compliance when applicable — human names or roles with current holders recorded in the repo>
## Outcome (jobs-to-be-done)
When <actor> <context>, they want <goal>, so <benefit>.
## Exit criteria (binary)
- [ ] <Criterion 1 — specific, falsifiable, checkable>
- [ ] <Criterion 2 — specific, falsifiable, checkable>
- [ ] <Criterion 3 — specific, falsifiable, checkable>
## KPIs
- <Measurable outcome 1, with target>
- <Measurable outcome 2, with target>
## Out of scope
- <Related work routed to another epic, with pointer>
- <Related work explicitly deferred to FUTURE.md, with pointer>
## Linked docs
- Pillar(s): [P<#> — <name>](../../docs/pillars/P<#>_<name>.md)
- Strategy: [<topic>](../../docs/strategy/<NN>_<topic>.md)
- Refinements (if any): [<refinement>](../../docs/architecture/<refinement>.md)
- Related epics: E<NN>, E<NN>
## Item roster
See [BACKLOG.md](BACKLOG.md) for active items, [ARCHIVE.md](ARCHIVE.md)
for completed, [FUTURE.md](FUTURE.md) for deferred.
planned — charter exists, items may be filed, but work has not started.active — work in progress; counts against the WIP limit.done — all items closed, exit criteria met, charter frozen.parked — work halted (priorities shifted, blocker appeared, etc.). Differs from done because the exit criteria are not met. Parked epics can resume; charter is preserved.The phase from the strategy roadmap (see 01_strategy.md). An epic belongs to exactly one phase. If an epic spans phases, it should usually be split at the phase boundary.
Started is the date the epic moved to active. Use — while in planned.Target close is the date by which the team intends the epic to be done. Use TBD if not yet committed. Adjust if the estimate changes; do not erase the original — note the change in the charter’s history.Name the human role (e.g., “product lead,” “tech lead”) and any agent role responsible for execution. Human roles must resolve to current holders in the repository. In the charter’s assurance/capability section, follow capability coverage and the assurance baseline. One person may cover several capabilities; mark inapplicable capabilities with a reason. Keep this section current when contributors rotate.
A single sentence in the canonical JTBD form: “When [actor] [context], they want [goal], so [benefit].” This is the heart of the charter. It is the answer to “what does this epic deliver?”
Examples (generic):
Note the pattern: actor, situation, desired outcome, business benefit. All four elements must be present. Vague actors (“the user”) or vague situations (“when using the app”) signal that the epic is not yet sharp enough.
Three to seven checkboxes, each of which:
“Improves quality” is not a criterion. “Median time-to-result drops below 200ms in the integration test suite” is.
If the epic genuinely cannot enumerate criteria, the epic is not ready to start. Charter it more carefully or break it into smaller, sharper epics.
Once a human approves them, the Outcome and the exit criteria are frozen intent — human-owned, not agent-editable. An epic whose exit criteria drift toward whatever the work happened to produce has no gate left. Mark the charter once, under the header:
> **Frozen intent** — Outcome and exit criteria approved by <who> on <YYYY-MM-DD>.
> Agents do not edit them; halt and renegotiate instead.
The measurable outcomes that prove the epic worked, not the exit criteria. KPIs may extend beyond the epic’s close date (e.g., “30-day retention after Phase 2 launch ≥ X%”). Two or three is the right number. More than five and the epic is unfocused.
KPIs differ from exit criteria. Exit criteria gate closure (“the integration test runs and passes”); KPIs measure success after closure (“the feature drives a measurable lift”).
Explicit. Pointed.
FUTURE.md.”The list should pre-empt scope creep. Whenever a reviewer or contributor asks “shouldn’t we also do X?” the answer should already exist in this section.
Links are absolute (within the repo). They must resolve. A broken link in a charter is a tax on every future reader.
The four allowed values:
| Status | Meaning | WIP cap counts? |
|---|---|---|
planned |
Charter exists; items may exist; work has not started. | No |
active |
Work in progress on the epic’s items. | Yes |
done |
All items archived; exit criteria met; charter frozen. | No |
parked |
Work halted before completion; exit criteria not met; can resume. | No |
planned ──┬──> active ──┬──> done
│ │
│ └──> parked ──> active (resume)
│ └──> done (close out, exit criteria met somehow)
│
└─────────────────────> parked (deprioritized before starting)
planned epic with no items for several months should be reviewed: still worth doing? If not, move to parked or document the decision.active epic with no item state change for two weeks should be audited: is the team actually working it? If not, move to parked and free up the WIP slot.done requires every exit-criteria checkbox to be true. If any are false, the epic stays active or parked. Do not move to done and leave open boxes.parked epic is not abandoned — its charter is preserved, its items remain in BACKLOG.md (or move to FUTURE.md if the pause is long). It can resume cleanly.EPICS.md)A single file at backlog/EPICS.md is the at-a-glance index of every epic. It is the first thing a new contributor or stakeholder reads to understand the state of work.
# Epics
Last updated: YYYY-MM-DD
| ID | Title | Pillar | Status | Phase | Open / Done | Next milestone | Owner |
|------|-------------------|--------|----------|-------|-------------|----------------------------------|------------------|
| E01 | <Epic title> | P1 | done | 1 | 0 / 14 | (closed) | product + agent |
| E02 | <Epic title> | P2 | active | 2 | 7 / 22 | <next visible shipment> | product + agent |
| E03 | <Epic title> | P3 | active | 2 | 4 / 11 | <next visible shipment> | product + agent |
| E04 | <Epic title> | P9 | active | 2 | 6 / 9 | <next visible shipment> | product + agent |
| E05 | <Epic title> | P7 | planned | 2 | 0 / 0 | <first item to land> | product + agent |
| ... | ... | ... | ... | ... | ... | ... | ... |
Update the rollup whenever any of the following happens:
BACKLOG.md and ARCHIVE.md (the Open and Done counts shift).Stale counts erode trust. If EPICS.md says 7 open and there are 4, contributors stop believing the rollup. Keep it honest.
The WIP limit is enforced by counting rows where Status is active. If that count would exceed the cap with a new active row, the transition is blocked until another active epic closes or parks.
Below the per-epic rollup, include a small “Pillar Coverage” table — the inverse view of the per-epic primary-pillar field. It answers “which epics are currently advancing pillar X?” in one glance.
## Pillar Coverage
| Pillar | Epics touching it |
|---------------------------------|----------------------------|
| P1 <pillar name> | E01 |
| P2 <pillar name> | E01, E02 |
| P3 <pillar name> | E03 |
| P4 <pillar name> | E06 |
| ... | ... |
Useful for:
The table is hand-maintained alongside the rollup. When an epic is added, removed, or changes primary pillar, both update.
A short “Last refresh” note at the top of the rollup makes the file’s freshness visible at a glance and lets readers see what changed since the last sweep:
> **Last refresh:** YYYY-MM-DD — <one-paragraph summary of what shipped since last refresh, what's currently in flight, and any known drift between summary counts and per-item state>.
When stale counts accumulate (a common backlog failure mode), the next refresh notes the drift explicitly and resets the table to ground truth.
The path an epic takes from creation to close:
stateDiagram-v2
[*] --> planned : charter written
planned --> active : WIP allows + work begins
active --> done : exit criteria all true
active --> parked : pause
parked --> active : resume
parked --> done : closed out
planned --> parked : deprioritized
done --> [*]
parked --> [*] : abandoned (rare, with note)
planned. The charter is written. Items can be filed against the epic (status backlog or ready per 04_backlog_items.md). No items are in-progress. The epic is not consuming a WIP slot.
active. Work has begun. At least one item should be in-progress or progressing toward done. The WIP slot is consumed. The rollup reflects open/done counts.
done. Every exit-criteria checkbox is true. Every item in the epic is in ARCHIVE.md (status done or rejected), with FUTURE.md containing any explicitly-deferred items. The charter is frozen — no more substantive edits. Subsequent work touching the same pillar starts a new epic.
parked. Work has paused without meeting exit criteria. Items are still in BACKLOG.md (or moved to FUTURE.md if the pause is expected to be long). The WIP slot is free.
Closing E<NN>:
- [ ] Every exit-criteria box in the charter is ticked.
- [ ] Every item in BACKLOG.md has been moved to ARCHIVE.md or FUTURE.md.
- [ ] BACKLOG.md is empty (only a placeholder line, if any).
- [ ] Pillar's "Delivering epics" list updated (this epic moves to "Past").
- [ ] EPICS.md rollup status flipped to `done`; counts final.
- [ ] If the epic produced new conventions or hard rules, those are
captured in the project instruction file (see 08_lessons_and_memory.md).
The close-out is a deliberate event, not a passive drift. Doing it cleanly preserves the audit trail and signals to the team that the epic is over.
Scope creep is the predictable enemy of every epic. The defense is structural: name what is out of scope explicitly, and route it visibly.
Every charter has this section. It is not optional. If you cannot name anything that is out of scope, you have not bounded the epic enough — every charter has natural neighbors of work that could be included and are not.
The section answers two questions for each excluded item:
FUTURE.md, or an explicit “we will not do this.”Three possible answers:
BACKLOG.md.FUTURE.md).FUTURE.md.”Without this discipline, epics absorb every adjacent suggestion and never finish.
## Out of scope
- Editorial review tooling — out of scope; see the E10 — Quality Ops epic in your project's backlog.
- Per-language voice catalog beyond the default — deferred; see [FUTURE.md](FUTURE.md).
- Migration of legacy content to the new schema — out of scope; one-off
migration handled by [E04 — Legacy Migration](../04-legacy-migration/README.md).
- Multi-region deployment — out of scope for this phase entirely; revisit
in Phase 3 planning.
Each line names what and where it goes. The reader leaves the section confident about the boundary.
Some work needs design before it can be chartered as an epic. The strategy is too abstract; the exit criteria can’t yet be written; the right scope isn’t yet visible. Forcing a charter at this stage produces vague exit criteria, which produces drifting epics.
The solution: a planning phase between strategy/pillars and epic chartering.
A planning doc is a pre-charter design artifact. It lives at docs/planning/<topic>.md (or wherever your project routes design work).
It captures:
The four planning layers (strategy, pillars, epics, items) all have crisp definitions and binary states. Design work doesn’t fit any of them:
Done means: for a design exploration).Naming this layer prevents two failure modes: (1) design work that never happens because there’s no place for it, and (2) epics that ship with vague scope because the design wasn’t finished before the charter.
A planning doc graduates to an epic charter when:
When the planning doc graduates, charter the epic per the template above. Link back to the planning doc from the epic charter’s “Linked docs” section — the planning doc remains the historical record of why the epic took the shape it did.
Planning docs typically carry a phase tag (e.g., phase2-beta, phase3-growth) so it’s clear which strategic phase the work serves. When a phase closes, planning docs from that phase move to an _archive/ subfolder; they remain reachable for audit.
Small, well-understood epics can charter directly. Use planning when:
If the team has already aligned on the approach, skip planning and charter directly.
| Mistake | Fix |
|---|---|
| Exit criteria are subjective (“looks good,” “is improved”). | Replace with checkable conditions (a test passes, a metric crosses a threshold, a feature ships). |
| Outcome reads like a feature list, not JTBD. | Rewrite in canonical form: “When |
| Two epics share scope ambiguously. | Sharpen the boundary in both charters. Use the “Out of scope” section to point at each other. |
Epic has been active for 14+ weeks. |
Audit. Likely too big — split into multiple epics. Or genuinely stalled — park it. |
Four epics are active and WIP cap is 3. |
One must close or park before any further work continues on a fourth. |
Rollup counts do not match BACKLOG.md reality. |
Recount. Establish an update-on-state-change habit. |
BACKLOG.md has items but charter exit criteria are blank. |
Stop work. Write the criteria first; otherwise the epic has no stopping condition. |
Closing an epic but FUTURE.md is empty when there are clearly deferred items. |
Add the deferred items to FUTURE.md before closing. Future contributors need to find them. |
| Charter changed silently mid-epic. | Charters can change, but the change should be visible — note it at the top under “Charter history.” Better still: bound the change to a re-chartering moment. |
| “Owner” lists specific people who left the team six months ago. | Use roles, not personal names. Roles persist; people change. |
# E07 — Content protection v1
**Pillar (primary):** P3 — Trust and quality
**Pillar (secondary, optional):** P6 — Safety and moderation
**Status:** active
**Phase:** Phase 2
**Started:** 2026-03-04
**Target close:** 2026-05-30
**Owner:** product lead + AI coding agent
## Assurance and capability owners
**Assurance baseline:** A2 — access control and paid-content protection.
**Capability owners:** product lead covers customer intent, product/UX, and
accountable acceptance; tech lead covers delivery, verification coordination,
security, and operations. Current holders are recorded in the project roster.
The author does not perform independent verification; assign a fresh verifier.
## Outcome (jobs-to-be-done)
When operators publish content to paying users, they want it to be
resistant to unauthorized copying and redistribution, so the value
exchange of the paid tier is preserved and contributors are paid for
their work.
## Exit criteria (binary)
- [ ] All paid-tier content delivered via signed, expiring URLs.
- [ ] Audio assets watermarked at generation with a verifiable identifier.
- [ ] Watermark recovery tool runs against a sample and identifies the
source contributor with 99% accuracy.
- [ ] Documented operator runbook for handling a suspected leak.
- [ ] Integration test exercises the full sign-deliver-revoke cycle.
## KPIs
- Verified leak incidents per 1000 paid users in the 90 days after
rollout: target less than 2.
- Median sign-and-deliver latency under 150ms at the 95th percentile.
## Out of scope
- Hardware-based DRM. Not in this phase; revisit in Phase 4 if leak
rates exceed target.
- Anti-screen-recording measures. Out of scope; see [FUTURE.md](FUTURE.md).
- Legal takedown workflow — out of scope; handled by
[E11 — Legal Operations](../11-legal-ops/README.md).
## Linked docs
- Pillar: [P3 — Trust and quality](../../docs/pillars/P3_trust.md)
- Pillar: [P6 — Safety and moderation](../../docs/pillars/P6_safety.md)
- Strategy: [Business model](../../docs/strategy/04_business.md)
- Strategy: [Risk register](../../docs/strategy/09_risk.md)
- Related epics: [E11 — Legal Operations](../11-legal-ops/README.md)
## Item roster
See [BACKLOG.md](BACKLOG.md), [ARCHIVE.md](ARCHIVE.md), [FUTURE.md](FUTURE.md).
Note how every section is filled, every claim is checkable, every link resolves, and every reasonable adjacent question (“what about hardware DRM? what about takedowns?”) has a pre-positioned answer.
Epics are bound by their charter. Mid-epic scope changes should be recorded explicitly, not absorbed silently. If a change is large enough to affect the exit criteria, treat it as a re-chartering moment — discuss, decide, edit the charter, note the change at the top.
Epics are bound by the strategy phase. An epic cannot exit unless its work belongs to a phase that is still active. (If a phase closes mid-epic, finish the epic or park it; do not retroactively reclassify it into a different phase.)
Epics are bound by the WIP limit. Starting a new active epic when the cap is full requires another epic to close or park first. No exceptions; the cap exists because the failure mode of ignoring it is severe.
Next: 04 — Backlog items