Governance¶
Nerthus.Core (until cutover). This page describes the frozen system that runs today and is deleted at cutover. Replaced by: not yet written.
Governance is the narrator permissions table — Uprawnienia — one row per Narrator,
keyed by Margonem ID and stored in private state (never the lore repository). Each row
records what a Narrator is allowed to run: ranga, magia, polityka, walki_pvp, and
the like. This page covers reading the table and upserting one row. The write example
targets Anward, the Narrator of the fixture
session.
Reads need governance.read, writes need governance.write; the admin token carries
both. Every example runs against a live daemon — see
how the reference is tested.
Routes¶
| Method | Path | Cmdlet | Cap | Write |
|---|---|---|---|---|
| GET | /governance/permissions |
Get-NerthusNarratorPermission |
governance.read |
— |
| PATCH | /governance/permissions/{nick} |
Set-NerthusNarratorPermission |
governance.write |
✓ |
| GET | /config/schedules |
— | governance.read |
— |
| PATCH | /config/schedules/{workload} |
— | governance.write |
✓ |
Cap is the required capability (— = public, no token); Write (✓) marks routes that pass the write gate; a — in Cmdlet is reached directly, no wrapper. Paths are relative to /v1/api; the cross-cutting contract — middleware, envelopes, status codes — is on the API reference index.
This page is the narrator permissions table and nothing else. The /governance/* prefix also
carries the fact ledger — who held which function when, which rule was in force — on
/governance/refs, /governance/{ref} and /governance/{ref}/log, which are public and are
covered by the governance ledger. The two share a prefix and no concept.
Route order keeps them apart: permissions is a literal declared before /{ref}, and it is not a
ref name.
The {nick} path segment also accepts the Margonem id; a successful edit fires the AfterGovernanceChange hook (governance:changed on the event stream). The Uprawnienia model: Permissions.
Read the permissions table¶
Schedule ownership¶
Three recurring workloads can run from two places. schedules.<workload>.owner in the committed
config.json names one owner each, and both halves of the deployment obey it: the primary's tick
through Get-NerthusScheduleOwner, the CI drivers through Get-NerthusScheduleOwnerFromRepo
before any daemon exists. These two routes are the only surface over that block.
GET /v1/api/config/schedules answers { workloads, source }. Each workload carries its owner,
its allowed set, its default, and a source of committed or default. source is read from
the committed file alone — the merged config lays the document over the built-in defaults, so every
workload reads as decided there whether or not anybody decided it, and a console must not render a
default nobody chose as a decision somebody made.
PATCH /v1/api/config/schedules/{workload} takes { "owner": "off" }. An owner outside the
workload's allowed set is 422 naming the set — fleet on settlement is refused rather than
defaulted, because settlement has no tick and fleet there would be silence dressed up as a
choice. An unknown workload is 404. ?dryRun=true answers 200 with wouldSet and persists
nothing.
Two things the block does not say and the answer does. off does not stop the pipeline — the
GitLab schedule still fires and the driver exits as a no-op; what stands down is the driver. And
the edit is committed lore, so the response carries effectiveAfterConverge: true: this host obeys
at once, the rest of the fleet at converge speed.
GET /v1/api/governance/permissions returns the { count, items } envelope — every
Uprawnienia row. Narrow to one Narrator with ?id= (Margonem ID or nick). A freshly
imported repository has no rows yet.
Response 200:
Preview a permission edit without writing¶
PATCH /v1/api/governance/permissions/{nick} upserts the matched row (by Margonem ID or
nick) and stamps zmieniono. With ?dryRun=true it returns 200 { wouldUpdate, fields }
and persists nothing — proven by the follow-up ?id=Anward read still finding no row.
Response 200: