P7.1 is falsified in a small way: a bare name still decodes (PA.f71).
Refusal wording, the table's missing authority, and test gaps are
PA.f72 to PA.f75, to fix in batch 7c. PA.f76 is recorded.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Answers and continues arrive with new request keys and discard the open
turn (PA.f62). Persona prose never reaches the agent (PA.f64). An empty
answer wedges the turn (PA.f65). communicate and set_persona_material
break invariants 3, 4 and 2 in substance (PA.f61): communicate leaves
PLAY_TOOLS, and persona material is limited to new subjects. Self's
rulings under the standing go are recorded in each finding.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The table view omits ids the play tools need (PA.f53), and decoded
calls cannot join one patch (PA.f54). Actor tools emit tools the decoder
refuses (PA.f55). Refusal text is wrong and serves both the agent and the
player (PA.f56, PA.f57). Self's rulings: one patch per run of authoring
calls, and an actor-facing refusal form.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
P4.1 is falsified: the resolver still counts a retired institution's
authority, and the kernel does not (PA.f48). The genesis acquired_at stamp
is off by one (PA.f49). The checkpoint check and the PA.f40 test are not
properly pinned (PA.f50, PA.f51). These are to fix; PA.f52 is recorded.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
PA.f47: table_view cannot print ruled, because the snapshot collapses
Ruled to Canonical for every reader. The omniscient view gains Ruled;
subject-facing renderings keep it canonical.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There is no world quarantine at the play table. Inference faults become
tool results for the agent, and only a kernel invariant stops the table.
Cut 8 is split into 8a (the loop) and 8b (the wiring).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A forged opportunity is recorded in a turn's binding (PA.f41). The
assembled Projector request and three lane paths are untested (PA.f42,
PA.f43). Rows with no minted_at never read as new, so the marker moves to
an acquired_at revision (PA.f44). The lane duplicates runner code
(PA.f46). The world brief is named in invariant 2 as world-public
(PA.f45).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
PA.f36 to PA.f40 are to fix in batch 5. Self's rulings under the standing
go: retired subjects' commitments stop moving, a retired promisor is
refused, and a retired institution lends no authority.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The journal's shape check judges past events against present assignments,
so a subject that acted cannot be retired and a used verb cannot be
revoked (PA.f31). The owner can retire the human in Draft to skip
approval (PA.f32). Retired subjects still hear and speak through subject
channels (PA.f33) and can gain or forget knowledge or hold office
(PA.f34). Self's design rulings under the standing go are recorded in each
finding.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
No promise was falsified. Genesis bypasses require_ruler (PA.f26), three
mutations survive the author-rule tests (PA.f27), and two promised tests
are missing (PA.f29); all three are to fix. PlayPort's convention sealing
(PA.f28) is defaulted and recorded under the standing go.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
PA.f23 (null response id quarantines the lane) and PA.f24 (no IPv6
loopback test) are to fix; PA.f25 is recorded.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The port's HTTP client honours proxy environment variables and follows
redirects. Loopback-only requests left the machine, and a proxy URL's
userinfo was sent as proxy-authorization. PA.f16 to PA.f22 are triaged
to fix in one batch after Cut 3 lands; PA.f21 is recorded.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Cut 1 (d69e9d4) deleted the tick driver and the Active elaboration sweep, and
the ignored live smoke that exercised them. These passages still described
that machine as live:
- notes/local-live-smoke.md was a runbook for the deleted smoke and its
command now runs zero tests. Trimmed to what is still true: connector and
Claude SDK sidecar bring-up, which the seed lane still depends on. Fixed
the references to its deleted sections in notes/fresh-workspace-handoff.md.
- docs/architecture/ghostlight-dungeon-mvp.md's Verification contract named
the live smoke as the road's one proof point; it now says none exists until
the play agent's own gate.
- notes/ghostlight-implementation-plan.md's Interruption section named
ControllerHttpResult::Interrupted and run_cover_tick as live; both are
deleted, and reporting an interruption to the play agent is Cut 8's.
- docs/architecture/ghostlight-stock-lenses.md gets one added sentence: the
concurrent-elaboration claim holds as a library capability, and Dungeon
runs none of it since Cut 1. The verdict is unchanged.
- notes/fresh-workspace-handoff.md's concurrent-elaboration and
tick-driver lines now say what Dungeon actually runs today.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
All four promises hold. P1.1 and P1.2 are unguarded by any test (PA.f11),
and the only test of the receipt kinds was dropped (PA.f12). Both are to
fix, along with the stale docs (PA.f15). PA.f13 and PA.f14 go to Cut 8.
The negative grep now allows the one hit at M1.1's test.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Nothing in Dungeon now runs a Persona, an operational agent or an
elaborator on its own. Deleted from runtime.rs: the cover tick driver
(drive_cover_tick, drive_one_tick, run_cover_tick, submit_clock_tick,
CoverSummary, InterruptedCell, cover_panel, the clock-tick constants,
configured_cover_budget, configured_tick_interval), the Active
elaboration sweep (elaborate_world, run_elaboration_sweep,
ELABORATION_SWEEP_INTERVAL, configured_elaboration_ceiling,
AppState.elaboration_permits), and the owner's "Let X act" route
(ControllerActPayload, dispatch_controller, admit_controller_command,
ControllerHttpResult and its builders, controller_error_disposition).
Deleted from eve.rs: CoverPanel, CoverPanelTick, cover_card, the owner's
controller buttons and descriptor, and world.controller.act from
operation_schema.
AppState.controller_quarantined is deleted as well: its only writers were
dispatch_controller and run_cover_tick, so it could never be set again.
controller_permits and configured_controller_concurrency stay for Cut 8;
until then only runtime_readiness reads the pool. ControllerRunner stays
for seeding and custody_probe; world.speak, the story card and
world.advance_time stay until Cut 9.
Tests dropped with the behaviour they pinned: the nine the cut map lists,
plus no_proposal_projection_carries_the_canonical_world_commit, which
tested the deleted controller_submission. Their fixtures go with them;
the world fixture collapses to the Draft-only path its remaining callers
use. removed_legacy_operation_is_denied_before_dispatch now also names
world.controller.act.
Docs: the MVP doc, the ontology and the handoff drop the cover,
tick-interval and elaboration-ceiling variables and the sentences that
described the deleted drivers.
Library untouched. Built and tested on Windows only.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Cut 3 now adds a unit FactStanding::Ruled and a new ComponentOp::Mint
rather than reshaping Admit. It adds one post-resolution author check,
require_ruler, which refuses either one unless the caller is
System(Play). The evidence gate is unchanged for every author, Play
included. The work-row bump to v17 moves into Cut 3.
PA-Q10 and Q12 are folded in as ruled designs. PA-Q7's list becomes 25
tools, with mint in and admit out. table_view prints ids, holdings, and
each fact with its standing and who knows it.
New findings: PA.f9 (the shared catalog shows mint and ruled to the seed
and elaborator lanes; watched at the gate), and PA.f10 (minted quantity's
only provenance is the commit caller; a question for the outbound pass).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The operator accepted the map's recommendation on PA-Q1, Q3, Q7, Q10, Q12
and Q13 on 2026-09-22. The operator also ruled PA-Q15: the play authority's
facts stand as Ruled, and it mints quantity without evidence ("if the agent
can invent people, it can invent loot"). Only Play gains either;
elaborators, consumers and the seed keep the evidence gate.
The target now lists the library's fourth piece (the table vocabulary and
inference seams) and the affordance grants. Invariant 5 gains Ruled facts
and minting, and invariant 8 shows the kernel's refusal of the player's own
act. Cut 3 still specifies the superseded PlayCarriesEvidence refusal and
is being respecified.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Imagination's cut map for the play agent target. Probes compiled a scratch
consumer against the library, and the agent's tool catalog was measured.
The map answers target questions Q1-Q14. Q2, Q5, Q6, Q8 and Q9 are
defaulted, Q4 and Q14 are findings, and Q11 is ruled by the operator.
Q1, Q3, Q7, Q10, Q12 and Q13 await operator rulings.
Ten cuts follow, subtraction in Dungeon first, then the local port, the
kernel pieces (play authority, retirement, affordance grants), the Persona
lane, the table vocabulary, the play table, and the Eve surface. Findings
PA.f1-PA.f8; PA.f1 was already resolved at 5ff1d54.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The map, handoff, plan and Session Zero doc now name plan step 16, the play
agent, as the playtest gate. L2-L4, D1-D3 and the L1 follow-ups are
recorded as deferred by ruling, not dropped.
A source check corrected the map. Inference routes per lane by model name
to the SDK sidecar or CodexConnector, and no local transport exists. The
sidecar is a private msgpack pipe behind InferencePort, not the CultNet
connector API the map claimed every backend shares.
The handoff's session_zero.begin item is retired: the name is refused, and
only tests reference it. One evidence record covers the pivot.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The operator ruled on 2026-09-22 that the player's perception goes through
the same Projector a Persona gets, which makes the Projector the player's
narration. The play agent writes none. The turn description and invariant 8
now say so.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The operator redirected the playtest gate on 2026-09-22. Ghostlight's
controller machinery suits offline simulation, not interactive role-play.
One operational agent now runs the table; the Projector and Persona passes
stay exactly as they are.
The target records the rulings (the play authority, actor acts through the
actor's affordances, deferral of L2-L4, D1-D3 and the L1 follow-ups), eight
invariants, the redefined playtest gate, and eleven open questions for the
cut map.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The closing memory pass found four stale spots:
- The ontology still said the schemas are consumer.v3, contradicting
consumer.v5 in the same paragraph. The sentence is gone.
- Evidence record 21 said each world carries a typed detail rule, which
is L3 and not built. It now says a world will carry one.
- Evidence record 20 pointed at the design section. It now points at the
landed L1 target.
- The system map's "Current acceptance body" describes the legacy release
Yggdrasil still serves. It is now headed as pre-rebuild, so its titled
worker text no longer reads as live.
Evidence is rewritten through compact-evidence, which archives the old
text.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The stock lenses pass is closed.
- The ghostlight library ships eight lenses.
- Worlds carry weights as world data, and the owner can replace them.
- Each elaborator session draws its lens replayably and records the lens and
its instruction text.
- Sessions run concurrently under their own permit ceiling.
- In-flight work is found again by reading the store.
All eight target invariants hold.
The cut map records the second Cut 4 fix batch, Soul's final pass, Cut 5's
verdicts and the ledger's actuals. The actuals are +4,907 / −266 in crates
against about +1,300 estimated, the overrun overwhelmingly tests that caught
real defects.
Recorded as follow-ups: an Uncovered case the tests do not pin (L1.f15), and
whether consumers may supply their own lens sets (L1.f16, the operator's).
The target is rewritten as reconciled. The ontology loop no longer claims
seed requests or Vault evidence for the Active sweep, the handoff says
lens weights, and map.yaml names L2 as next.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The verification contract named creation only as step 8's `world.create` v2.
It now states the current payload, `world_create.v4`, with its required
fields including lens weights, and that Dungeon's create surface offers
uniform weights as its editable default.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
"Elaborators" states the per-sweep claim set, the caller-owned ceiling and
Dungeon's two pools, and its loop takes a demand entry, resumes an in-flight
session answering it, and otherwise draws and records a lens.
"Elaboration lenses and detail rules" says which bullets L1 implemented and
which L2 to L4 still owe. The Lenses bullet describes the live mechanism:
weights required at creation, replaced by the owner through SetLensWeights in
any phase, a draw from world id and command id, lens and instruction text on
the checkpoint, LensWeightsNeverDraw and NoCanonicalChange refusals. The stock
set is closed. The cut list drops the sequential per-jurisdiction sweep.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The operator ruled L1-Q10 option A: the in-flight listing excludes rows
ready to submit, and the crash window goes under L1.f14. The operator
also agreed to the panic handling. A session-task panic becomes an error
returned after its siblings finish, and the driver keeps running.
Quarantine stays with L1.f1.
The fix batch landed at 6f35229..0764842. Soul's second pass confirmed the
new permit guard releases exactly once on every exit path, including
cancellation, and that a panicked session is adopted cleanly. It found the
adoption rule reachable through the sweep only by ready-to-submit boundary
rows.
Findings folded into the Cut 5 pass: pin that a retryable error does not
stop the sweep, pin that Uncovered work is swept alongside a deficit, and
delete a proven-dead digest comparison. Recorded for L1.f1: a panic during
a checkpoint write would wedge the lane with only debug-level logging.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Cut 4 landed at 8538fab..3e35b3d. Soul's first pass confirmed:
- distinct claims and the permit ceiling;
- deficit adoption, with no adoption across jurisdiction, world or a
NoPatch row;
- a listing read once per sweep;
- claims taken before any await, and sweeps that cannot overlap.
Going to a fix batch:
- Cut 3's adoption rule now rests on one test;
- speak-turn pool independence is untested;
- the sweep's Active-only gate is unpinned;
- the Uncovered jurisdiction is never swept in a test;
- a panic in one session task silently kills the elaboration driver
until restart. That fix makes a task panic an error returned after its
siblings finish, and leaves quarantine handling to L1.f1.
L1-Q10 asks the operator whether the in-flight listing excludes rows
ready to submit. Soul measured both sides: including them stalls every
committed deficit forever; excluding them costs one repeated round and one
orphan in a crash window. L1.f14 records that stored rows are never
retired.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Rulings L1-Q4 (revised) and L1-Q9 (A).
Library (elaboration.rs):
- The sequential per-jurisdiction loop and step(jurisdiction) are deleted.
ElaborationOutcome loses Clean and Inactive, which nothing produces now.
- sweep(permits) takes one snapshot and returns Ok unless the world is
Active. It reads the store's in-flight listing once, builds the claim set,
and spawns one step_session per entry into a JoinSet. Each session holds a
permit from the caller's pool for its whole step.
- Every spawned session finishes before sweep returns. A quarantine-class
error is returned after that, and no session starts after one has returned
such an error. The sequential loop's early return also started no further
session. Any other error is logged at debug.
- demand_entries is the claim set. For each swept jurisdiction it takes
every covered boundary in derivation order, then the deficit if nonzero.
Each entry is matched against the listing by world, jurisdiction and
answer before anything is drawn. A match adopts the row's session and
command id; if several match, the oldest is adopted and the rest are
logged as orphans. An unmatched entry derives its id and draws its lens
(fresh_session). An answer is claimed once, and so is a command id.
- step_session(command_id, session, snapshot) is the old step body. Its
lookup and Cut 3's adoption rule are unchanged.
- step_in(jurisdiction), test-only, steps the first entry of one
jurisdiction's claim set, so the Cut 3 tests keep reading one session's
outcome.
Store: the listing now returns only ElaboratorInFlight rows. A committed
session ends in ReadyToSubmit, so listing that stage adopted a committed
deficit row, and every later sweep resubmitted it (AlreadyApplied) instead
of opening the next deficit session. That departs from the map's listing
contract.
Dungeon: elaborate_world and the ignored road test pass
state.elaboration_permits to sweep. The driver doc states that sweeps never
overlap.
Tests: 12 library tests.
- Concurrency: distinct_entries_run_at_once_under_the_ceiling,
the_sweep_never_exceeds_its_ceiling, a_sweep_holds_a_permit_while_it_infers,
one_answer_is_one_session_per_sweep.
- Claim set: a_boundary_under_nested_roots_is_claimed_once,
a_deficit_entry_is_one_per_jurisdiction_per_ancestry.
- Errors: a_retryable_fault_ends_only_its_own_session,
a_quarantine_error_is_returned_after_every_session_finishes.
- Rediscovery: a_stranded_deficit_session_is_adopted_with_its_refusal_intact,
a_boundary_session_is_repaired_after_a_commit_and_a_tick,
the_store_gains_no_orphan_per_commit, a_row_for_another_answer_is_not_adopted.
Dungeon adds saturating_one_pool_never_delays_the_other. The dead-end
fixture can now declare its commons (or commons and a ward) as a
jurisdiction root, with a subject that holds a goal, because a sweep visits
only jurisdictions that have a deficit row. The Cut 3 tests call step_in.
Docs: ghostlight-world-ontology.md states the concurrent sweep as the
shipped rule.
Counts: library 456 + 1 ignored, Dungeon 53 + 1 ignored. This commit
builds.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ruling L1-Q4: neither lane may starve the other, and the elaboration pool is
a ceiling rather than a budget.
- AppState gains elaboration_permits beside controller_permits.
controller_permits stays the simulation budget, which speak turns and
cover cells draw from.
- configured_elaboration_ceiling() reads GHOSTLIGHT_ELABORATION_MAX_CONCURRENT
at open, in the same shape as the simulation pool: default 2, minimum 1.
- The speak handler's comment now names both pools.
- The test fixture opens the second pool with TEST_ELABORATION_CEILING = 2.
- docs/architecture/ghostlight-dungeon-mvp.md names both variables and what
each pool means.
This commit builds with one warning more than its parent:
elaboration_permits is never read. The next commit passes the pool to the
elaboration sweep, and the warning goes away there.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The batch landed at f63dfd1, b3b5053 and 2c3b513 with no production
change.
- The flaky illegal-transition test failed 3 of 40 runs before and passed
120 of 120 after.
- The call-site draw is now pinned to the session's own command id across
eight multi-lens worlds.
- A resumed session is proven to keep its stored instruction text, which
was the operator's purpose for Q7.
Both mutations that previously survived, S3 and S5, now fail. Cut 4's Soul
pass reruns them in place of a separate pass on a test-only batch.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Cut 3 landed at dfb3c52..2bf8164. Soul's first pass confirms that
boundary sessions now resume after unrelated commits, that a resumed
session keeps its recorded lens across a weight change, that admission is
the same under every lens, and that the catalog and session identity are
unchanged. It also observed all three illegal transitions (lens, text,
ancestry), and a stale adopted draft is still refused by the kernel.
Going to a test-only fix batch:
- the illegal-transition test is flaky, failing roughly one run in eight;
- nothing pins that the call-site draw reads the command id;
- nothing pins that a session resumes with its stored instruction text,
which was the whole point of the Q7 ruling.
Recorded: stored text is not tied to the recorded lens (inside Q7's
accepted cost); a route cost change re-rolls a boundary session's lens and
orphans its row; the seed lane orphans rows the same way deficits do
(L1.f13). The ledger text no longer doubles "recorded".
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A new elaborator session draws its lens and authors its instruction text
once, and the checkpoint row carries both from then on. A resume reads the
row's session instead of demanding the fresh derivation equal it.
Session:
- `ElaboratorSession` gains `lens: Lens` and `instructions: String`
(`deny_unknown_fields` kept).
- `select_answer` derives the command id from world, jurisdiction and
answer digest, draws `lens::draw(snapshot.lens_weights, world, id)`, and
authors `lens.instructions()`. It returns the id with the session, and
`step` uses that id instead of deriving it a second time.
- `session_command_id` takes the three identity fields instead of a session,
because the lens is drawn from the id and so the id exists before the
session does. The derivation bytes are unchanged: the Cut 0 id
`56dbcdb2-9337-ac07-f322-37376b58cbcb` is pinned in
`a_session_identity_is_derived_from_its_answer`.
- `ELABORATION_INSTRUCTIONS` moves into `lens.rs` as a private constant.
`elaboration_request` takes the text, and `step`, `persist_repair` and
`integrity_is_valid` pass `session.instructions`. Integrity binds the
stored invocation to the stored text, not to code (L1-Q7 (a)).
Adoption rule (L1-Q9, boundary half): the whole-session supersession
equality in `step` is deleted. A found row is this answer's row when world,
jurisdiction, answer and answer digest match (`same_answer`). Its session,
including ancestry, lens and text, replaces the fresh one. A boundary session
is no longer `Superseded` forever after an unrelated commit.
`valid_elaboration_progression` is unchanged and still compares whole
sessions row to row; the doc comments on both rules say why they differ.
Store: `controller_work.v15` -> `v16`; v15 rows are refused at open, not
migrated. The world ontology doc names v16.
Tests (controllers): `a_boundary_session_resumes_after_an_unrelated_commit`
(at 1a402e1 it reported Superseded),
`a_resumed_session_keeps_its_recorded_lens_when_the_weights_change`,
`a_checkpoint_that_changes_the_lens_or_its_text_is_an_illegal_transition`,
`a_row_whose_text_and_invocation_disagree_is_refused_at_open`,
`a_controller_work_row_from_v15_is_refused_at_open`,
`soul_the_same_patch_admits_the_same_under_every_lens` (pinned to the
Cut 0 mismatch JSON), and `the_catalog_takes_no_lens`. The single-dead-end
fixture now delegates to `dead_end_mailbox(weights, dead_ends)`, which builds
the first dead end with the same handles and labels as before.
Builds, but with two "this lint expectation is unfulfilled" warnings from
the `expect(dead_code)` markers on `Lens::instructions` and `lens::draw`. The
next commit removes those markers (c1.s1.f3).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>