mirror of
https://github.com/mvschwarz/openrig.git
synced 2026-11-07 05:56:21 -10:00
Product skills now regenerate from one editable home inside this repository, so a skill fix is made once and the apply can't replace reviewed text with an outside copy. - Each skill has one home: its spec copy when it has a spec edge, otherwise its plugin copy. `scripts/skill-edge-layout.generated.json` still lists which copies each skill has, and every other copy is generated from the home. - The apply reads nothing outside the repository. `OPENRIG_SKILL_CANON_ROOT` is no longer needed; when it's set, the script says it's ignored. - The apply can't erase a home. Every read and write is planned and every home is staged before any output is replaced, an output that overlaps a home is refused, and a home is never written. On an edge that holds homes, an undeclared skill is left in place and listed. - The sanitization and leak rules now check the home. Generated copies stay byte-identical to it, and each generated file takes its home's mode. - `--check` compares every generated copy with its home and reports `copy-diverged`, `copy-missing` or `copy-extra`, even after the digests are refreshed. - `skills/README.md` and `ARCHITECTURE.md` describe the in-repo source. One content change: `metadata.openrig.transfer_test: pending` is removed from `openrig-software-factory/SKILL.md` (its spec home and `_canonical` copy, with both digests updated). The sanitizer already strips that key from public copies, and nothing in the product reads it. Directory modes aren't restored from homes; only file modes are.
36 lines
1.9 KiB
JavaScript
36 lines
1.9 KiB
JavaScript
#!/usr/bin/env node
|
|
// Disk-truth regen of scripts/skill-edge-digests.generated.json.
|
|
//
|
|
// Recomputes every edge's file-integrity hashes from the files ON DISK, using the in-repo (already
|
|
// correct) scripts/skill-edge-layout.generated.json to know which edges to walk. NO external-canon
|
|
// YAMLs are required — the digests are purely disk + layout derived. Full mirror APPLY reads the same
|
|
// product policy JSON and regenerates each skill's copies from its home in this repo.
|
|
// THIS regen only refreshes the reality side (hashes of present files)
|
|
// to match folded main.
|
|
//
|
|
// PROPERTY (layout = authority, disk = reality, regen touches only reality): buildEdgeDigests hashes
|
|
// PRESENT files only. A layout-demanded file missing from disk is never given a digest here, so
|
|
// `mirror-skills.mjs --check` stays LOUD about it (via its layout-missing check + the narrow, named,
|
|
// self-policing external-canon-pending allowlist) — a future accidental deletion can never be silently
|
|
// blessed by a regen.
|
|
//
|
|
// Usage: node scripts/regen-edge-digests.mjs (writes in place; run when folded skill edges drift)
|
|
|
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
import { join, dirname } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { buildEdgeDigests } from "../packages/daemon/scripts/gen-control-plane-json.mjs";
|
|
|
|
const repoRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
const layoutPath = join(repoRoot, "scripts/skill-edge-layout.generated.json");
|
|
const outPath = join(repoRoot, "scripts/skill-edge-digests.generated.json");
|
|
|
|
const layout = JSON.parse(readFileSync(layoutPath, "utf8"));
|
|
const digests = buildEdgeDigests({ repoRoot, layout });
|
|
writeFileSync(outPath, `${JSON.stringify(digests, null, 2)}\n`);
|
|
|
|
const fileCount = Object.values(digests.edges).reduce((n, files) => n + Object.keys(files).length, 0);
|
|
console.log(
|
|
`Regenerated ${outPath} from disk: ${Object.keys(digests.edges).length} edges, ${fileCount} files.`,
|
|
);
|