// The generator's canonical inputs are THE SAME FILES the drift gate checks // (conventions/* + build/*), resolved package-relative exactly like // check-drift.ts's CLI entry — there is no second copy that can drift. A // generated repo therefore passes the gate by construction: byte-verbatim // files are emitted byte-verbatim, and the per-repo fill-ins live only where // the gate already masks or leaves structure free (the workflows' `product:` // line, the root tsconfig include list, the .gitignore tail, the wrapper // around the build-image bootstrap, the seed's pins). import { readFileSync } from "node:fs"; import { join } from "node:path"; const conventionsDir = join(import.meta.dir, "..", "conventions"); const buildDir = join(import.meta.dir, "..", "build"); export interface Canon { core: string; flake: string; /** build/ctl-shell.nix, emitted as nix/ctl-shell.nix — the flake imports it. */ ctlShell: string; flakeLock: string; bump: string; botPrs: string; checks: string; biome: string; tsconfigBase: string; dprint: string; buildImageBootstrap: string; buildImage: string; smoke: string; /** conventions/build-docs.yml — the embedded docs workflow a turnkey carries. */ buildDocs: string; gitignoreCore: string; invariantsTemplate: string; /** conventions/demo.sh, emitted as scripts/demo. */ demoShim: string; /** conventions/server-install.sh and server-uninstall.sh, emitted as * deployment/install.sh and deployment/uninstall.sh. */ serverInstall: string; serverUninstall: string; /** doc-guide/with-display.sh, emitted as scripts/with-display.sh — the docs * workflow invokes it by that repo-local path. */ withDisplay: string; } export function loadCanon(): Canon { return { core: readFileSync(join(conventionsDir, "CLAUDE.core.md"), "utf8"), flake: readFileSync(join(buildDir, "flake.nix"), "utf8"), ctlShell: readFileSync(join(buildDir, "ctl-shell.nix"), "utf8"), flakeLock: readFileSync(join(buildDir, "flake.lock"), "utf8"), bump: readFileSync(join(conventionsDir, "bump.yml"), "utf8"), botPrs: readFileSync(join(conventionsDir, "bot-prs.yml"), "utf8"), checks: readFileSync(join(conventionsDir, "checks.yml"), "utf8"), buildDocs: readFileSync(join(conventionsDir, "build-docs.yml"), "utf8"), withDisplay: readFileSync(join(conventionsDir, "..", "doc-guide", "with-display.sh"), "utf8"), biome: readFileSync(join(conventionsDir, "biome.base.json"), "utf8"), tsconfigBase: readFileSync(join(conventionsDir, "tsconfig.base.json"), "utf8"), dprint: readFileSync(join(conventionsDir, "dprint.base.jsonc"), "utf8"), buildImageBootstrap: readFileSync(join(buildDir, "build-image.bootstrap.sh"), "utf8"), buildImage: readFileSync(join(conventionsDir, "build-image.yml"), "utf8"), smoke: readFileSync(join(conventionsDir, "smoke.yml"), "utf8"), gitignoreCore: readFileSync(join(conventionsDir, "gitignore.core"), "utf8"), invariantsTemplate: readFileSync(join(import.meta.dir, "..", "testing", "INVARIANTS.template.md"), "utf8"), demoShim: readFileSync(join(conventionsDir, "demo.sh"), "utf8"), serverInstall: readFileSync(join(conventionsDir, "server-install.sh"), "utf8"), serverUninstall: readFileSync(join(conventionsDir, "server-uninstall.sh"), "utf8"), }; } export function loadAsset(name: string): string { return readFileSync(join(import.meta.dir, "assets", name), "utf8"); } /** The `product:` value in the shared workflows — the one line the drift gate * masks. The dashboard key drops the `norsk-` prefix by fleet convention * (norsk-reuters reports as `reuters`). */ export const PRODUCT_SENTINEL = "__PRODUCT__";