Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GT37Z1Xtfd9pUuQtMTg6Yt
55 lines
2.4 KiB
Markdown
55 lines
2.4 KiB
Markdown
# The lint
|
|
|
|
The iris over a site. A content push is an incoming wormhole; nothing
|
|
comes through until it checks out.
|
|
|
|
```
|
|
portal lint --path questions # a local checkout
|
|
portal lint --repo https://project.uhhm.no/uhhm/questions
|
|
portal lint replay --path questions --nats nats://127.0.0.1:14222
|
|
```
|
|
|
|
It was its own binary, iris, until portal 0.6: the same code, released
|
|
as portal's twin. Now it is the `portal` binary's `lint` command, so a
|
|
content repo's CI downloads the release and runs it:
|
|
|
|
```yaml
|
|
- run: |
|
|
curl -sfL "https://project.uhhm.no/uhhm/portal/releases/download/$PORTAL_RELEASE/portal-x86_64-linux" -o portal
|
|
chmod +x portal && ./portal lint --path questions
|
|
```
|
|
|
|
`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.
|
|
`portal lint 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 [Training a site](training.md) for what sits around those.
|
|
|
|
## Matching the site
|
|
|
|
The lint is the site: `portal lint` and `portal serve` are one binary
|
|
built from one source, so a content shape the site reads is a shape
|
|
the lint knows, at the same version. A content repo pins
|
|
`PORTAL_RELEASE` to what its site runs and lints with that release's
|
|
`portal`. The `IRIS_RELEASE` pins from before portal 0.6 keep working
|
|
against the iris releases that exist; nothing new is published there.
|