1. Purpose
Ensure that only well-shaped, well-understood work enters active development. DoR defines the entry criteria and artifacts required for any issue to move from Backlog to To Do. This removes ambiguity, reduces rework, and improves predictability across teams.
2. Reasoning
Historically, tickets have entered sprints without sufficient context (missing acceptance criteria, unclear scope, no UX, hidden dependencies). DoR creates a consistent handshake between Product, Design, and Engineering so the team commits to work with full information and aligned expectations.
3. Benefits
- Less thrash and handoffs during sprints
- Higher sprint predictability and throughput
- Clear ownership and faster reviews
- Earlier risk surfacing and dependency alignment
- Better QA readiness and fewer escaped defects
4. DoR Checklist (what must be true to enter ‘To Do’)
Every issue must satisfy the checklist below. Items not applicable should be marked N/A with rationale:
- Business justification and user story
- Acceptance criteria and success metrics
- UI/UX design or wireframe (if applicable)
- Dependencies identified (and contacted/confirmed)
- Risks or blockers documented
- Labels applied: DoR:Complete (added when all above are met)
5. Examples
5.1 Business Justification & User Story
Example Business Justification
Collecting demographic data can be subject to GDPR and similar regulations. We must require explicit consent if any demographic data is made mandatory by the assigning organization or if the respondent voluntarily provides non-mandatory demographic data. This reduces legal risk and builds trust through transparent consent.
Example User Story (format)
As a respondent completing an assessment, I want to see and accept clear terms and conditions when my demographic data is being collected so that I understand how my personal information may be processed and can give explicit consent when required.
5.2 Acceptance Criteria & Success Metrics
Acceptance Criteria (Gherkin-style)
Rules engine summary
- Terms and Conditions (T&C) consent is required if and only if:
- The assigner has configured one or more demographic fields as mandatory, or
- The respondent voluntarily fills at least one non-mandatory demographic field
- When consent is required:
- A T&C text block is displayed with a required checkbox
- Submit is disabled until the checkbox is checked
- Acceptance is recorded with timestamp, IP, user agent, assignment id, and hash of the T&C text version
Scenarios
Mandatory demographic fields trigger consent
- Given the assignment marks “Country” as mandatory
- And the demographics form is displayed
- When the respondent focuses or enters a value in any demographic field
- Then the T&C section is displayed with a required checkbox
- And the Submit button is disabled until the checkbox is checked
Optional demographics filled trigger consent
- Given no demographic fields are mandatory for this assignment
- And the respondent enters a value in “Department” (optional)
- When the respondent attempts to submit the form
- Then the T&C section is displayed with a required checkbox
- And the Submit button remains disabled until the checkbox is checked
No demographics provided does not require consent
- Given no demographic fields are mandatory for this assignment
- And the respondent leaves all demographic fields empty
- When the respondent submits the form
- Then the T&C section is not displayed
- And the submission is accepted without T&C consent
Consent required blocks submission until checked
- Given at least one demographic field value has been entered
- And the T&C section is displayed with an unchecked checkbox
- When the respondent clicks Submit
- Then the form does not submit
- And an inline error is shown stating “Please review and accept the terms to continue”
Consent recorded on submit
- Given the T&C section is displayed
- And the respondent has checked the T&C checkbox
- When the respondent submits the form
- Then the submission succeeds
- And an audit record is saved with consent=true, consent_version, timestamp, IP, user agent, and assignment id
Previously accepted consent on this page remains sticky during session
- Given the respondent has checked the T&C checkbox
- And then edits any demographic field value
- When the page revalidates
- Then the T&C checkbox remains checked
- And Submit remains enabled
Localized T&C content based on org locale
- Given the assignment organization locale is “fr-FR”
- And consent is required
- When the T&C section is displayed
- Then the T&C text and link open the French version for the configured consent_version
Negative security scenario: user attempts to bypass checkbox
- Given consent is required
- And the T&C checkbox is not checked
- When a client-side script tries to POST the form directly
- Then the server rejects the submission with HTTP 400 and code CONSENT_REQUIRED
- And no demographic data is persisted
Success Metrics (quantified)
- 100 percent of submissions that include demographic data have an associated consent event.
- Less than 1 percent of consent-required submissions are rejected due to missing consent after first attempt.
- Support tickets related to consent on demographics remain under 2 per thousand invitations in the first 30 days.
5.3 UI/UX Design or Wireframe (if applicable)
Page: Demographics
Layout
- Header: “About you” with short help copy that demographics are optional unless marked required by your organization
- Form grid
- Each field shows label, helper text, and required badge if mandatory by assignment configuration
- Optional fields have no badge and display “Optional” in helper text
- Conditional T&C section (hidden by default)
- Appears when rules engine determines consent is required
- Elements:
- Readable T&C excerpt (first 3 to 5 lines)
- Inline link “View full terms” that opens a modal with full text and version stamp
- Checkbox label: “I have read and accept the Terms and Conditions regarding processing of my demographic information”
- Error message placeholder directly under the checkbox
Actions
- Primary button: Submit
- Disabled state when consent is required and checkbox is not checked
- Secondary button: Save and return later
Interaction flow
- Page renders with assignment-driven field requirements
- User either leaves all fields blank or enters values
- As soon as any required field exists or any optional field receives a value, the T&C section appears
- Submit remains disabled until the checkbox is checked
- On Submit, server validates:
- If any demographic value present or any field required by assignment, consent must be present
- If consent missing, return validation error and do not persist demographics
- On success, persist demographics and consent audit in a single transaction
Accessibility
- Checkbox is focusable and linked to descriptive text via aria-describedby
- T&C link opens a modal with focus trap and close button
- Error messages use role=”alert” and are associated to the checkbox
5.4 Dependencies (examples)
Backend
- Assignment configuration exposes demographics_required_fields: [field_key]
- Consent service to persist consent records with consent_version, text_hash, assignment_id, respondent_id, ip, user_agent, timestamp
- Transactional save to ensure demographics and consent audit succeed together
- Server-side validation that enforces consent when demographics are present or required
Frontend
- Rules engine utility that decides whether to show T&C based on:
- Presence of any demographic values in the form state
- Presence of any required demographics from assignment config
- Modal component for full T&C text with version
- i18n strings for T&C excerpt and link text
Content
- Legal-approved T&C text with versioning and locales
- CMS or static asset pipeline delivering current content and version metadata
Analytics and audit
- Event demographics_consent_viewed when T&C section is first displayed
- Event demographics_consent_accepted when checkbox is checked
- Audit record persisted on submit as described above
Feature flag
- gdpr_demographics_consent to allow staged rollout
5.5 Risks / Blockers (examples)
- Legal accuracy: If T&C text or versioning is outdated, consent records may be invalid. Mitigation: integrate with a single source of truth and require version stamping in code review.
- Server-side enforcement: Relying only on the client to require consent risks bypass. Mitigation: enforce consent on the API and reject attempts without consent when demographics are present or required.
- Confusing UX for optional fields: Users may be surprised to see consent appear after typing into optional fields. Mitigation: helper copy explains that providing any demographics triggers consent.
- Localization gaps: Missing locale files could fall back to the wrong language. Mitigation: default to organization locale with explicit fallback matrix and automated test.
- Data privacy: Storing demographics without consent due to race conditions. Mitigation: single transaction that validates consent precondition before writing demographics.
6. GitLab Implementation (labels, automation, boards, and views)
6.1 Labels (create in Project → Issues → Labels)
Create the following labels:
- DoR:Pending (default for all new issues)
- DoR:Complete (applied only when the DoR checklist is fully met)
- Needs:Design, Needs:Acceptance, Needs:Dependency, Risk:Identified (optional helpers)
- Workflow:Backlog, Workflow:ToDo (or use your existing workflow labels)
6.2 Auto-apply DoR:Pending to all new issues
Option A — Default Issue Template with Quick Action (recommended, low-code)
- Project → Settings → General → Default templates → Default issue template = “DoR-Intake”.
- Create template at
.gitlab/issue_templates/DoR-Intake.mdwith the first line as a Quick Action:/label ~"DoR:Pending" ~"Workflow:Backlog" - Include the DoR checklist in the template so PMs must fill it before requesting readiness.
Option B — Bot via Webhook + Project Access Token (for guaranteed enforcement)
- Settings → Webhooks → Add webhook; trigger on “Issues events”. Point to an internal endpoint (Cloud Run/Lambda).
- Create a Project Access Token with “api” scope. Store as secret.
- On
issue_create, the bot calls GitLab Issues API to add label “DoR:Pending” (and “Workflow:Backlog” if missing). - Log actions and alert in your chat/incident tool if labeling fails.
6.3 Marking a ticket as DoR:Complete
When all checklist items are satisfied, the PM uses a Quick Action in the issue comment:
/unlabel ~"DoR:Pending"
/label ~"DoR:Complete" ~"Workflow:ToDo"
/assign @<tech_lead_or_engineer>
This creates an auditable event trail for readiness approval.
6.4 Preventing premature commitment
- Sprint Planning convention: Only issues with label “DoR:Complete” may be added to the iteration.
- CI helper: Nightly job uses the GitLab API to comment on any issue in “Workflow:ToDo” that still has “DoR:Pending”, asking PM to complete DoR or move back to Backlog.
6.5 Boards & Filters (let PMs see shaping work; keep dev boards clean)
PM Board:
- Board filter: none (or “Labels: DoR:Pending OR DoR:Complete”)
- Lists:
- Backlog (label=DoR:Pending)
- To Do (label=DoR:Complete)
- In Progress
- Under Review
- Closed
Dev Board:
- Board filter: “Labels != DoR:Pending”
- Lists: To Do, In Progress, Under Review, Closed
Result: Developers do not see DoR:Pending items in their default working view,
while PMs see the full shaping pipeline.
6.6 Saved searches (for rapid triage)
Create saved filters in Issues list:
- “Needs Readiness” → label: “DoR:Pending”
- “Ready for Planning” → label: “DoR:Complete” state: opened
- “Needs Design” → label: “Needs:Design”
- “Needs Acceptance” → label: “Needs:Acceptance”
6.7 Permissions note
GitLab does not restrict visibility of individual issues by role within the same project. Use board filters to keep developer working views clean. For stricter visibility, mark shaping issues Confidential, or intake in a separate “Intake” project and move to the delivery project when DoR is complete.
7. Governance & Roles
- Product Manager: Authors business justification, user story, acceptance criteria; coordinates design.
- Design: Delivers clickable wireframes/UX artifacts and usability notes.
- Engineering Lead: Confirms feasibility, dependencies, and risks.
- QA Lead: Validates testability and data needs.
- Delivery/Program Lead: Audits DoR compliance and board hygiene weekly.
8. Operational Cadence
- Weekly Backlog Grooming: Review all “DoR:Pending” items; assign actions to reach readiness.
- Sprint Readiness Review: Only “DoR:Complete” candidates are eligible for the next sprint.
- Monthly Audit: Sample 10 closed tickets to verify DoR artifacts matched delivered scope.
9. Template: .gitlab/issue_templates/DoR-Intake.md
/label ~"DoR:Pending" ~"Workflow:Backlog"
## Business Justification
- Why this matters; target KPI/OKR
## User Story
As a <role>, I want <capability>, so that <outcome>.
## Acceptance Criteria
- [ ] Given ..., when ..., then ...
- [ ] Given ..., when ..., then ...
## Success Metrics
- KPI baseline → target (time window)
- Performance target (e.g., p95 < 1.5s)
## UI/UX
- Figma link:
- States: empty, error, loading
- Accessibility notes:
## Dependencies
- API / Data / Integrations / Feature flags
## Risks / Blockers
- ...
10. API Automation Reference
Use these examples with a Project Access Token that has “api” scope. Store the token as a masked CI/CD variable named GITLAB_TOKEN and the numeric project ID as PROJECT_ID.
10.1 Sample curl commands
Add DoR:Pending and Workflow:Backlog to an issue by IID
curl --request PUT "https://gitlab.com/api/v4/projects/${PROJECT_ID}/issues/${ISSUE_IID}" \
--header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
--data-urlencode 'add_labels=DoR:Pending,Workflow:Backlog'
Swap labels when DoR is complete (remove pending, add complete and ToDo)
curl --request PUT "https://gitlab.com/api/v4/projects/${PROJECT_ID}/issues/${ISSUE_IID}" \
--header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
--data-urlencode 'remove_labels=DoR:Pending' \
--data-urlencode 'add_labels=DoR:Complete,Workflow:ToDo'
Post an audit comment on an issue by IID
curl --request POST "https://gitlab.com/api/v4/projects/${PROJECT_ID}/issues/${ISSUE_IID}/notes" \
--header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
--data-urlencode "body=This issue is in Workflow:ToDo but still labeled DoR:Pending. Complete DoR or move back to Backlog."
10.2 Register a webhook (optional)
Register a webhook that fires on issue events. Your handler can auto-label new issues with DoR:Pending if you prefer server-side enforcement.
curl --request POST "https://gitlab.com/api/v4/projects/${PROJECT_ID}/hooks" \
--header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
--form 'url=https://your-endpoint.example/issue-created' \
--form 'issues_events=true' \
--form 'enable_ssl_verification=true'
11. Nightly DoR Audit CI Job
This job runs on a nightly schedule. It finds all open issues that are in Workflow:ToDo but still labeled DoR:Pending, and posts a comment to prompt the PM to complete readiness or move the issue back to Backlog.
Add this job to your .gitlab-ci.yml (or include the standalone file below):
stages: [audit]
dor_audit:
stage: audit
image: alpine:3.20
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
script:
- apk add --no-cache curl jq
- BASE="https://gitlab.com/api/v4/projects/$PROJECT_ID"
- PAGE=1
- |
while :; do
RESP=$(curl -s --header "PRIVATE-TOKEN: $GITLAB_TOKEN" "$BASE/issues?state=opened&labels=Workflow:ToDo,DoR:Pending&per_page=100&page=$PAGE")
COUNT=$(echo "$RESP" | jq length)
[ "$COUNT" -eq 0 ] && break
echo "$RESP" | jq -c '.[] | {iid:.iid}' | while read -r row; do
IID=$(echo "$row" | jq -r .iid)
curl -s --request POST --header "PRIVATE-TOKEN: $GITLAB_TOKEN" "$BASE/issues/$IID/notes" \
--data-urlencode "body=This issue is in Workflow:ToDo but still labeled DoR:Pending. Complete DoR and relabel to DoR:Complete, or move back to Backlog."
done
PAGE=$((PAGE+1))
done
variables:
# Set these in Project → Settings → CI/CD → Variables (masked)
# GITLAB_TOKEN: project access token with 'api' scope
# PROJECT_ID: numeric project ID
allow_failure: false



