Address ds-review-bot v5/v6 review round 6:
- renderType tracks the active ancestor schemas by object identity (the frame
stack is the DFS path). A stateful getter can mutate the graph after
validation so a child returns an ancestor at render time; without this the
walk pushed frames forever instead of degrading. A repeated ancestor now
degrades to Any, honoring the never-throw contract; distinct nodes in a
legitimately deep chain are different objects, so it stays O(1) per push and
O(depth) memory.
- The multiline allocateClassName JSDoc was still attached to the
MAX_CLASS_NAME_BASE constant (a self-referential @link, and the function had
no doc). Move the doc onto the function and give the constant its own
one-liner.
- Tests cover the post-validation cycle and a non-object render-time child;
py-types.ts stays at 100% per-file coverage.
Address ds-review-bot v5/v6 review round 5:
- allocateClassName: keep a per-base collision counter (state.nextClassCounter)
so a deep single-field chain sharing one capped base allocates in amortized
O(1) instead of rescanning from 2 each time (Theta(depth^2) time); remove the
stale one-line JSDoc left above the multiline one and attach the doc to the
function, not the constant.
- renderType's catch rolls back the typing symbols the discarded subtree added
(not just the classes) so the import line still lists exactly the symbols the
surviving output uses; the comment now names that the same path also degrades
this module's internal-invariant throws to Any, the trade for never throwing.
- README (both languages) no longer describes an installable
dsh-code-runtime-python package: the Python renderer is built in and drives
any runtime reporting language: 'python'; the first-party backend ships
separately.
- Tests: assert the render-phase degrade on the first call, assert the import
line after rollback, and cover the collision-skip loop; py-types.ts stays at
100% per-file coverage.
Address ds-review-bot v5/v6 review round 4:
- renderType now holds the no-throw contract across the whole walk, not
just root validation: a stateful getter that passes validation and then
throws in the render phase degrades the node to Any, rolling back any
classes the call had begun emitting, instead of escaping.
- allocateClassName caps the accumulated base name. Child class names
derive from their parent's, so an unbounded single-field object chain
grew the sum of names to Theta(depth^2) (a 5000-deep schema produced a
~25MB SDK); the cap keeps total emitted text linear, the collision
counter still makes truncated bases unique.
- The language-dispatch note's Consequences first sentence and the zh
guard paragraph are corrected: two table entries (not one), and
full-width Chinese punctuation per translation-rules.md.
The index.ts JSDoc edits shifted source line numbers referenced by the
generated cordis catalog and event-producer-consumer graph. Regenerate
both so the static doc gates pass.
Address ds-review-bot v5/v6 review round 3:
- Config.mode JSDoc and the regenerated config-catalog no longer claim Code
Mode requires a TypeScript runtime; both now say a language with a
registered SDK renderer.
- The active 2026-06-15-code-mode base note (both languages) follows shipped
reality: the SDK renders the loaded runtime's language, dsh-tools accepts
any language with a renderer and run_code flavor, and it cross-links the
language-dispatch note.
- The language-dispatch note distinguishes the two Object.hasOwn guards'
reachability and documents the peekRuntime no-runtime degrade vs the
rejected silent fallback.
- SDK_RENDERERS comment: adding a language is two table entries, not one.
- py-types: document the deliberate PEP 586 deviation for float Literals;
add oneOf-object-branch tests (named union classes and context-free
degrade), keeping py-types.ts at 100% per-file coverage.
Recheck the listing cancellation signal after each child inspection settles:
a per-child read failing with a diagnostic-mapped code during an abort
previously bypassed the inspection's own checkpoints, letting a cancelled
single-child scan return a successful result.
- listChildren() checks its cancellation signal before starting the corpus
trace and immediately after it resolves, so a pre-aborted or trace-time
abort fails CANCELLED instead of returning a successful empty result.
- Corrected the persistence-repair claims: session query resolves persisted
candidates through the non-mutating inspect() read, so listing is
storage-read-only and a torn child tail is surfaced (shorter valid prefix)
rather than repaired; the Agent Note, README, and JSDoc now state that,
and the zh pair is re-recorded.
- listChildren() takes an optional AbortSignal and rechecks it after every
un-signalled session-query await (the cold-resume cooperative-cancellation
boundary); list_agents forwards exec.signal so the registry's drain of
started tool bodies cannot block on a slow or large catalog.
- The list_agents description now presents running/complete as a stored-record
snapshot and defers deliverability to send_message, matching the ownership-
conflict semantics the service tests pin.
Implements the durable-subagent-catalog RFC: SubagentControlService.listChildren()
enumerates a parent's direct continuable children from one sessionQuery trace,
validates each child's sole subagent/descriptor event (now carrying the durable
creation label), and returns one ordered SubagentListEntry[] with per-child
corrupt/unsupported/unavailable diagnostics. The list_agents tool ships as a
separately loadable plugin of dsh-tool-subagent-control requiring sessionQuery
at load; send_message stays usable without it.