Files
ctask/internal
typebasedio 0b21b8d3da feat(v0.6): schema_version and workspace.mode in task.yaml
Adds the two new metadata fields specified for Phase 1 of v0.6 plus
the validation and defaulting helpers around them.

internal/workspace/metadata.go:

- CurrentMetaSchemaVersion = 1 constant.
- WorkspaceSection struct {Mode string} with omitempty.
- SchemaVersion int and Workspace WorkspaceSection fields added to
  TaskMeta at the top of the struct. Both are omitempty so legacy
  task.yaml files (no schema_version, no workspace block) round-trip
  without acquiring these keys when an unrelated field is updated.
- EffectiveSchemaVersion(meta) — returns 1 for stored-value-0 legacy
  workspaces; non-zero stored values are returned verbatim.
- ValidateSchemaVersion(slug, meta) — rejects stored values higher
  than CurrentMetaSchemaVersion with the spec-mandated upgrade
  message. Accepts 0 (legacy missing).
- ValidateWorkspaceMode(slug, meta) — rejects modes other than ""
  and "native". "adopted" is reserved for v0.7.
- ReadMeta now runs both validators after unmarshal. The validation
  error includes the workspace slug (derived from task.yaml's slug
  field, falling back to the directory basename when the file itself
  is corrupt).

internal/workspace/create.go:

- workspace.Create stamps every new meta with
  SchemaVersion: CurrentMetaSchemaVersion and Workspace.Mode: "native".
  This is the ONLY write site for these fields in v0.6; resume,
  archive, restore, and any other path that rewrites task.yaml MUST
  NOT backfill them (the "no opportunistic schema writes" invariant).

internal/workspace/schema_test.go:

- 10 tests:
  * new meta written by Create contains schema_version: 1 +
    workspace.mode: native (both serialization and round-trip)
  * legacy meta without these fields loads with stored value 0 / ""
    and EffectiveSchemaVersion returns 1
  * task.yaml with schema_version: 2 is rejected with upgrade message
  * task.yaml with workspace.mode: adopted is rejected
  * the no-opportunistic-writes invariant is pinned for both WriteMeta
    and WriteMetaLocked: a legacy file rewritten with an updated
    UpdatedAt does NOT acquire schema_version or workspace: keys
  * ValidateSchemaVersion accepts {0, 1}; ValidateWorkspaceMode
    accepts {"", "native"}
2026-05-14 21:50:02 -04:00
..
2026-05-14 19:51:21 -04:00