Documentation
¶
Overview ¶
Package schema embeds the natively-owned kentra-spec-lifecycle schema descriptor (spec-lifecycle.md §4, implementation-plan.md §2.2): the artifact set (proposal -> specs -> design -> tasks), its requires: DAG, and the four artifact templates (spec-lifecycle.md §4's stage/content table; the tasks.md template carries §4.2's milestone/validation-contract grammar verbatim).
The schema.yaml + templates/*.md shape mirrors OpenSpec v1.5.0's own [experimental] project-local schema descriptor layout — <projectRoot>/openspec/schemas/<name>/{schema.yaml,templates/*.md} — confirmed against a v1.5.0 checkout's src/core/artifact-graph/resolver.ts (getProjectSchemasDir/resolveSchema) and its packaged schemas/spec-driven/{schema.yaml,templates/*.md}. That shape is copied for format-compatibility and human documentation ONLY: nothing at runtime reads this descriptor back. Stage ordering and the artifact DAG are enforced by lifecycle's own gate records (approval-state.json) and `lifecycle validate` (internal/validate), never by a schema interpreter — deliberately, so this primitive never grows the "young `[experimental]` subsystem" risk class OpenSpec's own schema loader carries (implementation-plan.md §0.5/§11).
Install writes the descriptor tree to a project directory; Verify checks an already-installed tree still matches the embedded assets byte-for-byte (the drift check a future `lifecycle init`/regen path, M6, needs). Neither function is `lifecycle init` itself — that verb (and its idempotent compose of this package with config.yaml wiring, constitution preflight, and skill fan-out) is M6, per implementation-plan.md §8's milestone map; M2 only needs the schema descriptor + its writer/verifier to exist and be tested.
Index ¶
Constants ¶
const Name = "kentra-spec-lifecycle"
Name is the schema's identifier: both the schema.yaml `name:` field and the directory name under openspec/schemas/ (spec-lifecycle.md §12 item 4 — "the format-compatible schema is kentra-branded").
Variables ¶
This section is empty.
Functions ¶
func Dir ¶
Dir returns the descriptor's install root under a project directory: <dir>/openspec/schemas/kentra-spec-lifecycle.
func Install ¶
Install writes the embedded schema descriptor to <dir>/openspec/schemas/kentra-spec-lifecycle/{schema.yaml,templates/*.md}, creating directories as needed. Every file is written atomically (internal/atomicwrite: a torn write here is exactly the "log is truth" failure mode that primitive is designed out at the syscall level). Install is idempotent — re-running it against an already-installed, unmodified tree rewrites the same bytes — and does not itself check for drift; callers that need drift detection call Verify first.
Types ¶
type Artifact ¶
type Artifact struct {
ID string `yaml:"id"`
Generates string `yaml:"generates"`
Description string `yaml:"description"`
Template string `yaml:"template"`
Instruction string `yaml:"instruction"`
Requires []string `yaml:"requires"`
}
Artifact is one schema.yaml `artifacts[]` entry.
type Definition ¶
type Definition struct {
Name string `yaml:"name"`
Version int `yaml:"version"`
Description string `yaml:"description"`
Artifacts []Artifact `yaml:"artifacts"`
}
Definition is the parsed shape of the embedded schema.yaml — the SINGLE runtime consumer of its structured content. This is distinct from Install/Verify (schema.go), which treat every embedded asset, including schema.yaml itself, as an opaque byte blob written to a project for format-compatibility/documentation only (schema.go's package doc: "nothing at runtime reads this descriptor BACK" — meaning the on-disk, project-local copy Install writes). Load instead reads the original asset the embed directive baked into the binary at build time — it is not the "[experimental] custom-schema loader" risk class that package doc disclaims; that phrase is about re-reading a project's on-disk copy as a configurable input, which lifecycle never does.
implementation-plan.md §2.6 directs `lifecycle approve` to "resolve the stage's artifact set via the schema's generates: globs" — Definition and Generates are what let internal/approve do that without hand-typing a second copy of "proposal.md" / "specs/**/spec.md" / "design.md" / "tasks.md" (schema.yaml already IS that source of truth).
func Load ¶
func Load() (*Definition, error)
Load parses the embedded schema.yaml into a Definition.
func (*Definition) Generates ¶
func (d *Definition) Generates(id string) string
Generates returns the generates: glob for the artifact with the given id (e.g. "proposal", "specs", "design", "tasks"), or "" if id is unknown to this schema.
type Mismatch ¶
type Mismatch struct {
// Rel is the path relative to the descriptor root (e.g.
// "templates/tasks.md").
Rel string
// Reason is "missing" (file absent) or "modified" (present, differs).
Reason string
}
Mismatch names one installed file that fails to verify against the embedded asset it should mirror.
func Verify ¶
Verify reports every embedded asset that is missing from, or byte-differs under, <dir>/openspec/schemas/kentra-spec-lifecycle. A nil slice means the installed tree matches exactly. Verify never flags EXTRA files present under the descriptor root beyond the embedded set — it only checks that every embedded asset is present and unmodified.