trim and escape commute for every input, so the new whitespace test does
not pin their order: UNPRINTABLE and LONE_SURROGATE are disjoint from the
set trim() strips, and both escapes emit plain non-whitespace ASCII,
leaving the leading and trailing whitespace runs byte-identical. State that instead of the false causal clause.
pyScalar's Literal path escapes nothing itself -- JSON.stringify is what
keeps it parseable, covering NUL and, under ES2019 well-formed
stringification, unpaired surrogates. Record the dependency and turn it
into a checked invariant. Pin the docstring emission site for a lone
surrogate too, mirroring the NUL case.
Two docstring corrections: describe's caller enumeration omitted the
synthetic { description } wrapper docLines builds, and "special in
statement position" does not describe `_`, which is special in a match
pattern. Both keep the conclusion they support.
Note which of the two table guards fires depends on the entry point.
U+00AD is 0xAD, so "Cf cannot be addressed by \xNN" was false for the
first example in its own list. The real boundary is the category: one
\xNN form covers Cc exactly, and escaping the single addressable Cf
member would leave a rule that is neither category- nor
addressability-shaped.
A lone surrogate is the NUL case rather than the invisible-character
case -- Python source must be UTF-8-encodable, and compile() raises
UnicodeEncodeError for one in a string literal or a # comment alike
(measured on 3.9). JSON.parse on a wire "\ud800" escape produces them,
so escape them as \uNNNN; the regex's u flag keeps well-formed astral
pairs intact.
Pin the whitespace-plus-surviving-control boundary, which also pins
trim-after-escape.
Unicode Cc is U+0000-U+001F plus U+007F-U+009F, and no C1 code point is
ECMAScript whitespace, so U+0080-U+009F all survived the collapse and
reached the docstring raw and invisible -- the gap the previous commit
closed for NEL alone. \xNN addresses the whole block, which is the same
reason the set stops at Cc, so widen the class to U+009F and pin
U+009B/U+009C/U+009F.
Windows-1252 bytes 0x80-0x9F decoded as Latin-1 produce exactly these.
Also: required TypedDict fields share the optional fields' listDepth
start, and a description of whitespace plus a surviving control
character is not absent.
The static-stub sentence over-generalized: `tools` and `ToolCallError`
ARE bound at run time, and a model reading "everything below is a stub"
could stop catching `ToolCallError`. State the boundary and pin both
halves in the fixed-instruction assertions.
UNPRINTABLE missed U+0085: it is Cc but not ECMAScript whitespace, so
it survived the collapse and reached the docstring raw and invisible.
Add it and scope the docstring to Cc, since the `\xNN` escape cannot
address the Cf formatting characters that pass through by design.
Record the backend PR's two runtime contracts -- inject only `tools`
and `ToolCallError`, and bind the assembly-time language to the
request -- in the Agent Note and at requireCodeRuntime.
A TypedDict reads as a constructible class, so a model that writes
FooArgs(field=1) fails with NameError before dispatch: the run request
injects only the tools namespace and ToolCallError. Say so in
SDK_INSTRUCTIONS and require plain dict/list JSON arguments. The TS
flavor needs no counterpart -- interface is visibly a type and its
"runs type-stripped" clause already covers erasure.
The list-nesting cap guards against a tokenizer SyntaxError, which makes the
text not Python. A long `A | B | …` union is valid at any length and only
defeats CPython's compile-time C recursion (measured: 1,000 branches compile,
5,000 raise RecursionError); nothing compiles this block, and capping would
retire the deep-chain tests pinning the walk's linear time. Records that
boundary at the `oneOf` arm and in the Agent Note (both languages).
Also documents that the context-free degrade marker reads the call's
className rather than the frame's — frames propagate a derived name, so a
per-frame read would declare classes the caller cannot receive — and pins
that path with oneOf-of-objects and array-of-oneOf assertions.
A schema nesting arrays past ~200 levels rendered a `list[list[...]]` chain
CPython's tokenizer rejects outright (`too many nested parentheses`), so the
SDK block was not valid Python at all — the failure docstring escaping in the
same file already guards against. The chain now degrades to `Any` at 180
levels; nesting restarts per TypedDict field, since a field annotation is its
own logical line. Unions and nested objects are unaffected: neither
accumulates open brackets.
Also aligns the unreachable SDK_RENDERERS guard message with the two reachable
ones, and corrects a test comment that still said class docstring.
A description was emitted above the `async def`, where Python treats the
first string as the `Tools` class docstring and every later one as a dead
expression — leaving each method undocumented in the model's only source of
tool semantics. Emit it as the first statement of the method body instead.
Also names the known languages in the run_code flavor guard (the reachable
rejection, symmetric with the SDK_RENDERERS guard) and corrects three doc
claims: the code-runtime group README no longer calls the generated SDK
TypeScript, the base Code Mode note states its serial dispatch in past
tense, and the tools README points at the rationale the language-dispatch
note actually carries.
The rewritten scheduler paragraph states that the native loop already
classifies through isConcurrencySafe, which contradicted two surviving
present-tense claims that parallel native dispatch is an open TODO
blocked on that same metadata. Both now attribute the TODO to decision
time and point at the shipped rolling pool.
The Python renderer partitioned identifier methods ahead of subscript
comments, so a tool set like {a-tool, z} emitted z first — contradicting
the documented lexicographic contract and the TypeScript flavor, which
quotes exotic keys in place. Interleave both kinds in one ordered stream
and track emitted statements for the pass fallback.
Also correct four stale serialization claims in the base Code Mode note
that the live-parallel scheduler superseded.
- docs: fix cross-class note links (../feature/...), mirror the membership
reuse criterion in README.zh.md and the connectWorkspace architecture
note (EN/ZH/sidecars re-recorded)
- test(client): stray + member blank at the same path — the scan skips the
stray and reuses the member
- test(web): re-registration after delete now mints a fresh blank session
(the old cwd-only reuse is gone), so the account is no longer empty;
assert the retained seeded session is still not re-adopted