The editing plane¶
Nerthus.Core (until cutover). This page describes the frozen system that runs today and is deleted at cutover. Replaced by: not yet written.
An editing session is a named set of pending lore changes, owned by one person and published as one act. It is not a buffer and not a per-file autosave: the hard case is one person touching a character's prose, a map alignment and an entity tag in one sitting and needing that to land as clean history rather than three tabs racing each other to git.
A pending edit is invisible because of where it lives — .nerthus/staging/edits/, outside the
four scan roots — and not because anything filters it out. The session model, the participation
graph, the integrity walk, the PU ledger and the distribution fan-out cannot see one, and the model
fingerprint does not move while somebody is typing.
Routes¶
| Method | Path | Cmdlet | Cap | Write |
|---|---|---|---|---|
| POST | /edits |
— | lore.edit |
✓ |
| GET | /edits/{eid} |
— | lore.edit |
— |
| PUT | /edits/{eid}/entries |
— | lore.edit |
✓ |
| DELETE | /edits/{eid}/entries/{n} |
— | lore.edit |
✓ |
| DELETE | /edits/{eid} |
— | lore.edit |
✓ |
| POST | /edits/{eid}/publish |
— | lore.edit |
✓ |
lore.edit is a capability of its own and not entity.write. entity.write authorises one
- @tag: value line through a primitive that cannot express anything else; these routes accept
arbitrary file text, which can rewrite a diary, empty a file, or put a session block where the model
will not find it. A token reading entity.write would be lying about what it permits.
POST /edits/{eid}/publish additionally requires whatever its entries' kinds imply —
location.override for a layout entry, entity.write for an entity one, docs.edit for a
document one — so a narrator cannot reach a Council-level write by routing it through the editor.
The route's own lore.edit is a floor, and the extra set is derived from the manifest rather
than restated in the handler, so a kind added later cannot reach the route ungated.
The owner is the principal's Gracz and is never read from the body. A client that could name its own owner could author a commit as somebody else, in a repository the community clones.
Two paths are denied outright: nerthus.contributors.md, because editing it with a permission it
grants is a loop and a namiestnik typo in it is unrecoverable through the tool that made it; and
nerthus.ledger.md, because settlement output keeps its Council review through the sync service's
merge-request rule.
The four staging writes have no dry run yet
?dryRun=true on POST /edits, PUT /edits/{eid}/entries, DELETE /edits/{eid}/entries/{n}
and DELETE /edits/{eid} answers 400 DryRunUnsupported rather than a preview. Those four
write only to the staging directory and a preview of them is real design work nobody has done;
a refusal a caller can act on is better than a flag the handler ignores. It matters because the
write gate's ReadOnly arm yields to a dry run, so a Write route that ignored the flag would
perform its write on a read-only replica the moment the gate let it past.
POST /edits/{eid}/publish — the one route that touches lore — does honour ?dryRun=true,
and that is the dialog a person confirms.
Publishing¶
The publish stages exactly the paths its manifest names and commits one per group, authored as the
person who made the edit — <slug>@nerthus.pl, derived, set per invocation and never written into
the clone's config. Two people whose names slug identically is a refusal, not a resolution.
It does not push. It commits and asks the sync tick to run now; the push, the rebase, the merge-request fallback and the retry all belong to the sync service, and a second path to origin would be a second set of its bugs.
A group that accepted a divergent propagation target goes out as a merge request. A mixed publish splits: the groups that overwrote nobody go direct to the default branch, and only the affected one waits for a reviewer. Such a publish announces nothing to the fleet, because no peer tracks the review branch — the person pressed a button, commits were made, and the fleet does not have them until somebody merges.
document — a second target kind¶
A document entry edits a file in another repository, named by an alias the host configures
under editor.targets. It carries docs.edit, never lore.edit, and none of the lore machinery
applies: no propagation, no announce, no model rebuild, and no sync-tick nudge. Its commit is local,
and whoever owns that repository publishes it.