Agentic AI Atlasby a5c.ai
OverviewWikiGraphFor AgentsEdgesSearchWorkspace
/
GitHubDocsDiscord
iiRecord
Agentic AI Atlas · Generator Design
page:generators-00-generator-designa5c.ai
Search record views/
Record · tabs

Available views

II.Record viewspp. 1 - 1
overviewarticlejsongraph
II.
Page overview

page:generators-00-generator-design

Reference · live

Generator Design overview

Inspect the raw attributes, linked wiki pages, and inbound or outbound graph edges for page:generators-00-generator-design.

PageOutgoing · 0Incoming · 1

Attributes

nodeKind
Page
title
Generator Design
displayName
Generator Design
slug
generators/00-generator-design
articlePath
wiki/generators/00-generator-design.md
article
# Generator Design > Concrete implementation plan for Phase 3. Extends `graph/schema/derivation-spec.md` with the runtime, query layer, template engine, and operational contracts the generators share. ## Language and runtime - **Language**: TypeScript, compiled to JavaScript ahead of time (no `ts-node`). - **Runtime**: Node.js LTS (v22.x at time of writing). Pinned via `.nvmrc` + `engines` in `tools/package.json`. - **Module system**: ESM (`"type": "module"`). - **Package manager**: npm. Lockfile committed. TypeScript is chosen for two reasons. First, it lets us reuse the schema-derived types for the SDK (Phase 6) directly inside generator code — a generator that emits a TypeScript artifact is itself typed against the schema it reads. Second, the toolchain matches the rest of the babysitter monorepo, so generator outputs integrate with existing CI infrastructure without translation. ## Query layer Generators do not load raw YAML; they query an in-memory graph. The graph is built once per CLI invocation by the loader in `tools/graph-load.ts`: 1. Walk `graph/schema/ontology-schema.yaml` to learn NodeKinds, EdgeKinds, attribute types, and invariants. 2. Walk `graph/schema/examples/**/*.yaml` and parse every record into a typed `Node` keyed by `id`. 3. Resolve every `ref<>` field, edge endpoint, and `evidenceSourceIds` list. Dangling references abort the load (this is the same check the Phase-1 validator stub runs). 4. Index by NodeKind, by attribute, and by edge (forward + reverse adjacency). Query helpers exposed by `tools/query.ts`: - `getByKind(kind)` → `Node[]` sorted by `id`. - `getById(id)` → `Node | undefined`. - `outgoing(nodeId, edgeKind?)` / `incoming(nodeId, edgeKind?)` → `Edge[]`. - `traverse(startId, path)` where `path` is a list of edge-kind names — returns the set of terminal nodes (used for the wiki page-type queries described in `wiki/01-derivation-mapping.md`). - `evidence(nodeId, attribute)` → `EvidenceSource[]` plus freshness metadata. All helpers are pure functions over the loaded graph. They do **not** hit the filesystem. ## Template engine **Handlebars** for markdown / OpenAPI / YAML / mermaid outputs. Handlebars strikes the right balance: powerful enough to express collection iteration and partials, small enough that templates remain reviewable. Custom helpers register at startup: - `{{slug id}}` — turn a graph id into a slug. - `{{trustBadge evidence}}` — render a `TrustLevel` badge. - `{{freshness evidence}}` — emit a freshness indicator (green/yellow/red) based on the `EvidencePolicy` in force. For TypeScript outputs we use `ts-morph` directly rather than templates — a structured AST is easier to keep deterministic across schema edits than string concatenation. ## I/O contract Each generator is a Node module exporting: ```ts export interface Generator { id: string; // matches Generator.id in the graph consumes: { nodeKinds: string[]; edgeKinds: string[] }; outputs: { path: string; format: OutputFormat }[]; run(ctx: GenerateContext): Promise<GenerateResult>; } ``` The CLI (`tools/cli.ts`) loads the generator registry, runs the requested generators, writes outputs to `<repo>/<path>` exactly as declared, and writes a sibling `<path>.manifest.json` with: - `generatorId` - `generatedAt` (only in the manifest, never in output content — outputs must remain byte-stable) - `sourceCatalogVersion` (read from the graph) - `inputs`: `{ nodeIds: [], edgeKinds: [] }` actually traversed - `contentHash`: SHA-256 of the rendered output ## Idempotency and content-hashing After each run the CLI compares the new content hash against the existing manifest. If equal, the file is not rewritten (preserves filesystem timestamps and avoids no-op git diffs). If unequal, the file is rewritten and the manifest is updated. CI's "regenerate-on-merge" gate (Phase 5) runs every generator and fails the build if the working tree diff is non-empty *and* the change was not authored in the same PR. This is what enforces "prose drift is structurally impossible". ## Determinism rules - Iterate collections in `id`-sorted order. - Render dates only via `freshness` helper (which emits coarse-grained labels, not exact timestamps). - Never embed paths absolute to a developer's checkout. - Use `\n` line endings. UTF-8 without BOM. ## Failure modes A generator MUST fail (non-zero exit, no partial writes) when: - The graph load fails any invariant. - A required NodeKind / EdgeKind it `consumes` is empty. - A template references a missing helper or unresolved id. - An output's content hash collides with another generator's output (catches accidentally double-owned files). ## Test surface (handed to Phase 5) Each generator ships: - A unit test against a hand-rolled in-memory graph fixture. - An integration test against `graph/schema/examples/`. - A snapshot test of its output under a frozen graph version. See `qa/00-qa-architecture.md` for how these slot into the wider test pyramid.
documents
[]

Outgoing edges

None.

Incoming edges

contains_page1
  • page:generators·PageGenerators and Derived Artifacts

Related pages

No related wiki pages for this record.

Shortcuts

Open in graph
Browse node kind