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_dispatch — note: 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-triage→status:ready→status:in-progress(agent) →status:retest-pending(automatic after staging deploy) → issue closed by Eefje - Fetch the backlog with:
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:
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:
- The CI run on the staging push deploys to staging (new SHA, shown in the
orange bar on
staging.freezedesign.eu) .github/workflows/feedback-retest-comment.yml— triggered on completion of the "CI"workflow_runfor staging pushes — resolves which PR(s) were deployed, parsesFeedback: 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 setsstatus:retest-pending- Eefje gets a Discord/email notification via the feedback repo's notify-discord workflow
- She tests on
staging.freezedesign.eu; OK → she closes the issue herself - 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 tostatus:readyor 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¶
- ❌ 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.
- ❌ 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.
- ❌ Letting raw input bypass the intake layer. If it's not a feedback issue or a todo, it doesn't exist.
- ❌ Creating GSD phases directly from Eefje's raw list. Always batch through the intake layer first — gives time for clarification and grouping.
- ❌ 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.
- ❌ Combining multiple issues/todos in one fix unless Ivar explicitly says so. Each report closes independently.