Guide: the governance dashboard
A thin, read-only view of an ASDD project's governance state. GitHub shows you a raw list of pull
requests; this curates the ASDD-specific view: PRs bucketed by governance stage (awaiting review, in
progress, changes requested, recently merged), by lane, with the asdd/intake and asdd/review
verdicts where the token can read them, plus the intake queue, contributors, and releases. Each PR also
shows its declared target version, and a suggested next-release section groups the open PRs by version.
It renders one self-contained HTML page and writes nothing back to the repo.
Run it
GITHUB_TOKEN=<read-only token> python3 cli/dashboard.py --repo OWNER/REPO --out dashboard.html
The token needs read access to the repo's pull requests and releases. The page is a single file with no external assets. Options:
--from snapshot.jsonrenders offline from a saved snapshot instead of fetching (the same shape the live fetch builds:{"repo","pulls","releases","statuses"}).--intake DIRincludes a local intake queue (the*.jsonspec objects the pipeline writes).--jsonprints the computed model instead of HTML, for piping into your own view.
As sensitive as the repo it reports on
Everything on the page comes from the repo it reports on, so its sensitivity follows the repo's. The default is the careful reading.
Private repo: internal only
This is the default, and it covers most adopters. PR titles, authors, verdicts, contributors and the configuration are private activity. So:
- Open it locally, or serve it from an internal host behind authentication.
- Never publish it to a public URL, and never commit it to a public repo.
- Generating it in the private repo's own CI is fine: those artifacts reach only people who can already read the repo. What is not fine is moving the output somewhere wider, such as a public Pages site, a public repo, or a shared bucket.
The page carries a visible internal banner and noindex,nofollow,noarchive, so an accidental exposure is
not indexed. That is a mitigation, not a control: keeping the URL private is still on you.
Public repo: publishable, and it is the demo
If the repo is public, every fact the page renders is already readable on GitHub by anyone, so
publishing it discloses nothing new. Render it for publication with --public:
GITHUB_TOKEN=<read-only token> python3 cli/dashboard.py --repo OWNER/REPO --public --out dashboard.html
That drops the internal banner and lets the page be indexed. The flag is verified, not trusted: with
--repo it asks the API and refuses if the repo is private, and unknown visibility counts as private.
The exception cannot be taken by mistake.
A public project running ASDD on itself is the strongest demonstration of it: every pull request carrying
a disclosure trailer, passing intake, getting a real review verdict, merged by a human. Publish it once
the review lenses are live (see the runtime credential below). A dry-run page advertises the gap instead
of the pipeline: the model lenses read skipped, which is the opposite of the point.
Credential-shaped values in the config panel are redacted, but a credential should not be in .asdd.yml
at all. Model names belong there; keys belong in your runtime's keyring or a CI secret.
Keep it current
Regenerate on a schedule, on a host your admins can reach. A private repo can do it in CI and keep the result as a repo-scoped artifact:
- run: GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} python3 cli/dashboard.py --repo ${{ github.repository }} --out dashboard.html
- uses: actions/upload-artifact@v4
with: { name: asdd-dashboard, path: dashboard.html, retention-days: 7 }
On a public repo, run it outside public CI (a cron on an internal host) so the output never becomes publicly downloadable.
Declaration check
Each PR declares a change scope (normative or non-normative). The dashboard reads the paths a PR changes and applies the same normative-path rule the impact gate uses, then flags any PR declared non-normative that in fact edits the standard's normative text. Those show a "scope mismatch" in the Target column and are listed under "Declaration check". The impact gate already blocks such a PR from merging; this surface makes the misclassification visible at a glance rather than only on the PR itself. It mirrors the gate's deterministic path rule; a behavioural mismatch that only a model surfaces is enforced at the gate, not re-shown here.
Suggested next release
A normative change declares a target version in its PR (the impact lens checks it). The dashboard reads that declaration from the PR body and shows it as a Target column on each PR, then groups the open PRs that share a version under a "Suggested next release" heading, so you can see what an upcoming release would contain in one place. An open PR that declares a normative change but names no version is listed under "No target version" so the gap is visible.
This is a suggestion, not an action. The tool assigns nothing, tags no release, and edits no changelog. Grouping a release stays a human act: you review the proposed grouping and decide. The section is built so an assistant could propose a grouping here later, but it makes no such call today.
What it is not
It is read-only and advisory. It never merges, comments, or changes anything; it reflects the state the
gates and humans produced. The verdict columns degrade to - when the token cannot read commit statuses,
so the core view (PRs by stage, lanes, releases, contributors) works with a minimal token.
Next: how it works · adopt the govern layer