Publish requirement health
Publish the requirement-health report and badge on GitHub Pages so proof status is visible on every pull request.
Publish a continuously updated Kibi requirement-health report on GitHub Pages,
with a clickable % tested badge in the repository README.
Badge and report are one feature. Someone who sees 87% tested needs to open
the report to see what that percentage represents and which requirements are
missing proof. Kibi does not host badges or reports; GitHub Pages is the
expected publisher. Knowledge stays in the repository's .kb/ directory.
What the badge means
A badge such as kibi | 87% tested is the share of applicable current
Kibi requirements that have current proof. Non-current (for example superseded)
requirements are excluded, as are requirements marked not applicable to proof.
The published HTML report is the place to inspect:
- which requirements are tested end to end
- which are missing proof
- contradictions
- stale verification state
- other requirement-health details already exposed by
kibi report
The badge and index.html always come from one kibi report coverage
snapshot. Do not compute a separate GitHub-only percentage.
Recommended flow: badge + full report
1. Enable GitHub Pages
In GitHub:
Settings → Pages → Source → GitHub ActionsThis is the only expected GitHub UI step. Kibi does not change repository settings for you.
2. Add the Kibi workflow
Copy the canonical workflow to:
.github/workflows/kibi-report.ymlThe file to copy is
docs/examples/github/kibi-report.yml. It is
byte-identical to the template shipped in kibi-cli.
One build-report job generates the report. Pull requests validate that
generation and upload the candidate site as an ordinary workflow artifact.
Only the repository default branch (it does not assume the branch is named
main) and workflow_dispatch may deploy GitHub Pages. A pull_request event
never deploys Pages, never replaces the canonical report or badge, and never
receives pages: write or id-token: write. The workflow uses pull_request,
not pull_request_target, with repository-level contents: read. GitHub
Actions checkouts are detached, so the workflow sets KIBI_BRANCH to the
pull-request head ref or the pushed/dispatched branch name before kibi sync
and kibi report.
The generate job:
- checks out the candidate GitHub Actions ref (the PR merge commit on pull requests, otherwise the pushed or dispatched commit)
- sets up Node.js
- installs project dependencies with npm (SWI-Prolog arrives with them as the
bundled
kibi-swipl-linux-x64-gnupackage, so there is no separate install step) - runs
kibi sync - runs
kibi report --output kibi-report(the job fails if this fails) - on
pull_request, uploads thekibi-report/directory as thekibi-pr-reportartifact (HTML report plus badge) - on the default branch or
workflow_dispatch, copies that output underpages/kibi-report/so the public path is/kibi-report/and uploads it as a GitHub Pages artifact
The deploy-report job then deploys that Pages artifact. It does not run for
pull requests. Pushes to non-default branches start the workflow and skip both
jobs. The workflow does not build or test the rest of the application, does not
commit generated files, and does not use an orphan gh-pages branch.
3. Add the clickable badge
[](https://OWNER.github.io/REPOSITORY/kibi-report/)Replace OWNER with the repository owner (lower case is fine, since the
*.github.io host is case-insensitive) and REPOSITORY with the repository name
exactly as GitHub spells it. The project-site path is case-sensitive, so
MyRepo and myrepo are different URLs. Clicking the badge must open the
report. Files are published under /kibi-report/ so Kibi does not occupy the
Pages site root.
This workflow still replaces the GitHub Pages deployment. If the repository
already publishes a site, copy kibi-report/ into that site's output instead
of using this workflow as the only deploy.
Expected URLs
| Repository | Report | Badge |
|---|---|---|
OWNER/REPOSITORY |
https://OWNER.github.io/REPOSITORY/kibi-report/ |
https://OWNER.github.io/REPOSITORY/kibi-report/badge.svg |
Owner/MyRepo (mixed case) |
https://owner.github.io/MyRepo/kibi-report/ |
https://owner.github.io/MyRepo/kibi-report/badge.svg |
OWNER/OWNER.github.io (owner site) |
https://OWNER.github.io/kibi-report/ |
https://OWNER.github.io/kibi-report/badge.svg |
The image URL must be anonymously reachable for GitHub to render it in a public README. For a private report, publish both files to an authenticated static host that your intended audience can access. GitHub Actions artifacts expire and are not a stable badge URL.
Do not commit generated kibi-report/ files.
CLI shortcut
kibi init --github performs normal kibi init behavior, then scaffolds the
same documented integration:
kibi init --githubIt:
- writes
.github/workflows/kibi-report.ymlfrom the packaged template - adds the clickable badge to an existing root README when a github.com remote can be determined
- adds
kibi-report/to.gitignorewhen missing - prints the Pages enable instruction
It is safe to run more than once. Matching workflows are left as already configured. Customized workflows are not overwritten. An existing Kibi badge is not duplicated. If no README exists, the workflow is still written and the badge Markdown is printed. If owner/repository cannot be determined from a github.com remote, the workflow is still written and placeholder badge Markdown is printed instead of inventing a URL.
Package-manager adaptations
The canonical workflow uses npm because that matches the documented Kibi
install (npm install --save-dev kibi-cli ... and npm exec -- kibi).
Change only the Node setup cache and the install/exec commands:
pnpm
- uses: actions/setup-node@v5
with:
node-version: 24
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm exec kibi sync
- run: pnpm exec kibi report --output kibi-reportInstall the pnpm action (pnpm/action-setup) before setup-node if the runner
does not already have pnpm.
Yarn
- uses: actions/setup-node@v5
with:
node-version: 24
cache: yarn
- run: yarn install --frozen-lockfile
- run: yarn kibi sync
- run: yarn kibi report --output kibi-reportBun
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bunx kibi sync
- run: bunx kibi report --output kibi-reportKeep kibi-cli as a project dependency so CI uses the version the repository
pinned. Do not add application build or test steps just to generate the
report.
Badge-only opt-out
Prefer the full report. To publish only the badge:
kibi init --github --badge-onlyOr copy docs/examples/github/kibi-badge.yml to
.github/workflows/kibi-badge.yml.
That workflow still runs kibi report (same snapshot, same % tested). Pull
requests upload the generated report directory as kibi-pr-report and still
do not deploy Pages. Default-branch and workflow_dispatch publishes only
badge.svg under /kibi-report/. The README link should point at this section
rather than pretending a report exists:
[](https://looted.github.io/kibi/guide/github-integration.html#what-the-badge-means)--badge-only without --github is rejected. --github by itself always
means badge + full report.
Merge conflicts in Kibi manifests
Two branches that each add symbols both append to the end of
.kb/symbols.yaml (and sometimes to the same .kb/relationships/*.yaml
shard), so Git reports a conflict even though the additions are independent.
kibi merge-driver is a Git merge driver that merges these manifests by
record id instead of by line:
- records added on either side are kept (ours first, then theirs)
- an edit made on only one side wins over the unchanged other side
- a deletion on one side is kept when the other side left the record unchanged
- relationships and links that both sides added to one symbol are unioned
- anything else both sides changed differently (for example two different
statusvalues) is a real conflict: the driver names it, leaves ordinary conflict markers, and exits non-zero so the file stays unmerged
.kb/symbol-coordinates.yaml is a gitignored local cache derived by every
kibi sync, so it never takes part in a merge.
Locally
Declare the driver in the repository's .gitattributes:
.kb/symbols.yaml merge=kibi
.kb/relationships/*.yaml merge=kibiThen each clone opts in once (Git never runs a driver from repository content alone):
git config merge.kibi.driver "npm exec --no -- kibi merge-driver %O %A %B"Without that setting Git ignores the attribute and falls back to its normal line merge, so declaring it is safe for contributors who do not use Kibi.
In CI
Copy docs/examples/github/kibi-kb-merge.yml
to .github/workflows/kibi-kb-merge.yml. On every push to the default branch
it test-merges each open same-repository pull request with
git merge-tree. When the only conflicts are Kibi manifests, it merges the
default branch into the PR branch with kibi merge-driver and pushes the
merge commit. A branch that still tracks .kb/symbol-coordinates.yaml from
before schema 13 has it removed in that merge. Pull requests with any other conflict, or a real conflict inside a
manifest, are left untouched for a person. Fork pull requests are skipped
because the workflow cannot push to them.
The merge driver and kibi sync run from the default branch's install of
kibi-cli, not the pull request's, so branches opened before the driver
existed are still handled. The default branch therefore needs a kibi-cli
version that includes kibi merge-driver.
Pushes made with the default GITHUB_TOKEN do not start other workflows, so
the pull request's checks would not re-run on the merge commit. Add a
repository secret named KIBI_MERGE_TOKEN and the workflow pushes with it
instead. Use a fine-grained personal access token or GitHub App token limited
to the repository, with Contents and Workflows set to read and write.
Workflows access is needed because a merge that brings in changes under
.github/workflows/ is rejected without it; the default GITHUB_TOKEN can
never push those merges. An expired secret fails the job rather than falling
back to GITHUB_TOKEN, so renew it or delete the secret. The same
package-manager adaptations as the report workflow apply.
Troubleshooting
The workflow succeeds but https://OWNER.github.io/REPOSITORY/kibi-report/ is 404.
Enable Settings → Pages → Source → GitHub Actions. Until that is set,
Pages deployments do not go live. The report is not at the Pages site root.
The badge image is a broken picture in the README.
The SVG URL must be anonymously reachable. Private Pages sites will not render
in public READMEs. Confirm /kibi-report/badge.svg loads in a logged-out browser.
The workflow is skipped on every feature-branch push.
Report generation runs on pull_request, workflow_dispatch, or a push to the
repository default branch. Pushes to other branches start the workflow and
then skip the jobs. Open a pull request to validate a candidate report, change
the GitHub default branch, or use Run workflow for a one-off publish.
GitHub Pages still deploys only from the default branch or workflow_dispatch.
kibi: command not found or npm exec -- kibi fails.
Install kibi-cli as a project dependency and commit the lockfile. The
workflow does not install Kibi globally.
Kibi could not find a usable SWI-Prolog.
The workflow relies on the bundled runtime that npm ci installs on
ubuntu-latest (Linux x64, glibc). It is missing when the install skipped
optional dependencies (--omit=optional, --no-optional, pnpm
supportedArchitectures that excludes the runner's platform) or the lockfile
lacks the platform package. Install with the package manager's defaults, or add
kibi-swipl-linux-x64-gnu explicitly. On a runner without a bundled build
(Alpine/musl containers, self-hosted Windows), install SWI-Prolog 9.0+ from the
SWI-Prolog PPA or your platform package
manager and put swipl on PATH; see
Installation.
Pages published the wrong site / two Kibi workflows.
A repository can host one Pages site. Keep either kibi-report.yml or
kibi-badge.yml, not both.
kibi init --github did not overwrite my workflow.
If .github/workflows/kibi-report.yml already exists and differs from the
template, Kibi leaves it in place. Compare it with
docs/examples/github/kibi-report.yml.
Owner/repository could not be determined.
kibi init --github only parses github.com remotes (HTTPS or SSH). GitHub
Enterprise hosts are not auto-filled. The workflow is still written; paste the
printed badge Markdown after replacing OWNER/REPOSITORY.