shell-redesign V1 pre-release CLI/daemon Item 3: rename projection markers from RIGGED to OpenRig

Renames the managed-block markers that the daemon writes into user-managed
files (CLAUDE.md / AGENTS.md) from "BEGIN/END RIGGED MANAGED BLOCK" to
"BEGIN/END OpenRig MANAGED BLOCK". The marker carries the canonical
product name now that the package and CLI binary use the openrig
identity.

Backwards-compat for files written by prior installs:
- stripManagedBlocks recognizes both legacy (RIGGED) and current
  (OpenRig) marker patterns so uninstall/cleanup paths handle both
  transitional states.
- mergeManagedBlock detects legacy blocks for a package id when
  deciding whether to replace; the replacement always emits the
  OpenRig form so user files migrate forward in place.
- conflict-detector.hasExistingBlock returns true for legacy markers
  too, so re-applying a guidance package over a pre-rename file
  doesn't quietly add a duplicate block.
- install-engine.applyGuidanceMerge falls back to legacy marker
  search when the OpenRig markers aren't present, then writes the
  OpenRig form in place of the legacy block.
- install-verifier accepts either marker form when checking that a
  guidance install's BEGIN/END markers are intact.

Test fixtures and assertions across 8 daemon tests updated to expect
the new marker form. Production write paths emit OpenRig exclusively;
production read paths recognize both forms.

Verification:
- npx tsc --noEmit --project packages/daemon/tsconfig.json: clean
- npx vitest run on the 9 affected test files: 178/178 PASS

SC-29 EXCEPTION #4 (declared in pre-release CLI/daemon ACK §5):
release-blocker product-feature change, not allowlist-only. Existing
allowlist exceptions #1 (Phase 4 advisor/operator) + #2 (Phase 5
feed.subscriptions) + additive #3 (polish-slice-4 graph payload token
telemetry) untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
mvschwarzandClaude Opus 4.7 committed 2026-05-07 04:29:41 -07:00
1 parent 4ad5078224
commit 7a026128a0
12 files changed
+93 -47

No files matched your search

@@ -16,9 +16,9 @@ function hashContent(content: string): string {
}
const MANAGED_BLOCK_START = (packageName: string) =>
`<!-- BEGIN RIGGED MANAGED BLOCK: ${packageName} -->`;
`<!-- BEGIN OpenRig MANAGED BLOCK: ${packageName} -->`;
const MANAGED_BLOCK_END = (packageName: string) =>
`<!-- END RIGGED MANAGED BLOCK: ${packageName} -->`;
`<!-- END OpenRig MANAGED BLOCK: ${packageName} -->`;
/**
* Refines an InstallPlan with content-aware conflict detection.
@@ -95,7 +95,11 @@ export function detectConflicts(
const targetContent = fs.readFile(entry.targetPath);
const beginMarker = MANAGED_BLOCK_START(plan.packageName);
const endMarker = MANAGED_BLOCK_END(plan.packageName);
const hasExistingBlock = targetContent.includes(beginMarker) && targetContent.includes(endMarker);
const legacyBegin = `<!-- BEGIN RIGGED MANAGED BLOCK: ${plan.packageName} -->`;
const legacyEnd = `<!-- END RIGGED MANAGED BLOCK: ${plan.packageName} -->`;
const hasExistingBlock =
(targetContent.includes(beginMarker) && targetContent.includes(endMarker)) ||
(targetContent.includes(legacyBegin) && targetContent.includes(legacyEnd));
const refined: InstallPlanEntry & { guidanceMeta?: GuidanceConflictMeta } = {
...entry,
+22 -6
View File
@@ -27,8 +27,8 @@ export interface RollbackResult {
deleted: string[];
}
const BLOCK_START = (name: string) => `<!-- BEGIN RIGGED MANAGED BLOCK: ${name} -->`;
const BLOCK_END = (name: string) => `<!-- END RIGGED MANAGED BLOCK: ${name} -->`;
const BLOCK_START = (name: string) => `<!-- BEGIN OpenRig MANAGED BLOCK: ${name} -->`;
const BLOCK_END = (name: string) => `<!-- END OpenRig MANAGED BLOCK: ${name} -->`;
function hashContent(content: string): string {
return createHash("sha256").update(content).digest("hex");
@@ -180,12 +180,28 @@ export class InstallEngine {
const existing = this.fs.readFile(entry.targetPath);
const startMarker = BLOCK_START(packageName);
const endMarker = BLOCK_END(packageName);
const startIdx = existing.indexOf(startMarker);
const endIdx = existing.indexOf(endMarker);
const legacyStart = `<!-- BEGIN RIGGED MANAGED BLOCK: ${packageName} -->`;
const legacyEnd = `<!-- END RIGGED MANAGED BLOCK: ${packageName} -->`;
// Prefer the OpenRig form; fall back to legacy markers from
// prior installs so re-applying a guidance package over a
// pre-rename file replaces the old block instead of appending a
// duplicate.
let startIdx = existing.indexOf(startMarker);
let endIdx = existing.indexOf(endMarker);
let matchedEndLength = endMarker.length;
if (startIdx === -1 || endIdx === -1) {
const legacyStartIdx = existing.indexOf(legacyStart);
const legacyEndIdx = existing.indexOf(legacyEnd);
if (legacyStartIdx !== -1 && legacyEndIdx !== -1) {
startIdx = legacyStartIdx;
endIdx = legacyEndIdx;
matchedEndLength = legacyEnd.length;
}
}
if (startIdx !== -1 && endIdx !== -1) {
// Update existing block
const updated = existing.slice(0, startIdx) + block + existing.slice(endIdx + endMarker.length);
// Update existing block (rewrites legacy markers to OpenRig form).
const updated = existing.slice(0, startIdx) + block + existing.slice(endIdx + matchedEndLength);
this.fs.writeFile(entry.targetPath, updated);
} else {
// Insert new block at end
+10 -5
View File
@@ -27,8 +27,8 @@ export interface VerifierFsOps {
exists: (filePath: string) => boolean;
}
const BLOCK_START = (name: string) => `<!-- BEGIN RIGGED MANAGED BLOCK: ${name} -->`;
const BLOCK_END = (name: string) => `<!-- END RIGGED MANAGED BLOCK: ${name} -->`;
const BLOCK_START = (name: string) => `<!-- BEGIN OpenRig MANAGED BLOCK: ${name} -->`;
const BLOCK_END = (name: string) => `<!-- END OpenRig MANAGED BLOCK: ${name} -->`;
function hashContent(content: string): string {
return createHash("sha256").update(content).digest("hex");
@@ -125,10 +125,15 @@ export class InstallVerifier {
});
}
// Check 3: Guidance managed block markers
// Check 3: Guidance managed block markers — recognize both
// the OpenRig form (current writes) and the legacy RIGGED form
// from prior installs so verification of pre-rename installs
// does not falsely report missing markers.
if (entry.exportType === "guidance") {
const hasStart = content.includes(BLOCK_START(packageName));
const hasEnd = content.includes(BLOCK_END(packageName));
const legacyStart = `<!-- BEGIN RIGGED MANAGED BLOCK: ${packageName} -->`;
const legacyEnd = `<!-- END RIGGED MANAGED BLOCK: ${packageName} -->`;
const hasStart = content.includes(BLOCK_START(packageName)) || content.includes(legacyStart);
const hasEnd = content.includes(BLOCK_END(packageName)) || content.includes(legacyEnd);
checks.push({
name: "managed_block_markers",
passed: hasStart && hasEnd,
+24 -3
View File
@@ -1,7 +1,13 @@
import nodePath from "node:path";
export const MANAGED_BLOCK_START = (id: string) => `<!-- BEGIN RIGGED MANAGED BLOCK: ${id} -->`;
export const MANAGED_BLOCK_END = (id: string) => `<!-- END RIGGED MANAGED BLOCK: ${id} -->`;
// Pre-release: projection markers that land in user-managed files
// (CLAUDE.md / AGENTS.md) carry the canonical product name. New writes
// emit the OpenRig form; legacy "RIGGED" markers from prior installs
// are still recognized by stripManagedBlocks below for clean uninstall.
export const MANAGED_BLOCK_START = (id: string) => `<!-- BEGIN OpenRig MANAGED BLOCK: ${id} -->`;
export const MANAGED_BLOCK_END = (id: string) => `<!-- END OpenRig MANAGED BLOCK: ${id} -->`;
const LEGACY_BLOCK_START = (id: string) => `<!-- BEGIN RIGGED MANAGED BLOCK: ${id} -->`;
const LEGACY_BLOCK_END = (id: string) => `<!-- END RIGGED MANAGED BLOCK: ${id} -->`;
export interface ManagedBlockMergeFsOps {
exists(path: string): boolean;
@@ -40,7 +46,12 @@ export function mergeManagedBlock(
const replaceableIds = allReplaceIds.filter((id) => {
const candidateBegin = MANAGED_BLOCK_START(id);
const candidateEnd = MANAGED_BLOCK_END(id);
return existing.includes(candidateBegin) && existing.includes(candidateEnd);
const legacyBegin = LEGACY_BLOCK_START(id);
const legacyEnd = LEGACY_BLOCK_END(id);
return (
(existing.includes(candidateBegin) && existing.includes(candidateEnd)) ||
(existing.includes(legacyBegin) && existing.includes(legacyEnd))
);
});
if (replaceableIds.length > 0) {
@@ -50,6 +61,12 @@ export function mergeManagedBlock(
const candidateEnd = MANAGED_BLOCK_END(id);
const regex = new RegExp(`${escapeRegex(candidateBegin)}[\\s\\S]*?${escapeRegex(candidateEnd)}`, "g");
updated = updated.replace(regex, id === blockId ? block : "");
// Legacy marker variant from prior installs — replace with the
// OpenRig form (or strip when not the active block id).
const legacyBegin = LEGACY_BLOCK_START(id);
const legacyEnd = LEGACY_BLOCK_END(id);
const legacyRegex = new RegExp(`${escapeRegex(legacyBegin)}[\\s\\S]*?${escapeRegex(legacyEnd)}`, "g");
updated = updated.replace(legacyRegex, id === blockId ? block : "");
}
if (!updated.includes(begin) || !updated.includes(end)) {
updated = `${updated.trim()}\n\n${block}`.trim();
@@ -82,7 +99,11 @@ export function removeManagedBlocksFromFile(fs: ManagedBlockCleanupFsOps, target
}
export function stripManagedBlocks(content: string): string {
// Recognize both the OpenRig form (current writes) and the legacy
// RIGGED form (existing user files written by prior installs) so
// uninstall + cleanup paths handle both transitional states.
return content
.replace(/(?:\n|^)\s*<!-- BEGIN OpenRig MANAGED BLOCK: [\s\S]*?<!-- END OpenRig MANAGED BLOCK: [^>]+ -->\s*(?=\n|$)/g, "\n")
.replace(/(?:\n|^)\s*<!-- BEGIN RIGGED MANAGED BLOCK: [\s\S]*?<!-- END RIGGED MANAGED BLOCK: [^>]+ -->\s*(?=\n|$)/g, "\n")
.replace(/\n{3,}/g, "\n\n")
.trim();
@@ -159,15 +159,15 @@ describe("Agent Starter v1 vertical — real Claude adapter delivery (M2 R2)", (
expect(result.ok).toBe(true);
// The Claude adapter's `mergeGuidance` writes to <binding.cwd>/CLAUDE.md
// wrapped in a `BEGIN RIGGED MANAGED BLOCK` envelope. The cwd for this
// wrapped in a `BEGIN OpenRig MANAGED BLOCK` envelope. The cwd for this
// member resolves to RIG_ROOT (`cwd: "."`).
const expectedClaudeMdPath = path.join(RIG_ROOT, "CLAUDE.md");
const claudeMd = claudeFs._store[expectedClaudeMdPath];
expect(claudeMd, "expected real ClaudeCodeAdapter to have written CLAUDE.md via guidance_merge").toBeDefined();
// The managed block is keyed on the starter file path (`file.path`,
// which is the basename returned by the resolver).
expect(claudeMd).toContain("BEGIN RIGGED MANAGED BLOCK: claude-fixture-starter.yaml");
expect(claudeMd).toContain("END RIGGED MANAGED BLOCK: claude-fixture-starter.yaml");
expect(claudeMd).toContain("BEGIN OpenRig MANAGED BLOCK: claude-fixture-starter.yaml");
expect(claudeMd).toContain("END OpenRig MANAGED BLOCK: claude-fixture-starter.yaml");
// Some piece of the starter YAML body must appear inside the block.
// We pick `starter_id: claude-fixture-starter` because it's a stable,
// unambiguous marker the resolver passed through.
@@ -153,8 +153,8 @@ describe("Agent Starter v1 vertical — real Codex adapter delivery (M2 R2)", ()
const expectedAgentsMdPath = path.join(RIG_ROOT, "AGENTS.md");
const agentsMd = codexFs._store[expectedAgentsMdPath];
expect(agentsMd, "expected real CodexRuntimeAdapter to have written AGENTS.md via guidance_merge").toBeDefined();
expect(agentsMd).toContain("BEGIN RIGGED MANAGED BLOCK: codex-fixture-starter.yaml");
expect(agentsMd).toContain("END RIGGED MANAGED BLOCK: codex-fixture-starter.yaml");
expect(agentsMd).toContain("BEGIN OpenRig MANAGED BLOCK: codex-fixture-starter.yaml");
expect(agentsMd).toContain("END OpenRig MANAGED BLOCK: codex-fixture-starter.yaml");
expect(agentsMd).toContain("starter_id: codex-fixture-starter");
db.close();
@@ -115,10 +115,10 @@ describe("Claude Code runtime adapter", () => {
const fs = mockFs({
"/rig/openrig-start.md": "# OpenRig Start\n\nNew guidance",
"/project/CLAUDE.md": [
"<!-- BEGIN RIGGED MANAGED BLOCK: using-openrig.md -->",
"<!-- BEGIN OpenRig MANAGED BLOCK: using-openrig.md -->",
"# Using OpenRig",
"Old guidance",
"<!-- END RIGGED MANAGED BLOCK: using-openrig.md -->",
"<!-- END OpenRig MANAGED BLOCK: using-openrig.md -->",
].join("\n"),
});
const adapter = new ClaudeCodeAdapter({ tmux: mockTmux(), fsOps: fs });
@@ -135,8 +135,8 @@ describe("Claude Code runtime adapter", () => {
const store = (fs as unknown as { _store: Record<string, string> })._store;
const content = store["/project/CLAUDE.md"]!;
expect(content).toContain("BEGIN RIGGED MANAGED BLOCK: openrig-start.md");
expect(content).not.toContain("BEGIN RIGGED MANAGED BLOCK: using-openrig.md");
expect(content).toContain("BEGIN OpenRig MANAGED BLOCK: openrig-start.md");
expect(content).not.toContain("BEGIN OpenRig MANAGED BLOCK: using-openrig.md");
expect(content).toContain("New guidance");
});
@@ -539,7 +539,7 @@ describe("Claude Code runtime adapter", () => {
await adapter.project(plan, makeBinding());
const store = (fs as unknown as { _store: Record<string, string> })._store;
expect(store["/project/CLAUDE.md"]).toContain("BEGIN RIGGED MANAGED BLOCK: using-openrig.md");
expect(store["/project/CLAUDE.md"]).toContain("BEGIN OpenRig MANAGED BLOCK: using-openrig.md");
expect(store["/project/CLAUDE.md"]).toContain("hub guidance");
});
@@ -287,10 +287,10 @@ describe("Codex runtime adapter", () => {
const fs = mockFs({
"/rig/openrig-start.md": "# OpenRig Start\n\nNew guidance",
"/project/AGENTS.md": [
"<!-- BEGIN RIGGED MANAGED BLOCK: using-openrig.md -->",
"<!-- BEGIN OpenRig MANAGED BLOCK: using-openrig.md -->",
"# Using OpenRig",
"Old guidance",
"<!-- END RIGGED MANAGED BLOCK: using-openrig.md -->",
"<!-- END OpenRig MANAGED BLOCK: using-openrig.md -->",
].join("\n"),
});
const adapter = new CodexRuntimeAdapter({ tmux: mockTmux(), fsOps: fs });
@@ -307,8 +307,8 @@ describe("Codex runtime adapter", () => {
const store = (fs as unknown as { _store: Record<string, string> })._store;
const content = store["/project/AGENTS.md"]!;
expect(content).toContain("BEGIN RIGGED MANAGED BLOCK: openrig-start.md");
expect(content).not.toContain("BEGIN RIGGED MANAGED BLOCK: using-openrig.md");
expect(content).toContain("BEGIN OpenRig MANAGED BLOCK: openrig-start.md");
expect(content).not.toContain("BEGIN OpenRig MANAGED BLOCK: using-openrig.md");
expect(content).toContain("New guidance");
});
@@ -348,7 +348,7 @@ describe("Codex runtime adapter", () => {
it("replay on restore is safe for already-projected content", async () => {
const fs = mockFs({
"/rig/guide.md": "# Guidance",
"/project/AGENTS.md": "<!-- BEGIN RIGGED MANAGED BLOCK: guide.md -->\n# Guidance\n<!-- END RIGGED MANAGED BLOCK: guide.md -->",
"/project/AGENTS.md": "<!-- BEGIN OpenRig MANAGED BLOCK: guide.md -->\n# Guidance\n<!-- END OpenRig MANAGED BLOCK: guide.md -->",
});
const adapter = new CodexRuntimeAdapter({ tmux: mockTmux(), fsOps: fs });
const file: ResolvedStartupFile = {
@@ -362,7 +362,7 @@ describe("Codex runtime adapter", () => {
const store = (fs as unknown as { _store: Record<string, string> })._store;
const content = store["/project/AGENTS.md"]!;
const blockCount = (content.match(/BEGIN RIGGED MANAGED BLOCK/g) ?? []).length;
const blockCount = (content.match(/BEGIN OpenRig MANAGED BLOCK/g) ?? []).length;
expect(blockCount).toBe(1); // exactly one block, not two
});
@@ -1044,7 +1044,7 @@ describe("Codex runtime adapter", () => {
await adapter.project(plan, makeBinding());
const store = (fs as unknown as { _store: Record<string, string> })._store;
expect(store["/project/AGENTS.md"]).toContain("BEGIN RIGGED MANAGED BLOCK: using-openrig.md");
expect(store["/project/AGENTS.md"]).toContain("BEGIN OpenRig MANAGED BLOCK: using-openrig.md");
expect(store["/project/AGENTS.md"]).toContain("hub guidance");
});
@@ -112,7 +112,7 @@ describe("ConflictDetector", () => {
// Test 6: Existing guidance, has managed block -> managed_merge, hasExistingBlock=true
it("existing guidance, has managed block -> managed_merge, hasExistingBlock=true", () => {
const result = resolveAndPlan(BASIC_MANIFEST, {
"/repo/AGENTS.md": "# Header\n<!-- BEGIN RIGGED MANAGED BLOCK: test-pkg -->\nold content\n<!-- END RIGGED MANAGED BLOCK: test-pkg -->\n# Footer",
"/repo/AGENTS.md": "# Header\n<!-- BEGIN OpenRig MANAGED BLOCK: test-pkg -->\nold content\n<!-- END OpenRig MANAGED BLOCK: test-pkg -->\n# Footer",
});
const guidance = result.actionable.find((e) => e.exportType === "guidance") as InstallPlanEntry & { guidanceMeta?: GuidanceConflictMeta };
expect(guidance).toBeDefined();
@@ -252,7 +252,7 @@ exports:
// Test 11: Managed block for DIFFERENT package -> hasExistingBlock=false
it("existing guidance with managed block for different package -> hasExistingBlock=false", () => {
const result = resolveAndPlan(BASIC_MANIFEST, {
"/repo/AGENTS.md": "# Header\n<!-- BEGIN RIGGED MANAGED BLOCK: other-package -->\nother content\n<!-- END RIGGED MANAGED BLOCK: other-package -->\n",
"/repo/AGENTS.md": "# Header\n<!-- BEGIN OpenRig MANAGED BLOCK: other-package -->\nother content\n<!-- END OpenRig MANAGED BLOCK: other-package -->\n",
});
const guidance = result.actionable.find((e) => e.exportType === "guidance") as InstallPlanEntry & { guidanceMeta?: GuidanceConflictMeta };
expect(guidance).toBeDefined();
+4 -4
View File
@@ -143,9 +143,9 @@ describe("InstallEngine", () => {
engine.apply(makePolicy([entry]), makePlan([entry]), pkg.id, repoRoot);
const content = fs.readFileSync(targetPath, "utf-8");
expect(content).toContain("<!-- BEGIN RIGGED MANAGED BLOCK: test-pkg -->");
expect(content).toContain("<!-- BEGIN OpenRig MANAGED BLOCK: test-pkg -->");
expect(content).toContain("Review all PRs carefully.");
expect(content).toContain("<!-- END RIGGED MANAGED BLOCK: test-pkg -->");
expect(content).toContain("<!-- END OpenRig MANAGED BLOCK: test-pkg -->");
});
// Test 3: Journal entries with hashes
@@ -197,7 +197,7 @@ describe("InstallEngine", () => {
expect(content).toContain("# Existing content");
expect(content).toContain("Keep this.");
expect(content).toContain("New guidance.");
expect(content).toContain("<!-- BEGIN RIGGED MANAGED BLOCK: test-pkg -->");
expect(content).toContain("<!-- BEGIN OpenRig MANAGED BLOCK: test-pkg -->");
});
// Test 6: Existing managed block updated in place
@@ -206,7 +206,7 @@ describe("InstallEngine", () => {
const sourcePath = writeSource("guidance/AGENTS.md", "Updated guidance.");
const targetPath = path.join(repoRoot, "AGENTS.md");
fs.writeFileSync(targetPath,
"# Header\n<!-- BEGIN RIGGED MANAGED BLOCK: test-pkg -->\nOld content.\n<!-- END RIGGED MANAGED BLOCK: test-pkg -->\n# Footer\n",
"# Header\n<!-- BEGIN OpenRig MANAGED BLOCK: test-pkg -->\nOld content.\n<!-- END OpenRig MANAGED BLOCK: test-pkg -->\n# Footer\n",
"utf-8"
);
+2 -2
View File
@@ -299,8 +299,8 @@ describe("Package API routes", () => {
// Verify managed block was inserted
const claudeMd = fs.readFileSync(path.join(targetDir, "CLAUDE.md"), "utf-8");
expect(claudeMd).toContain("<!-- BEGIN RIGGED MANAGED BLOCK: guidance-pkg -->");
expect(claudeMd).toContain("<!-- END RIGGED MANAGED BLOCK: guidance-pkg -->");
expect(claudeMd).toContain("<!-- BEGIN OpenRig MANAGED BLOCK: guidance-pkg -->");
expect(claudeMd).toContain("<!-- END OpenRig MANAGED BLOCK: guidance-pkg -->");
expect(claudeMd).toContain("# Existing content");
});
+5 -5
View File
@@ -287,9 +287,9 @@ describe("RigTeardownOrchestrator", () => {
const claudeMd = path.join(cwd, "CLAUDE.md");
fs.writeFileSync(claudeMd, [
"# User intro",
"<!-- BEGIN RIGGED MANAGED BLOCK: role -->",
"<!-- BEGIN OpenRig MANAGED BLOCK: role -->",
"managed role",
"<!-- END RIGGED MANAGED BLOCK: role -->",
"<!-- END OpenRig MANAGED BLOCK: role -->",
"<!-- BEGIN THIRD PARTY BLOCK -->",
"third party",
"<!-- END THIRD PARTY BLOCK -->",
@@ -304,7 +304,7 @@ describe("RigTeardownOrchestrator", () => {
expect(content).toContain("# User intro");
expect(content).toContain("third party");
expect(content).toContain("tail");
expect(content).not.toContain("BEGIN RIGGED MANAGED BLOCK");
expect(content).not.toContain("BEGIN OpenRig MANAGED BLOCK");
});
it("deletes guidance file if only OpenRig-managed content remains after teardown", async () => {
@@ -312,9 +312,9 @@ describe("RigTeardownOrchestrator", () => {
fs.mkdirSync(cwd, { recursive: true });
const agentsMd = path.join(cwd, "AGENTS.md");
fs.writeFileSync(agentsMd, [
"<!-- BEGIN RIGGED MANAGED BLOCK: role -->",
"<!-- BEGIN OpenRig MANAGED BLOCK: role -->",
"managed role",
"<!-- END RIGGED MANAGED BLOCK: role -->",
"<!-- END OpenRig MANAGED BLOCK: role -->",
].join("\n"));
const { rigId } = seedRigWithNode({ runtime: "codex", cwd, sessionStatus: "exited" });
const td = buildTeardown();