Skip to content

Eefje Bug/Feature Intake Process (v1)

Status: active (revised 2026-07-02) Owner: Ivar Created: 2026-04-17

Updated 2026-05-06: intake now runs through the feedback repo

Since 2026-05-06 Eefje reports bugs and feature requests via issue forms in Voorman/freezedesign-feedback — no longer via WhatsApp or PDF. The authoritative process description for agents lives in .claude/CLAUDE.md (section "Eefje Intake and Bug Handling"); this document is the longer-form background. Internal work (Ivar/agent-reported, not visible to Eefje) still uses .planning/todos/pending/<slug>.md with status: ready.

Why this document exists

Eefje (the business owner and primary tester) is the only non-technical stakeholder reporting bugs and feature requests on Freeze Design. Historically (pre-2026-05-06) she delivered them via PDF files dropped in the repo root (Foutmeldingen nieuw porduct aanmaken..pdf, Nog meer dingetjes.pdf) and via WhatsApp notes. That is fine for occasional input but breaks down at volume:

  • Items are mixed together (bugs, features, decisions-still-to-make, content)
  • Nothing is versioned against the staging SHA she tested on
  • Duplicate reports can't be detected
  • No audit trail of what was triaged, fixed, or deferred
  • Agents can't pick up work without manual translation

This document defines the intake process and shows how it maps to the existing GSD workflow.

The layered model (since 2026-05-06)

There are two intake tracks. An agent works on exactly one of two sources:

Track 1 — Eefje reports (feedback repo):

flowchart TD
    A["Issue form in Voorman/freezedesign-feedback<br/>(label status:ready)"]:::intake
    A -->|"agent picks up: status:ready → status:in-progress"| B["Branch fix/feedback-N-slug → PR against staging<br/>PR body: Feedback: Voorman/freezedesign-feedback#N<br/>+ 'Verify on staging:' checklist (PR template)"]:::exec
    B -->|"merge → staging deploy (deploy job in ci.yml)"| C["feedback-retest-comment.yml posts retest comment<br/>with the deployed SHA, sets status:retest-pending"]:::verify
    C -->|"Eefje retests on staging.freezedesign.eu"| D["Eefje closes the issue herself"]:::closed
    classDef intake fill:#e0f2fe,stroke:#0284c7;
    classDef exec fill:#fef9c3,stroke:#ca8a04;
    classDef verify fill:#dcfce7,stroke:#16a34a;
    classDef closed fill:#f3f4f6,stroke:#6b7280;

Track 2 — Internal work (Ivar/agent-reported, not Eefje-visible):

flowchart TD
    A[".planning/todos/pending/slug.md (status: ready)"]:::intake
    A -->|"Ivar groups by theme"| B["New GSD milestone (v1.26, v1.27, ...)"]:::plan
    B -->|"/gsd:new-milestone → /gsd:plan-milestone"| C["Phases + Plans"]:::exec
    C -->|"/gsd:execute-phase, optionally parallel agents via Cline Kanban"| D["PR to staging → deploy → verification"]:::verify
    D -->|"confirmed OK"| E["todo moved to .planning/todos/done/ (by Ivar)"]:::closed
    classDef intake fill:#e0f2fe,stroke:#0284c7;
    classDef plan fill:#ede9fe,stroke:#7c3aed;
    classDef exec fill:#fef9c3,stroke:#ca8a04;
    classDef verify fill:#dcfce7,stroke:#16a34a;
    classDef closed fill:#f3f4f6,stroke:#6b7280;

Key insight: feedback issues and todos are the intake layer. They don't replace GSD's milestone/phase/plan system — they feed into it. Raw input (WhatsApp, PDF, verbal, email) is never a task in itself: Ivar or Eefje opens a feedback issue first.

Branch model (since 2026-05-04)

Branch Purpose Deploy target
feature/* of fix/* Active work, one per todo none
staging Integration; auto-deploys to staging.freezedesign.eu staging environment
main Code-of-record; only updated by promotion-PRs from staging after Eefje confirms none directly (production via tagged release only)
vX.YZ tags Production releases production environment via workflow_dispatchnote: no production VPS exists yet (status 2026-06-10), so this path is dormant

Promotion flow: feature → PR against staging → CI green → squash-merge → auto-deploy to staging → Eefje retests → on confirmation, fast-forward or PR staging → main → tag the main commit → manual gh workflow run deploy-production.yml -f tag=vX.YZ to ship.

Automation: scripts/release.sh <pr-number> automates the entire flow (merge to staging → wait for staging-deploy → UAT-pause → promotion PR → CI green → rebase-merge → sync staging force-push). Use --promote-only for staging→main alone, --no-uat to skip the pause, --dry-run to preview. Force-pushing staging back to main HEAD after the rebase-merge is intentional — it keeps both branches at the same SHA after each release.

Pre-2026-05-04 the project deployed staging from main directly; the CLAUDE.md rule "PR against staging, never main" only matched the infrastructure as of this commit.

How Eefje reports (since 2026-05-06: one channel)

GitHub issue form in Voorman/freezedesign-feedback

  • Dutch issue forms in the dedicated feedback repo (separate from the code repo)
  • The form fields ("Wat ging er mis?", "Wat verwachtte je?") are the source of truth — not an agent's own interpretation
  • Status labels drive the workflow: status:needs-triagestatus:readystatus:in-progress (agent) → status:retest-pending (automatic after staging deploy) → issue closed by Eefje
  • Fetch the backlog with:
gh issue list -R Voorman/freezedesign-feedback -l status:ready \
  --json number,title,body,labels

WhatsApp, PDF, and email are no longer intake channels. If raw input still arrives that way, Ivar (or Eefje herself) opens a feedback issue first — raw input is never a task in itself, and agents never create feedback issues on Eefje's behalf without Ivar's instruction.

The triage step (Ivar, 5-10 min per report)

For each feedback issue (or internal item), Ivar decides. For Eefje reports the statuses are labels on the feedback issue (status:ready, status:needs-clarification, status:awaiting-decision, status:blocked-on-content); for internal work they are frontmatter fields on the todo file:

Kind Example Action
Clear bug "Footer shows 2025, moet 2026 zijn" label status:ready (or /gsd:add-todo for internal work)
Clear small feature "Logo iets groter" label status:ready
Ambiguous "De categorie" (incomplete sentence) Reply on the issue, label status:needs-clarification
Decision-in-progress "Ik moet even kijken wat ik doe met..." label/status awaiting-decision
Content delivery "Afbeelding stuur ik per email" label/status blocked-on-content
Big feature "Producten van eigen ontwerpen zonder designer" status needs-scoping, plan a /gsd:discuss-milestone session
Duplicate Already reported Link the issues, close the duplicate
Already fixed She missed it Reply with "dit is al gefixt in vX.YZ"

Todo file format (extends GSD default)

This applies to internal todos (Track 2) — Eefje reports live as feedback issues and don't get a todo file. GSD's default todo template is minimal; add these frontmatter fields so todos carry enough context to become phase plans:

---
title: <short descriptive title>
type: bug | feature | content | decision
status: ready | needs-clarification | awaiting-decision | blocked-on-content | needs-scoping
severity: blocker | important | nice-to-have
area: homepage | designer | product-catalog | admin | checkout | email | other
reporter: eefje | ivar | agent
reported_via: whatsapp | github | email | pdf
reported_date: YYYY-MM-DD
source: "<verbatim quote from Eefje if available>"
staging_sha_when_reported: <short sha or 'unknown'>
related_todos: []
blocked_by: []
---

Body sections: 1. What Eefje said (verbatim) — her exact words, Dutch preserved 2. Ivar's interpretation — what this actually means technically 3. Proposed scope — smallest change that solves the reported problem 4. Open questions — what's unclear, what needs confirmation 5. Definition of done — how we'll know it's fixed (from Eefje's perspective)

From todos to milestones

Once .planning/todos/pending/ has ~5–15 ready-status todos that cluster around a theme, run:

/gsd:discuss-milestone

Feed it the todos. The discuss step decides scope. Then /gsd:new-milestone turns them into phases and plans.

Todos that are needs-clarification or awaiting-decision stay in pending/ across milestones — they're not ready yet.

Todos that become part of a milestone stay in pending/ until the associated phase is completed, then move to done/ with a note pointing to the phase that closed them.

Eefje's retest loop (automated since 2026-05-06)

After a PR merges to staging:

  1. The CI run on the staging push deploys to staging (new SHA, shown in the orange bar on staging.freezedesign.eu)
  2. .github/workflows/feedback-retest-comment.yml — triggered on completion of the "CI" workflow_run for staging pushes — resolves which PR(s) were deployed, parses Feedback: Voorman/freezedesign-feedback#<N> from each PR body, posts a retest comment with the deployed SHA and the "Verify on staging:" checklist on each linked issue, and sets status:retest-pending
  3. Eefje gets a Discord/email notification via the feedback repo's notify-discord workflow
  4. She tests on staging.freezedesign.eu; OK → she closes the issue herself
  5. Not OK → she comments "still broken"; the status flips back via a follow-up PR

Agents are not involved in steps 2-5 — those run automatically or are human-to-human.

What this costs Ivar daily

  • Morning (5 min): scan new feedback issues (status:needs-triage), triage to status:ready or ask a clarifying question
  • Anytime (ongoing): when starting a phase, grab the relevant todos
  • Evening retest-WhatsApp — automated since 2026-05-06 (retest comment + Discord notification via the feedback repo)

Total: ~5-10 minutes/day for intake, not counting execution.

What this costs Eefje

  • First time: 10 min GitHub onboarding, plus bookmarking the issue form
  • Per report: 2-3 min via the issue form
  • Per retest: varies by item; she closes the issue herself when OK

Anti-patterns to avoid

  1. Agent creates feedback issues or todos autonomously from Eefje's raw input (PDF, WhatsApp). It will misinterpret ambiguity and create noise. Only Eefje (via the form) or Ivar opens issues.
  2. Skipping the "needs-clarification" status to keep things moving. Better to block on a 2-minute reply from Eefje than to build the wrong thing.
  3. Letting raw input bypass the intake layer. If it's not a feedback issue or a todo, it doesn't exist.
  4. Creating GSD phases directly from Eefje's raw list. Always batch through the intake layer first — gives time for clarification and grouping.
  5. Closing feedback issues or moving todos to done/ yourself. Closing an issue is Eefje's call (after retest on staging); moving a todo to done/ is Ivar's.
  6. Combining multiple issues/todos in one fix unless Ivar explicitly says so. Each report closes independently.