design/revertible-effects and design/context-model carry real TeX that was
showing as literal $$ source. markdown: { math: true } enables
markdown-it-mathjax3; pinned ^4.3.2 deliberately — v5 injects a <style> tag
per formula (31 on one page), which Vue's template compiler rejects, so v5
cannot work under VitePress; v4 emits pure SVG (probed: 0 style tags).
The generated API pages put each member at h3 under an h2 group; default
outline depth (h2 only) hid them, leaving e.g. the Context page outline with a
single 'Static members' entry.
scripts/gen-website-api.ts renders website/zh-CN/api/{cordis,harness}/* and the
api-sidebar.json fragment the VitePress config imports, so pages and navigation
can never drift from the code: signatures, @param/@returns prose, dispatch
modes, and GitHub source links are extracted, never transcribed, and the
generator hard-errors on any rendered member missing docs. verify-website-api
(doc-sync + run-gates) is the freshness gate.
Replaces the hand-written zh api pages (7 pages covering 7 of 15 services,
with phantom APIs: Context.current/Context.events, agent/post-step, tool/call,
compact/*, llm/pre-request none of which exist) with generated English
references: 5 cordis pages, 15 per-service pages, and a 35-event catalog
grouped by scope. The hand-written hub api/index.md stays and now indexes the
full surface; zh for these pages arrives with the unified translation flow.
New doc-sync gate verify-website-yaml: each ```yaml block under
website/zh-CN (api/ excluded — generator-owned) must parse with the loader's
real schema (JSON_SCHEMA + !!js), use only EntryOptions keys, name only real
workspace packages, and pass only config keys the plugin's declared Config
type / schemastery schema accepts (collectConfigCatalog drives the key sets).
```yaml ignore-check opts out a deliberate-placeholder block (the
capability-trio tutorial keeps its fictional package names).
Comment-only enrichment across cordis/src/*.ts — Context, EventsService (+ the
ctx merges), Fiber, RegistryService, ReflectService, Service, logger — so the
website API generator can render a complete reference and hard-error on any
future undocumented member (vendor sync included). Logged as local
modification 6 in vendor/README.md; retire it when upstreamed to the fork.
INHERITED_SERVICES/EVENTS source pointers refreshed for the shifted lines;
cordis catalogs regenerated.
- website joins the pnpm workspace; root scripts website:dev/website:build;
run-gates gains a website-build gate (ci-primary + ci-static) — the
VitePress build doubles as the site's dead-link check; AGENTS.md documents
the commands.
- doc-typecheck + verify-type-equiv now scan website/zh-CN/**/*.md; every
```typescript fence converted to ```ts and made standalone-compilable
(55 compiled, 1 ignore-check). Phantom APIs the compiler caught are fixed:
invented event names (agent/turn-end, tool/call, llm/pre-request, ready,
dispose) replaced with real catalog events or per-plugin declare-module
merges; presentCall/inject/Config claims corrected to the real shapes.
- guide/config.md entry-fields table completed against loader EntryOptions;
its coding-agent example brought in line with examples/coding-agent.
Introduce packages/loop as a capability seam covering goal-based (and
naturally proactive) loops around the existing agent-loop, deferring
time-based scheduling to a future dsh-schedule RFC. Four cordis service
seams — loop-as-session, pluggable Evaluator/Budget with EvaluatorSpec
tiers and protectedPaths, RoundHandoff, GoalReflector — plus a driver-
enforced Default-FAIL contract and reuse of packages/fs policy gate for
reward-hacking defense. Bilingual pair.
Fold automatic.ts into BasicCompactService as a private
_registerAutomaticCompaction method, removing the AutomaticCompactor
structural interface the standalone module needed to avoid an import
cycle. Listener behavior is unchanged; compactIfNeeded stays
dynamically dispatched so subclass overrides are honored at event time.
Fix the executable-resolution lifecycle contradiction to match the
shipped implementation: the executable resolves eagerly at load
(failing before registration if unavailable), while the server process
launch stays lazy until the first query. Align both language versions.
Correct two zh counterpart divergences: drop the "only" condition the
Chinese text added to the English "behave best" source modality, and
apply binding terminology (包(package)/包, transcript(文本记录)).
Final review pass on the local provider:
- Tear the instance down when `initialize` REJECTS (utf-8 negotiation, malformed
result), not only on abort, so a permanently-rejecting `ready` is never pooled.
- Use the group-aware SIGKILL on a framing failure so helpers are reached.
- Validate maxMessageBytes and maxDocumentBytes positive at load alongside the
other byte caps.
- Fix the location renderer's outside-workspace check to match a `..` segment
exactly, so an in-workspace path like `..generated/a.ts` stays relative.
- Document the accepted ancestor-directory symlink-swap TOCTOU under the
trusted-host model (O_NOFOLLOW guards only the final component).
Further lifecycle/safety hardening of the local provider:
- Tear the instance down when the initialize handshake is aborted, so a
poisoned pending `ready` can't make later queries for that workspace re-wait.
- Make the serialized-queue wait itself abortable, so a query blocked behind
hung earlier work can still observe its own timeout.
- Spawn the server detached and signal the whole process group on teardown, so
helper processes (e.g. tsserver) can't outlive dispose().
- Open the source with O_NOFOLLOW and cap the read at maxDocumentBytes+1, closing
the symlink-swap and concurrent-grow windows the fd-based read left open.
- Honor an already-aborted signal before any host I/O or startup.
- Validate maxStderrBytes positive at load; surface the retained stderr tail in
the "language server exited" error so a fatal startup diagnostic is visible.