Skip to main content

Configuration Reference

Full reference for every field in workspace/scraut.yml.


sprint

sprint:
length_days: 14 # int — Sprint duration in calendar days
start_day: monday # string — monday | tuesday | wednesday | thursday | friday
start_time: "09:00" # string — HH:MM in 24-hour format
timezone: "UTC" # string — IANA timezone identifier
capacity_buffer: 0.85 # float 0–1 — Sprint capacity safety factor
current_sprint: 1 # int — Auto-managed; do not edit manually
folder_padding: 3 # int — Zero-padding width for sprint folder names
FieldDefaultNotes
length_days14Calendar days, not working days
start_daymondayAffects morning notification scheduling
start_time"09:00"Combined with timezone for cron scheduling
timezone"UTC"Use pytz-compatible IANA string
capacity_buffer0.85planning_capacity = velocity × buffer
current_sprint1Incremented automatically by close_sprint.py
folder_padding3Digits in sprint folder names: 3sprint/001/, 4sprint/0001/. Widen with scraut sprint repad <N>. Never reduce.
work_daysMon–FriList of day names your team works. Affects is_working_day(), burndown ideal line, and ceremony skip logic. See examples below.

work_days examples:

# Standard Mon–Fri (default — field can be omitted)
work_days: [monday, tuesday, wednesday, thursday, friday]

# Middle East / Gulf Sun–Thu
work_days: [sunday, monday, tuesday, wednesday, thursday]

# 4-day week (Mon–Thu)
work_days: [monday, tuesday, wednesday, thursday]

Day names are case-insensitive. Unknown names are ignored with a warning. If the list is empty or the field is absent, Mon–Fri is assumed.


team

team:
members:
- login: string # required — exact GitHub username
display: string # required — human-readable name
role: string # optional — developer | product_owner | scrum_master
slack_id: string # optional — Slack member ID for morning DMs
email: string # optional — email for weekly digest
product_owner: string # optional — login of the PO (informational)
scrum_master: string # optional — login of the SM (informational)
slack_channel: string # required — e.g. "#scraut-bot"
FieldRequired?Notes
members[].loginYesExact GitHub username — used for standup file paths
members[].displayYesHuman-readable name shown in summaries and reports
members[].roleNoInformational label in LLM prompts; does not gate any action
members[].slack_idNoRequired for morning DMs; silently skipped if absent
members[].emailNoRequired for weekly email digest; skipped if absent
product_ownerNoInformational — not read by any current workflow
scrum_masterNoInformational — not read by any current workflow
slack_channelYesChannel for all ceremony posts (e.g. #scraut-bot)
Role fields are informational

product_owner, scrum_master, and members[].role do not currently change what automation runs. Any team member with repo write access can trigger any workflow. The fields exist as documentation of intent and as a foundation for future role-based routing. They can all be set to the same person — common for small teams and solo setups.


ceremonies

ceremonies:
planning: true # Sprint planning workflow
standup: true # Daily standup summarisation
grooming: true # Mid-sprint backlog grooming
review: true # Sprint review generation
retrospective: true # Retrospective synthesis
estimation: true # Emoji-based story point voting

Set to false to disable an entire ceremony's automation.


definition_of_done

definition_of_done:
- string # Each item is a DoD criterion checked by the LLM when issues close

The LLM checks each criterion against the closed issue's linked PRs. Write criteria in plain English — be specific about what "done" means.


repos

repos:
- name: string # Display name for this repo
url: string # org/repo format (e.g. myorg/backend-api)
branch_filter: # List of branch names to watch
- string
enabled: boolean # true | false

Multiple repos can be configured. Set enabled: false to temporarily pause sync without removing the config.

Requires SCRAUT_GITHUB_TOKEN secret with repo:read permission.


llm

llm:
provider: string # anthropic | openai | gemini | ollama | github
model: string # Provider-specific model name
small_model: string # Optional: cheaper/faster model for simple tasks
base_url: string # Optional: custom API endpoint
max_tokens: integer # Per-call output token limit
cost_controls:
max_daily_tokens: integer # Hard daily limit across all calls
batch_where_possible: bool # Combine multiple LLM calls where safe
FieldDefaultNotes
provideranthropicgithub requires no extra secret — uses GITHUB_TOKEN
modelProvider defaultUsed for complex tasks (planning, synthesis, decomposition)
small_model"" (uses primary)When set, used for standup summaries, issue triage, and coach DMs
base_urlProvider defaultOverride for proxies or OpenAI-compatible endpoints
max_tokens1000Per-call output token limit
cost_controls.max_daily_tokens100000Hard fail-safe across all daily LLM calls
cost_controls.batch_where_possiblefalseMerge multiple LLM requests into one call
fallback.provider"" (disabled)Retried automatically when the primary provider fails
fallback.model""Model for the fallback provider

Fallback examples:

# Option A — GitHub Models (recommended): zero setup, GITHUB_TOKEN always present
llm:
fallback:
provider: github
model: gpt-4o-mini

# Option B — Ollama: fully local, no API key needed
# Add the setup-ollama composite action to your workflows (already included).
llm:
fallback:
provider: ollama
model: qwen2.5:0.5b # 394 MB, sub-1B, best quality/size for CPU inference

See LLM Providers → Automatic fallback for the full comparison and guidance on Ollama in GitHub Actions.


agents

agents:
enabled: boolean # Master switch for agent mode

roles:
- id: string # Unique identifier (e.g. agent-backend)
type: string # orchestrator | specialist
specialty: string # backend | frontend | testing | review
enabled: boolean # Per-agent enable/disable
github_workflow: string # Path to the agent's workflow file
description: string # Human-readable description

human_checkpoints:
- event: string # sprint_boundary | milestone_eta_slip |
# escalation_count | agent_failure

autonomy_level: string # supervised | semi-auto | full-auto

notifications

notifications:
slack_webhook: string # Leave empty — use SLACK_WEBHOOK secret
morning_dm: boolean # Send personal DM at 7:55am
weekly_email: boolean # Send Monday email digest
stakeholder_emails: # Email list for weekly digest
- string

Important: Never put the webhook URL directly in scraut.yml. Leave slack_webhook: "" and use the SLACK_WEBHOOK GitHub Secret instead.


portal

portal:
enabled: boolean # Enable visibility portal
title: string # Dashboard title
public: boolean # false = private GitHub Pages (requires Team/Enterprise plan)
refresh_minutes: int # How often board state syncs from text files
sync_board: boolean # Sync GitHub Projects board alongside HTML portal (default: true)
project_number: int # GitHub Projects board number — required for board sync
# Find it in the URL: github.com/orgs/your-org/projects/N
FieldDefaultNotes
enabledtrueMaster switch for portal generation
title"<org> Dashboard"Shown in the portal header
publictruePrivate Pages requires GitHub Team/Enterprise plan
refresh_minutes30Cron interval for the visibility engine
sync_boardtrueSet to false to disable GitHub Projects board sync while keeping the HTML portal
project_number(unset)Required when sync_board: true. Without it, board sync is skipped with a warning. HTML portal always generates regardless.
Board sync is on by default

When sync_board: true, the visibility engine updates your GitHub Projects board on every run. Set project_number to the board number from the URL (e.g. https://github.com/orgs/myorg/projects/5project_number: 5).

To turn off board sync entirely without disabling the portal:

portal:
sync_board: false
HTML portal vs. GitHub Projects board

These are two separate outputs from the same pipeline:

  • HTML portal (apps/portal/index.html) — always generated, deployed to GitHub Pages
  • GitHub Projects board — only updated if sync_board: true AND project_number is set

Both are derived from text files. The board is never read to make decisions.


suggestions

suggestions:
enabled: boolean # Enable pattern detection
min_evidence_count: int # Min occurrences before generating a suggestion (default: 3)
measurement_sprints: int # Sprints to measure after implementation (default: 2)

standup_coach

When enabled, the standup coach runs after the daily summary. It detects team members whose Today section is brief and doesn't reference specific issues, then sends each affected person a private Slack DM with personalised task recommendations based on their open sprint issues, the sprint goal, and the team's OKRs.

standup_coach:
enabled: false # Master switch — set to true to activate
min_today_words: 20 # Flag Today sections shorter than this word count
require_issue_ref: true # Also flag if no #NN issue reference in Today section
skip_sprint_start_days: 1 # Skip coaching for the first N working days of each sprint
notify_sm: false # DM the Scrum Master a summary of who was coached today
FieldDefaultNotes
enabledfalseDisabled by default — SM opts in
min_today_words20Today sections under this length are candidates for coaching
require_issue_reftrueIf true, a Today section must also contain a #NN issue reference to pass
skip_sprint_start_days1Avoids coaching on sprint day 1, when exploratory work is normal
notify_smfalseIf true, the SM receives a daily DM listing who was coached (never names individuals in the public channel)

Detection is conservative. A standup is only flagged if the Today section is both shorter than min_today_words AND (when require_issue_ref: true) has no #NN reference. Common legitimate vague-but-valid patterns are automatically exempt: code reviews, pairing sessions, sprint ceremonies, OOO, interviews, sick days.

Delivery is private. Recommendations go only to the individual's Slack DM — never to the team channel. The optional SM notification also goes as a DM, not to the channel.

Requires: SLACK_BOT_TOKEN GitHub Secret (for DMs). Without it, coach detection still runs but DMs are skipped with a warning.

When to enable

Teams that already have well-labelled sprint backlogs and active Slack usage benefit most. If your backlog is messy or incomplete, the recommendations will be generic. Fix the backlog first, then enable the coach.


paths

paths:
workspace: string # Root for human-editable files (default: workspace)
scraut: string # Root for bot-generated files (default: .scraut)
portal: string # Portal application path (default: apps/portal)

Do not change paths unless you are restructuring the repository.


holidays

Controls which days Scraut treats as non-working. Two sources are merged:

  1. Nager.Date API — automatic public holidays by country (free, no API key)
  2. Manual overridesextra_dates adds company/team days; skip_dates removes API dates your team works anyway

Merged rule: (api_holidays ∪ extra_dates) − skip_dates

holidays:
country_code: "ID" # ISO 3166-1 alpha-2 (e.g. US, ID, GB, AU). Blank = no API lookup
extra_dates: # Company/team holidays not covered by the API (YYYY-MM-DD)
- "2026-12-26"
- "2026-08-17"
skip_dates: # API-provided dates your team works anyway (YYYY-MM-DD)
- "2026-01-02"
FieldDefaultNotes
country_code""ISO 3166-1 alpha-2. Leave blank to disable API lookup.
extra_dates[]Additional non-working dates. Useful for company-wide days, bridge days, regional observances not in the API.
skip_dates[]Override API holidays — treat these as normal working days.

Effect on Scraut ceremonies:

What skips on holidaysWhat is not affected
Daily standup template creationSprint planning (manual trigger)
Morning Slack DMsRetrospective / review (manual trigger)
Burndown chart (holidays excluded from ideal line)Sprint velocity calculations

API caching: Results are cached in .scraut/holidays/{CC}/{YEAR}.json on first fetch and reused for all subsequent runs. Delete the file to force a refresh.

Supported countries

Nager.Date covers 100+ countries. Check the full list at date.nager.at/Country.


Environment variables reference

All secrets are GitHub repository secrets — never committed to files.

VariableUsed byRequired?
GITHUB_TOKENAll workflowsAuto-provided
ANTHROPIC_API_KEYLLM workflowsIf using Anthropic
OPENAI_API_KEYLLM workflowsIf using OpenAI
GOOGLE_API_KEYLLM workflowsIf using Gemini
SLACK_WEBHOOKNotification workflowsRecommended
SLACK_BOT_TOKENMorning DM workflowOptional
SCRAUT_GITHUB_TOKENRepo sync workflowOptional
SMTP_HOSTWeekly email digestOptional
SMTP_PORTWeekly email digestOptional
SMTP_USERWeekly email digestOptional
SMTP_PASSWeekly email digestOptional