/*
RFC-0548: backup existing AGENTS.md and regenerate it with the new
behavioral layer. The migrator backs up AGENTS.md to AGENTS.md.bak if it
exists, then delegates regeneration to forge.agents.generate. If
AGENTS.md does not exist or forge.agents.generate is unavailable, the
migrator is a no-op (idempotent).
- Do not modify any file other than AGENTS.md and AGENTS.md.bak.
- Do not delete AGENTS.md.bak — it is the operator's rollback path.
- Do not run forge.agents.generate if AGENTS.md has no generated marker — that would fail.
- RFC-0548: initial migrator — backup AGENTS.md and regenerate with behavioral layer.
- RFC-1149: migrate ambient filesystem and process IO to the WorkspaceIO port across engine and shared
*/
import path from "node:path";
import { createDefaultIO } from "@warpgogol/werkstatt-shared/kernel/workspace-io";
import type { Migrator, SternsystemData, MigrationContext } from "./types.ts";
export const RFC_0548_MIGRATOR_ID = "rfc-0548";
export const rfc0548Migrator: Migrator = {
id: RFC_0548_MIGRATOR_ID,
fromVersion: "5.28.0",
toVersion: "5.29.0",
description:
"Backup AGENTS.md to AGENTS.md.bak and regenerate with core behavioral layer (intent-to-skill routing, auto-documentation, creator-facing communication, safety net). If AGENTS.md is hand-written (no generated marker), skip regeneration — the operator must delete or rename it first.",
transform: async (data: SternsystemData, ctx: MigrationContext): Promise => {
const io = ctx.io ?? createDefaultIO().io;
const agentsMdPath = path.join(data.rootPath, "AGENTS.md");
const backupPath = path.join(data.rootPath, "AGENTS.md.bak");
if (!(await io.exists(agentsMdPath))) {
return data;
}
const content = await io.readFile(agentsMdPath);
// Check for generated marker — if absent, this is a hand-written AGENTS.md
// and we must not overwrite it. Backup only.
const hasGeneratedMarker = content.includes("