Node's built-in fetch ignores HTTP_PROXY, so every harness request connected
directly regardless of what the user exported. Resolve one policy from the
launch environment and install it as undici's global dispatcher, then wire the
four surfaces a global dispatcher cannot reach: web_fetch's pinned transport,
the OTLP exporter's node:http agent, the E2B SDK's own proxy option, and the
environment a child process or worker thread is given.
Each outbound call site carries an egress test that drives its real code path
through a fake proxy; that measurement is what found the OTLP and E2B gaps.
Each index route also emits a parent-level alias twin, projected over
the alias route so its relative links stay correct; llms.txt and the
docs now state the drop-trailing-slash convention exactly. Frontmatter
failures name their page, the twin pass refuses to overwrite existing
build files, the dev middleware documents the deliberate in-page
fetch() divergence, and the per-locale collection order moves to one
shared export. Refs #2846.
Append .md to any published route for the page as plain Markdown: the
build emits a raw-Markdown twin of every route (frontmatter dropped,
home bodies kept, images beside pages) plus a manifest-generated
llms.txt, the dev server serves both per request, and the post-build
gate fails when either is missing. Fixes#2846.
A plugin that registered a settings namespace could not reach the browser
configuration page: the api-proxy filtered every read and gated every
write through two hardcoded namespace lists, and the plugin configuration
section rendered an unordered list of cards carrying an opaque id rather
than the namespace they edit. Both gates lived in this repository, so a
user-authored plugin was configurable only by hand-editing settings.yaml.
The proxy now serves whatever ctx.settings.describe() returns and adds no
boundary of its own; a name no registration answers folds into the seam's
own settings-rejected, and the settings-not-exposed code retires. The
settings seam is untouched: which client may read a namespace, and which
page renders it, are facts about consumers.
settings.plugin.item becomes a keyed slot whose key is the namespace a
card edits, following tool.call.toolview. The section reads describe once
and dispatches the intersection of the slot ledger and the served set, so
a namespace another surface owns renders nothing without declaring
anything, and a card for an uncomposed plugin is never dispatched.
The navigation bar named `/guide/` while the manifest published the guide's
first page at `guide/quickstart.md`, so the item served a 404 in both locales.
`landingLink` resolves each item against `orderedPages`, the ordering the
sidebar already renders, and a test asserts every navigation target is a route
the manifest publishes.
The VitePress config declared no position for the subsystem or other-interface
sections, so `indexOf` returned -1 and sorted them ahead of every declared
group: the reference landing page's own sidebar entry sat 1549px below the
fold. Four subsystem pages also shared `order` values with pages in the same
section, resolved only by sort stability and array concatenation order.
Section placement and collapse move into the manifest as a per-locale
declaration, and `sectionSpec` throws for an undeclared section instead of
sorting it silently to the top. Subsystem pages are grouped by concern, the
six topical groups collapse until one holds the page being read, and page
order derives from array position.
The projector drops the language-switcher line and repository badge the
canonical pages carry for their GitHub readers. The navigation bar gains the
DeepSeek wordmark, a release-stage tag, and a favicon; the sidebar scrollbar
rests invisible and appears while scrolling. Subsystem pages carry a two-level
outline, and the two plugin-development tracks now cross-link.
core.md claimed to be the packages/core reference but opened on repo-wide type patterns and never documented the ownership vocabulary: AgentHandle, CreateAgentOptions, ResumeAgentOptions, and AgentFactory were TYPE_LINK_EXEMPTIONS pointing at a package README, invisible to the folder that calls itself the type reference. The page now reads spine map -> creation and ownership (AgentHandle pasted; the options and factory summarized with links into the generated registry section) -> the Agent handle (AgentStatus, AgentOptions, SteeringOutcome, SteeringReceipt, and SettleReason now pasted; the one settlement prose wall split by topic; delivery vocabulary ordered as a message travels) -> initiator -> interception -> a Sessions summary -> the ToolDefinition pointer -> an explicitly framed repo-wide patterns tail (the ...Map pattern, branded ids). The duplicate SessionEvent paste is gone -- session.md owns it and LINK_MAP follows -- the four ownership types moved from TYPE_LINK_EXEMPTIONS into LINK_MAP -> core.md, and three dead LINK_MAP entries (ContinuationDecision, ContinuationStop, HookContext) no longer name types absent from the source tree. The "what this page owns" meta-section folds into the intro.
The subsystems README index silently lost tasks.md and session-reference.md on both language sides during a base absorption; the rows are restored and scripts/project-doc-site.spec.ts now fails when any page misses either side of the index (proven red on a removed row). tools.md links ToolSchema to its llm-streaming.md declaration instead of calling it core; subagent.md links AgentHandle and CreateAgentOptions.seed to the new section. A new Agent Note records the package-anchored page-scoping decision; the 2026-06-20 catalog note marks its spine-vs-seam rule superseded as the page-scoping rule while keeping the type-equiv mechanism current, and docs/AGENTS.md cites the new note.
core.md read as a type grab-bag: LLM wire vocabulary up front, the agent/loop story buried, and no correspondence to packages/core. It now opens on the packages/core control spine — the package-by-package loop map with a Page column into session/system-prompt/tools/scope — and keeps only what the spine group declares plus the repo-wide patterns: the Agent handle with its delivery/cancellation/interception contracts, the SessionEvent envelope, branded ids, the …Map pattern. The conversation vocabulary (Message/ContentBlock, the model request, adapters — 17 type-equiv blocks) moves to llm-streaming.md, which now declares packages/llm end-to-end; the duplicate ContentBlockMap paste near its seam section folds into the moved section, and the manifest, LINK_MAP, README table rows, website label (Core data structures → Core), and inbound anchors follow.
Every packages/<group>/README pair is now a thin front door in one shape: a why-first intro (bash's seam-pattern-first paragraph rewritten as 'shell execution for the agent'), the package table, and a closing pointer to the owning docs/subsystems page — the bash-style table stays the load-bearing middle. Load-bearing trailing paragraphs relocate rather than vanish: the fs no-timeout rationale becomes a filesystem.md section (both languages), session's four sectioned tables merge into one 12-row table, examples' legacy-bin H2 collapses to a pointer at jsonrpc-demo's README, and design rationale that already lives in an Agent Note or subsystem page is now linked instead of restated. All 40 pair records re-recorded.
core.md doubled as the folder index: its intro claimed "this folder catalogs the data structures" and carried the 38-row page table, wording that predates the one-page-per-subsystem shape where every page also carries its generated Cordis surface. The folder index now lives in docs/subsystems/README.md (page table plus the type-equiv note), and core.md is one subsystem page among siblings: the spine vocabulary. Structural referents move with it: the docs/AGENTS.md tier table and update rule, development.md's type-equiv pointer, the dsh-code-review skill, the two owning catalog Agent Notes, and website/docs.ts (README projects as reference/subsystems/index.md and takes the docs/subsystems folder alias; sidebar orders shift by one). Remaining "data-structure catalog" / "sub-page" phrasing in active notes and READMEs is reworded to subsystem-page terms in both languages; touched pairs re-recorded; translation-prompt snapshot re-recorded (its example embeds development.md).
Rebuild of the region machinery (PR3) on the post-#904 Typert projection:
renderPageRegion/renderInheritedPage live in dsh-typert-generator beside the
projection; scripts/gen-cordis-catalog.ts owns the curated SERVICE_PAGE /
EVENT_SCOPE_PAGE / SERVICE_WALK_EXEMPTIONS / LINK_MAP partition (fail-loud in
both directions, with the independent Context-merge scan backstopping the
projection's blind spot), spliceRegion, and the guarded pair auto-record.
docs/cordis-catalog/ is deleted: the flat events/services catalogs dissolve
into per-page regions and docs/cordis-catalog/core moves to docs/cordis-api/
with the inherited tier as its own generated page. The partition absorbs the
post-regrouping surface: ctx.typert → invariants.md, ctx.directoryPicker →
workspace.md, skills/* events → skills.md, and the four launcher-provided tui
accessor values join the named exemptions.
The folder is becoming the home of one-doc-per-subsystem pages (intro +
data structures + cordis services/events), so the name must describe the
whole contract, not just the type-vocabulary third of it. Mechanical
rename rebuilt on current master: every inbound Markdown link, generator
constant, website route, type-equiv manifest path, and spec expectation
moves together; the zh sides of the notes whose prose names the folder
are aligned (子系统) in the same change; touched bilingual pairs
re-recorded; translation-prompt snapshot re-recorded (its example embeds
development.md). Historical Agent Note slugs keep their dated
filenames.