Scrum4Me/docs/plans/docs-restructure-pbi-spec.md
Janpeter Visser 7e45bbdbc0
docs: AI-optimized docs restructure (Phases 1–8) (#61)
* docs(dialog-pattern): add generic entity-dialog spec

Introduceert docs/patterns/dialog.md als bron-of-truth voor elke
create/edit/detail-dialog in Scrum4Me, ongeacht het achterliggende
dataobject. Bevat 14 secties: uitgangspunten, stack, component-
architectuur, layout, validatie, drielaagse demo-policy, submission,
dialog-gedrag, theming, footer, triggers/URL-state, per-entiteit
profile-template, out-of-scope, en een verificatie-checklist.

Registreert het patroon in CLAUDE.md "Implementatiepatronen"-tabel
zodat Claude (en mensen) de spec verplicht raadplegen voor elke
nieuwe dialog.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(dialog-pattern): convert task spec + add pbi/story entity-profiles

Reduceert docs/scrum4me-task-dialog.md van 507 naar ~140 regels: alle
gedeelde regels verhuisd naar docs/patterns/dialog.md, dit document
bevat nu alleen Task-specifieke velden, URL-pattern, status-veld,
server actions, triggers en bewuste out-of-scope-keuzes.

Voegt twee nieuwe entity-profielen toe voor bestaande dialogen:
- docs/scrum4me-pbi-dialog.md (PbiDialog: state-based, code+title-rij,
  PbiStatusSelect, geen delete in v1)
- docs/scrum4me-story-dialog.md (StoryDialog: state-based, header met
  status/priority badges, inline activity-log, demo-readonly-fallback,
  inline-delete-confirm i.p.v. AlertDialog)

Beide profielen documenteren expliciet de "Bekende gaps t.o.v.
generieke spec" zodat opvolgende PR's de afwijkingen kunnen
rechtzetten of bewust kunnen accorderen.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Added pdevelopment docs

* docs(plans): add docs-restructure plan for AI-optimized lookup

Audit of existing 39 doc files (~10.700 lines) and a phased restructure
proposal aimed at minimising the tokens an AI agent has to read to find
the right reference. Captures resolved decisions on language (English),
ADR template (Nygard default with MADR escape-hatch), index generator
(node script), and folder taxonomy. Proposal status — fase 1 to follow.

* docs(adr): add ADR scaffolding (templates, README, meta-ADR)

Set up docs/adr/ as the canonical home for architecture decisions:

- templates/nygard.md — default four-section format (Status, Context,
  Decision, Consequences) for one-way-door decisions.
- templates/madr.md — MADR v4 with YAML front-matter and explicit
  Considered Options for decisions where rejected alternatives matter.
- README.md — naming convention (NNNN-kebab-case), template-selection
  guidance (Nygard default; MADR for auth, queue mechanics, agent
  integration), status lifecycle, and ADR roster.
- 0000-record-architecture-decisions.md — meta-ADR establishing the
  practice itself, in Nygard format.

Backfilling existing implicit decisions (base-ui-over-radix, float
sort_order, demo-user three-layer policy, etc.) is fase 6 of the
docs-restructure plan.

* feat(docs): add docs index generator + initial INDEX.md

scripts/generate-docs-index.mjs walks docs/**/*.md, parses YAML
front-matter (or first H1 fallback) and a Nygard-style ## Status
section, then writes docs/INDEX.md with grouped tables for ADRs,
Specs, Plans (with archive subsection), Patterns, and Other.

Pure Node 20 (no external deps); idempotent — running it twice
produces byte-identical output. Excludes adr/templates/, the ADR
README, INDEX.md itself, and any *_*.md sidecar file.

Wire-up:
- package.json: docs:index → node scripts/generate-docs-index.mjs

Initial run indexed 35 docs across the existing structure; the
generated INDEX.md is committed so the table is reviewable in the
PR before hooking generation into a pre-commit step.

* chore: ignore Obsidian vault and personal sidecar files

Add .obsidian/ (Obsidian vault config) and _*.md (personal sidecar
notes) to .gitignore so the docs/ tree can serve as canonical source
of truth while still being usable as an Obsidian vault for personal
authoring. The docs index generator already excludes the same _*.md
pattern from INDEX.md.

* docs(plans): add PBI bulk-create spec for docs-restructure

Machine-parseable spec for an executor that calls the scrum4me MCP
(create_pbi → create_story → create_task) to seed the docs-restructure
work into the DB.

- Section 1 (Context) is the PBI description; serves as task-context
  via mcp__scrum4me__get_claude_context.
- Section 2 lists the 6 resolved decisions (English, MD3+styling
  merged, solo-paneel merged, .Plans archived, Nygard ADR default,
  node index script).
- Section 3 records what already shipped on this branch so the
  executor doesn't duplicate the ADR scaffolding or index generator.
- Section 4 carries the structured YAML graph: 1 PBI, 8 stories
  (one per phase), 39 tasks. product_id is REPLACE_ME — fill before
  running.
- YAML validated with PyYAML; field schema sanity-checked.

* docs(junk-cleanup): remove stub patterns/test.md

* docs(junk-cleanup): archive .Plans/ to docs/plans/archive/

* docs(front-matter): add YAML front-matter to docs/ root

* docs(front-matter): add YAML front-matter to patterns/

* docs(front-matter): add YAML front-matter to plans + agent files

* docs(index): regenerate INDEX.md after front-matter pass

* docs(naming): drop scrum4me- prefix from doc filenames

* docs(naming): lowercase API.md and MD3 filenames

* docs(naming): rename plan file to kebab-case ASCII

* docs(naming): rename middleware.md to proxy.md (next 16)

* docs(naming): polish CLAUDE.md doc-index after renames

* docs(taxonomy): scaffold topical folders under docs/

* docs(taxonomy): move spec files into docs/specs/

* docs(taxonomy): move design/api/qa/backlog/assets into folders

* docs(taxonomy): move agent-instruction-audit into decisions/

* docs(split): break architecture.md into 6 topical files

* docs(split): merge solo-paneel-spec into specs/functional.md

* docs(split): merge md3-color-scheme into design/styling

* docs(trim): extract branch/commit rules into runbook

* docs(trim): extract MCP integration into runbook

* docs(adr): add 0001-base-ui-over-radix

* docs(adr): add 0002-float-sort-order

* docs(adr): add 0003-one-branch-per-milestone

* docs(adr): add 0004-status-enum-mapping

* docs(adr): add 0005-iron-session-over-nextauth

* docs(adr): add 0006-demo-user-three-layer-policy

* docs(adr): add 0007-claude-question-channel-design

* docs(adr): add 0008-agent-instructions-in-claude-md + update README index

* docs(index): regenerate after ADR 0001-0008

* docs(glossary): add docs/glossary.md

* chore(docs): regenerate INDEX.md in pre-commit hook

* docs(readme): link INDEX + glossary + agent instructions

* feat(docs): add doc-link checker script

* chore(docs): wire docs:check-links and docs npm scripts

* ci(docs): block merge on broken doc links

* docs(links): fix broken cross-references after restructure

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 03:21:59 +02:00

37 KiB
Raw Blame History

spec_version spec_type generated_at language notes
1 pbi-bulk-create 2026-05-02 en Input for a bulk-create executor that calls mcp__scrum4me__create_pbi mcp__scrum4me__create_story mcp__scrum4me__create_task in that order. The executor reads the YAML graph at the bottom of this file. The prose above the graph is identical to what the executor sends as the PBI's `description` field, so any agent that later picks up a task gets the full context via mcp__scrum4me__get_claude_context. product_id is intentionally left as a placeholder (REPLACE_ME) — fill it in before running the executor. priority uses 1 = critical … 5 = trivial. sort_order is omitted everywhere; the MCP server auto-assigns last+1 within the priority group.

PBI Bulk-Create Spec — Docs-Restructure for AI-Optimized Lookup

1. Context (this becomes the PBI description)

This PBI executes the docs-restructure plan (docs/plans/docs-restructure-ai-lookup.md) over eight phases, mapped here as eight stories with three to eight tasks each. The goal is to cut the documentation surface an AI agent has to read to find the right reference, without breaking existing workflows.

Why this PBI exists

Today an agent loads CLAUDE.md (340 lines) every turn before reading a single line of code, then has to choose from 35 docs in docs/ whose purpose is only inferable from the filename — there is no front-matter, no index, no machine-readable status. After this PBI, the agent reads CLAUDE.md (≤150 lines) plus docs/INDEX.md and knows where to go.

Going-forward defaults — every task must respect these

  • Language: all new and touched docs in English. Code comments stay English (already the case). UI strings stay Dutch.
  • Front-matter: every .md under docs/ (and CLAUDE.md, AGENTS.md) carries YAML front-matter with at minimum title, status, audience, language, last_updated. Add related, when_to_read, do_not_read_for where useful.
  • Naming: lowercase kebab-case. No `` prefix. No spaces in filenames. No UPPER. Files matching _*.md are personal sidecar and excluded from the index.
  • Commits: one commit per logical layer. Use docs(<story-slug>): as the prefix when no ST-code applies. Reference the matching story slug from this spec (e.g. docs(naming): drop prefix).
  • Pushing: never push without explicit user approval. Local commits on the feature branch only. The branch convention is feat/docs-restructure-<phase-slug> (one branch per story).
  • Cross-references: when renaming or moving a file, update every internal link to it in the same commit. After the link-check story (Story 8) is done, run npm run docs:check-links before each commit.

Sequencing

Stories run in numeric order. Story N+1 assumes the changes from Story N are merged. If you pick up a task and earlier stories aren't done, stop and surface it — don't try to leapfrog. The exception is Story 6 (ADR-backfill) and Story 7 (glossary): both are content-only and can run in parallel with Stories 35 if you want.

Out of scope

  • Translating Dutch docs that this PBI doesn't otherwise touch — that's a separate full-sweep PR.
  • Code changes outside docs/, scripts/, package.json, .gitignore.
  • Pushing branches or opening PRs against main.
  • Restyling, content rewrites beyond what each task asks for.

Where to look first

Definition of done for this PBI

  • All 8 stories' tasks accepted.
  • docs/INDEX.md regenerates without errors and lists every doc grouped correctly.
  • npm run docs:check-links passes (after Story 8).
  • CLAUDE.md ≤ 150 lines.
  • Zero docs without front-matter.
  • Zero junk files (docs/patterns/test.md, Brainstorm.md at root, .Plans/ at root) remain.

2. Resolved decisions (quick reference)

# Question Decision
1 Doc language English for all new/touched docs
2 MD3-color + styling Merge into one docs/design/styling.md
3 solo-paneel-spec.md Merge into docs/specs/functional.md
4 .Plans/ Archive under docs/plans/archive/
5 ADR template Nygard default; MADR for auth, queue, agent integration
6 Index generator Node script (scripts/generate-docs-index.mjs, already exists)

3. What's already done (do not re-do)

These commits on feat/docs-adr-and-index already shipped:

  • docs(plans): the restructure plan itself.
  • docs(adr): ADR scaffolding — templates, README, meta-ADR (0000).
  • feat(docs): the docs index generator + initial docs/INDEX.md.
  • chore: .gitignore for .obsidian/ + _*.md.

So Story 6 only needs the content (the actual ADR-0001 … 0008 files); Story 7 only needs the glossary + husky hook, the script already exists.


4. Structured graph (executor reads this)

pbi:
  product_id: REPLACE_ME
  title: "Docs-restructure for AI-optimized lookup"
  description: |
    See section 1 (Context) above. Every task in this PBI must respect:
    - English for new/touched docs (UI strings stay Dutch).
    - YAML front-matter on every doc (title, status, audience, language,
      last_updated; related/when_to_read/do_not_read_for where useful).
    - kebab-case, lowercase, no  prefix, no spaces.
    - One commit per logical layer (`docs(<story-slug>):` prefix).
    - No pushes without user approval.
    - Update every internal link in the same commit as a rename.
    Read docs/plans/docs-restructure-ai-lookup.md §3, §4, §6, §8 first.
  priority: 2

  stories:

    - slug: junk-cleanup-and-front-matter
      title: "Phase 1 — Junk cleanup + front-matter on every doc"
      description: |
        Lowest-risk first phase. Remove stub/junk files, archive parallel
        plan folder, and add YAML front-matter to every existing .md
        under docs/. No paths change yet — every existing link still
        works after this story.
      acceptance_criteria: |
        - docs/patterns/test.md is deleted.
        - .Plans/ is moved to docs/plans/archive/ and the .gitignore
          entry for .Plans/ is removed.
        - Brainstorm.md at repo root is deleted (or moved to
          docs/scratch/) — it's already gitignored.
        - Every existing .md under docs/ (and CLAUDE.md, AGENTS.md) has
          YAML front-matter with at least title, status, audience,
          language, last_updated.
        - `npm run docs:index` reports 0 docs missing front-matter and
          regenerates docs/INDEX.md cleanly.
      priority: 2
      tasks:

        - title: "Remove docs/patterns/test.md"
          description: "One-word stub file (`test`) committed by accident."
          implementation_plan: |
            git rm docs/patterns/test.md
            grep -rn "patterns/test" docs/ CLAUDE.md AGENTS.md README.md
              # expect no matches
            commit: docs(junk-cleanup): remove stub patterns/test.md
          priority: 3

        - title: "Archive .Plans/ into docs/plans/archive/"
          description: "Three historical plan files at repo root parallel to docs/plans/."
          implementation_plan: |
            mkdir -p docs/plans/archive
            git mv .Plans/2026-04-27-claude-md-workflow-update.md docs/plans/archive/
            git mv .Plans/2026-04-27-insert-milestone-tool.md docs/plans/archive/
            git mv .Plans/2026-04-27-m8-realtime-solo.md docs/plans/archive/
            rmdir .Plans
            # remove the .Plans/ entry from .gitignore (line 55 today)
            commit: docs(junk-cleanup): archive .Plans/ to docs/plans/archive/
          priority: 3

        - title: "Delete root Brainstorm.md"
          description: "Already gitignored; contains stray Prisma + DOM dump with no context."
          implementation_plan: |
            git rm -f Brainstorm.md
            # leave the .gitignore Brainstorm.md entry — harmless if file gone
            commit: docs(junk-cleanup): remove root Brainstorm.md scratch file
          priority: 4

        - title: "Add front-matter to all docs/*.md (root)"
          description: "13 files at docs/ root currently have no front-matter."
          implementation_plan: |
            For each file in docs/*.md (excluding INDEX.md):
              prepend a YAML block:
                ---
                title: <copy from H1>
                status: active
                audience: [maintainer, contributor]
                language: nl   # or en, match the actual file
                last_updated: 2026-05-02
                ---
            Verify: head -1 docs/*.md | grep -c '^==>' should equal
            (count of files), and head -2 docs/*.md should show "---" on
            line 2 of every file.
            commit: docs(front-matter): add YAML front-matter to docs/ root
          priority: 2

        - title: "Add front-matter to docs/patterns/*.md"
          description: "11 patterns get front-matter with audience=ai-agent."
          implementation_plan: |
            For each docs/patterns/*.md:
              ---
              title: <H1 minus 'Patroon: ' prefix>
              status: active
              audience: [ai-agent, contributor]
              language: nl
              last_updated: 2026-05-02
              when_to_read: <one sentence — what triggers reading this>
              ---
            commit: docs(front-matter): add YAML front-matter to patterns/
          priority: 2

        - title: "Add front-matter to docs/plans/*.md and CLAUDE.md/AGENTS.md"
          description: "Plans, the orientation file, and AGENTS.md."
          implementation_plan: |
            Plans (active + archive): include `applies_to: [<milestone>]`
            and `status: <proposal|active|done|deprecated>` based on git
            history of the file.
            CLAUDE.md and AGENTS.md: status: active, audience: ai-agent.
            commit: docs(front-matter): add YAML front-matter to plans + agent files
          priority: 2

        - title: "Verify INDEX.md picks up new metadata"
          description: "Sanity check: status and dates now visible in INDEX.md."
          implementation_plan: |
            npm run docs:index
            grep -c "| — |" docs/INDEX.md
              # expect significantly fewer than before (most rows now
              # show real status/date)
            commit: docs(index): regenerate INDEX.md after front-matter pass
          priority: 3

    - slug: naming-normalization
      title: "Phase 2 — Normalize file naming"
      description: |
        Drop the `` prefix. Lowercase everything. Remove the
        space + em-dash filename. Rename Next.js 16 middleware to proxy.
        After this story all filenames are kebab-case and grep-friendly.
      acceptance_criteria: |
        - No file under docs/ starts with ``.
        - No file under docs/ uses UPPER, snake_case, or contains spaces.
        - docs/patterns/proxy.md is renamed to docs/patterns/proxy.md.
        - Every internal link to renamed files is updated in the same
          commit as the rename.
        - `npm run docs:index` runs cleanly with no missing files.
      priority: 2
      tasks:

        - title: "Rename docs/* (drop prefix)"
          description: "8 spec/backlog/styling files at docs/ root."
          implementation_plan: |
            git mv docs/architecture.md     docs/architecture.md
            git mv docs/backlog/index.md          docs/backlog/index.md
            git mv docs/specs/functional.md  docs/specs/functional.md
            git mv docs/specs/dialogs/pbi.md       docs/specs/dialogs/pbi.md
            git mv docs/specs/personas.md         docs/specs/personas.md
            git mv docs/backlog/product-historical.md  docs/backlog/product-historical.md
            git mv docs/specs/dialogs/story.md     docs/specs/dialogs/story.md
            git mv docs/design/styling.md          docs/design/styling.md
            git mv docs/specs/dialogs/task.md      docs/specs/dialogs/task.md
            git mv docs/qa/api-test-plan.md        docs/qa/api-test-plan.md
            # update every internal link
            grep -rln "" docs/ CLAUDE.md AGENTS.md README.md \
              | xargs sed -i '' 's|||g'
            npm run docs:index
            commit: docs(naming): drop  prefix from doc filenames
          priority: 2

        - title: "Lowercase api.md and MD3 file"
          description: "Two files use non-kebab capitalization."
          implementation_plan: |
            git mv docs/api/rest-contract.md docs/api/rest-contract.md
            git mv docs/design/styling.md docs/design/styling.md
            grep -rln "API\.md\|MD3_Color_Scheme" docs/ CLAUDE.md AGENTS.md README.md \
              | xargs sed -i '' 's|API\.md|api.md|g; s|md3-color-scheme|md3-color-scheme|g'
            npm run docs:index
            commit: docs(naming): lowercase api.md and MD3 filenames
          priority: 2

        - title: "Rename plan file with spaces + em-dash"
          description: "`tweede-claude-agent-planning.md` → kebab-case."
          implementation_plan: |
            git mv "docs/plans/tweede-claude-agent-planning.md" \
                   docs/plans/tweede-claude-agent-planning.md
            grep -rln "Tweede Claude Agent" docs/ CLAUDE.md AGENTS.md README.md \
              | xargs sed -i '' 's|Tweede Claude Agent — Planning Agent\.md|tweede-claude-agent-planning.md|g'
            npm run docs:index
            commit: docs(naming): rename plan file to kebab-case ASCII
          priority: 3

        - title: "Rename middleware.md → proxy.md"
          description: "Next.js 16 renamed middleware.ts to proxy.ts."
          implementation_plan: |
            git mv docs/patterns/proxy.md docs/patterns/proxy.md
            grep -rln "patterns/proxy" docs/ CLAUDE.md AGENTS.md README.md \
              | xargs sed -i '' 's|patterns/proxy|patterns/proxy|g'
            npm run docs:index
            commit: docs(naming): rename middleware.md to proxy.md (next 16)
          priority: 3

        - title: "Update CLAUDE.md doc-index table"
          description: "After renames, CLAUDE.md §Specificatiedocumenten and §Implementatiepatronen tables need a sweep."
          implementation_plan: |
            Manually review CLAUDE.md lines 1332 (specs table) and
            99118 (patterns table) — the sed sweeps already updated the
            paths, but column wording may need a quick polish.
            commit: docs(naming): polish CLAUDE.md doc-index after renames
          priority: 3

    - slug: folder-taxonomy
      title: "Phase 3 — Move docs into topical folders"
      description: |
        Create architecture/, specs/, design/, api/, runbooks/,
        decisions/, backlog/, qa/, assets/ folders. Move existing files
        into them. Keep one git mv per group so commits stay readable.
      acceptance_criteria: |
        - docs/ root contains only INDEX.md and (later) glossary.md.
        - All existing docs moved into the right folder per
          docs/plans/docs-restructure-ai-lookup.md §4.
        - Internal links updated in the same commit as each move.
        - `npm run docs:index` shows docs grouped correctly.
      priority: 2
      tasks:

        - title: "Create folder skeleton"
          description: "Empty folders with .gitkeep so structure is visible."
          implementation_plan: |
            for d in architecture specs specs/dialogs design api runbooks decisions backlog qa assets; do
              mkdir -p docs/$d
              touch docs/$d/.gitkeep
            done
            commit: docs(taxonomy): scaffold topical folders under docs/
          priority: 3

        - title: "Move spec files into docs/specs/"
          description: "functional, personas, dialogs/."
          implementation_plan: |
            git mv docs/specs/functional.md      docs/specs/functional.md
            git mv docs/specs/personas.md        docs/specs/personas.md
            git mv docs/specs/dialogs/pbi.md      docs/specs/dialogs/pbi.md
            git mv docs/specs/dialogs/story.md    docs/specs/dialogs/story.md
            git mv docs/specs/dialogs/task.md     docs/specs/dialogs/task.md
            grep -rln "docs/specs/personas\|docs/specs/functional\|docs/.*-dialog" \
              docs/ CLAUDE.md AGENTS.md README.md \
              | xargs sed -i '' \
                -e 's|docs/specs/functional|docs/specs/functional|g' \
                -e 's|docs/specs/personas|docs/specs/personas|g' \
                -e 's|docs/specs/dialogs/pbi|docs/specs/dialogs/pbi|g' \
                -e 's|docs/specs/dialogs/story|docs/specs/dialogs/story|g' \
                -e 's|docs/specs/dialogs/task|docs/specs/dialogs/task|g'
            commit: docs(taxonomy): move spec files into docs/specs/
          priority: 2

        - title: "Move design + api + qa + backlog + assets"
          description: "Bulk move per topic."
          implementation_plan: |
            git mv docs/design/styling.md          docs/design/styling.md
            git mv docs/design/styling.md docs/design/styling.md
            git mv docs/api/rest-contract.md              docs/api/rest-contract.md
            git mv docs/qa/api-test-plan.md        docs/qa/api-test-plan.md
            git mv docs/backlog/index.md          docs/backlog/index.md
            git mv docs/backlog/product-historical.md  docs/backlog/product-historical.md
            git mv docs/assets/erd.svg             docs/assets/erd.svg
            git mv docs/assets/icons.html          docs/assets/icons.html
            # update links — sed sweep
            commit: docs(taxonomy): move design/api/qa/backlog/assets into folders
          priority: 2

        - title: "Move decisions/agent-instructions-history → decisions/ as ADR seed"
          description: "Sets up Story 6 ADR-0008 (will replace this file with a real ADR)."
          implementation_plan: |
            git mv docs/decisions/agent-instructions-history.md docs/decisions/agent-instructions-history.md
            grep -rln "decisions/agent-instructions-history" docs/ CLAUDE.md AGENTS.md README.md \
              | xargs sed -i '' 's|decisions/agent-instructions-history|decisions/agent-instructions-history|g'
            commit: docs(taxonomy): move decisions/agent-instructions-history into decisions/
          priority: 3

    - slug: split-monoliths
      title: "Phase 4 — Split oversized docs"
      description: |
        Four docs exceed 800 lines and conflate multiple topics. Split
        them so an agent can grep for the right section directly.
      acceptance_criteria: |
        - No doc in docs/ exceeds 800 lines.
        - The original location of each split doc still exists as a
          breadcrumb file (≤25 lines) listing the new paths so old links
          fail gracefully.
        - solo-panel content lives inside docs/specs/functional.md as
          its own H2 section.
        - md3-color-scheme.md content is merged into docs/design/styling.md.
      priority: 2
      tasks:

        - title: "Split docs/architecture.md into 6 files under docs/architecture/"
          description: "Current size: 1247 lines."
          implementation_plan: |
            Target split (per plan §4):
              docs/architecture/overview.md             (today §1§3)
              docs/architecture/data-model.md           (Datamodel + Prisma Schema)
              docs/architecture/auth-and-sessions.md    (Authenticatieflow)
              docs/architecture/qr-pairing.md           (QR-pairing flow)
              docs/architecture/claude-question-channel.md (Q&A kanaal)
              docs/architecture/project-structure.md    (Projectstructuur)
            Replace docs/specs/architecture.md (after Phase 3 it's at
            docs/architecture.md still — adjust path) with a 20-line
            breadcrumb pointing to the six new files.
            Each new file gets fresh front-matter.
            commit: docs(split): break architecture.md into 6 topical files
          priority: 2

        - title: "Merge solo-paneel-spec.md into specs/functional.md"
          description: "Per resolved decision 3."
          implementation_plan: |
            Append solo-paneel-spec.md content as a new H2 section
            "Solo Panel" inside docs/specs/functional.md.
            git rm docs/specs/functional.md#solo-panel
            grep -rln "solo-paneel-spec" docs/ CLAUDE.md AGENTS.md README.md \
              | xargs sed -i '' 's|docs/solo-paneel-spec\.md|docs/specs/functional.md#solo-panel|g'
            commit: docs(split): merge solo-paneel-spec into specs/functional.md
          priority: 3

        - title: "Merge md3-color-scheme.md into design/styling.md"
          description: "Per resolved decision 2."
          implementation_plan: |
            Append md3-color-scheme.md content as H2 sections inside
            docs/design/styling.md. Drop redundant intro paragraphs.
            git rm docs/design/styling.md
            grep -rln "md3-color-scheme" docs/ CLAUDE.md AGENTS.md README.md \
              | xargs sed -i '' 's|docs/design/md3-color-scheme\.md|docs/design/styling.md|g'
            commit: docs(split): merge md3-color-scheme into design/styling
          priority: 3

    - slug: trim-orientation
      title: "Phase 5 — Trim CLAUDE.md and AGENTS.md"
      description: |
        Move conventions, branch/commit rules, MCP details, and deploy
        notes out of CLAUDE.md into runbooks/. Replace AGENTS.md with a
        10-line stub. Goal: CLAUDE.md ≤ 150 lines.
      acceptance_criteria: |
        - CLAUDE.md is at most 150 lines and contains only: scope,
          orientation pointers, hardstop rules, stack one-liner, pattern
          quickref, verification command. (See plan §5 for the
          skeleton.)
        - AGENTS.md is the 10-line stub from plan §7.
        - Removed sections live as their own files under docs/runbooks/.
      priority: 2
      tasks:

        - title: "Extract Branch & Commit strategy → docs/runbooks/branch-and-commit.md"
          description: "CLAUDE.md §Branch & PR Strategy + §Commit Strategy + §Plan Mode."
          implementation_plan: |
            Move CLAUDE.md lines covering Branch & PR Strategy, Plan
            Mode, and Commit Strategy verbatim into
            docs/runbooks/branch-and-commit.md (with front-matter).
            In CLAUDE.md, leave a one-line link.
            commit: docs(trim): extract branch/commit rules into runbook
          priority: 2

        - title: "Extract MCP integration → docs/runbooks/mcp-integration.md"
          description: "CLAUDE.md §MCP-integratie."
          implementation_plan: |
            Move §MCP-integratie verbatim. Replace in CLAUDE.md with a
            link + the bare list of tool names (no schemas).
            commit: docs(trim): extract MCP integration into runbook
          priority: 2

        - title: "Extract Deployment → docs/runbooks/deploy-vercel.md"
          description: "CLAUDE.md §Deployment."
          implementation_plan: |
            Move §Deployment verbatim. Replace in CLAUDE.md with a link.
            commit: docs(trim): extract Vercel deployment into runbook
          priority: 2

        - title: "Rewrite CLAUDE.md skeleton ≤ 150 lines"
          description: "Per plan §5 layout."
          implementation_plan: |
            Following plan §5, rewrite CLAUDE.md as:
              §1 What is Scrum4Me (2 sentences + README link)
              §2 Read first (INDEX, glossary)
              §3 How to find work (compact 2-track summary)
              §4 Hardstop rules (one line each, link to detail)
              §5 Stack one-liner per layer
              §6 Pattern quickref table (≤10 rows)
              §7 Verification command
            Verify: wc -l CLAUDE.md → ≤ 150
            commit: docs(trim): rewrite CLAUDE.md as ≤150-line skeleton
          priority: 2

        - title: "Replace AGENTS.md with stub"
          description: "10-line redirect to CLAUDE.md per plan §7."
          implementation_plan: |
            Overwrite AGENTS.md with the stub from plan §7 (English).
            Verify no other doc references AGENTS.md for content
            (only as a name).
            commit: docs(trim): replace AGENTS.md with redirect stub
          priority: 3

    - slug: adr-backfill
      title: "Phase 6 — Backfill ADRs for implicit decisions"
      description: |
        Write the actual ADR-0001 through ADR-0008 files. Scaffolding
        (templates, README, meta-ADR 0000) already exists from
        feat/docs-adr-and-index. Use Nygard for one-way-door decisions,
        MADR where rejected alternatives matter (auth, agent integration).
      acceptance_criteria: |
        - 8 new ADR files exist under docs/adr/ with correct numbering.
        - Each is status `accepted` and dated.
        - docs/adr/README.md table-of-contents lists all 8.
        - `npm run docs:index` shows them in the ADRs section.
      priority: 3
      tasks:

        - title: "ADR-0001: base-ui-over-radix (Nygard)"
          description: "Why @base-ui/react instead of Radix."
          implementation_plan: |
            Copy docs/adr/templates/nygard.md → docs/adr/0001-base-ui-over-radix.md
            Context: shadcn/ui visually identical to Radix-based components,
              but @base-ui/react uses render-prop composition and TS-correct
              prop API. Radix asChild caused TS errors in our setup.
            Decision: We adopt @base-ui/react and never import from Radix.
            Consequences: positive — TS-clean composition; negative — agent
              must remember the render-prop pattern (not asChild).
            Update docs/adr/README.md TOC.
            commit: docs(adr): add 0001-base-ui-over-radix
          priority: 3

        - title: "ADR-0002: float-sort-order (Nygard)"
          description: "Why float instead of integer for drag-and-drop ordering."
          implementation_plan: |
            See docs/patterns/sort-order.md for the existing pattern.
            Context: drag-and-drop reordering with N items — integer
              positions force a renumber on every reorder.
            Decision: Use float sort_order; insert between two items as
              the midpoint.
            Consequences: positive — O(1) inserts; negative — float
              precision drift requires periodic compaction (document
              when).
            commit: docs(adr): add 0002-float-sort-order
          priority: 3

        - title: "ADR-0003: one-branch-per-milestone (MADR)"
          description: "Why milestones, not stories, get branches — and the cost driver."
          implementation_plan: |
            Use MADR (alternatives matter — Vercel cost driver explicit).
            Considered options: branch-per-story, branch-per-milestone,
              trunk-based.
            Decision: branch-per-milestone, push only after user-test.
            Decision drivers: Vercel Hobby preview-build cost; small team
              size; AI-driven dev flow.
            More information: revisit when Vercel Pro is on.
            commit: docs(adr): add 0003-one-branch-per-milestone
          priority: 3

        - title: "ADR-0004: status-enum-mapping (Nygard)"
          description: "Why DB UPPER_SNAKE and API lowercase, plus the lib/task-status.ts mapper."
          implementation_plan: |
            Context: Prisma uses UPPER_SNAKE for enums; OpenAPI/REST
              clients expect lowercase.
            Decision: DB stays UPPER; API exposes lower; conversion
              exclusively via lib/task-status.ts mappers.
            Consequences: negative — anyone tempted to .toLowerCase()
              elsewhere breaks the contract; mitigated by lint rule.
            commit: docs(adr): add 0004-status-enum-mapping
          priority: 3

        - title: "ADR-0005: iron-session-over-nextauth (MADR)"
          description: "Why iron-session — alternatives weighed."
          implementation_plan: |
            Use MADR.
            Considered options: NextAuth/Auth.js v5, Clerk, Supabase Auth,
              iron-session.
            Decision: iron-session.
            Drivers: full control over cookie shape; demo-user policy
              requires synchronous check; no third-party redirect chain.
            commit: docs(adr): add 0005-iron-session-over-nextauth
          priority: 3

        - title: "ADR-0006: demo-user-three-layer-policy (Nygard)"
          description: "Why the same check exists in proxy + actions + UI."
          implementation_plan: |
            Context: demo-user must never write. Defense-in-depth across
              network, server, and UI layers.
            Decision: enforce in proxy.ts (network), every Server
              Action / Route Handler (server), and disabled buttons +
              DemoTooltip (UI).
            See: docs/architecture/auth-and-sessions.md (after Phase 4
              split) and ST-1110 plan.
            commit: docs(adr): add 0006-demo-user-three-layer-policy
          priority: 3

        - title: "ADR-0007: claude-question-channel-design (MADR)"
          description: "How the agent ↔ user async channel works and why."
          implementation_plan: |
            Use MADR.
            Considered options: synchronous polling only, push via SSE,
              persistent claude_questions table + LISTEN/NOTIFY.
            Decision: persistent table + LISTEN/NOTIFY trigger.
            See: docs/patterns/claude-question-channel.md and M11 plan.
            commit: docs(adr): add 0007-claude-question-channel-design
          priority: 3

        - title: "ADR-0008: agent-instructions-policy (Nygard, supersedes audit doc)"
          description: "Replaces docs/decisions/agent-instructions-history.md as a real ADR."
          implementation_plan: |
            Migrate the conclusions of docs/decisions/agent-instructions-history.md
            into an ADR.
            After accepted: mark history doc as superseded with a
            top-of-file note linking to ADR-0008.
            commit: docs(adr): add 0008-agent-instructions-policy
          priority: 3

    - slug: glossary-and-husky
      title: "Phase 7 — Glossary + pre-commit hook for INDEX.md"
      description: |
        Write a glossary and wire the index generator into husky so
        INDEX.md never goes stale. The script itself already exists.
      acceptance_criteria: |
        - docs/glossary.md exists with entries for PBI, Story, Sprint,
          Solo, Todo, demo-token, MCP-job, agent worker, claude-question.
        - .husky/pre-commit runs `npm run docs:index` only when staged
          changes touch docs/**/*.md, then `git add docs/INDEX.md`.
        - README points to docs/INDEX.md and docs/glossary.md.
      priority: 3
      tasks:

        - title: "Write docs/glossary.md"
          description: "Single-page domain-term reference."
          implementation_plan: |
            Front-matter: status active, audience [ai-agent, contributor],
              language en.
            Terms (alphabetical):
              demo-token, demo-user, MCP-job, PBI, Solo Panel, Sprint,
              Story, Task, Todo, agent worker, claude-question.
            Each term: 1-2 sentences + link to canonical doc.
            commit: docs(glossary): add docs/glossary.md
          priority: 3

        - title: "Wire docs:index into husky pre-commit"
          description: "Avoid stale INDEX.md."
          implementation_plan: |
            Edit .husky/pre-commit:
              if git diff --cached --name-only | grep -q '^docs/.*\.md$'; then
                npm run docs:index
                git add docs/INDEX.md
              fi
            Verify with: stage a doc edit and run git commit --dry-run
            commit: chore(docs): regenerate INDEX.md in pre-commit hook
          priority: 3

        - title: "Add INDEX + glossary pointer to README"
          description: "Mensbezoekers vinden dan ook het orientation-laagje."
          implementation_plan: |
            In README.md add a short section under "Architectuur (kort)":
              ## Documentation
              - docs/INDEX.md — generated index of all docs
              - docs/glossary.md — domain terms
              - CLAUDE.md / AGENTS.md — agent instructions
            commit: docs(readme): link INDEX + glossary + agent instructions
          priority: 4

    - slug: link-check
      title: "Phase 8 — Doc-link health check"
      description: |
        Add a small node script that walks docs/, finds every markdown
        link, and verifies the path (and anchor) exists. Wire into
        npm test or CI so a broken link blocks merge.
      acceptance_criteria: |
        - scripts/check-doc-links.mjs exists, pure Node, no deps.
        - It validates relative .md links and #anchors.
        - It prints a non-zero exit code on failures.
        - `npm run docs:check-links` is wired in package.json.
        - At least one CI step (vitest config or a separate npm script)
          runs it.
        - All current docs pass the check after the renames from
          Stories 24.
      priority: 3
      tasks:

        - title: "Write scripts/check-doc-links.mjs"
          description: "Walk docs/, parse markdown links, validate."
          implementation_plan: |
            Pure Node 20.
            For each .md file:
              extract markdown links via regex /\[([^\]]+)\]\(([^)]+)\)/g
              skip http(s):// and mailto: links
              for each relative link:
                resolve against the file's directory
                check the path exists
                if the link includes #anchor:
                  read the target file, check for a heading whose
                    GitHub-style slug matches the anchor
            Print a table of failures; exit 1 if any.
            commit: feat(docs): add doc-link checker script
          priority: 3

        - title: "Wire docs:check-links in package.json"
          description: "Plus a `docs` super-script that runs index + check together."
          implementation_plan: |
            Add to package.json scripts:
              "docs:check-links": "node scripts/check-doc-links.mjs",
              "docs":             "npm run docs:index && npm run docs:check-links"
            commit: chore(docs): wire docs:check-links and docs npm scripts
          priority: 4

        - title: "Add docs check to CI"
          description: "Block merge on broken links."
          implementation_plan: |
            Edit .github/workflows/<existing>.yml:
              after the lint+test step, add:
                - run: npm run docs:check-links
            commit: ci(docs): block merge on broken doc links
          priority: 3

        - title: "Run + fix any reported broken links"
          description: "Final sweep across the whole tree."
          implementation_plan: |
            npm run docs:check-links
            For each reported broken link: fix in a single commit per
            file. If the target was renamed in Stories 24 but a link
            slipped through, that's a missed sed sweep — fix and update
            this story's notes.
            commit: docs(links): fix broken cross-references after restructure
          priority: 3

5. Executor notes

The executor reads the YAML graph above and calls, in order:

  1. mcp__scrum4me__create_pbi with the pbi.title, pbi.description, pbi.priority, pbi.product_id (substituted from REPLACE_ME). Capture the returned pbi_id.
  2. For each story under pbi.stories: mcp__scrum4me__create_story with pbi_id, story.title, story.description, story.acceptance_criteria, story.priority. Capture the returned story_id.
  3. For each task under story.tasks: mcp__scrum4me__create_task with story_id, task.title, task.description, task.implementation_plan, task.priority.

sort_order is intentionally omitted everywhere — the MCP server auto-assigns last + 1 within the priority group, which gives a stable order matching this file's reading order.

If any call fails, halt and surface the response — don't retry blindly, because a partial create leaves the graph half-built.

After a successful run: store the returned PBI/story/task IDs somewhere the executor can hand back, so a follow-up can verify everything exists and the totals match (1 PBI, 8 stories, 39 tasks).


6. Verification

  • Spec written.
  • YAML graph parses cleanly with PyYAML; story/task counts verified (1 PBI, 8 stories, 39 tasks; phase distribution 7/5/4/3/5/8/3/4).
  • Executor runs end-to-end against the docker sandbox.
  • DB shows 1 PBI titled "Docs-restructure for AI-optimized lookup".
  • DB shows 8 stories under it.
  • DB shows 39 tasks across the 8 stories.
  • mcp__scrum4me__get_claude_context for the PBI returns the context block (section 1) verbatim as the description.