Record the witness operation in the docs
One speakerless event over a place subtree: recipients derived at apply time by the one reach owner, already-holders untouched, an empty subtree refused at both layers, confinement through the operation's place, an affordance slot so a world can author a beacon or a blast. Schemas at consumer.v2; the operation count aligned to the catalog's pinned count. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
70ea6b1323
commit
12445955d5
3 changed files with 92 additions and 29 deletions
|
|
@ -139,6 +139,10 @@ those subjects (`confine_to_ground`, the `PatchGround::Consumer` arm):
|
|||
- a declared place, a declared route, `Relocate`, `OpenRoute`, `CloseRoute`,
|
||||
and `AlterCost` are always refused — they carry a place or a route, and a
|
||||
consumer's ground names no place;
|
||||
- `Witness` is always refused, for the same reason: its ground is the named
|
||||
place, never the acting subject, and a consumer's ground names no place.
|
||||
A consumer tells what its mirror knows through `AcquireKnowledge` on its own
|
||||
bound subject; it cannot cause a place-wide witnessed event;
|
||||
- a `Claimed { by }` fact must name a bound subject; a `Canonical` fact
|
||||
declaration is refused outright — a consumer's evidence buys an `Admit`
|
||||
into its own custody and a `Claimed` fact, never a canonization;
|
||||
|
|
@ -175,8 +179,8 @@ enters a log, a receipt, or the journal.
|
|||
|
||||
The consumer capability's tag is part of the commit digest and the
|
||||
externally controlled assignment is part of the state shape, so both bump the
|
||||
schema: state schema `ghostlight.world_state.consumer.v1` (state-schema
|
||||
generation `world-v3`), commit schema `ghostlight.world_commit.consumer.v1`.
|
||||
schema: state schema `ghostlight.world_state.consumer.v2` (state-schema
|
||||
generation `world-v3`), commit schema `ghostlight.world_commit.consumer.v2`.
|
||||
A store written under an earlier schema is refused, not migrated.
|
||||
|
||||
## Not in this pass
|
||||
|
|
|
|||
|
|
@ -103,7 +103,9 @@ target, otherwise `ActionMismatch::DelegationNotMonotone`.
|
|||
A `Fact` is an entity with a `Statement` and a `FactStanding`: `Canonical`
|
||||
with evidence, or `Claimed { by }`. `Knowledge` is subject-keyed per fact with
|
||||
a `Confidence` and a `KnowledgeSource { Witnessed, Told { by, via }, Evidenced }`;
|
||||
a telling never overwrites a holder. A `Channel` is an entity with a
|
||||
a telling never overwrites a holder. `Witnessed` is minted by an authored
|
||||
patch's `AcquireKnowledge` and, with no author at all, by `Witness` (below). A
|
||||
`Channel` is an entity with a
|
||||
`Reach { Subjects, Place }` and a controller. Speech is an affordance whose
|
||||
entry declares exactly one `Audience { Colocated, Channel }`: `exercise`
|
||||
mints the `Claimed` fact through `derive_id` (one of the fixed set of `derive_id`
|
||||
|
|
@ -120,6 +122,31 @@ controller lane cannot name because `ControllerRunner` holds a
|
|||
`ControllerPort`, not the mailbox. `WorldMailbox::create` declares the genesis
|
||||
place `commons` and stands genesis subjects there.
|
||||
|
||||
`Witness` is one speakerless event over a place subtree: a beacon, a bell, a
|
||||
blast. It names a fact, a place, and a confidence, and no speaker at all.
|
||||
Recipients are never stored; they are derived at apply time by `under_place`,
|
||||
the same subtree walk `audience`'s `Reach::Place` arm uses, so a declared
|
||||
broadcast area and a witnessed event cannot disagree about who is "under" a
|
||||
place. Every subject standing anywhere under the place learns the fact;
|
||||
whoever already holds it is untouched (`unheld`, the same never-overwrite rule
|
||||
`Communicate`'s fan-out applies). The landed row is `KnowledgeSource::Witnessed`
|
||||
at the authored `confidence`. A telling still occurred even into an empty room,
|
||||
so `Communicate`'s empty fan-out is a legal no-op; a witnessed event is only
|
||||
its reception, so a `Witness` over an empty subtree — or one where every
|
||||
standing subject already holds the fact — is refused as
|
||||
`Mismatch::NoOperationEffect` at resolve and `KernelError::Invariant` at apply,
|
||||
the same rule at both layers. Confinement runs through `operation_ground`
|
||||
returning the named place as the whole ground: an elaborator may witness only
|
||||
under its own jurisdiction root, and a consumer patch may never witness at all,
|
||||
because `PatchGround::Consumer` and `Jurisdiction(Uncovered)` refuse every
|
||||
place. `ComponentOpKind::Witness { confidence }` puts the same operation behind
|
||||
an affordance slot naming `[fact, place]` roles and no subject role, so a
|
||||
world-authored affordance can cause a witnessed event with no proposer ever
|
||||
choosing a speaker. Because every recipient's `knows` component changes, every
|
||||
recipient's scope digest moves — nobody else's does — which is what lets a
|
||||
regional or global event interrupt whoever was mid-thought under that place
|
||||
(the interruption mechanism of pass 9).
|
||||
|
||||
Time is `now: FictionalMinutes`, moved only by `CommandBody::AdvanceTime`
|
||||
from `CallerId::System(SystemCapability::Clock)`; the runtime tick submits
|
||||
the constant `CLOCK_TICK_MINUTES`, never a measured duration. `world/clock.rs`
|
||||
|
|
@ -205,7 +232,7 @@ under four caps — `MAX_PATCH_BYTES`, `MAX_PATCH_DECLARATIONS`,
|
|||
`MAX_PATCH_OPERATIONS`, `MAX_PATCH_EVIDENCE` — and the consumer document
|
||||
travels over two wire schema constants, `CONSUMER_PATCH_SCHEMA` and
|
||||
`CONSUMER_RECEIPT_SCHEMA`, both `.v0`. The state and commit schemas bump to
|
||||
`ghostlight.world_state.consumer.v1` and `ghostlight.world_commit.consumer.v1`
|
||||
`ghostlight.world_state.consumer.v2` and `ghostlight.world_commit.consumer.v2`
|
||||
(state-schema generation `world-v3`); a store written under an earlier schema
|
||||
is refused, not migrated.
|
||||
|
||||
|
|
@ -254,8 +281,8 @@ is the typed component diff against the fresh components plus the
|
|||
knowledge row, and never another subject's snapshot. The re-lowering's
|
||||
provider request is a distinct round (`interpreter_round`) with its own
|
||||
content-addressed request id, so it cannot collide with the first lowering's
|
||||
request. State schema is `ghostlight.world_state.consumer.v1`, commit schema
|
||||
`ghostlight.world_commit.consumer.v1`, controller work `controller_work.v11`,
|
||||
request. State schema is `ghostlight.world_state.consumer.v2`, commit schema
|
||||
`ghostlight.world_commit.consumer.v2`, controller work `controller_work.v11`,
|
||||
Persona turn receipt `ghostlight.persona_turn_receipt.v3`; earlier stores and
|
||||
earlier rows are refused. Ghostlight owns a conserved narrative ledger;
|
||||
Delvehold owns the economy (`delvehold-forced-ontology-integration.md`).
|
||||
|
|
@ -404,7 +431,7 @@ Authority grant(subject, scope, kind), revoke
|
|||
Selection open_office, close_office, install(office, incumbent), vacate
|
||||
Redress open_forum(kind, forum, standing), close_forum
|
||||
Knowledge acquire(subject, fact, source, confidence), communicate(speaker, fact,
|
||||
channel), forget
|
||||
channel), witness(fact, place, confidence), forget
|
||||
Channel set_reach, set_controller
|
||||
Commitment create(subject, counterparty, kind, due, period, checks), discharge
|
||||
Pressure advance, reduce, resolve
|
||||
|
|
@ -413,7 +440,7 @@ Retirement retire(referent, reason)
|
|||
Time advance(minutes)
|
||||
```
|
||||
|
||||
Twenty-seven operations. Adding one is a design change to this document and a
|
||||
Twenty-nine operations. Adding one is a design change to this document and a
|
||||
code change to the reducer; it is never a runtime patch.
|
||||
|
||||
## Patch construction
|
||||
|
|
@ -468,7 +495,7 @@ counts do not appear here and may not be added.
|
|||
The kernel owns component operations. A **world** owns its affordance catalog.
|
||||
This is the generality lever: a setting with spellcraft, insurance claims,
|
||||
oath-rhythms, or memetic sovereignty authors affordances from the same
|
||||
twenty-seven operations, and the kernel never learns a genre.
|
||||
twenty-nine operations, and the kernel never learns a genre.
|
||||
|
||||
```text
|
||||
Affordance
|
||||
|
|
@ -766,7 +793,7 @@ Deleted before replacement behavior is added, with no compatibility path:
|
|||
|
||||
## Subtraction budget
|
||||
|
||||
- 20 component kinds → 12; 18 `WorldMutation` variants → 27 named operations
|
||||
- 20 component kinds → 12; 18 `WorldMutation` variants → 29 named operations
|
||||
under 1 patch primitive, replacing both the mutation enum and the separate
|
||||
outcome-effect sum;
|
||||
- 5 qualification and verification types plus 1 outcome resolver → 0;
|
||||
|
|
|
|||
|
|
@ -99,8 +99,8 @@ projection of committed history.
|
|||
Interpreter does not accept, reject, or commit world state.
|
||||
5. Structural invalidity is rejected deterministically before persistence and
|
||||
without a model verifier. A failed batch changes nothing.
|
||||
6. Private knowledge remains scoped until an explicit communication command
|
||||
changes it.
|
||||
6. Private knowledge remains scoped until an explicit communication command or
|
||||
a witnessed event under the subject's place changes it.
|
||||
7. External consumers retain sovereignty. Ghostlight views, proposals, and
|
||||
acknowledgements cannot mutate external-owned state.
|
||||
8. Sparse causal sufficiency governs structural validity; counts and
|
||||
|
|
@ -429,29 +429,61 @@ a live provider — none exists yet for the narrative lane's re-lowering
|
|||
round, so the next road run is the first evidence of `interpreter_round`
|
||||
producing a real second request.
|
||||
|
||||
### 10. Witnessed events over a place subtree — in design
|
||||
### 10. Witnessed events over a place subtree — landed
|
||||
|
||||
Objective: stories that carry regional and global effects. An asteroid is
|
||||
witnessed by everyone under a region's root; the moon going dark by everyone
|
||||
under a hemisphere's; a subject standing in a village under both sees both.
|
||||
|
||||
Current mechanism: knowledge enters a subject through `AcquireKnowledge`
|
||||
(one operation per subject), through speech fan-out (`Communicate`, which
|
||||
names a speaker and follows a channel's `Reach`), or through evidence. An
|
||||
event with no speaker that a thousand people saw costs a thousand operations
|
||||
and hits the patch caps.
|
||||
|
||||
Intended change: one operation, `Witness { fact, place }`, that lands
|
||||
Landed mechanism: `ComponentOp::Witness { fact, place, confidence }` lands
|
||||
`Witnessed` knowledge of the fact on every subject positioned anywhere under
|
||||
the place, recipients derived at apply time from live positions exactly as
|
||||
speech fan-out derives its audience, never stored. Every witness's scope
|
||||
digest moves, which is what makes a global event interrupt whoever was
|
||||
mid-thought (step 9).
|
||||
the place. Recipients are never stored; `ResolvedOp::Witness`'s apply arm
|
||||
derives them at apply time through `under_place`, the same subtree walk
|
||||
`audience`'s `Reach::Place` arm now calls, so a declared broadcast area and a
|
||||
witnessed event share one definition of "under a place". Whoever already
|
||||
holds the fact is dropped through `unheld`, factored out of `fan_out`'s old
|
||||
inlined filter so `Communicate` and `Witness` cannot disagree about who
|
||||
already knows. A telling still occurs into an empty room, so `Communicate`'s
|
||||
empty fan-out stays a legal no-op; a witnessed event is only its reception,
|
||||
so a `Witness` over an empty subtree, or one where every standing subject
|
||||
already holds the fact, is refused as `Mismatch::NoOperationEffect` at
|
||||
resolve (over the candidate graph, including this patch's own relocations)
|
||||
and `KernelError::Invariant("a witness reaches nobody who does not already
|
||||
hold the fact")` at apply — one rule, both layers. Confinement runs through
|
||||
one new `operation_ground` arm returning the named place as the whole
|
||||
ground: an elaborator may witness only under its own jurisdiction root, and a
|
||||
`PatchGround::Consumer` patch can never witness, because its ground names no
|
||||
place. Every recipient's scope digest moves and nobody else's does, which is
|
||||
what makes a regional or global event interrupt whoever was mid-thought
|
||||
(step 9).
|
||||
|
||||
Cut line: no second fan-out owner; no stored recipient list; a witness names
|
||||
no speaker; the subtree walk reuses the one covering predicate; the tool
|
||||
surface and exemplar lists grow by exactly one; confinement treats the place
|
||||
like any other operation ground.
|
||||
Beyond the operation itself, an affordance slot,
|
||||
`ComponentOpKind::Witness { confidence }` with roles `[fact, place]` and no
|
||||
subject role, was not anticipated by this plan's text but was needed to let
|
||||
a world-authored affordance (a bell, a beacon) cause a witnessed event
|
||||
without a proposer ever naming a speaker; the source is `Witnessed` by
|
||||
construction, since `ComponentOp::Witness` has no field a teller could enter.
|
||||
One `PATCH_TOOLS` entry, `witness`, rounds out the model-facing surface.
|
||||
Both store schemas moved to `ghostlight.world_state.consumer.v2` and
|
||||
`ghostlight.world_commit.consumer.v2`; a store written under the prior schema
|
||||
is refused, not migrated.
|
||||
|
||||
Cut line held: one fan-out owner (`under_place`), shared by `audience` and
|
||||
`Witness`; one never-overwrite owner (`unheld`), shared by `fan_out` and
|
||||
`Witness`; no stored recipient list; a witness names no speaker, so `Told`
|
||||
stays unrepresentable outside `Communicate`; no new `Mismatch`,
|
||||
`KernelError` variant, `CommandBody`, `SystemCapability`, or
|
||||
`CompositeShape`; `verify_state_shape`, `can_broadcast`, and
|
||||
`candidate_in_audience` untouched.
|
||||
|
||||
What is undone: the affordance-declaration refusal for a slot whose second
|
||||
role binds a subject is proved directly through `arity` and
|
||||
`role_kind_fits`, not by submitting a malformed `AffordanceDeclaration`
|
||||
through admission — the gate is the one gate either way, but the submission
|
||||
path itself is untested. The grouped lane's cost is untouched: a
|
||||
region-wide or global witness still discards a grouped cell's in-flight work
|
||||
for every constituent it touches, which is the debt this pass explicitly
|
||||
declined to pay.
|
||||
|
||||
## Subtraction budget
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue