CI
Nostr CI results are published as events, like everything else. Two things matter: finding the workflow, and reading the result correctly.
Where workflows live
.ngit/act/workflows/Not .github/workflows/. A repository can have both, and the presence of one says nothing about the other. To read the workflow as it existed at a given commit:
git show <COMMIT>:.ngit/act/workflows/<WORKFLOW>.yamlCheck that its triggers actually cover the event you care about, and that its steps run the checks you think they do.
Checking a commit
ngit ci status <COMMIT-ISH>
ngit ci status <COMMIT-ISH> --offline # cache only, after the first queryThe target can be a commit-ish, a PR (#<prefix>, an nevent, or a full event ID), or nothing at all — in which case it means HEAD. Query the commit that introduced the change, not just the tip.
A PR reports only the runs for its latest revision; results from earlier revisions are never presented as current.
status: ok does not mean CI passed
The top-level status field reports whether the query succeeded. Whether the build passed is ci.conclusion.
A green status: "ok" next to a failing ci.conclusion is a perfectly normal response, and reading the wrong one is the most common way to mistake a broken commit for a working one.
What the fields mean:
| Field | Meaning |
|---|---|
status | Did the query command succeed |
ci.state | Pending, running, or concluded |
ci.conclusion | Success, failure, cancelled, or other outcome |
ci.runs[].jobs | Which job passed or failed |
ci.runs[].workflow | Which workflow produced the run |
ci.runs[].integrity | Whether the commit is present locally and the workflow hash matches |
coverage | How completely the result covers the commit |
Partial coverage is not evidence of success.
Gating on a result
To make the command exit non-zero unless CI is green and meets a trust floor:
ngit ci status <COMMIT-ISH> --require-ci-trust maintainer-directedTwo floors are available:
| Level | Meaning |
|---|---|
maintainer-directed | The result traces back to a maintainer's instruction |
operationally-associated | A weaker association with the repository's operators |
The gate passes only if the result is a success and its weakest run meets the floor.
The same gate works on a merge, which is where it matters most:
ngit merge <ID> --require-ci-trust maintainer-directedWithout it, a failing, unfinished, untrusted or entirely absent CI result will not block the merge. A successful push does not enforce CI by itself.
Asking a coordinator to run CI
CI runs are performed by a coordinator you ask. A request is standing: it covers runs the coordinator starts after it, never earlier ones, and stays in force until you stop it.
ngit ci request <COORDINATOR> # npub or hex
ngit ci stop <COORDINATOR>Requests are signed for one repository perspective — your own announcement if you've published one, otherwise the selected maintainer's. A coordinator's default policy accepts only a confirmed maintainer of that perspective, so ngit warns (but doesn't refuse) if you aren't one; an operator may have allowed your key explicitly.
To run a single workflow once, without a standing request:
ngit ci trigger <COORDINATOR> --workflow .ngit/act/workflows/test.yaml
ngit ci trigger <COORDINATOR> <COMMIT-ISH> --workflow .ngit/act/workflows/test.yamlThe workflow is identified by the SHA-256 of the blob at the resolved commit — not your working tree, whose line endings and clean/smudge filters may hash differently from what the coordinator sees.
When no run appears
Report it as "no matching CI event found" rather than as a pass. Then check, in order:
- Did the workflow exist at that commit?
- Did its trigger match the event?
- Did the query refresh the repository relays — or was it
--offlineagainst a cold cache?
Only after all three should you conclude that CI genuinely did not run.