feat: preserve evidence in workspace artifacts
This commit is contained in:
@@ -177,6 +177,72 @@ function localizedIntroduction(workspace: WorkspaceDescriptor): string {
|
||||
: `Installation setup for ${workspace.workspace.name}. Configure only the bindings supported by this installation.`;
|
||||
}
|
||||
|
||||
function evidenceDocumentation(
|
||||
workspace: WorkspaceDescriptor,
|
||||
variables: readonly InstallationVariable[],
|
||||
): string[] {
|
||||
if (!("evidence" in workspace) || workspace.evidence === undefined) return [];
|
||||
const { source, policy } = workspace.evidence;
|
||||
const common = [
|
||||
"## Evidence source",
|
||||
"",
|
||||
`- Type: \`${source.type}\``,
|
||||
];
|
||||
let details: string[];
|
||||
if (source.type === "filesystem") {
|
||||
details = [
|
||||
`- URI: \`${source.uri}\``,
|
||||
`- Patterns: ${source.patterns.map((pattern) => `\`${pattern}\``).join(", ")}`,
|
||||
`- Maximum source bytes: \`${source.max_bytes}\``,
|
||||
"- Ownership: the descriptor and its Evidence tree are owned by the same Git revision.",
|
||||
"- Materialization: P6 materializes that revision-pinned tree and verifies real containment, including symlink safety.",
|
||||
"- Export boundary: the browser/API ZIP does not include Evidence file bytes.",
|
||||
];
|
||||
} else if (source.type === "http") {
|
||||
details = [
|
||||
"- URIs:",
|
||||
...source.uris.map((uri) => ` - \`${uri}\``),
|
||||
`- Authentication: \`${source.authentication}\`. ${source.authentication === "none"
|
||||
? "No credential file is required."
|
||||
: "Provide the signed URL file through the installation file variable listed below."}`,
|
||||
`- Connect timeout (ms): \`${source.connect_timeout_ms}\``,
|
||||
`- Read timeout (ms): \`${source.read_timeout_ms}\``,
|
||||
`- Maximum source bytes: \`${source.max_bytes}\``,
|
||||
`- Maximum redirects: \`${source.max_redirects}\``,
|
||||
`- Private hosts allowed: \`${source.allow_private_hosts}\``,
|
||||
`- Maximum cache bytes: \`${source.max_cache_bytes}\``,
|
||||
];
|
||||
} else {
|
||||
details = [
|
||||
`- URI: \`${source.uri}\``,
|
||||
...(source.endpoint_url === undefined ? [] : [`- Endpoint URL: \`${source.endpoint_url}\``]),
|
||||
...(source.region === undefined ? [] : [`- Region: \`${source.region}\``]),
|
||||
`- Credentials: \`${source.credentials}\`. ${source.credentials === "ambient"
|
||||
? "Use ambient credentials; no Evidence credential file is required."
|
||||
: "Provide credentials through the installation file variables listed below."}`,
|
||||
`- Trusted endpoint: \`${source.trusted_endpoint}\``,
|
||||
`- Private endpoint allowed: \`${source.allow_private_endpoint}\``,
|
||||
`- Insecure endpoint allowed: \`${source.allow_insecure_endpoint}\``,
|
||||
`- Maximum source bytes: \`${source.max_bytes}\``,
|
||||
`- Maximum objects: \`${source.max_objects}\``,
|
||||
`- Maximum pages: \`${source.max_pages}\``,
|
||||
`- Page size: \`${source.page_size}\``,
|
||||
];
|
||||
}
|
||||
const evidenceVariables = variables.filter(({ role }) => role === "EVIDENCE");
|
||||
return [
|
||||
...common,
|
||||
...details,
|
||||
`- Maximum chunk characters: \`${policy.max_chunk_chars}\``,
|
||||
`- Retained published generations: \`${policy.retain_published_generations}\``,
|
||||
...(evidenceVariables.length === 0 ? [] : [
|
||||
"- Required installation file variables:",
|
||||
...evidenceVariables.map(({ name }) => ` - \`${name}\``),
|
||||
]),
|
||||
"",
|
||||
];
|
||||
}
|
||||
|
||||
export function renderWorkspaceDocs(workspace: WorkspaceDescriptor): { envExample: string; markdown: string } {
|
||||
const descriptor = validateWorkspaceDescriptor(workspace);
|
||||
const contract = buildInstallationContract(descriptor);
|
||||
@@ -213,6 +279,7 @@ export function renderWorkspaceDocs(workspace: WorkspaceDescriptor): { envExampl
|
||||
)),
|
||||
"",
|
||||
]),
|
||||
...evidenceDocumentation(descriptor, contract.variables),
|
||||
].join("\n");
|
||||
|
||||
return { envExample, markdown };
|
||||
|
||||
@@ -790,6 +790,8 @@ export class WorkspaceRegistry {
|
||||
}
|
||||
|
||||
private expectedSnapshotFiles(state: ActiveState): string[] {
|
||||
// P1 snapshots only descriptors and derived public docs. P6 owns revision-pinned
|
||||
// workspace-content materialization and its recursive containment checks.
|
||||
return state.revisions.flatMap((revision) => revision.state === "operational"
|
||||
? [`${revision.id}.yaml`, `${revision.id}.env.example`, `${revision.id}.md`]
|
||||
: [`${revision.id}.yaml`]);
|
||||
|
||||
Reference in New Issue
Block a user