Visibility Portal
The Visibility Portal is a GitHub Pages dashboard that gives stakeholders a real-time view of sprint progress, team velocity, and milestone health — without needing access to GitHub issues or source code.
Accessing the portal
The portal is deployed at:
https://your-org.github.io/your-repo/
It shows:
- Current sprint Kanban board (derived from GitHub issues)
- Today's standup summary
- Velocity chart (last 5 sprints)
- Milestone health indicators
- Active suggestions
Two separate GitHub Pages deployments
Scraut has two deployments that look similar but serve completely different purposes:
| Scraut docs | Your team's portal | |
|---|---|---|
| URL | aldhosutra.github.io/scraut/ | your-org.github.io/your-repo/ |
| What | Docusaurus documentation for Scraut itself | Your sprint dashboard |
| Who it's for | Scraut users learning the tool | Your team and stakeholders |
| Source | docs/ folder (built from apps/docusaurus/) | apps/portal/ (generated by visibility engine) |
| Deploy method | Branch-based (/docs folder) | GitHub Actions artifact (portal-publish.yml) |
| Updated by | Template maintainer, on docs changes | Visibility engine every 30 min |
When you clone Scraut for your team, your GitHub Pages should serve the portal (Settings → Pages → Source: GitHub Actions). The Docusaurus docs live at the template URL above — your users are linked there from their portal and README.
How it works
The portal is driven by two workflows:
1. Visibility Engine (board sync + HTML generation)
Trigger: Push to standup files or sprint meta, plus every 30 minutes
Workflow: visibility-engine.yml
Standup files change (or 30-min cron fires)
│
├─ derive_state.py
│ Reads all workspace/ text files
│ Reads .scraut/ generated summaries
│ Derives sprint board state: to-do / in-progress / done
│ NEVER reads GitHub Projects board (text files are source of truth)
│
├─ sync_board.py [if portal.sync_board: true AND project_number is set]
│ Updates GitHub Projects board columns from derived state
│ Skips with warning if project_number not configured
│
└─ generate_portal.py [always runs]
Renders apps/portal/index.html ← full dashboard HTML
Writes apps/portal/data.json ← raw sprint data
Writes apps/portal/style.css
Commits all three with [skip ci]
The HTML portal always generates on every visibility engine run.
GitHub Projects board sync is on by default (sync_board: true) but requires portal.project_number to be set. Without it, board sync is skipped and a warning is logged — the portal is unaffected.
To disable board sync entirely:
# workspace/scraut.yml
portal:
sync_board: false
2. Portal Publish
Trigger: Push to apps/portal/ (triggered by the commit above)
Workflow: portal-publish.yml
index.html + data.json committed to apps/portal/
│
└─ Deploys apps/portal/ to GitHub Pages via artifact
→ dashboard is live at your-org.github.io/your-repo/
The two workflows chain automatically — you never need to trigger portal deployment manually.
What the portal shows
Sprint board
A Kanban-style view derived from issue labels and standup activity:
| To Do | In Progress | In Review | Done |
|---|---|---|---|
| #41 Export CSV (sp:5) | #21 OAuth (sp:5) — Alice | #25 Rate limiting — Bob | #33 Login bug ✓ |
| #44 Dark mode (sp:5) | #28 Dashboard (sp:8) — Charlie | #35 Tests ✓ |
The board state is derived from:
in-sprintlabel → card exists- Standup "Today" section mentions issue → moves to In Progress
- PR opened with
Closes #N→ moves to In Review - Issue closed → moves to Done
Velocity chart
A bar chart showing completed vs. planned story points for each sprint.
Standup summary
Today's LLM-generated standup summary, rendered as a clean team status report.
Milestone health
Traffic-light indicator per milestone (green / yellow / red based on forecast).
Making the portal private
By default, the portal is public. To restrict access:
# workspace/scraut.yml
portal:
public: false
Then in GitHub: Settings → Pages → Visibility → Private
Note: Private GitHub Pages requires a GitHub Enterprise or Team plan.
Scenario: Stakeholder checks progress without bothering the team
Characters: David (CTO), Sprint 2 in progress
- David wants to know if the v2.0 milestone is on track
- He opens
https://myorg.github.io/my-repo/ - He sees: Milestone v2.0 — 🟡 At Risk — forecast Sep 14 (target Aug 31)
- He clicks through to see which epics are behind
- He sees the "Analytics pipeline" epic is blocked on a dependency
- He emails the backend team directly — no status meeting needed
- Team is not interrupted — they learn David checked from the portal access logs
Total interruption to the team: 0 minutes.