conventions/programming_ts/code_standards.yaml
Natalie 59656b5b93 feat(conventions): apiVersion+semver versioning, run lint:yaml CLI, rename infra_manifest
Add document apiVersion (conventions/v1) + per-convention semver + updated date to
the schema and all seed conventions; manifest files carry their own apiVersion
(infra/v1). New ./run (symlink -> scripts/cli/run) with lint:yaml validating every
programming_*/<name>.yaml against the schema (name==filename, scope==dir). Rename
infra-manifest.yaml -> infra_manifest.yaml for name match. 4/4 valid.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 08:36:10 -04:00

43 lines
1.8 KiB
YAML

apiVersion: conventions/v1
version: 0.1.0
updated: "2026-06-29"
name: code_standards
title: TypeScript code standards
scope: ts
status: active
summary: Portable TS conventions — strict typing, ESM, typed errors, named exports, Vitest. Project-specific architecture (kernels, golden-vectors, file-size caps) lives with the project, not here.
appliesTo: ["**/*.ts", "**/*.tsx"]
rules:
- id: strict
level: must
text: "tsconfig strict:true; prefer noUncheckedIndexedAccess + exactOptionalPropertyTypes. No escape hatches."
- id: no_any
level: must
text: No `any`; use `unknown` at boundaries and narrow with type guards. Never `as unknown as T`.
- id: no_ts_ignore
level: must
text: No `@ts-ignore`; fix the type, or `@ts-expect-error` with a reason.
- id: explicit_return_types
level: should
text: Explicit return types on exported functions and React components.
- id: discriminated_unions
level: should
text: Discriminated unions over boolean flags; add variants via switch, don't branch on strings.
- id: typed_errors
level: must
text: Typed Error subclasses with cause chaining. Never empty catch; never catch-and-only-console.
- id: esm_named_exports
level: must
text: ESM only; named exports in libraries (default exports only in app pages/components); index.ts is the public manifest.
- id: no_link_file
level: must
text: Monorepo deps via workspace:* or the registry — never file:/link:.
- id: vitest
level: must
text: Vitest (not Jest); *.test.ts co-located, full-sentence it(...); mocks only in test files.
- id: structured_logging
level: must
text: No console.log in library code — use a structured logger.
- id: no_dead_code
level: must
text: Delete unused code entirely; no _unused prefixes, no commented-out blocks.