Files
pad/internal/artifact/frontmatter.go
T
xarmian 7ea552fa9b feat(artifact): MD+frontmatter export/import core for playbooks & conventions (#754)
* feat(artifact): add MD+frontmatter export/import core for playbooks & conventions

Pure-Go internal/artifact package: Encode/Decode a single playbook or
convention item to a portable Markdown + YAML-frontmatter artifact with
deterministic key order and a provenance block. Field-key tables map item
fields to frontmatter per kind; FieldKeysForKind is exported for the
server layer. Round-trip + golden + determinism + error-case tests.

Server-side validation, forgiving coercion, slug-collision handling, and
YAML input limits are deferred to Phase 2 (HTTP boundary).

Implements Phase 1 of PLAN-1867 (TASK-1868, TASK-1869, TASK-1870).

Claude-Session: https://claude.ai/code/session_01KmxkPxLksjf1pmrZDpsnTJ

* fix(artifact): tolerate CRLF line endings on decode

Normalize CRLF to LF at Decode's entry point so artifacts authored or
transported on Windows decode identically (fence detection + body
preservation operate on canonical LF). Addresses Codex P2 round 1.

Claude-Session: https://claude.ai/code/session_01KmxkPxLksjf1pmrZDpsnTJ
2026-06-22 11:07:37 -04:00

31 lines
1.1 KiB
Go

package artifact
// frontmatter is the typed YAML frontmatter representation. Using a struct
// (not a map) guarantees stable, deterministic key order on encode.
//
// Key order on the wire MUST be:
//
// pad_artifact, format_version, title, status, trigger, scope,
// invocation_slug, arguments, priority, role, provenance
//
// The kind-specific field keys carry omitempty so a convention artifact does
// not emit empty playbook keys and vice-versa.
type frontmatter struct {
PadArtifact Kind `yaml:"pad_artifact"`
FormatVersion int `yaml:"format_version"`
Title string `yaml:"title"`
// Playbook keys.
Status string `yaml:"status,omitempty"`
Trigger string `yaml:"trigger,omitempty"`
Scope string `yaml:"scope,omitempty"`
InvocationSlug string `yaml:"invocation_slug,omitempty"`
Arguments []map[string]any `yaml:"arguments,omitempty"`
// Convention-only keys (status/trigger/scope are shared above).
Priority string `yaml:"priority,omitempty"`
Role string `yaml:"role,omitempty"`
Provenance Provenance `yaml:"provenance"`
}