mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
New authoritative section docs/development.md#typescript-project-layout (five files, three roles, the program-vs-resolution principle and its two disciplines), two repo conventions in AGENTS.md, package tsconfig shape in packages/AGENTS.md, cookbook touch-lists updated for the two aggregates, test source-plane rule in docs/testing.md. Decision record: new Agent Note 2026-07-22-tsconfig-solution-root-two-aggregates; ts-build-config note updated in place (tsc-first pipeline unchanged); the two GUI RFCs now name tsconfig.host.json. All bilingual pairs re-recorded. Doc budget ceilings raised: AGENTS.md 1680, docs/testing.md 1020, packages/AGENTS.md 660 (two new one-line conventions and one new section on already-near-ceiling docs). Mission spec for the code-side migration: missions/tsconfig-single-graph-migration.md.
5.5 KiB
5.5 KiB
AGENTS.md — Harness Packages
These package-specific rules supplement the repo-wide conventions.
- Plugin export shape: service packages default-export their service class; function plugins named-export
name/inject/Config/applyand have no default export. Mixing the forms makes the Loader discard the function plugin's namespace (postmortem). - Optional services use
ctx.get(name). Reservectx.<name>for declared injections; the property proxy is topology-sensitive, while strictctx.getreads the global service store (postmortem). - Product-visible plugins require a non-unit REAL-composition test. Hand-built
ctx.plugin(...)suites are insufficient. Boot test-onlycordis.ymlthrough the Loader and app/process; mock only external/nondeterministic boundaries and assert model-visible, durable, or user-visible output. Keep opt-ins out of shipped defaults. Policy. - Initiator-owned private chains derive, then capture. Under
ctx.agents.withInitiator(), recover the Agent at each orchestration entry, deriveagent.session, and let operation-local helpers close over it. KeepAgentandSessionexplicit at lifecycle, session-log, service, authority, worker/process, persistence, and wire interfaces; do not widen a leaf helper fromSessiontoContextmerely to hide a parameter (rationale). - Represent one asynchronous operation with one lifecycle controller or transaction. Separate readiness, cancellation, disposal, reservation, or sentinel state requires an independent owner or settlement boundary; otherwise fold it while preserving rollback, callback containment, and quiescence.
- Shape capability interfaces around all current consumers. Keep tool-schema, Loader, UI, transport, and backend-specific behavior in the consumer or adapter; do not let one consumer dictate the interface (capability-seam rationale).
- Require a current owner and need. Tie each abstraction, state machine, option, defensive copy, and compatibility path to a current contract or production consumer, and keep behavior in its owning plugin or service.
- Require evidence for public choices. Configurability does not justify an unsupported default, public operation set, format, or imported external concept. Use current-consumer evidence or relevant prior art; otherwise require an explicit value or defer the choice.
- Write model-facing contracts from the model's perspective. Prompts, tool schemas, results, and diagnostics contain only task-relevant concepts, not UI, transport, or implementation vocabulary. Pin stable model-visible text verbatim and dynamic behavior through snapshots or end-to-end coverage.
- Enforce at the operation boundary that owns the decision. Schema omission, prompt filtering, facades, wrappers, and listener order are not enforcement when direct or alternate callers can bypass them; test denial through the executor.
- Publish state only at its commit point. Emit each notification and update derived state only after the success boundary that makes it true; derive caches, prompts, UI echoes, replay, and query views from one authoritative source.
- Apply bounds to the complete result. Enforce byte, token, item, and time limits where the complete emitted or retained value, including wrappers and metadata, is known; test tiny and exact limits, oversized single chunks, and multibyte byte limits.
- Registry contributions prove disposal through the HMR-safety test required by testing policy: dispose the fiber and observe removal.
- Every package owns
./invariant. Register the manifest name; check an event/data relation or give empty installers package-specificNo runtime invariant:reasons. Generated companions, unexplained empties, and ignored reporters failverify-package-invariants.
Naming notes:
- Package tsconfig shape: extends
tsconfig.base.json(client:tsconfig.base.client.json),rootDir: src,outDir: lib/types, areferencesentry per workspace dependency plussupport/invariants; registered in exactly one aggregate — host packages intsconfig.host.json, client intsconfig.client.json(layout). src/types.tscontains only types — no runtime code.- Tests live at package level under
tests/, notsrc/__tests__/. - A package's README and JSDoc are part of the change: altered behavior (config keys, defaults, error codes, wire fields) updates them in the same commit.
doc-syncgates what it can; apply dsh-prose-standard for complete, concise prose and verify accuracy against code. - Package READMEs document model, token, and KV-cache effects using the canonical Model Experience format.
- Package READMEs put durable consumer gaps and non-obvious maintainer constraints under
## Known Limitations and Deferred Work; ordinary cleanup stays in its TODO or Agent Note. Packages with none use a justified allowlist entry (rationale).