You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The bundled derive-session-context helper runs JSON schema validation against .agents/preferences.yaml and ~/.agents/preferences.yaml on every invocation, and treats any validation failure as a hard exit. This conflates authoring-time validation with read-time consumption, and asserts ownership over a file that is a multi-tool surface.
.agents/preferences.yaml is not codeassembly-owned. The directory name (.agents/, not .codeassembly/) signals a shared agent-tooling surface, analogous to .editorconfig or package.json, where convention is "ignore what you don't recognize, validate what you do." The user's own preferences file already contains top-level keys (worktrees:, merge_commit:) and nested keys (artifacts.enabled) that other tooling uses or that the author kept deliberately. Codeassembly's reader has no business hard-failing on keys outside its declared schema.
Concrete failure mode.~/.agents/preferences.yaml carried a merge_commit: block annotated # @deprecated - Use \merge`., transitional from a prior rename. The schema's top level sets additionalProperties: falseand no longer definesmerge_commit`, so the validator rejected the file:
derive-session-context: preferences failed schema validation at "merge_commit" (failed keyword: https://json-schema.org/evaluation/validate). Check the contents of .agents/preferences.yaml (or the global ~/.agents/preferences.yaml).
The deriver propagated the rejection as exit 1. Every downstream consumer — resolve-frontmatter.sh and every skill that reads session context via the deriver — failed too. The user's actual artifacts.base_dir and project.slug (the only fields the deriver reads) were well-formed and unaffected.
Validation belongs at authoring time, not on every read. The preferences file already carries a $schema reference for editor LSPs, the right authoring-time surface where the user sees and resolves schema feedback in context. The reader's job is to extract the fields it consumes with sensible defaults. Coupling reads to strict validation means any schema tightening can break preferences files that the deriver doesn't read meaningfully.
This affects every downstream consumer of the deriver: frontmatter resolution, ticket creation, artifact saving, and orchestrated runs that depend on .agents/{branch}.branch-manifest.json being derivable.
Context
Validation falls into three concentric circles, which the current code conflates:
Outer (file as a whole): Not codeassembly's territory — .agents/ may host config for other tools.
Middle (declared schema): Validated at authoring time by the editor LSP (via the YAML's $schema reference) and by preferences-schema.test.ts for the project-checked-in .agents/preferences.yaml.
Inner (fields the deriver consumes): Hard-fail on wrong type or wrong enum at the read site, because the deriver's contract depends on the field's shape.
The fix removes the outer ring entirely and leaves the middle as an authoring-time concern. The inner ring becomes the deriver's only runtime responsibility for shape.
Proposed solution
Replace the schema-validation step in the deriver's preferences reader with a projection function that walks the merged preferences object and produces a typed ResolvedPreferences by reading only the fields the deriver consumes. Unknown sibling keys at every level pass through silently. Per-field narrowing throws with a key-path-anchored message when a consumed field has the wrong type or wrong enum value.
The schema file stays in place: referenced by the YAML's $schema for editor LSPs and exercised by the existing schema test against the project-level .agents/preferences.yaml. No runtime callers of the schema remain in the deriver.
Add a short note to artifact-conventions.md documenting the reader-is-tolerant design so the next contributor doesn't re-introduce read-time validation.
Acceptance criteria
Must have
derive-session-context reads the fields it consumes (artifacts.base_dir, artifacts.paths, project.slug, project.ticket_ref_prefix, platform, repository.slug, repository.default_remote.{name,default_branch}) with sensible defaults when absent, without invoking the JSON schema validator on the preferences file.
Unknown top-level keys and unknown nested keys in either .agents/preferences.yaml or ~/.agents/preferences.yaml do not cause the deriver to fail.
The deriver still hard-fails on:
malformed YAML
missing required git state (not in a repo, no branch resolvable)
shape problems on fields the deriver consumes (e.g., artifacts.base_dir set to a non-string; platform set to a value outside the github | bitbucket enum)
resolve-frontmatter.sh and the skills that depend on it (frontmatter writing, ticket creation, artifact saving, design-and-plan, refine-plan, etc.) no longer fail when the user's preferences carry unknown keys.
artifact-conventions.md documents that the reader is intentionally tolerant and that authoring-time validation lives in the editor LSP and preferences-schema.test.ts.
New and modified behavior in the reader is covered by tests, including: tolerance for unknown top-level keys, tolerance for unknown nested keys, hard-fail on wrong type for a consumed field, hard-fail on out-of-enum platform.
Out of scope (potential follow-ups)
A standalone validate-preferences CLI or --validate flag for on-demand linting
Schema tombstone support (a first-class way to mark a key as known-deprecated, distinct from unknown)
Stderr warnings on unknown top-level keys — rejected as an inappropriate ownership claim on a multi-tool config surface
Problem
The bundled
derive-session-contexthelper runs JSON schema validation against.agents/preferences.yamland~/.agents/preferences.yamlon every invocation, and treats any validation failure as a hard exit. This conflates authoring-time validation with read-time consumption, and asserts ownership over a file that is a multi-tool surface..agents/preferences.yamlis not codeassembly-owned. The directory name (.agents/, not.codeassembly/) signals a shared agent-tooling surface, analogous to.editorconfigorpackage.json, where convention is "ignore what you don't recognize, validate what you do." The user's own preferences file already contains top-level keys (worktrees:,merge_commit:) and nested keys (artifacts.enabled) that other tooling uses or that the author kept deliberately. Codeassembly's reader has no business hard-failing on keys outside its declared schema.Concrete failure mode.
~/.agents/preferences.yamlcarried amerge_commit:block annotated# @deprecated - Use \merge`., transitional from a prior rename. The schema's top level setsadditionalProperties: falseand no longer definesmerge_commit`, so the validator rejected the file:The deriver propagated the rejection as exit 1. Every downstream consumer —
resolve-frontmatter.shand every skill that reads session context via the deriver — failed too. The user's actualartifacts.base_dirandproject.slug(the only fields the deriver reads) were well-formed and unaffected.Validation belongs at authoring time, not on every read. The preferences file already carries a
$schemareference for editor LSPs, the right authoring-time surface where the user sees and resolves schema feedback in context. The reader's job is to extract the fields it consumes with sensible defaults. Coupling reads to strict validation means any schema tightening can break preferences files that the deriver doesn't read meaningfully.This affects every downstream consumer of the deriver: frontmatter resolution, ticket creation, artifact saving, and orchestrated runs that depend on
.agents/{branch}.branch-manifest.jsonbeing derivable.Context
Validation falls into three concentric circles, which the current code conflates:
.agents/may host config for other tools.$schemareference) and bypreferences-schema.test.tsfor the project-checked-in.agents/preferences.yaml.The fix removes the outer ring entirely and leaves the middle as an authoring-time concern. The inner ring becomes the deriver's only runtime responsibility for shape.
Proposed solution
Replace the schema-validation step in the deriver's preferences reader with a projection function that walks the merged preferences object and produces a typed
ResolvedPreferencesby reading only the fields the deriver consumes. Unknown sibling keys at every level pass through silently. Per-field narrowing throws with a key-path-anchored message when a consumed field has the wrong type or wrong enum value.The schema file stays in place: referenced by the YAML's
$schemafor editor LSPs and exercised by the existing schema test against the project-level.agents/preferences.yaml. No runtime callers of the schema remain in the deriver.Add a short note to
artifact-conventions.mddocumenting the reader-is-tolerant design so the next contributor doesn't re-introduce read-time validation.Acceptance criteria
Must have
derive-session-contextreads the fields it consumes (artifacts.base_dir,artifacts.paths,project.slug,project.ticket_ref_prefix,platform,repository.slug,repository.default_remote.{name,default_branch}) with sensible defaults when absent, without invoking the JSON schema validator on the preferences file..agents/preferences.yamlor~/.agents/preferences.yamldo not cause the deriver to fail.artifacts.base_dirset to a non-string;platformset to a value outside thegithub | bitbucketenum)resolve-frontmatter.shand the skills that depend on it (frontmatter writing, ticket creation, artifact saving,design-and-plan,refine-plan, etc.) no longer fail when the user's preferences carry unknown keys.artifact-conventions.mddocuments that the reader is intentionally tolerant and that authoring-time validation lives in the editor LSP andpreferences-schema.test.ts.platform.Out of scope (potential follow-ups)
validate-preferencesCLI or--validateflag for on-demand linting