Define the in-file RFC contract in docs/rfc/README.md § The file format: the header block (`# RFC: <title>` plus a dateless Status enum cross-checked against the lifecycle folder), the per-lifecycle body skeleton (a Problem opener everywhere; Proposal/Alternatives considered/ Acceptance criteria/Risks in proposed/; present-tense Decision/ Consequences with proposal-era headings banned in implemented/; the frozen proposal shape in rejected/), and a mandatory Alternatives considered section with a date-fenced grandfather comment for pre-format RFCs whose alternatives are not reconstructible from the record. Enforce it with a new doc-sync gate, scripts/verify-rfc-format.ts, and normalize all 112 RFCs to it: ~15 Status-line spellings collapse to the enum, 29 Context openers become Problem, the 39 legacy-format XXX debt markers are resolved and banned from reappearing, proposal-era sections in implemented RFCs are rewritten to shipped reality (including the web/fs/subagent seam RFCs' migration plans and test checklists, closing the doc-tiers deferred-work item on the web seam), every RFC gains an Alternatives considered section or the grandfather comment, and the bilingual pair is re-mirrored and re-recorded. Move the generated index tables out of README.md into a fully generated docs/rfc/INDEX.md — gen-rfc-index now writes the whole file, and verify-rfc-classification checks its freshness and rejects index-shaped rows in the curated README — which makes room for the format contract to live in the README front door instead of a separate FORMAT.md. The decision record, and the first RFC written in the new format, is docs/rfc/implemented/process/2026-07-05-uniform-rfc-format.md.
2.1 KiB
RFC: Vendor Cordis as source, not npm dependencies
Status: implemented
Problem
DeepSeek Harness SDK is built on the Cordis framework. Cordis core was at 4.0.0-rc.6 (a release candidate) when this repo started; the harness depends on framework internals (fiber lifecycle, effect disposal, waterfall dispatch) whose exact behavior matters to the agent loop's correctness guarantees.
Decision
Copy the needed Cordis packages (core, loader, include, group, timer, hmr, logger-console) and the cordiverse foundation libraries (cosmokit, schemastery) into vendor/ as source, flattened, keeping their original npm names so workspace resolution is transparent. Truly third-party dependencies (js-yaml, chokidar, @standard-schema/spec, …) stay on npm.
vendor/README.md is the manifest: upstream repo + commit SHA per package and an exhaustive local-modification log. A pre-commit guard (scripts/check-vendor-manifest.sh) rejects vendored-source changes that don't update the manifest in the same commit.
Alternatives considered
- Depend on the npm packages — rejected: core was at a release candidate, and the harness leans on framework internals (fiber lifecycle, effect disposal, waterfall dispatch) whose exact behavior the agent loop's correctness guarantees depend on; an upstream RC bump could break them without a local fix path.
- Vendor everything transitively — rejected: truly third-party dependencies (js-yaml, chokidar, @standard-schema/spec, …) stay on npm; only the framework layer whose internals matter is owned.
Consequences
- The harness fully owns its framework layer: auditable, patchable, pinned — an RC upstream can't break us, and we can fix framework bugs in-tree.
- Upstream sync is manual (documented procedure in the manifest). The modification log keeps the diff surface known.
- Vendored packages keep upstream code style; lint/strictness gates exclude them (their tsconfigs relax our newer compiler flags locally).
- One local patch exists from day one: hmr's locale-YAML imports removed (the runtime YAML import hook isn't vendored).