Files
iris/README.md
T
Bendik Aagaard LynghaugandClaude Fable 5.1 73906cdf35
Test / test (push) Failing after 12s
Publish release / publish (push) Failing after 4s
iris: the lint over a portal site, as its own repo
question_lint becomes `iris check`, needs_replay becomes `iris
replay`, and the needs module and local-checkout loaders come with
them. Portal is a library dependency pinned to the release iris
matches (v0.3.36), so every type iris reads is the site's own and the
two never disagree about what a page is. `iris --path questions`
still works, so a content repo's one-line CI needs only a new path.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4jrCgLiKKHAEFuZUJjckH
2026-09-22 17:25:52 +02:00

2.3 KiB

iris

The iris over a portal site. A content push is an incoming wormhole; nothing comes through until it checks out.

iris check --path questions                      # a local checkout
iris check --repo https://project.uhhm.no/uhhm/questions
iris --path questions                            # the same, for one-line CI

check loads a content repo exactly the way the running site does, validates it (every action lands on a page, every transition is one the state machine allows, every recorded bucket is read back somewhere), and then holds it to the business needs the repo declares in needs.yaml, when it has one:

  • a path of submissions gets each kind of visitor's answer into the bucket it names, within a submission and required-field budget;
  • the handling group holds a desk over that bucket, and every finished state is reachable through the buttons it (and any also_moved_by group) offers; no record strands on the way;
  • every stage the business named is a state of the machine.

A need marked planned warns instead of failing. Exit status is the verdict, so a content repo's CI is one line.

Beyond the verdict, check exports what a trainer needs to grade the wording: --needs-tasks writes the personas as typed choice tasks (--skim for headings only), --needs-score grades an engine's answers, and --needs-sim writes a resolved model of the whole site. iris replay runs simulated cases through the site's real aggregate engine on a throwaway JetStream and reports every bucket by state; --report-only takes the same scorecard from a live site's buckets. See portal-trainer for what sits around those.

Matching the site

Every type iris reads is portal's own: portal is a library dependency pinned to a release tag in Cargo.toml, and iris --version says which. A content repo should run the iris that matches the portal release its site runs. Portal's own release tarball ships an iris binary built the same way, so a site that pins nothing extra has one at /srv/app/<instance>/current/iris.

Release

Move the Unreleased lines in CHANGELOG.md under a heading for the version, bump Cargo.toml, commit, tag v<version>, push. CI builds the binary and attaches it to the Gitea release as iris, with that section as the notes.