The run ledger is the one owner of what a run began as: its cap and the
world id and state digest it started from. Replay takes the store, the run
and a restored world and refuses a different world up front with a typed
error naming the field. Restores the decode checks the ledger rules do not
imply, makes the replay key an exhaustive destructure, and pins the
over-bound edge. Not yet built or tested at this commit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A record with a run id that is no key segment has no readable ledger, and a
record at sequence zero fails the density rule at open; the two decode_row
conditions were equivalent mutants (cargo-mutants missed both). Builds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two reserve mutants timed out because the test spun waiting for a call a
mutant had refused. The wait is now bounded and fails. Builds: yes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The in-memory run tally no longer counts rows (only open used it); the store
test pins a record whose run id is not a key segment; the lend_tool_results
forwarding has a test; the in-flight test fails by timeout instead of hanging
when a held call is let through. Builds: yes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ProviderCallRecord (ghostlight.verse_provider_call.v1) keyed (run id, sequence),
CallRecordStore over an owned redb CultCache file, RecordingInferencePort
(bound check before the call, real usage charged after, record written before
the output returns) and ReplayInferencePort. InferenceFaultClass gains
BudgetExhausted. Not yet compiled or run: this commit may not build.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follow-up hosted-key-del-pin: a mutant allowing DEL survived the key-shape
test. The case list gains an interior DEL. Builds: yes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds hosted_binding_refuses_a_key_shape_that_cannot_ride_a_header (interior
newline, CR, tab, NUL, leading space, trailing space, non-ASCII, leading
newline; typed refusal at open, no key or path echoed) and the missing
prompt_tokens half of the usage-absence test. Builds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
key-shape-late-fault: the key must be one run of visible ASCII after the trailing
newline is stripped; an interior newline, whitespace, control or non-ASCII byte
is refused at open with HostedKeyUnreadable, which names no value.
null-count-widened: a present-but-null prompt or completion count fails to
decode (BadReply, integrity violation) on both lanes as the local lane did
before the cut; only an absent count or absent usage is a typed absence.
Builds: yes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
InferenceOutput gained a persisted usage field without a version bump, so a v17
row written before the cut was refused at open as not canonical. Rows now bump
to v18 the way the v16 -> v17 bump did: the earlier version is refused at open
with the store's named fault, not migrated; the recipe slot, its drift check and
the ontology doc move with it. The earlier-version refusal test now pins v17.
Builds: yes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The empty, newline-only and padded key cases all pointed at one file that the
last write replaced, so the production empty-key check was never exercised
(cargo-mutants survivor 544:23).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The OpenAI-compatible port gains a hosted binding (https endpoint, bearer key
read once from a file); InferenceOutput carries Option<TokenUsage>.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seed_vault_root_from becomes seed_vault_root_from_environment(lookup): the
only place naming GHOSTLIGHT_SEED_VAULT_ROOT. Open passes std::env::var_os.
A test pins that the root comes from that variable only. The comment at the
bridge test's no-world.seed assertion names AppState.seed_vault_root.
README notes the root is read once at startup. Builds: all.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Captured by running the drift test's own create/approve/activate/play walk
with a temporary, uncommitted patch that writes the regenerated intents
instead of comparing them (vendor/eve at 672c0c1). Only idempotencyKey and
issuedAt differ from the previous file; the drift test normalizes both.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Joining the thread from the test body starved the world mailbox's owner task
and hung the test; spawn_blocking leaves the runtime free. Ignored test,
verified on Starfire.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A second PlayTable over the same store cannot open while the first is alive
(the store takes an exclusive lock), so the first leg now runs on its own
runtime and dies with it, as a crashed process would. Does not run on the
stopgap (ignored test); verified on Starfire.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The previous commit does not compile (E0505 in the ignored bridge test's
closure); this one fixes it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- AppState carries the seed vault root, read once at open through
seed_vault_root_from (blank or whitespace is no configuration); tests no
longer set or remove the environment variable.
- world.create treats a cleared persona or agent label as none, at the one
place the payload becomes the kernel's intent.
- The real-client bridge test types text to open a turn, restarts over the
same store, and continues the Running turn with an untouched Play box.
Builds. Bridge tests are ignored and run separately on Starfire.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The previous commit's walk expected acceptance; with no running turn the table refuses an empty opening, which is the proof the payload arrived. Builds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
world.play.text carries an authored value "" so the lowering sends text "" for a box left untouched. seed_vault_root() is the one reader of GHOSTLIGHT_SEED_VAULT_ROOT; the surface offers the seed controls, card and descriptor only when it answers, and seed_once reads its root through it. The committed bridge fixture drops its world.seed step, which the real client can no longer produce on an unconfigured server.
Not yet compiled when committed; verification follows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The shared faulted-turn assertion now takes the expected class and checks the
warn line carries it (Connect, Timeout, BadReply, Status(404), Status(502)),
with the endpoint and reply canaries still absent. Not yet built or tested at
this commit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
close_with_fault now takes a TurnFault (detail plus InferenceFaultClass) and
logs the class beside the fixed detail, so a 404 and a 502 read differently
again. absorb_or_close hands the fault's class through; every non-inference
caller is Unclassified. The &'static str comment now says what it does and
does not guarantee (Box::leak defeats it; the per-port canary tests are the
backstop). Not yet built or tested at this commit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SidecarLinkError::Spawn and Codec held error text that the fault type now
refuses, leaving two never-read payloads; they are unit variants.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The previous commit (29efabe) does not build: a string literal in the new
malformed-reply test was mis-escaped.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
InferenceFault.detail is a &'static str, so no inference port (local,
connector, SDK) can put an endpoint, request or reply text into a fault. The
connector and SDK details that were built from error text are now fixed per
kind or reason. LocalBinding loses its public response_timeout field; the
short timeout the PlayTable canary needs comes from open_local_port_with_timeout,
which exists only under the ghostlight test-support feature (a dungeon
dev-dependency feature), so a release has one timeout, RESPONSE_TIMEOUT.
Canary tests on the malformed-body path (port and PlayTable), on the SDK and
connector ports, and on the default timeout at both resolving sites.
Not yet built or tested at this commit.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
reqwest's json() reports a body cut mid-stream as a decode error, so the
is_decode branch in send_fault misclassed it BadReply. The body is now read
with bytes() through send_fault (timeout / connect / no complete reply), and
only a whole body that fails serde_json is classed by bad_reply().
Not yet built at this commit; verified by the following job.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- send_fault now classifies the reply-body read too: a body-read timeout is
Timeout, a body cut mid-stream is NoResponse (retryable), a whole body that
does not decode stays BadReply. The response.json() map_err is gone.
- LocalBinding.response_timeout (None = RESPONSE_TIMEOUT) lets a test reach the
timeout path through the full PlayTable path.
- Tests: stalled, cut and malformed bodies against loopback listeners; a
timeout canary at the port and through PlayTable (stored fault, warn line,
card row, Debug); a PlayTable turn that survives N empty replies and faults
past ROUND_RETRY_BUDGET.
- Comments: CREATE_BINDINGS doc reattached, backoff comments state the curve,
close_with_fault no longer claims "endpoint-free by construction".
Not yet built or tested at this commit; verified by the following job.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The table mints the turn id, so the log assertion must read it from the stored turn, not the id the caller passed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
R3: every local send that fails before a status arrives is Retryable except a timeout; the fault carries a typed InferenceFaultClass (Connect, NoResponse, Timeout, Status, BadReply) and a detail without the request URL.
R1: PlayTurnView.fault and a fixed world.play.fault card row.
R2: close_with_fault logs the turn id and the (endpoint-free) detail at warn.
R4: backoff cap 20 s, shift clamp 8: the retry budget now spans about 105 s.
Not yet built or run when committed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ontology:103 lists all three FactStanding variants (patch.rs:298); the Eve
table gains app.auth.logout (eve.rs operation_schema, 9 ids); mvp:466 names
the three RoutedInferencePort routes (sdk_inference.rs:700).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
VerificationUnavailable now carries an error class and never the fetch error,
whose text named the key-set URL. fetch_jwks returns the reqwest error so the
class is read from it, not from a string. run_refresh_loop loses its period
parameter: SESSION_REFRESH_PERIOD is decided in one place and a paused-clock
test observes it exactly and over twelve ticks.
Tests drive HeimdallClient::verify_access against a loopback issuer that
counts fetches (cache stored, read, ttl 299 s fresh and 301 s stale), a closed
port and a 503 (kept session and receipt, no URL in the error or the log line),
and nine wrong-algorithm tokens. The moved-session test also pins that the
newer claim is the one spent next.
Builds and passes under ygg-verify (28 of 28 in heimdall:: and refresh_loop_tests).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ComponentOp has 34 variants (table rewritten), Precondition 9, ActionMismatch
26, FactStanding 3, EdgeKind 1; CausalBoundary field shapes, PatchAnswer,
and the live state/commit/controller-work schema generations follow the
code. The consumer page lists the ops a confined consumer is refused. The
smoke note points at the Idunn acceptance step instead of the historical
play-agent page.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CommandBody has seven variants, WorldPhase two, EdgeKind one, WorldState
a fixed field set; the page now lists those and marks membership, contract,
archive and general relations as unbuilt. Persistence rows and WorldCommit
fields match journal.rs and lib.rs. The play-agent gate citation points at
the Idunn recipe's acceptance step.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ontology: drop the two citations of deleted pre-rebuild pages; Session Zero is
named as an unbuilt consumer. mvp: bounded co-op and the archived phase are
marked design intent, since crates/ has neither.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The README no longer calls unbuilt or historical pages current design records:
play-agent is historical, session-zero is unbuilt, public-architecture and
articles are unbuilt design and essays, extraction and stock-lenses are closed
records. The authority architecture page loses its citation of a deleted file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README and AGENTS.md state what exists (sealed kernel, Dungeon, persona
projection, sidecar, browser host) and what does not (the verse, storylets,
cast, episodes). The handoff becomes a pointer to the Eureka mind. The Eve
interface page matches eve.rs (world.create v4, Draft/Active cards, play
card). Live pages cite crates/ghostlight/src/<file> instead of world/*.rs.
The implementation plan gains a historical status line.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The refresh pass keeps a spent-upstream receipt when verification could not
fetch the signing keys and verifies it on the next pass instead of refreshing
again; only a positive verification failure revokes. The loop body is
run_refresh_loop, tested for calling the pass; tests pin that a moved session
is not revoked and a higher revision is applied.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A JWKS fetch failure is now VerificationUnavailable, distinct from a receipt that
positively fails verification. The fetched key set is cached for five minutes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Removes state:*, prestate:*, *:validate, schema:validate, images:count and
coverage:status (they called the deleted Python tools); keeps dungeon:* and
sdk:*. Description now names the Rust kernel and Dungeon. Drops .gitignore
lines for __pycache__, *.pyc, .venv, state scratch and experiments/images.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Parked at tag parked/ghostlight-pre-rebuild (ruling ghostlight-verse:ruling:park-pre-rebuild-tree).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>