cujo
Skip to content
Contents

Install it

Put the GitHub App on a repository, open a pull request, and read what comes back.

Two things the repository needs

  • The App installed on it. Public or private: a private repository’s trees reach the sandbox through the App’s own access, fetched outside the box and copied in, so the box still holds no credential. Its runs are visible on this board only to an owner of the installation, signed in.
  • Branch protection, if you want a block to actually hold. Require the cujo/guard status check on the target branch. Without it a block is a REQUEST_CHANGES review and a failed check on the commit, both visible and neither holding the merge; a review alone can be dismissed by anyone with write access, which is why the check exists.

Installing it

  1. 01
    Install the App on the repository.

    github.com/apps/cujo-guard. Running your own instance means creating your own App instead — self-hosting has the settings.

  2. 02
    Open a pull request, or push to one that is open.

    Within about a second the pull request wears an eye. That reaction arrives before the agent has done anything, so its presence proves the delivery, the signature and the claim; its absence says the failure is at the front of the pipeline.

  3. 03
    Read the review.

    One review from cujo-guard[bot], and the reaction settles on the verdict. What the run measured is on this board too, if the repository is public.

Nothing needs to be configured first. Cujo infers the install, test and boot commands from the repository’s own build files; a .cujo.yml overrides what it got wrong.

Pull requests Cujo skips

Three filters, applied before a sandbox is provisioned or a token is spent. The first two are explicit human choices and are full stops; the third is an inference, so it softens the posture rather than producing silence.

ConditionWhat happens
Draft pull requestNothing runs. Marking it ready for review starts a run.
The cujo:skip labelNothing runs. An explicit opt-out by someone with write access.
Documentation onlyEvery changed file is prose — .md, .txt, .rst, .adoc, LICENSE, CHANGELOG and the like. The sandbox still runs in full and every hard rule still fires; the review can only be advisory, so it cannot block a merge.
A file that is a dependency manifest is never documentation, and an empty changed-file list is not documentation-only — a metadata-only pull request should still be judged.

What the App asks for

Five permissions and four event subscriptions, and one of them looks wrong.

PermissionWhy
Contents: readClone the pull request, and read the default branch’s policy.
Metadata: readRequired by the others.
Pull requests: writePost the review, the inline comments, the reaction and the replies, and dismiss the review when a maintainer lifts a block.
Checks: writeWrite the cujo/guard check run on each commit it reviews. This is the merge lock; an installation that has not approved it gets reviews and reactions and no check.
Issues: readDelivery only. No code here reads an issue — GitHub releases the issue_comment event on this permission and on nothing else, even for a comment on a pull request, and that event is how /cujo dismiss arrives.

Events: pull_request (opened, synchronize, ready for review), issue_comment, pull_request_review_comment, and repository — the last so that a repository going private is noticed within seconds rather than at the next sweep.