| name | agile:epic:pack |
| description | Pack every markdown artifact in an epic folder (epic.md, plan.md, design.md, checklist.md, and every feature's spec.md + tasks.md) into a single NotebookLM-ready source document at NNN-pack.md, then strictly validate that no content was lost in translation. Use this whenever the user wants to combine epic artifacts for Google NotebookLM ingestion, generate a single source for Gemini-based infographic / slide deck / video presentation creation, prepare an epic for stakeholder briefing material, or asks to "pack", "combine", "bundle", "consolidate", or "flatten" an epic's documentation. Strict validation blocks the commit on any context loss. |
| user-invocable | true |
| disable-model-invocation | true |
| allowed-tools | Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion |
Epic Pack
Combine every markdown artifact in an epic folder into a single, NotebookLM-optimized source document. Strictly validate the result so Gemini can generate infographics, slide decks, and video presentations without silent context loss.
Invocation
/agile:epic:pack — auto-detect a target epic in agile/epics/
/agile:epic:pack 015 — target epic 015
/agile:epic:pack agile/epics/015-cicd-pipelines — target a specific path
Context
- Current branch: !
git branch --show-current
- Recent epics: !
ls agile/epics/ 2>/dev/null | sort | tail -10
Why this skill exists
Epic artifacts live as 4 top-level files (epic.md, design.md, plan.md, checklist.md) plus 2 files per feature (spec.md, tasks.md). NotebookLM can technically take many sources per notebook, but Gemini produces dramatically better outputs (audio overview, mind map, slide deck, video presentation, infographic) when given a single, well-structured source with explicit cross-section navigation. Multi-source notebooks fragment Gemini's outline extraction and break cross-references.
This skill produces that single source, deterministically, and then validates it strictly so the user can be confident that nothing was dropped, truncated, or silently rewritten.
Phases
Phase 1: Resolve & Verify
-
Resolve EPIC_DIR:
- If
$ARGUMENTS is a 3-digit number (e.g. 015): match a directory in agile/epics/ whose name starts with that prefix.
- If
$ARGUMENTS is a path: use it directly (must exist).
- If no argument: list candidates in
agile/epics/ that have epic.md AND plan.md. If exactly one is in the current branch context, use it. Otherwise use AskUserQuestion to let the user choose from up to 10 most-recently-modified candidates.
-
Hard prerequisites (exit with a clear error if any fails):
EPIC_DIR/epic.md exists
EPIC_DIR/plan.md exists
EPIC_DIR contains at least one NNN-XX-* feature subdirectory containing either spec.md or tasks.md
-
Soft warnings (do not block, but report):
design.md missing → may have been archived elsewhere; pack will still proceed and the validator will not require it.
checklist.md missing → same.
- Any feature directory missing both
spec.md and tasks.md.
Phase 2: Pack
Run the packer:
python3 .claude/skills/agile-epic-pack/scripts/pack.py --epic-dir EPIC_DIR
The packer writes EPIC_DIR/NNN-pack.md (where NNN is the epic number prefix) and prints a one-line summary with source count, feature count, output word count, and output byte count. Capture the output for the final report.
If the packer exits non-zero, surface the stderr verbatim and stop. Do not proceed to validation.
Phase 3: Strict Validation
Run the validator in strict mode:
python3 .claude/skills/agile-epic-pack/scripts/validate.py \
--epic-dir EPIC_DIR \
--pack EPIC_DIR/NNN-pack.md \
--strict
The validator runs eight checks against the freshly written pack:
| # | Check | What it guarantees |
|---|
| 1 | content-coverage | Every non-heading content line from every source appears verbatim in the pack |
| 2 | heading-preservation | Pack contains at least as many headings as the sum of source headings |
| 3 | table-preservation | Every table row from every source is preserved |
| 4 | code-fence-preservation | Code fence count is preserved (so ASCII DAGs survive intact) |
| 5 | metadata-preservation | Every **FieldName**: metadata line (DevOps IDs, Status, dates, etc.) is preserved |
| 6 | cross-reference-rewriting | No unrewritten epic.md / design.md / plan.md / checklist.md references remain outside code fences |
| 7 | word-count-sanity | Pack word count ≥ 95% of the sum of source word counts |
| 8 | notebooklm-size-limit | Pack word count is below NotebookLM's per-source limit (500,000 words; warns at 400,000) |
On failure (validator exits 1):
- Show the validator's full report to the user.
- Identify whether the failure is in
pack.py (a code bug — the source content exists but the script dropped it) or in the source artifacts (an unusual structure the script doesn't yet handle).
- Use
AskUserQuestion to present options:
- "Diagnose and fix the packer", "Skip validation and write the pack anyway (NOT recommended)", "Abort"
- Do NOT auto-commit on validation failure.
On success (validator exits 0):
- Show the validator's summary report (one PASS line per check) so the user can see exactly what was checked.
- Proceed to Phase 4.
Phase 4: Present & Commit
-
Print a summary block:
Epic Pack Complete
Source: EPIC_DIR
Pack: EPIC_DIR/NNN-pack.md
Sources packed: M epic-level files + N features
Pack size: X words / Y bytes
Validation:
[PASS] content-coverage (no missing lines)
[PASS] heading-preservation (P pack / Q source headings)
[PASS] table-preservation (R rows preserved)
[PASS] code-fence-preservation (S fences preserved)
[PASS] metadata-preservation (T metadata lines preserved)
[PASS] cross-reference-rewriting (no dangling .md refs)
[PASS] word-count-sanity (ratio Z)
[PASS] notebooklm-size-limit (X / 500000 words)
Next: upload NNN-pack.md to a new NotebookLM notebook as the only source,
then generate audio overview → mind map → slide deck → video.
-
Use AskUserQuestion to ask:
- Question: "Pack written and validated. What would you like to do next?"
- Options:
"Commit the pack" — git add EPIC_DIR/NNN-pack.md && git commit -m "docs(agile): add NotebookLM pack for epic NNN"
"Open the pack for review first" — print the path and stop
"Done — leave uncommitted" — print the path and stop
-
If the user picks "Commit", run the git commands and report the new commit hash.
Key Principles
- Deterministic packer:
pack.py is pure text transformation. The same inputs always produce the same output. There is no LLM in the packing path so the result is reproducible and easy to debug.
- Strict validation by default: silent context loss is the worst failure mode for this skill — Gemini will happily generate confident, polished slides about content that was dropped. The validator's job is to make that impossible.
- Single H1, demoted hierarchy: the pack has exactly one H1 (the epic title). Source H1s are demoted to H2; deeper headings shift accordingly. NotebookLM uses heading hierarchy as the primary signal for outline / slide / mind-map generation, so a clean hierarchy directly improves output quality.
- Anchors, not file paths: cross-references like "see design.md" become anchor links (
[Design](#design)) so the pack reads top-to-bottom without dangling references.
- ASCII DAGs stay in code fences: Feature Workflow and Tasks Workflow diagrams use whitespace alignment that NotebookLM only preserves inside fenced code blocks. The packer never lifts content out of fences.
- Bridge paragraphs help video output: short narrative bridges between major sections give Gemini natural transition points; video narrations come out noticeably more coherent with them.
- The 500k word limit is real: NotebookLM truncates oversized sources silently. The validator hard-fails above 500k words and warns above 400k so the user can split the epic into phase-scoped packs before hitting that ceiling.
Scripts
| Script | Purpose | Inputs | Output |
|---|
scripts/pack.py | Combine all epic artifacts into one markdown file | --epic-dir, optional --output | Writes NNN-pack.md; prints summary to stdout |
scripts/validate.py | Strict context-preservation validation | --epic-dir, --pack, --strict | Exit 0 = pass, 1 = fail; report on stdout |
References
| File | Purpose |
|---|
references/notebooklm-optimization.md | Background on how NotebookLM/Gemini ingests markdown sources, why the pack is structured the way it is, common failure modes, and tips for the post-pack NotebookLM workflow. Read this when debugging unexpected NotebookLM output, or when adjusting the packer for new artifact types. |
Terminal State
The terminal state is a written, validated NNN-pack.md in the epic root, optionally committed. This skill does NOT upload to NotebookLM, generate any infographic / slide deck / video, or invoke any other skill — those are external steps the user takes manually with the produced file.