Changes in 0.6.0
In development, not yet released.
tools/release/release.sh prepare 0.6.0removes this note.
Kiro
- A new adapter,
kiro-local, collects the sessions Kiro’s V3 agent engine writes under~/.kiro: kiro-cli started with--v3or withchat.agentEngineset tov3, and Kiro Crew on itskasbackend. It is on by default and needs nothing from Kiro. Measured with kiro-cli 2.28.0 and its engine@kiro/agent0.66.26, and Kiro Crew 0.7.2, over 86 sessions and 3,101 records, and with Kiro Crew 0.8.0, which bundles kiro-cli 2.27.1 and engine 0.66.22, over 13 sessions and 2,069 records. A session is read when its header names schema1.0.0; kiro-cli’s V2 sessions and V3 sessions of another schema are counted, inasz sourcesand once inasz collect, and not collected. See Kiro and the Kiro adapter. - A prompt carries no turn id in Kiro, nor does a message sent while a turn runs. Each belongs to the first turn named after it in the file, and waits to land until that turn is named, since a landed record is never written again. A prompt whose turn never starts lands with no turn once its file has been still for five minutes.
- A Kiro record’s id is the engine’s id followed by the record’s digest. The engine gives one id to an approval it asks twice, 46 ids in the measured records, and assembly would have removed the second as a copy.
- Kiro’s subagents are joined by the child’s id, which the parent’s start and end records and the
child’s own file share. A compaction is a context reset with its summary. A turn’s
elapsedTimeis its measured duration. Kiro Crew’s system prompt arrives as the first prompt of a session and is not namedsystem_prompt, because nothing in the record tells it from a person’s prompt. - Kiro records no token counts, so no token metric is derived for it. Pushed, its sessions are the
service
Kiro.
LangChain and LangGraph
- Two records that could carry a system prompt unnamed are named. An unfinished model call whose
client put the prompt among its parameters, in the
extrathat lands whole with the envelope, is namedsystem_promptby that shape, as its tools already were. A graph’s first input whose person’s message carries, as its content, an object that takes a request’s shape is named by that shape, as the LangChain page says a graph’s first input is. The test of a root function’s first input checks that record’s own flags, where it checked every record’s together. - A LangChain JS or LangGraph JS application lands as a Python one does. Its client, LangSmith JS,
writes a run’s end time as the milliseconds since the epoch, so every run it sent was refused
and nothing landed; the receiver now reads either time. It serializes every message as a
constructor whose kind is named only by the class that ends its
id, with its fields underkwargs, so a LangGraph JS conversation had no question opening it, a tool’s result landed as the serialized message, and a system message in a decorated function’s arguments landed unnamed; each of these now reads the message by its class. A decorated function carries nols_methodfrom it, and is known by the library that made the run, which both clients write. A model call inside a decorated function supplies no thread, because LangSmith JS passes the function’s metadata to none of the runs inside it, and takes the function’s, as the next entry says. Measured with LangSmith JS 0.10.8 on a LangGraph JS agent and a traced function, the two applications undertests/apps/langchain-js. Their captures sit beside the Python ones undertests/apps/langchain/testdata, and the recorder reads the chunked body that client sends. - A run that supplies no thread takes the conversation of the nearest run it ran inside whose
conversation was supplied. Its dotted order names the runs it ran inside, and the thread was
supplied there. A model call inside a LangSmith JS
traceablesupplies none, so it landed in a conversation of its own under its trace, with its answer, while the question’s conversation had no answer. A run that supplies its own key keeps it, and a trace that supplied none anywhere still lands unassigned. The conversation is decided once the run’s ancestry has arrived, so the order runs arrive in does not change it. A run above that is not known stops the search, and the run lands unassigned. A run’s own key decides from the first of its arrivals that brings one before the run lands, and once it has landed its later arrivals follow it, while the receiver remembers it. A thread an update names before the run’s project is known does not decide while the run waits, and the run neither takes a thread from above in its place nor passes one below. - A summary
SummarizationMiddlewarewrote now resets the context, as a Claude Code compaction does. The middleware marks its summary message withadditional_kwargs.lc_sourceset tosummarization. A model call sent that message starts a new epoch in its stream, with anepoch.boundaryand the message as itsepoch.summary, joined bysummarizes. The summariser’s own call stays in the epoch whose history it read. A summary is sent again with every later call, and the conversation keeps one reset for it. Nothing is inferred from how the message list changed:trim_messages, langmem andRemoveMessagewrite no mark and make no reset. A conversation landed before this keeps one epoch; the reset is taken when a request lands. - A link to a plain model call inside a tool landed with its
auxiliaryflag twice. A request is placed once to check it can land and again to land it, and the second placement built on the first. Placement now leaves the request as it arrived. - The page shows what a LangChain model call was sent. The Prompt tab read a LangChain request as
Claude Code’s shape and drew it as one empty message. It now shows each message in LangChain’s
own words,
system,human,aiandtool, with the tool calls anaimessage made and each tool result under the call it answers. A response shows the answer, the model and the token counts. What it added stays unavailable for a LangChain call, because no request names the one before it, and it now says so. It used to say the request before was not among the loaded bodies, here and for the first call of any chain, where nothing is missing. The renderer is Horizon’s, pinned at88e0110for this, which also draws a light theme’s scrollbars and other native controls light. - A landed LangChain file is named for the collected time in its header. The collector read the clock once per pass for the name and once per file for the header, so a server that stores files by session and sequence and names them from the header, as the OAP does, named them apart from asz. On a real root, all 50 LangChain files were named apart from their header, by up to 99 milliseconds, and none of the 7,185 Claude Code files was. Files landed before this keep their names, because landed files are never rewritten.
- On a LangChain conversation, the system message lands in the provider bodies, which a reader that
withholds anything is never served. The tools, sent in an out-of-band
extra, land nowhere. Two other records can hold the request: the whole run envelope a model call lands when it arrives before it has finished, and the first input of a trace whose root is a model call with no message list. Each is namedsystem_promptwhen it holds inputs of any shape, andtool_schemaswhen it offers tools or functions, nested in the client’s own configuration too. A decorated function’s own arguments and result, and a graph’s first input, are the application’s own, so they are named only by their shape: a message of thesystemordeveloperrole, a value under a key a provider takes the prompt by, or a list of tools. The shapes are listed on the LangChain page. On the captured corpus the client sends both out of band, and all 48 trace roots are chain runs, so the one record named is the arguments of the LangChain JS traced function, which hold its system message.
Claude Code
-
A headless run’s question is on the page.
claude -pand an Agent SDK application write their prompt withpromptSource: "sdk"and noorigin, and onlyorigin.kind: "human"was read as a person’s input, so the page showed each answer without the question it answered. Such a prompt is now external input that opens its talk. A session collected before this keeps the gap, because landed records are never rewritten. -
What the runtime sent the model is named. In Claude Code 2.1.259 to 2.1.286, the versions measured, and in a runtime built on the Claude Agent SDK, the transcript holds the system prompt and the tool schemas the runtime sent, in a
prompt_snapshotattachment, and the schemas of the tools it offers on demand, in adeferred_tools_record. asz landed both as injection steps with nothing saying so. A snapshot now carries thesystem_promptflag, and either attachment carriestool_schemaswhen it holds tools, by its type and keys, never by the text. The rule is on the Claude Code page. An operator who serves a conversation to the people the agent served can then withhold them by rule. Such a step never names a talk. The page shows the flags on the step. A session collected before this keeps its records as they are, because landed records are never rewritten. Collecting it into a new root names them.
MCP calls
- A call to an MCP server names its server and its tool. Claude Code calls an MCP tool
mcp__<server>__<tool>. A landed call part now carriesserverandserver_toolwhen the name splits exactly, with one__aftermcp__, and the step’sattrscarrymcp_serverandmcp_tool. A name with a second__is left whole, since the separator cannot be told apart from a name that holds it, and so is one whose underscores run together:mcp__foo___barisfooand_bar, orfoo_andbar. It used to be split as the first. A session collected before this has neither, because landed records are never rewritten. - The Claude Code plugin records each call to an MCP server. Its hooks after every
mcp__call write anexecution/1record: the server and where its configuration came from, how the call ended, the time Claude Code measured around it, and the size and SHA-256 of the arguments and of the answer, never their text. Thechangesadapter lands them as a new kind,execution. Assembly does not read them.asz.viewlists them astool_executions, and a step names its records inexecutions, joined by the tool-use id.mcp.enabled: falsein the plugin’s settings turns them off. The shapes were measured on Claude Code 2.1.282, and the real hook payloads are the plugin’s test data. asz viewdraws what the plugin recorded of each call to an MCP server. A call named by its server and tool sits on its own MCP lane, its card shows how it ended and the time measured around it, and the inspector gains an Execution tab. The Evidence tab lists each change and execution record after the step’s own positions, and shows what the document carries for the picked one: the step’s text, a call’s result on its result position, or the record itself. It used to show the step’s text under every position. The renderer is Horizon’s, pinned atc903e77for this.
The page
- A withheld step that names one empty part keeps its size of zero. It took the size of all the record’s parts, which the asz.view page reserves for a step that names no single part.
- The page refuses an address holding
;, where it dropped ahidewritten after one and asked for the whole conversation. The API refuses such a query, and now the page does before asking. - The asz.view page says that
hideignores spaces around a name and empty entries, that a run journal’s record is what names no stream, and that the withheld count is as of the last load. - A view can withhold the system prompt and the tool schemas. An operator who serves a conversation
to the people an agent served may need to keep from them what the runtime sent the model, while
the operator still sees it. asz knows nothing about who is reading. It withholds by the flags the
adapter set, never by the text or the size of a part.
view.hidein the configuration lists the flags thatasz viewandasz serverwithhold, and by default it is the whole answer: a request that carries ahideparameter is refused with status 400. Withview.hide_overrideon, ahideparameter on the document, record and files endpoints replacesview.hidefor that request, andhide=with no name withholds nothing. A host that serves the API through its own route sets it on every request, and so decides per reader. The page passes ahidein its own address on to its document, record and files calls. - A withheld step keeps its node, its flags and its size, loses its text and says
omitted.summary.withheldcounts what was withheld, and lists every name asked for, a zero included. So a filter over a root landed before the flags shows that it found nothing. For a reader that withholds anything, no call lists a provider body, and neither the files nor the record endpoint serves one. A request carries the system prompt and the tool schemas again, and a body is served whole or not at all. The rules are on the asz.view page, so a server that mirrors the format withholds the same way. - The
hideparameter spelled another way, any key whose letters alone spellhidein any case, such asHide,hide[]orhide[0], and a query that does not parse, are refused with status 400, as a name that is not a flag a reader may withhold is. Either would otherwise read as nohideat all, and the reader would be shown everything. - The files endpoint serves provider body files only. It served any landed file whole by its sequence, transcripts included, and the Prompt tab reads provider body files only. Any other file, and one whose header does not read, is refused with status 400.
- The page’s copy buttons work when the page is served over plain HTTP from an address other than
localhost. A browser gives a page the Clipboard API only on HTTPS or localhost, and without it
every copy button did nothing and said nothing. Each copy button of the Prompt tab now sits in the
title of what it copies, so the whole body and the settings copy while their section is closed.
The renderer is Horizon’s, now pinned at
e55f329(apache/skywalking-horizon-ui#190).
Collection
- A file that fails to land leaves nothing behind. Its records entered the index while it was being written, and it kept the number it took, so a failed rename left index entries for records that never landed, and a gap in the landed numbers that every later round reported as a missing file. Claude Code’s transcripts and workspace changes and Kiro’s sessions did both. Provider bodies stopped the session’s pass at the failed file, before anything was saved, and they land in the same order now. Records enter the index only once their file has landed, and a file that did not land gives its number back.
- Every landed file fits
max_delta_bytes. A collector cut a file by the bytes it read, and a record is larger than its source line by its envelope: 4 KiB of short lines landed as 19 KB. Files are now cut by what their records take once written. A single record larger than the budget lands alone, and its largest payloads are taken out, one at a time, until the file fits. A part taken out keeps its place, its kind and its identifiers, and saystoo_large, with the size of the original and the SHA-256 of what it carried in the new part fieldsha256. A part loses its data before its text, so a result whose runtime record of a written file is large keeps its readable text, and saystruncated. A change record or an execution record is never taken out whole, since a step joins to it: a change record is made smaller in its own format, its largest files losing their hunks and then its file list going, so it keeps its identity and saystruncated, as its entry in the document now says withstate. A pasted screenshot measured 4.6 MB in one transcript line, and a file that size is more than a receiver may have to store at once. A provider body is fitted by its cutter, which never takes out the manifest: a later body names a piece taken out as it names any piece, a body of short strings with nothing to take out lands whole and is taken out whole, and such a body cannot be rebuilt from the root. In the document, a step that stands on a whole record saystoo_largewhen a part of it was taken out.asz verifycounts both apart from damage, and still holds a body’s record to its manifest. See Too large to land. - One command writes to a storage root at a time.
asz collectandasz serverhold the new root lock,_root/.lock, for each pass.asz parseandasz pushhold it for their run,asz scenario buildfor each session it builds, andasz scenario checkfor each root it builds.asz repackholds the root it reads and the root it writes, and refuses a destination inside the root it reads, which every command would take for a session. Another command waits for it, and a watching pipeline does nothing that period and says so once.asz viewandasz indexonly read and take none. The LangSmith receiver is the one writer outside a pass: it only adds requests to_langsmith/, and a pass takes them under that directory’s own lock. - A session goes to one owner: the endpoint, the configured
service_nameand theservice.instance.idit was first sent under.push.staterecords it, as anownerline, before the first request carrying anything of the session goes out, so a request whose answer never came still leaves the session with its owner. After the endpoint, the service name or the instance changes, a session sent before is held. None of its files, rounds or metrics are sent, every pass says why, andasz pushexits non-zero. A receiver holds a session whole, so its later files must not go somewhere else. - A failed directory sync is reported. After the rename that publishes a landed file, a round or a state file, the directory is synced, an attempt to make the name survive a power loss as well, and a failure there was ignored without a word. It is now reported once for the directory, since a power loss may lose the newest names there; the write still succeeds, since the file is in place, which is what a process crash needs, and another process may have read it. A filesystem that cannot sync a directory at all, as some network, FUSE and container mounts cannot, reports nothing; on macOS a plain fsync is tried before a directory is called so, and on Windows none is synced.
- A source line larger than the budget lands in a file of its own. The Claude Code, Kiro and workspace change collectors read on to the end of the source to find where the long line ended, and landed every line up to the last one in the same file: one 4.6 MB line made an 8 MB file. The window now grows until it holds the line’s end, and stops growing when the source was cut short while it was read.
Retention
- A storage root no longer only grows.
storage.retention,-1and off by default, removes the landed files of a conversation that was sent and has had nothing new land for that long, such as72hor30d. On one root, 7,235 landed files of 847.5 MB had skeletons of 29.6 MB, 3.5% of them, measured on 2026-10-13.asz collectandasz serverremove at the end of a pass, after the send, the whole conversation’s files at once, and only once its head round covers them and, with metrics derived, every file of it is derived. A conversation never sent is kept. See Retention. - A provider body landed after a removal is cut exactly as with nothing removed. The cutter holds
each removed body by its skeleton, and the session’s store, under
provider/, keeps the bytes of every chain tip at a removal and of each removed piece a later body cites, so the same pieces are cited and the same tip is copied. A removal keeps the tips before it writes its intent, so a tip it cannot keep leaves the session’s collectors landing. A body’s skeleton keeps every segment of its manifest but the literal strings, so a body the session did not accept is not accepted from its skeleton either, and the index reads the same keys from it.asz verifyrebuilds every body that is not removed from them, and reads the bodies again when a removal changed the session while it read them. With every scenario run twice, once removing everything after each send, bodies under a budget too small for a piece included, every body landed as the same record. - Each removed file is replaced by a skeleton,
<name>.sk: Session Data, compressed with gzip, that keeps every record and part in its place with every identifier the index reads, and none of the content, each part sayingremoved, ortoo_largewhere it was. Its header records the file’s digest, size and record count, when and by which removal it was removed, and what the receiver confirmed of it. The index rebuilt from skeletons is the index rebuilt from the landed files, byte for byte, so a conversation that becomes active again continues the same chain. With every scenario run twice, once removing everything after each send, the receiver got the same files, rounds and metrics, byte for byte. A skeleton is never sent. See Skeletons. - A removal writes
removing.jsonfirst, then the skeletons, each synced with the error of its first sync checked, before it deletes a landed file, and only once its skeleton reads whole and records the file’s digest. The directories the deletions changed are synced before the intent goes, and the session directory after it. A crash or a power loss at any point is finished by the next pass before anything lands, and no collector lands into a session while its removal is unfinished. A skeleton takes its file’s modification time. A removed file’s metrics request goes once the receiver has it, on the first pass after it is sent while retention is on; its receipt stays, so a deriver whose state a power loss took back derives the file as before. - Every reader takes a skeleton.
asz verifychecks lines and bytes through it, binds rounds to the digest it recorded, and reports removed files apart, never as verified.asz showsays a record was removed. The page keeps what it read for the chain head and the removal generation, in the newremoval.state, so one served by another process sees a removal too. It lists a removed file withstate: removedand the size and digest it had, and draws its steps with no text and the stateremoved. A change record keeps its step, its identity, its time and each file’s path, operation and lines, with no diff, and an execution record its step, identity, time and outcome, so the page lists both in their places,removed. Metrics turned on after a removal count the tokens a skeleton keeps, and no MCP call, whose record it does not keep. LangSmith’s next position goes on from a skeleton.asz repackrefuses a session with skeletons.
Configuration
- The
viewsection is read strictly. A key it does not have is refused, where every other section ignores one, because a misspelled key there would show everything to everyone.hideis read only inside theviewsection, and written anywhere else it is ignored and withholds nothing.view.hide_override, off by default, lets a request’shideparameter replaceview.hide. Only the first YAML document of a file is read, so a file with a later one that holds anything is refused rather than read in part. The rule is on the configuration page.
Metrics
- Metrics are derived only when they will be sent:
export.otlp.endpointis set andexport.otlp.metricsis on. A root with no endpoint derived every metric on every pass and kept each request in its spool until it was sent, which was never, so the spool only grew. Such a root now derives nothing, and the pipeline’s first lines say so.asz pushderives what the root has not derived yet before it sends, under the export lock, so a root collected with no endpoint and pushed later still carries its metrics; a file it cannot derive fails the command. One derivation runs at a time over a root: two at once, of different files of one series, could each decide a window from the state as it was and send windows that overlap. A root that never derived starts with a first derivation, bounded bymetrics.lookback; one that derived before goes on from what it derived. - Metrics are one section of the configuration, for the whole root.
metrics.enabled, on by default, derives every metric from every landed file, whichever adapter landed it.metrics.lookback, 72 hours by default, bounds the first derivation over a root that already has history. The adapter keysmetricsandmetrics_lookbackare gone, and a file that still writes them has them ignored. Metrics used to be off by default, with a look-back of 24 hours. claude_code.token.usageis nowagent.token.usage, with the same description, unit, kind and labels. The family is asz’s and is meant for any agent, and a runtime’s vocabulary stops at its adapter. A receiver’s rules must read the new name.- Two new metrics count the calls to MCP servers, from the plugin’s execution records:
agent.mcp.callsandagent.mcp.duration, by server, tool, the source of the server’s configuration, outcome and query source. A server and a tool together name the target a call reached, which a receiver can treat as an endpoint of the agent. - The
claude-code-otlpreceiver is removed. Every metric asz sends is derived from the landed files, so one root has one source for each count. The exporter’s labels a transcript does not carry, such as the user and the organisation, and its other metrics, such as cost, are no longer sent. Point Claude Code’s exporter at the receiver that reads it: the SkyWalking OAP reads its cost, active time, sessions, lines of code, commits, pull requests and edit decisions, and takes the tokens from asz. A configuration that still names the adapter loads, and an enabled entry is skipped with a line that says so. The spool holds only derived requests, andspool.stateis no longer written.
Development
- The
all-kindsscenario holds a call to an MCP server, so the push to a real OpenTelemetry Collector carries anexecutionfile and the MCP metrics, and the check compares them with the root. - The first benchmark:
BenchmarkLangChainRequestsmeasures cutting every request body of one LangChain conversation, for context windows from 8K to 1M tokens, trimmed, summarised or neither.make testand CI only compile it. Its comment gives the command that runs it, the reference numbers, and the machine they come from. - A scenario’s
errorstep can name no call,error: {text, unidentified: true}, and an expectation can check the session’s title,session: {title}.all-kindschecks that a child’s meta file does not rename the conversation. - golangci-lint is v2.14.0. Go 1.27.2 writes export data version 5, which v2.13.2 cannot read, so under it lint stopped at the first package with a type-check error. CI takes the newest Go 1.27 release, so CI failed as soon as 1.27.2 came out.
- Two tests in
tests/chaincover an upgrade cut into several rounds: one losesconversation.stateafter the first round and the next parse finishes from the rounds on disk; in the other, a round written by hand removes a node and a relation, adds others and an open unresolved entry, and changes a node, and the next parse, one frame a round, adds, removes, revises and resolves until the conversation is what the evidence builds. - The verify package’s record digest field, never filled, is removed. A record’s
shais the digest of its source bytes, which the storage root does not hold, so only each file’s closing digest and each provider body’s digest can be checked, and both are. - A scenario’s tool result and queued message can be padded,
result: {text, pad}andqueued: {text, pad}, to carry more than a landed file’s budget without spelling it out. An expectation counts the document’s steps by content state,view: {states}, and its change records by theirs,view: {change_states}. A new property,files_fit_the_budget, holds every landed file of every scenario to the budget.parts_keep_source_byteschecks that a part taken out names the digest of a value of its source record, and rebuilds a provider body that took a piece out from the file the runtime wrote, andrecords_matchcompares the size and digest of a part taken out or shrunk across the two formats. Thetoo-largescenario returns a 40,000-byte result, queues a 30,000-byte message, and writes two 30,000-byte files, one through a shell command the plugin observes and one through the runtime’s own Write tool, under a 16 KiB budget. The scenario’s Session Data writer now gives an editing tool’s result the runtime’s own record of it as data, as the adapter lands it; it gave such a result the shell’s shape before.
Conversation model
-
Model output whose record names no provider call is a step of its run. It was in no node at all, because only a call held text and reasoning. No Claude Code or LangChain record lacks the call; every Kiro record does, since Kiro ties no record to a request. Grouping such output into calls by turn or by record would draw boundaries the runtime never recorded, so no
llm.callis written for it. The scenariooutput-without-callholds it. -
A sidecar of the
mainstream names the conversation: its label is the session’s title, as a title record’s is. A sidecar used to name only the stream it described. Kiro keeps a session’s title in its header, which lands as the main stream’sagent_meta. -
control.noticeis inmodel.Vocabulary, the list every glossary is checked against. It was the one kind the model emits that the list left out, so a glossary could miss it with no test failing, and the Kiro and LangSmith glossaries did. -
A stream whose first record is a reset now has one epoch, opened by that reset. It used to get an empty epoch before the reset, with the reset’s own id, so one epoch replaced the other and followed itself. No Claude Code stream starts with a reset. A LangChain agent whose first model call was sent a summary does.
-
A stream a call started now leads back to it. A sub-agent does a task and hands the result back, and the model recorded the way in,
starts, with nothing for the way out, so every child read as a dead end. A child’sagent.output, and an auxiliary stream’s last model call, now have aresult_ofrelation to the call that started the stream, with the result that call received as its evidence, and the child’sreturned_valueis observed where it said unavailable. It is written only when it is exact: one call started the stream directly, and its result is its own and not the acknowledgement of a background launch. A background child keeps its way back through the notification,reports, and a child that never came back has noresult_of. LangChain’s nested agents and Claude Code’s synchronous returns gain it; nothing is re-landed, and the next round of an existing conversation adds it. -
The document lists what happened in the order it happened, never by id: a stream’s
opened_by, a step’sedgesand therelationslist by the position of their records inside one stream or run, and by time across streams; workspace changes and tool executions of one time by where each was read. A workflow launch listed the streams it started by the hash in their ids; on real data, 130 of 150 steps that started several streams led with a different stream than their run’s first. A stream’s origins had been listed in the order a Go map gave them, so the document changed from one read to the next: on a real conversation whose stream had three, five reads gave three orders. -
On one record, a node on the whole record comes before the nodes on its parts, and those follow their block. The two used to be decided by id, which made a cycle, so a sort could return the siblings in any order from one read to the next. The OAP already ordered them this way.
-
The page reads a record’s time only up to the first line of a file that does not decode, as Session Data says a reader stops there; it read the times of the records after it. Reading them now decodes each record, which on a 142 MB session takes about 0.25 s more. A file’s first and last time, and a node’s, keep a time before 1970, which the last time used to lose, and no longer depend on the order Go gives a map when a record is at exactly 1970-01-01T00:00:00Z.
-
Segments are activity windows only. A segment node carries no attributes: its talks are its
in_segmentrelations, and its time range is theirs.state,gates_unmetandcommittableare gone, with the four gates that set them. A round carries no clock, so the last window of every session stayedopenfor ever, even in a session quiet for weeks, and nothing committed a segment or read its state. Inasz.viewa segment keepsid,talks,fromandto; whether the last one is still going is for a reader, who knows the time. -
A round no longer repeats what it says elsewhere. Gone from the nodes: the session’s
conversation, which the header names, andtitle_from; an epoch’srecords; a talk’sloopsandruns, which its runs are; a talk’s and a run’strigger(on the main stream a talk’s first run is external and every later run a notification, and a child’s talk is unknown); a call’sfragments, which itsrefsare; and a tool’sname, which its call part carries. A provider body’s manifest no longer repeats a request’srun, which is the record’s own, orwhy, which is the text of the part that holds the body whole. The fixture conversation’s round is 6% smaller. The header’sbash_runsis counted as before, from the tool calls assembly made. -
The next round of an existing conversation revises each session, segment, epoch, talk, run, call and tool node once, without the dropped keys. Nothing is landed again, and the parser and policy stay the same.
-
Revisions that need no new evidence go first, cut to the round budget by their frames. A round cannot be narrowed below one landed file, so on a long conversation an upgrade’s revisions made one round past
max_round_bytes: 12.5 MB for 35,434 nodes on a 17 MB chain, more than the 10 MiB one write may be in a BanyanDB cluster. They are now rounds of their own over no new file, six of at most 2 MiB there, and the round of the new evidence follows. -
The Claude Code provider adapter extends only an index that agrees with its saved state, as the other adapters do. A pass that wrote the index and stopped before saving its state made the next pass index the same files a second time, out of landed order.
-
A round cut by
max_round_bytesreads nothing past its watermark, not even through a lookup. Finding the record a reset continues from, or the run a record’s parents lead to, could reach records past the round’sthrough_seq, so the round could hold structure its own header and input digest did not cover. Assembly now works on the index as it stood at the watermark.
Release
- The
pypiskill says what a release manager sets up before an upload. PyPI requires two-factor authentication. The upload that creates a project needs a token scoped to the whole account. Every later upload uses a token scoped to the project. The token is read fromSW_PYPI_TOKEN, exported before Claude Code starts. - The
pypiskill downloads from downloads.apache.org first, because archive.apache.org still had no 0.5.0 fifteen minutes after the move. It verifies withgpgv, which leaves the user’s keyring alone. After the upload, it checks that PyPI holds the files it built. - The text
publishwrites for the GitHub release says the downloads page links the source package and the binary archives. It said each package, and the page does not list the Debian packages. - The release guide lets
--remove-oldgo ahead without a Scoop bucket when the project has none, and asks that archive.apache.org holds each version before it is removed. - The
homebrewskill no longer runsgit rminside the temporary tap, where git stops the check wheneverasz.rbmoves. Its template fits 0.5.0 and later only. - The
aptskill installs every older version in the index through the redirects, not only the versions added. Adding a version moves the one that was newest to the archive, so its redirect changes too.
Documentation
- Session Data and Session Flow say a reader may refuse a line that holds more than 256 objects and lists open at once, as the OAP does. The deepest real line measured holds 16.
- asz.view said the document carries no RFC 3339 strings. A workspace
change and a tool execution keep their record’s
timeas that string, and the page now says so. It also says how siblings on one record are ordered. Session Data and OpenTelemetry export listexecutionamong the kinds a file can have. - The format pages state every rule a reader needs to build the same document, so a reader in any
language follows the pages and never asz’s code. Session Data
gives the type of every record and part field, what a reader does with a line of another type, and
how times are written and compared. Session Flow says that ids and
attrskeys sort in code point order, and when a call’sprovider_bodiesmakes a round unreadable. asz.view says that times round down to the millisecond, thatattrsand data are as written, what white space is, which record gives a call its result, and how deep a tree is written. - The Claude Code adapter page said a
claude_code.tool.executionspan from Claude Code’s OpenTelemetry export supplies a tool’s execution time. asz keeps nothing of that export, and no such span was measured, so the page now says the export may carry it and that this is unmeasured. For a call to an MCP server, the plugin’s execution record carries the measured time. source_rootofclaude-code-localwas described as the directory Claude Code keeps its files in,~/.claude. It is theprojectsdirectory inside it, which is what the collector reads and what the container image page sets. Set to~/.claude, the collector found no sessions.- The setup pages no longer carry upgrade guides from one version to another. The steps for upgrading from 0.4.0, and the notes about the names 0.5.0 replaced, are gone. The changelog of 0.5.0 still lists every rename. Each way to install still says how to move to a newer version, and the Claude Code plugin keeps its upgrade steps, whose order keeps the plugin’s data.
- LangChain and LangGraph said a LangChain conversation has no context
reset. A summary that
SummarizationMiddlewaremarked now resets it. - The LangChain plugin’s README, which is its page on PyPI, says the plugin needs
asz-changesand atools.scopenaming the application’s tools. It links the documentation of the released version. - The contributing guide and the docs index pointed to this repository’s issues, which are turned off. They now point to the SkyWalking issue tracker, which the SkyWalking projects share.
- The Claude Code adapter page said the system prompt and the tool schemas are absent from transcripts. That holds for the versions it was measured on, 2.1.220 to 2.1.251, and the page now says so. Later versions write them in two attachments, which the adapter names.