Four places where the gate and serving still disagreed:
- the gate applied a document write to the held document whatever path
it wrote, while serving refuses any other path; a write at another
path is now unmodelled;
- a create took the first held collection its parent value matched,
so with acme1 and %61cme1 both held a create for acme1 could land in
the encoded one; the verbatim spelling now wins, as for item calls;
- the gate accepts a 2xx JSON null as a recorded absence, but serving
answered a missing entity only with a recorded 400, 404 or 410; the
null answer is now served too;
- data/add measured only the document it was given, so one that omits
types and the state Evidence id could load under 32 MiB and grow past
it as data/get writes it back; such a document is now refused.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keying checked lines by the raw path skipped a read serving still
answers: with the list recorded at /api/orgs/%61cme1/books, a later
/api/orgs/acme1/books read names the same line through replay's decoded
fallback, so it went unchecked while serving listed the encoded
collection, and a delete it contradicted stayed served.
The gate now ranks a view's checked lines for a read as replay ranks
them for its call: every parameter the read's value verbatim or once
percent-decoded and the same query, then the most verbatim parameters,
then recorded order. A list is compared from the collection of the line
it answers from, as serving lists it, in the check, the taint checks and
the insert retry.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Five places where the gate approved a write serving would answer
differently:
- list and document reads are matched to checked lines as serving
matches calls (path and query values decoded, the query in any
order), so a reordered query no longer hides a contradiction;
- an increment or slug applies to every call, so a plan is
unexplained-change when one call changes such a field and another
leaves it as it was, in either order;
- an item read confirming a create no longer stops a later list from
choosing another insert candidate; only a list check fixes the rule;
- the gate runs serving's document body check (accepted members, JSON
types from the held and initial document), so a recorded write that
serving would refuse leaves the plan unserved;
- a served create decodes its path values from the collection the call
names, as the gate decoded the recorded path, whichever spelling the
call used.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The write gate confirmed effects the served environment would not show:
- a list check let a member the state no longer holds pass, so a
filtered list still showing a deleted entity confirmed the delete; it
now compares the whole list serving would return;
- item and list checks compared only the entity, so a wrapper member
that changed after the write (a revision, say) went unnoticed while
serving kept the base recording's; reads are now compared as the full
response rendered into the item view's or the line's base envelope;
- a later update's constant rule kept no value, so serving stored the
first observation's; each constant rule now carries the value the
call that showed it recorded, and the gate and serving read it alike;
- a redirected or unanswered write could become the example or a
modelled effect; only a 2xx write is modelled, others taint as
unmodelled writes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A refused call no longer advances the served clock, the write counter or a
sequence: values are reserved while a call is answered and committed with its
mutation, and deletes and document writes advance the clock like the others.
Updated entities cite no records, so data/get output loads back unchanged.
The gate withholds an update or delete that answers with the entity when no
initial entity holds every field its recorded answer shows, which would
answer only for entities the environment created (incomplete-entities). A
create whose template keeps a path value is tied to its collection like a
constant, and a delimited token is found after an overlapping undelimited one.
Documents write plans, the gate and served writes in the environment-state
and serving guides, the CLI help, the analysis-view contract and the bundle
README, and records the replay card the response summaries now produce.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The environment-state view now builds a write plan for every tool whose
method may change state (create, update, delete or document, by the state
type or document its path names) from its first successful recorded call:
the request body members the application stored as sent, values it generated
(identities, sequences, UUIDs, clock values in their recorded format), values
derived from the call (copies, path values, slugs, strings around a generated
id) and the recorded response's shape. It replays the capture's timeline on a
copy of the initial state, applying each modelled write and checking every
later read the served state would answer; a plan is served only when a later
read confirms it and none contradicts it. Writes it does not model leave the
entities and collections below their paths unknown until a read shows them
again, and failures they may explain are checked only on the members a write
sent. Unserved plans carry their reason.
Served from the state, the catalog adds the confirmed write tools, described
by their effect and body members. A call applies its effect atomically to the
live store and answers with a recorded status and a rendered body; refused
calls leave the state unchanged. Generated values are deterministic per state
Evidence and write count, sequences never reuse a value, and the clock starts
at the capture's end: data/reset and data/add restart them. Reads of an
entity the state does not hold answer the recorded 400, 404 or 410, and a
list line that only pages its collection and listed all of it answers calls
without query arguments from the state.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>