refactor!: rename RoleDefinition.meta → frontmatter

BREAKING CHANGE: All workflow YAML files must use 'frontmatter' instead of 'meta'.

- workflow-protocol: RoleDefinition.meta → frontmatter, schema updated
- cli-workflow: validate.ts, workflow.ts — resolveMetaRef → resolveFrontmatterRef
- workflow-agent-kit: run.ts — metaSchema → frontmatterSchema
- All YAML files updated (examples/, .workflows/)

Fixes #374
This commit is contained in:
2026-05-22 06:04:45 +00:00
parent 8ea554bb5e
commit 02f7f0b708
8 changed files with 39 additions and 25 deletions
+15 -6
View File
@@ -46,11 +46,16 @@ function isJsonSchema(value: unknown): value is JSONSchema {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
async function resolveMetaRef(uwf: UwfStore, roleName: string, meta: unknown): Promise<CasRef> {
if (!isJsonSchema(meta)) {
fail(`role "${roleName}": meta must be a JSON Schema object`);
async function resolveFrontmatterRef(
uwf: UwfStore,
roleName: string,
frontmatter: unknown,
): Promise<CasRef> {
if (!isJsonSchema(frontmatter)) {
fail(`role "${roleName}": frontmatter must be a JSON Schema object`);
}
const schema: JSONSchema = meta.title === undefined ? { ...meta, title: roleName } : meta;
const schema: JSONSchema =
frontmatter.title === undefined ? { ...frontmatter, title: roleName } : frontmatter;
return putSchema(uwf.store, schema);
}
@@ -60,14 +65,18 @@ export async function materializeWorkflowPayload(
): Promise<WorkflowPayload> {
const roles: Record<string, RoleDefinition> = {};
for (const [roleName, role] of Object.entries(raw.roles)) {
const meta = await resolveMetaRef(uwf, `${raw.name}.${roleName}`, role.meta);
const frontmatter = await resolveFrontmatterRef(
uwf,
`${raw.name}.${roleName}`,
role.frontmatter,
);
roles[roleName] = {
description: role.description,
goal: role.goal,
capabilities: role.capabilities,
procedure: role.procedure,
output: role.output,
meta,
frontmatter,
};
}
return {
+3 -3
View File
@@ -15,8 +15,8 @@ function isRoleDefinition(value: unknown): boolean {
if (!isRecord(value)) {
return false;
}
const meta = value.meta;
const metaOk = isRecord(meta) && typeof meta.type === "string";
const frontmatter = value.frontmatter;
const frontmatterOk = isRecord(frontmatter) && typeof frontmatter.type === "string";
const capabilities = value.capabilities;
const capabilitiesOk =
Array.isArray(capabilities) && capabilities.every((c) => typeof c === "string");
@@ -26,7 +26,7 @@ function isRoleDefinition(value: unknown): boolean {
capabilitiesOk &&
typeof value.procedure === "string" &&
typeof value.output === "string" &&
metaOk
frontmatterOk
);
}
+9 -4
View File
@@ -130,13 +130,18 @@ export function createAgent(options: AgentOptions): () => Promise<void> {
fail(`unknown role: ${role}`);
}
const metaSchema = getSchema(ctx.meta.store, roleDef.meta);
if (metaSchema !== null) {
ctx.outputFormatInstruction = buildOutputFormatInstruction(metaSchema);
const frontmatterSchema = getSchema(ctx.meta.store, roleDef.frontmatter);
if (frontmatterSchema !== null) {
ctx.outputFormatInstruction = buildOutputFormatInstruction(frontmatterSchema);
}
const agentResult = await runAgent(options, ctx);
const outputHash = await extractOutput(agentResult.output, roleDef.meta, storageRoot, ctx);
const outputHash = await extractOutput(
agentResult.output,
roleDef.frontmatter,
storageRoot,
ctx,
);
const stepHash = await persistStep({
ctx,
outputHash,
+2 -2
View File
@@ -2,14 +2,14 @@ import type { JSONSchema } from "@uncaged/json-cas";
const ROLE_DEFINITION: JSONSchema = {
type: "object",
required: ["description", "goal", "capabilities", "procedure", "output", "meta"],
required: ["description", "goal", "capabilities", "procedure", "output", "frontmatter"],
properties: {
description: { type: "string" },
goal: { type: "string" },
capabilities: { type: "array", items: { type: "string" } },
procedure: { type: "string" },
output: { type: "string" },
meta: { type: "string", format: "cas_ref" },
frontmatter: { type: "string", format: "cas_ref" },
},
additionalProperties: false,
};
+1 -1
View File
@@ -22,7 +22,7 @@ export type RoleDefinition = {
capabilities: string[];
procedure: string;
output: string;
meta: CasRef;
frontmatter: CasRef;
};
export type Transition = {