This commit was merged in pull request #813.
This commit is contained in:
@@ -204,6 +204,53 @@ export async function prepareAgentEnvironmentProjection(
|
||||
};
|
||||
}
|
||||
|
||||
/** A generated-only projection validated without touching any legacy/local/quarantine file. */
|
||||
export interface PreparedGeneratedAgentEnvironmentProjection {
|
||||
readonly mosaicHome: string;
|
||||
readonly agentEnvDir: string;
|
||||
readonly generatedPath: string;
|
||||
readonly generated: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates ONLY the roster-derived generated projection for a recovery rebuild.
|
||||
* Unlike {@link prepareAgentEnvironmentProjection}, this never reads, classifies,
|
||||
* relocates, or quarantines the legacy `.env` / `.env.local` operator surface — it
|
||||
* exists so `mosaic fleet regen` has no code path that can mutate anything except
|
||||
* `<name>.env.generated`. The existing generated file, if present, must already be
|
||||
* a private regular file.
|
||||
*/
|
||||
export async function prepareGeneratedAgentEnvironmentProjection(
|
||||
options: AgentEnvironmentProjectionOptions,
|
||||
): Promise<PreparedGeneratedAgentEnvironmentProjection> {
|
||||
if (!AGENT_NAME.test(options.agentName)) {
|
||||
throw new AgentEnvBoundaryError('unsafe-agent-name', 'MOSAIC_AGENT_NAME', options.agentName);
|
||||
}
|
||||
await validatePrivateProjectionDirectory(options.mosaicHome, options.agentEnvDir);
|
||||
const generatedPath = join(options.agentEnvDir, `${options.agentName}.env.generated`);
|
||||
const generated = renderGeneratedAgentEnvironment(options.generated);
|
||||
await assertPrivateRegularFileIfPresent(generatedPath);
|
||||
return {
|
||||
mosaicHome: options.mosaicHome,
|
||||
agentEnvDir: options.agentEnvDir,
|
||||
generatedPath,
|
||||
generated,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a generated-only projection: writes ONLY `<name>.env.generated` atomically
|
||||
* and touches nothing else. It never writes `.env.local`/`.env.quarantine` and never
|
||||
* unlinks the legacy `.env` — the projection-only recovery guarantee is structural.
|
||||
*/
|
||||
export async function applyPreparedGeneratedAgentEnvironmentProjection(
|
||||
prepared: PreparedGeneratedAgentEnvironmentProjection,
|
||||
): Promise<string> {
|
||||
await ensurePrivateProjectionDirectory(prepared.mosaicHome, prepared.agentEnvDir);
|
||||
await writePrivateAtomically(prepared.generatedPath, prepared.generated);
|
||||
return prepared.generatedPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates only the exact generated projection eligible for a roster delete.
|
||||
* Local overrides, legacy input, and quarantine records are operator-retained and
|
||||
|
||||
Reference in New Issue
Block a user