# @govlab/docs ## Purpose The single documentation module for the workspace, spanning placement, validation and generation of one concern, laid out in the `configuration`, `core` and `runtime` containers with a flat `types` bucket. - **Placement:** `computeLocation` in `core/resolvers/location.resolver.ts` routes every authored, non-boundary document to one deterministic path from its form, concern and member, and `isBoundaryFilename` classifies the co-located boundary set. The engine owns both vocabularies, `DOC_FORMS` and the default `DOC_CONCERNS`, under `configuration/constants/`. - **Validation:** spine, conventions, path references, reference constructs, banned language, section schema, Mermaid hardening and syntax, and a document-dependency graph that catches dead edges, cycles and duplicate names. `analyzeSync` in `core/analyzers/document.analyzer.ts` runs the synchronous gates, and `DocValidator` in `core/coordinators/validation.coordinator.ts` adds the ones that read files or parse diagrams. - **Generation:** `createModuleDocs` in `core/factories/document.factory.ts` renders a module's README and its declared typed documents from the `_manifest.json` `docs` and `documents[]` blocks plus the derived source surface, and the chart engine renders `_code.info.generated/mermaid-charts.generated.md` from the code graph. The engine is pure and injection-based, and the entry points under `runtime/entrypoints/` supply the host specifics. ## When to use - You want deterministic placement: every authored non-boundary document lives at a path computed from its form, concern and member, and a stray document is a finding rather than a silent scatter. - You want documentation gated the way code is: a malformed spine, an unlabeled code fence, a bare path in prose, a broken path reference, an unresolved reference construct, or history-smell language is a build failure. - You want a module's README, typed documents and architecture charts generated from its manifest and its source, so the prose is authored once and the API surface, dependencies and governance are derived from the code. - You want a resolvable document graph, with `depends-on`, `links`, `supersedes` and `governs` edges keyed on doc name, and with dead edges, cycles and duplicate names surfaced. ## When NOT to use - As a general markdown renderer or a static-site generator. It places, validates and generates governed workspace documents, nothing more. - When a project will not commit to a closed form set and a concern taxonomy. The router needs both registries to compute a location. - For prose that has no manifest backing it. The engine places and validates a hand-authored `doc-arch` document, but the developer or the model writes its content, and nothing generates it. ## Architecture charts The structure, logical-flow and dependency diagrams derived from the source AST live in [_code.info.generated/mermaid-charts.generated.md](./_code.info.generated/mermaid-charts.generated.md). ## Install A private workspace package resolved through the root `package.json` `workspaces` globs. It imports `@govlab/argv`, `@govlab/canonical-write`, `@govlab/constants`, `@govlab/content-fingerprint`, `@govlab/context`, `@govlab/quality` and `@ssot/paths`, all workspace siblings hoisted into the single root `node_modules`. It is authored in TypeScript and runs directly from source through the root `docs:*` scripts, with no build step. ## Quick start ```ts EXAMPLE: Route a document from its form, concern and member import { DOC_CONCERNS, DOC_FORMS, computeLocation } from "@govlab/docs"; const registries = { concerns: DOC_CONCERNS, forms: DOC_FORMS, owners: ["project"] }; const result = computeLocation({ concern: "scaling", form: "guide", member: "project", name: "scale-web", registries }); console.log(result.ok ? result.path : result.detail); ``` ```ts EXAMPLE: Gate a document's prose import { conventionHits, pathReferences, validateSpine } from "@govlab/docs"; const source = "---\ntype: guide\nname: scale-web\nsummary: How to scale.\n---\n\n# Scale web\n"; const spine = validateSpine(source, ["type", "name", "summary"], { requireFrontmatter: true, requireTitle: true }); console.log(spine.length, conventionHits(source).length, pathReferences(source).length); ``` ```sh EXAMPLE: Run the documentation verbs npm run docs:validate npm run docs:generate npm run docs:fix npm run docs:new -- --type guide --concern scaling --member project --subject web ``` ## API - `const ACTIVITY_VERBS: Readonly>` - `function analyzeSync(context: ValidateCtx, meta: DocMeta): Categories` - `function bodyStart(lines: readonly string[]): number` - `function codeLineMask(lines: readonly string[], start: number): boolean[]` - `function computeLocation(request: LocationRequest): LocationResult` — the pure total router, returning `{ ok: true, path }` or `{ ok: false, reason, detail }` from a location request. - `function conventionHits(source: string): ConventionHit[]` - `function createModuleDocs(options: ModuleDocsOptions): ModuleDocs` — the manifest-driven generator factory. It returns `generateReadme`, `renderDeclaredDoc`, `declaredDocLocation` and the `govern*` gates, with every host specific injected. - `interface DescribedFinding` - `function describeFindings(all: Categories): DescribedFinding[]` - `const DIAGRAM_KINDS: readonly DiagramKind[]` - `interface DiagramContext` - `function diagramContextFor(moduleDir: string, relPath: string, label?: string): Promise` — derives a module's chart context from its code graph, type graph and package scripts, or null when nothing in the module is analyzable. - `interface DiagramKind` - `const DOC_CONCERNS: readonly string[]` - `const DOC_FORMS: Readonly>` - `const DOC_VERBS: Readonly>` - `function docMeta(context: ValidateCtx, doc: string, source: string): DocMeta` - `interface DocsHost` - `function docsHostFor(rootDir: string): Promise` — builds the validation host for a workspace root from its `govlab.config`: the registries, the harness profiles, the file index and the walk every document gate uses. - `function isBoundaryFilename(filename: string): boolean` - `function mermaidBlocks(source: string): MermaidBlock[]` - `function pathReferences(source: string): PathRef[]` - `const REF_CLAIMS: readonly string[]` - `function refScanOf(context: ValidateCtx, meta: DocMeta): RefScan` - `function renderCharts(context: DiagramContext): string | null` - `interface RenderedDiagram` - `function splitLines(source: string): string[]` - `interface ValidateCtx` - `function validateSpine(source: string, requiredKeys: readonly string[], options?: SpineOptions): SpineDefect[]` - `function workspaceMembers(root: string): string[]` ## Configuration `computeLocation(request)` is a pure total router over `{ form, concern, name, member?, generated?, registries, options? }`, where `registries` is `{ forms, concerns, owners? }` and `options` is `{ rootPrefix?, resolveOwner? }`. The gates are pure functions over a source string. `createModuleDocs(options)` takes `{ docConcerns, docForms?, docMembers?, consumerRoot, hostTokens, archRelations, conceptMap, deriveGovernedBy, deriveRepoMetrics? }`, so every host specific is injected and the engine imports no consumer state. The host side reads the `docs` section of `govlab.config` through `docsHostFor`: `members`, `ignore`, `boundaryDocs`, `hostTokens` and `harness`. Every entry point declares its command line through `@govlab/argv` in `configuration/configs/invocation.config.ts`, so `--help` prints the contract and an undeclared flag is refused. ## Dependencies - `@govlab/argv` - `@govlab/canonical-write` - `@govlab/constants` - `@govlab/content-fingerprint` - `@govlab/context` - `@govlab/quality` - `@ssot/paths` ## AI context - The one documentation module: placement, validation and manifest-driven generation of the same governed workspace documents. Placement routes every authored non-boundary document to a deterministic `doc-arch` path from its form, concern and member. Validation gates prose against spine, conventions, path references, reference constructs, banned language, section schema, Mermaid rules and a document-dependency graph. Generation renders module READMEs, typed documents and architecture charts. - The engine under `core/` is pure and injection-based: `createModuleDocs` takes an `@govlab/context` port, the canonical concept map and a governance deriver as options, so it reaches into no consumer state. The entry points under `runtime/entrypoints/` are the thin compositions that supply those host specifics. - Every extension seam is a file in `core/plugins/`, discovered by the export it carries: `plugin` for a manifest section, `diagram` for a chart kind, `analyzer` for a code language and `recognizer` for a syntax classifier. Adding a capability adds a file, and no list is edited. - A consumer extends the vocabularies without editing the package: forms, concerns, reference verbs and manifest plugins in the `doc-forms`, `doc-concerns`, `doc-verbs` and `manifest-plugins` folders of its govlab extension host are discovered and merged into the registries the entry points use. - Generate and verify with the root scripts: `npm run docs:generate` writes every derived document, and `npm run docs:validate` runs every gate, including the drift check that regenerates each output and compares it with the file on disk. ## Domains This package serves these software domains, which `_manifest.json` declares in `domains` from the two-tier software-domain vocabulary (`meta → sub`): - **developer-tooling** — documentation-generation ## Quality governance The canonical quality catalog resolves the quality concepts that govern this package. `_manifest.json` declares them in `governedBy`, and a lint package derives them from the concepts its own rules enforce. Each maps to the custom lint rules that enforce it: - **separation-of-concerns** — _complexity_ - **type-safety** — _correctness_ - **missing-docs** — _style_ ## Disposal - Remove the package directory `govlab.root/govlab.docs/` and every `docs:*` script from the root `package.json`. - Remove every import site in consumers and the gate steps that call `runtime/entrypoints/invocation.entrypoint.ts`. - Remove the injected concern registry and canonical catalog wiring. Documents then revert to hand-maintained prose with no placement, convention gate or generation. --- stable · 30 exports · 7 deps · 0 principles · 3 concepts