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: 3 → sprint/001/, 4 → sprint/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/5 → project_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 overrides — extra_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