Replace focus with typed detail rules; ship titles as stock lenses

A detail rule is a function from place to detail level. Each consumer
chooses its own level-of-detail rule. Dungeon uses ByDistance anchored on
important subjects, the player first. Delvehold starts from Uniform.

Rules are typed world data that the library evaluates, not consumer code.
The deficit a rule produces is an admission input, and journal replay
re-runs reduce, so a changed consumer function would break committed
history. WorldScaleIntent per-kind targets remain the ceiling a rule
distributes.

The eight titles move into the library doc as the stock lens set. The
kernel extraction is ordered as plan step 15 pass L0, ahead of every
library pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-09-15 22:55:18 +02:00
commit e19c9d9bda
7 changed files with 120 additions and 117 deletions

View file

@ -12,23 +12,22 @@ to the library: no Vault registry, player, slider, starting location, or
Session Zero phase exists in the library vocabulary.
The library capabilities it needs are specified, consumer-neutral, in
`ghostlight-world-ontology.md` under "Elaboration lenses and focus (target)":
consumer-supplied elaboration lenses with weights, focus-weighted elaboration
demand with a consumer-supplied detail profile, per-world evidence binding,
and elaborator sessions in Draft. Other consumers (Delvehold, Epiphany, future
narrative simulations) use the same capabilities with their own policy.
`ghostlight-world-ontology.md` under "Elaboration lenses and detail rules
(target)": the stock lens set and weights, detail rules, per-world evidence
binding, and elaborator sessions in Draft. Other consumers use the same
capabilities with their own policy; Delvehold, for one, starts from a
`Uniform` detail rule.
Source today does not match this boundary: the world kernel lives in
`crates/ghostlight-dungeon/src/world/` beside Dungeon's runtime. Plan step 15
names the extraction question.
Source does not yet match this boundary: the world kernel lives in
`crates/ghostlight-dungeon/src/world/` beside Dungeon's runtime. Extracting it
into a library crate is the first pass of plan step 15.
## Objective
A player chooses a Vault, says what kind of experience they want, and gets a
world seeded from that Vault. The world is dense where they stand and sketched
where they don't, and it grows detail ahead of them as they travel. The flavor
of the world comes from how often each of the eight titled elaborators works
on it.
of the world comes from how often each of the eight stock lenses works on it.
## The flow
@ -37,68 +36,49 @@ on it.
read, for example Kalsa's `Public`. The payload carries a Vault id, never a
path. Dungeon binds the chosen Vault as the world's evidence source.
2. **Describe the experience.** The player writes what they want. A model
reads that description and proposes weights for the eight titles. The
reads that description and proposes weights for the eight stock lenses. The
proposal fills the sliders; the player adjusts them. Dungeon submits only
the numbers and the description, which becomes the world brief.
3. **Create.** Dungeon creates a library world with title, brief, lens set and
weights, and Dungeon's detail profile. No player subject is declared yet.
3. **Create.** Dungeon creates a library world with title, brief, the stock
lens set and weights, and Dungeon's detail rule with no anchor yet. No
player subject is declared yet, so every place sits at the rule's floor.
4. **Sketch.** Dungeon's seed session authors a coarse world from the Vault:
regions, routes with travel costs, institutions, populations.
5. **Choose a start.** The player picks a sketch place. Dungeon submits one
owner patch declaring the player's human-controlled subject there, and sets
that subject as a focus of the world.
owner patch declaring the player's human-controlled subject there, and pins
that subject as the first anchor of its detail rule.
6. **Elaborate.** The library's elaborator sessions run, pulled toward the
focus by distance.
anchors by distance.
7. **Activate** when the player chooses. Dungeon never makes activation wait
on a count.
8. **Play.** As the player travels, the library's derived demand follows the
focus and detail follows the player.
## Dungeon's lens set
Dungeon uses the eight titles under their original names and meanings as its
lens set:
| Title | Reaches for |
|---|---|
| Patina | ordinary objects, customs, nicknames, local jokes |
| Charter | government, law, offices, selection, succession, redress |
| Ledger | resources, labor, trade, infrastructure, scarcity, class pressure |
| Hearth | kinship, daily life, care, obligation, belonging |
| Tangle | factions, alliances, rivalries, leverage |
| Veil | secrets, rumors, misinformation, taboos, unevenly held knowledge |
| Ember | disputes, hazards, instability, escalation, urgent pressure |
| Numen | religion, magic, ritual, awe, cosmology, the genuinely strange |
Each title is a library lens: brief text plus an emphasis over the operation
catalog. Ledger leads with custody and dependency operations, Veil with
knowledge and channels, Charter with authority and selection. Whether the
eight ship with the library as a stock set or live in Dungeon is an open
decision below.
anchor and detail follows the player.
## Dungeon policy
- **Focus:** the subjects controlled by Dungeon's players.
- **Detail profile:** near 60 minutes (persons, institutions, populations),
middle 1 day (institutions and populations), far (institutions), lookahead
120 minutes. These are recommendations, tuned on the road.
- **Weights after creation:** the world owner may change them in Draft and
Active; later sessions use the new weights.
- **Lenses:** the library's stock set of eight, weighted by the player's
sliders. The owner may change weights in Draft and Active; later sessions use
the new weights.
- **Detail rule:** `ByDistance`, anchored on important subjects, the player
first. Recommended levels: within 60 minutes, persons, institutions, and
populations; within 1 day, institutions and populations; beyond, institutions
only; lookahead 120 minutes. Tuned on the road. Which other subjects Dungeon
pins, and when, is Dungeon policy not yet decided.
- **Travel:** Dungeon's seed authors a travel affordance for persons, and the
Eve surface projects one control per affordance a player's subject holds.
## Authority map (Dungeon)
- **Owner:** Dungeon's runtime owns Session Zero's flow, the Vault registry,
the weight proposal, the player principal, and the Eve surface. Every world
change it makes is an ordinary library command.
the weight proposal, the player principal, anchor pinning, and the Eve
surface. Every world change it makes is an ordinary library command.
- **Inputs:** the authenticated player, the admitted Vault list, the player's
description and slider values, the chosen start place.
- **Outputs:** library world creation, seed and owner patches, focus changes,
- **Outputs:** library world creation, seed and owner patches, rule and
weight changes, activation, and Eve projections.
- **Derived state:** the slider proposal, the Session Zero step a player is on
(derived from the library snapshot's phase, focus, and structure), and every
projection.
(derived from the library snapshot's phase, rule anchors, and structure), and
every projection.
- **Forbidden writers:** Dungeon writing world state other than through
library commands; the proposal model submitting weights without the
player's command; a Vault path in any payload; any Dungeon identifier,
@ -109,7 +89,7 @@ decision below.
- `GHOSTLIGHT_SEED_VAULT_ROOT` as the only Vault: Dungeon's Vault registry
replaces it.
- The `world.create` payload fields for jurisdiction roots and permille, when
the library's detail profile replaces them.
the library's detail rule replaces them.
- The genesis human subject: Dungeon declares its player at the chosen start.
## Verification (Dungeon)
@ -118,30 +98,19 @@ decision below.
unknown id or a path is refused before anything is spent.
2. The slider proposal changes nothing until the player submits weights.
3. The start choice declares exactly one player subject, at a sketch place,
once, in Draft, and sets it as focus.
once, in Draft, and pins it as the rule's first anchor.
4. Activation succeeds with nonzero deficits.
5. Road: a seeded world on the SDK route shows persons near the start,
institutions far from it, and new persons at a place after the player's
subject travels toward it.
## Decisions the operator owns
- **Where the eight titles live.** Recommend: the library ships them as a
stock lens set any consumer may use or replace, because they are
world-agnostic narrative categories; Dungeon selects them and supplies
weights.
- **Library extraction.** Whether the world kernel moves out of
`crates/ghostlight-dungeon` into its own library crate before the library
passes land, so new library capabilities are not built inside a consumer.
Recommend: extract first.
## Pass order
Library passes are in the ontology doc's target section and plan step 15.
Dungeon passes follow them:
Library passes L0 through L4 are in plan step 15; L0 is the kernel
extraction. Dungeon passes follow them:
1. Vault registry, world creation with Vault id, brief, lens set, weights, and
detail profile.
1. Vault registry, world creation with Vault id, brief, lens weights, and
detail rule.
2. The Session Zero Eve surface: Vault choice, description, slider proposal,
sliders, sketch, start choice, activation.
3. Travel affordance and per-affordance player controls. This pass closes the

View file

@ -134,7 +134,7 @@ log; the story feed is `operator_log`, an owner-only projection that the
controller lane cannot name because `ControllerRunner` holds a
`ControllerPort`, not the mailbox. `WorldMailbox::create` declares the genesis
place `commons` and stands genesis subjects there. Genesis declaration of
consumer subjects is cut ("Elaboration lenses and focus"); a consumer declares
consumer subjects is cut ("Elaboration lenses and detail rules"); a consumer declares
its own subjects by owner patch.
`Witness` is one speakerless event over a place subtree: a beacon, a bell, a
@ -359,7 +359,8 @@ and fixed titled quotas. They were compensators for an ontology with nowhere
to put depth. The eight titles themselves (Patina, Charter, Ledger, Hearth,
Tangle, Veil, Ember, Numen) were lenses, not tribunals. `6bb6869` deleted them
together with their verifier and no operator decision covered them; they
return as lenses ("Elaboration lenses and focus").
return as the library's stock lens set ("Elaboration lenses and
detail rules").
Character action had a matching defect: an attempt was an event, and a separate
wave-level outcome resolver asked a model whether it worked. Resources,
@ -664,7 +665,7 @@ carried as `SystemCapability::Elaborator { jurisdiction }`. Its lens decides
what kind of structure the session reaches for. A lens never enters the caller
identity, never narrows or widens admission, and never fills a quota. Target:
sessions draw a lens by the world's lens weights (below, "Elaboration lenses
and focus"). Shipped: the sweep runs one sequential unlensed session per
and detail rules"). Shipped: the sweep runs one sequential unlensed session per
jurisdiction. The tool catalog is
generated from this document's operation set and declaration kinds, plus
`record_gap` and `submit`. It cannot contain an operation the reducer does not
@ -711,7 +712,7 @@ A translation gap never mints a boundary. Gaps are non-fictional inference
evidence that may inform a later human decision to extend this vocabulary, and
that extension is a code change, not a world patch.
### Elaboration lenses and focus (target)
### Elaboration lenses and detail rules (target)
Adopted 2026-09-15, not implemented. These are library capabilities, neutral
to every consumer. A consumer supplies the policy: Ghostlight Dungeon's
@ -725,26 +726,53 @@ consumer's concept enters this vocabulary.
session ordinal and records it on its checkpoint and receipt as evaluation
evidence. The same patch under two lenses has the same admission result. A
zero weight never draws; an all-zero weight set is refused.
- **Focus.** A world carries a set of focus subjects written by its owner.
Distance is the least route cost, in travel minutes, from a focus subject's
position to a place over open routes that subject may traverse, computed by
the same route walk as `reachable`, factored to return a cost map. A place
without routes takes its nearest routed container's distance. With no focus,
every place is far.
- **Detail profile.** Supplied at creation: distance bands, each naming a
density per place for each subject kind, plus a lookahead in minutes that
measures the nearest band from where a focus could be after that much
travel. It replaces `WorldScaleIntent` jurisdiction permille; per-kind
targets survive inside it.
- **Stock lens set.** The library ships eight lenses any consumer may use or
replace:
| Lens | Reaches for | Leads with |
|---|---|---|
| Patina | ordinary objects, customs, nicknames, local jokes | persona material, ordinary affordances |
| Charter | government, law, offices, selection, succession, redress | authority, selection, redress |
| Ledger | resources, labor, trade, infrastructure, scarcity, class pressure | custody, dependency, route cost |
| Hearth | kinship, daily life, care, obligation, belonging | commitments, reads |
| Tangle | factions, alliances, rivalries, leverage | relations, pressure, authority |
| Veil | secrets, rumors, misinformation, taboos, unevenly held knowledge | knowledge scope, channels |
| Ember | disputes, hazards, instability, escalation, urgent pressure | pressure, near-due commitments |
| Numen | religion, magic, ritual, awe, cosmology, the genuinely strange | facts, affordances, material |
- **Detail rules.** A world carries one detail rule: a function from place to
detail level. A detail level names a target density per place for each
subject kind, and the rule carries its own level table. The rule is typed
world data, written by the world's creator and changed by its owner through
one command, never consumer code: the deficit it produces is an admission
input, and replay re-runs `reduce`, so a consumer function that changed
after admission would make committed history fail replay. Each commit is
checked against the rule in force at its revision. The library evaluates a
closed, versioned set of forms:
- `Uniform { level }`: every place at one level.
- `ByDistance { anchors, bands, floor, lookahead }`: anchors are canonical
subjects. Distance is the least route cost, in travel minutes, from any
anchor's position to a place over open routes that anchor may traverse,
reduced by `lookahead`. It uses the same route walk as `reachable`,
factored to return a cost map. A place without routes takes its nearest
routed container's distance. Bands map distance to a level; beyond the last
band, and for every place when no anchor is placed, the level is `floor`.
A consumer whose rule no form expresses asks for a new form, and the library
adds it without consumer names. Combinators wait for a consumer that needs
one. `WorldScaleIntent` per-kind world targets remain the ceiling the rule
distributes; jurisdiction permille is replaced by the rule.
- **Demand.** Derived in `snapshot`, never stored: open boundaries and
per-place deficits against the band target, ordered by distance, then by the
kernel's boundary order. A session's confinement ground is the place subtree
of the demand it answers. A focus moving changes demand without a commit.
`IndividuationRequired` derives for a population whose place enters the
nearest band.
- **Sessions.** Up to the configured concurrency run at once, in Draft once a
focus exists and in Active, each answering the head of demand. Each world
binds one evidence source, which every session and the seed lane read.
per-place deficits against each place's level, capped by the remaining world
target, ordered by level (most detailed first), then by the form's own key
(distance for `ByDistance`), then by the kernel's boundary order. A session's
confinement ground is the place subtree of the demand it answers. Under a
rule that reads positions, a subject moving changes demand without a commit.
`IndividuationRequired` derives for a population whose place's level asks
for persons.
- **Sessions.** Up to the configured concurrency run at once, in Draft and in
Active, each answering the head of demand. Each world binds one evidence
source, which every session and the seed lane read.
Cut when these land: authored jurisdiction roots as confinement units,
permille distribution, the `Uncovered` deficit row, the sequential
@ -753,8 +781,10 @@ per-jurisdiction sweep, `NullEvidenceSource` on the Active elaborator lane,
consumer subject.
Verification: the lens-invariant admission test; sampler determinism and
weight-following frequencies; zero-weight refusal; demand absent from
`WorldState` and reordered by a focus move alone; out-of-ground refusal; Active
weight-following frequencies; zero-weight refusal; `Uniform` assigning every
place one level; demand absent from `WorldState` and reordered by an anchor's
move alone under `ByDistance`; the world target capping a rule's deficits;
replay of a history spanning a rule change; out-of-ground refusal; Active
patches citing only the bound evidence source; activation with nonzero
deficits.
@ -878,7 +908,7 @@ Deleted before replacement behavior is added, with no compatibility path:
`CivicSystem` manifest (the typed subgraph), `PopulationLineage`
(individuation), `Lifecycle` and `WorldTime` (kernel-owned);
- the titled semantic verifier and titled quotas (the eight titles return as
lenses; see "Elaboration lenses and focus"), elaboration demand and deficit,
the stock lens set; see "Elaboration lenses and detail rules"), elaboration demand and deficit,
complexity rounds,
strategic waves, fission completion counts, `detail_debt` rotation, and every
`*Qualification` and `*Verification` type;